diff options
Diffstat (limited to 'src/newt/native/X11Window.c')
-rw-r--r-- | src/newt/native/X11Window.c | 215 |
1 files changed, 210 insertions, 5 deletions
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 8a07067b7..26bce0c63 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -48,6 +48,10 @@ #include <X11/keysym.h> #include <X11/Xatom.h> +#include<X11/extensions/Xrandr.h> + +#include "com_jogamp_newt_impl_x11_X11Screen.h" +#include "com_jogamp_newt_impl_x11_X11Display.h" #include "com_jogamp_newt_impl_x11_X11Window.h" #include "MouseEvent.h" @@ -463,6 +467,44 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated) XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); } +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 + +static void NewtWindows_setFullscreen (Display *dpy, Window w, Bool fullscreen) { + Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False ); + Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False ); + Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False ); + + Atom types[2]={0}; + int ntypes=0; + + types[ntypes++] = _NET_WM_STATE_FULLSCREEN; + types[ntypes++] = _NET_WM_STATE_ABOVE; + + XEvent xev; + memset ( &xev, 0, sizeof(xev) ); + + xev.type = ClientMessage; + xev.xclient.window = w; + xev.xclient.message_type = _NET_WM_STATE; + xev.xclient.format = 32; + + if(True==fullscreen) { + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE; + xev.xclient.data.l[3] = 1; //source indication for normal applications + } else { + xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE; + xev.xclient.data.l[3] = 1; //source indication for normal applications + } + + XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); + XSendEvent (dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev ); +} + /* * Class: com_jogamp_newt_impl_x11_X11Display * Method: DispatchMessages @@ -690,6 +732,158 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0 return (jint) XDisplayHeight( dpy, scrn_idx); } +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getDesktopScreenModeIndex0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getDesktopScreenModeIndex0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + // get current resolutions and frequency configuration + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + short original_rate = XRRConfigCurrentRate(conf); + + Rotation original_rotation; + SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation); + + //free + XRRFreeScreenConfigInfo(conf); + + return (jint)original_size_id; +} + +static void X11Screen_changeScreenMode(Display* dpy, Window root, int screen_indx, XRRScreenSize *xrrs, int screenModeIndex, short freq) +{ + int num_rates; //number of available rates for selected mode index + short *rates = XRRRates(dpy, screen_indx, screenModeIndex, &num_rates); + + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + + // Change the resolution + DBG_PRINT("\nCHANGED TO %i x %i PIXELS, %i Hz\n\n", xrrs[screenModeIndex].width, xrrs[screenModeIndex].height, selectedFreq); + XRRSetScreenConfigAndRate(dpy, conf, root, screenModeIndex, RR_Rotate_0, freq, CurrentTime); + + //free + XRRFreeScreenConfigInfo(conf); +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: setScreenMode0 + * Signature: (JIIS)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setScreenMode0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx, jshort freq) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + int screenModeIndex = (int)mode_indx; + + if((screenModeIndex > num_sizes) || (screenModeIndex < 0)) + { + DBG_PRINT("\nSelected mode index not available for selected screen, index: %i\n", screenModeIndex); + return; + } + + X11Screen_changeScreenMode(dpy, root, (int)scrn_indx, xrrs, screenModeIndex, (short)freq); +} + +#define NUM_SCREEN_MODE_PROPERTIES 3 + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getScreenMode0 + * Signature: (JII)[I + */ +JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenMode0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + + int num_rates; + short *rates = XRRRates(dpy, (int)scrn_indx, (int)mode_indx, &num_rates); + + int prop_size = NUM_SCREEN_MODE_PROPERTIES +num_rates; + + jintArray properties = (*env)->NewIntArray(env, prop_size); + if (properties == NULL) + { + return NULL; /* out of memory error thrown */ + } + + //Fill the properties in temp jint array + int propIndex = 0; + jint prop[prop_size]; + + prop[propIndex++] = (int)mode_indx; + prop[propIndex++] = xrrs[(int)mode_indx].width; + prop[propIndex++] = xrrs[(int)mode_indx].height; + + //loop through all possible resolutions + //with the selectable display frequencies + int i= 0; + while(i < num_rates) + { + prop[propIndex++] = rates[i]; + i++; + } + + + // move from the temp structure to the java structure + (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop); + + return properties; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getNumScreenModes0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModes0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + + return num_sizes; +} + + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getCurrentScreenRate0 + * Signature: (JI)S + */ +JNIEXPORT jshort JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + // get current resolutions and frequencies + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + short original_rate = XRRConfigCurrentRate(conf); + + //free + XRRFreeScreenConfigInfo(conf); + + return original_rate; +} /** * Window @@ -1037,7 +1231,7 @@ static void NewtWindows_reparentWindow */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0 (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, - jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible) + jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible, jboolean isFullscreen) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -1045,17 +1239,23 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow XWindowChanges xwc; XWindowAttributes xwa; - - DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n", - (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible); + + DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d, fullscreen %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible,isFullscreen); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } + XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - + + if(JNI_FALSE == isFullscreen ) { + NewtWindows_setFullscreen(dpy, w, False ); + XSync(dpy, False); + } + NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); XSync(dpy, False); @@ -1066,6 +1266,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow xwc.height=height; XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); XSync(dpy, False); + + if(JNI_TRUE == isFullscreen ) { + NewtWindows_setFullscreen(dpy, w, True ); + XSync(dpy, False); + } } /* |