aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Display.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2019-03-27 03:10:41 +0100
committerSven Gothel <[email protected]>2019-03-27 03:10:41 +0100
commit746383476aa449e9cab4a25df27be85b61aa074b (patch)
tree8f5d54b10abd6fbc23b8b82011b4a24bb16c7d21 /src/newt/native/X11Display.c
parent92006e4baef57f1f3fb647dd307aed5989fd4c8d (diff)
Bug 1348: X11 XI Multitouch: Fixes of previous commit 92006e4baef57f1f3fb647dd307aed5989fd4c8d
Previous commit 92006e4baef57f1f3fb647dd307aed5989fd4c8d (Note to Danny: I cannot test this now - please re-test and/or review) X11Common::JavaWindow - Owns XI extension's xiOpcode, selected xiTouchDeviceId and tracked XITouchPosition array X11Window::CreateWindow - Query XI extension only once @ window creation and earmark xiOpcode in JavaWindow instance - Fix: Device selection code was "class->type != XITouchClass", but shouldn't it be 'XITouchClass == class->type' (as patched here) - Fix: Free XIQueryDevice returned XIDeviceInfo array via XIFreeDeviceInfo - Earmark deviceid in JavaWindow instance X11Display - Moved global static touch_coordinates to JavaWindow::xiTouchCoords instance X11Display::DispatchMessage - Changed event handling structure similar to https://keithp.com/blogs/Cursor_tracking/ - Fix: Free XGetEventData's optional memory allocation via XFreeEventData - Reuse JavaWindow's queried xiOpcode - Fix: Don't overrise windowPointer, instead validate and require a match. JavaWindow must match! - Fix: Also validate chosen deviceid with JavaWindow's registered device Newt Build: - Added libXi in build recipe and doc
Diffstat (limited to 'src/newt/native/X11Display.c')
-rw-r--r--src/newt/native/X11Display.c166
1 files changed, 60 insertions, 106 deletions
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index effc488f9..1f3388fff 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -58,12 +58,6 @@ static jmethodID visibleChangedSendMouseEventID = NULL;
static jmethodID sizePosMaxInsetsVisibleChangedID = NULL;
static jmethodID sendTouchScreenEventID = NULL;
-struct touchPosition {
- int touch_id;
- int x;
- int y;
-};
-
/**
* Keycode
*/
@@ -226,8 +220,6 @@ static jint X11InputState2NewtModifiers(unsigned int xstate, jshort javaVKey, jb
}
-static struct touchPosition touch_coordinates[10];
-
/**
* Keycode
*/
@@ -275,8 +267,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V");
visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)V");
- sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
sendTouchScreenEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendTouchScreenEvent", "(SII[I[I[I[FF)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
if (displayCompletedID == NULL ||
sendRRScreenChangeNotifyID == NULL ||
@@ -301,8 +293,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
return JNI_FALSE;
}
- memset(touch_coordinates, -1, sizeof(touch_coordinates));
-
return JNI_TRUE;
}
@@ -397,28 +387,24 @@ static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *j
return visibleChange;
}
-void sendTouchScreenEvent(JNIEnv *env, jobject window,
+static void sendTouchScreenEvent(JNIEnv *env, JavaWindow *jw,
short eventType, // MouseEvent.EVENT_MOUSE_PRESSED, MouseEvent.EVENT_MOUSE_RELEASED, MouseEvent.EVENT_MOUSE_MOVED
int modifiers, // 0!
int actionId) // index of multiple-pointer arrays representing the pointer which triggered the event
{
- jint cnt = 0;
- jint pointerNames[10];
- jint x[10];
- jint y[10];
- jfloat pressure[] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
+ jint pointerNames[XI_TOUCHCOORD_COUNT];
+ jint x[XI_TOUCHCOORD_COUNT];
+ jint y[XI_TOUCHCOORD_COUNT];
+ jfloat pressure[] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
jint actionIdx = -1;
- int i = 0;
-
- for(i = 0; i < 10; i++)
- {
- if(touch_coordinates[i].touch_id != -1)
- {
- x[cnt] = touch_coordinates[i].x;
- y[cnt] = touch_coordinates[i].y;
- pointerNames[cnt] = touch_coordinates[i].touch_id;
- if (touch_coordinates[i].touch_id == actionId)
- {
+ int i, cnt;
+
+ for(i = 0, cnt = 0; i < XI_TOUCHCOORD_COUNT; i++) {
+ if( -1 != jw->xiTouchCoords[i].id ) {
+ x[cnt] = jw->xiTouchCoords[i].x;
+ y[cnt] = jw->xiTouchCoords[i].y;
+ pointerNames[cnt] = jw->xiTouchCoords[i].id;
+ if (jw->xiTouchCoords[i].id == actionId) {
actionIdx = cnt;
}
cnt++;
@@ -449,10 +435,9 @@ void sendTouchScreenEvent(JNIEnv *env, jobject window,
}
(*env)->SetFloatArrayRegion(env, jPressure, 0, cnt, pressure);
- (*env)->CallVoidMethod(env, window, sendTouchScreenEventID,
+ (*env)->CallVoidMethod(env, jw->jwindow, sendTouchScreenEventID,
(jshort)eventType, (jint)modifiers, (jint)actionIdx,
jNames, jX, jY, jPressure, (jfloat)1.0f);
-
}
/*
@@ -521,36 +506,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
continue;
}
- // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
-
Window windowPointer = evt.xany.window;
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)windowPointer, (int)evt.type);
-
- int isXInputExtensionEvent = 0;
- XGenericEventCookie *cookie = &evt.xcookie; // hacks!
- XIDeviceEvent *devev;
-
-
- if (XGetEventData(dpy, cookie)) // extended event
- {
- int xi_opcode;
- int ev;
- int err;
- XQueryExtension(dpy, "XInputExtension", &xi_opcode, &ev, &err);
-
- // check if this belongs to XInput
- if (cookie->type == GenericEvent
- && cookie->extension == xi_opcode) {
- static int last = -1;
-
- devev = cookie->data;
- windowPointer = devev->event;
- isXInputExtensionEvent = 1;
-
- }
- }
-
-
jw = getJavaWindowProperty(env, dpy, windowPointer, javaObjectAtom,
#ifdef VERBOSE_ON
True
@@ -564,59 +522,55 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
continue;
}
- if (isXInputExtensionEvent) {
- int i;
-
- switch (devev->evtype) {
- case XI_TouchBegin:
-
- for (i = 0; i < 10; i++)
- {
- if (touch_coordinates[i].touch_id == -1)
- {
- touch_coordinates[i].touch_id = devev->detail % 32767;
- touch_coordinates[i].x = devev->event_x;
- touch_coordinates[i].y = devev->event_y;
- break;
+ XGenericEventCookie *cookie = &evt.xcookie; // hacks: https://keithp.com/blogs/Cursor_tracking/
+
+ if ( GenericEvent == cookie->type && jw->xiOpcode == cookie->extension && XGetEventData(dpy, cookie) ) {
+ // Valid registered XI Event w/ cookie data
+ // Here: https://www.x.org/wiki/Development/Documentation/Multitouch/
+ XIDeviceEvent *devev = cookie->data;
+ if( devev->event != windowPointer ) {
+ DBG_PRINT( "X11: DispatchMessages.XI dpy %p, win %p, Event %d: Event Window %p not matching\n", (void*)dpy, (void*)windowPointer, (int)evt.type, (void*)devev->event);
+ } else if( devev->deviceid != jw->xiTouchDeviceId) {
+ DBG_PRINT( "X11: DispatchMessages.XI dpy %p, win %p, Event %d: DeviceID not matching: Window %d, this %d\n", (void*)dpy, (void*)windowPointer, (int)evt.type, devev->deviceid, jw->xiTouchDeviceId);
+ } else {
+ int i;
+ switch (devev->evtype) {
+ case XI_TouchBegin:
+ for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) {
+ if (jw->xiTouchCoords[i].id == -1) {
+ jw->xiTouchCoords[i].id = devev->detail % 32767;
+ jw->xiTouchCoords[i].x = devev->event_x;
+ jw->xiTouchCoords[i].y = devev->event_y;
+ break;
+ }
}
- }
-
- sendTouchScreenEvent(env, jw->jwindow, EVENT_MOUSE_PRESSED,
- 0, devev->detail % 32767);
-
- break;
- case XI_TouchUpdate:
-
- for (i = 0; i < 10; i++)
- {
- if (touch_coordinates[i].touch_id == devev->detail % 32767)
- {
- touch_coordinates[i].x = devev->event_x;
- touch_coordinates[i].y = devev->event_y;
+ sendTouchScreenEvent(env, jw, EVENT_MOUSE_PRESSED, 0, devev->detail % 32767);
+ break;
+
+ case XI_TouchUpdate:
+ for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) {
+ if (jw->xiTouchCoords[i].id == devev->detail % 32767) {
+ jw->xiTouchCoords[i].x = devev->event_x;
+ jw->xiTouchCoords[i].y = devev->event_y;
+ }
}
- }
- sendTouchScreenEvent(env, jw->jwindow, EVENT_MOUSE_MOVED, 0,
- devev->detail % 32767);
-
- break;
- case XI_TouchEnd:
-
- sendTouchScreenEvent(env, jw->jwindow, EVENT_MOUSE_RELEASED,
- 0, devev->detail % 32767);
-
- for (i = 0; i < 10; i++)
- {
- if (touch_coordinates[i].touch_id == devev->detail % 32767)
- {
- touch_coordinates[i].touch_id = -1;
+ sendTouchScreenEvent(env, jw, EVENT_MOUSE_MOVED, 0, devev->detail % 32767);
+ break;
+
+ case XI_TouchEnd:
+ sendTouchScreenEvent(env, jw, EVENT_MOUSE_RELEASED, 0, devev->detail % 32767);
+ for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) {
+ if (jw->xiTouchCoords[i].id == devev->detail % 32767) {
+ jw->xiTouchCoords[i].id = -1;
+ }
}
- }
- break;
-
- continue;
+ break;
+ }
}
+ XFreeEventData(dpy, cookie);
+ continue; // next event, skip evt.type below
}
-
+
switch(evt.type) {
case KeyRelease:
if (XEventsQueued(dpy, QueuedAfterReading)) {