From 3b8b751935fe4d7b3b469cd1335a9e824198682f Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 31 Jan 2006 12:31:41 +0000 Subject: [PATCH] Linux: Fixed resetDisplayMode in case XRandr is used and the first reported mode is not the initial mode --- src/java/org/lwjgl/opengl/LinuxDisplay.java | 25 ++++++++++++++-- src/native/common/common_tools.h | 1 + src/native/linux/display.c | 33 +++++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 24b4de6e..5e2dde1d 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -369,7 +369,16 @@ final class LinuxDisplay implements DisplayImplementation { DisplayMode[] modes = getAvailableDisplayModes(); if (modes == null || modes.length == 0) throw new LWJGLException("No modes available"); - saved_mode = modes[0]; + switch (current_displaymode_extension) { + case XRANDR: + saved_mode = getCurrentXRandrMode(); + break; + case XF86VIDMODE: + saved_mode = modes[0]; + break; + default: + throw new LWJGLException("Unknown display mode extension: " + current_displaymode_extension); + } current_mode = saved_mode; saved_gamma = getCurrentGammaRamp(); current_gamma = saved_gamma; @@ -378,8 +387,18 @@ final class LinuxDisplay implements DisplayImplementation { unlockAWT(); } } - /** Assumes extension != NONE */ - private static native DisplayMode nInit(int extension) throws LWJGLException; + + private static DisplayMode getCurrentXRandrMode() throws LWJGLException { + incDisplay(); + try { + return nGetCurrentXRandrMode(); + } finally { + decDisplay(); + } + } + + /** Assumes extension == XRANDR */ + private static native DisplayMode nGetCurrentXRandrMode() throws LWJGLException; public void setTitle(String title) { lockAWT(); diff --git a/src/native/common/common_tools.h b/src/native/common/common_tools.h index 0e32b388..1839c41d 100644 --- a/src/native/common/common_tools.h +++ b/src/native/common/common_tools.h @@ -141,6 +141,7 @@ extern int copyEvents(event_queue_t *event_queue, jint *output_event_buffer, int extern bool putEvent(event_queue_t *queue, jint *event); extern void throwGeneralException(JNIEnv * env, const char *exception_name, const char * err); extern void throwException(JNIEnv *env, const char *msg); +extern void throwFormattedException(JNIEnv * env, const char *format, ...); extern void throwFMODException(JNIEnv * env, const char * err); extern void setDebugEnabled(bool enable); extern void printfDebugJava(JNIEnv *env, const char *format, ...); diff --git a/src/native/linux/display.c b/src/native/linux/display.c index 0c4e616a..23c850b0 100644 --- a/src/native/linux/display.c +++ b/src/native/linux/display.c @@ -197,7 +197,7 @@ static Status trySetXrandrMode(Display *disp, int screen, mode_info *mode, Time Time config_time; *timestamp = XRRConfigTimes(screen_configuration, &config_time); Rotation current_rotation; - XRRConfigRotations(screen_configuration, ¤t_rotation); + XRRConfigCurrentConfiguration(screen_configuration, ¤t_rotation); status = XRRSetScreenConfigAndRate(disp, screen_configuration, root_window, mode->mode_data.size_index, current_rotation, mode->freq, *timestamp); XRRFreeScreenConfigInfo(screen_configuration); return status; @@ -359,7 +359,6 @@ static jobjectArray getAvailableDisplayModes(JNIEnv * env, Display *disp, int sc avail_modes = getDisplayModes(disp, screen, extension, &num_modes); if (avail_modes == NULL) { printfDebugJava(env, "Could not get display modes"); - XCloseDisplay(disp); return NULL; } // Allocate an array of DisplayModes big enough @@ -375,6 +374,36 @@ static jobjectArray getAvailableDisplayModes(JNIEnv * env, Display *disp, int sc return ret; } +static jobject getCurrentXRandrMode(JNIEnv * env, Display *disp, int screen) { + Drawable root_window = RootWindow(disp, screen); + XRRScreenConfiguration *config = XRRGetScreenInfo(disp, root_window); + if (config == NULL) { + throwException(env, "Could not get current screen configuration."); + return NULL; + } + short rate = XRRConfigCurrentRate(config); + Rotation current_rotation; + SizeID size_index = XRRConfigCurrentConfiguration(config, ¤t_rotation); + int n_sizes; + XRRScreenSize *sizes = XRRConfigSizes(config, &n_sizes); + if (size_index >= n_sizes) { + throwFormattedException(env, "Xrandr current index (%d) is larger than or equals to the number of sizes (%d).", size_index, n_sizes); + XRRFreeScreenConfigInfo(config); + return NULL; + } + XRRScreenSize current_size = sizes[size_index]; + XRRFreeScreenConfigInfo(config); + int bpp = XDefaultDepth(disp, screen); + jclass displayModeClass = (*env)->FindClass(env, "org/lwjgl/opengl/DisplayMode"); + jmethodID displayModeConstructor = (*env)->GetMethodID(env, displayModeClass, "", "(IIII)V"); + jobject displayMode = (*env)->NewObject(env, displayModeClass, displayModeConstructor, current_size.width, current_size.height, bpp, rate); + return displayMode; +} + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetCurrentXRandrMode(JNIEnv *env, jclass unused) { + return getCurrentXRandrMode(env, getDisplay(), getCurrentScreen()); +} + JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetAvailableDisplayModes(JNIEnv *env, jclass clazz, jint extension) { return getAvailableDisplayModes(env, getDisplay(), getCurrentScreen(), extension); }