summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-07-11 19:57:01 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-07-11 19:57:01 +0000
commit50da0ae808262ba787204baf6a9f544edf8aee25 (patch)
treea744a7c9753f082d94d9358a1cd41c40db8e0474 /gdk
parent7f8ae32c1d8c48cb361d1864c27a69f27f6a2dbd (diff)
downloadgtk+-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.c3
-rw-r--r--gdk/x11/gdkdisplay-x11.h7
-rw-r--r--gdk/x11/gdkevents-x11.c193
-rw-r--r--gdk/x11/gdkimage-x11.c41
-rw-r--r--gdk/x11/gdkinput-x11.c13
-rw-r--r--gdk/x11/gdkprivate-x11.h3
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);