diff options
Diffstat (limited to 'src/newt/native/X11Screen.c')
-rw-r--r-- | src/newt/native/X11Screen.c | 422 |
1 files changed, 35 insertions, 387 deletions
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c index 334c39727..152a092c9 100644 --- a/src/newt/native/X11Screen.c +++ b/src/newt/native/X11Screen.c @@ -29,7 +29,7 @@ // #define VERBOSE_ON 1 // #define DBG_PERF 1 -#include "X11Common.h" +#include "X11Screen.h" #ifdef DBG_PERF #include "timespec.h" @@ -74,418 +74,66 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0 return (jint) DisplayHeight( dpy, scrn_idx); } -static int showedRandRVersion = 0; - -static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) { - if( 0 == XRRQueryVersion(dpy, major, minor) ) { - return False; - } - if(0 == showedRandRVersion) { - DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor); - showedRandRVersion = 1; - } - return True; -} - -static Bool NewtScreen_hasRANDR(Display *dpy) { - int major, minor; - return NewtScreen_getRANDRVersion(dpy, &major, &minor); -} - -static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) { - int rot; +int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) { + int degree; if(xrotation == RR_Rotate_0) { - rot = 0; + degree = 0; } else if(xrotation == RR_Rotate_90) { - rot = 90; + degree = 90; } else if(xrotation == RR_Rotate_180) { - rot = 180; + degree = 180; } else if(xrotation == RR_Rotate_270) { - rot = 270; + degree = 270; } else { NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation); } - return rot; + return degree; } -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getAvailableScreenModeRotations0 - * Signature: (JI)I - */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) -{ - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - int num_rotations = 0; - Rotation cur_rotation, rotations_supported; - int rotations[4]; - int major, minor; - - if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) { - fprintf(stderr, "RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - - rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation); - - if(0 != (rotations_supported & RR_Rotate_0)) { - rotations[num_rotations++] = 0; - } - if(0 != (rotations_supported & RR_Rotate_90)) { - rotations[num_rotations++] = 90; - } - if(0 != (rotations_supported & RR_Rotate_180)) { - rotations[num_rotations++] = 180; +int NewtScreen_Degree2XRotation(JNIEnv *env, int degree) { + int xrot; + if(degree == 0) { + xrot = RR_Rotate_0; } - if(0 != (rotations_supported & RR_Rotate_270)) { - rotations[num_rotations++] = 270; + else if(degree == 90) { + xrot = RR_Rotate_90; } - - jintArray properties = NULL; - - if(num_rotations>0) { - properties = (*env)->NewIntArray(env, num_rotations); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations); - } - - // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations); - } - - return properties; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getNumScreenModeResolution0 - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) -{ - Display *dpy = (Display *) (intptr_t) display; -#ifdef DBG_PERF - struct timespec t0, t1, td; - long td_ms; - timespec_now(&t0); -#endif - - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0: RANDR not available\n"); - return 0; + else if(degree == 180) { + xrot = RR_Rotate_180; } - -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL); -#endif - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions - -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL); -#endif - - DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes); - - return num_sizes; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getScreenModeResolutions0 - * Signature: (JII)[I - */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) -{ - Display *dpy = (Display *) (intptr_t) display; - - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0: RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); - } - - // Fill the properties in temp jint array - int propIndex = 0; - jint prop[4]; - - prop[propIndex++] = xrrs[(int)resMode_idx].width; - prop[propIndex++] = xrrs[(int)resMode_idx].height; - prop[propIndex++] = xrrs[(int)resMode_idx].mwidth; - prop[propIndex++] = xrrs[(int)resMode_idx].mheight; - - jintArray properties = (*env)->NewIntArray(env, 4); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4); + else if(degree == 270) { + xrot = RR_Rotate_270; + } else { + NewtCommon_throwNewRuntimeException(env, "invalid degree: %d", degree); } - - // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, properties, 0, 4, prop); - - return properties; + return xrot; } /* * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getScreenModeRates0 - * Signature: (JII)[I + * Method: GetRandRVersion0 + * Signature: (J)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getRandRVersion0 + (JNIEnv *env, jclass clazz, jlong display) { - Display *dpy = (Display *) (intptr_t) display; - - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0: RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); + Display * dpy = (Display *)(intptr_t)display; + jint version[2]; + if( 0 == XRRQueryVersion(dpy, &version[0], &version[1] ) ) { + version[0] = 0; + version[1] = 0; } - - int num_rates; - short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates); - - jint prop[num_rates]; - int i; - for(i=0; i<num_rates; i++) { - prop[i] = (int) rates[i]; - /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */ - } - - jintArray properties = (*env)->NewIntArray(env, num_rates); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates); + jintArray jversion = (*env)->NewIntArray(env, 2); + if (jversion == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size 2"); } // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop); + (*env)->SetIntArrayRegion(env, jversion, 0, 2, version); - return properties; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getScreenConfiguration0 - * Signature: (JI)J - */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0 - (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) -{ - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)screen_idx); -#ifdef DBG_PERF - struct timespec t0, t1, td; - long td_ms; - timespec_now(&t0); -#endif - - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0: RANDR not available\n"); - return 0; - } -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL); -#endif - - // get current resolutions and frequencies - XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL); -#endif - - return (jlong) (intptr_t) conf; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: freeScreenConfiguration0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_freeScreenConfiguration0 - (JNIEnv *env, jclass clazz, jlong screenConfiguration) -{ - XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration ); -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenRate0 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0 - (JNIEnv *env, jclass clazz, jlong screenConfiguration) -{ - XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; - - short original_rate = XRRConfigCurrentRate(conf); - DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate); - - return (jint) original_rate; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenRotation0 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0 - (JNIEnv *env, jclass clazz, jlong screenConfiguration) -{ - XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; - Rotation rotation; - - XRRConfigCurrentConfiguration(conf, &rotation); - - return NewtScreen_XRotation2Degree(env, rotation); -} - - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenResolutionIndex0 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0 - (JNIEnv *env, jclass clazz, jlong screenConfiguration) -{ - XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; - - short original_rate = XRRConfigCurrentRate(conf); - - Rotation original_rotation; - SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation); - - DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id); - return (jint)original_size_id; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: setCurrentScreenModeStart0 - * Signature: (JIJIII)Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0 - (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation) -{ - Display *dpy = (Display *) (intptr_t) display; - XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; - Window root = RootWindow(dpy, (int)screen_idx); - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions - int rot; - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); - } - - switch(rotation) { - case 0: - rot = RR_Rotate_0; - break; - case 90: - rot = RR_Rotate_90; - break; - case 180: - rot = RR_Rotate_180; - break; - case 270: - rot = RR_Rotate_270; - break; - default: - NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation); - } - - DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n", - resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation); - - XRRSelectInput (dpy, root, RRScreenChangeNotifyMask); - - XSync(dpy, False); - XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime); - XSync(dpy, False); - - return JNI_TRUE; -} - -/* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: setCurrentScreenModePollEnd0 - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0 - (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) -{ - Display *dpy = (Display *) (intptr_t) display; - int randr_event_base, randr_error_base; - XEvent evt; - XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt; - - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0: RANDR not available\n"); - return JNI_FALSE; - } - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions - XRRScreenConfiguration *conf; - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); - } - - XRRQueryExtension(dpy, &randr_event_base, &randr_error_base); - - int done = 0; - int rot; - do { - if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) { - return; - } - XNextEvent(dpy, &evt); - - switch (evt.type - randr_event_base) { - case RRScreenChangeNotify: - rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation); - DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n", - (void*)scn_event->window, (void*)scn_event->root, - (int)scn_event->size_index, rot, - scn_event->width, scn_event->height); - // done = scn_event->size_index == resMode_idx; // not reliable .. - done = rot == rotation && - scn_event->width == xrrs[resMode_idx].width && - scn_event->height == xrrs[resMode_idx].height; - break; - default: - DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window); - } - XRRUpdateConfiguration(&evt); - } while(!done); - - XSync(dpy, False); - + return jversion; } |