diff options
author | Julien Danjou <julien@danjou.info> | 2009-01-28 16:13:42 +0100 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2009-04-03 12:58:59 +0200 |
commit | 15c0bae76e0bcd5d2839a791cf51c8b22e615fe2 (patch) | |
tree | 1d0d8843cc2c5501d7804fe9f9ada53ecf455c79 | |
parent | 3dfbceccffe5c7d44f4acc9cde4ed4e8e2e2ce36 (diff) | |
download | startup-notification-15c0bae76e0bcd5d2839a791cf51c8b22e615fe2.tar.gz |
Add XCB backend
Signed-off-by: Julien Danjou <julien@danjou.info>
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.in | 18 | ||||
-rw-r--r-- | libsn/sn-common.c | 264 | ||||
-rw-r--r-- | libsn/sn-common.h | 31 | ||||
-rw-r--r-- | libsn/sn-internals.h | 18 | ||||
-rw-r--r-- | libsn/sn-xmessages.c | 244 | ||||
-rw-r--r-- | libsn/sn-xutils.c | 53 |
8 files changed, 532 insertions, 103 deletions
@@ -1 +1,2 @@ -Havoc Pennington <hp@redhat.com>
\ No newline at end of file +Havoc Pennington <hp@redhat.com> +Julien Danjou <julien@danjou.info> @@ -1,3 +1,7 @@ +2009-01-28 Julien Danjou <julien@danjou.info> + + * add xcb support + 2007-03-17 Elijah Newren <newren gmail com> * configure.in: post-release bump to 0.10. diff --git a/configure.in b/configure.in index 7ce5ce8..dad1c2f 100644 --- a/configure.in +++ b/configure.in @@ -78,8 +78,22 @@ fi ## try definining HAVE_BACKTRACE AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)]) -LIBSN_CFLAGS=$X_CFLAGS -LIBSN_LIBS=" $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" +AC_ARG_WITH([xcb], AS_HELP_STRING([--with-xcb], [build with XCB library])) + +if test "x$with_xcb" = "xyes"; then + PKG_CHECK_MODULES([xcb], [xcb],, + [AC_MSG_ERROR([Cannot find xcb])]) + PKG_CHECK_MODULES([xcb_aux], [xcb-aux],, + [AC_MSG_ERROR([Cannot find xcb-aux])]) + PKG_CHECK_MODULES([xcb_event], [xcb-event],, + [AC_MSG_ERROR([Cannot find xcb-event])]) + PKG_CHECK_MODULES([xcb_atom], [xcb-atom],, + [AC_MSG_ERROR([Cannot find xcb-atom])]) + AC_DEFINE([HAVE_XCB],1,[Defined to use xcb]) +fi + +LIBSN_CFLAGS="$X_CFLAGS $xcb_CFLAGS $xcb_aux_CFLAGS $xcb_event_CFLAGS $xcb_atom_CFLAGS" +LIBSN_LIBS=" $xcb_LIBS $xcb_aux_LIBS $xcb_event_LIBS $xcb_atom_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" AC_SUBST(LIBSN_CFLAGS) AC_SUBST(LIBSN_LIBS) diff --git a/libsn/sn-common.c b/libsn/sn-common.c index d5c52c0..66ca2b6 100644 --- a/libsn/sn-common.c +++ b/libsn/sn-common.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2009 Julien Danjou <julien@danjou.info> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,14 +27,35 @@ #include "sn-common.h" #include "sn-internals.h" +#ifdef HAVE_XCB +#include <xcb/xcb.h> +#include <xcb/xcb_aux.h> +#endif + struct SnDisplay { int refcount; - Display *xdisplay; + enum SnDisplayType type; + union + { + struct + { + Display *xdisplay; + Screen **screens; + SnDisplayErrorTrapPush push_trap_func; + SnDisplayErrorTrapPop pop_trap_func; + } xlib; +#ifdef HAVE_XCB + struct + { + xcb_connection_t *xconnection; + xcb_screen_t **screens; + SnXcbDisplayErrorTrapPush push_trap_func; + SnXcbDisplayErrorTrapPop pop_trap_func; + } xcb; +#endif + } x; int n_screens; - Screen **screens; - SnDisplayErrorTrapPush push_trap_func; - SnDisplayErrorTrapPop pop_trap_func; SnList *xmessage_funcs; SnList *pending_messages; }; @@ -67,19 +89,66 @@ sn_display_new (Display *xdisplay, display = sn_new0 (SnDisplay, 1); - display->xdisplay = xdisplay; + display->type = SN_DISPLAY_TYPE_XLIB; + display->x.xlib.xdisplay = xdisplay; display->n_screens = ScreenCount (xdisplay); - display->screens = sn_new (Screen*, display->n_screens); + display->x.xlib.screens = sn_new (Screen*, display->n_screens); + display->refcount = 1; + + display->x.xlib.push_trap_func = push_trap_func; + display->x.xlib.pop_trap_func = pop_trap_func; + + for (i = 0; i < display->n_screens; ++i) + display->x.xlib.screens[i] = ScreenOfDisplay (display->x.xlib.xdisplay, i); + + return display; +} + +#ifdef HAVE_XCB +/** + * sn_xcb_display_new: + * @xdisplay: an X window system display + * @push_trap_func: function to push an X error trap + * @pop_trap_func: function to pop an X error trap + * + * Creates a new #SnDisplay object, containing + * data that libsn associates with an X display. + * + * @push_trap_func should be a function that causes X errors to be + * ignored until @pop_trap_func is called as many times as + * @push_trap_func has been called. (Nested push/pop pairs must be + * supported.) The outermost @pop_trap_func in a set of nested pairs + * must call XSync() to ensure that all errors that will occur have in + * fact occurred. These functions are used to avoid X errors due to + * BadWindow and such. + * + * Return value: the new #SnDisplay + **/ +SnDisplay* +sn_xcb_display_new (xcb_connection_t *xconnection, + SnXcbDisplayErrorTrapPush push_trap_func, + SnXcbDisplayErrorTrapPop pop_trap_func) +{ + SnDisplay *display; + int i; + + display = sn_new0 (SnDisplay, 1); + + display->type = SN_DISPLAY_TYPE_XCB; + display->x.xcb.xconnection = xconnection; + display->n_screens = xcb_setup_roots_length (xcb_get_setup (xconnection)); + display->x.xcb.screens = sn_new (xcb_screen_t*, display->n_screens); display->refcount = 1; - display->push_trap_func = push_trap_func; - display->pop_trap_func = pop_trap_func; + display->x.xcb.push_trap_func = push_trap_func; + display->x.xcb.pop_trap_func = pop_trap_func; for (i = 0; i < display->n_screens; ++i) - display->screens[i] = ScreenOfDisplay (display->xdisplay, i); + display->x.xcb.screens[i] = xcb_aux_get_screen(xconnection, i); return display; } +#endif /** * sn_display_ref: @@ -110,7 +179,19 @@ sn_display_unref (SnDisplay *display) sn_list_free (display->xmessage_funcs); if (display->pending_messages) sn_list_free (display->pending_messages); - sn_free (display->screens); +#ifdef HAVE_XCB + switch (display->type) + { + case SN_DISPLAY_TYPE_XCB: + sn_free (display->x.xcb.screens); + break; + case SN_DISPLAY_TYPE_XLIB: +#endif + sn_free (display->x.xlib.screens); +#ifdef HAVE_XCB + break; + } +#endif sn_free (display); } } @@ -126,9 +207,28 @@ sn_display_unref (SnDisplay *display) Display* sn_display_get_x_display (SnDisplay *display) { + if(display->type == SN_DISPLAY_TYPE_XLIB) + return display->x.xlib.xdisplay; + return NULL; +} - return display->xdisplay; +#ifdef HAVE_XCB +/** + * sn_display_get_x_connection: + * @display: an #SnDisplay + * + * + * + * Return value: X connection for this #SnDisplay + **/ +xcb_connection_t* +sn_display_get_x_connection(SnDisplay *display) +{ + if(display->type == SN_DISPLAY_TYPE_XCB) + return display->x.xcb.xconnection; + return NULL; } +#endif /** * sn_internal_display_get_id: @@ -141,27 +241,38 @@ sn_display_get_x_display (SnDisplay *display) void * sn_internal_display_get_id (SnDisplay *display) { - return display->xdisplay; +#ifdef HAVE_XCB + switch (display->type) + { + case SN_DISPLAY_TYPE_XLIB: +#endif + return display->x.xlib.xdisplay; +#ifdef HAVE_XCB + case SN_DISPLAY_TYPE_XCB: + return display->x.xcb.xconnection; + } + return NULL; +#endif } /** * sn_internal_display_get_x_screen: * @display: an #SnDisplay * @number: screen number to get - * + * * Gets a screen by number; if the screen number * does not exist, returns %NULL. - * + * * Return value: X screen or %NULL **/ Screen* sn_internal_display_get_x_screen (SnDisplay *display, int number) { - if (number < 0 || number >= display->n_screens) + if (display->type != SN_DISPLAY_TYPE_XLIB || number < 0 || number >= display->n_screens) return NULL; else - return display->screens[number]; + return display->x.xlib.screens[number]; } /** @@ -178,12 +289,58 @@ Window sn_internal_display_get_root_window (SnDisplay *display, int number) { - if (number < 0 || number >= display->n_screens) - return None; - return RootWindow (display->xdisplay, number); + if (number >= 0 && number < display->n_screens) +#ifdef HAVE_XCB + switch (display->type) + { + case SN_DISPLAY_TYPE_XLIB: +#endif + return RootWindow (display->x.xlib.xdisplay, number); +#ifdef HAVE_XCB + case SN_DISPLAY_TYPE_XCB: + return display->x.xcb.screens[number]->root; + } +#endif + return None; } /** + * sn_internal_display_get_type + * @display: an #SnDisplay + * + * + * + * Return value: X connection type + */ +enum SnDisplayType +sn_internal_display_get_type (SnDisplay *display) +{ + return display->type; +} + +#ifdef HAVE_XCB +/** + * sn_internal_display_get_x_screen: + * @display: an #SnDisplay + * @number: screen number to get + * + * Gets a screen by number; if the screen number + * does not exist, returns %NULL. + * + * Return value: X screen or %NULL + **/ +xcb_screen_t* +sn_internal_display_get_xcb_screen (SnDisplay *display, + int number) +{ + if (display->type != SN_DISPLAY_TYPE_XCB || number < 0 || number >= display->n_screens) + return NULL; + else + return display->x.xcb.screens[number]; +} +#endif + +/** * sn_internal_display_get_screen_number: * @display an #SnDisplay * @@ -230,6 +387,41 @@ sn_display_process_event (SnDisplay *display, return retval; } +#ifdef HAVE_XCB +/** + * sn_xcb_display_process_event: + * @display: a display + * @xevent: X event + * + * libsn should be given a chance to see all X events by passing them + * to this function. If the event was a property notify or client + * message related to the launch feedback protocol, the + * sn_display_process_event() returns true. Calling + * sn_display_process_event() is not currently required for launchees, + * only launchers and launch feedback displayers. The function returns + * false for mapping, unmapping, window destruction, and selection + * events even if they were involved in launch feedback. + * + * Return value: true if the event was a property notify or client message involved in launch feedback + **/ +sn_bool_t +sn_xcb_display_process_event (SnDisplay *display, + xcb_generic_event_t *xevent) +{ + sn_bool_t retval; + + retval = FALSE; + + if (sn_internal_monitor_process_event (display)) + retval = TRUE; + + if (sn_xcb_internal_xmessage_process_event (display, xevent)) + retval = TRUE; + + return retval; +} +#endif + /** * sn_display_error_trap_push: * @display: a display @@ -239,8 +431,21 @@ sn_display_process_event (SnDisplay *display, void sn_display_error_trap_push (SnDisplay *display) { - if (display->push_trap_func) - (* display->push_trap_func) (display, display->xdisplay); +#ifdef HAVE_XCB + switch (display->type) + { + case SN_DISPLAY_TYPE_XCB: + if (display->x.xcb.push_trap_func) + (* display->x.xcb.push_trap_func) (display, display->x.xcb.xconnection); + break; + case SN_DISPLAY_TYPE_XLIB: +#endif + if (display->x.xlib.push_trap_func) + (* display->x.xlib.push_trap_func) (display, display->x.xlib.xdisplay); +#ifdef HAVE_XCB + break; + } +#endif } /** @@ -252,8 +457,21 @@ sn_display_error_trap_push (SnDisplay *display) void sn_display_error_trap_pop (SnDisplay *display) { - if (display->pop_trap_func) - (* display->pop_trap_func) (display, display->xdisplay); +#ifdef HAVE_XCB + switch (display->type) + { + case SN_DISPLAY_TYPE_XCB: + if (display->x.xcb.pop_trap_func) + (* display->x.xcb.pop_trap_func) (display, display->x.xcb.xconnection); + break; + case SN_DISPLAY_TYPE_XLIB: +#endif + if (display->x.xlib.pop_trap_func) + (* display->x.xlib.pop_trap_func) (display, display->x.xlib.xdisplay); +#ifdef HAVE_XCB + break; + } +#endif } void diff --git a/libsn/sn-common.h b/libsn/sn-common.h index 79366ca..8fa34e8 100644 --- a/libsn/sn-common.h +++ b/libsn/sn-common.h @@ -29,6 +29,14 @@ #include <libsn/sn-util.h> #include <X11/Xlib.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_XCB +#include <xcb/xcb.h> +#endif + SN_BEGIN_DECLS #ifndef SN_API_NOT_YET_FROZEN @@ -42,14 +50,37 @@ typedef void (* SnDisplayErrorTrapPush) (SnDisplay *display, typedef void (* SnDisplayErrorTrapPop) (SnDisplay *display, Display *xdisplay); +#ifdef HAVE_XCB +typedef void (* SnXcbDisplayErrorTrapPush) (SnDisplay *display, + xcb_connection_t *xconnection); +typedef void (* SnXcbDisplayErrorTrapPop) (SnDisplay *display, + xcb_connection_t *xconnection); +#endif + SnDisplay* sn_display_new (Display *xdisplay, SnDisplayErrorTrapPush push_trap_func, SnDisplayErrorTrapPop pop_trap_func); + +#ifdef HAVE_XCB +SnDisplay* sn_xcb_display_new (xcb_connection_t *xconnection, + SnXcbDisplayErrorTrapPush push_trap_func, + SnXcbDisplayErrorTrapPop pop_trap_func); +#endif + void sn_display_ref (SnDisplay *display); void sn_display_unref (SnDisplay *display); Display* sn_display_get_x_display (SnDisplay *display); +#ifdef HAVE_XCB +xcb_connection_t* sn_display_get_x_connection (SnDisplay *display); +#endif + sn_bool_t sn_display_process_event (SnDisplay *display, XEvent *xevent); +#ifdef HAVE_XCB +sn_bool_t sn_xcb_display_process_event (SnDisplay *display, + xcb_generic_event_t *xevent); +#endif + void sn_display_error_trap_push (SnDisplay *display); void sn_display_error_trap_pop (SnDisplay *display); diff --git a/libsn/sn-internals.h b/libsn/sn-internals.h index 43ea186..1024d0b 100644 --- a/libsn/sn-internals.h +++ b/libsn/sn-internals.h @@ -49,6 +49,12 @@ SN_BEGIN_DECLS #define NULL ((void*) 0) #endif +enum SnDisplayType +{ + SN_DISPLAY_TYPE_XLIB, + SN_DISPLAY_TYPE_XCB +}; + /* --- From sn-common.c --- */ Screen* sn_internal_display_get_x_screen (SnDisplay *display, int number); @@ -59,6 +65,13 @@ int sn_internal_display_get_screen_number (SnDisplay *display); void* sn_internal_display_get_id (SnDisplay *display); +#ifdef HAVE_XCB +xcb_screen_t* sn_internal_display_get_xcb_screen (SnDisplay *display, + int number); +#endif + +enum SnDisplayType sn_internal_display_get_type (SnDisplay *display); + void sn_internal_display_get_xmessage_data (SnDisplay *display, SnList **funcs, SnList **pending); @@ -87,6 +100,11 @@ void sn_internal_append_to_string (char **append_to, sn_bool_t sn_internal_xmessage_process_event (SnDisplay *display, XEvent *xevent); +#ifdef HAVE_XCB +sn_bool_t sn_xcb_internal_xmessage_process_event (SnDisplay *display, + xcb_generic_event_t *xevent); +#endif + SN_END_DECLS #endif /* __SN_INTERNALS_H__ */ diff --git a/libsn/sn-xmessages.c b/libsn/sn-xmessages.c index ed1df71..1e1653b 100644 --- a/libsn/sn-xmessages.c +++ b/libsn/sn-xmessages.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2009 Julien Danjou <julien@danjou.info> * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -22,6 +23,12 @@ * SOFTWARE. */ +#include <config.h> + +#ifdef HAVE_XCB +#include <xcb/xcb_event.h> +#endif + #include "sn-xmessages.h" #include "sn-list.h" #include "sn-internals.h" @@ -145,11 +152,6 @@ sn_internal_broadcast_xmessage (SnDisplay *display, const char *message_type_begin, const char *message) { - Atom type_atom; - Atom type_atom_begin; - Window xwindow; - Display *xdisplay; - if (!sn_internal_utf8_validate (message, -1)) { fprintf (stderr, @@ -158,70 +160,137 @@ sn_internal_broadcast_xmessage (SnDisplay *display, return; } - xdisplay = sn_display_get_x_display (display); - +#ifdef HAVE_XCB + switch (sn_internal_display_get_type (display)) { - XSetWindowAttributes attrs; - - attrs.override_redirect = True; - attrs.event_mask = PropertyChangeMask | StructureNotifyMask; - - xwindow = - XCreateWindow (xdisplay, - RootWindow (xdisplay, 0), - -100, -100, 1, 1, - 0, - CopyFromParent, - CopyFromParent, - CopyFromParent, - CWOverrideRedirect | CWEventMask, - &attrs); - } - - type_atom = sn_internal_atom_get (display, message_type); - type_atom_begin = sn_internal_atom_get (display, message_type_begin); + case SN_DISPLAY_TYPE_XLIB: +#endif + { + Atom type_atom; + Atom type_atom_begin; + Window xwindow; + XSetWindowAttributes attrs; + Display *xdisplay = sn_display_get_x_display (display); - { - XEvent xevent; - const char *src; - const char *src_end; - char *dest; - char *dest_end; - - xevent.xclient.type = ClientMessage; - xevent.xclient.message_type = type_atom_begin; - xevent.xclient.display = xdisplay; - xevent.xclient.window = xwindow; - xevent.xclient.format = 8; - - src = message; - src_end = message + strlen (message) + 1; /* +1 to include nul byte */ + attrs.override_redirect = True; + attrs.event_mask = PropertyChangeMask | StructureNotifyMask; + + xwindow = + XCreateWindow (xdisplay, + RootWindow (xdisplay, 0), + -100, -100, 1, 1, + 0, + CopyFromParent, + CopyFromParent, + CopyFromParent, + CWOverrideRedirect | CWEventMask, + &attrs); + type_atom = sn_internal_atom_get (display, message_type); + type_atom_begin = sn_internal_atom_get (display, message_type_begin); - while (src != src_end) { - dest = &xevent.xclient.data.b[0]; - dest_end = dest + 20; + XEvent xevent; + const char *src; + const char *src_end; + char *dest; + char *dest_end; + + xevent.xclient.type = ClientMessage; + xevent.xclient.message_type = type_atom_begin; + xevent.xclient.display = xdisplay; + xevent.xclient.window = xwindow; + xevent.xclient.format = 8; + + src = message; + src_end = message + strlen (message) + 1; /* +1 to include nul byte */ - while (dest != dest_end && - src != src_end) + while (src != src_end) { - *dest = *src; - ++dest; - ++src; + dest = &xevent.xclient.data.b[0]; + dest_end = dest + 20; + + while (dest != dest_end && + src != src_end) + { + *dest = *src; + ++dest; + ++src; + } + + XSendEvent (xdisplay, + RootWindow (xdisplay, screen), + False, + PropertyChangeMask, + &xevent); + + xevent.xclient.message_type = type_atom; } - - XSendEvent (xdisplay, - RootWindow (xdisplay, screen), - False, - PropertyChangeMask, - &xevent); + } + + XDestroyWindow (xdisplay, xwindow); + XFlush (xdisplay); + } +#ifdef HAVE_XCB + break; + case SN_DISPLAY_TYPE_XCB: + { + xcb_atom_t type_atom; + xcb_atom_t type_atom_begin; + xcb_window_t xwindow; + uint32_t attrs[] = { 1, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY }; + xcb_connection_t *xconnection = sn_display_get_x_connection (display); + xcb_screen_t *s = sn_internal_display_get_xcb_screen (display, screen); + + xwindow = xcb_generate_id(xconnection); + xcb_create_window(xconnection, s->root_depth, xwindow, s->root, + -100, -100, 1, 1, 0, XCB_COPY_FROM_PARENT, s->root_visual, + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, + attrs); + + type_atom = sn_internal_atom_get (display, message_type); + type_atom_begin = sn_internal_atom_get (display, message_type_begin); + + { + xcb_client_message_event_t xevent; + const char *src; + const char *src_end; + unsigned char *dest; + unsigned char *dest_end; + + xevent.response_type = XCB_CLIENT_MESSAGE; + xevent.type = type_atom_begin; + xevent.window = xwindow; + xevent.format = 8; + + src = message; + src_end = message + strlen (message) + 1; /* +1 to include nul byte */ + + while (src != src_end) + { + dest = &xevent.data.data8[0]; + dest_end = dest + 20; + + while (dest != dest_end && + src != src_end) + { + *dest = *src; + ++dest; + ++src; + } - xevent.xclient.message_type = type_atom; + xcb_send_event (xconnection, 0, s->root, XCB_EVENT_MASK_PROPERTY_CHANGE, + (char *) &xevent); + + xevent.type = type_atom; + } } - } - XDestroyWindow (xdisplay, xwindow); - XFlush (xdisplay); + xcb_destroy_window (xconnection, xwindow); + xcb_flush(xconnection); + } + break; + } +#endif } typedef struct @@ -252,7 +321,8 @@ handler_for_atom_foreach (void *value, static sn_bool_t some_handler_handles_event (SnDisplay *display, - XEvent *xevent) + Atom atom, + Window win) { HandlerForAtomData hfad; SnList *xmessage_funcs; @@ -260,9 +330,9 @@ some_handler_handles_event (SnDisplay *display, sn_internal_display_get_xmessage_data (display, &xmessage_funcs, NULL); - hfad.atom = xevent->xclient.message_type; + hfad.atom = atom; hfad.xid = sn_internal_display_get_id (display); - hfad.xwindow = xevent->xclient.window; + hfad.xwindow = win; hfad.found_handler = FALSE; if (xmessage_funcs) @@ -367,7 +437,9 @@ get_or_add_message(SnList *pending_messages, static SnXmessage* add_event_to_messages (SnDisplay *display, - XEvent *xevent) + Window win, + Atom message_type, + const char *data) { SnXmessage *message; SnList *pending_messages; @@ -376,8 +448,7 @@ add_event_to_messages (SnDisplay *display, &pending_messages); message = get_or_add_message(pending_messages, - xevent->xclient.window, - xevent->xclient.message_type); + win, message_type); /* We don't want screwy situations to end up causing us to allocate * infinite memory. Cap the length of a message. @@ -393,7 +464,7 @@ add_event_to_messages (SnDisplay *display, return NULL; } - if (message_set_message (message, &xevent->xclient.data.b[0])) + if (message_set_message (message, data)) { /* Pull message out of the pending queue and return it */ sn_list_remove (pending_messages, message); @@ -476,11 +547,47 @@ sn_internal_xmessage_process_event (SnDisplay *display, switch (xevent->xany.type) { case ClientMessage: - if (some_handler_handles_event (display, xevent)) + if (some_handler_handles_event (display, + xevent->xclient.message_type, + xevent->xclient.window)) + { + retval = TRUE; + + message = add_event_to_messages (display, + xevent->xclient.window, + xevent->xclient.message_type, + xevent->xclient.data.b); + } + break; + } + + xmessage_process_message (display, message); + + return retval; +} + +#ifdef HAVE_XCB +sn_bool_t +sn_xcb_internal_xmessage_process_event (SnDisplay *display, + xcb_generic_event_t *xevent) +{ + sn_bool_t retval = FALSE; + SnXmessage *message = NULL; + xcb_client_message_event_t *ev = (xcb_client_message_event_t *) xevent; + + switch (XCB_EVENT_RESPONSE_TYPE(xevent)) + { + case XCB_CLIENT_MESSAGE: + if (some_handler_handles_event (display, + ev->type, + ev->window)) { retval = TRUE; - message = add_event_to_messages (display, xevent); + message = add_event_to_messages (display, + ev->window, + ev->type, + (const char *) ev->data.data8); } break; } @@ -489,6 +596,7 @@ sn_internal_xmessage_process_event (SnDisplay *display, return retval; } +#endif static void sn_internal_append_to_string_escaped (char **append_to, diff --git a/libsn/sn-xutils.c b/libsn/sn-xutils.c index b40b305..1fece87 100644 --- a/libsn/sn-xutils.c +++ b/libsn/sn-xutils.c @@ -22,17 +22,35 @@ * SOFTWARE. */ +#include <config.h> #include "sn-internals.h" #include <X11/Xutil.h> #include <X11/Xatom.h> +#ifdef HAVE_XCB +#include <xcb/xcb.h> +#include <xcb/xcb_atom.h> +#endif + Atom sn_internal_atom_get (SnDisplay *display, const char *atom_name) { - return XInternAtom (sn_display_get_x_display (display), - atom_name, - False); +#ifdef HAVE_XCB + switch (sn_internal_display_get_type (display)) + { + case SN_DISPLAY_TYPE_XLIB: +#endif + return XInternAtom (sn_display_get_x_display (display), + atom_name, + False); +#ifdef HAVE_XCB + case SN_DISPLAY_TYPE_XCB: + return xcb_atom_get (sn_display_get_x_connection (display), + atom_name); + } + return None; +#endif } void @@ -43,12 +61,29 @@ sn_internal_set_utf8_string (SnDisplay *display, { sn_display_error_trap_push (display); - XChangeProperty (sn_display_get_x_display (display), - xwindow, - sn_internal_atom_get (display, property), - sn_internal_atom_get (display, "UTF8_STRING"), - 8, PropModeReplace, (unsigned char*) str, - strlen (str)); +#ifdef HAVE_XCB + switch (sn_internal_display_get_type (display)) + { + case SN_DISPLAY_TYPE_XLIB: +#endif + XChangeProperty (sn_display_get_x_display (display), + xwindow, + sn_internal_atom_get (display, property), + sn_internal_atom_get (display, "UTF8_STRING"), + 8, PropModeReplace, (unsigned char*) str, + strlen (str)); +#ifdef HAVE_XCB + break; + case SN_DISPLAY_TYPE_XCB: + xcb_change_property (sn_display_get_x_connection (display), + XCB_PROP_MODE_REPLACE, + xwindow, + sn_internal_atom_get (display, property), + sn_internal_atom_get (display, "UTF8_STRING"), + 8, strlen (str), str); + break; + } +#endif sn_display_error_trap_pop (display); } |