aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native/X11Display.c')
-rw-r--r--src/newt/native/X11Display.c115
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)) {