]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkasync.c
moved and renamed the gdk_settings_names and gdk_settings_map.
[~andy/gtk] / gdk / x11 / gdkasync.c
index 06dc6d8ca79e30bf6ec1b8b533005d47331ba3c2..e360bf1a15c5c210be5aadf6d9274a7e115dc2c6 100644 (file)
@@ -43,12 +43,18 @@ used in advertising or otherwise to promote the sale, use or other dealings
 in this Software without prior written authorization from The Open Group.
 
 */
+#include <config.h>
+#ifdef NEED_XIPROTO_H_FOR_XREPLY
+#include <X11/extensions/XIproto.h>
+#endif
 #include <X11/Xlibint.h>
 #include "gdkasync.h"
 #include "gdkx.h"
+#include "gdkalias.h"
 
 typedef struct _ChildInfoChildState ChildInfoChildState;
 typedef struct _ChildInfoState ChildInfoState;
+typedef struct _ListChildrenState ListChildrenState;
 typedef struct _SendEventState SendEventState;
 typedef struct _SetInputFocusState SetInputFocusState;
 
@@ -78,6 +84,14 @@ struct _ChildInfoState
   gboolean child_has_error;
 };
 
+struct _ListChildrenState
+{
+  Display *dpy;
+  gulong get_property_req;
+  gboolean have_error;
+  gboolean has_wm_state;
+};
+
 struct _SendEventState
 {
   Display *dpy;
@@ -137,24 +151,67 @@ send_event_handler (Display *dpy,
 
       DeqAsyncHandler(state->dpy, &state->async);
 
+      g_free (state);
+
       return (rep->generic.type != X_Error);
     }
 
   return False;
 }
 
+static void
+client_message_to_wire (XClientMessageEvent *ev,
+                       xEvent              *event)
+{
+  int i;
+  event->u.clientMessage.window = ev->window;
+  event->u.u.type = ev->type;
+  event->u.u.detail = ev->format;
+  switch (ev->format)
+    {
+    case 8:    
+      event->u.clientMessage.u.b.type   = ev->message_type;
+      for (i = 0; i < 20; i++)
+       event->u.clientMessage.u.b.bytes[i] = ev->data.b[i];
+      break;
+    case 16:
+      event->u.clientMessage.u.s.type   = ev->message_type;
+      event->u.clientMessage.u.s.shorts0   = ev->data.s[0];
+      event->u.clientMessage.u.s.shorts1   = ev->data.s[1];
+      event->u.clientMessage.u.s.shorts2   = ev->data.s[2];
+      event->u.clientMessage.u.s.shorts3   = ev->data.s[3];
+      event->u.clientMessage.u.s.shorts4   = ev->data.s[4];
+      event->u.clientMessage.u.s.shorts5   = ev->data.s[5];
+      event->u.clientMessage.u.s.shorts6   = ev->data.s[6];
+      event->u.clientMessage.u.s.shorts7   = ev->data.s[7];
+      event->u.clientMessage.u.s.shorts8   = ev->data.s[8];
+      event->u.clientMessage.u.s.shorts9   = ev->data.s[9];
+      break;
+    case 32:
+      event->u.clientMessage.u.l.type   = ev->message_type;
+      event->u.clientMessage.u.l.longs0   = ev->data.l[0];
+      event->u.clientMessage.u.l.longs1   = ev->data.l[1];
+      event->u.clientMessage.u.l.longs2   = ev->data.l[2];
+      event->u.clientMessage.u.l.longs3   = ev->data.l[3];
+      event->u.clientMessage.u.l.longs4   = ev->data.l[4];
+      break;
+    default:
+      /* client passing bogus data, let server complain */
+      break;
+    }
+}
+
 void
