Implement YDK Touch API for Linux/X11
This commit is contained in:
parent
89da2f2c87
commit
5cf392b17a
@ -164,6 +164,7 @@ def configure(conf):
|
||||
conf.check_cc(header_name='X11/extensions/Xinerama.h',
|
||||
lib='Xinerama', uselib_store="XINERAMA", define_name='HAVE_XFREE_XINERAMA',
|
||||
execute = False, mandatory=False)
|
||||
autowaf.check_pkg(conf, 'xi', uselib_store='XINPUT2', mandatory=False, atleast_version='1.7.10')
|
||||
|
||||
def build(bld):
|
||||
if not bld.is_defined('YTK'):
|
||||
@ -202,7 +203,7 @@ def build(bld):
|
||||
obj.ldflags = '-limm32 -lole32 -lgdi32 -lcomdlg32 -lwinspool -lcomctl32 -luuid'
|
||||
else:
|
||||
obj.source = libydk_sources + libydk_x11_sources
|
||||
obj.uselib += ' GIO-UNIX X11 XEXT XINERAMA RANDR'
|
||||
obj.uselib += ' GIO-UNIX X11 XEXT XINERAMA RANDR DL'
|
||||
obj.includes += ['ydk/x11/gdk', 'ydk/gdk/x11']
|
||||
obj.export_includes += ['ydk/gdk']
|
||||
obj.export_includes += ['ydk/x11']
|
||||
|
@ -65,6 +65,9 @@
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
static void gdk_display_x11_dispose (GObject *object);
|
||||
static void gdk_display_x11_finalize (GObject *object);
|
||||
@ -864,6 +867,13 @@ gdk_display_x11_finalize (GObject *object)
|
||||
g_hash_table_destroy (display_x11->atom_from_virtual);
|
||||
g_hash_table_destroy (display_x11->atom_to_virtual);
|
||||
|
||||
/* Multitouch */
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (display_x11->xi.libxi)
|
||||
dlclose (display_x11->xi.libxi);
|
||||
g_hash_table_destroy (display_x11->touch_devices);
|
||||
#endif
|
||||
|
||||
/* Leader Window */
|
||||
XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
|
||||
|
||||
|
@ -62,6 +62,11 @@
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <dlfcn.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
typedef struct _GdkIOClosure GdkIOClosure;
|
||||
@ -237,6 +242,64 @@ _gdk_events_init (GdkDisplay *display)
|
||||
gdk_atom_intern_static_string ("WM_PROTOCOLS"),
|
||||
gdk_wm_protocols_filter,
|
||||
NULL);
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
void* lxi = dlopen ("libXi.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (lxi)
|
||||
{
|
||||
display_x11->xi.XISelectEvents = dlsym (lxi, "XISelectEvents");
|
||||
display_x11->xi.XIQueryDevice = dlsym (lxi, "XIQueryDevice");
|
||||
display_x11->xi.XIFreeDeviceInfo = dlsym (lxi, "XIFreeDeviceInfo");
|
||||
if (display_x11->xi.XISelectEvents && display_x11->xi.XIQueryDevice && display_x11->xi.XIFreeDeviceInfo)
|
||||
{
|
||||
display_x11->xi.libxi = lxi;
|
||||
}
|
||||
else
|
||||
{
|
||||
dlclose (lxi);
|
||||
}
|
||||
}
|
||||
|
||||
int firstevent, firsterror;
|
||||
if (display_x11->xi.libxi && XQueryExtension (display_x11->xdisplay, "XInputExtension", &display_x11->xid_opcode, &firstevent, &firsterror))
|
||||
{
|
||||
printf ("CHECK FOR TOUCHSCREENs\n");
|
||||
|
||||
int n_devices;
|
||||
XIDeviceInfo* info;
|
||||
|
||||
info = display_x11->xi.XIQueryDevice (display_x11->xdisplay, XIAllDevices, &n_devices);
|
||||
|
||||
for (int i = 0; i < n_devices; ++i) {
|
||||
XIDeviceInfo* dev = &info[i];
|
||||
if (!dev->enabled) {
|
||||
continue;
|
||||
}
|
||||
if (!(dev->use == XISlavePointer || dev->use == XIFloatingSlave)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gboolean direct_touch = FALSE;
|
||||
XITouchClassInfo* classInfo;
|
||||
|
||||
for (int j = 0; j < dev->num_classes; ++j) {
|
||||
classInfo = (XITouchClassInfo*)(dev->classes[j]);
|
||||
|
||||
if (classInfo->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
|
||||
direct_touch = TRUE;
|
||||
}
|
||||
}
|
||||
if (direct_touch) {
|
||||
printf ("XI: touch-device id=%d name='%s' ntouch: %d\n", dev->deviceid, dev->name, classInfo->num_touches);
|
||||
if (!display_x11->touch_devices) {
|
||||
display_x11->touch_devices = g_hash_table_new (g_direct_hash, NULL);
|
||||
}
|
||||
g_hash_table_insert (display_x11->touch_devices, GUINT_TO_POINTER (dev->deviceid), GUINT_TO_POINTER(1));
|
||||
}
|
||||
}
|
||||
display_x11->xi.XIFreeDeviceInfo (info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -1233,7 +1296,7 @@ gdk_event_translate (GdkDisplay *display,
|
||||
event->button.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.device = display->core_pointer;
|
||||
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
@ -2124,6 +2187,9 @@ gdk_event_translate (GdkDisplay *display,
|
||||
break;
|
||||
|
||||
default:
|
||||
if (xevent->xcookie.type == GenericEvent) {
|
||||
XGetEventData (display_x11->xdisplay, &xevent->xcookie);
|
||||
}
|
||||
#ifdef HAVE_XKB
|
||||
if (xevent->type == display_x11->xkb_event_type)
|
||||
{
|
||||
@ -2175,6 +2241,47 @@ gdk_event_translate (GdkDisplay *display,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (xevent->xcookie.type == GenericEvent && xevent->xcookie.extension == display_x11->xid_opcode
|
||||
&& display_x11->touch_devices && g_hash_table_lookup (display_x11->touch_devices, GUINT_TO_POINTER (((XIDeviceEvent *)xevent->xcookie.data)->deviceid)))
|
||||
{
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) xevent->xcookie.data;
|
||||
printf ("TOUCH dev=%d src=%d | dt: %u flags: %x\n", xev->deviceid, xev->sourceid, xev->detail, xev->flags);
|
||||
window = gdk_window_lookup_for_display (display, xev->event);
|
||||
g_object_ref (window);
|
||||
|
||||
event->touch.window = window;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = xev->event_x;
|
||||
event->touch.y = xev->event_y;
|
||||
event->touch.x_root = xev->root_x;
|
||||
event->touch.y_root = xev->root_y;
|
||||
event->touch.state = 0 ; (GdkModifierType) xevent->xbutton.state;
|
||||
event->touch.sequence = xev->detail;
|
||||
event->touch.flags = xev->flags;
|
||||
event->touch.deviceid = xev->deviceid;
|
||||
|
||||
switch (xevent->xcookie.evtype) {
|
||||
case XI_TouchBegin:
|
||||
event->touch.type = GDK_TOUCH_BEGIN;
|
||||
break;
|
||||
case XI_TouchUpdate:
|
||||
event->touch.type = GDK_TOUCH_UPDATE;
|
||||
break;
|
||||
case XI_TouchEnd:
|
||||
event->touch.type = GDK_TOUCH_END;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!set_screen_from_root (display, event, xev->root)) {
|
||||
return_val = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
|
||||
if (display_x11->have_xdamage && window_private && window_private->composited &&
|
||||
xevent->type == display_x11->xdamage_event_base + XDamageNotify &&
|
||||
|
@ -71,6 +71,10 @@
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
const int _gdk_event_mask_table[21] =
|
||||
{
|
||||
ExposureMask,
|
||||
@ -797,6 +801,24 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
g_object_ref (window);
|
||||
_gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window);
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
|
||||
if (display_x11->touch_devices)
|
||||
{
|
||||
XIEventMask evmask;
|
||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0 };
|
||||
evmask.deviceid = XIAllDevices;
|
||||
evmask.mask_len = sizeof(mask);
|
||||
evmask.mask = mask;
|
||||
|
||||
XISetMask(evmask.mask, XI_TouchBegin);
|
||||
XISetMask(evmask.mask, XI_TouchUpdate);
|
||||
XISetMask(evmask.mask, XI_TouchEnd);
|
||||
|
||||
display_x11->xi.XISelectEvents (xdisplay, xid, &evmask, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (GDK_WINDOW_TYPE (private))
|
||||
{
|
||||
case GDK_WINDOW_DIALOG:
|
||||
|
@ -36,6 +36,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDisplayX11 GdkDisplayX11;
|
||||
typedef struct _GdkXInput2Fn GdkXInput2Fn;
|
||||
typedef struct _GdkDisplayX11Class GdkDisplayX11Class;
|
||||
|
||||
#define GDK_TYPE_DISPLAY_X11 (_gdk_display_x11_get_type())
|
||||
@ -52,6 +53,19 @@ typedef enum
|
||||
GDK_YES
|
||||
} GdkTristate;
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
struct _GdkXInput2Fn
|
||||
{
|
||||
int (*XISelectEvents)(Display*, Window, XIEventMask*, int);
|
||||
XIDeviceInfo* (*XIQueryDevice)(Display*, int, int*);
|
||||
void (*XIFreeDeviceInfo)(XIDeviceInfo*);
|
||||
void* libxi;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct _GdkDisplayX11
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
@ -155,6 +169,12 @@ struct _GdkDisplayX11
|
||||
|
||||
/* The offscreen window that has the pointer in it (if any) */
|
||||
GdkWindow *active_offscreen_window;
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
int xid_opcode;
|
||||
GHashTable* touch_devices;
|
||||
GdkXInput2Fn xi;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GdkDisplayX11Class
|
||||
|
Loading…
Reference in New Issue
Block a user