diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-07-11 19:57:01 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-07-11 19:57:01 +0000 |
commit | 50da0ae808262ba787204baf6a9f544edf8aee25 (patch) | |
tree | a744a7c9753f082d94d9358a1cd41c40db8e0474 /gdk | |
parent | 7f8ae32c1d8c48cb361d1864c27a69f27f6a2dbd (diff) | |
download | gtk+-50da0ae808262ba787204baf6a9f544edf8aee25.tar.gz |
gdk/x11/gdkevents-x11.c (get_real_window) gdk/x11/gdkinput-x11.c
Tue Jul 8 20:11:04 2003 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkevents-x11.c (get_real_window)
gdk/x11/gdkinput-x11.c (_gdk_input_common_init)
gdk/x11/gdkimage-x11.c (_gdk_windowing_image_init)
gdk/x11/gdkprivate-x11.h (_gdk_windowing_image_init)
Don't assume that all events start with XEventAny - Xkb events
don't! (#105745). So, only do that for core events, and for
non-core events, add a system for registering event types
that start with XEventAny.
* gdk/x11/gdkevents-x11.c (gdk_event_translate):
Check to see if the result of gdk_window_lookup_for_display()
is actually a window.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/x11/gdkdisplay-x11.c | 3 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.h | 7 | ||||
-rw-r--r-- | gdk/x11/gdkevents-x11.c | 193 | ||||
-rw-r--r-- | gdk/x11/gdkimage-x11.c | 41 | ||||
-rw-r--r-- | gdk/x11/gdkinput-x11.c | 13 | ||||
-rw-r--r-- | gdk/x11/gdkprivate-x11.h | 3 |
6 files changed, 159 insertions, 101 deletions
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 30dbde9c73..9227e943d3 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -653,6 +653,9 @@ gdk_display_x11_finalize (GObject *object) XDestroyWindow (display_x11->xdisplay, display_x11->leader_window); /* list of filters for client messages */ g_list_free (display_x11->client_filters); + /* List of event window extraction functions */ + g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL); + g_slist_free (display_x11->event_types); /* X ID hashtable */ g_hash_table_destroy (display_x11->xid_ht); /* input GdkDevice list */ diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 1acfe457a5..d8e37cc2ec 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -112,7 +112,10 @@ struct _GdkDisplayX11 gboolean leader_window_title_set; /* list of filters for client messages */ - GList *client_filters; + GList *client_filters; + + /* List of functions to go from extension event => X window */ + GSList *event_types; /* X ID hashtable */ GHashTable *xid_ht; @@ -132,7 +135,7 @@ struct _GdkDisplayX11 gchar *input_gxid_host; gint input_gxid_port; - gint use_xft; + gint use_xft; /* Startup notification */ gchar *startup_notification_id; diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index f4be985a48..5e99a299cf 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -53,6 +53,7 @@ typedef struct _GdkIOClosure GdkIOClosure; typedef struct _GdkDisplaySource GdkDisplaySource; +typedef struct _GdkEventTypeX11 GdkEventTypeX11; #define DOUBLE_CLICK_TIME 250 #define TRIPLE_CLICK_TIME 500 @@ -75,6 +76,12 @@ struct _GdkDisplaySource GPollFD event_poll_fd; }; +struct _GdkEventTypeX11 +{ + gint base; + gint n_events; +}; + /* * Private function declarations */ @@ -639,50 +646,101 @@ translate_key_event (GdkDisplay *display, return; } -/* Return the window this has to do with, if any, rather - * than the frame or root window that was selecting - * for substructure - */ -static Window -get_real_window (XEvent *event) +void +_gdk_x11_register_event_type (GdkDisplay *display, + gint event_base, + gint n_events) { - switch (event->type) - { - case CreateNotify: - return event->xcreatewindow.window; - - case DestroyNotify: - return event->xdestroywindow.window; - - case UnmapNotify: - return event->xunmap.window; - - case MapNotify: - return event->xmap.window; + GdkEventTypeX11 *event_type; + GdkDisplayX11 *display_x11; - case MapRequest: - return event->xmaprequest.window; + display_x11 = GDK_DISPLAY_X11 (display); + event_type = g_new (GdkEventTypeX11, 1); - case ReparentNotify: - return event->xreparent.window; - - case ConfigureNotify: - return event->xconfigure.window; - - case ConfigureRequest: - return event->xconfigurerequest.window; + event_type->base = event_base; + event_type->n_events = n_events; - case GravityNotify: - return event->xgravity.window; + display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type); +} - case CirculateNotify: - return event->xcirculate.window; +/* Return the window this has to do with, if any, rather + * than the frame or root window that was selecting + * for substructure + */ +static void +get_real_window (GdkDisplay *display, + XEvent *event, + Window *event_window, + Window *filter_window) +{ + /* Core events all have an event->xany.window field, but that's + * not true for extension events + */ + if (event->type >= KeyPress && + event->type <= MappingNotify) + { + *filter_window = event->xany.window; + switch (event->type) + { + case CreateNotify: + *event_window = event->xcreatewindow.window; + + case DestroyNotify: + *event_window = event->xdestroywindow.window; + + case UnmapNotify: + *event_window = event->xunmap.window; + + case MapNotify: + *event_window = event->xmap.window; + + case MapRequest: + *event_window = event->xmaprequest.window; + + case ReparentNotify: + *event_window = event->xreparent.window; + + case ConfigureNotify: + *event_window = event->xconfigure.window; + + case ConfigureRequest: + *event_window = event->xconfigurerequest.window; + + case GravityNotify: + *event_window = event->xgravity.window; + + case CirculateNotify: + *event_window = event->xcirculate.window; + + case CirculateRequest: + *event_window = event->xcirculaterequest.window; + + default: + *event_window = event->xany.window; + } + } + else + { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + GSList *tmp_list; - case CirculateRequest: - return event->xcirculaterequest.window; + for (tmp_list = display_x11->event_types; + tmp_list; + tmp_list = tmp_list->next) + { + GdkEventTypeX11 *event_type = tmp_list->data; - default: - return event->xany.window; + if (event->type >= event_type->base && + event->type < event_type->base + event_type->n_events) + { + *event_window = event->xany.window; + *filter_window = event->xany.window; + return; + } + } + + *event_window = None; + *filter_window = None; } } @@ -723,7 +781,7 @@ gdk_event_translate (GdkDisplay *display, GdkScreenX11 *screen_x11 = NULL; GdkToplevelX11 *toplevel = NULL; GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); - Window xwindow; + Window xwindow, filter_xwindow; return_val = FALSE; @@ -750,18 +808,27 @@ gdk_event_translate (GdkDisplay *display, * Basically this means substructure events * are reported same as structure events */ - xwindow = get_real_window (xevent); + get_real_window (display, xevent, &xwindow, &filter_xwindow); window = gdk_window_lookup_for_display (display, xwindow); + /* We may receive events such as NoExpose/GraphicsExpose + * and ShmCompletion for pixmaps + */ + if (window && !GDK_IS_WINDOW (window)) + window = NULL; window_private = (GdkWindowObject *) window; /* We always run the filters for the window where the event * is delivered, not the window that it relates to */ - if (xevent->xany.window == xwindow) + if (filter_xwindow == xwindow) filter_window = window; else - filter_window = gdk_window_lookup_for_display (display, xevent->xany.window); + { + filter_window = gdk_window_lookup_for_display (display, filter_xwindow); + if (filter_window && !GDK_IS_WINDOW (filter_window)) + filter_window = NULL; + } if (window) { @@ -772,32 +839,24 @@ gdk_event_translate (GdkDisplay *display, if (window != NULL) { - /* Window may be a pixmap, so check its type. - * (This check is probably too expensive unless - * GLib short-circuits an exact type match, - * which has been proposed) - */ - if (GDK_IS_WINDOW (window)) - { - window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl); - - /* Move key events on focus window to the real toplevel, and - * filter out all other events on focus window - */ - if (toplevel && xwindow == toplevel->focus_window) - { - switch (xevent->type) - { - case KeyPress: - case KeyRelease: - xwindow = GDK_WINDOW_XID (window); - xevent->xany.window = xwindow; - break; - default: - return FALSE; - } - } - } + window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl); + + /* Move key events on focus window to the real toplevel, and + * filter out all other events on focus window + */ + if (toplevel && xwindow == toplevel->focus_window) + { + switch (xevent->type) + { + case KeyPress: + case KeyRelease: + xwindow = GDK_WINDOW_XID (window); + xevent->xany.window = xwindow; + break; + default: + return FALSE; + } + } g_object_ref (window); } diff --git a/gdk/x11/gdkimage-x11.c b/gdk/x11/gdkimage-x11.c index 06bf212bf9..be9f4df6db 100644 --- a/gdk/x11/gdkimage-x11.c +++ b/gdk/x11/gdkimage-x11.c @@ -195,26 +195,6 @@ gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint width, gint height) return(image); } /* gdk_image_new_bitmap() */ -/* - * Desc: query the server for support for the MIT_SHM extension - * Return: 0 = not available - * 1 = shared XImage support available - * 2 = shared Pixmap support available also - */ -static int -gdk_image_check_xshm(Display *display) -{ -#ifdef USE_SHM - int major, minor; - Bool pixmaps; - - if (XShmQueryExtension (display) && - XShmQueryVersion (display, &major, &minor, &pixmaps)) - return pixmaps ? 2 : 1; -#endif /* USE_SHM */ - return 0; -} - void _gdk_windowing_image_init (GdkDisplay *display) { @@ -222,12 +202,23 @@ _gdk_windowing_image_init (GdkDisplay *display) if (display_x11->use_xshm) { - gint res = gdk_image_check_xshm (GDK_DISPLAY_XDISPLAY (display)); - - if (!res) - display_x11->use_xshm = False; +#ifdef USE_SHM + Display *xdisplay = display_x11->xdisplay; + int major, minor, event_base; + Bool pixmaps; + + if (XShmQueryExtension (xdisplay) && + XShmQueryVersion (xdisplay, &major, &minor, &pixmaps)) + { + display_x11->have_shm_pixmaps = pixmaps; + event_base = XShmGetEventBase (xdisplay); + + _gdk_x11_register_event_type (display, + event_base, ShmNumberEvents); + } else - display_x11->have_shm_pixmaps = (res == 2); + display_x11->use_xshm = TRUE; +#endif /* USE_SHM */ } } diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c index bfbadc5f50..adcf0da5c7 100644 --- a/gdk/x11/gdkinput-x11.c +++ b/gdk/x11/gdkinput-x11.c @@ -385,18 +385,17 @@ _gdk_input_common_init (GdkDisplay *display, XDeviceInfo *devices; int num_devices; int num_extensions, loop; + int ignore, event_base; GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); /* Init XInput extension */ - - extensions = XListExtensions(display_x11->xdisplay, &num_extensions); - for (loop = 0; loop < num_extensions && - (strcmp(extensions[loop], "XInputExtension") != 0); loop++); - XFreeExtensionList(extensions); + display_x11->input_devices = NULL; - if (loop < num_extensions) + if (XQueryExtension (display_x11->xdisplay, "XInputExtension", + &ignore, &event_base, &ignore)) { - /* XInput extension found */ + _gdk_x11_register_event_type (display, + event_base, 9 /* Number of events */); devices = XListInputDevices(display_x11->xdisplay, &num_devices); diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index 3543d86cc6..93d226a71f 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -170,6 +170,9 @@ gboolean _gdk_x11_display_is_root_window (GdkDisplay *display, void _gdk_x11_precache_atoms (GdkDisplay *display, const gchar * const *atom_names, gint n_atoms); +void _gdk_x11_register_event_type (GdkDisplay *display, + gint event_base, + gint n_events); void _gdk_x11_events_init_screen (GdkScreen *screen); void _gdk_x11_events_uninit_screen (GdkScreen *screen); |