-_gdk_x11_send_xevent_async (GdkDisplay           *display, 
-                           Window                window, 
-                           gboolean              propagate,
-                           glong                 event_mask,
-                           XEvent               *event_send,
-                           GdkSendXEventCallback callback,
-                           gpointer              data)
+_gdk_x11_send_client_message_async (GdkDisplay           *display, 
+                                   Window                window, 
+                                   gboolean              propagate,
+                                   glong                 event_mask,
+                                   XClientMessageEvent  *event_send,
+                                   GdkSendXEventCallback callback,
+                                   gpointer              data)
 {
   Display *dpy;
   SendEventState *state;
-  Status status;
   
   dpy = GDK_DISPLAY_XDISPLAY (display);
 
@@ -176,24 +233,8 @@ _gdk_x11_send_xevent_async (GdkDisplay           *display,
   {
     register xSendEventReq *req;
     xEvent ev;
-    register Status (**fp)();
     
-    /* call through display to find proper conversion routine */
-    
-    fp = &dpy->wire_vec[event_send->type & 0177];
-    if (*fp == NULL) *fp = _XEventToWire;
-    status = (**fp)(dpy, event_send, &ev);
-    
-    if (!status)
-      {
-       g_warning ("Error converting event to wire");
-       DeqAsyncHandler(dpy, &state->async);
-       UnlockDisplay(dpy);
-       SyncHandle();
-       g_free (state);
-
-       return;
-      }
+    client_message_to_wire (event_send, &ev);
       
     GetReq(SendEvent, req);
     req->destination = window;
@@ -316,6 +357,116 @@ _gdk_x11_set_input_focus_safe (GdkDisplay             *display,
   SyncHandle();
 }
 
+static Bool
+list_children_handler (Display *dpy,
+                      xReply  *rep,
+                      char    *buf,
+                      int      len,
+                      XPointer data)
+{
+  ListChildrenState *state = (ListChildrenState *)data;
+
+  if (dpy->last_request_read != state->get_property_req)
+    return False;
+  
+  if (rep->generic.type == X_Error)
+    {
+      state->have_error = TRUE;
+      return False;
+    }
+  else
+    {
+      xGetPropertyReply replbuf;
+      xGetPropertyReply *repl;
+           
+      repl = (xGetPropertyReply *)
+       _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
+                       (sizeof(xGetPropertyReply) - sizeof(xReply)) >> 2,
+                       True);
+
+      state->has_wm_state = repl->propertyType != None;
+      /* Since we called GetProperty with longLength of 0, we don't
+       * have to worry about consuming the property data that would
+       * normally follow after the reply
+       */
+
+      return True;
+    }
+}
+
+static gboolean
+list_children_and_wm_state (Display      *dpy,
+                           Window        w,
+                           Atom          wm_state_atom,
+                           gboolean     *has_wm_state,
+                           Window      **children,
+                           unsigned int *nchildren)
+{
+  ListChildrenState state;
+  _XAsyncHandler async;
+  long nbytes;
+  xQueryTreeReply rep;
+  register xResourceReq *req;
+  xGetPropertyReq *prop_req;
+
+  LockDisplay(dpy);
+
+  *children = NULL;
+  *nchildren = 0;
+  *has_wm_state = FALSE;
+  
+  state.have_error = FALSE;
+  state.has_wm_state = FALSE;
+
+  if (wm_state_atom)
+    {
+      async.next = dpy->async_handlers;
+      async.handler = list_children_handler;
+      async.data = (XPointer) &state;
+      dpy->async_handlers = &async;
+
+      GetReq (GetProperty, prop_req);
+      prop_req->window = w;
+      prop_req->property = wm_state_atom;
+      prop_req->type = AnyPropertyType;
+      prop_req->delete = False;
+      prop_req->longOffset = 0;
+      prop_req->longLength = 0;
+      
+      state.get_property_req = dpy->request;
+    }
+  
+  GetResReq(QueryTree, w, req);
+  if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
+    {
+      state.have_error = TRUE;
+      goto out;
+    }
+
+  if (rep.nChildren != 0)
+    {
+      nbytes = rep.nChildren << 2;
+      if (state.have_error)
+       {
+         _XEatData(dpy, (unsigned long) nbytes);
+         goto out;
+       }
+      *children = g_new (Window, rep.nChildren);
+      _XRead32 (dpy, (long *) *children, nbytes);
+    }
+
+  *nchildren = rep.nChildren;
+  *has_wm_state = state.has_wm_state;
+
+ out:
+  if (wm_state_atom)
+    DeqAsyncHandler(dpy, &async);
+  UnlockDisplay(dpy);
+  SyncHandle();
+  
+  return !state.have_error;
+}
+
 static void
 handle_get_wa_reply (Display                   *dpy,
                     ChildInfoState            *state,
@@ -454,14 +605,15 @@ gboolean
 _gdk_x11_get_window_child_info (GdkDisplay       *display,
                                Window            window,
                                gboolean          get_wm_state,
+                               gboolean         *win_has_wm_state,
                                GdkChildInfoX11 **children,
                                guint            *nchildren)
 {
   Display *dpy;
   _XAsyncHandler async;
   ChildInfoState state;
-  Window root, parent;
   Atom wm_state_atom;
+  gboolean has_wm_state;
   Bool result;
   guint i;
 
@@ -469,14 +621,38 @@ _gdk_x11_get_window_child_info (GdkDisplay       *display,
   *nchildren = 0;
   
   dpy = GDK_DISPLAY_XDISPLAY (display);
-  wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE");
+  if (get_wm_state)
+    wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE");
+  else
+    wm_state_atom = None;
+
+  state.children = NULL;
+  state.nchildren = 0;
 
   gdk_error_trap_push ();
-  result = XQueryTree (dpy, window, &root, &parent,
-                      &state.children, &state.nchildren);
+  result = list_children_and_wm_state (dpy, window,
+                                      win_has_wm_state ? wm_state_atom : None,
+                                      &has_wm_state,
+                                      &state.children, &state.nchildren);
   gdk_error_trap_pop ();
   if (!result)
-    return FALSE;
+    {
+      g_free (state.children);
+      return FALSE;
+    }
+
+  if (has_wm_state)
+    {
+      if (win_has_wm_state)
+       *win_has_wm_state = TRUE;
+      g_free (state.children);
+      return TRUE;
+    }
+  else
+    {
+      if (win_has_wm_state)
+       *win_has_wm_state = FALSE;
+    }
 
   state.get_wm_state = get_wm_state;
   state.child_info = g_new (GdkChildInfoX11, state.nchildren);
@@ -547,7 +723,7 @@ _gdk_x11_get_window_child_info (GdkDisplay       *display,
       g_free (state.child_info);
     }
 
-  XFree (state.children);
+  g_free (state.children);
   g_free (state.child_states);
   
   DeqAsyncHandler(dpy, &async);
@@ -557,3 +733,5 @@ _gdk_x11_get_window_child_info (GdkDisplay       *display,
   return !state.have_error;
 }
 
+#define __GDK_ASYNC_C__
+#include "gdkaliasdef.c"