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 */,
124 char *fb_modes_keywords[] =
139 fb_modes_parse_mode (GScanner *scanner,
140 struct fb_var_screeninfo *modeinfo,
141 char *specified_modename)
149 int vsync=0, hsync=0, csync=0, extsync=0, doublescan=0, laced=0;
150 int found_geometry = 0;
151 int found_timings = 0;
153 token = g_scanner_get_next_token (scanner);
154 if (token != G_TOKEN_SYMBOL)
157 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
158 if (keyword != FB_MODE)
161 token = g_scanner_get_next_token (scanner);
162 if (token != G_TOKEN_STRING)
165 modename = g_strdup (scanner->value.v_string);
167 token = g_scanner_get_next_token (scanner);
168 if (token != G_TOKEN_SYMBOL)
171 return -1; /* Not a valid keyword */
173 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
174 while ( keyword != FB_ENDMODE )
177 switch (GPOINTER_TO_INT (scanner->value.v_symbol))
180 for (i = 0; i < 5;i++) {
181 token = g_scanner_get_next_token (scanner);
182 if (token != G_TOKEN_INT)
185 return -1; /* need a integer */
187 geometry[i] = scanner->value.v_int;
189 found_geometry = TRUE;
192 for (i = 0; i < 7; i++) {
193 token = g_scanner_get_next_token (scanner);
194 if (token != G_TOKEN_INT)
197 return -1; /* need a integer */
199 timings[i] = scanner->value.v_int;
201 found_timings = TRUE;
204 token = g_scanner_get_next_token (scanner);
205 if (token != G_TOKEN_IDENTIFIER)
210 if (g_strcasecmp (scanner->value.v_identifier, "true")==0)
212 else if (g_strcasecmp (scanner->value.v_identifier, "false")==0)
221 token = g_scanner_get_next_token (scanner);
222 if (token != G_TOKEN_IDENTIFIER)
227 if (g_strcasecmp (scanner->value.v_identifier, "true")==0)
229 else if (g_strcasecmp (scanner->value.v_identifier, "false")==0)
238 token = g_scanner_get_next_token (scanner);
239 if (token != G_TOKEN_IDENTIFIER)
244 if (g_strcasecmp (scanner->value.v_identifier, "true")==0)
246 else if (g_strcasecmp (scanner->value.v_identifier, "false")==0)
255 token = g_scanner_get_next_token (scanner);
256 if (token != G_TOKEN_IDENTIFIER)
261 if (g_strcasecmp (scanner->value.v_identifier, "high")==0)
263 else if (g_strcasecmp (scanner->value.v_identifier, "low")==0)
272 token = g_scanner_get_next_token (scanner);
273 if (token != G_TOKEN_IDENTIFIER)
278 if (g_strcasecmp (scanner->value.v_identifier, "high")==0)
280 else if (g_strcasecmp (scanner->value.v_identifier, "low")==0)
289 token = g_scanner_get_next_token (scanner);
290 if (token != G_TOKEN_IDENTIFIER)
295 if (g_strcasecmp (scanner->value.v_identifier, "high")==0)
297 else if (g_strcasecmp (scanner->value.v_identifier, "low")==0)
307 token = g_scanner_get_next_token (scanner);
308 if (token != G_TOKEN_SYMBOL)
311 return -1; /* Not a valid keyword */
313 keyword = GPOINTER_TO_INT (scanner->value.v_symbol);
316 if (strcmp (modename, specified_modename)== 0) {
318 g_warning ("Geometry not specified");
322 modeinfo->xres = geometry[0];
323 modeinfo->yres = geometry[1];
324 modeinfo->xres_virtual = geometry[2];
325 modeinfo->yres_virtual = geometry[3];
326 modeinfo->bits_per_pixel = geometry[4];
330 g_warning ("Timing not specified");
334 modeinfo->pixclock = timings[0];
335 modeinfo->left_margin = timings[1];
336 modeinfo->right_margin = timings[2];
337 modeinfo->upper_margin = timings[3];
338 modeinfo->lower_margin = timings[4];
339 modeinfo->hsync_len = timings[5];
340 modeinfo->vsync_len = timings[6];
344 modeinfo->vmode |= FB_VMODE_INTERLACED;
346 modeinfo->vmode |= FB_VMODE_DOUBLE;
350 modeinfo->sync |= FB_SYNC_HOR_HIGH_ACT;
352 modeinfo->sync |= FB_SYNC_VERT_HIGH_ACT;
365 gdk_fb_setup_mode_from_name (struct fb_var_screeninfo *modeinfo,
376 filename = "/etc/fb.modes";
378 fd = open (filename, O_RDONLY);
381 g_warning ("Cannot read %s", filename);
385 scanner = g_scanner_new ((GScannerConfig *) &fb_modes_scanner_config);
386 scanner->input_name = filename;
388 for (i = 0; i < sizeof(fb_modes_keywords)/sizeof(fb_modes_keywords[0]); i++)
389 g_scanner_add_symbol (scanner, fb_modes_keywords[i], GINT_TO_POINTER (i));
391 g_scanner_input_file (scanner, fd);
394 if (g_scanner_peek_next_token (scanner) == G_TOKEN_EOF) {
397 result = fb_modes_parse_mode (scanner, modeinfo, modename);
400 g_warning ("parse error in %s at line %d", filename, scanner->line);
410 g_scanner_destroy (scanner);
419 gdk_fb_set_mode (GdkFBDisplay *display)
422 int depth, height, width;
425 if (ioctl (display->fb_fd, FBIOGET_VSCREENINFO, &display->modeinfo) < 0)
428 display->orig_modeinfo = display->modeinfo;
432 env = getenv ("GDK_DISPLAY_MODE");
435 if (gdk_fb_setup_mode_from_name (&display->modeinfo, env))
438 g_warning ("Couldn't find mode named '%s'", env);
441 env = getenv ("GDK_DISPLAY_DEPTH");
444 depth = strtol (env, &end, 10);
448 display->modeinfo.bits_per_pixel = depth;
452 env = getenv ("GDK_DISPLAY_WIDTH");
455 width = strtol (env, &end, 10);
459 display->modeinfo.xres = width;
460 display->modeinfo.xres_virtual = width;
464 env = getenv ("GDK_DISPLAY_HEIGHT");
467 height = strtol (env, &end, 10);
471 display->modeinfo.yres = height;
472 display->modeinfo.yres_virtual = height;
477 (ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->modeinfo) < 0))
479 g_warning ("Couldn't set specified mode");
483 if (ioctl (display->fb_fd, FBIOGET_FSCREENINFO, &display->sinfo) < 0)
485 g_warning ("Error getting fixed screen info");
491 #ifdef ENABLE_FB_MANAGER
493 gdk_fb_switch_from (void)
495 g_print ("Switch from\n");
496 gdk_shadow_fb_stop_updates ();
497 gdk_fb_mouse_close ();
498 gdk_fb_keyboard_close ();
502 gdk_fb_switch_to (void)
504 g_print ("switch_to\n");
505 gdk_shadow_fb_update (0, 0,
506 gdk_display->fb_width,
507 gdk_display->fb_height);
509 if (!gdk_fb_keyboard_open ())
510 g_warning ("Failed to re-initialize keyboard");
512 if (!gdk_fb_mouse_open ())
513 g_warning ("Failed to re-initialize mouse");
519 gdk_fb_manager_callback (GIOChannel *gioc,
523 struct FBManagerMessage msg;
524 GdkFBDisplay *display;
529 res = recv (display->manager_fd, &msg, sizeof (msg), 0);
533 g_source_remove (gdk_display->manager_tag);
534 /*g_io_channel_unref (kb->io);*/
535 close (gdk_display->manager_fd);
539 if (res != sizeof (msg))
541 g_warning ("Got wrong size message");
545 switch (msg.msg_type)
547 case FB_MANAGER_SWITCH_FROM:
548 g_print ("Got switch from message\n");
549 display->manager_blocked = TRUE;
550 gdk_fb_switch_from ();
551 msg.msg_type = FB_MANAGER_ACK;
552 send (display->manager_fd, &msg, sizeof (msg), 0);
554 case FB_MANAGER_SWITCH_TO:
555 g_print ("Got switch to message\n");
556 display->manager_blocked = FALSE;
560 g_warning ("Got unknown message");
565 #endif /* ENABLE_FB_MANAGER */
568 gdk_fb_manager_connect (GdkFBDisplay *display)
571 struct sockaddr_un addr;
572 struct msghdr msg = {0};
573 struct cmsghdr *cmsg;
574 struct ucred credentials;
575 struct FBManagerMessage init_msg;
577 char buf[CMSG_SPACE (sizeof (credentials))]; /* ancillary data buffer */
581 display->manager_blocked = FALSE;
582 display->manager_fd = -1;
584 #ifdef ENABLE_FB_MANAGER
585 fd = socket (PF_UNIX, SOCK_STREAM, 0);
587 g_print ("socket: %d\n", fd);
592 addr.sun_family = AF_UNIX;
593 strcpy (addr.sun_path, "/tmp/.fb.manager");
595 if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
597 g_print ("connect failed\n");
602 credentials.pid = getpid ();
603 credentials.uid = geteuid ();
604 credentials.gid = getegid ();
606 init_msg.msg_type = FB_MANAGER_NEW_CLIENT;
607 iov.iov_base = &init_msg;
608 iov.iov_len = sizeof (init_msg);
614 msg.msg_control = buf;
615 msg.msg_controllen = sizeof buf;
616 cmsg = CMSG_FIRSTHDR(&msg);
617 cmsg->cmsg_level = SOL_SOCKET;
618 cmsg->cmsg_type = SCM_CREDENTIALS;
619 cmsg->cmsg_len = CMSG_LEN (sizeof (credentials));
620 /* Initialize the payload: */
621 fdptr = (int *)CMSG_DATA (cmsg);
622 memcpy (fdptr, &credentials, sizeof (credentials));
623 /* Sum of the length of all control messages in the buffer: */
624 msg.msg_controllen = cmsg->cmsg_len;
626 res = sendmsg (fd, &msg, 0);
628 display->manager_fd = fd;
629 display->manager_blocked = TRUE;
631 display->manager_tag = g_io_add_watch (g_io_channel_unix_new (fd),
632 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
633 gdk_fb_manager_callback,
636 init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID;
637 init_msg.data = getpid ();
639 /* Request a switch-to */
640 send (fd, &init_msg, sizeof (init_msg), 0);
644 static GdkFBDisplay *
645 gdk_fb_display_new ()
647 GdkFBDisplay *display;
654 display = g_new0 (GdkFBDisplay, 1);
656 display->console_fd = open ("/dev/console", O_RDWR);
657 if (display->console_fd < 0)
659 g_warning ("Can't open /dev/console: %s", strerror (errno));
664 ioctl (display->console_fd, VT_GETSTATE, &vs);
665 display->start_vt = vs.v_active;
667 vt = display->start_vt;
668 s = getenv("GDK_VT");
671 if (g_strcasecmp ("new", s)==0)
673 n = ioctl (display->console_fd, VT_OPENQRY, &vt);
674 if (n < 0 || vt == -1)
675 g_error("Cannot allocate new VT");
679 vt = strtol (s, &send, 10);
682 g_warning ("Cannot parse GDK_VT");
683 vt = display->start_vt;
691 /* Switch to the new VT */
692 if (vt != display->start_vt)
694 ioctl (display->console_fd, VT_ACTIVATE, vt);
695 ioctl (display->console_fd, VT_WAITACTIVE, vt);
699 g_snprintf (buf, sizeof(buf), "/dev/tty%d", vt);
700 display->tty_fd = open (buf, O_RDWR|O_NONBLOCK);
701 if (display->tty_fd < 0)
703 g_warning ("Can't open %s: %s", buf, strerror (errno));
704 close (display->console_fd);
709 /* Set controlling tty */
710 ioctl (0, TIOCNOTTY, 0);
711 ioctl (display->tty_fd, TIOCSCTTY, 0);
713 fb_filename = gdk_get_display ();
714 display->fb_fd = open (fb_filename, O_RDWR);
715 if (display->fb_fd < 0)
717 g_warning ("Can't open %s: %s", fb_filename, strerror (errno));
718 g_free (fb_filename);
719 close (display->tty_fd);
720 close (display->console_fd);
724 g_free (fb_filename);
726 if (gdk_fb_set_mode (display) < 0)
728 close (display->fb_fd);
729 close (display->tty_fd);
730 close (display->console_fd);
735 /* Disable normal text on the console */
736 ioctl (display->fb_fd, KDSETMODE, KD_GRAPHICS);
738 ioctl (display->fb_fd, FBIOBLANK, 0);
740 /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */
741 display->fb_mmap = mmap (NULL,
742 display->modeinfo.yres * display->sinfo.line_length,
743 PROT_READ|PROT_WRITE,
747 g_assert (display->fb_mmap != MAP_FAILED);
749 if (display->sinfo.visual == FB_VISUAL_TRUECOLOR)
751 display->red_byte = display->modeinfo.red.offset >> 3;
752 display->green_byte = display->modeinfo.green.offset >> 3;
753 display->blue_byte = display->modeinfo.blue.offset >> 3;
756 #ifdef ENABLE_SHADOW_FB
757 if (_gdk_fb_screen_angle % 2 == 0)
759 display->fb_width = display->modeinfo.xres;
760 display->fb_height = display->modeinfo.yres;
764 display->fb_width = display->modeinfo.yres;
765 display->fb_height = display->modeinfo.xres;
768 display->fb_width * (display->modeinfo.bits_per_pixel / 8);
769 display->fb_mem = g_malloc(display->fb_height * display->fb_stride);
771 display->fb_mem = display->fb_mmap;
772 display->fb_width = display->modeinfo.xres;
773 display->fb_height = display->modeinfo.yres;
774 display->fb_stride = display->sinfo.line_length;
781 gdk_fb_display_destroy (GdkFBDisplay *display)
783 /* Restore old framebuffer mode */
784 ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->orig_modeinfo);
786 /* Enable normal text on the console */
787 ioctl (display->fb_fd, KDSETMODE, KD_TEXT);
789 munmap (display->fb_mmap, display->modeinfo.yres * display->sinfo.line_length);
790 close (display->fb_fd);
792 ioctl (display->console_fd, VT_ACTIVATE, display->start_vt);
793 ioctl (display->console_fd, VT_WAITACTIVE, display->start_vt);
794 if (display->vt != display->start_vt)
795 ioctl (display->console_fd, VT_DISALLOCATE, display->vt);
797 close (display->tty_fd);
798 close (display->console_fd);
803 _gdk_windowing_init_check (int argc, char **argv)
808 /* Create new session and become session leader */
811 gdk_display = gdk_fb_display_new ();
816 gdk_shadow_fb_init ();
818 gdk_fb_manager_connect (gdk_display);
820 if (!gdk_fb_keyboard_init (!gdk_display->manager_blocked))
822 g_warning ("Failed to initialize keyboard");
823 gdk_fb_display_destroy (gdk_display);
828 if (!gdk_fb_mouse_init (!gdk_display->manager_blocked))
830 g_warning ("Failed to initialize mouse");
831 gdk_fb_keyboard_close ();
832 gdk_fb_display_destroy (gdk_display);
837 gdk_initialized = TRUE;
839 gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
846 *--------------------------------------------------------------
849 * Grabs the pointer to a specific window
852 * "window" is the window which will receive the grab
853 * "owner_events" specifies whether events will be reported as is,
854 * or relative to "window"
855 * "event_mask" masks only interesting events
856 * "confine_to" limits the cursor movement to the specified window
857 * "cursor" changes the cursor for the duration of the grab
858 * "time" specifies the time
863 * requires a corresponding call to gdk_pointer_ungrab
865 *--------------------------------------------------------------
869 gdk_pointer_grab (GdkWindow * window,
871 GdkEventMask event_mask,
872 GdkWindow * confine_to,
876 return gdk_fb_pointer_grab (window,
884 static gboolean _gdk_fb_pointer_implicit_grab = FALSE;
887 gdk_fb_pointer_grab (GdkWindow * window,
889 GdkEventMask event_mask,
890 GdkWindow * confine_to,
893 gboolean implicit_grab)
895 g_return_val_if_fail (window != NULL, 0);
896 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
897 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
899 if (_gdk_fb_pointer_grab_window)
901 if (implicit_grab && !_gdk_fb_pointer_implicit_grab)
902 return GDK_GRAB_ALREADY_GRABBED;
904 gdk_pointer_ungrab (time);
907 gdk_fb_window_send_crossing_events (NULL,
911 if (event_mask & GDK_BUTTON_MOTION_MASK)
913 GDK_BUTTON1_MOTION_MASK |
914 GDK_BUTTON2_MOTION_MASK |
915 GDK_BUTTON3_MOTION_MASK;
917 _gdk_fb_pointer_implicit_grab = implicit_grab;
919 _gdk_fb_pointer_grab_window = gdk_window_ref (window);
920 _gdk_fb_pointer_grab_owner_events = owner_events;
922 _gdk_fb_pointer_grab_confine = confine_to ? gdk_window_ref (confine_to) : NULL;
923 _gdk_fb_pointer_grab_events = event_mask;
924 _gdk_fb_pointer_grab_cursor = cursor ? gdk_cursor_ref (cursor) : NULL;
929 gdk_fb_cursor_reset ();
931 return GDK_GRAB_SUCCESS;
935 *--------------------------------------------------------------
938 * Releases any pointer grab
946 *--------------------------------------------------------------
950 gdk_pointer_ungrab (guint32 time)
952 gdk_fb_pointer_ungrab (time, FALSE);
956 gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab)
958 gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1;
960 GdkWindow *old_grab_window;
962 if (!_gdk_fb_pointer_grab_window)
965 if (implicit_grab && !_gdk_fb_pointer_implicit_grab)
968 if (_gdk_fb_pointer_grab_confine)
969 gdk_window_unref (_gdk_fb_pointer_grab_confine);
970 _gdk_fb_pointer_grab_confine = NULL;
972 if (_gdk_fb_pointer_grab_cursor)
973 gdk_cursor_unref (_gdk_fb_pointer_grab_cursor);
974 _gdk_fb_pointer_grab_cursor = NULL;
976 if (have_grab_cursor)
977 gdk_fb_cursor_reset ();
979 old_grab_window = _gdk_fb_pointer_grab_window;
981 _gdk_fb_pointer_grab_window = NULL;
983 _gdk_fb_pointer_implicit_grab = FALSE;
985 mousewin = gdk_window_at_pointer (NULL, NULL);
986 gdk_fb_window_send_crossing_events (old_grab_window,
988 GDK_CROSSING_UNGRAB);
991 gdk_window_unref (old_grab_window);
995 *--------------------------------------------------------------
996 * gdk_pointer_is_grabbed
998 * Tell wether there is an active x pointer grab in effect
1006 *--------------------------------------------------------------
1010 gdk_pointer_is_grabbed (void)
1012 return _gdk_fb_pointer_grab_window != NULL;
1016 *--------------------------------------------------------------
1019 * Grabs the keyboard to a specific window
1022 * "window" is the window which will receive the grab
1023 * "owner_events" specifies whether events will be reported as is,
1024 * or relative to "window"
1025 * "time" specifies the time
1030 * requires a corresponding call to gdk_keyboard_ungrab
1032 *--------------------------------------------------------------
1036 gdk_keyboard_grab (GdkWindow * window,
1040 g_return_val_if_fail (window != NULL, 0);
1041 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1043 if (_gdk_fb_pointer_grab_window)
1044 gdk_keyboard_ungrab (time);
1046 _gdk_fb_keyboard_grab_window = gdk_window_ref (window);
1047 _gdk_fb_keyboard_grab_owner_events = owner_events;
1049 return GDK_GRAB_SUCCESS;
1053 *--------------------------------------------------------------
1054 * gdk_keyboard_ungrab
1056 * Releases any keyboard grab
1064 *--------------------------------------------------------------
1068 gdk_keyboard_ungrab (guint32 time)
1070 if (_gdk_fb_keyboard_grab_window)
1071 gdk_window_unref (_gdk_fb_keyboard_grab_window);
1072 _gdk_fb_keyboard_grab_window = NULL;
1076 *--------------------------------------------------------------
1079 * Return the width of the screen.
1087 *--------------------------------------------------------------
1091 gdk_screen_width (void)
1093 return gdk_display->fb_width;
1097 *--------------------------------------------------------------
1100 * Return the height of the screen.
1108 *--------------------------------------------------------------
1112 gdk_screen_height (void)
1114 return gdk_display->fb_height;
1118 *--------------------------------------------------------------
1119 * gdk_screen_width_mm
1121 * Return the width of the screen in millimeters.
1129 *--------------------------------------------------------------
1133 gdk_screen_width_mm (void)
1135 return 0.5 + gdk_screen_width () * (25.4 / 72.);
1139 *--------------------------------------------------------------
1142 * Return the height of the screen in millimeters.
1150 *--------------------------------------------------------------
1154 gdk_screen_height_mm (void)
1156 return 0.5 + gdk_screen_height () * (25.4 / 72.);
1160 *--------------------------------------------------------------
1161 * gdk_set_sm_client_id
1163 * Set the SM_CLIENT_ID property on the WM_CLIENT_LEADER window
1164 * so that the window manager can save our state using the
1165 * X11R6 ICCCM session management protocol. A NULL value should
1166 * be set following disconnection from the session manager to
1167 * remove the SM_CLIENT_ID property.
1171 * "sm_client_id" specifies the client id assigned to us by the
1172 * session manager or NULL to remove the property.
1178 *--------------------------------------------------------------
1182 gdk_set_sm_client_id (const gchar* sm_client_id)
1187 gdk_key_repeat_disable (void)
1192 gdk_key_repeat_restore (void)
1197 extern void keyboard_shutdown(void);
1200 gdk_windowing_exit (void)
1203 gdk_fb_mouse_close ();
1204 /*leak g_free (gdk_fb_mouse);*/
1206 gdk_fb_keyboard_close ();
1207 /*leak g_free (gdk_fb_keyboard);*/
1209 gdk_fb_display_destroy (gdk_display);
1215 gdk_keyval_name (guint keyval)
1221 gdk_keyval_from_name (const gchar *keyval_name)
1227 gdk_get_display(void)
1231 s = getenv ("GDK_DISPLAY");
1235 return g_strdup (s);
1242 static int pitch = 600, duration = 100;
1245 /* Thank you XFree86 */
1246 arg = ((1193190 / pitch) & 0xffff) |
1247 (((unsigned long)duration) << 16);
1249 ioctl (gdk_display->tty_fd, KDMKTONE, arg);
1253 static const guint type_masks[] = {
1254 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0, */
1255 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1, */
1256 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2, */
1257 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3, */
1258 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4, */
1259 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5, */
1260 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6, */
1261 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7, */
1262 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8, */
1263 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9, */
1264 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10, */
1265 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11, */
1266 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12, */
1267 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13, */
1268 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14, */
1269 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15, */
1270 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16, */
1271 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17, */
1272 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18, */
1273 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19, */
1274 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20, */
1275 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21, */
1276 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22, */
1277 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23, */
1278 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24, */
1279 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25, */
1280 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26, */
1281 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27, */
1282 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28, */
1283 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29, */
1284 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30, */
1285 GDK_SCROLL_MASK /* GDK_SCROLL = 31 */
1289 gdk_fb_other_event_window (GdkWindow *window,
1296 while (w != gdk_parent_root)
1298 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1299 if ((w != window) &&
1300 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1301 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1304 evmask = GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
1306 if (evmask & type_masks[type])
1309 w = gdk_window_get_parent (w);
1316 gdk_fb_pointer_event_window (GdkWindow *window,
1320 GdkModifierType mask;
1323 gdk_fb_mouse_get_info (NULL, NULL, &mask);
1325 if (_gdk_fb_pointer_grab_window &&
1326 !_gdk_fb_pointer_grab_owner_events)
1328 evmask = _gdk_fb_pointer_grab_events;
1330 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1332 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1333 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1334 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1335 evmask |= GDK_POINTER_MOTION_MASK;
1338 if (evmask & type_masks[type])
1339 return _gdk_fb_pointer_grab_window;
1345 while (w != gdk_parent_root)
1347 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1348 if ((w != window) &&
1349 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1350 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1353 evmask = GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
1355 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1357 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1358 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1359 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1360 evmask |= GDK_POINTER_MOTION_MASK;
1363 if (evmask & type_masks[type])
1366 w = gdk_window_get_parent (w);
1369 if (_gdk_fb_pointer_grab_window &&
1370 _gdk_fb_pointer_grab_owner_events)
1372 evmask = _gdk_fb_pointer_grab_events;
1374 if (evmask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK))
1376 if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
1377 ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
1378 ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
1379 evmask |= GDK_POINTER_MOTION_MASK;
1382 if (evmask & type_masks[type])
1383 return _gdk_fb_pointer_grab_window;
1390 gdk_fb_keyboard_event_window (GdkWindow *window,
1396 if (_gdk_fb_keyboard_grab_window &&
1397 !_gdk_fb_keyboard_grab_owner_events)
1399 return _gdk_fb_keyboard_grab_window;
1403 while (w != gdk_parent_root)
1405 /* Huge hack, so that we don't propagate events to GtkWindow->frame */
1406 if ((w != window) &&
1407 (GDK_WINDOW_P (w)->window_type != GDK_WINDOW_CHILD) &&
1408 (g_object_get_data (G_OBJECT (w), "gdk-window-child-handler")))
1411 evmask = GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
1413 if (evmask & type_masks[type])
1416 w = gdk_window_get_parent (w);
1419 if (_gdk_fb_keyboard_grab_window &&
1420 _gdk_fb_keyboard_grab_owner_events)
1422 return _gdk_fb_keyboard_grab_window;
1429 gdk_event_make (GdkWindow *window,
1431 gboolean append_to_queue)
1433 GdkEvent *event = gdk_event_new ();
1436 the_time = gdk_fb_get_time ();
1438 event->any.type = type;
1439 event->any.window = gdk_window_ref (window);
1440 event->any.send_event = FALSE;
1443 case GDK_MOTION_NOTIFY:
1444 event->motion.time = the_time;
1445 event->motion.axes = NULL;
1447 case GDK_BUTTON_PRESS:
1448 case GDK_2BUTTON_PRESS:
1449 case GDK_3BUTTON_PRESS:
1450 case GDK_BUTTON_RELEASE:
1451 event->button.time = the_time;
1452 event->button.axes = NULL;
1455 case GDK_KEY_RELEASE:
1456 event->key.time = the_time;
1458 case GDK_ENTER_NOTIFY:
1459 case GDK_LEAVE_NOTIFY:
1460 event->crossing.time = the_time;
1463 case GDK_PROPERTY_NOTIFY:
1464 event->property.time = the_time;
1467 case GDK_SELECTION_CLEAR:
1468 case GDK_SELECTION_REQUEST:
1469 case GDK_SELECTION_NOTIFY:
1470 event->selection.time = the_time;
1472 case GDK_PROXIMITY_IN:
1473 case GDK_PROXIMITY_OUT:
1474 event->proximity.time = the_time;
1476 case GDK_DRAG_ENTER:
1477 case GDK_DRAG_LEAVE:
1478 case GDK_DRAG_MOTION:
1479 case GDK_DRAG_STATUS:
1480 case GDK_DROP_START:
1481 case GDK_DROP_FINISHED:
1482 event->dnd.time = the_time;
1485 case GDK_FOCUS_CHANGE:
1489 case GDK_CLIENT_EVENT:
1490 case GDK_VISIBILITY_NOTIFY:
1500 if (append_to_queue)
1501 gdk_event_queue_append (event);
1507 gdk_fb_set_rotation (GdkFBAngle angle)
1509 if (angle == _gdk_fb_screen_angle)
1512 #ifdef ENABLE_SHADOW_FB
1515 gdk_shadow_fb_stop_updates ();
1517 gdk_fb_cursor_hide ();
1519 _gdk_fb_screen_angle = angle;
1523 gdk_display->fb_width = gdk_display->modeinfo.xres;
1524 gdk_display->fb_height = gdk_display->modeinfo.yres;
1528 gdk_display->fb_width = gdk_display->modeinfo.yres;
1529 gdk_display->fb_height = gdk_display->modeinfo.xres;
1531 gdk_display->fb_stride =
1532 gdk_display->fb_width * (gdk_display->modeinfo.bits_per_pixel / 8);
1534 gdk_fb_recompute_all();
1535 gdk_fb_redraw_all ();
1537 gdk_fb_cursor_unhide ();
1540 _gdk_fb_screen_angle = angle;
1542 g_warning ("Screen rotation without shadow fb not supported.");