diff options
Diffstat (limited to 'src/newt')
5 files changed, 454 insertions, 9 deletions
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java b/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java index 74dd8ebcd..2b61d34c4 100644 --- a/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java @@ -9,6 +9,8 @@ public class ScreenMode { private int index; private int width; private int height; + private int bitsPerPixel = -1; + private short[] rates = null; public ScreenMode(int index, int width, int height) { @@ -16,7 +18,15 @@ public class ScreenMode { this.width = width; this.height = height; } - + /** Not safe to use this on platforms + * other than windows. Since the mode ids + * on X11 match the native ids. unlike windows + * where the ids are generated . + * @param index + */ + public void setIndex(int index) { + this.index = index; + } public int getIndex() { return index; } @@ -38,4 +48,29 @@ public class ScreenMode { public void setRates(short[] rates) { this.rates = rates; } + + public int getBitsPerPixel() { + return bitsPerPixel; + } + + public void setBitsPerPixel(int bitsPerPixel) { + this.bitsPerPixel = bitsPerPixel; + } + + public short getHighestAvailableRate(){ + short highest = rates[0]; + if(rates.length > 1){ + for (int i = 1; i < rates.length; i++) { + if(rates[i] > highest){ + highest = rates[i]; + } + } + } + return highest; + } + + public String toString() { + return "ScreenMode: " + this.index + " - " + this.width + " x " + + this.height + " " + getHighestAvailableRate() + " Hz"; + } } diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index a0879a634..49816c79d 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -1165,7 +1165,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer h = nfs_height; } if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen); + System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen); } this.fullscreen = fullscreen; reconfigureWindowImpl(x, y, w, h); diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java index 5dd2689e5..3cac617ab 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java @@ -33,8 +33,13 @@ package com.jogamp.newt.impl.windows; +import java.util.ArrayList; + import com.jogamp.newt.*; import com.jogamp.newt.impl.ScreenImpl; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.newt.impl.ScreenModeStatus; + import javax.media.nativewindow.*; public class WindowsScreen extends ScreenImpl { @@ -52,7 +57,155 @@ public class WindowsScreen extends ScreenImpl { } protected void closeNativeImpl() { } + + public int getDesktopScreenModeIndex() { + int index = super.getDesktopScreenModeIndex(); + if(index == -1) { + /** Set the current screen mode to refering to index zero + * dependent on the impl of getScreenModes which saves the + * current screen mode at index 0 which is the original screen mode + */ + ScreenMode[] screenModes = getScreenModes(); + if(screenModes != null) { + if(screenModes[0] != null) { + index = screenModes[0].getIndex(); + } + } + } + return index; + } + + public void setScreenMode(int modeIndex, short rate) { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + ScreenMode[] screenModes = sms.getScreenModes(); + + short selectedRate = rate; + int selectedMode = modeIndex; + + if(modeIndex < 0 || (modeIndex > screenModes.length)){ + selectedMode = sms.getOriginalScreenMode(); + } + ScreenMode sm = screenModes[selectedMode]; + + if(selectedRate == -1){ + selectedRate = sms.getOriginalScreenRate(); + } + + boolean rateAvailable = false; + short[] rates = sm.getRates(); + for(int i=0;i<rates.length;i++){ + if(rates[i] == selectedRate){ + rateAvailable = true; + break; + } + } + if(!rateAvailable){ + selectedRate = rates[0]; + } + + if(0 == setScreenMode0(idx, sm.getWidth(), sm.getHeight(), sm.getBitsPerPixel(), selectedRate)){ + sms.setCurrentScreenMode(selectedMode); + sms.setCurrentScreenRate(selectedRate); + } + } + + public short getCurrentScreenRate() { + short rate = super.getCurrentScreenRate(); + if(rate == -1){ + rate = (short)getCurrentScreenRate0(idx); + } + return rate; + } + + public ScreenMode[] getScreenModes() { + ScreenMode[] screenModes = super.getScreenModes(); + if(screenModes == null) { + ArrayList smTemp = new ArrayList(); + + int modeID = -1; + ScreenMode mySM = getScreenMode(modeID++); + int currentBitsPerPixel = mySM.getBitsPerPixel(); + while(mySM != null){ + //filter out modes with diff bits per pixel + if(mySM.getBitsPerPixel() == currentBitsPerPixel) { + smTemp.add(mySM); + } + mySM = getScreenMode(modeID++); + } + int numModes = smTemp.size(); + if(numModes > 0) { + screenModes = new ScreenMode[numModes]; + for(int i=0;i<numModes;i++) { + ScreenMode sm = (ScreenMode)smTemp.get(i); + sm.setIndex(i); + screenModes[i] = sm; + } + } + } + return screenModes; + } + private ScreenMode getScreenMode(int modeIndex) { + int[] modeProp = getScreenMode0(idx, modeIndex); + if(modeProp == null){ + return null; + } + int propIndex = 0; + int width = modeProp[propIndex++]; + int height = modeProp[propIndex++]; + int bits = modeProp[propIndex++]; + short rate = (short)modeProp[propIndex++]; + + ScreenMode screenMode = new ScreenMode(modeIndex+1, width, height); + screenMode.setRates(new short[]{rate}); + screenMode.setBitsPerPixel(bits); + return screenMode; + } + + public void setScreenRotation(int rot) { + if(!isRotationValid(rot)){ + return; + } + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(0 == setScreenRotation0(idx, rot)) { + sms.setCurrentScreenRotation(rot); + } + } + + /** Check if this rotation is valid for platform + * @param rot user requested rotation angle + * @return true if is valid + */ + private boolean isRotationValid(int rot){ + if((rot == ScreenMode.ROTATE_0) || (rot == ScreenMode.ROTATE_90) || + (rot == ScreenMode.ROTATE_180) || (rot == ScreenMode.ROTATE_270)) { + return true; + } + return false; + } + + public int getCurrentScreenRotation() { + int rot = super.getCurrentScreenRotation(); + if(rot == -1){ + return getCurrentScreenRotation0(idx); + } + return rot; + } + + // Native calls - private native int getWidthImpl0(int scrn_idx); - private native int getHeightImpl0(int scrn_idx); + private native int getWidthImpl0(int scrn_idx); + private native int getHeightImpl0(int scrn_idx); + + private native int getCurrentScreenRate0(int scrn_idx); + private native int[] getScreenMode0(int screen_index, int mode_index); + + /** Change screen mode and return zero if successful + */ + private native int setScreenMode0(int screen_index, int width, int height, int bits, short freq); + + private native int getCurrentScreenRotation0(int screen_index); + + /** Change screen mode and return zero if successful + */ + private native int setScreenRotation0(int screen_index, int rot); } diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 3ade599da..d5d969023 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -157,7 +157,7 @@ public class WindowsWindow extends WindowImpl { } protected void reconfigureWindowImpl(int x, int y, int width, int height) { - reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated()); + reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated(), isFullscreen()); } protected boolean reparentWindowImpl() { @@ -194,7 +194,7 @@ public class WindowsWindow extends WindowImpl { private native void setSize0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height); private static native void setPosition0(long parentWindowHandle, long windowHandle, int x, int y /*, int width, int height*/); private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, - int x, int y, int width, int height, boolean isUndecorated); + int x, int y, int width, int height, boolean isUndecorated, boolean fullscreen); private native void reparentWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated); private static native void setTitle0(long windowHandle, String title); private native void requestFocus0(long windowHandle, boolean reparented); diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index e1250811c..612fd2cc9 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -90,6 +90,8 @@ #define MONITOR_DEFAULTTONEAREST 2 #endif +#include "com_jogamp_newt_impl_windows_WindowsDisplay.h" +#include "com_jogamp_newt_impl_windows_WindowsScreen.h" #include "com_jogamp_newt_impl_windows_WindowsWindow.h" #include "MouseEvent.h" @@ -1066,6 +1068,220 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight } /* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getCurrentScreenRate0 + * Signature: (I)S + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRate0 + (JNIEnv *env, jobject object, jint scrn_idx) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + int rate = -1; + if (0 != EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + rate = dm.dmDisplayFrequency; + } + + return rate; +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getScreenMode0 + * Signature: (II)[I + */ +JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getScreenMode0 + (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx) +{ + int propIndex = 0; + int prop_size = 4; //wxhxbxf + + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + int devModeID = (int)mode_idx; + + if(devModeID == -1) + { + devModeID = ENUM_CURRENT_SETTINGS; + } + + jintArray properties = (*env)->NewIntArray(env, prop_size); + + //Fill the properties in temp jint array + jint prop[prop_size]; + if (0 == EnumDisplaySettings(NULL /*current display device*/, devModeID, &dm)) + { + return NULL; + } + prop[propIndex++] = dm.dmPelsWidth; + prop[propIndex++] = dm.dmPelsHeight; + prop[propIndex++] = dm.dmBitsPerPel; + prop[propIndex++] = dm.dmDisplayFrequency; + + (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop); + + return properties; +} + +#define SCREEN_MODE_NOERROR 0 +#define SCREEN_MODE_ERROR 1 +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: setScreenMode0 + * Signature: (IIIIS)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenMode0 + (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jshort rate) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_MODE_ERROR; + } + + dm.dmPelsWidth = (int)width; + dm.dmPelsHeight = (int)height; + dm.dmBitsPerPel = (int)bits; + dm.dmDisplayFrequency = (int)rate; + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + + long result = ChangeDisplaySettings(&dm, 0); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return SCREEN_MODE_NOERROR; + } + return SCREEN_MODE_ERROR; +} + +#define SCREEN_ROT_ERROR -1 +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getCurrentScreenRotation0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRotation0 + (JNIEnv *env, jobject object, jint scrn_idx) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_ROT_ERROR; + } + + int currentRotation = -1; + switch (dm.dmDisplayOrientation) + { + case DMDO_DEFAULT: + currentRotation = 0; + break; + case DMDO_270: + currentRotation = 270; + break; + case DMDO_180: + currentRotation = 180; + break; + case DMDO_90: + currentRotation = 90; + break; + default: + break; + } + return currentRotation; +} +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: setScreenRotation0 + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenRotation0 + (JNIEnv *env, jobject object, jint scrn_idx, jint rot) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_MODE_ERROR; + } + int requestedRotation = dm.dmDisplayOrientation; + int currentRotation = dm.dmDisplayOrientation; + + int shouldFlipDims = 0; + + int rotation = (int)rot; + switch (rotation) + { + case 0: + requestedRotation = DMDO_DEFAULT; + if (currentRotation == DMDO_90 || currentRotation == DMDO_270) + { + shouldFlipDims = 1; + } + break; + case 270: + requestedRotation = DMDO_270; + if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180) + { + shouldFlipDims = 1; + } + break; + case 180: + requestedRotation = DMDO_180; + if (currentRotation == DMDO_90 || currentRotation == DMDO_270) + { + shouldFlipDims = 1; + } + break; + case 90: + requestedRotation = DMDO_90; + if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180) + { + shouldFlipDims = 1; + } + break; + default: + //requested rotation not available + return SCREEN_MODE_ERROR; + break; + } + /** swap width and height if changing from vertical to horizantal + * or horizantal to vertical + */ + if (shouldFlipDims) + { + int tempWidth = dm.dmPelsWidth; + dm.dmPelsWidth = dm.dmPelsHeight; + dm.dmPelsHeight = tempWidth; + } + dm.dmDisplayOrientation = requestedRotation; + dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + + long result = ChangeDisplaySettings(&dm, 0); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return SCREEN_MODE_NOERROR; + } + return SCREEN_MODE_ERROR; +} + +/* * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: initIDs0 * Signature: ()Z @@ -1365,13 +1581,45 @@ static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWN DBG_PRINT("*** WindowsWindow: reparentWindow.X\n"); } +#define FULLSCREEN_NOERROR 0 +#define FULLSCREEN_ERROR 1 + +static int NewtWindows_setFullScreen(jboolean fullscreen) +{ + int flags = 0; + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return FULLSCREEN_ERROR; + } + + if(fullscreen == JNI_TRUE) + { + flags = CDS_FULLSCREEN; //set fullscreen temporary + } + else + { + flags = CDS_RESET; // reset to registery values + } + long result = ChangeDisplaySettings(&dm, flags); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return FULLSCREEN_NOERROR; + } + return FULLSCREEN_ERROR; +} + /* * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: reconfigureWindow0 * Signature: (JIIIIZ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigureWindow0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) + (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated, jboolean isFullscreen) { UINT flags; HWND hwndP = (HWND) (intptr_t) parent; @@ -1382,9 +1630,18 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigu DBG_PRINT("*** WindowsWindow: reconfigureWindow0.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n", parent, window, x, y, width, height, bIsUndecorated, isVisible); + if(isFullscreen == JNI_FALSE) + { + NewtWindows_setFullScreen(isFullscreen); + } NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated); - - if ( NULL == hwndP ) { + + if(isFullscreen == JNI_TRUE) + { + NewtWindows_setFullScreen(isFullscreen); + } + + if ( NULL == hwndP ) { flags = SWP_SHOWWINDOW; hWndInsertAfter = HWND_TOPMOST; } else { |