? gdk/x11/gdkasync-bak.c
? gdk/x11/gdkasync-bak.h
? gdk/x11/gdkasync-extras.c
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.4290
diff -u -p -u -p -r1.4290 ChangeLog
--- ChangeLog	8 Jul 2003 22:27:44 -0000	1.4290
+++ ChangeLog	9 Jul 2003 00:24:13 -0000
@@ -1,3 +1,18 @@
+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)
+	Dont' 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
+	and functions for extracting their window.
+
+	* gdk/x11/gdkevents-x11.c (gdk_event_translate):
+	Check to see if the result of gdk_window_lookup_for_display()
+	is actually a window.
+
 Tue Jul  8 17:36:21 2003  Owen Taylor  <otaylor@redhat.com>
 
 	* gdk/x11/gdkasync.[ch] gdk/gdkdnd-x11.c: 
Index: gdk/x11/gdkdisplay-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.c,v
retrieving revision 1.35
diff -u -p -u -p -r1.35 gdkdisplay-x11.c
--- gdk/x11/gdkdisplay-x11.c	5 Jul 2003 05:27:11 -0000	1.35
+++ gdk/x11/gdkdisplay-x11.c	9 Jul 2003 00:24:13 -0000
@@ -653,6 +653,9 @@ gdk_display_x11_finalize (GObject *objec
   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 */
Index: gdk/x11/gdkdisplay-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.h,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 gdkdisplay-x11.h
--- gdk/x11/gdkdisplay-x11.h	5 Jul 2003 15:02:35 -0000	1.11
+++ gdk/x11/gdkdisplay-x11.h	9 Jul 2003 00:24:13 -0000
@@ -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;
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.114
diff -u -p -u -p -r1.114 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	5 Jul 2003 15:02:35 -0000	1.114
+++ gdk/x11/gdkevents-x11.c	9 Jul 2003 00:24:13 -0000
@@ -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,13 @@ struct _GdkDisplaySource
   GPollFD event_poll_fd;
 };
 
+struct _GdkEventTypeX11
+{
+  gint base;
+  gint n_events;
+  GdkExtractWindowFunc extract;
+};
+
 /* 
  * Private function declarations
  */
@@ -639,50 +647,114 @@ translate_key_event (GdkDisplay *display
   return;
 }
 
+static void
+event_window_extract_default (GdkDisplay *display,
+			      gint        event_base,
+			      XEvent     *xev,
+			      Window     *event_window,
+			      Window     *filter_window)
+{
+  *event_window = xev->xany.window;
+  *filter_window = xev->xany.window;
+}
+
+void
+_gdk_x11_register_event_type (GdkDisplay          *display,
+			      gint                 event_base,
+			      gint                 n_events,
+			      GdkExtractWindowFunc extract)
+{
+  GdkEventTypeX11 *event_type;
+  GdkDisplayX11 *display_x11;
+
+  display_x11 = GDK_DISPLAY_X11 (display);
+  event_type = g_new (GdkEventTypeX11, 1);
+
+  event_type->base = event_base;
+  event_type->n_events = n_events;
+  event_type->extract = extract ? extract: event_window_extract_default;
+
+  display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type);
+}
+
 /* 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)
+static void
+get_real_window (GdkDisplay *display,
+		 XEvent     *event,
+		 Window     *event_window,
+		 Window     *filter_window)
 {
-  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;
-
-    case MapRequest:
-      return event->xmaprequest.window;
-
-    case ReparentNotify:
-     return event->xreparent.window;
-      
-    case ConfigureNotify:
-      return event->xconfigure.window;
-      
-    case ConfigureRequest:
-      return event->xconfigurerequest.window;
-
-    case GravityNotify:
-      return event->xgravity.window;
-
-    case CirculateNotify:
-      return event->xcirculate.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_type->extract (display, event_type->base, event,
+				   event_window, filter_window);
+	      return;
+	    }
+	}
+	   
+      *event_window = None;
+      *filter_window = None;
     }
 }
 
@@ -723,7 +795,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 +822,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 +853,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);
     }
Index: gdk/x11/gdkimage-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkimage-x11.c,v
retrieving revision 1.52
diff -u -p -u -p -r1.52 gdkimage-x11.c
--- gdk/x11/gdkimage-x11.c	5 Jul 2003 01:54:05 -0000	1.52
+++ gdk/x11/gdkimage-x11.c	9 Jul 2003 00:24:13 -0000
@@ -195,26 +195,6 @@ gdk_image_new_bitmap(GdkVisual *visual, 
   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,24 @@ _gdk_windowing_image_init (GdkDisplay *d
   
   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,
+					NULL); /* Events conform to XEventAny */
+	}
       else
-	display_x11->have_shm_pixmaps = (res == 2);
+	display_x11->use_xshm = TRUE;
+#endif /* USE_SHM */
     }
 }
 
Index: gdk/x11/gdkinput-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkinput-x11.c,v
retrieving revision 1.29
diff -u -p -u -p -r1.29 gdkinput-x11.c
--- gdk/x11/gdkinput-x11.c	3 Jun 2003 18:47:20 -0000	1.29
+++ gdk/x11/gdkinput-x11.c	9 Jul 2003 00:24:13 -0000
@@ -385,18 +385,18 @@ _gdk_input_common_init (GdkDisplay *disp
   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 */,
+				    NULL); /* Events conform to XEventAny */
 
       devices = XListInputDevices(display_x11->xdisplay, &num_devices);
   
Index: gdk/x11/gdkprivate-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkprivate-x11.h,v
retrieving revision 1.29
diff -u -p -u -p -r1.29 gdkprivate-x11.h
--- gdk/x11/gdkprivate-x11.h	5 Jul 2003 01:54:05 -0000	1.29
+++ gdk/x11/gdkprivate-x11.h	9 Jul 2003 00:24:13 -0000
@@ -57,6 +57,12 @@ typedef struct _GdkVisualPrivate       G
 typedef struct _GdkGCX11      GdkGCX11;
 typedef struct _GdkGCX11Class GdkGCX11Class;
 
+typedef void (*GdkExtractWindowFunc) (GdkDisplay *display,
+				      gint        event_base,
+				      XEvent     *xev,
+				      Window     *event_window,
+				      Window     *filter_window);
+
 struct _GdkGCX11
 {
   GdkGC parent_instance;
@@ -170,6 +176,10 @@ gboolean _gdk_x11_display_is_root_window
 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,
+				   GdkExtractWindowFunc extract);
 
 void _gdk_x11_events_init_screen   (GdkScreen *screen);
 void _gdk_x11_events_uninit_screen (GdkScreen *screen);
