diff options
Diffstat (limited to 'src/newt/native/X11Display.c')
-rw-r--r-- | src/newt/native/X11Display.c | 115 |
1 files changed, 110 insertions, 5 deletions
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 32e0f8786..1f3388fff 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -56,6 +56,7 @@ static jmethodID sendMouseEventRequestFocusID = NULL; static jmethodID visibleChangedWindowRepaintID = NULL; static jmethodID visibleChangedSendMouseEventID = NULL; static jmethodID sizePosMaxInsetsVisibleChangedID = NULL; +static jmethodID sendTouchScreenEventID = NULL; /** * Keycode @@ -266,6 +267,7 @@ 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"); + 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 || @@ -286,11 +288,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 sendMouseEventID == NULL || sendMouseEventRequestFocusID == NULL || visibleChangedSendMouseEventID == NULL || + sendTouchScreenEventID == NULL || sendKeyEventID == NULL) { return JNI_FALSE; } - return JNI_TRUE; } @@ -385,6 +387,59 @@ static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *j return visibleChange; } +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 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, 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++; + } + } + + jintArray jNames = (*env)->NewIntArray(env, cnt); + if (jNames == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (names) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jNames, 0, cnt, pointerNames); + + jintArray jX = (*env)->NewIntArray(env, cnt); + if (jX == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (x) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jX, 0, cnt, x); + + jintArray jY = (*env)->NewIntArray(env, cnt); + if (jY == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (y) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jY, 0, cnt, y); + + jfloatArray jPressure = (*env)->NewFloatArray(env, cnt); + if (jPressure == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate float array (pressure) of size %d", cnt); + } + (*env)->SetFloatArrayRegion(env, jPressure, 0, cnt, pressure); + + (*env)->CallVoidMethod(env, jw->jwindow, sendTouchScreenEventID, + (jshort)eventType, (jint)modifiers, (jint)actionIdx, + jNames, jX, jY, jPressure, (jfloat)1.0f); +} + /* * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DispatchMessages0 @@ -451,9 +506,10 @@ 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); - jw = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, + jw = getJavaWindowProperty(env, dpy, windowPointer, javaObjectAtom, #ifdef VERBOSE_ON True #else @@ -462,10 +518,59 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage ); if(NULL==jw) { - fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)windowPointer); continue; } - + + 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, 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, 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; + } + } + XFreeEventData(dpy, cookie); + continue; // next event, skip evt.type below + } + switch(evt.type) { case KeyRelease: if (XEventsQueued(dpy, QueuedAfterReading)) { |