X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fx11%2Fgdkmain-x11.c;h=e40866751eba1171ea9fb95eec4b0abb89a204a9;hb=0611f06b5ad90258d274dfb64ba07171cbd053d5;hp=de8a76e0d7cc416d838d34c5f508199b2c9fa822;hpb=fc7e845c8f4d3eb4481f803eae3f9c7f8d75a1d9;p=~andy%2Fgtk diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index de8a76e0d..e40866751 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -8,28 +8,30 @@ * * 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 + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ -#include "../config.h" -/* If you don't want to use gdk's signal handlers define this */ -/* #define I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS 1 */ +/* + * 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 #include #include -#ifdef USE_XIM -#include -#endif +#include #ifdef HAVE_SYS_SELECT_H #include @@ -40,537 +42,283 @@ #include #include #include -#include -#ifdef USE_XIM -#include -#endif #include + #include "gdk.h" -#include "gdkprivate.h" -#include "gdkinput.h" -#ifdef USE_XIM -#include "gdkx.h" -#include "gdkkeysyms.h" -#endif -#include "gdki18n.h" - -#ifndef X_GETTIMEOFDAY -#define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL) -#endif /* X_GETTIMEOFDAY */ - - -#define DOUBLE_CLICK_TIME 250 -#define TRIPLE_CLICK_TIME 500 -#define DOUBLE_CLICK_DIST 5 -#define TRIPLE_CLICK_DIST 5 - - -#ifndef NO_FD_SET -# define SELECT_MASK fd_set -#else -# ifndef _AIX - typedef long fd_mask; -# endif -# if defined(_IBMR2) -# define SELECT_MASK void -# else -# define SELECT_MASK int -# endif -#endif +#include "gdkprivate-x11.h" +#include "gdkinternals.h" +#include "gdkinputprivate.h" +#include -typedef struct _GdkInput GdkInput; typedef struct _GdkPredicate GdkPredicate; +typedef struct _GdkErrorTrap GdkErrorTrap; -struct _GdkInput +struct _GdkPredicate { - gint tag; - gint source; - GdkInputCondition condition; - GdkInputFunction function; + GdkEventFunc func; gpointer data; - GdkDestroyNotify destroy; }; -struct _GdkPredicate +struct _GdkErrorTrap { - GdkEventFunc func; - gpointer data; + gint error_warnings; + gint error_code; }; /* * Private function declarations */ -static GdkEvent *gdk_event_new (void); -static gint gdk_event_wait (void); -static gint gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters); -static gint gdk_event_translate (GdkEvent *event, - XEvent *xevent); -#if 0 -static Bool gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg); -#endif -static void gdk_synthesize_click (GdkEvent *event, - gint nclicks); - -static void gdk_dnd_drag_begin (GdkWindow *initial_window); -static void gdk_dnd_drag_enter (Window dest); -static void gdk_dnd_drag_leave (Window dest); -static void gdk_dnd_drag_end (Window dest, - GdkPoint coords); -static GdkAtom gdk_dnd_check_types (GdkWindow *window, - XEvent *xevent); -#ifdef DEBUG_DND -static void gdk_print_atom (GdkAtom anatom); +#ifndef HAVE_XCONVERTCASE +static void gdkx_XConvertCase (KeySym symbol, + KeySym *lower, + KeySym *upper); +#define XConvertCase gdkx_XConvertCase #endif -/* - * old junk from offix, we might use it though so leave it - */ -Window gdk_get_client_window (Display *dpy, - Window win); -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y); -#endif -static void gdk_exit_func (void); -static int gdk_x_error (Display *display, +static int gdk_x_error (Display *display, XErrorEvent *error); -static int gdk_x_io_error (Display *display); -static RETSIGTYPE gdk_signal (int signum); - - -#ifdef USE_XIM -static GdkIM gdk_im_get (void); -static gint gdk_im_open (XrmDatabase db, - gchar* res_name, - gchar* rec_class); -static void gdk_im_close (void); -static void gdk_ic_cleanup (void); -#endif /* USE_XIM */ +static int gdk_x_io_error (Display *display); /* Private variable declarations */ -static int initialized = 0; /* 1 if the library is initialized, +static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ -static int connection_number = 0; /* The file descriptor number of our - * connection to the X server. This - * is used so that we may determine - * when events are pending by using - * the "select" system call. - */ - - -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 GList *inputs; /* A list of the input file descriptors - * that we care about. Each list node - * contains a GdkInput struct that describes - * when we are interested in the specified - * file descriptor. That is, when it is - * available for read, write or has an - * exception pending. - */ -static guint32 button_click_time[2]; /* The last 2 button click times. Used - * to determine if the latest button click - * is part of a double or triple click. - */ -static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. - * Also used to determine if the latest button - * click is part of a double or triple click. - */ -static guint button_number[2]; /* The last 2 buttons to be pressed. - */ -static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds the - * x pointer grab - */ - -#ifdef USE_XIM -static gint xim_using; /* using XIM Protocol if TRUE */ -static GdkIM xim_im; /* global IM */ -static XIMStyles* xim_styles; /* im supports these styles */ -static XIMStyle xim_best_allowed_style; -static GdkICPrivate *xim_ic; /* currently using IC */ -static GdkWindow* xim_window; /* currently using Widow */ -static GList* xim_ic_list; -#endif - -#define OTHER_XEVENT_BUFSIZE 4 -static XEvent other_xevent[OTHER_XEVENT_BUFSIZE]; /* XEvents passed along to user */ -static int other_xevent_i = 0; -static GList *putback_events = NULL; - -static gulong base_id; static gint autorepeat; +static gboolean gdk_synchronize = FALSE; #ifdef G_ENABLE_DEBUG -static GDebugKey gdk_debug_keys[] = { - {"events", GDK_DEBUG_EVENTS}, - {"misc", GDK_DEBUG_MISC}, - {"dnd", GDK_DEBUG_DND}, +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} + {"xim", GDK_DEBUG_XIM} }; + +static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey); + #endif /* G_ENABLE_DEBUG */ -/* - *-------------------------------------------------------------- - * gdk_init - * - * 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). - * - * Side effects: - * The library is initialized. - * - *-------------------------------------------------------------- - */ +static void +gdk_arg_xim_preedit_cb (const gchar *arg, const gchar *value, gpointer cb_data) +{ + if (strcmp ("none", value) == 0) + gdk_im_set_best_style (GDK_IM_PREEDIT_NONE); + else if (strcmp ("nothing", value) == 0) + gdk_im_set_best_style (GDK_IM_PREEDIT_NOTHING); + else if (strcmp ("area", value) == 0) + gdk_im_set_best_style (GDK_IM_PREEDIT_AREA); + else if (strcmp ("position", value) == 0) + gdk_im_set_best_style (GDK_IM_PREEDIT_POSITION); + else if (strcmp ("callbacks", value) == 0) + gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS); +} -void -gdk_init (int *argc, - char ***argv) +static void +gdk_arg_xim_status_cb (const gchar *arg, const gchar *value, gpointer cb_data) +{ + if (strcmp ("none", value) == 0) + gdk_im_set_best_style (GDK_IM_STATUS_NONE); + else if (strcmp ("nothing", value) == 0) + gdk_im_set_best_style (GDK_IM_STATUS_NOTHING); + else if (strcmp ("area", value) == 0) + gdk_im_set_best_style (GDK_IM_STATUS_AREA); + else if (strcmp ("callbacks", value) == 0) + gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS); +} + +GdkArgDesc _gdk_windowing_args[] = { + { "display", GDK_ARG_STRING, &gdk_display_name, (GdkArgFunc)NULL }, + { "sync", GDK_ARG_BOOL, &gdk_synchronize, (GdkArgFunc)NULL }, + { "no-xshm", GDK_ARG_NOBOOL, &gdk_use_xshm, (GdkArgFunc)NULL }, + { "class", GDK_ARG_STRING, &gdk_progclass, (GdkArgFunc)NULL }, + { "gxid-host", GDK_ARG_STRING, &gdk_input_gxid_host, (GdkArgFunc)NULL }, + { "gxid-port", GDK_ARG_INT, &gdk_input_gxid_port, (GdkArgFunc)NULL }, + { "xim-preedit", GDK_ARG_CALLBACK, NULL, gdk_arg_xim_preedit_cb }, + { "xim-status", GDK_ARG_CALLBACK, NULL, gdk_arg_xim_status_cb }, + { NULL } +}; + +gboolean +_gdk_windowing_init_check (int argc, char **argv) { XKeyboardState keyboard_state; - int synchronize; - int i, j, k; XClassHint *class_hint; - int argc_orig = *argc; - char **argv_orig; - - gboolean debug_set = FALSE; - - argv_orig = 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); - -#ifndef I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS - signal (SIGHUP, gdk_signal); - signal (SIGINT, gdk_signal); - signal (SIGQUIT, gdk_signal); - signal (SIGBUS, gdk_signal); - signal (SIGSEGV, gdk_signal); - signal (SIGPIPE, gdk_signal); - signal (SIGTERM, gdk_signal); -#endif - - gdk_display_name = NULL; - + XSetErrorHandler (gdk_x_error); XSetIOErrorHandler (gdk_x_io_error); - - synchronize = FALSE; - - if (argc && argv) - { - if (*argc > 0) - gdk_progname = (*argv)[0]; - - for (i = 1; i < *argc;) - { - if ((*argv)[i] == NULL) - continue; - -#ifdef G_ENABLE_DEBUG - if (strcmp ("--gdk-debug", (*argv)[i]) == 0) - { - (*argv)[i] = NULL; - - if ((i + 1) < *argc && (*argv)[i + 1]) - { - gdk_debug_flags = g_parse_debug_string ((*argv)[i+1], - gdk_debug_keys, - sizeof(gdk_debug_keys) / sizeof(GDebugKey)); - debug_set = TRUE; - (*argv)[i + 1] = NULL; - i += 1; - } - } -#endif G_ENABLE_DEBUG - else 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; - gdk_progname = (*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 (GdkIMPreeditNone); - else if (strcmp ("nothing", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditNothing); - else if (strcmp ("area", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditArea); - else if (strcmp ("position", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditPosition); - else if (strcmp ("callbacks", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditCallbacks); - } - } - 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 (GdkIMStatusNone); - else if (strcmp ("nothing", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusNothing); - else if (strcmp ("area", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusArea); - else if (strcmp ("callbacks", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusCallbacks); - } - } -#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 - { - gdk_progname = ""; - } - - if (!debug_set) - { - gchar *debug_string = getenv("GDK_DEBUG"); - if (debug_string != NULL) - gdk_debug_flags = g_parse_debug_string (debug_string, - gdk_debug_keys, - sizeof(gdk_debug_keys) / sizeof(GDebugKey)); - } - + gdk_display = XOpenDisplay (gdk_display_name); if (!gdk_display) - { - g_warning ("cannot open display: %s", XDisplayName (gdk_display_name)); - exit(1); - } - - /* This is really crappy. We have to look into the display structure - * to find the base resource id. This is only needed for recording - * and playback of events. - */ - /* base_id = RESOURCE_BASE; */ - base_id = 0; - GDK_NOTE (EVENTS, g_print ("base id: %lu\n", base_id)); - - connection_number = ConnectionNumber (gdk_display); - GDK_NOTE (MISC, - g_print ("connection number: %d\n", connection_number)); - - if (synchronize) + return FALSE; + + if (gdk_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 = gdk_progname; + class_hint->res_name = g_get_prgname (); if (gdk_progclass == NULL) { - gdk_progclass = g_strdup (gdk_progname); + gdk_progclass = g_strdup (g_get_prgname ()); gdk_progclass[0] = toupper (gdk_progclass[0]); } class_hint->res_class = gdk_progclass; - XSetClassHint(gdk_display, gdk_leader_window, class_hint); - XSetCommand(gdk_display, gdk_leader_window, argv_orig, argc_orig); + XmbSetWMProperties (gdk_display, gdk_leader_window, + NULL, NULL, argv, argc, + NULL, NULL, class_hint); XFree (class_hint); - - 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_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", False); + gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", False); + gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", False); 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); - - gdk_dnd.gdk_XdeEnter = gdk_atom_intern("_XDE_ENTER", FALSE); - gdk_dnd.gdk_XdeLeave = gdk_atom_intern("_XDE_LEAVE", FALSE); - gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE); - gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE); - gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE); - gdk_dnd.gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity); - gdk_dnd.gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart); - + XGetKeyboardControl (gdk_display, &keyboard_state); autorepeat = keyboard_state.global_auto_repeat; + + return TRUE; +} - timer.tv_sec = 0; - timer.tv_usec = 0; - timerp = NULL; - - button_click_time[0] = 0; - button_click_time[1] = 0; - button_window[0] = NULL; - button_window[1] = NULL; - button_number[0] = -1; - button_number[1] = -1; - - if (ATEXIT (gdk_exit_func)) - g_warning ("unable to register exit function"); - - gdk_visual_init (); - gdk_window_init (); - gdk_image_init (); - gdk_input_init (); - -#ifdef USE_XIM - /* initialize XIM Protocol variables */ - xim_using = FALSE; - xim_im = NULL; - xim_styles = NULL; - if (!(xim_best_allowed_style & GdkIMPreeditMask)) - gdk_im_set_best_style (GdkIMPreeditCallbacks); - if (!(xim_best_allowed_style & GdkIMStatusMask)) - gdk_im_set_best_style (GdkIMStatusCallbacks); - xim_ic = NULL; - xim_window = (GdkWindow*)NULL; - - gdk_im_open (NULL, NULL, NULL); - if (gdk_im_get () == NULL) - g_warning ("unable to open input method."); -#endif +void +gdk_set_use_xshm (gboolean use_xshm) +{ + gdk_use_xshm = use_xshm; +} + +gboolean +gdk_get_use_xshm (void) +{ + return gdk_use_xshm; +} + +static GdkGrabStatus +gdk_x11_convert_grab_status (gint status) +{ + switch (status) + { + case GrabSuccess: + return GDK_GRAB_SUCCESS; + case AlreadyGrabbed: + return GDK_GRAB_ALREADY_GRABBED; + case GrabInvalidTime: + return GDK_GRAB_INVALID_TIME; + case GrabNotViewable: + return GDK_GRAB_NOT_VIEWABLE; + case GrabFrozen: + return GDK_GRAB_FROZEN; + } - initialized = 1; + g_assert_not_reached(); } /* *-------------------------------------------------------------- - * gdk_exit + * gdk_pointer_grab * - * Restores the library to an un-itialized state and exits - * the program using the "exit" system call. + * Grabs the pointer to a specific window * * Arguments: - * "errorcode" is the error value to pass to "exit". + * "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: - * Allocated structures are freed and the program exits - * cleanly. * * Side effects: + * requires a corresponding call to gdk_pointer_ungrab * *-------------------------------------------------------------- */ -void -gdk_exit (int errorcode) +GdkGrabStatus +gdk_pointer_grab (GdkWindow * window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow * confine_to, + GdkCursor * cursor, + guint32 time) { - /* de-initialisation is done by the gdk_exit_funct(), - no need to do this here (Alex J.) */ - exit (errorcode); + gint return_val; + GdkCursorPrivate *cursor_private; + guint xevent_mask; + Window xwindow; + Window xconfine_to; + Cursor xcursor; + int i; + + g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); + + cursor_private = (GdkCursorPrivate*) cursor; + + xwindow = GDK_WINDOW_XID (window); + + if (!confine_to || GDK_WINDOW_DESTROYED (confine_to)) + xconfine_to = None; + else + xconfine_to = GDK_WINDOW_XID (confine_to); + + 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]; + } + + return_val = _gdk_input_grab_pointer (window, + owner_events, + event_mask, + confine_to, + time); + + if (return_val == GrabSuccess) + { + if (!GDK_WINDOW_DESTROYED (window)) + return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (window), + xwindow, + owner_events, + xevent_mask, + GrabModeAsync, GrabModeAsync, + xconfine_to, + xcursor, + time); + else + return_val = AlreadyGrabbed; + } + + if (return_val == GrabSuccess) + gdk_xgrab_window = (GdkWindowObject *)window; + + return gdk_x11_convert_grab_status (return_val); } /* *-------------------------------------------------------------- - * gdk_set_locale + * gdk_pointer_ungrab + * + * Releases any pointer grab * * Arguments: * @@ -581,3373 +329,421 @@ gdk_exit (int errorcode) *-------------------------------------------------------------- */ -gchar* -gdk_set_locale () +void +gdk_pointer_ungrab (guint32 time) { - if (!setlocale (LC_ALL,"")) - g_print ("locale not supported by C library\n"); - - if (!XSupportsLocale ()) - { - g_print ("locale not supported by Xlib, locale set to C\n"); - setlocale (LC_ALL, "C"); - } - - if (!XSetLocaleModifiers ("")) - { - g_print ("can not set locale modifiers\n"); - } - - return setlocale (LC_ALL,NULL); + _gdk_input_ungrab_pointer (time); + + XUngrabPointer (gdk_display, time); + gdk_xgrab_window = NULL; } /* *-------------------------------------------------------------- - * gdk_events_pending + * gdk_pointer_is_grabbed * - * Returns the number of events pending on the queue. - * These events have already been read from the server - * connection. + * Tell wether there is an active x pointer grab in effect * * Arguments: * * Results: - * Returns the number of events on XLib's event queue. * * Side effects: * *-------------------------------------------------------------- */ -gint -gdk_events_pending () +gboolean +gdk_pointer_is_grabbed (void) { - gint result; - GList *tmp_list; - - result = XPending (gdk_display); - - tmp_list = putback_events; - while (tmp_list) - { - result++; - tmp_list = tmp_list->next; - } - - return result; + return gdk_xgrab_window != NULL; } /* *-------------------------------------------------------------- - * gdk_event_get_graphics_expose + * gdk_keyboard_grab * - * Waits for a GraphicsExpose or NoExpose event + * 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: - * For GraphicsExpose events, returns a pointer to the event - * converted into a GdkEvent Otherwise, returns NULL. + * Results: * * Side effects: + * requires a corresponding call to gdk_keyboard_ungrab * - *-------------------------------------------------------------- */ + *-------------------------------------------------------------- + */ -static Bool -graphics_expose_predicate (Display *display, - XEvent *xevent, - XPointer arg) +GdkGrabStatus +gdk_keyboard_grab (GdkWindow * window, + gboolean owner_events, + guint32 time) { - GdkWindowPrivate *private = (GdkWindowPrivate *)arg; + gint return_val; - g_return_val_if_fail (private != NULL, False); - - if ((xevent->xany.window == private->xwindow) && - ((xevent->xany.type == GraphicsExpose) || - (xevent->xany.type == NoExpose))) - return True; - else - return False; -} - -GdkEvent * -gdk_event_get_graphics_expose (GdkWindow *window) -{ - XEvent xevent; - GdkEvent *event; + g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); - g_return_val_if_fail (window != NULL, NULL); - - XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer)window); - - if (xevent.xany.type == GraphicsExpose) - { - event = gdk_event_new (); + if (!GDK_WINDOW_DESTROYED (window)) + return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + owner_events, + GrabModeAsync, GrabModeAsync, + time); + else + return_val = AlreadyGrabbed; - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; + return gdk_x11_convert_grab_status (return_val); } /* *-------------------------------------------------------------- - * gdk_event_get + * gdk_keyboard_ungrab * - * Gets the next event. + * Releases any keyboard grab * * Arguments: * * Results: - * If an event was received that we care about, returns - * a pointer to that event, to be freed with gdk_event_free. - * Otherwise, returns NULL. This function will also return - * before an event is received if the timeout interval - * runs out. * * Side effects: * *-------------------------------------------------------------- */ -GdkEvent * -gdk_event_get (void) -{ - GdkEvent *event; - GList *temp_list; - XEvent xevent; - -#if 0 - if (pred) - { - temp_list = putback_events; - while (temp_list) - { - temp_event = temp_list->data; - - if ((* pred) (temp_event, data)) - { - if (event) - *event = *temp_event; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free (temp_list); - return TRUE; - } - - temp_list = temp_list->next; - } - - event_pred.func = pred; - event_pred.data = data; - - if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) & event_pred)) - if (event) - return gdk_event_translate (event, &xevent); - } - else -#endif - if (putback_events) - { - event = putback_events->data; - - temp_list = putback_events; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free_1 (temp_list); - - return event; - } - - /* Wait for an event to occur or the timeout to elapse. - * If an event occurs "gdk_event_wait" will return TRUE. - * If the timeout elapses "gdk_event_wait" will return - * FALSE. - */ - if (gdk_event_wait ()) - { - /* If we get here we can rest assurred that an event - * has occurred. Read it. - */ -#ifdef USE_XIM - gint filter_status; - if (xim_using && xim_window) - do - { /* don't dispatch events used by IM */ - XNextEvent (gdk_display, &xevent); - filter_status = XFilterEvent (&xevent, - GDK_WINDOW_XWINDOW (xim_window)); - } while (filter_status == True); - else - XNextEvent (gdk_display, &xevent); -#else - XNextEvent (gdk_display, &xevent); -#endif - event = gdk_event_new (); - - event->any.type = GDK_NOTHING; - event->any.window = NULL; - event->any.send_event = FALSE; - event->any.send_event = xevent.xany.send_event; - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - void -gdk_event_put (GdkEvent *event) +gdk_keyboard_ungrab (guint32 time) { - GdkEvent *new_event; - - g_return_if_fail (event != NULL); - - new_event = gdk_event_copy (event); - - putback_events = g_list_prepend (putback_events, new_event); + XUngrabKeyboard (gdk_display, time); } /* *-------------------------------------------------------------- - * gdk_event_copy + * gdk_screen_width * - * Copy a event structure into new storage. + * Return the width of the screen. * * Arguments: - * "event" is the event struct to copy. * * Results: - * A new event structure. Free it with gdk_event_free. * * Side effects: - * The reference count of the window in the event is increased. * *-------------------------------------------------------------- */ -static GMemChunk *event_chunk; - -static GdkEvent* -gdk_event_new (void) +gint +gdk_screen_width (void) { - GdkEvent *new_event; + gint return_val; - if (event_chunk == NULL) - event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), - 4096, - G_ALLOC_AND_FREE); - - new_event = g_chunk_new (GdkEvent, event_chunk); - - return new_event; -} - -GdkEvent* -gdk_event_copy (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_val_if_fail (event != NULL, NULL); - - new_event = gdk_event_new (); - - *new_event = *event; - gdk_window_ref (new_event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - new_event->key.string = g_strdup (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_ref (event->crossing.subwindow); - break; - - case GDK_DROP_DATA_AVAIL: - new_event->dropdataavailable.data_type = g_strdup (event->dropdataavailable.data_type); - new_event->dropdataavailable.data = g_malloc (event->dropdataavailable.data_numbytes); - memcpy (new_event->dropdataavailable.data, - event->dropdataavailable.data, - event->dropdataavailable.data_numbytes); - break; - - default: - break; - } - - return new_event; -} - -/* - *-------------------------------------------------------------- - * gdk_event_free - * - * Free a event structure obtained from gdk_event_copy. Do not use - * with other event structures. - * - * Arguments: - * "event" is the event struct to free. - * - * Results: - * - * Side effects: - * The reference count of the window in the event is decreased and - * might be freed, too. - * - *-------------------------------------------------------------- */ - -void -gdk_event_free (GdkEvent *event) -{ - g_assert (event_chunk != NULL); - g_return_if_fail (event != NULL); - - if (event->any.window) - gdk_window_unref (event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - g_free (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_unref (event->crossing.subwindow); - break; - - case GDK_DROP_DATA_AVAIL: - g_free (event->dropdataavailable.data_type); - g_free (event->dropdataavailable.data); - break; - - case GDK_DRAG_REQUEST: - g_free (event->dragrequest.data_type); - break; - - default: - break; - } - - g_mem_chunk_free (event_chunk, event); + return_val = DisplayWidth (gdk_display, gdk_screen); + + return return_val; } /* *-------------------------------------------------------------- - * gdk_set_show_events + * gdk_screen_height * - * Turns on/off the showing of events. + * Return the height of the screen. * * Arguments: - * "show_events" is a boolean describing whether or - * not to show the events gdk receives. * * Results: * * Side effects: - * When "show_events" is TRUE, calls to "gdk_event_get" - * will output debugging informatin regarding the event - * received to stdout. * *-------------------------------------------------------------- */ -void -gdk_set_show_events (int show_events) -{ - if (show_events) - gdk_debug_flags |= GDK_DEBUG_EVENTS; - else - gdk_debug_flags &= ~GDK_DEBUG_EVENTS; -} - -void -gdk_set_use_xshm (gint use_xshm) -{ - gdk_use_xshm = use_xshm; -} - -gint -gdk_get_show_events () -{ - return gdk_debug_flags & GDK_DEBUG_EVENTS; -} - gint -gdk_get_use_xshm () +gdk_screen_height (void) { - return gdk_use_xshm; + gint return_val; + + return_val = DisplayHeight (gdk_display, gdk_screen); + + return return_val; } /* *-------------------------------------------------------------- - * gdk_time_get + * gdk_screen_width_mm * - * Get the number of milliseconds since the library was - * initialized. + * Return the width of the screen in millimeters. * * 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 () +gint +gdk_screen_width_mm (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; + gint return_val; + + return_val = DisplayWidthMM (gdk_display, gdk_screen); + + return return_val; } /* *-------------------------------------------------------------- - * gdk_timer_get + * gdk_screen_height * - * Returns the current timer. + * Return the height of the screen in millimeters. * * Arguments: * * Results: - * Returns the current timer interval. This interval is - * in units of milliseconds. * * Side effects: * *-------------------------------------------------------------- */ -guint32 -gdk_timer_get () +gint +gdk_screen_height_mm (void) { - return timer_val; + gint return_val; + + return_val = DisplayHeightMM (gdk_display, gdk_screen); + + return return_val; } /* *-------------------------------------------------------------- - * gdk_timer_set + * gdk_set_sm_client_id * - * Sets the timer interval. + * 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: - * "milliseconds" is the new value for the timer. + * + * "sm_client_id" specifies the client id assigned to us by the + * session manager or NULL to remove the property. * * 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) +gdk_set_sm_client_id (const gchar* sm_client_id) { - timer_val = milliseconds; - timer.tv_sec = milliseconds / 1000; - timer.tv_usec = (milliseconds % 1000) * 1000; - + 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_timer_enable () +gdk_key_repeat_disable (void) { - timerp = &timer; + XAutoRepeatOff (gdk_display); } void -gdk_timer_disable () +gdk_key_repeat_restore (void) { - timerp = NULL; + if (autorepeat) + XAutoRepeatOn (gdk_display); + else + XAutoRepeatOff (gdk_display); } -gint -gdk_input_add_full (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data, - GdkDestroyNotify destroy) -{ - static gint next_tag = 1; - GList *list; - GdkInput *input; - gint tag; - - tag = 0; - list = inputs; - - while (list) - { - input = list->data; - list = list->next; - - if ((input->source == source) && (input->condition == condition)) - { - if (input->destroy) - (input->destroy) (input->data); - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - } - } - - if (!tag) - { - input = g_new (GdkInput, 1); - input->tag = next_tag++; - input->source = source; - input->condition = condition; - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - - inputs = g_list_prepend (inputs, input); - } - - return tag; -} -gint -gdk_input_add (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data) +void +gdk_beep (void) { - return gdk_input_add_interp (source, condition, function, data, NULL); + XBell(gdk_display, 0); } void -gdk_input_remove (gint tag) +gdk_windowing_exit (void) { - GList *list; - GList *temp_list; - GdkInput *input; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag == tag) - { - if (input->destroy) - (input->destroy) (input->data); - - temp_list = list; - - if (list->next) - list->next->prev = list->prev; - if (list->prev) - list->prev->next = list->next; - if (inputs == list) - inputs = list->next; - - temp_list->next = NULL; - temp_list->prev = NULL; - - g_free (temp_list->data); - g_list_free (temp_list); - break; - } - - list = list->next; - } + pango_x_shutdown_display (gdk_display); + + XCloseDisplay (gdk_display); } /* *-------------------------------------------------------------- - * gdk_pointer_grab + * gdk_x_error * - * Grabs the pointer to a specific window + * The X error handling routine. * * 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 + * "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: - * 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) +static int +gdk_x_error (Display *display, + XErrorEvent *error) { - /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; - - 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 < nevent_masks; i++) + if (error->error_code) { - if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; - } + if (gdk_error_warnings) + { + char buf[64]; + + XGetErrorText (display, error->error_code, buf, 63); - if (((GdkWindowPrivate *)window)->extension_events && - 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; +#ifdef G_ENABLE_DEBUG + 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); +#else /* !G_ENABLE_DEBUG */ + fprintf (stderr, "Gdk-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); + + exit(1); +#endif /* G_ENABLE_DEBUG */ + } + gdk_error_code = error->error_code; } - - if (return_val == GrabSuccess) - xgrab_window = window_private; - return return_val; + return 0; } /* *-------------------------------------------------------------- - * gdk_pointer_ungrab + * gdk_x_io_error * - * Releases any pointer grab + * 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: * *-------------------------------------------------------------- */ -void -gdk_pointer_ungrab (guint32 time) +static int +gdk_x_io_error (Display *display) { - if (gdk_input_vtable.ungrab_pointer) - gdk_input_vtable.ungrab_pointer (time); + /* This is basically modelled after the code in XLib. We need + * an explicit error handler here, so we can disable our atexit() + * which would otherwise cause a nice segfault. + * We fprintf(stderr, instead of g_warning() because g_warning() + * could possibly be redirected to a dialog + */ + if (errno == EPIPE) + { + fprintf (stderr, "Gdk-ERROR **: X connection to %s broken (explicit kill or server shutdown).\n", gdk_display ? DisplayString (gdk_display) : gdk_get_display()); + } + else + { + fprintf (stderr, "Gdk-ERROR **: Fatal IO error %d (%s) on X server %s.\n", + errno, g_strerror (errno), + gdk_display ? DisplayString (gdk_display) : gdk_get_display()); + } - XUngrabPointer (gdk_display, time); - xgrab_window = NULL; + /* Disable the atexit shutdown for GDK */ + gdk_initialized = 0; + + exit(1); } -/* - *-------------------------------------------------------------- - * 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) +gchar * +gdk_get_display (void) { - return xgrab_window != NULL; + return (gchar *)XDisplayName (gdk_display_name); } -/* - *-------------------------------------------------------------- - * 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) +gint +gdk_send_xevent (Window window, gboolean propagate, glong event_mask, + XEvent *event_send) { - GdkWindowPrivate *window_private; - Window xwindow; - - g_return_val_if_fail (window != NULL, 0); + 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; +} - window_private = (GdkWindowPrivate*) window; - xwindow = window_private->xwindow; +gchar* +gdk_keyval_name (guint keyval) +{ + return XKeysymToString (keyval); +} - if (!window_private->destroyed) - return XGrabKeyboard (window_private->xdisplay, - xwindow, - owner_events, - GrabModeAsync, GrabModeAsync, - time); - else - return AlreadyGrabbed; +guint +gdk_keyval_from_name (const gchar *keyval_name) +{ + g_return_val_if_fail (keyval_name != NULL, 0); + + return XStringToKeysym (keyval_name); } -/* - *-------------------------------------------------------------- - * 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 () -{ - 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 () -{ - gint return_val; - - return_val = DisplayHeight (gdk_display, gdk_screen); - - return return_val; -} - -void -gdk_key_repeat_disable () -{ - XAutoRepeatOff (gdk_display); -} - -void -gdk_key_repeat_restore () -{ - if (autorepeat) - XAutoRepeatOn (gdk_display); - else - XAutoRepeatOff (gdk_display); -} - - -/* - *-------------------------------------------------------------- - * gdk_flush - * - * Flushes the Xlib output buffer and then waits - * until all requests have been received and processed - * by the X server. The only real use for this function - * is in dealing with XShm. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void gdk_flush () -{ - XSync (gdk_display, False); -} - - -void -gdk_beep () -{ - XBell(gdk_display, 100); -} - - -/* - *-------------------------------------------------------------- - * gdk_event_wait - * - * Waits until an event occurs or the timer runs out. - * - * Arguments: - * - * Results: - * Returns TRUE if an event is ready to be read and FALSE - * if the timer ran out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static gint -gdk_event_wait () -{ - GList *list; - GdkInput *input; - GdkInputCondition condition; - SELECT_MASK readfds; - SELECT_MASK writefds; - SELECT_MASK exceptfds; - int max_input; - int nfd; - - /* If there are no events pending we will wait for an event. - * The time we wait is dependant on the "timer". If no timer - * has been specified then we'll block until an event arrives. - * If a timer has been specified we'll block until an event - * arrives or the timer expires. (This is all done using the - * "select" system call). - */ - - if (XPending (gdk_display) == 0) - { - FD_ZERO (&readfds); - FD_ZERO (&writefds); - FD_ZERO (&exceptfds); - - FD_SET (connection_number, &readfds); - max_input = connection_number; - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - if (input->condition & GDK_INPUT_READ) - FD_SET (input->source, &readfds); - if (input->condition & GDK_INPUT_WRITE) - FD_SET (input->source, &writefds); - if (input->condition & GDK_INPUT_EXCEPTION) - FD_SET (input->source, &exceptfds); - - max_input = MAX (max_input, input->source); - } - - nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp); - - timerp = NULL; - timer_val = 0; - - if (nfd > 0) - { - if (FD_ISSET (connection_number, &readfds)) - { - if (XPending (gdk_display) == 0) - { - if (nfd == 1) - { - XNoOp (gdk_display); - XFlush (gdk_display); - } - return FALSE; - } - else - return TRUE; - } - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - condition = 0; - if (FD_ISSET (input->source, &readfds)) - condition |= GDK_INPUT_READ; - if (FD_ISSET (input->source, &writefds)) - condition |= GDK_INPUT_WRITE; - if (FD_ISSET (input->source, &exceptfds)) - condition |= GDK_INPUT_EXCEPTION; - - if (condition && input->function) - (* input->function) (input->data, input->source, condition); - } - } - } - else - return TRUE; - - return FALSE; -} - -static gint -gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters) -{ - GdkEventFilter *filter; - GList *tmp_list; - GdkFilterReturn result; - - tmp_list = filters; - - while (tmp_list) - { - filter = (GdkEventFilter *)tmp_list->data; - - result = (*filter->function)(xevent, event, filter->data); - if (result != GDK_FILTER_CONTINUE) - return result; - - tmp_list = tmp_list->next; - } - - return GDK_FILTER_CONTINUE; -} - -static gint -gdk_event_translate (GdkEvent *event, - XEvent *xevent) -{ - - GdkWindow *window; - GdkWindowPrivate *window_private; - XComposeStatus compose; - int charcount; -#ifdef USE_XIM - static gchar* buf = NULL; - static gint buf_len= 0; -#else - char buf[16]; -#endif - gint return_val; - - /* Are static variables used for this purpose thread-safe? */ - static GdkPoint dnd_drag_start = {0,0}, - dnd_drag_oldpos = {0,0}; - static GdkRectangle dnd_drag_dropzone = {0,0,0,0}; - static gint dnd_drag_perhaps = 0; - static gboolean dnd_grabbed = FALSE; - static GdkWindowPrivate *real_sw = NULL; - static Window dnd_drag_curwin = None, dnd_drag_target = None; - - return_val = FALSE; - - /* Find the GdkWindow that this event occurred in. - * All events occur in some GdkWindow (otherwise, why - * would we be receiving them). It really is an error - * to receive an event for which we cannot find the - * corresponding GdkWindow. We handle events with window=None - * specially - they are generated by XFree86's XInput under - * some circumstances. - */ - - if ((xevent->xany.window == None) && - gdk_input_vtable.window_none_event) - { - return_val = gdk_input_vtable.window_none_event (event,xevent); - - if (return_val >= 0) /* was handled */ - return return_val; - else - return_val = FALSE; - } - - window = gdk_window_lookup (xevent->xany.window); - window_private = (GdkWindowPrivate *) window; - - if (window == NULL) - g_warning ("%#lx -> NULL\n", xevent->xany.window); - else - gdk_window_ref (window); - - - /* Check for filters for this window */ - - if (window_private) - { - GdkFilterReturn result; - result = gdk_event_apply_filters (xevent, event, window_private->filters); - - if (result != GDK_FILTER_CONTINUE) - { - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - } - - /* We do a "manual" conversion of the XEvent to a - * GdkEvent. The structures are mostly the same so - * the conversion is fairly straightforward. We also - * optionally print debugging info regarding events - * received. - */ - /* Addendum: - * During drag & drop you get events where the pointer is - * in other windows. Need to just do finer-grained checking - */ - switch (xevent->type) - { - case KeyPress: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } - if (xim_using == TRUE && xim_ic) - { - Status status; - - /* Clear keyval. Depending on status, may not be set */ - event->key.keyval = GDK_VoidSymbol; - charcount = XmbLookupString(xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - (KeySym*) &event->key.keyval, - &status); - if (status == XBufferOverflow) - { /* retry */ - /* alloc adequate size of buffer */ - GDK_NOTE (XIM, - g_print("XIM: overflow (required %i)\n", charcount)); - - while (buf_len <= charcount) - buf_len *= 2; - buf = (gchar *) g_realloc (buf, buf_len); - - charcount = XmbLookupString (xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - (KeySym*) &event->key.keyval, - &status); - } - if (status == XLookupNone) - { - return_val = FALSE; - break; - } - } - else - charcount = XLookupString (&xevent->xkey, buf, buf_len, - (KeySym*) &event->key.keyval, - &compose); -#else - charcount = XLookupString (&xevent->xkey, buf, 16, - (KeySym*) &event->key.keyval, - &compose); -#endif - if (charcount > 0 && buf[charcount-1] == '\0') - charcount --; - else - buf[charcount] = '\0'; - - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - { - g_print ("key press:\twindow: %ld key: %12s %d\n", - xevent->xkey.window - base_id, - event->key.keyval ? XKeysymToString (event->key.keyval) : "(none)", - event->key.keyval); - if (charcount > 0) - g_print ("\t\tlength: %4d string: \"%s\"\n", - charcount, buf); - } -#endif /* G_ENABLE_DEBUG */ - - event->key.type = GDK_KEY_PRESS; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.string = g_strdup (buf); - event->key.length = charcount; - - return_val = window_private && !window_private->destroyed; - - if (!return_val) - g_free (event->key.string); - - break; - - case KeyRelease: - /* Lookup the string corresponding to the given keysym. - */ - charcount = XLookupString (&xevent->xkey, buf, 16, - (KeySym*) &event->key.keyval, - &compose); - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("key release:\t\twindow: %ld key: %12s %d\n", - xevent->xkey.window - base_id, - XKeysymToString (event->key.keyval), - event->key.keyval)); - - event->key.type = GDK_KEY_RELEASE; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.length = 0; - event->key.string = NULL; - - return_val = window_private && !window_private->destroyed; - break; - - case ButtonPress: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("button press[%d]:\t\twindow: %ld x,y: %d %d button: %d\n", - window_private?window_private->dnd_drag_enabled:0, - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->button.type = GDK_BUTTON_PRESS; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) && - (event->button.window == button_window[1]) && - (event->button.button == button_number[1])) - { - gdk_synthesize_click (event, 3); - - button_click_time[1] = 0; - button_click_time[0] = 0; - button_window[1] = NULL; - button_window[0] = 0; - button_number[1] = -1; - button_number[0] = -1; - } - else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) && - (event->button.window == button_window[0]) && - (event->button.button == button_number[0])) - { - gdk_synthesize_click (event, 2); - - button_click_time[1] = button_click_time[0]; - button_click_time[0] = event->button.time; - button_window[1] = button_window[0]; - button_window[0] = event->button.window; - button_number[1] = button_number[0]; - button_number[0] = event->button.button; - } - else - { - button_click_time[1] = 0; - button_click_time[0] = event->button.time; - button_window[1] = NULL; - button_window[0] = event->button.window; - button_number[1] = -1; - button_number[0] = event->button.button; - } - if(window_private - && window_private->dnd_drag_enabled - && !dnd_drag_perhaps - && !gdk_dnd.drag_really) - { - dnd_drag_perhaps = 1; - dnd_drag_start.x = xevent->xbutton.x_root; - dnd_drag_start.y = xevent->xbutton.y_root; - real_sw = window_private; - - if(gdk_dnd.drag_startwindows) - { - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - } - gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0; - dnd_grabbed = FALSE; - - { - /* Set motion mask for first DnD'd window, since it - will be the one that is actually dragged */ - XWindowAttributes dnd_winattr; - XSetWindowAttributes dnd_setwinattr; - - /* We need to get motion events while the button is down, so - we can know whether to really start dragging or not... */ - XGetWindowAttributes(gdk_display, (Window)window_private->xwindow, - &dnd_winattr); - - window_private->dnd_drag_savedeventmask = dnd_winattr.your_event_mask; - dnd_setwinattr.event_mask = - window_private->dnd_drag_eventmask = ButtonMotionMask | EnterWindowMask | LeaveWindowMask; - XChangeWindowAttributes(gdk_display, window_private->xwindow, - CWEventMask, &dnd_setwinattr); - } - } - return_val = window_private && !window_private->destroyed; - break; - - case ButtonRelease: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("button release[%d]:\twindow: %ld x,y: %d %d button: %d\n", - window_private?window_private->dnd_drag_enabled:0, - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->button.type = GDK_BUTTON_RELEASE; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - if(dnd_drag_perhaps) - { - { - XSetWindowAttributes attrs; - /* Reset event mask to pre-drag value, assuming event_mask - doesn't change during drag */ - attrs.event_mask = real_sw->dnd_drag_savedeventmask; - XChangeWindowAttributes(gdk_display, real_sw->xwindow, - CWEventMask, &attrs); - } - - if (dnd_grabbed) - { - XUngrabPointer(gdk_display, CurrentTime); - dnd_grabbed = FALSE; - } - - if(gdk_dnd.drag_really) - { - GdkPoint foo; - foo.x = xevent->xbutton.x_root; - foo.y = xevent->xbutton.y_root; - - if(dnd_drag_target != None) - gdk_dnd_drag_end(dnd_drag_target, foo); - gdk_dnd.drag_really = 0; - - gdk_dnd.drag_numwindows = 0; - if(gdk_dnd.drag_startwindows) - { - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - } - - real_sw = NULL; - } - - dnd_drag_perhaps = 0; - dnd_drag_start.x = dnd_drag_start.y = 0; - dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0; - dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0; - dnd_drag_curwin = None; - return_val = window_private?TRUE:FALSE; - } else - return_val = window_private && !window_private->destroyed; - break; - - case MotionNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s d:%d r%d\n", - xevent->xmotion.window - base_id, - xevent->xmotion.x, xevent->xmotion.y, - (xevent->xmotion.is_hint) ? "true" : "false", - dnd_drag_perhaps, gdk_dnd.drag_really)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = window; - event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x; - event->motion.y = xevent->xmotion.y; - event->motion.x_root = (gfloat)xevent->xmotion.x_root; - event->motion.y_root = (gfloat)xevent->xmotion.y_root; - event->motion.pressure = 0.5; - event->motion.xtilt = 0; - event->motion.ytilt = 0; - event->motion.state = (GdkModifierType) xevent->xmotion.state; - event->motion.is_hint = xevent->xmotion.is_hint; - event->motion.source = GDK_SOURCE_MOUSE; - event->motion.deviceid = GDK_CORE_POINTER; - -#define IS_IN_ZONE(cx, cy) (cx >= dnd_drag_dropzone.x \ - && cy >= dnd_drag_dropzone.y \ - && cx < (dnd_drag_dropzone.x + dnd_drag_dropzone.width) \ - && cy < (dnd_drag_dropzone.y + dnd_drag_dropzone.height)) - - if(dnd_drag_perhaps && gdk_dnd.drag_really) - { - /* First, we have to find what window the motion was in... */ - /* XXX there has to be a better way to do this, perhaps with - XTranslateCoordinates or XQueryTree - I don't know how, - and this sort of works */ - static Window lastwin = None, curwin = None, twin; - Window childwin = gdk_root_window; - int x, y, ox, oy; - lastwin = curwin; - curwin = gdk_root_window; - ox = x = xevent->xmotion.x_root; - oy = y = xevent->xmotion.y_root; - while(childwin != None) - { - ox = x; oy = y; - curwin = childwin; - XTranslateCoordinates(gdk_display, curwin, curwin, - x, y, &x, &y, &childwin); - if(childwin != None) - { - XTranslateCoordinates(gdk_display, curwin, childwin, - x, y, &x, &y, &twin); - } - } - GDK_NOTE (DND, - g_print("Drag is now in window %#lx, lastwin was %#lx, ddc = %#lx\n", - curwin, lastwin, dnd_drag_curwin)); - if(curwin != dnd_drag_curwin && curwin != lastwin) - { - /* We have left one window and entered another - (do leave & enter bits) */ - if(dnd_drag_curwin != None) - gdk_dnd_drag_leave(dnd_drag_curwin); - dnd_drag_curwin = curwin; - gdk_dnd_drag_enter(dnd_drag_curwin); - dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0; - dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0; - dnd_drag_target = None; - GDK_NOTE (DND, - g_print("curwin = %#lx, lastwin = %#lx, dnd_drag_curwin = %#lx\n", - curwin, lastwin, dnd_drag_curwin)); - - XChangeActivePointerGrab(gdk_display, - ButtonMotionMask | - ButtonPressMask | ButtonReleaseMask, - gdk_dnd.gdk_cursor_dragdefault, - CurrentTime); - } - else if(dnd_drag_dropzone.width > 0 - && dnd_drag_dropzone.height > 0 - && curwin == dnd_drag_curwin) - { - /* Handle all that dropzone stuff - thanks John ;-) */ - if (dnd_drag_target != None) - { - gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root, - xevent->xmotion.y_root); - gboolean old_in_zone = IS_IN_ZONE(dnd_drag_oldpos.x, - dnd_drag_oldpos.y); - - if (!in_zone && old_in_zone) - { - /* We were in the drop zone and moved out */ - dnd_drag_target = None; - gdk_dnd_drag_leave(curwin); - } - else if (!in_zone && !old_in_zone) - { - /* We were outside drop zone but in the window - - have to send enter events */ - gdk_dnd_drag_enter(curwin); - dnd_drag_curwin = curwin; - dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0; - dnd_drag_target = None; - } - } - } /* else - dnd_drag_curwin = None; */ - return_val = FALSE; - } - else - return_val = window_private && !window_private->destroyed; - break; - - case EnterNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("enter notify:\t\twindow: %ld detail: %d subwin: %ld\n", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow - base_id)); - - /* Tell XInput stuff about it if appropriate */ - if (window_private && - (window_private->extension_events != 0) && - gdk_input_vtable.enter_event) - gdk_input_vtable.enter_event (&xevent->xcrossing, window); - - event->crossing.type = GDK_ENTER_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps) - { - g_print("We may[%d] have a drag into %#lx = %#lx\n", - gdk_dnd.drag_really, - xevent->xcrossing.window, real_sw->xwindow); - } - - if (dnd_drag_perhaps && gdk_dnd.drag_really && - (xevent->xcrossing.window == real_sw->xwindow)) - { - gdk_dnd.drag_really = 0; - - GDK_NOTE (DND, g_print("Ungrabbed\n")); - - gdk_dnd.drag_numwindows = 0; - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - /* We don't want to ungrab the pointer here, or we'll - * start getting spurious enter/leave events */ - XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime); - } - - return_val = window_private && !window_private->destroyed; - break; - - case LeaveNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("leave notify:\t\twindow: %ld detail: %d subwin: %ld\n", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id)); - - event->crossing.type = GDK_LEAVE_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - if ((gdk_debug_flags & GDK_DEBUG_DND) & dnd_drag_perhaps) - { - g_print("We may[%d] have a drag out of %#lx = %#lx\n", - gdk_dnd.drag_really, - xevent->xcrossing.window, real_sw->xwindow); - } - if (dnd_drag_perhaps && !gdk_dnd.drag_really && - (xevent->xcrossing.window == real_sw->xwindow)) - { - gdk_dnd_drag_addwindow((GdkWindow *) real_sw); - gdk_dnd_drag_begin((GdkWindow *) real_sw); - XGrabPointer(gdk_display, real_sw->xwindow, False, - ButtonMotionMask | - ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, gdk_root_window, - gdk_dnd.gdk_cursor_dragdefault, CurrentTime); - dnd_grabbed = TRUE; - gdk_dnd.drag_really = 1; - } - - return_val = window_private && !window_private->destroyed; - break; - - case FocusIn: - case FocusOut: - /* We only care about focus events that indicate that _this_ - * window (not a ancestor or child) got or lost the focus - */ - switch (xevent->xfocus.detail) - { - case NotifyAncestor: - case NotifyInferior: - case NotifyNonlinear: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("focus %s:\t\twindow: %ld\n", - (xevent->xany.type == FocusIn) ? "in" : "out", - xevent->xfocus.window - base_id)); - - event->focus_change.type = GDK_FOCUS_CHANGE; - event->focus_change.window = window; - event->focus_change.in = (xevent->xany.type == FocusIn); - - return_val = window_private && !window_private->destroyed; - break; - default: - ; - } - break; - - case KeymapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("keymap notify\n")); - - /* Not currently handled */ - break; - - case Expose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d\n", - xevent->xexpose.window - base_id, xevent->xexpose.count, - xevent->xexpose.x, xevent->xexpose.y, - xevent->xexpose.width, xevent->xexpose.height)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xexpose.x; - event->expose.area.y = xevent->xexpose.y; - event->expose.area.width = xevent->xexpose.width; - event->expose.area.height = xevent->xexpose.height; - event->expose.count = xevent->xexpose.count; - - return_val = window_private && !window_private->destroyed; - break; - - case GraphicsExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("graphics expose:\tdrawable: %ld\n", - xevent->xgraphicsexpose.drawable - base_id)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xgraphicsexpose.x; - event->expose.area.y = xevent->xgraphicsexpose.y; - event->expose.area.width = xevent->xgraphicsexpose.width; - event->expose.area.height = xevent->xgraphicsexpose.height; - event->expose.count = xevent->xexpose.count; - - return_val = window_private && !window_private->destroyed; - break; - - case NoExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("no expose:\t\tdrawable: %ld\n", - xevent->xnoexpose.drawable - base_id)); - - event->no_expose.type = GDK_NO_EXPOSE; - event->no_expose.window = window; - - return_val = window_private && !window_private->destroyed; - break; - - case VisibilityNotify: - /* Print debugging info. - */ - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - g_print ("visibility notify:\twindow: %ld none\n", - xevent->xvisibility.window - base_id); - break; - case VisibilityPartiallyObscured: - g_print ("visibility notify:\twindow: %ld partial\n", - xevent->xvisibility.window - base_id); - break; - case VisibilityUnobscured: - g_print ("visibility notify:\twindow: %ld full\n", - xevent->xvisibility.window - base_id); - break; - } - - event->visibility.type = GDK_VISIBILITY_NOTIFY; - event->visibility.window = window; - - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED; - break; - - case VisibilityPartiallyObscured: - event->visibility.state = GDK_VISIBILITY_PARTIAL; - break; - - case VisibilityUnobscured: - event->visibility.state = GDK_VISIBILITY_UNOBSCURED; - break; - } - - return_val = window_private && !window_private->destroyed; - break; - - case CreateNotify: - /* Not currently handled */ - break; - - case DestroyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("destroy notify:\twindow: %ld\n", - xevent->xdestroywindow.window - base_id)); - - event->any.type = GDK_DESTROY; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - - gdk_window_destroy_notify (window); - break; - - case UnmapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("unmap notify:\t\twindow: %ld\n", - xevent->xmap.window - base_id)); - - event->any.type = GDK_UNMAP; - event->any.window = window; - - if (xgrab_window == window_private) - xgrab_window = NULL; - - return_val = window_private && !window_private->destroyed; - break; - - case MapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("map notify:\t\twindow: %ld\n", - xevent->xmap.window - base_id)); - - event->any.type = GDK_MAP; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - break; - - case ReparentNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("reparent notify:\twindow: %ld\n", - xevent->xreparent.window - base_id)); - - /* Not currently handled */ - break; - - case ConfigureNotify: - /* Print debugging info. - */ - while ((XPending (gdk_display) > 0) && - XCheckTypedWindowEvent(gdk_display, xevent->xany.window, - ConfigureNotify, xevent)) - /*XSync (gdk_display, 0)*/; - - GDK_NOTE (EVENTS, - g_print ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d\n", - xevent->xconfigure.window - base_id, - xevent->xconfigure.x, - xevent->xconfigure.y, - xevent->xconfigure.width, - xevent->xconfigure.height, - xevent->xconfigure.border_width, - xevent->xconfigure.above - base_id, - xevent->xconfigure.override_redirect)); - - if (window_private) - { - if ((window_private->extension_events != 0) && - gdk_input_vtable.configure_event) - gdk_input_vtable.configure_event (&xevent->xconfigure, window); - - if (window_private->window_type != GDK_WINDOW_CHILD) - { - event->configure.type = GDK_CONFIGURE; - event->configure.window = window; - event->configure.width = xevent->xconfigure.width; - event->configure.height = xevent->xconfigure.height; - - if (!xevent->xconfigure.x && - !xevent->xconfigure.y) - { - gint tx = 0; - gint ty = 0; - Window child_window = 0; - - if (!XTranslateCoordinates (window_private->xdisplay, - window_private->xwindow, - gdk_root_window, - 0, 0, - &tx, &ty, - &child_window)) - g_warning ("GdkWindow %ld doesn't share root windows display?", - window_private->xwindow - base_id); - event->configure.x = tx; - event->configure.y = ty; - } - else - { - event->configure.x = xevent->xconfigure.x; - event->configure.y = xevent->xconfigure.y; - } - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->width = xevent->xconfigure.width; - window_private->height = xevent->xconfigure.height; - if (window_private->resize_count > 1) - window_private->resize_count -= 1; - - return_val = !window_private->destroyed; - } - } - break; - - case PropertyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("property notify:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->property.type = GDK_PROPERTY_NOTIFY; - event->property.window = window; - event->property.atom = xevent->xproperty.atom; - event->property.time = xevent->xproperty.time; - event->property.state = xevent->xproperty.state; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionClear: - GDK_NOTE (EVENTS, - g_print ("selection clear:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_CLEAR; - event->selection.window = window; - event->selection.selection = xevent->xselectionclear.selection; - event->selection.time = xevent->xselectionclear.time; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionRequest: - GDK_NOTE (EVENTS, - g_print ("selection request:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_REQUEST; - event->selection.window = window; - event->selection.selection = xevent->xselectionrequest.selection; - event->selection.target = xevent->xselectionrequest.target; - event->selection.property = xevent->xselectionrequest.property; - event->selection.requestor = xevent->xselectionrequest.requestor; - event->selection.time = xevent->xselectionrequest.time; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionNotify: - GDK_NOTE (EVENTS, - g_print ("selection notify:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - - event->selection.type = GDK_SELECTION_NOTIFY; - event->selection.window = window; - event->selection.selection = xevent->xselection.selection; - event->selection.target = xevent->xselection.target; - event->selection.property = xevent->xselection.property; - event->selection.time = xevent->xselection.time; - - return_val = window_private && !window_private->destroyed; - break; - - case ColormapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("colormap notify:\twindow: %ld\n", - xevent->xcolormap.window - base_id)); - - /* Not currently handled */ - break; - - case ClientMessage: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("client message:\twindow: %ld\n", - xevent->xclient.window - base_id)); - - /* Client messages are the means of the window manager - * communicating with a program. We'll first check to - * see if this is really the window manager talking - * to us. - */ - if (xevent->xclient.message_type == gdk_wm_protocols) - { - if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window) - { - /* The delete window request specifies a window - * to delete. We don't actually destroy the - * window because "it is only a request". (The - * window might contain vital data that the - * program does not want destroyed). Instead - * the event is passed along to the program, - * which should then destroy the window. - */ - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("delete window:\t\twindow: %ld\n", - xevent->xclient.window - base_id)); - - event->any.type = GDK_DELETE; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - } - else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus) - { - } - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter) - { - Atom reptype = 0; - - event->dropenter.u.allflags = xevent->xclient.data.l[1]; - - GDK_NOTE (DND, g_print ("GDK_DROP_ENTER [%d][%d]\n", - window_private->dnd_drop_enabled, event->dropenter.u.flags.sendreply)); - return_val = FALSE; - - /* Now figure out if we really want this drop... - * If someone is trying funky clipboard stuff, ignore - */ - if (window_private - && window_private->dnd_drop_enabled - && event->dropenter.u.flags.sendreply - && (reptype = gdk_dnd_check_types (window, xevent))) - { - XEvent replyev; - - replyev.xclient.type = ClientMessage; - replyev.xclient.window = xevent->xclient.data.l[0]; - replyev.xclient.format = 32; - replyev.xclient.message_type = gdk_dnd.gdk_XdeRequest; - replyev.xclient.data.l[0] = window_private->xwindow; - - event->dragrequest.u.allflags = 0; - event->dragrequest.u.flags.protocol_version = - DND_PROTOCOL_VERSION; - event->dragrequest.u.flags.willaccept = 1; - event->dragrequest.u.flags.delete_data = - (window_private->dnd_drop_destructive_op) ? 1 : 0; - - replyev.xclient.data.l[1] = event->dragrequest.u.allflags; - replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0; - replyev.xclient.data.l[4] = reptype; - - XSendEvent (gdk_display, replyev.xclient.window, - False, NoEventMask, &replyev); - - event->any.type = GDK_DROP_ENTER; - event->any.window = window; - event->dropenter.requestor = replyev.xclient.window; - event->dropenter.u.allflags = xevent->xclient.data.l[1]; - - GDK_NOTE (DND, g_print("We sent a GDK_DROP_ENTER on to Gtk\n")); - return_val = TRUE; - } - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeLeave) - { -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print ("GDK_DROP_LEAVE\n"); -#endif - - if (window_private && window_private->dnd_drop_enabled) - { - event->dropleave.type = GDK_DROP_LEAVE; - event->dropleave.window = window; - event->dropleave.requestor = xevent->xclient.data.l[0]; - event->dropleave.u.allflags = xevent->xclient.data.l[1]; - return_val = TRUE; - } - else - return_val = FALSE; - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeRequest) - { - /* - * make sure to only handle requests from the window the cursor is - * over - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print ("GDK_DRAG_REQUEST\n"); -#endif - event->dragrequest.u.allflags = xevent->xclient.data.l[1]; - return_val = FALSE; - - if (window && gdk_dnd.drag_really && - xevent->xclient.data.l[0] == dnd_drag_curwin && - event->dragrequest.u.flags.sendreply == 0) - { - /* Got request - do we need to ask user? */ - if (!event->dragrequest.u.flags.willaccept - && event->dragrequest.u.flags.senddata) - { - /* Yes we do :) */ - event->dragrequest.type = GDK_DRAG_REQUEST; - event->dragrequest.window = window; - event->dragrequest.requestor = xevent->xclient.data.l[0]; - event->dragrequest.isdrop = 0; - event->dragrequest.drop_coords.x = - event->dragrequest.drop_coords.y = 0; - return_val = TRUE; - } - else if (event->dragrequest.u.flags.willaccept) - { - window_private->dnd_drag_destructive_op = - event->dragrequest.u.flags.delete_data; - window_private->dnd_drag_accepted = 1; - window_private->dnd_drag_data_type = - xevent->xclient.data.l[4]; - - dnd_drag_target = dnd_drag_curwin; - XChangeActivePointerGrab (gdk_display, - ButtonMotionMask | - ButtonPressMask | - ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask, - gdk_dnd.gdk_cursor_dragok, - CurrentTime); - } - dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535; - dnd_drag_dropzone.y = - (xevent->xclient.data.l[2] >> 16) & 65535; - dnd_drag_dropzone.width = xevent->xclient.data.l[3] & 65535; - dnd_drag_dropzone.height = - (xevent->xclient.data.l[3] >> 16) & 65535; - } - } - else if(xevent->xclient.message_type == gdk_dnd.gdk_XdeDataAvailable) - { - gint tmp_int; Atom tmp_atom; - gulong tmp_long; - guchar *tmp_charptr; - -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print("GDK_DROP_DATA_AVAIL\n"); -#endif - event->dropdataavailable.u.allflags = xevent->xclient.data.l[1]; - if(window - /* No preview of data ATM */ - && event->dropdataavailable.u.flags.isdrop) - { - event->dropdataavailable.type = GDK_DROP_DATA_AVAIL; - event->dropdataavailable.window = window; - event->dropdataavailable.requestor = xevent->xclient.data.l[0]; - event->dropdataavailable.data_type = - gdk_atom_name(xevent->xclient.data.l[2]); - if(XGetWindowProperty (gdk_display, - event->dropdataavailable.requestor, - xevent->xclient.data.l[2], - 0, LONG_MAX - 1, - False, XA_PRIMARY, &tmp_atom, - &tmp_int, - &event->dropdataavailable.data_numbytes, - &tmp_long, - &tmp_charptr) - != Success) - { - g_warning("XGetWindowProperty on %#x may have failed\n", - event->dropdataavailable.requestor); - event->dropdataavailable.data = NULL; - } - else - { - GDK_NOTE (DND, g_print("XGetWindowProperty got us %ld bytes\n", - event->dropdataavailable.data_numbytes)); - event->dropdataavailable.data = - g_malloc (event->dropdataavailable.data_numbytes); - memcpy (event->dropdataavailable.data, - tmp_charptr, event->dropdataavailable.data_numbytes); - XFree(tmp_charptr); - return_val = TRUE; - } - return_val = TRUE; - } - } - else - { - /* Send unknown ClientMessage's on to Gtk for it to use */ - event->client.type = GDK_CLIENT_EVENT; - event->client.window = window; - event->client.message_type = xevent->xclient.message_type; - event->client.data_format = xevent->xclient.format; - memcpy(&event->client.data, &xevent->xclient.data, - sizeof(event->client.data)); - if(window) - return_val = TRUE; - else - return_val = FALSE; - } - if(window_private) - return_val = return_val && !window_private->destroyed; - break; - - case MappingNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("mapping notify\n")); - - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&xevent->xmapping); - break; - - default: - /* something else - (e.g., a Xinput event) */ - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_vtable.other_event) - return_val = gdk_input_vtable.other_event(event, xevent, window); - else - return_val = -1; - - if (return_val < 0) /* not an XInput event, convert */ - { - event->other.type = GDK_OTHER_EVENT; - event->other.window = window; - event->other.xevent = (GdkXEvent *)&other_xevent[other_xevent_i]; - memcpy (&other_xevent[other_xevent_i], xevent, sizeof (XEvent)); - other_xevent_i = (other_xevent_i+1) % OTHER_XEVENT_BUFSIZE; - return_val = TRUE; - } - else - return_val = return_val && !window_private->destroyed; - - break; - } - - if (return_val) - { - if (event->any.window) - gdk_window_ref (event->any.window); - if (((event->any.type == GDK_ENTER_NOTIFY) || - (event->any.type == GDK_LEAVE_NOTIFY)) && - (event->crossing.subwindow != NULL)) - gdk_window_ref (event->crossing.subwindow); - } - else - { - /* Mark this event as having no resources to be freed */ - event->any.window = NULL; - event->any.type = GDK_NOTHING; - } - - if (window) - gdk_window_unref (window); - - return return_val; -} - -#if 0 -static Bool -gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkEvent event; - GdkPredicate *pred; - - if (gdk_event_translate (&event, xevent)) - { - pred = (GdkPredicate*) arg; - return (* pred->func) (&event, pred->data); - } - - return FALSE; -} -#endif - -static void -gdk_synthesize_click (GdkEvent *event, - gint nclicks) -{ - GdkEvent temp_event; - - g_return_if_fail (event != NULL); - - temp_event = *event; - temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - - gdk_event_put (&temp_event); -} - -/* - *-------------------------------------------------------------- - * 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 () -{ - 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_print to work) */ - if(in_gdk_exit_func == TRUE) return; - in_gdk_exit_func = TRUE; - - if (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); - 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", buf); - } - - 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; -} - -/* - *-------------------------------------------------------------- - * gdk_signal - * - * The signal handler. - * - * Arguments: - * "sig_num" is the number of the signal we received. - * - * Results: - * The signals we catch are all fatal. So we simply build - * up a nice little error message and print it and exit. - * If in the process of doing so another signal is received - * we notice that we are already exiting and simply kill - * our process. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static RETSIGTYPE -gdk_signal (int sig_num) -{ - static int caught_fatal_sig = 0; - char *sig; - - if (caught_fatal_sig) - kill (getpid (), sig_num); - caught_fatal_sig = 1; - - switch (sig_num) - { - case SIGHUP: - sig = "sighup"; - break; - case SIGINT: - sig = "sigint"; - break; - case SIGQUIT: - sig = "sigquit"; - break; - case SIGBUS: - sig = "sigbus"; - break; - case SIGSEGV: - sig = "sigsegv"; - break; - case SIGPIPE: - sig = "sigpipe"; - break; - case SIGTERM: - sig = "sigterm"; - break; - default: - sig = "unknown signal"; - break; - } - - g_print ("\n** ERROR **: %s caught\n", sig); - gdk_exit (1); -} - -static void -gdk_dnd_drag_begin (GdkWindow *initial_window) -{ - GdkEventDragBegin tev; - tev.type = GDK_DRAG_BEGIN; - tev.window = initial_window; - tev.u.allflags = 0; - tev.u.flags.protocol_version = DND_PROTOCOL_VERSION; - - gdk_event_put ((GdkEvent *) &tev); -} - -static void -gdk_dnd_drag_enter (Window dest) -{ - XEvent sev; - GdkEventDropEnter tev; - int i; - GdkWindowPrivate *wp; - - sev.xclient.type = ClientMessage; - sev.xclient.format = 32; - sev.xclient.message_type = gdk_dnd.gdk_XdeEnter; - sev.xclient.window = dest; - - tev.u.allflags = 0; - tev.u.flags.protocol_version = DND_PROTOCOL_VERSION; - tev.u.flags.sendreply = 1; - for (i = 0; i < gdk_dnd.drag_numwindows; i++) - { - wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i]; - if (wp->dnd_drag_data_numtypesavail) - { - sev.xclient.data.l[0] = wp->xwindow; - tev.u.flags.extended_typelist = (wp->dnd_drag_data_numtypesavail > 3)?1:0; - sev.xclient.data.l[1] = tev.u.allflags; - sev.xclient.data.l[2] = wp->dnd_drag_data_typesavail[0]; - if (wp->dnd_drag_data_numtypesavail > 1) - { - sev.xclient.data.l[3] = wp->dnd_drag_data_typesavail[1]; - if (wp->dnd_drag_data_numtypesavail > 2) - { - sev.xclient.data.l[4] = wp->dnd_drag_data_typesavail[2]; - } - else - sev.xclient.data.l[4] = None; - } - else - sev.xclient.data.l[3] = sev.xclient.data.l[4] = None; - XSendEvent (gdk_display, dest, False, NoEventMask, &sev); - } - - } -} - - -#ifdef USE_XIM - -/* - *-------------------------------------------------------------- - * gdk_im_begin - * - * Begin using input method with XIM Protocol(X11R6 standard) - * - * Arguments: - * "ic" is the "Input Context" which is created by gtk_ic_new. - * The input area is specified with "window". - * - * Results: - * The gdk's event handling routine is switched to XIM based routine. - * XIM based routine uses XFilterEvent to get rid of events used by IM, - * and uses XmbLookupString instead of XLookupString. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_im_begin (GdkIC ic, GdkWindow* window) -{ - GdkICPrivate *private; - Window xwin; - - g_return_if_fail (ic != NULL); - g_return_if_fail (window); - - private = (GdkICPrivate *) ic; - - xim_using = TRUE; - xim_ic = private; - xim_window = window; - if (gdk_im_ready()) - { - XGetICValues (private->xic, XNFocusWindow, &xwin, NULL); - if (xwin != GDK_WINDOW_XWINDOW(window)) - XSetICValues (private->xic, XNFocusWindow, - GDK_WINDOW_XWINDOW(window), NULL); - if (private != xim_ic) - XSetICFocus (private->xic); - } -} - -/* - *-------------------------------------------------------------- - * gdk_im_end - * - * End using input method with XIM Protocol(X11R6 standard) - * - * Arguments: - * - * Results: - * The gdk's event handling routine is switched to normal routine. - * User should call this function before ic and window will be destroyed. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_im_end (void) -{ - xim_using = FALSE; - xim_ic = NULL; - xim_window = NULL; -} - -static GdkIM -gdk_im_get (void) -{ - return xim_im; -} - -static GdkIMStyle -gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2) -{ - GdkIMStyle s1, s2, u; - - if (style1 == 0) return style2; - if (style2 == 0) return style1; - if ((style1 & (GdkIMPreeditMask | GdkIMStatusMask)) - == (style2 & (GdkIMPreeditMask | GdkIMStatusMask))) - return style1; - - s1 = style1 & GdkIMPreeditMask; - s2 = style2 & GdkIMPreeditMask; - u = s1 | s2; - if (s1 != s2) { - if (u & GdkIMPreeditCallbacks) - return (s1 == GdkIMPreeditCallbacks)? style1:style2; - else if (u & GdkIMPreeditPosition) - return (s1 == GdkIMPreeditPosition)? style1:style2; - else if (u & GdkIMPreeditArea) - return (s1 == GdkIMPreeditArea)? style1:style2; - else if (u & GdkIMPreeditNothing) - return (s1 == GdkIMPreeditNothing)? style1:style2; - } else { - s1 = style1 & GdkIMStatusMask; - s2 = style2 & GdkIMStatusMask; - u = s1 | s2; - if ( u & GdkIMStatusCallbacks) - return (s1 == GdkIMStatusCallbacks)? style1:style2; - else if ( u & GdkIMStatusArea) - return (s1 == GdkIMStatusArea)? style1:style2; - else if ( u & GdkIMStatusNothing) - return (s1 == GdkIMStatusNothing)? style1:style2; - else if ( u & GdkIMStatusNone) - return (s1 == GdkIMStatusNone)? style1:style2; - } - return 0; /* Get rid of stupid warning */ -} - -GdkIMStyle -gdk_im_decide_style (GdkIMStyle supported_style) -{ - gint i; - GdkIMStyle style, tmp; - - g_return_val_if_fail (xim_styles != NULL, 0); - - style = 0; - for (i=0; icount_styles; i++) - { - tmp = xim_styles->supported_styles[i]; - if (tmp == (tmp & supported_style & xim_best_allowed_style)) - style = gdk_im_choose_better_style (style, tmp); - } - return style; -} - -GdkIMStyle -gdk_im_set_best_style (GdkIMStyle style) -{ - if (style & GdkIMPreeditMask) - { - xim_best_allowed_style &= ~GdkIMPreeditMask; - - xim_best_allowed_style |= GdkIMPreeditNone; - if (!(style & GdkIMPreeditNone)) - { - xim_best_allowed_style |= GdkIMPreeditNothing; - if (!(style & GdkIMPreeditNothing)) - { - xim_best_allowed_style |= GdkIMPreeditArea; - if (!(style & GdkIMPreeditArea)) - { - xim_best_allowed_style |= GdkIMPreeditPosition; - if (!(style & GdkIMPreeditPosition)) - xim_best_allowed_style |= GdkIMPreeditCallbacks; - } - } - } - } - if (style & GdkIMStatusMask) - { - xim_best_allowed_style &= ~GdkIMStatusMask; - - xim_best_allowed_style |= GdkIMStatusNone; - if (!(style & GdkIMStatusNone)) - { - xim_best_allowed_style |= GdkIMStatusNothing; - if (!(style & GdkIMStatusNothing)) - { - xim_best_allowed_style |= GdkIMStatusArea; - if (!(style & GdkIMStatusArea)) - xim_best_allowed_style |= GdkIMStatusCallbacks; - } - } - } - - return xim_best_allowed_style; -} - -static gint -gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class) -{ - xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class); - if (xim_im == NULL) - { - g_warning ("Don\'t open IM."); - return FALSE; - } - XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL); - - return TRUE; -} - -static void -gdk_im_close (void) -{ - if (xim_im) - { - XCloseIM (xim_im); - xim_im = NULL; - } - if (xim_styles) - { - XFree (xim_styles); - xim_styles = NULL; - } -} - -gint -gdk_im_ready (void) -{ - return (xim_im != NULL); -} - -GdkIC -gdk_ic_new (GdkWindow* client_window, - GdkWindow* focus_window, - GdkIMStyle style, ...) -{ - va_list list; - GdkICPrivate *private; - XVaNestedList preedit_attr; - - g_return_val_if_fail (client_window != NULL, NULL); - g_return_val_if_fail (focus_window != NULL, NULL); - g_return_val_if_fail (gdk_im_ready(), NULL); - - private = g_new (GdkICPrivate, 1); - - va_start (list, style); - preedit_attr = (XVaNestedList) & (va_arg (list, void *)); - va_end (list); - - private->style = gdk_im_decide_style (style); - if (private->style != style) - { - g_warning ("can not create input context with specified input style."); - g_free (private); - return NULL; - } - - private->xic = XCreateIC(gdk_im_get (), - XNInputStyle, style, - XNClientWindow, GDK_WINDOW_XWINDOW (client_window), - XNFocusWindow, GDK_WINDOW_XWINDOW (focus_window), - preedit_attr? XNPreeditAttributes : NULL, preedit_attr, - NULL); - if (!private->xic) - { - g_free (private); - return NULL; - } - - xim_ic_list = g_list_append (xim_ic_list, private); - return private; -} - -void -gdk_ic_destroy (GdkIC ic) -{ - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - if (xim_ic == private) - gdk_im_end (); - - XDestroyIC (private->xic); - xim_ic_list = g_list_remove (xim_ic_list, private); -} - -GdkIMStyle -gdk_ic_get_style (GdkIC ic) -{ - GdkICPrivate *private; - - g_return_val_if_fail (ic != NULL, 0); - - private = (GdkICPrivate *) ic; - - return private->style; -} - -void -gdk_ic_set_values (GdkIC ic, ...) -{ - va_list list; - XVaNestedList args; - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, ic); - args = (XVaNestedList) & (va_arg (list, void *)); - va_end (list); - - XSetICValues (private->xic, XNVaNestedList, args, NULL); -} - -void -gdk_ic_get_values (GdkIC ic, ...) -{ - va_list list; - XVaNestedList args; - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, ic); - args = (XVaNestedList) & (va_arg (list, void *)); - va_end (list); - - XGetICValues (private->xic, XNVaNestedList, args, NULL); -} - -void -gdk_ic_set_attr (GdkIC ic, const char *target, ...) -{ - va_list list; - XVaNestedList attr; - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - g_return_if_fail (target != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, target); - attr = (XVaNestedList) & (va_arg (list, void *)); - va_end (list); - - XSetICValues (private->xic, target, attr, NULL); -} - -void -gdk_ic_get_attr (GdkIC ic, const char *target, ...) -{ - va_list list; - XVaNestedList attr; - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - g_return_if_fail (target != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, target); - attr = (XVaNestedList) & (va_arg (list, void *)); - va_end (list); - - XGetICValues (private->xic, target, attr, NULL); -} - -GdkEventMask -gdk_ic_get_events (GdkIC ic) -{ - GdkEventMask mask; - glong xmask; - glong bit; - GdkICPrivate *private; - gint i; - - /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; - - g_return_val_if_fail (ic != NULL, 0); - - private = (GdkICPrivate *) ic; - - XGetICValues (private->xic, XNFilterEvents, &xmask, NULL); - - mask = 0; - for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1) - if (xmask & event_mask_table [i]) - { - mask |= bit; - xmask &= ~ event_mask_table [i]; - } - - if (xmask) - g_warning ("ic requires the events not supported by the application (%04lx)", xmask); - - return mask; -} - -static void -gdk_ic_cleanup (void) -{ - GList* node; - gint destroyed; - GdkICPrivate *private; - - destroyed = 0; - for (node = xim_ic_list; node != NULL; node = node->next) - { - if (node->data) - { - private = (GdkICPrivate *) (node->data); - XDestroyIC (private->xic); - g_free (private); - destroyed++; - } - } - if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0) - { - g_warning ("Cleaned up %i IC(s)\n", destroyed); - } - g_list_free(xim_ic_list); - xim_ic_list = NULL; -} - -#else /* !USE_XIM */ - -void -gdk_im_begin (GdkIC ic, GdkWindow* window) -{ -} - -void -gdk_im_end (void) -{ -} - -GdkIMStyle -gdk_im_decide_style (GdkIMStyle supported_style) -{ - return GdkIMPreeditNone | GdkIMStatusNone; -} - -GdkIMStyle -gdk_im_set_best_style (GdkIMStyle style) -{ - return GdkIMPreeditNone | GdkIMStatusNone; -} - -gint -gdk_im_ready (void) -{ - return FALSE; -} - -GdkIC -gdk_ic_new (GdkWindow* client_window, - GdkWindow* focus_window, - GdkIMStyle style, ...) -{ - return NULL; -} - -void -gdk_ic_destroy (GdkIC ic) -{ -} - -GdkIMStyle -gdk_ic_get_style (GdkIC ic) -{ - return GdkIMPreeditNone | GdkIMStatusNone; -} - -void -gdk_ic_set_values (GdkIC ic, ...) -{ -} - -void -gdk_ic_get_values (GdkIC ic, ...) -{ -} - -void -gdk_ic_set_attr (GdkIC ic, const char *target, ...) -{ -} - -void -gdk_ic_get_attr (GdkIC ic, const char *target, ...) -{ -} - -GdkEventMask -gdk_ic_get_events (GdkIC ic) -{ - return 0; -} - -#endif /* USE_XIM */ - -#ifdef X_LOCALE - -gint -_g_mbtowc (wchar_t *wstr, const char *str, size_t len) -{ - static wchar_t wcs[MB_CUR_MAX + 1]; - static gchar mbs[MB_CUR_MAX + 1]; - - wcs[0] = (wchar_t) NULL; - mbs[0] = '\0'; - - len = _Xmbstowcs (wcs, str, (lenxwindow; - XSendEvent(gdk_display, dest, False, NoEventMask, &sev); - wp->dnd_drag_accepted = 0; - } -} - -/* - * when a drop occurs, we go through the list of windows being dragged and - * tell them that it has occurred, so that they can set things up and reply - * to 'dest' window - */ -static void -gdk_dnd_drag_end (Window dest, - GdkPoint coords) -{ - GdkWindowPrivate *wp; - GdkEventDragRequest tev; - int i; - - tev.type = GDK_DRAG_REQUEST; - tev.drop_coords = coords; - tev.requestor = dest; - tev.u.allflags = 0; - tev.u.flags.protocol_version = DND_PROTOCOL_VERSION; - tev.isdrop = 1; - - for (i = 0; i < gdk_dnd.drag_numwindows; i++) - { - wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i]; - if (wp->dnd_drag_accepted) - { - tev.window = (GdkWindow *) wp; - tev.u.flags.delete_data = wp->dnd_drag_destructive_op; - tev.data_type = - gdk_atom_name(wp->dnd_drag_data_type); - - gdk_event_put((GdkEvent *) &tev); - } - } -} - -static GdkAtom -gdk_dnd_check_types (GdkWindow *window, - XEvent *xevent) -{ - GdkWindowPrivate *wp = (GdkWindowPrivate *) window; - int i, j; - GdkEventDropEnter event; - - g_return_val_if_fail(window != NULL, 0); - g_return_val_if_fail(xevent != NULL, 0); - g_return_val_if_fail(xevent->type == ClientMessage, 0); - g_return_val_if_fail(xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter, 0); - - if(wp->dnd_drop_data_numtypesavail <= 0 || - !wp->dnd_drop_data_typesavail) - return 0; - - for (i = 2; i <= 4; i++) - { - for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++) - { - if (xevent->xclient.data.l[i] == wp->dnd_drop_data_typesavail[j]) - return xevent->xclient.data.l[i]; - } - } - - /* Now we get the extended type list if it's available */ - event.u.allflags = xevent->xclient.data.l[1]; - if (event.u.flags.extended_typelist) - { - Atom *exttypes, realtype; - gulong nitems, nbar; - gint realfmt; - - if (XGetWindowProperty(gdk_display, xevent->xclient.data.l[0], - gdk_dnd.gdk_XdeTypelist, 0L, LONG_MAX - 1, - False, AnyPropertyType, &realtype, &realfmt, - &nitems, &nbar, (unsigned char **) &exttypes) - != Success) - return 0; - - if (realfmt != (sizeof(Atom) * 8)) - { - g_warning("XdeTypelist property had format of %d instead of the expected %d, on window %#lx\n", - realfmt, sizeof(Atom) * 8, xevent->xclient.data.l[0]); - return 0; - } - - for (i = 0; i <= nitems; i++) - { - for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++) - { - if (exttypes[i] == wp->dnd_drop_data_typesavail[j]) - { - XFree (exttypes); - return exttypes[i]; - } - } - } - XFree (exttypes); - } - return 0; -} - -/* - * used for debugging only - */ -#ifdef DEBUG_DND -static void -gdk_print_atom (GdkAtom anatom) -{ - gchar *tmpstr = NULL; - tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)"; - g_print("Atom %lu has name %s\n", anatom, tmpstr); - if(tmpstr) - g_free(tmpstr); -} -#endif - -/* - * used only by below routine and itself - */ -static Window -getchildren (Display *dpy, - Window win, - Atom WM_STATE) -{ - Window root, parent, *children, inf = 0; - Atom type = None; - unsigned int nchildren, i; - int format; - unsigned long nitems, after; - unsigned char *data; - - if (XQueryTree(dpy, win, &root, &parent, &children, &nchildren) == 0) - return 0; - - for (i = 0; !inf && (i < nchildren); i++) - { - XGetWindowProperty (dpy, children[i], WM_STATE, 0, 0, False, - AnyPropertyType, &type, &format, &nitems, - &after, &data); - if (type != 0) - inf = children[i]; - XFree(data); - } - - for (i = 0; !inf && (i < nchildren); i++) - inf = getchildren (dpy, children[i], WM_STATE); - - if (children != None) - XFree ((char *) children); - - return inf; -} - -/* - * find a window with WM_STATE, else return win itself, as per ICCCM - * - * modification of the XmuClientWindow() routine from X11R6.3 - */ -Window -gdk_get_client_window (Display *dpy, - Window win) -{ - Atom WM_STATE; - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; - Window inf; - - if (win == 0) - return DefaultRootWindow(dpy); - - if ((WM_STATE = XInternAtom (dpy, "WM_STATE", True)) == 0) - return win; - - XGetWindowProperty (dpy, win, WM_STATE, 0, 0, False, AnyPropertyType, - &type, &format, &nitems, &after, &data); - if (type) - return win; - - inf = getchildren (dpy, win, WM_STATE); - - if (inf == 0) - return win; - else - return inf; -} - -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * -gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y) -{ - GdkWindow *retval = w; - GdkWindowPrivate *awin; - GList *children; - gint16 myx = *x, myy = *y; - - g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL); - - myx = *x; - myy = *y; - -descend: - for (children = gdk_window_get_children(retval); - children && children->next; - children = children->next) - { - awin = (GdkWindowPrivate *) children->data; - if ((myx >= awin->x) && (myy >= awin->y) - && (myx < (awin->x + awin->width)) - && (myy < (awin->y + awin->height))) - { - retval = (GdkWindow *) awin; - myx -= awin->x; - myy -= awin->y; - goto descend; - } - } - - *x = myx; - *y = myy; - - return retval; -} -#endif - -/* Sends a ClientMessage to all toplevel client windows */ +#ifdef HAVE_XCONVERTCASE void -gdk_event_send_clientmessage_toall(GdkEvent *event) -{ - XEvent sev; - Window *ret_children, ret_root, ret_parent, curwin; - unsigned int ret_nchildren; - int i; - - g_return_if_fail(event != NULL); - - /* Set up our event to send, with the exception of its target window */ - sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; - sev.xclient.format = event->client.data_format; - sev.xclient.serial = CurrentTime; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = event->client.message_type; - - /* OK, we're all set, now let's find some windows to send this to */ - if(XQueryTree(gdk_display, gdk_root_window, &ret_root, &ret_parent, - &ret_children, &ret_nchildren) != True) - return; - - /* foreach true child window of the root window, send an event to it */ - for(i = 0; i < ret_nchildren; i++) { - curwin = gdk_get_client_window(gdk_display, ret_children[i]); - sev.xclient.window = curwin; - XSendEvent(gdk_display, curwin, False, NoEventMask, &sev); - } - - XFree(ret_children); -} - -gchar * -gdk_get_display(void) -{ - return (gchar *)XDisplayName (gdk_display_name); -} +gdk_keyval_convert_case (guint symbol, + guint *lower, + guint *upper) +{ + KeySym xlower = 0; + KeySym xupper = 0; + + if (symbol) + XConvertCase (symbol, &xlower, &xupper); + + if (lower) + *lower = xlower; + if (upper) + *upper = xupper; +} +#endif HAVE_XCONVERTCASE