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;
gboolean child_has_error;
};
+struct _ListChildrenState
+{
+ Display *dpy;
+ gulong get_property_req;
+ gboolean have_error;
+ gboolean has_wm_state;
+};
+
struct _SendEventState
{
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);
{
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;
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,
_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;
*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);
g_free (state.child_info);
}
- XFree (state.children);
+ g_free (state.children);
g_free (state.child_states);
DeqAsyncHandler(dpy, &async);
return !state.have_error;
}
+#define __GDK_ASYNC_C__
+#include "gdkaliasdef.c"