static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( GET_LONG(canvasObj, gCanvasClassInfo.mNativeCanvas)); SET_LONG(canvasObj, gCanvasClassInfo.mNativeCanvas, (long) newCanvas); SET_LONG(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (long) newCanvas); SkSafeUnref(previousCanvas); }
void SjTrackInfo::SetValue(long ti, const wxString& value) { long longValue; #define SET_STRING(n) \ (n) = value; return; #define SET_LONG(n) \ if( value.ToLong(&longValue) ) { (n) = longValue; } return; switch( ti ) { case SJ_TI_URL: SET_STRING (m_url); case SJ_TI_TRACKNAME: SET_STRING (m_trackName); case SJ_TI_TRACKNR: SET_LONG (m_trackNr); case SJ_TI_TRACKCOUNT: SET_LONG (m_trackCount); case SJ_TI_DISKNR: SET_LONG (m_diskNr); case SJ_TI_DISKCOUNT: SET_LONG (m_diskCount); case SJ_TI_LEADARTISTNAME: SET_STRING (m_leadArtistName); case SJ_TI_ORGARTISTNAME: SET_STRING (m_orgArtistName); case SJ_TI_COMPOSERNAME: SET_STRING (m_composerName); case SJ_TI_ALBUMNAME: SET_STRING (m_albumName); case SJ_TI_GENRENAME: SET_STRING (m_genreName); case SJ_TI_GROUPNAME: SET_STRING (m_groupName); case SJ_TI_COMMENT: SET_STRING (m_comment); case SJ_TI_BEATSPERMINUTE: SET_LONG (m_beatsPerMinute); case SJ_TI_RATING: SET_LONG (m_rating); case SJ_TI_YEAR: SET_LONG (m_year); case SJ_TI_PLAYTIMEMS: SET_LONG (m_playtimeMs); } wxASSERT( 0 ); }
static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView, jobject surface) { sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surface)); sp<ANativeWindow> window = new Surface(producer, true); window->incStrong((void*)android_view_TextureView_createNativeWindow); SET_LONG(textureView, gTextureViewClassInfo.nativeWindow, jlong(window.get())); }
static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject textureView) { ANativeWindow* nativeWindow = (ANativeWindow*) GET_LONG(textureView, gTextureViewClassInfo.nativeWindow); if (nativeWindow) { sp<ANativeWindow> window(nativeWindow); window->decStrong((void*)android_view_TextureView_createNativeWindow); SET_LONG(textureView, gTextureViewClassInfo.nativeWindow, 0); } }
JNIEXPORT jboolean JNICALL Java_com_turbovnc_vncviewer_Viewport_processExtInputEvent (JNIEnv *env, jobject obj, jint type) { jclass cls; jfieldID fid; union { int type; XEvent xe; XDeviceMotionEvent motion; XDeviceButtonEvent button; } e; Display *dpy; int buttonPressType = -1, buttonReleaseType = -1, motionType = -1; jboolean retval = JNI_FALSE; int i; bailif0(cls = (*env)->GetObjectClass(env, obj)); bailif0(fid = (*env)->GetFieldID(env, cls, "buttonPressType", "I")); buttonPressType = (*env)->GetIntField(env, obj, fid); bailif0(fid = (*env)->GetFieldID(env, cls, "buttonReleaseType", "I")); buttonReleaseType = (*env)->GetIntField(env, obj, fid); bailif0(fid = (*env)->GetFieldID(env, cls, "motionType", "I")); motionType = (*env)->GetIntField(env, obj, fid); bailif0(fid = (*env)->GetFieldID(env, cls, "x11dpy", "J")); bailif0(dpy = (Display *)(*env)->GetLongField(env, obj, fid)); while (XCheckTypedEvent(dpy, type, &e.xe)) { if (e.type == motionType) { jclass eventcls; jobject event, jvaluators; jint valuators[6]; bailif0(eventcls = (*env)->FindClass(env, "com/turbovnc/rfb/ExtInputEvent")); bailif0(fid = (*env)->GetFieldID(env, cls, "lastEvent", "Lcom/turbovnc/rfb/ExtInputEvent;")); bailif0(event = (*env)->GetObjectField(env, obj, fid)); SET_INT(eventcls, event, type, rfbGIIValuatorRelative); SET_LONG(eventcls, event, deviceID, e.motion.deviceid); SET_LONG(eventcls, event, buttonMask, e.motion.state); SET_INT(eventcls, event, numValuators, e.motion.axes_count); SET_INT(eventcls, event, firstValuator, e.motion.first_axis); bailif0(fid = (*env)->GetFieldID(env, eventcls, "valuators", "[I")); bailif0(jvaluators = (jintArray)(*env)->GetObjectField(env, event, fid)); for (i = 0; i < e.motion.axes_count; i++) valuators[i] = e.motion.axis_data[i]; (*env)->SetIntArrayRegion(env, jvaluators, 0, e.motion.axes_count, valuators); retval = JNI_TRUE; } else if (e.type == buttonPressType || e.type == buttonReleaseType) { jclass eventcls; jobject event, jvaluators; jint valuators[6]; bailif0(eventcls = (*env)->FindClass(env, "com/turbovnc/rfb/ExtInputEvent")); bailif0(fid = (*env)->GetFieldID(env, cls, "lastEvent", "Lcom/turbovnc/rfb/ExtInputEvent;")); bailif0(event = (*env)->GetObjectField(env, obj, fid)); SET_INT(eventcls, event, type, e.type == buttonPressType ? rfbGIIButtonPress : rfbGIIButtonRelease); SET_LONG(eventcls, event, deviceID, e.button.deviceid); SET_LONG(eventcls, event, buttonMask, e.button.state); SET_INT(eventcls, event, numValuators, e.button.axes_count); SET_INT(eventcls, event, firstValuator, e.button.first_axis); SET_INT(eventcls, event, buttonNumber, e.button.button); bailif0(fid = (*env)->GetFieldID(env, eventcls, "valuators", "[I")); bailif0(jvaluators = (jintArray)(*env)->GetObjectField(env, event, fid)); for (i = 0; i < e.button.axes_count; i++) valuators[i] = e.button.axis_data[i]; (*env)->SetIntArrayRegion(env, jvaluators, 0, e.button.axes_count, valuators); retval = JNI_TRUE; } } bailout: return retval; }
JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_setupExtInput (JNIEnv *env, jobject obj) { jclass cls, eidcls; jfieldID fid; jmethodID mid; Display *dpy = NULL; Window win = 0; XDeviceInfo *devInfo = NULL; XDevice *device = NULL; int nDevices = 0, i, ci, ai, nEvents = 0; int buttonPressType = -1, buttonReleaseType = -1, motionType = -1; XEventClass events[100] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; jobject extInputDevice; if ((dpy = XOpenDisplay(NULL)) == NULL) _throw("Could not open X display"); bailif0(cls = (*env)->GetObjectClass(env, obj)); bailif0(fid = (*env)->GetFieldID(env, cls, "x11win", "J")); if ((win = (Window)(*env)->GetLongField(env, obj, fid)) == 0) _throw("X window handle has not been initialized"); if ((devInfo = XListInputDevices(dpy, &nDevices)) == NULL) _throw("Could not list XI devices"); for (i = 0; i < nDevices; i++) { char *type; XAnyClassPtr classInfo = devInfo[i].inputclassinfo; CARD32 canGenerate = 0, productID = 0; if (devInfo[i].use != IsXExtensionPointer) continue; if (devInfo[i].type == None) continue; type = XGetAtomName(dpy, devInfo[i].type); if (!strcmp(type, "MOUSE")) { XFree(type); continue; } /* TurboVNC-specific: we use productID to represent the device type, so we can recreate it on the server */ if (!strcmp(type, "CURSOR")) productID = rfbGIIDevTypeCursor; else if (!strcmp(type, "STYLUS")) productID = rfbGIIDevTypeStylus; else if (!strcmp(type, "ERASER")) productID = rfbGIIDevTypeEraser; else if (!strcmp(type, "TOUCH")) productID = rfbGIIDevTypeTouch; else if (!strcmp(type, "PAD")) productID = rfbGIIDevTypePad; XFree(type); bailif0(eidcls = (*env)->FindClass(env, "com/turbovnc/rfb/ExtInputDevice")); bailif0(extInputDevice = (*env)->AllocObject(env, eidcls)); SET_STRING(eidcls, extInputDevice, name, devInfo[i].name); SET_LONG(eidcls, extInputDevice, vendorID, 4242); SET_LONG(eidcls, extInputDevice, productID, productID); SET_LONG(eidcls, extInputDevice, id, devInfo[i].id); for (ci = 0; ci < devInfo[i].num_classes; ci++) { switch (classInfo->class) { case ButtonClass: { XButtonInfoPtr b = (XButtonInfoPtr)classInfo; SET_INT(eidcls, extInputDevice, numButtons, b->num_buttons); canGenerate |= rfbGIIButtonPressMask | rfbGIIButtonReleaseMask; break; } case ValuatorClass: { XValuatorInfoPtr v = (XValuatorInfoPtr)classInfo; jclass valcls; bailif0(valcls = (*env)->FindClass(env, "com/turbovnc/rfb/ExtInputDevice$Valuator")); if (v->mode == Absolute) canGenerate |= rfbGIIValuatorAbsoluteMask; else if (v->mode == Relative) canGenerate |= rfbGIIValuatorRelativeMask; for (ai = 0; ai < v->num_axes; ai++) { jobject valuator; XAxisInfoPtr a = &v->axes[ai]; char longName[75], shortName[5]; bailif0(valuator = (*env)->AllocObject(env, valcls)); SET_INT(valcls, valuator, index, ai); snprintf(longName, 75, "Valuator %d", ai); SET_STRING(valcls, valuator, longName, longName); snprintf(shortName, 5, "%d", ai); SET_STRING(valcls, valuator, shortName, shortName); SET_INT(valcls, valuator, rangeMin, a->min_value); SET_INT(valcls, valuator, rangeCenter, (a->min_value + a->max_value) / 2); SET_INT(valcls, valuator, rangeMax, a->max_value); SET_INT(valcls, valuator, siUnit, rfbGIIUnitLength); SET_INT(valcls, valuator, siDiv, a->resolution); bailif0(mid = (*env)->GetMethodID(env, eidcls, "addValuator", "(Lcom/turbovnc/rfb/ExtInputDevice$Valuator;)V")); (*env)->CallVoidMethod(env, extInputDevice, mid, valuator); } break; } } classInfo = (XAnyClassPtr)((char *)classInfo + classInfo->length); } SET_LONG(eidcls, extInputDevice, canGenerate, canGenerate); if (canGenerate & rfbGIIValuatorAbsoluteMask) SET_BOOL(eidcls, extInputDevice, absolute, 1); if ((device = XOpenDevice(dpy, devInfo[i].id)) == NULL) _throw("Could not open XI device"); for (ci = 0; ci < device->num_classes; ci++) { if (device->classes[ci].input_class == ButtonClass) { DeviceButtonPress(device, buttonPressType, events[nEvents]); nEvents++; DeviceButtonRelease(device, buttonReleaseType, events[nEvents]); nEvents++; } else if (device->classes[ci].input_class == ValuatorClass) { DeviceMotionNotify(device, motionType, events[nEvents]); nEvents++; } } XCloseDevice(dpy, device); device=NULL; bailif0(mid = (*env)->GetMethodID(env, cls, "addInputDevice", "(Lcom/turbovnc/rfb/ExtInputDevice;)V")); (*env)->CallVoidMethod(env, obj, mid, extInputDevice); } XFreeDeviceList(devInfo); devInfo = NULL; if (nEvents == 0) { printf("No extended input devices.\n"); goto bailout; } if (XSelectExtensionEvent(dpy, win, events, nEvents)) _throw("Could not select XI events"); SET_INT(cls, obj, buttonPressType, buttonPressType); SET_INT(cls, obj, buttonReleaseType, buttonReleaseType); SET_INT(cls, obj, motionType, motionType); SET_LONG(cls, obj, x11dpy, (jlong)dpy); printf("TurboVNC Helper: Listening for XInput events on %s (window 0x%.8x)\n", DisplayString(dpy), (unsigned int)win); bailout: if (dpy && device) XCloseDevice(dpy, device); if (devInfo) XFreeDeviceList(devInfo); }