JNIEXPORT void JNICALL TJCompressor_encodeYUV_12 (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width, jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) { tjhandle handle=0; jsize arraySize=0; unsigned char *srcBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1 || pitch<0) _throwarg("Invalid argument in encodeYUV()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throwarg("Mismatch between Java and C API"); arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height; if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize) _throwarg("Source buffer is not large enough"); if((*env)->GetArrayLength(env, dst) <(jsize)tjBufSizeYUV(width, height, subsamp)) _throwarg("Destination buffer is not large enough"); bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp, flags)==-1) _throwtj(); bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); return; }
JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors (JNIEnv *env, jclass cls) { jclass sfcls=NULL; jfieldID fid=0; tjscalingfactor *sf=NULL; int n=0, i; jobject sfobj=NULL; jobjectArray sfjava=NULL; if((sf=tjGetScalingFactors(&n))==NULL || n==0) _throw(tjGetErrorStr()); bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor")); bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); for(i=0; i<n; i++) { bailif0(sfobj=(*env)->AllocObject(env, sfcls)); bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].num); bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].denom); (*env)->SetObjectArrayElement(env, sfjava, i, sfobj); } bailout: return sfjava; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize) { tjhandle handle=0; unsigned char *jpegBuf=NULL; int width=0, height=0, jpegSubsamp=-1; gethandle(); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); if(tjDecompressHeader2(handle, jpegBuf, (unsigned long)jpegSize, &width, &height, &jpegSubsamp)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); _throw(tjGetErrorStr()); } (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL; bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); (*env)->SetIntField(env, obj, _fid, jpegSubsamp); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); (*env)->SetIntField(env, obj, _fid, width); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); (*env)->SetIntField(env, obj, _fid, height); bailout: return; }
/* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, jint flags) { tjhandle handle=0; unsigned char *jpegBuf=NULL, *dstBuf=NULL; int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0; gethandle(); if((*env)->GetArrayLength(env, src)<jpegSize) _throwarg("Source buffer is not large enough"); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight=(int)(*env)->GetIntField(env, obj, _fid); if((*env)->GetArrayLength(env, dst) <(jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)) _throwarg("Destination buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, flags)==-1) _throwtj(); bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); return; }
/* TurboJPEG 1.2.x: TJDecompressor::init() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init (JNIEnv *env, jobject obj) { jclass cls; jfieldID fid; tjhandle handle; if((handle=tjInitDecompress())==NULL) _throwtj(); bailif0(cls=(*env)->GetObjectClass(env, obj)); bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); (*env)->SetLongField(env, obj, fid, (size_t)handle); bailout: return; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init (JNIEnv *env, jobject obj) { jclass cls; jfieldID fid; tjhandle handle; if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr()); bailif0(cls=(*env)->GetObjectClass(env, obj)); bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); (*env)->SetLongField(env, obj, fid, (jlong)handle); bailout: return; }
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, jint flags) { tjhandle handle=0; unsigned long jpegSize=0; jsize arraySize=0, actualStride; unsigned char *srcBuf=NULL, *jpegBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1 || stride<0) _throw("Invalid argument in compress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if(tjPixelSize[pf]!=sizeof(jint)) _throw("Pixel format must be 32-bit when compressing from an integer buffer."); actualStride=(stride==0)? width:stride; arraySize=(y+height-1)*actualStride + x+width; if((*env)->GetArrayLength(env, src)<arraySize) _throw("Source buffer is not large enough"); jpegSize=tjBufSize(width, height, jpegSubsamp); if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize) _throw("Destination buffer is not large enough"); bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjCompress2(handle, &srcBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint), height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual, flags|TJFLAG_NOREALLOC)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); jpegBuf=srcBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); return (jint)jpegSize; }
JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_cleanupExtInput (JNIEnv *env, jobject obj) { jclass cls; jfieldID fid; Display *dpy; bailif0(cls = (*env)->GetObjectClass(env, obj)); bailif0(fid = (*env)->GetFieldID(env, cls, "x11dpy", "J")); bailif0(dpy = (Display *)(*env)->GetLongField(env, obj, fid)); printf("TurboVNC Helper: Shutting down XInput listener on display %s\n", DisplayString(dpy)); XCloseDisplay(dpy); bailout: return; }
int ProcessSystemProperties(JNIEnv *env) { jclass cls; jmethodID mid; jstring jName, jValue; const char *value; bailif0(cls=(*env)->FindClass(env, "java/lang/System")); bailif0(mid=(*env)->GetStaticMethodID(env, cls, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;")); prop2env("turbojpeg.optimize", "TJ_OPTIMIZE"); prop2env("turbojpeg.arithmetic", "TJ_ARITHMETIC"); prop2env("turbojpeg.restart", "TJ_RESTART"); prop2env("turbojpeg.progressive", "TJ_PROGRESSIVE"); return 0; bailout: return -1; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) { tjhandle handle=0; jsize arraySize=0; unsigned char *srcBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1 || pitch<0) _throw("Invalid argument in compress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if(tjPixelSize[pf]!=sizeof(jint)) _throw("Pixel format must be 32-bit when encoding from an integer buffer."); arraySize=(pitch==0)? width*height:pitch*height; if((*env)->GetArrayLength(env, src)<arraySize) _throw("Source buffer is not large enough"); if((*env)->GetArrayLength(env, dst) <(jsize)tjBufSizeYUV(width, height, subsamp)) _throw("Destination buffer is not large enough"); bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjEncodeYUV2(handle, srcBuf, width, pitch*sizeof(jint), height, pf, dstBuf, subsamp, flags)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); dstBuf=srcBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); return; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags) { tjhandle handle=0; jsize arraySize=0, actualStride; unsigned char *jpegBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF) _throw("Invalid argument in decompress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if(tjPixelSize[pf]!=sizeof(jint)) _throw("Pixel format must be 32-bit when decompressing to an integer buffer."); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); actualStride=(stride==0)? width:stride; arraySize=(y+height-1)*actualStride + x+width; if((*env)->GetArrayLength(env, dst)<arraySize) _throw("Destination buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint), height, pf, flags)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); dstBuf=jpegBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); return; }
static jint TJCompressor_compress (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y, jint width, jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, jint flags) { tjhandle handle=0; unsigned long jpegSize=0; jsize arraySize=0, actualPitch; unsigned char *srcBuf=NULL, *jpegBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1 || pitch<0) _throwarg("Invalid argument in compress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throwarg("Mismatch between Java and C API"); actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch; arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf]; if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize) _throwarg("Source buffer is not large enough"); jpegSize=tjBufSize(width, height, jpegSubsamp); if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize) _throwarg("Destination buffer is not large enough"); bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(ProcessSystemProperties(env)<0) goto bailout; if(tjCompress2(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual, flags|TJFLAG_NOREALLOC)==-1) _throwtj(); bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); return (jint)jpegSize; }
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, jint flags) { tjhandle handle=0; unsigned long jpegSize=0; jsize arraySize=0; unsigned char *srcBuf=NULL, *jpegBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1 || pitch<0) _throw("Invalid argument in compress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height; if((*env)->GetArrayLength(env, src)<arraySize) _throw("Source buffer is not large enough"); jpegSize=tjBufSize(width, height, jpegSubsamp); if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize) _throw("Destination buffer is not large enough"); bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjCompress2(handle, srcBuf, width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual, flags|TJFLAG_NOREALLOC)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); jpegBuf=srcBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); return (jint)jpegSize; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) { tjhandle handle=0; jsize arraySize=0, actualPitch; unsigned char *jpegBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF) _throw("Invalid argument in decompress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch; arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf]; if((*env)->GetArrayLength(env, dst)<arraySize) _throw("Destination buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf, flags)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); dstBuf=jpegBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); return; }
static void TJDecompressor_decodeYUV (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) { tjhandle handle=0; jsize arraySize=0, actualPitch; jbyteArray jSrcPlanes[3]={NULL, NULL, NULL}; unsigned char *srcPlanes[3], *dstBuf=NULL; int *srcOffsets=NULL, *srcStrides=NULL; int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP) _throwarg("Invalid argument in decodeYUV()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF || org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP) _throwarg("Mismatch between Java and C API"); if((*env)->GetArrayLength(env, srcobjs)<nc) _throwarg("Planes array is too small for the subsampling type"); if((*env)->GetArrayLength(env, jSrcOffsets)<nc) _throwarg("Offsets array is too small for the subsampling type"); if((*env)->GetArrayLength(env, jSrcStrides)<nc) _throwarg("Strides array is too small for the subsampling type"); actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch; arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf]; if((*env)->GetArrayLength(env, dst)*dstElementSize<arraySize) _throwarg("Destination buffer is not large enough"); bailif0(srcOffsets=(*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); bailif0(srcStrides=(*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); for(i=0; i<nc; i++) { int planeSize=tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); int pw=tjPlaneWidth(i, width, subsamp); if(planeSize<0 || pw<0) _throwarg(tjGetErrorStr()); if(srcOffsets[i]<0) _throwarg("Invalid argument in decodeYUV()"); if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0) _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); bailif0(jSrcPlanes[i]=(*env)->GetObjectArrayElement(env, srcobjs, i)); if((*env)->GetArrayLength(env, jSrcPlanes[i])<srcOffsets[i]+planeSize) _throwarg("Source plane is not large enough"); bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); srcPlanes[i]=&srcPlanes[i][srcOffsets[i]]; } bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp, &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf, flags)==-1) _throwtj(); bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); for(i=0; i<nc; i++) { if(srcPlanes[i] && jSrcPlanes[i]) (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i], 0); } if(srcStrides) (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0); if(srcOffsets) (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0); return; }
/* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, jint width, jintArray jSrcStrides, jint height, jint subsamp, jbyteArray dst, jint jpegQual, jint flags) { tjhandle handle=0; unsigned long jpegSize=0; jbyteArray jSrcPlanes[3]={NULL, NULL, NULL}; unsigned char *srcPlanes[3], *jpegBuf=NULL; int *srcOffsets=NULL, *srcStrides=NULL; int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i; gethandle(); if(subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP) _throwarg("Invalid argument in compressFromYUV()"); if(org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP) _throwarg("Mismatch between Java and C API"); if((*env)->GetArrayLength(env, srcobjs)<nc) _throwarg("Planes array is too small for the subsampling type"); if((*env)->GetArrayLength(env, jSrcOffsets)<nc) _throwarg("Offsets array is too small for the subsampling type"); if((*env)->GetArrayLength(env, jSrcStrides)<nc) _throwarg("Strides array is too small for the subsampling type"); jpegSize=tjBufSize(width, height, subsamp); if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize) _throwarg("Destination buffer is not large enough"); bailif0(srcOffsets=(*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); bailif0(srcStrides=(*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); for(i=0; i<nc; i++) { int planeSize=tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); int pw=tjPlaneWidth(i, width, subsamp); if(planeSize<0 || pw<0) _throwarg(tjGetErrorStr()); if(srcOffsets[i]<0) _throwarg("Invalid argument in compressFromYUV()"); if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0) _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); bailif0(jSrcPlanes[i]=(*env)->GetObjectArrayElement(env, srcobjs, i)); if((*env)->GetArrayLength(env, jSrcPlanes[i])<srcOffsets[i]+planeSize) _throwarg("Source plane is not large enough"); bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); srcPlanes[i]=&srcPlanes[i][srcOffsets[i]]; } bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(ProcessSystemProperties(env)<0) goto bailout; if(tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height, subsamp, &jpegBuf, &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1) _throwtj(); bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); for(i=0; i<nc; i++) { if(srcPlanes[i] && jSrcPlanes[i]) (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i], 0); } if(srcStrides) (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0); if(srcOffsets) (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0); return (jint)jpegSize; }
/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth, jintArray jDstStrides, jint desiredHeight, jint flags) { tjhandle handle=0; jbyteArray jDstPlanes[3]={NULL, NULL, NULL}; unsigned char *jpegBuf=NULL, *dstPlanes[3]; int *dstOffsets=NULL, *dstStrides=NULL; int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0; int nc=0, i, width, height, scaledWidth, scaledHeight, nsf=0; tjscalingfactor *sf; gethandle(); if((*env)->GetArrayLength(env, src)<jpegSize) _throwarg("Source buffer is not large enough"); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight=(int)(*env)->GetIntField(env, obj, _fid); nc=(jpegSubsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3); width=desiredWidth; height=desiredHeight; if(width==0) width=jpegWidth; if(height==0) height=jpegHeight; sf=tjGetScalingFactors(&nsf); if(!sf || nsf<1) _throwarg(tjGetErrorStr()); for(i=0; i<nsf; i++) { scaledWidth=TJSCALED(jpegWidth, sf[i]); scaledHeight=TJSCALED(jpegHeight, sf[i]); if(scaledWidth<=width && scaledHeight<=height) break; } bailif0(dstOffsets=(*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); bailif0(dstStrides=(*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); for(i=0; i<nc; i++) { int planeSize=tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight, jpegSubsamp); int pw=tjPlaneWidth(i, scaledWidth, jpegSubsamp); if(planeSize<0 || pw<0) _throwarg(tjGetErrorStr()); if(dstOffsets[i]<0) _throwarg("Invalid argument in decompressToYUV()"); if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0) _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); bailif0(jDstPlanes[i]=(*env)->GetObjectArrayElement(env, dstobjs, i)); if((*env)->GetArrayLength(env, jDstPlanes[i])<dstOffsets[i]+planeSize) _throwarg("Destination plane is not large enough"); bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); dstPlanes[i]=&dstPlanes[i][dstOffsets[i]]; } bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); if(tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, dstPlanes, desiredWidth, dstStrides, desiredHeight, flags)==-1) _throwtj(); bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); for(i=0; i<nc; i++) { if(dstPlanes[i] && jDstPlanes[i]) (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i], 0); } if(dstStrides) (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0); if(dstOffsets) (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0); return; }
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; }
static int JNICustomFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentIndex, int transformIndex, tjtransform *transform) { JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data; JNIEnv *env=params->env; jobject tobj=params->tobj, cfobj=params->cfobj; jobject arrayRegionObj, planeRegionObj, bufobj, borobj; jclass cls; jmethodID mid; jfieldID fid; bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs, sizeof(short)*arrayRegion.w*arrayRegion.h)); bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder")); bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder", "()Ljava/nio/ByteOrder;")); bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid)); bailif0(cls=(*env)->GetObjectClass(env, bufobj)); bailif0(mid=(*env)->GetMethodID(env, cls, "order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;")); (*env)->CallObjectMethod(env, bufobj, mid, borobj); bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer", "()Ljava/nio/ShortBuffer;")); bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid)); bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle")); bailif0(arrayRegionObj=(*env)->AllocObject(env, cls)); bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x); bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y); bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w); bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h); bailif0(planeRegionObj=(*env)->AllocObject(env, cls)); bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x); bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y); bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w); bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h); bailif0(cls=(*env)->GetObjectClass(env, cfobj)); bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter", "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V")); (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj, planeRegionObj, componentIndex, transformIndex, tobj); return 0; bailout: return -1; }
JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize, jobjectArray dstobjs, jobjectArray tobjs, jint flags) { tjhandle handle=0; int i; unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0; unsigned long *dstSizes=NULL; tjtransform *t=NULL; jbyteArray *jdstBufs=NULL; int jpegWidth=0, jpegHeight=0, jpegSubsamp; jintArray jdstSizes=0; jint *dstSizesi=NULL; JNICustomFilterParams *params=NULL; gethandle(); if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize) _throw("Source buffer is not large enough"); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid); n=(*env)->GetArrayLength(env, dstobjs); if(n!=(*env)->GetArrayLength(env, tobjs)) _throw("Mismatch between size of transforms array and destination buffers array"); if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL) _throw("Memory allocation failure"); if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL) _throw("Memory allocation failure"); if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL) _throw("Memory allocation failure"); if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL) _throw("Memory allocation failure"); if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n)) ==NULL) _throw("Memory allocation failure"); for(i=0; i<n; i++) { dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0; memset(&t[i], 0, sizeof(tjtransform)); memset(¶ms[i], 0, sizeof(JNICustomFilterParams)); } for(i=0; i<n; i++) { jobject tobj, cfobj; bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i)); bailif0(_cls=(*env)->GetObjectClass(env, tobj)); bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I")); t[i].op=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I")); t[i].options=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I")); t[i].r.x=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I")); t[i].r.y=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I")); t[i].r.w=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I")); t[i].r.h=(*env)->GetIntField(env, tobj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf", "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;")); cfobj=(*env)->GetObjectField(env, tobj, _fid); if(cfobj) { params[i].env=env; params[i].tobj=tobj; params[i].cfobj=cfobj; t[i].customFilter=JNICustomFilter; t[i].data=(void *)¶ms[i]; } } bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); for(i=0; i<n; i++) { int w=jpegWidth, h=jpegHeight; if(t[i].r.w!=0) w=t[i].r.w; if(t[i].r.h!=0) h=t[i].r.h; bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i)); if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) <tjBufSize(w, h, jpegSubsamp)) _throw("Destination buffer is not large enough"); bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0)); } if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t, flags|TJFLAG_NOREALLOC)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0); jpegBuf=NULL; for(i=0; i<n; i++) { (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0); dstBufs[i]=NULL; } _throw(tjGetErrorStr()); } jdstSizes=(*env)->NewIntArray(env, n); bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0)); for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i]; bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0); if(dstBufs) { for(i=0; i<n; i++) { if(dstBufs[i] && jdstBufs && jdstBufs[i]) (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0); } free(dstBufs); } if(jdstBufs) free(jdstBufs); if(dstSizes) free(dstSizes); if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0); if(t) free(t); return jdstSizes; }
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); }