summaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Window.c
diff options
context:
space:
mode:
authorRami Santina <[email protected]>2010-10-17 03:36:59 +0300
committerRami Santina <[email protected]>2010-10-17 03:36:59 +0300
commit735ebb60ead9996106dfcb958ddfbb6b00b407fd (patch)
treebf393633d7fffc754ef6928aba6cc63abd299e53 /src/newt/native/X11Window.c
parent774138544e1eec3330309ad682fa05154a07ab8d (diff)
Screen Mode manipulation API (with X11 impl) ; X11 Fullscreen impl
Added screen mode change capability with impl for X11 (using Xrandr) com.jogamp.newt.Screen: added 4 methods which cover screen mode lifecycle ScreenMode[] getScreenModes(): Get list of available screen modes returns null if not natively implemented. On first call will fetch the list thru a set of native calls and stores them in the ScreenModeState. Consequent calls will retreive the data from the ScreenModeStatus object. Native calls are done on creation stage, so subsequent API calls will return cached data. int getDesktopScreenModeIndex(): Get the Current Desktop Screen mode index returns -1 if functionality not natively implemented. The index returned refers to the screen mode location in the ScreenMode array. Used to get initial mode for reverting back. Initial call will retreive the mode thru a native call (done on initialization), subsequent API calls will retreive it from the ScreenModeStatus object. Note: If Window is closed without reverting back and screen is set to unreachable. The api will revert the screen. A call to destoy(unreachable) is needed for revert to take place on close windowDestroyNotify(WindowEvent e) { ... window.destroy(true); } short getCurrentScreenRate(): Get the current screen rate returns -1 if not natively implemented. Used along with getDesktopScreenModeIndex You can identify the current screen mode (w x h) and the rate. Initial call will retreive the mode thru a native call (done on initialization), subsequent API calls will retreive it from the ScreenModeStatus object. void setScreenMode(int modeIndex, short rate): change the screen mode to the mode index which refers to one of the screen modes retreived by getScreenModes() and a rate which can be one of screenModes.getRates(). If the rate provided doesnt belong to the list of available rates the first rate is chosen. build-newt.xml: Added header files generation for Screen and Display Added Xrandr syslink to x11 based builds. +++++++++++++ Fullscreen for X11Window: Added Fullscreen WM Hint for X11Window. Event of Fullscreen is sent to the display root. When changing to fullscreen the request is send after configuring the window otherwize before decoration. Not Stable yet, needs tweeking on other Linux dist. Window looses focus after switching to fullscreen mode. +++++++++++++++ Added TestScreenMode01NEWT which includes 4 tests 1- Fullscreen change mode 2- Screen mode change 3- Screen change with fullscreen (revert screenmode then revert fullscreen) 4- Screen change with fullscreen (revert fullscreen then revert screenmode) should fail if not screenmode not implemented on platform. +++++++++++++++ Cleaned up some unused imports
Diffstat (limited to 'src/newt/native/X11Window.c')
-rw-r--r--src/newt/native/X11Window.c215
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);
+ }
}
/*