From 584c50216245086f728bab81ca4df8c9d3b9bca2 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Sat, 26 Dec 2009 10:35:42 +0000 Subject: [PATCH] Play with XI2. SVN revision: 44721 --- configure.ac | 8 ++++ src/E.h | 1 + src/Makefile.am | 5 ++- src/edebug.h | 1 + src/events.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ src/x.c | 43 ++++++++++++++++++ src/xwin.h | 3 ++ 7 files changed, 173 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fbad45e0..038bec9c 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,13 @@ if test "x$enable_xft" = "xyes"; then fi AM_CONDITIONAL(USE_LIBXFT, test "x$enable_xft" = "xyes") +AC_ARG_ENABLE(xi2, + [ --enable-xi2 compile with XI2 support (experimental) @<:@default=no@:>@],, + enable_xi2=no) +if test "x$enable_xi2" = "xyes"; then + PKG_CHECK_MODULES(XI, xi >= 1.3, AC_DEFINE(USE_XI2, 1, [XI2 support]), enable_xi2=no) +fi + AC_ARG_ENABLE(ecore, [ --enable-ecore use ecore functions (for testing only - DO NOT USE!) @<:@default=no@:>@],, enable_ecore=no) @@ -435,6 +442,7 @@ echo " Compile with ecore/ecore_x ... $enable_ecore" echo " GLX .......................... $enable_glx" echo " ScreenSaver .................. $enable_xscrnsaver" echo " D-Bus ........................ $enable_dbus" +echo " XI2 .......................... $enable_xi2" echo echo "Installation path .............. $prefix" echo " Install HTML docs ............ $enable_docs" diff --git a/src/E.h b/src/E.h index 6ea4d7f8..bd9195f0 100644 --- a/src/E.h +++ b/src/E.h @@ -127,6 +127,7 @@ #define XEXT_FIXES 6 #define XEXT_RENDER 7 #define XEXT_GLX 8 +#define XEXT_XI 9 #define XEXT_CM_ALL 16 diff --git a/src/Makefile.am b/src/Makefile.am index 65c46a0a..2f971b2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -121,7 +121,9 @@ e16_CPPFLAGS = -I$(top_builddir) \ $(MODULE_CFLAGS) \ $(IMLIB2_CFLAGS) \ $(DBUS_CFLAGS) \ - $(X_CFLAGS) $(CWARNFLAGS) \ + $(XI_CFLAGS) \ + $(X_CFLAGS) \ + $(CWARNFLAGS) \ -D LOCALEDIR=\"$(datadir)/locale\" \ -D ENLIGHTENMENT_BIN=\"$(bindir)\" \ -D ENLIGHTENMENT_LIB=\"$(pkglibdir)\" \ @@ -134,6 +136,7 @@ LDADD = \ $(IMLIB2_LIBS) \ $(MODULE_LIBS) \ $(GLX_LIBS) \ + $(XI_LIBS) \ $(X_LIBS) \ $(SM_LIBS) \ $(XINERAMA_LIBS) \ diff --git a/src/edebug.h b/src/edebug.h index 7f1c6fc1..c7c5aa5c 100644 --- a/src/edebug.h +++ b/src/edebug.h @@ -54,6 +54,7 @@ #define EDBUG_TYPE_TIMERS 150 #define EDBUG_TYPE_IDLERS 151 #define EDBUG_TYPE_SOUND 152 +#define EDBUG_TYPE_XI2 153 #define EDBUG_TYPE_COMPMGR 161 #define EDBUG_TYPE_COMPMGR2 162 diff --git a/src/events.c b/src/events.c index 82c37e91..95618082 100644 --- a/src/events.c +++ b/src/events.c @@ -49,6 +49,9 @@ #if USE_GLX #include #endif +#if USE_XI2 +#include +#endif #if ENABLE_DEBUG_EVENTS static const char *EventName(unsigned int type); @@ -153,6 +156,64 @@ ExtInitRR(int available) } #endif +#if USE_XI2 +static int xi_major_op = 0; + +static Bool +EInputQueryExtension(Display * dpy, + int *event_base_return, int *error_base_return) +{ + return XQueryExtension(dpy, "XInputExtension", &xi_major_op, + event_base_return, error_base_return); +} + +static Status +EInputQueryVersion(Display * dpy, + int *major_version_return, int *minor_version_return) +{ + *major_version_return = XI_2_Major; + *minor_version_return = XI_2_Minor; + + return XIQueryVersion(dpy, major_version_return, minor_version_return); +} + +#include "X11/extensions/XInput.h" + +static void +ExtInitInput(int available) +{ + int i, j, nd; + XDeviceInfo *dvi, *dvis; + char *p; + + if (!available) + return; + + if (!EDebug(EDBUG_TYPE_VERBOSE)) + return; + + dvis = XListInputDevices(disp, &nd); + Eprintf("Dev id nc use name\n"); + for (i = 0; i < nd; i++) + { + dvi = dvis + i; + Eprintf(" %2d %#3lx %d %d %-32s", i, + dvi->id, dvi->num_classes, dvi->use, dvi->name); + p = (char *)dvi->inputclassinfo; + for (j = 0; j < dvi->num_classes; j++) + { + XAnyClassPtr pcany = (XAnyClassPtr) p; + + printf(" %#3lx %3d", pcany->class, pcany->length); + p += pcany->length; + } + printf("\n"); + + } + XFreeDeviceList(dvis); +} +#endif + static const EServerExt Extensions[] = { {"Shape", XEXT_SHAPE, XShapeQueryExtension, XShapeQueryVersion, ExtInitShape}, @@ -176,6 +237,9 @@ static const EServerExt Extensions[] = { #if USE_GLX {"GLX", XEXT_GLX, glXQueryExtension, glXQueryVersion, NULL}, #endif +#if USE_XI2 + {"Input", XEXT_XI, EInputQueryExtension, EInputQueryVersion, ExtInitInput}, +#endif }; static void @@ -634,6 +698,47 @@ EventsCompress(XEvent * evq, int count) #endif } +#if USE_XI2 +static void +EventFetchXI2(XEvent * ev) +{ + XIDeviceEvent *xie; + + if (!XGetEventData(disp, &ev->xcookie)) + return; + + xie = (XIDeviceEvent *) ev->xcookie.data; + + if (EDebug(EDBUG_TYPE_XI2)) + Eprintf("%s: %#lx: XI2 ext=%d type=%d devid=%d srcid=%d\n", + "EventsFetch", xie->event, xie->extension, + xie->evtype, xie->deviceid, xie->sourceid); + + switch (ev->xcookie.evtype) + { + default: + break; + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + ev->type = ev->xcookie.evtype; + ev->xbutton.window = xie->event; + ev->xbutton.root = xie->root; + ev->xbutton.subwindow = xie->child; + ev->xbutton.time = xie->time; + ev->xbutton.x = (int)xie->event_x; + ev->xbutton.y = (int)xie->event_y; + ev->xbutton.x_root = (int)xie->root_x; + ev->xbutton.y_root = (int)xie->root_y; + ev->xbutton.button = xie->detail; + ev->xbutton.state = xie->mods.effective; + ev->xbutton.same_screen = 1; /* FIXME */ + break; + } + XFreeEventData(disp, &ev->xcookie); +} +#endif + static int EventsFetch(XEvent ** evq_p, int *evq_n) { @@ -654,6 +759,14 @@ EventsFetch(XEvent ** evq_p, int *evq_n) for (; i < count; i++, ev++) { XNextEvent(disp, ev); +#if USE_XI2 + if (ev->type == GenericEvent) + { + if (ev->xcookie.extension == xi_major_op) + EventFetchXI2(ev); + continue; + } +#endif /* USE_XI2 */ /* Map some event types to E internals */ if (ev->type == event_base_shape + ShapeNotify) diff --git a/src/x.c b/src/x.c index 91f1bac7..03e85db9 100644 --- a/src/x.c +++ b/src/x.c @@ -40,6 +40,9 @@ #if USE_GLX #include "eglx.h" #endif +#if USE_XI2 +#include "X11/extensions/XInput2.h" +#endif #define DEBUG_XWIN 0 #define DEBUG_PIXMAP 0 @@ -1018,18 +1021,58 @@ ESetWindowBackground(Win win, unsigned int col) void ESelectInput(Win win, unsigned int event_mask) { +#if USE_XI2 + +#define EVENTS_TO_XI \ + (/* KeyPressMask | KeyReleaseMask | */ \ + ButtonPressMask | ButtonReleaseMask | PointerMotionMask) + + win->event_mask = event_mask; + + if (Mode.server.extensions & XEXT_XI) + { + XIEventMask em; + unsigned char mask[(XI_LASTEVENT + 8) / 8]; + + em.deviceid = XIAllMasterDevices; /* XIAllDevices; */ + em.mask_len = sizeof(mask); + em.mask = mask; + memset(mask, 0, sizeof(mask)); +#if 0 + if (event_mask & KeyPressMask) + XISetMask(mask, XI_KeyPress); + if (event_mask & KeyReleaseMask) + XISetMask(mask, XI_KeyRelease); +#endif + if (event_mask & ButtonPressMask) + XISetMask(mask, XI_ButtonPress); + if (event_mask & ButtonReleaseMask) + XISetMask(mask, XI_ButtonRelease); + if (event_mask & PointerMotionMask) + XISetMask(mask, XI_Motion); + XISelectEvents(disp, win->xwin, &em, 1); + event_mask &= ~EVENTS_TO_XI; + } +#endif + XSelectInput(disp, win->xwin, event_mask); } void ESelectInputChange(Win win, unsigned int set, unsigned int clear) { +#if USE_XI2 + win->event_mask |= set; + win->event_mask &= ~clear; + ESelectInput(win, win->event_mask); +#else XWindowAttributes xwa; XGetWindowAttributes(disp, win->xwin, &xwa); xwa.your_event_mask |= set; xwa.your_event_mask &= ~clear; XSelectInput(disp, win->xwin, xwa.your_event_mask); +#endif } void diff --git a/src/xwin.h b/src/xwin.h index 315f6b6b..48fc3c59 100644 --- a/src/xwin.h +++ b/src/xwin.h @@ -111,6 +111,9 @@ struct _xwin { Colormap cmap; Pixmap bgpmap; unsigned int bgcol; +#if USE_XI2 + unsigned int event_mask; +#endif }; Win ELookupXwin(Window xwin);