/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif /* HAVE_SYS_SELECT_H_ */ #define XLIB_ILLEGAL_ACCESS #include #include #include #include #include #include #include "gdk.h" #include "gdkprivate.h" #include "gdkinput.h" #include "gdkx.h" #include "gdki18n.h" #ifndef X_GETTIMEOFDAY #define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL) #endif /* X_GETTIMEOFDAY */ typedef struct _GdkPredicate GdkPredicate; typedef struct _GdkErrorTrap GdkErrorTrap; struct _GdkPredicate { GdkEventFunc func; gpointer data; }; struct _GdkErrorTrap { gint error_warnings; gint error_code; }; /* * Private function declarations */ #ifndef HAVE_XCONVERTCASE static void gdkx_XConvertCase (KeySym symbol, KeySym *lower, KeySym *upper); #define XConvertCase gdkx_XConvertCase #endif static void gdk_exit_func (void); static int gdk_x_error (Display *display, XErrorEvent *error); static int gdk_x_io_error (Display *display); GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, GdkEvent *event, gpointer data); /* Private variable declarations */ static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ static struct timeval start; /* The time at which the library was * last initialized. */ static struct timeval timer; /* Timeout interval to use in the call * to "select". This is used in * conjunction with "timerp" to create * a maximum time to wait for an event * to arrive. */ static struct timeval *timerp; /* The actual timer passed to "select" * This may be NULL, in which case * "select" will block until an event * arrives. */ static guint32 timer_val; /* The timeout length as specified by * the user in milliseconds. */ static gint autorepeat; static GSList *gdk_error_traps = NULL; /* List of error traps */ static GSList *gdk_error_trap_free_list = NULL; /* Free list */ #ifdef G_ENABLE_DEBUG static const GDebugKey gdk_debug_keys[] = { {"events", GDK_DEBUG_EVENTS}, {"misc", GDK_DEBUG_MISC}, {"dnd", GDK_DEBUG_DND}, {"color-context", GDK_DEBUG_COLOR_CONTEXT}, {"xim", GDK_DEBUG_XIM} }; static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey); #endif /* G_ENABLE_DEBUG */ /* *-------------------------------------------------------------- * gdk_init_heck * * Initialize the library for use. * * Arguments: * "argc" is the number of arguments. * "argv" is an array of strings. * * Results: * "argc" and "argv" are modified to reflect any arguments * which were not handled. (Such arguments should either * be handled by the application or dismissed). If initialization * fails, returns FALSE, otherwise TRUE. * * Side effects: * The library is initialized. * *-------------------------------------------------------------- */ gboolean gdk_init_check (int *argc, char ***argv) { XKeyboardState keyboard_state; gint synchronize; gint i, j, k; XClassHint *class_hint; gchar **argv_orig = NULL; gint argc_orig = 0; if (gdk_initialized) return TRUE; if (g_thread_supported ()) gdk_threads_mutex = g_mutex_new (); if (argc && argv) { argc_orig = *argc; argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*)); for (i = 0; i < argc_orig; i++) argv_orig[i] = g_strdup ((*argv)[i]); argv_orig[argc_orig] = NULL; } X_GETTIMEOFDAY (&start); gdk_display_name = NULL; XSetErrorHandler (gdk_x_error); XSetIOErrorHandler (gdk_x_io_error); synchronize = FALSE; #ifdef G_ENABLE_DEBUG { gchar *debug_string = getenv("GDK_DEBUG"); if (debug_string != NULL) gdk_debug_flags = g_parse_debug_string (debug_string, (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); } #endif /* G_ENABLE_DEBUG */ if (argc && argv) { if (*argc > 0) { gchar *d; d = strrchr((*argv)[0],'/'); if (d != NULL) g_set_prgname (d + 1); else g_set_prgname ((*argv)[0]); } for (i = 1; i < *argc;) { #ifdef G_ENABLE_DEBUG if ((strcmp ("--gdk-debug", (*argv)[i]) == 0) || (strncmp ("--gdk-debug=", (*argv)[i], 12) == 0)) { gchar *equal_pos = strchr ((*argv)[i], '='); if (equal_pos != NULL) { gdk_debug_flags |= g_parse_debug_string (equal_pos+1, (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); } else if ((i + 1) < *argc && (*argv)[i + 1]) { gdk_debug_flags |= g_parse_debug_string ((*argv)[i+1], (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); (*argv)[i] = NULL; i += 1; } (*argv)[i] = NULL; } else if ((strcmp ("--gdk-no-debug", (*argv)[i]) == 0) || (strncmp ("--gdk-no-debug=", (*argv)[i], 15) == 0)) { gchar *equal_pos = strchr ((*argv)[i], '='); if (equal_pos != NULL) { gdk_debug_flags &= ~g_parse_debug_string (equal_pos+1, (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); } else if ((i + 1) < *argc && (*argv)[i + 1]) { gdk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1], (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); (*argv)[i] = NULL; i += 1; } (*argv)[i] = NULL; } else #endif /* G_ENABLE_DEBUG */ if (strcmp ("--display", (*argv)[i]) == 0) { (*argv)[i] = NULL; if ((i + 1) < *argc && (*argv)[i + 1]) { gdk_display_name = g_strdup ((*argv)[i + 1]); (*argv)[i + 1] = NULL; i += 1; } } else if (strcmp ("--sync", (*argv)[i]) == 0) { (*argv)[i] = NULL; synchronize = TRUE; } else if (strcmp ("--no-xshm", (*argv)[i]) == 0) { (*argv)[i] = NULL; gdk_use_xshm = FALSE; } else if (strcmp ("--name", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; g_set_prgname ((*argv)[i]); (*argv)[i] = NULL; } } else if (strcmp ("--class", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; gdk_progclass = (*argv)[i]; (*argv)[i] = NULL; } } #ifdef XINPUT_GXI else if (strcmp ("--gxid_host", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; gdk_input_gxid_host = ((*argv)[i]); (*argv)[i] = NULL; } } else if (strcmp ("--gxid_port", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; gdk_input_gxid_port = atoi ((*argv)[i]); (*argv)[i] = NULL; } } #endif #ifdef USE_XIM else if (strcmp ("--xim-preedit", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; if (strcmp ("none", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_PREEDIT_NONE); else if (strcmp ("nothing", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_PREEDIT_NOTHING); else if (strcmp ("area", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_PREEDIT_AREA); else if (strcmp ("position", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_PREEDIT_POSITION); else if (strcmp ("callbacks", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS); } } else if (strcmp ("--xim-status", (*argv)[i]) == 0) { if ((i + 1) < *argc && (*argv)[i + 1]) { (*argv)[i++] = NULL; if (strcmp ("none", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_STATUS_NONE); else if (strcmp ("nothing", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_STATUS_NOTHING); else if (strcmp ("area", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_STATUS_AREA); else if (strcmp ("callbacks", (*argv)[i]) == 0) gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS); } } #endif i += 1; } for (i = 1; i < *argc; i++) { for (k = i; k < *argc; k++) if ((*argv)[k] != NULL) break; if (k > i) { k -= i; for (j = i + k; j < *argc; j++) (*argv)[j-k] = (*argv)[j]; *argc -= k; } } } else { g_set_prgname (""); } GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ())); gdk_display = XOpenDisplay (gdk_display_name); if (!gdk_display) return FALSE; if (synchronize) XSynchronize (gdk_display, True); gdk_screen = DefaultScreen (gdk_display); gdk_root_window = RootWindow (gdk_display, gdk_screen); gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window, 10, 10, 10, 10, 0, 0 , 0); class_hint = XAllocClassHint(); class_hint->res_name = g_get_prgname (); if (gdk_progclass == NULL) { gdk_progclass = g_strdup (g_get_prgname ()); gdk_progclass[0] = toupper (gdk_progclass[0]); } class_hint->res_class = gdk_progclass; XmbSetWMProperties (gdk_display, gdk_leader_window, NULL, NULL, argv_orig, argc_orig, NULL, NULL, class_hint); XFree (class_hint); for (i = 0; i < argc_orig; i++) g_free(argv_orig[i]); g_free(argv_orig); gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True); gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True); gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True); gdk_wm_window_protocols[0] = gdk_wm_delete_window; gdk_wm_window_protocols[1] = gdk_wm_take_focus; gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False); XGetKeyboardControl (gdk_display, &keyboard_state); autorepeat = keyboard_state.global_auto_repeat; timer.tv_sec = 0; timer.tv_usec = 0; timerp = NULL; g_atexit (gdk_exit_func); gdk_events_init (); gdk_visual_init (); gdk_window_init (); gdk_image_init (); gdk_input_init (); gdk_dnd_init (); #ifdef USE_XIM gdk_im_open (); #endif gdk_initialized = 1; return TRUE; } void gdk_init (int *argc, char ***argv) { if (!gdk_init_check (argc, argv)) { g_warning ("cannot open display: %s", gdk_get_display ()); exit(1); } } /* *-------------------------------------------------------------- * gdk_exit * * Restores the library to an un-itialized state and exits * the program using the "exit" system call. * * Arguments: * "errorcode" is the error value to pass to "exit". * * Results: * Allocated structures are freed and the program exits * cleanly. * * Side effects: * *-------------------------------------------------------------- */ void gdk_exit (gint errorcode) { /* de-initialisation is done by the gdk_exit_funct(), no need to do this here (Alex J.) */ exit (errorcode); } void gdk_set_use_xshm (gint use_xshm) { gdk_use_xshm = use_xshm; } gint gdk_get_use_xshm (void) { return gdk_use_xshm; } /* *-------------------------------------------------------------- * gdk_time_get * * Get the number of milliseconds since the library was * initialized. * * Arguments: * * Results: * The time since the library was initialized is returned. * This time value is accurate to milliseconds even though * a more accurate time down to the microsecond could be * returned. * * Side effects: * *-------------------------------------------------------------- */ guint32 gdk_time_get (void) { struct timeval end; struct timeval elapsed; guint32 milliseconds; X_GETTIMEOFDAY (&end); if (start.tv_usec > end.tv_usec) { end.tv_usec += 1000000; end.tv_sec--; } elapsed.tv_sec = end.tv_sec - start.tv_sec; elapsed.tv_usec = end.tv_usec - start.tv_usec; milliseconds = (elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000); return milliseconds; } /* *-------------------------------------------------------------- * gdk_timer_get * * Returns the current timer. * * Arguments: * * Results: * Returns the current timer interval. This interval is * in units of milliseconds. * * Side effects: * *-------------------------------------------------------------- */ guint32 gdk_timer_get (void) { return timer_val; } /* *-------------------------------------------------------------- * gdk_timer_set * * Sets the timer interval. * * Arguments: * "milliseconds" is the new value for the timer. * * Results: * * Side effects: * Calls to "gdk_event_get" will last for a maximum * of time of "milliseconds". However, a value of 0 * milliseconds will cause "gdk_event_get" to block * indefinately until an event is received. * *-------------------------------------------------------------- */ void gdk_timer_set (guint32 milliseconds) { timer_val = milliseconds; timer.tv_sec = milliseconds / 1000; timer.tv_usec = (milliseconds % 1000) * 1000; } void gdk_timer_enable (void) { timerp = &timer; } void gdk_timer_disable (void) { timerp = NULL; } /* *-------------------------------------------------------------- * gdk_pointer_grab * * Grabs the pointer to a specific window * * Arguments: * "window" is the window which will receive the grab * "owner_events" specifies whether events will be reported as is, * or relative to "window" * "event_mask" masks only interesting events * "confine_to" limits the cursor movement to the specified window * "cursor" changes the cursor for the duration of the grab * "time" specifies the time * * Results: * * Side effects: * requires a corresponding call to gdk_pointer_ungrab * *-------------------------------------------------------------- */ gint gdk_pointer_grab (GdkWindow * window, gint owner_events, GdkEventMask event_mask, GdkWindow * confine_to, GdkCursor * cursor, guint32 time) { /* From gdkwindow.c */ gint return_val; GdkWindowPrivate *window_private; GdkWindowPrivate *confine_to_private; GdkCursorPrivate *cursor_private; guint xevent_mask; Window xwindow; Window xconfine_to; Cursor xcursor; int i; g_return_val_if_fail (window != NULL, 0); window_private = (GdkWindowPrivate*) window; confine_to_private = (GdkWindowPrivate*) confine_to; cursor_private = (GdkCursorPrivate*) cursor; xwindow = window_private->xwindow; if (!confine_to || confine_to_private->destroyed) xconfine_to = None; else xconfine_to = confine_to_private->xwindow; if (!cursor) xcursor = None; else xcursor = cursor_private->xcursor; xevent_mask = 0; for (i = 0; i < gdk_nevent_masks; i++) { if (event_mask & (1 << (i + 1))) xevent_mask |= gdk_event_mask_table[i]; } if (gdk_input_vtable.grab_pointer) return_val = gdk_input_vtable.grab_pointer (window, owner_events, event_mask, confine_to, time); else return_val = Success; if (return_val == Success) { if (!window_private->destroyed) return_val = XGrabPointer (window_private->xdisplay, xwindow, owner_events, xevent_mask, GrabModeAsync, GrabModeAsync, xconfine_to, xcursor, time); else return_val = AlreadyGrabbed; } if (return_val == GrabSuccess) gdk_xgrab_window = window_private; return return_val; } /* *-------------------------------------------------------------- * gdk_pointer_ungrab * * Releases any pointer grab * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ void gdk_pointer_ungrab (guint32 time) { if (gdk_input_vtable.ungrab_pointer) gdk_input_vtable.ungrab_pointer (time); XUngrabPointer (gdk_display, time); gdk_xgrab_window = NULL; } /* *-------------------------------------------------------------- * gdk_pointer_is_grabbed * * Tell wether there is an active x pointer grab in effect * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ gint gdk_pointer_is_grabbed (void) { return gdk_xgrab_window != NULL; } /* *-------------------------------------------------------------- * gdk_keyboard_grab * * Grabs the keyboard to a specific window * * Arguments: * "window" is the window which will receive the grab * "owner_events" specifies whether events will be reported as is, * or relative to "window" * "time" specifies the time * * Results: * * Side effects: * requires a corresponding call to gdk_keyboard_ungrab * *-------------------------------------------------------------- */ gint gdk_keyboard_grab (GdkWindow * window, gint owner_events, guint32 time) { GdkWindowPrivate *window_private; Window xwindow; g_return_val_if_fail (window != NULL, 0); window_private = (GdkWindowPrivate*) window; xwindow = window_private->xwindow; if (!window_private->destroyed) return XGrabKeyboard (window_private->xdisplay, xwindow, owner_events, GrabModeAsync, GrabModeAsync, time); else return AlreadyGrabbed; } /* *-------------------------------------------------------------- * gdk_keyboard_ungrab * * Releases any keyboard grab * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ void gdk_keyboard_ungrab (guint32 time) { XUngrabKeyboard (gdk_display, time); } /* *-------------------------------------------------------------- * gdk_screen_width * * Return the width of the screen. * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ gint gdk_screen_width (void) { gint return_val; return_val = DisplayWidth (gdk_display, gdk_screen); return return_val; } /* *-------------------------------------------------------------- * gdk_screen_height * * Return the height of the screen. * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ gint gdk_screen_height (void) { gint return_val; return_val = DisplayHeight (gdk_display, gdk_screen); return return_val; } /* *-------------------------------------------------------------- * gdk_screen_width_mm * * Return the width of the screen in millimeters. * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ gint gdk_screen_width_mm (void) { gint return_val; return_val = DisplayWidthMM (gdk_display, gdk_screen); return return_val; } /* *-------------------------------------------------------------- * gdk_screen_height * * Return the height of the screen in millimeters. * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */ gint gdk_screen_height_mm (void) { gint return_val; return_val = DisplayHeightMM (gdk_display, gdk_screen); return return_val; } /* *-------------------------------------------------------------- * gdk_set_sm_client_id * * Set the SM_CLIENT_ID property on the WM_CLIENT_LEADER window * so that the window manager can save our state using the * X11R6 ICCCM session management protocol. A NULL value should * be set following disconnection from the session manager to * remove the SM_CLIENT_ID property. * * Arguments: * * "sm_client_id" specifies the client id assigned to us by the * session manager or NULL to remove the property. * * Results: * * Side effects: * *-------------------------------------------------------------- */ void gdk_set_sm_client_id (const gchar* sm_client_id) { if (sm_client_id && strcmp (sm_client_id, "")) { XChangeProperty (gdk_display, gdk_leader_window, gdk_atom_intern ("SM_CLIENT_ID", FALSE), XA_STRING, 8, PropModeReplace, sm_client_id, strlen(sm_client_id)); } else XDeleteProperty (gdk_display, gdk_leader_window, gdk_atom_intern ("SM_CLIENT_ID", FALSE)); } void gdk_key_repeat_disable (void) { XAutoRepeatOff (gdk_display); } void gdk_key_repeat_restore (void) { if (autorepeat) XAutoRepeatOn (gdk_display); else XAutoRepeatOff (gdk_display); } void gdk_beep (void) { XBell(gdk_display, 100); } /* *-------------------------------------------------------------- * gdk_exit_func * * This is the "atexit" function that makes sure the * library gets a chance to cleanup. * * Arguments: * * Results: * * Side effects: * The library is un-initialized and the program exits. * *-------------------------------------------------------------- */ static void gdk_exit_func (void) { static gboolean in_gdk_exit_func = FALSE; /* This is to avoid an infinite loop if a program segfaults in an atexit() handler (and yes, it does happen, especially if a program has trounced over memory too badly for even g_message to work) */ if (in_gdk_exit_func == TRUE) return; in_gdk_exit_func = TRUE; if (gdk_initialized) { #ifdef USE_XIM /* cleanup IC */ gdk_ic_cleanup (); /* close IM */ gdk_im_close (); #endif gdk_image_exit (); gdk_input_exit (); gdk_key_repeat_restore (); XCloseDisplay (gdk_display); gdk_initialized = 0; } } /* *-------------------------------------------------------------- * gdk_x_error * * The X error handling routine. * * Arguments: * "display" is the X display the error orignated from. * "error" is the XErrorEvent that we are handling. * * Results: * Either we were expecting some sort of error to occur, * in which case we set the "gdk_error_code" flag, or this * error was unexpected, in which case we will print an * error message and exit. (Since trying to continue will * most likely simply lead to more errors). * * Side effects: * *-------------------------------------------------------------- */ static int gdk_x_error (Display *display, XErrorEvent *error) { char buf[64]; if (gdk_error_warnings) { XGetErrorText (display, error->error_code, buf, 63); g_error ("%s\n serial %ld error_code %d request_code %d minor_code %d\n", buf, error->serial, error->error_code, error->request_code, error->minor_code); } gdk_error_code = -1; return 0; } /* *-------------------------------------------------------------- * gdk_x_io_error * * The X I/O error handling routine. * * Arguments: * "display" is the X display the error orignated from. * * Results: * An X I/O error basically means we lost our connection * to the X server. There is not much we can do to * continue, so simply print an error message and exit. * * Side effects: * *-------------------------------------------------------------- */ static int gdk_x_io_error (Display *display) { g_error ("an x io error occurred"); return 0; } gchar * gdk_get_display (void) { return (gchar *)XDisplayName (gdk_display_name); } /************************************************************* * gdk_error_trap_push: * Push an error trap. X errors will be trapped until * the corresponding gdk_error_pop(), which will return * the error code, if any. * arguments: * * results: *************************************************************/ void gdk_error_trap_push (void) { GSList *node; GdkErrorTrap *trap; if (gdk_error_trap_free_list) { node = gdk_error_trap_free_list; gdk_error_trap_free_list = gdk_error_trap_free_list->next; } else { node = g_slist_alloc(); node->data = g_new (GdkErrorTrap, 1); } node->next = gdk_error_traps; gdk_error_traps = node; trap = node->data; trap->error_code = gdk_error_code; trap->error_warnings = gdk_error_warnings; gdk_error_code = 0; gdk_error_warnings = 0; } /************************************************************* * gdk_error_trap_pop: * Pop an error trap added with gdk_error_push() * arguments: * * results: * 0, if no error occured, otherwise the error code. *************************************************************/ gint gdk_error_trap_pop (void) { GSList *node; GdkErrorTrap *trap; gint result; g_return_val_if_fail (gdk_error_traps != NULL, 0); node = gdk_error_traps; gdk_error_traps = gdk_error_traps->next; node->next = gdk_error_trap_free_list; gdk_error_trap_free_list = node; result = gdk_error_code; trap = node->data; gdk_error_code = trap->error_code; gdk_error_warnings = trap->error_warnings; return result; } gint gdk_send_xevent (Window window, gboolean propagate, glong event_mask, XEvent *event_send) { Status result; gint old_warnings = gdk_error_warnings; gdk_error_code = 0; gdk_error_warnings = 0; result = XSendEvent (gdk_display, window, propagate, event_mask, event_send); XSync (gdk_display, False); gdk_error_warnings = old_warnings; return result && (gdk_error_code != -1); } #ifndef HAVE_XCONVERTCASE /* compatibility function from X11R6.3, since XConvertCase is not * supplied by X11R5. */ static void gdkx_XConvertCase (KeySym symbol, KeySym *lower, KeySym *upper) { register KeySym sym = symbol; g_return_if_fail (lower != NULL); g_return_if_fail (upper != NULL); *lower = sym; *upper = sym; switch (sym >> 8) { #if defined (GDK_A) && defined (GDK_Ooblique) case 0: /* Latin 1 */ if ((sym >= GDK_A) && (sym <= GDK_Z)) *lower += (GDK_a - GDK_A); else if ((sym >= GDK_a) && (sym <= GDK_z)) *upper -= (GDK_a - GDK_A); else if ((sym >= GDK_Agrave) && (sym <= GDK_Odiaeresis)) *lower += (GDK_agrave - GDK_Agrave); else if ((sym >= GDK_agrave) && (sym <= GDK_odiaeresis)) *upper -= (GDK_agrave - GDK_Agrave); else if ((sym >= GDK_Ooblique) && (sym <= GDK_Thorn)) *lower += (GDK_oslash - GDK_Ooblique); else if ((sym >= GDK_oslash) && (sym <= GDK_thorn)) *upper -= (GDK_oslash - GDK_Ooblique); break; #endif /* LATIN1 */ #if defined (GDK_Aogonek) && defined (GDK_tcedilla) case 1: /* Latin 2 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym == GDK_Aogonek) *lower = GDK_aogonek; else if (sym >= GDK_Lstroke && sym <= GDK_Sacute) *lower += (GDK_lstroke - GDK_Lstroke); else if (sym >= GDK_Scaron && sym <= GDK_Zacute) *lower += (GDK_scaron - GDK_Scaron); else if (sym >= GDK_Zcaron && sym <= GDK_Zabovedot) *lower += (GDK_zcaron - GDK_Zcaron); else if (sym == GDK_aogonek) *upper = GDK_Aogonek; else if (sym >= GDK_lstroke && sym <= GDK_sacute) *upper -= (GDK_lstroke - GDK_Lstroke); else if (sym >= GDK_scaron && sym <= GDK_zacute) *upper -= (GDK_scaron - GDK_Scaron); else if (sym >= GDK_zcaron && sym <= GDK_zabovedot) *upper -= (GDK_zcaron - GDK_Zcaron); else if (sym >= GDK_Racute && sym <= GDK_Tcedilla) *lower += (GDK_racute - GDK_Racute); else if (sym >= GDK_racute && sym <= GDK_tcedilla) *upper -= (GDK_racute - GDK_Racute); break; #endif /* LATIN2 */ #if defined (GDK_Hstroke) && defined (GDK_Cabovedot) case 2: /* Latin 3 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= GDK_Hstroke && sym <= GDK_Hcircumflex) *lower += (GDK_hstroke - GDK_Hstroke); else if (sym >= GDK_Gbreve && sym <= GDK_Jcircumflex) *lower += (GDK_gbreve - GDK_Gbreve); else if (sym >= GDK_hstroke && sym <= GDK_hcircumflex) *upper -= (GDK_hstroke - GDK_Hstroke); else if (sym >= GDK_gbreve && sym <= GDK_jcircumflex) *upper -= (GDK_gbreve - GDK_Gbreve); else if (sym >= GDK_Cabovedot && sym <= GDK_Scircumflex) *lower += (GDK_cabovedot - GDK_Cabovedot); else if (sym >= GDK_cabovedot && sym <= GDK_scircumflex) *upper -= (GDK_cabovedot - GDK_Cabovedot); break; #endif /* LATIN3 */ #if defined (GDK_Rcedilla) && defined (GDK_Amacron) case 3: /* Latin 4 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= GDK_Rcedilla && sym <= GDK_Tslash) *lower += (GDK_rcedilla - GDK_Rcedilla); else if (sym >= GDK_rcedilla && sym <= GDK_tslash) *upper -= (GDK_rcedilla - GDK_Rcedilla); else if (sym == GDK_ENG) *lower = GDK_eng; else if (sym == GDK_eng) *upper = GDK_ENG; else if (sym >= GDK_Amacron && sym <= GDK_Umacron) *lower += (GDK_amacron - GDK_Amacron); else if (sym >= GDK_amacron && sym <= GDK_umacron) *upper -= (GDK_amacron - GDK_Amacron); break; #endif /* LATIN4 */ #if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu) case 6: /* Cyrillic */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= GDK_Serbian_DJE && sym <= GDK_Serbian_DZE) *lower -= (GDK_Serbian_DJE - GDK_Serbian_dje); else if (sym >= GDK_Serbian_dje && sym <= GDK_Serbian_dze) *upper += (GDK_Serbian_DJE - GDK_Serbian_dje); else if (sym >= GDK_Cyrillic_YU && sym <= GDK_Cyrillic_HARDSIGN) *lower -= (GDK_Cyrillic_YU - GDK_Cyrillic_yu); else if (sym >= GDK_Cyrillic_yu && sym <= GDK_Cyrillic_hardsign) *upper += (GDK_Cyrillic_YU - GDK_Cyrillic_yu); break; #endif /* CYRILLIC */ #if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma) case 7: /* Greek */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= GDK_Greek_ALPHAaccent && sym <= GDK_Greek_OMEGAaccent) *lower += (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent); else if (sym >= GDK_Greek_alphaaccent && sym <= GDK_Greek_omegaaccent && sym != GDK_Greek_iotaaccentdieresis && sym != GDK_Greek_upsilonaccentdieresis) *upper -= (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent); else if (sym >= GDK_Greek_ALPHA && sym <= GDK_Greek_OMEGA) *lower += (GDK_Greek_alpha - GDK_Greek_ALPHA); else if (sym >= GDK_Greek_alpha && sym <= GDK_Greek_omega && sym != GDK_Greek_finalsmallsigma) *upper -= (GDK_Greek_alpha - GDK_Greek_ALPHA); break; #endif /* GREEK */ } } #endif gchar* gdk_keyval_name (guint keyval) { return XKeysymToString (keyval); } guint gdk_keyval_from_name (const gchar *keyval_name) { g_return_val_if_fail (keyval_name != NULL, 0); return XStringToKeysym (keyval_name); } guint gdk_keyval_to_upper (guint keyval) { if (keyval) { KeySym lower_val = 0; KeySym upper_val = 0; XConvertCase (keyval, &lower_val, &upper_val); return upper_val; } return 0; } guint gdk_keyval_to_lower (guint keyval) { if (keyval) { KeySym lower_val = 0; KeySym upper_val = 0; XConvertCase (keyval, &lower_val, &upper_val); return lower_val; } return 0; } gboolean gdk_keyval_is_upper (guint keyval) { if (keyval) { KeySym lower_val = 0; KeySym upper_val = 0; XConvertCase (keyval, &lower_val, &upper_val); return upper_val == keyval; } return TRUE; } gboolean gdk_keyval_is_lower (guint keyval) { if (keyval) { KeySym lower_val = 0; KeySym upper_val = 0; XConvertCase (keyval, &lower_val, &upper_val); return lower_val == keyval; } return TRUE; } void gdk_threads_enter () { GDK_THREADS_ENTER (); } void gdk_threads_leave () { GDK_THREADS_LEAVE (); }