1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <sys/types.h>
32 #include <sys/ioctl.h>
42 #include <sys/socket.h>
47 #include "gdkprivate-fb.h"
48 #include "gdkinternals.h"
49 #include "gdkfbmanager.h"
51 /* Private variable declarations
53 static int gdk_initialized = 0; /* 1 if the library is initialized,
58 static const GDebugKey gdk_debug_keys[] = {
59 {"misc", GDK_DEBUG_MISC},
60 {"events", GDK_DEBUG_EVENTS},
63 static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey);
65 #endif /* G_ENABLE_DEBUG */
67 GdkArgDesc _gdk_windowing_args[] = {
71 static const GScannerConfig fb_modes_scanner_config =
75 ) /* cset_skip_characters */,
79 ) /* cset_identifier_first */,
84 ) /* cset_identifier_nth */,
85 ( "#\n" ) /* cpair_comment_single */,
87 FALSE /* case_sensitive */,
89 FALSE /* skip_comment_multi */,
90 TRUE /* skip_comment_single */,
91 FALSE /* scan_comment_multi */,
92 TRUE /* scan_identifier */,
93 TRUE /* scan_identifier_1char */,
94 FALSE /* scan_identifier_NULL */,
95 TRUE /* scan_symbols */,
96 FALSE /* scan_binary */,
97 FALSE /* scan_octal */,
98 FALSE /* scan_float */,
100 FALSE /* scan_hex_dollar */,
101 FALSE /* scan_string_sq */,
102 TRUE /* scan_string_dq */,
103 TRUE /* numbers_2_int */,
104 FALSE /* int_2_float */,
105 FALSE /* identifier_2_string */,
106 TRUE /* char_2_token */,
107 FALSE /* symbol_2_token */,
108 FALSE /* scope_0_fallback */,
125 char *fb_modes_keywords[] =
141 fb_modes_parse_mode (GScanner *scanner,
142 struct fb_var_screeninfo *modeinfo,
143 char *specified_modename)
151 int vsync=0, hsync=0, csync=0, extsync=0, doublescan=0, laced=0, accel=1;
152 int found_geometry = 0;
153 int found_timings = 0;
155 token = g_scanner_get_next_token (scanner);
156 if (token != G_TOKEN_SYMBOL)
159 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
160 if (keyword != FB_MODE)
163 token = g_scanner_get_next_token (scanner);
164 if (token != G_TOKEN_STRING)
167 modename = g_strdup (scanner->value.v_string);
169 token = g_scanner_get_next_token (scanner);
170 if (token != G_TOKEN_SYMBOL)
173 return -1; /* Not a valid keyword */
175 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
176 while ( keyword != FB_ENDMODE )
179 switch (GPOINTER_TO_INT (scanner->value.v_symbol))
182 for (i = 0; i < 5;i++) {
183 token = g_scanner_get_next_token (scanner);
184 if (token != G_TOKEN_INT)
187 return -1; /* need a integer */
189 geometry[i] = scanner->value.v_int;
191 found_geometry = TRUE;
194 for (i = 0; i < 7; i++) {
195 token = g_scanner_get_next_token (scanner);
196 if (token != G_TOKEN_INT)
199 return -1; /* need a integer */
201 timings[i] = scanner->value.v_int;
203 found_timings = TRUE;
206 token = g_scanner_get_next_token (scanner);
207 if (token != G_TOKEN_IDENTIFIER)
212 if (g_ascii_strcasecmp (scanner->value.v_identifier, "true")==0)
214 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "false")==0)
223 token = g_scanner_get_next_token (scanner);
224 if (token != G_TOKEN_IDENTIFIER)
229 if (g_ascii_strcasecmp (scanner->value.v_identifier, "true")==0)
231 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "false")==0)
240 token = g_scanner_get_next_token (scanner);
241 if (token != G_TOKEN_IDENTIFIER)
246 if (g_ascii_strcasecmp (scanner->value.v_identifier, "true")==0)
248 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "false")==0)
257 token = g_scanner_get_next_token (scanner);
258 if (token != G_TOKEN_IDENTIFIER)
263 if (g_ascii_strcasecmp (scanner->value.v_identifier, "high")==0)
265 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "low")==0)
274 token = g_scanner_get_next_token (scanner);
275 if (token != G_TOKEN_IDENTIFIER)
280 if (g_ascii_strcasecmp (scanner->value.v_identifier, "high")==0)
282 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "low")==0)
291 token = g_scanner_get_next_token (scanner);
292 if (token != G_TOKEN_IDENTIFIER)
297 if (g_ascii_strcasecmp (scanner->value.v_identifier, "high")==0)
299 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "low")==0)
308 token = g_scanner_get_next_token (scanner);
309 if (token != G_TOKEN_IDENTIFIER)
314 if (g_ascii_strcasecmp (scanner->value.v_identifier, "false")==0)
316 else if (g_ascii_strcasecmp (scanner->value.v_identifier, "true")==0)
326 token = g_scanner_get_next_token (scanner);
327 if (token != G_TOKEN_SYMBOL)
330 return -1; /* Not a valid keyword */
332 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
335 if (strcmp (modename, specified_modename)== 0) {
337 g_warning ("Geometry not specified");
341 modeinfo->xres = geometry[0];
342 modeinfo->yres = geometry[1];
343 modeinfo->xres_virtual = geometry[2];
344 modeinfo->yres_virtual = geometry[3];
345 modeinfo->bits_per_pixel = geometry[4];
349 g_warning ("Timing not specified");
353 modeinfo->pixclock = timings[0];
354 modeinfo->left_margin = timings[1];
355 modeinfo->right_margin = timings[2];
356 modeinfo->upper_margin = timings[3];
357 modeinfo->lower_margin = timings[4];
358 modeinfo->hsync_len = timings[5];
359 modeinfo->vsync_len = timings[6];
363 modeinfo->vmode |= FB_VMODE_INTERLACED;
365 modeinfo->vmode |= FB_VMODE_DOUBLE;
369 modeinfo->sync |= FB_SYNC_HOR_HIGH_ACT;
371 modeinfo->sync |= FB_SYNC_VERT_HIGH_ACT;
373 modeinfo->accel_flags = FB_ACCELF_TEXT;
375 modeinfo->accel_flags = 0;
388 gdk_fb_setup_mode_from_name (struct fb_var_screeninfo *modeinfo,
399 filename = "/etc/fb.modes";
401 fd = open (filename, O_RDONLY);
404 g_warning ("Cannot read %s", filename);
408 scanner = g_scanner_new ((GScannerConfig *) &fb_modes_scanner_config);
409 scanner->input_name = filename;
411 for (i = 0; i < sizeof(fb_modes_keywords)/sizeof(fb_modes_keywords[0]); i++)
412 g_scanner_add_symbol (scanner, fb_modes_keywords[i], GINT_TO_POINTER (i));
414 g_scanner_input_file (scanner, fd);
417 if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF) {
420 result = fb_modes_parse_mode (scanner, modeinfo, modename);
423 g_warning ("parse error in %s at line %d", filename, scanner->line);
433 g_scanner_destroy (scanner);
442 gdk_fb_set_mode (GdkFBDisplay *display)
445 int depth, height, width;
448 if (ioctl (display->fb_fd, FBIOGET_VSCREENINFO, &display->modeinfo) < 0)
451 display->orig_modeinfo = display->modeinfo;
455 env = getenv ("GDK_DISPLAY_MODE");
458 if (gdk_fb_setup_mode_from_name (&display->modeinfo, env))
461 g_warning ("Couldn't find mode named '%s'", env);
464 env = getenv ("GDK_DISPLAY_DEPTH");
467 depth = strtol (env, &end, 10);
471 display->modeinfo.bits_per_pixel = depth;
475 env = getenv ("GDK_DISPLAY_WIDTH");
478 width = strtol (env, &end, 10);
482 display->modeinfo.xres = width;
483 display->modeinfo.xres_virtual = width;
487 env = getenv ("GDK_DISPLAY_HEIGHT");
490 height = strtol (env, &end, 10);
494 display->modeinfo.yres = height;
495 display->modeinfo.yres_virtual = height;
500 (ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->modeinfo) < 0))
502 g_warning ("Couldn't set specified mode");
506 if (ioctl (display->fb_fd, FBIOGET_FSCREENINFO, &display->sinfo) < 0)
508 g_warning ("Error getting fixed screen info");
514 #ifdef ENABLE_FB_MANAGER
516 gdk_fb_switch_from (void)
518 g_print ("Switch from\n");
519 gdk_shadow_fb_stop_updates ();
520 gdk_fb_mouse_close ();
521 gdk_fb_keyboard_close ();
525 gdk_fb_switch_to (void)
527 g_print ("switch_to\n");
528 gdk_shadow_fb_update (0, 0,
529 gdk_display->fb_width,
530 gdk_display->fb_height);
532 if (!gdk_fb_keyboard_open ())
533 g_warning ("Failed to re-initialize keyboard");
535 if (!gdk_fb_mouse_open ())
536 g_warning ("Failed to re-initialize mouse");
542 gdk_fb_manager_callback (GIOChannel *gioc,
546 struct FBManagerMessage msg;
547 GdkFBDisplay *display;
552 res = recv (display->manager_fd, &msg, sizeof (msg), 0);
556 g_source_remove (gdk_display->manager_tag);
557 /*g_io_channel_unref (kb->io);*/
558 close (gdk_display->manager_fd);
562 if (res != sizeof (msg))
564 g_warning ("Got wrong size message");
568 switch (msg.msg_type)
570 case FB_MANAGER_SWITCH_FROM:
571 g_print ("Got switch from message\n");
572 display->manager_blocked = TRUE;
573 gdk_fb_switch_from ();
574 msg.msg_type = FB_MANAGER_ACK;
575 send (display->manager_fd, &msg, sizeof (msg), 0);
577 case FB_MANAGER_SWITCH_TO:
578 g_print ("Got switch to message\n");
579 display->manager_blocked = FALSE;
583 g_warning ("Got unknown message");
588 #endif /* ENABLE_FB_MANAGER */
591 gdk_fb_manager_connect (GdkFBDisplay *display)
593 #ifdef ENABLE_FB_MANAGER
595 struct sockaddr_un addr;
596 struct msghdr msg = {0};
597 struct cmsghdr *cmsg;
598 struct ucred credentials;
599 struct FBManagerMessage init_msg;
601 char buf[CMSG_SPACE (sizeof (credentials))]; /* ancillary data buffer */
605 display->manager_blocked = FALSE;
606 display->manager_fd = -1;
608 fd = socket (PF_UNIX, SOCK_STREAM, 0);
610 g_print ("socket: %d\n", fd);
615 addr.sun_family = AF_UNIX;
616 strcpy (addr.sun_path, "/tmp/.fb.manager");
618 if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
620 g_print ("connect failed\n");
625 credentials.pid = getpid ();
626 credentials.uid = geteuid ();
627 credentials.gid = getegid ();
629 init_msg.msg_type = FB_MANAGER_NEW_CLIENT;
630 iov.iov_base = &init_msg;
631 iov.iov_len = sizeof (init_msg);
637 msg.msg_control = buf;
638 msg.msg_controllen = sizeof buf;
639 cmsg = CMSG_FIRSTHDR(&msg);
640 cmsg->cmsg_level = SOL_SOCKET;
641 cmsg->cmsg_type = SCM_CREDENTIALS;
642 cmsg->cmsg_len = CMSG_LEN (sizeof (credentials));
643 /* Initialize the payload: */
644 fdptr = (int *)CMSG_DATA (cmsg);
645 memcpy (fdptr, &credentials, sizeof (credentials));
646 /* Sum of the length of all control messages in the buffer: */
647 msg.msg_controllen = cmsg->cmsg_len;
649 res = sendmsg (fd, &msg, 0);
651 display->manager_fd = fd;
652 display->manager_blocked = TRUE;
654 display->manager_tag = g_io_add_watch (g_io_channel_unix_new (fd),
655 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
656 gdk_fb_manager_callback,
659 init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID;
660 init_msg.data = getpid ();
662 /* Request a switch-to */
663 send (fd, &init_msg, sizeof (init_msg), 0);
667 static GdkFBDisplay *
668 gdk_fb_display_new ()
670 GdkFBDisplay *display;
677 display = g_new0 (GdkFBDisplay, 1);
679 display->console_fd = open ("/dev/console", O_RDWR);
680 if (display->console_fd < 0)
682 g_warning ("Can't open /dev/console: %s", strerror (errno));
687 ioctl (display->console_fd, VT_GETSTATE, &vs);
688 display->start_vt = vs.v_active;
690 vt = display->start_vt;
691 s = getenv("GDK_VT");
694 if (g_ascii_strcasecmp ("new", s)==0)
696 n = ioctl (display->console_fd, VT_OPENQRY, &vt);
697 if (n < 0 || vt == -1)
698 g_error("Cannot allocate new VT");
702 vt = strtol (s, &send, 10);
705 g_warning ("Cannot parse GDK_VT");
706 vt = display->start_vt;
714 /* Switch to the new VT */
715 if (vt != display->start_vt)
717 ioctl (display->console_fd, VT_ACTIVATE, vt);
718 ioctl (display->console_fd, VT_WAITACTIVE, vt);
722 g_snprintf (buf, sizeof(buf), "/dev/tty%d", vt);
723 display->tty_fd = open (buf, O_RDWR|O_NONBLOCK);
724 if (display->tty_fd < 0)
726 g_warning ("Can't open %s: %s", buf, strerror (errno));
727 close (display->console_fd);
732 /* Set controlling tty */
733 ioctl (0, TIOCNOTTY, 0);
734 ioctl (display->tty_fd, TIOCSCTTY, 0);
736 fb_filename = gdk_get_display ();
737 display->fb_fd = open (fb_filename, O_RDWR);
738 if (display->fb_fd < 0)
740 g_warning ("Can't open %s: %s", fb_filename, strerror (errno));
741 g_free (fb_filename);
742 close (display->tty_fd);
743 close (display->console_fd);
747 g_free (fb_filename);
749 if (gdk_fb_set_mode (display) < 0)
751 close (display->fb_fd);
752 close (display->tty_fd);
753 close (display->console_fd);
758 /* Disable normal text on the console */
759 ioctl (display->fb_fd, KDSETMODE, KD_GRAPHICS);
761 ioctl (display->fb_fd, FBIOBLANK, 0);
763 /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */
764 display->fb_mmap = mmap (NULL,
765 display->modeinfo.yres * display->sinfo.line_length,
766 PROT_READ|PROT_WRITE,
770 g_assert (display->fb_mmap != MAP_FAILED);
772 if (display->sinfo.visual == FB_VISUAL_TRUECOLOR)
774 display->red_byte = display->modeinfo.red.offset >> 3;
775 display->green_byte = display->modeinfo.green.offset >> 3;
776 display->blue_byte = display->modeinfo.blue.offset >> 3;
779 #ifdef ENABLE_SHADOW_FB
780 if (_gdk_fb_screen_angle % 2 == 0)
782 display->fb_width = display->modeinfo.xres;
783 display->fb_height = display->modeinfo.yres;
787 display->fb_width = display->modeinfo.yres;
788 display->fb_height = display->modeinfo.xres;
791 display->fb_width * (display->modeinfo.bits_per_pixel / 8);
792 display->fb_mem = g_malloc(display->fb_height * display->fb_stride);
794 display->fb_mem = display->fb_mmap;
795 display->fb_width = display->modeinfo.xres;
796 display->fb_height = display->modeinfo.yres;
797 display->fb_stride = display->sinfo.line_length;
804 gdk_fb_display_destroy (GdkFBDisplay *display)
806 /* Restore old framebuffer mode */
807 ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->orig_modeinfo);
809 /* Enable normal text on the console */
810 ioctl (display->fb_fd, KDSETMODE, KD_TEXT);
812 munmap (display->fb_mmap, display->modeinfo.yres * display->sinfo.line_length);
813 close (display->fb_fd);
815 ioctl (display->console_fd, VT_ACTIVATE, display->start_vt);
816 ioctl (display->console_fd, VT_WAITACTIVE, display->start_vt);
817 if (display->vt != display->start_vt)
818 ioctl (display->console_fd, VT_DISALLOCATE, display->vt);
820 close (display->tty_fd);
821 close (display->console_fd);
826 _gdk_windowing_init (int *argc, char ***argv)
831 /* Create new session and become session leader */
834 gdk_display = gdk_fb_display_new ();
839 gdk_shadow_fb_init ();
841 gdk_fb_manager_connect (gdk_display);
843 if (!gdk_fb_keyboard_init (!gdk_display->manager_blocked))
845 g_warning ("Failed to initialize keyboard");
846 gdk_fb_display_destroy (gdk_display);
851 if (!gdk_fb_mouse_init (!gdk_display->manager_blocked))
853 g_warning ("Failed to initialize mouse");
854 gdk_fb_keyboard_close ();
855 gdk_fb_display_destroy (gdk_display);
860 /* Although atexit is evil, we need it here because otherwise the
861 * keyboard is left in a bad state. you can still run 'reset' but
862 * that gets annoying after running testgtk for the 20th time.
864 g_atexit(_gdk_windowing_exit);
866 gdk_initialized = TRUE;
868 _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
873 _gdk_windowing_set_default_display (GdkDisplay *display)
878 *--------------------------------------------------------------
881 * Grabs the pointer to a specific window
884 * "window" is the window which will receive the grab
885 * "owner_events" specifies whether events will be reported as is,
886 * or relative to "window"
887 * "event_mask" masks only interesting events
888 * "confine_to" limits the cursor movement to the specified window
889 * "cursor" changes the cursor for the duration of the grab
890 * "time" specifies the time
895 * requires a corresponding call to gdk_pointer_ungrab
897 *--------------------------------------------------------------
901 gdk_pointer_grab (GdkWindow * window,
903 GdkEventMask event_mask,
904 GdkWindow * confine_to,
908 return gdk_fb_pointer_grab (window,
916 static gboolean _gdk_fb_pointer_implicit_grab = FALSE;
919 gdk_fb_pointer_grab (GdkWindow * window,
921 GdkEventMask event_mask,
922 GdkWindow * confine_to,
925 gboolean implicit_grab)
927 g_return_val_if_fail (window != NULL, 0);
928 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
929 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
931 if (_gdk_fb_pointer_grab_window)
933 if (implicit_grab && !_gdk_fb_pointer_implicit_grab)
934 return GDK_GRAB_ALREADY_GRABBED;
936 gdk_pointer_ungrab (time);
939 gdk_fb_window_send_crossing_events (NULL,
943 if (event_mask & GDK_BUTTON_MOTION_MASK)
945 GDK_BUTTON1_MOTION_MASK |
946 GDK_BUTTON2_MOTION_MASK |
947 GDK_BUTTON3_MOTION_MASK;
949 _gdk_fb_pointer_implicit_grab = implicit_grab;
951 _gdk_fb_pointer_grab_window = gdk_window_ref (window);
952 _gdk_fb_pointer_grab_owner_events = owner_events;
954 _gdk_fb_pointer_grab_confine = confine_to ? gdk_window_ref (confine_to) : NULL;
955 _gdk_fb_pointer_grab_events = event_mask;
956 _gdk_fb_pointer_grab_cursor = cursor ? gdk_cursor_ref (cursor) : NULL;
961 gdk_fb_cursor_reset ();
963 return GDK_GRAB_SUCCESS;
967 *--------------------------------------------------------------
968 * gdk_display_pointer_ungrab
970 * Releases any pointer grab
978 *--------------------------------------------------------------
982 gdk_display_pointer_ungrab (GdkDisplay *display,
985 gdk_fb_pointer_ungrab (time, FALSE);
989 gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab)
991 gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1;
993 GdkWindow *old_grab_window;
995 if (!_gdk_fb_pointer_grab_window)
998 if (implicit_grab && !_gdk_fb_pointer_implicit_grab)
1001 if (_gdk_fb_pointer_grab_confine)
1002 gdk_window_unref (_gdk_fb_pointer_grab_confine);
1003 _gdk_fb_pointer_grab_confine = NULL;
1005 if (_gdk_fb_pointer_grab_cursor)
1006 gdk_cursor_unref (_gdk_fb_pointer_grab_cursor);
1007 _gdk_fb_pointer_grab_cursor = NULL;
1009 if (have_grab_cursor)
1010 gdk_fb_cursor_reset ();
1012 old_grab_window = _gdk_fb_pointer_grab_window;
1014 _gdk_fb_pointer_grab_window = NULL;
1016 _gdk_fb_pointer_implicit_grab = FALSE;
1018 mousewin = gdk_window_at_pointer (NULL, NULL);
1019 gdk_fb_window_send_crossing_events (old_grab_window,
1021 GDK_CROSSING_UNGRAB);
1023 if (old_grab_window)
1024 gdk_window_unref (old_grab_window);
1028 *--------------------------------------------------------------
1029 * gdk_display_pointer_is_grabbed
1031 * Tell wether there is an active x pointer grab in effect
1039 *--------------------------------------------------------------
1043 gdk_display_pointer_is_grabbed (GdkDisplay *display)
1045 return _gdk_fb_pointer_grab_window != NULL;
1049 *--------------------------------------------------------------
1052 * Grabs the keyboard to a specific window
1055 * "window" is the window which will receive the grab
1056 * "owner_events" specifies whether events will be reported as is,
1057 * or relative to "window"
1058 * "time" specifies the time
1063 * requires a corresponding call to gdk_keyboard_ungrab
1065 *--------------------------------------------------------------
1069 gdk_keyboard_grab (GdkWindow *window,
1073 g_return_val_if_fail (window != NULL, 0);
1074 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1076 if (_gdk_fb_pointer_grab_window)
1077 gdk_keyboard_ungrab (time);
1079 _gdk_fb_keyboard_grab_window = gdk_window_ref (window);
1080 _gdk_fb_keyboard_grab_owner_events = owner_events;
1082 return GDK_GRAB_SUCCESS;
1086 *--------------------------------------------------------------
1087 * gdk_display_keyboard_ungrab
1089 * Releases any keyboard grab
1097 *--------------------------------------------------------------
1101 gdk_display_keyboard_ungrab (GdkDisplay *display,
1104 if (_gdk_fb_keyboard_grab_window)
1105 gdk_window_unref (_gdk_fb_keyboard_grab_window);
1106 _gdk_fb_keyboard_grab_window = NULL;
1110 gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
1111 GdkWindow **grab_window,
1112 gboolean *owner_events)
1114 if (_gdk_fb_pointer_grab_window)
1117 *grab_window = (GdkWindow *)_gdk_fb_pointer_grab_window;
1119 *owner_events = _gdk_fb_pointer_grab_owner_events;
1128 gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
1129 GdkWindow **grab_window,
1130 gboolean *owner_events)
1132 if (_gdk_fb_keyboard_grab_window)
1135 *grab_window = (GdkWindow *)_gdk_fb_keyboard_grab_window;
1137 *owner_events = _gdk_fb_keyboard_grab_owner_events;
1147 *--------------------------------------------------------------
1148 * gdk_screen_get_width
1150 * Return the width of the screen.
1158 *--------------------------------------------------------------
1162 gdk_screen_get_width (GdkScreen *screen)
1164 return gdk_display->fb_width;
1168 *--------------------------------------------------------------
1169 * gdk_screen_get_height
1171 * Return the height of the screen.
1179 *--------------------------------------------------------------
1183 gdk_screen_get_height (GdkScreen *screen)
1185 return gdk_display->fb_height;
1189 *--------------------------------------------------------------
1190 * gdk_screen_get_width_mm
1192 * Return the width of the screen in millimeters.
1200 *--------------------------------------------------------------
1204 gdk_screen_get_width_mm (GdkScreen *screen)
1206 return 0.5 + gdk_screen_width () * (25.4 / 72.);
1210 *--------------------------------------------------------------
1211 * gdk_screen_get_height_mm
1213 * Return the height of the screen in millimeters.
1221 *--------------------------------------------------------------
1225 gdk_screen_get_height_mm (GdkScreen *screen)
1227 return 0.5 + gdk_screen_height () * (25.4 / 72.);
1231 _gdk_windowing_display_set_sm_client_id (GdkDisplay* display,
1232 const gchar* sm_client_id)
1236 extern void keyboard_shutdown(void);
1239 _gdk_windowing_exit (void)
1242 gdk_fb_mouse_close ();
1243 /*leak g_free (gdk_fb_mouse);*/
1245 gdk_fb_keyboard_close ();
1246 /*leak g_free (gdk_fb_keyboard);*/
1248 gdk_fb_display_destroy (gdk_display);
1254 gdk_get_display(void)
1258 s = getenv ("GDK_DISPLAY");
1262 return g_strdup (s);
1266 gdk_display_beep (GdkDisplay *display)
1268 static int pitch = 600, duration = 100;
1271 /* Thank you XFree86 */
1272 arg = ((1193190 / pitch) & 0xffff) |
1273 (((unsigned long)duration) << 16);
1275 ioctl (gdk_display->tty_fd, KDMKTONE, arg);
1279 static const guint type_masks[] = {
1280 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0, */
1281 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1, */
1282 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2, */
1283 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3, */
1284 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4, */
1285 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5, */
1286 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6, */
1287 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7, */
1288 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8, */
1289 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9, */
1290 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10, */
1291 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11, */
1292 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12, */
1293 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13, */
1294 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14, */
1295 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15, */
1296 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16, */
1297 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17, */
1298 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18, */
1299 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19, */
1300 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20, */
1301 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21, */
1302 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22, */
1303 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23, */
1304 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24, */
1305 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25, */
1306 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26, */
1307 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27, */
1308 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28, */
1309 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29, */
1310 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30, */
1311 GDK_SCROLL_MASK /* GDK_SCROLL = 31 */
1315 gdk_fb_other_event_window (GdkWindow *window,
1322 while (w != _gdk_parent_root)
1324 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1325 if ((w != window) &&
1326 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1327 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1330 evmask = GDK_WINDOW_OBJECT(window)->event_mask;
1332 if (evmask & type_masks[type])
1335 w = gdk_window_get_parent (w);
1342 gdk_fb_pointer_event_window (GdkWindow *window,
1346 GdkModifierType mask;
1349 gdk_fb_mouse_get_info (NULL, NULL, &mask);
1351 if (_gdk_fb_pointer_grab_window &&
1352 !_gdk_fb_pointer_grab_owner_events)
1354 evmask = _gdk_fb_pointer_grab_events;
1356 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1358 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1359 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1360 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1361 evmask |= GDK_POINTER_MOTION_MASK;
1364 if (evmask & type_masks[type])
1365 return _gdk_fb_pointer_grab_window;
1371 while (w != _gdk_parent_root)
1373 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1374 if ((w != window) &&
1375 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1376 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1379 evmask = GDK_WINDOW_OBJECT(window)->event_mask;
1381 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1383 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1384 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1385 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1386 evmask |= GDK_POINTER_MOTION_MASK;
1389 if (evmask & type_masks[type])
1392 w = gdk_window_get_parent (w);
1395 if (_gdk_fb_pointer_grab_window &&
1396 _gdk_fb_pointer_grab_owner_events)
1398 evmask = _gdk_fb_pointer_grab_events;
1400 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1402 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1403 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1404 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1405 evmask |= GDK_POINTER_MOTION_MASK;
1408 if (evmask & type_masks[type])
1409 return _gdk_fb_pointer_grab_window;
1416 gdk_fb_keyboard_event_window (GdkWindow *window,
1422 if (_gdk_fb_keyboard_grab_window &&
1423 !_gdk_fb_keyboard_grab_owner_events)
1425 return _gdk_fb_keyboard_grab_window;
1429 while (w != _gdk_parent_root)
1431 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1432 if ((w != window) &&
1433 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1434 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1437 evmask = GDK_WINDOW_OBJECT(window)->event_mask;
1439 if (evmask & type_masks[type])
1442 w = gdk_window_get_parent (w);
1445 if (_gdk_fb_keyboard_grab_window &&
1446 _gdk_fb_keyboard_grab_owner_events)
1448 return _gdk_fb_keyboard_grab_window;
1455 gdk_event_make (GdkWindow *window,
1457 gboolean append_to_queue)
1459 GdkEvent *event = _gdk_event_new ();
1462 the_time = gdk_fb_get_time ();
1464 event->any.type = type;
1465 event->any.window = gdk_window_ref (window);
1466 event->any.send_event = FALSE;
1469 case GDK_MOTION_NOTIFY:
1470 event->motion.time = the_time;
1471 event->motion.axes = NULL;
1473 case GDK_BUTTON_PRESS:
1474 case GDK_2BUTTON_PRESS:
1475 case GDK_3BUTTON_PRESS:
1476 case GDK_BUTTON_RELEASE:
1477 event->button.time = the_time;
1478 event->button.axes = NULL;
1481 case GDK_KEY_RELEASE:
1482 event->key.time = the_time;
1484 case GDK_ENTER_NOTIFY:
1485 case GDK_LEAVE_NOTIFY:
1486 event->crossing.time = the_time;
1489 case GDK_PROPERTY_NOTIFY:
1490 event->property.time = the_time;
1493 case GDK_SELECTION_CLEAR:
1494 case GDK_SELECTION_REQUEST:
1495 case GDK_SELECTION_NOTIFY:
1496 event->selection.time = the_time;
1498 case GDK_PROXIMITY_IN:
1499 case GDK_PROXIMITY_OUT:
1500 event->proximity.time = the_time;
1502 case GDK_DRAG_ENTER:
1503 case GDK_DRAG_LEAVE:
1504 case GDK_DRAG_MOTION:
1505 case GDK_DRAG_STATUS:
1506 case GDK_DROP_START:
1507 case GDK_DROP_FINISHED:
1508 event->dnd.time = the_time;
1511 case GDK_FOCUS_CHANGE:
1515 case GDK_CLIENT_EVENT:
1516 case GDK_VISIBILITY_NOTIFY:
1526 if (append_to_queue)
1527 _gdk_event_queue_append (gdk_display_get_default (), event);
1533 gdk_fb_set_rotation (GdkFBAngle angle)
1535 if (angle == _gdk_fb_screen_angle)
1538 #ifdef ENABLE_SHADOW_FB
1541 gdk_shadow_fb_stop_updates ();
1543 gdk_fb_cursor_hide ();
1545 _gdk_fb_screen_angle = angle;
1549 gdk_display->fb_width = gdk_display->modeinfo.xres;
1550 gdk_display->fb_height = gdk_display->modeinfo.yres;
1554 gdk_display->fb_width = gdk_display->modeinfo.yres;
1555 gdk_display->fb_height = gdk_display->modeinfo.xres;
1557 gdk_display->fb_stride =
1558 gdk_display->fb_width * (gdk_display->modeinfo.bits_per_pixel / 8);
1560 gdk_fb_recompute_all();
1561 gdk_fb_redraw_all ();
1563 gdk_fb_cursor_unhide ();
1566 _gdk_fb_screen_angle = angle;
1568 g_warning ("Screen rotation without shadow fb not supported.");
1573 gdk_error_trap_push (void)
1578 gdk_error_trap_pop (void)