Linux: Move gamma ramps to java code

This commit is contained in:
Elias Naur 2005-11-21 16:32:34 +00:00
parent c9669d20c9
commit debaaf6538
4 changed files with 120 additions and 90 deletions

View File

@ -44,6 +44,7 @@ import java.nio.IntBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Keyboard;
final class LinuxDisplay implements DisplayImplementation {
@ -78,6 +79,28 @@ final class LinuxDisplay implements DisplayImplementation {
private static PeerInfo peer_info;
/** Saved gamma used to restore display settings */
private static ByteBuffer saved_gamma;
private static ByteBuffer current_gamma;
private static ByteBuffer getCurrentGammaRamp() throws LWJGLException {
lockAWT();
try {
incDisplay();
try {
if (isXF86VidModeSupported())
return nGetCurrentGammaRamp();
else
return BufferUtils.createByteBuffer(0);
} finally {
decDisplay();
}
} finally {
unlockAWT();
}
}
private static native ByteBuffer nGetCurrentGammaRamp() throws LWJGLException;
private static int getBestDisplayModeExtension() throws LWJGLException {
lockAWT();
try {
@ -233,30 +256,55 @@ final class LinuxDisplay implements DisplayImplementation {
public void resetDisplayMode() {
lockAWT();
try {
nResetDisplayMode(current_displaymode_extension);
nResetDisplayMode(current_displaymode_extension, saved_gamma);
} finally {
unlockAWT();
}
}
private static native void nResetDisplayMode(int extension);
private static native void nResetDisplayMode(int extension, ByteBuffer gamma_ramp);
public int getGammaRampLength() {
lockAWT();
int length = nGetGammaRampLength();
unlockAWT();
return length;
try {
try {
incDisplay();
int length;
if (isXF86VidModeSupported()) {
length = nGetGammaRampLength();
} else
length = 0;
decDisplay();
return length;
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to get gamma ramp length: " + e);
return 0;
}
} finally {
unlockAWT();
}
}
private static native int nGetGammaRampLength();
public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException {
lockAWT();
try {
nSetGammaRamp(gammaRamp);
incDisplay();
boolean xf86_support = isXF86VidModeSupported();
decDisplay();
if (!xf86_support)
throw new LWJGLException("No gamma ramp support (Missing XF86VM extension)");
current_gamma = convertToNativeRamp(gammaRamp);
nSetGammaRamp(current_gamma);
} finally {
unlockAWT();
}
}
private static native void nSetGammaRamp(FloatBuffer gammaRamp) throws LWJGLException;
private static native void nSetGammaRamp(ByteBuffer gammaRamp) throws LWJGLException;
private static ByteBuffer convertToNativeRamp(FloatBuffer ramp) throws LWJGLException {
return nConvertToNativeRamp(ramp, ramp.position(), ramp.remaining());
}
private static native ByteBuffer nConvertToNativeRamp(FloatBuffer ramp, int offset, int length) throws LWJGLException;
public String getAdapter() {
return null;
@ -273,6 +321,8 @@ final class LinuxDisplay implements DisplayImplementation {
if (current_displaymode_extension == NONE)
throw new LWJGLException("No display mode extension is available");
DisplayMode mode = nInit(current_displaymode_extension);
saved_gamma = getCurrentGammaRamp();
current_gamma = saved_gamma;
return mode;
} finally {
unlockAWT();
@ -327,10 +377,10 @@ final class LinuxDisplay implements DisplayImplementation {
public void update() {
lockAWT();
nUpdate(current_displaymode_extension, current_window_mode);
nUpdate(current_displaymode_extension, current_window_mode, saved_gamma, current_gamma);
unlockAWT();
}
private static native void nUpdate(int extension, int current_window_mode);
private static native void nUpdate(int extension, int current_window_mode, ByteBuffer saved_gamma, ByteBuffer current_gamma);
public void reshape(int x, int y, int width, int height) {
lockAWT();

View File

@ -70,10 +70,6 @@ static int saved_freq;
static int current_width;
static int current_height;
static int current_freq;
static int saved_gamma_ramp_length = 0;
static unsigned short *saved_ramp = NULL;
static unsigned short *current_ramp = NULL;
static int current_gamma_ramp_length = 0;
int getScreenModeWidth(void) {
return current_width;
@ -281,18 +277,8 @@ static bool setMode(JNIEnv *env, Display *disp, int screen, jint extension, int
return result;
}
static void freeSavedGammaRamps() {
free(saved_ramp);
saved_ramp = NULL;
saved_gamma_ramp_length = 0;
}
static int getGammaRampLengthOfDisplay(JNIEnv *env, Display *disp, int screen) {
int getGammaRampLengthOfDisplay(JNIEnv *env, Display *disp, int screen) {
int ramp_size;
if (!isXF86VidModeSupported(env, disp)) {
printfDebugJava(env, "XF86VidMode extension version >= 2 not found");
return 0;
}
if (XF86VidModeGetGammaRampSize(disp, screen, &ramp_size) == False) {
printfDebugJava(env, "XF86VidModeGetGammaRampSize call failed");
return 0;
@ -300,15 +286,23 @@ static int getGammaRampLengthOfDisplay(JNIEnv *env, Display *disp, int screen) {
return ramp_size;
}
int getGammaRampLength(JNIEnv *env, int screen) {
Display *disp = XOpenDisplay(NULL);
if (disp == NULL) {
printfDebugJava(env, "Could not open display");
return 0;
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nConvertToNativeRamp(JNIEnv *env, jclass unused, jobject ramp_buffer, jint buffer_offset, jint length) {
const jfloat *ramp_ptr = (const jfloat *)(*env)->GetDirectBufferAddress(env, ramp_buffer) + buffer_offset;
jobject native_ramp = newJavaManagedByteBuffer(env, length*3*sizeof(unsigned short));
if (native_ramp == NULL) {
throwException(env, "Failed to allocate gamma ramp buffer");
return NULL;
}
int length = getGammaRampLengthOfDisplay(env, disp, screen);
XCloseDisplay(disp);
return length;
unsigned short *native_ramp_ptr = (unsigned short *)(*env)->GetDirectBufferAddress(env, native_ramp);
int i;
for (i = 0; i < length; i++) {
float scaled_gamma = ramp_ptr[i]*0xffff;
short scaled_gamma_short = (unsigned short)round(scaled_gamma);
native_ramp_ptr[i] = scaled_gamma_short;
native_ramp_ptr[i + length] = scaled_gamma_short;
native_ramp_ptr[i + length*2] = scaled_gamma_short;
}
return native_ramp;
}
jobject initDisplay(JNIEnv *env, int screen, jint extension) {
@ -337,38 +331,41 @@ jobject initDisplay(JNIEnv *env, int screen, jint extension) {
free(avail_modes);
/* Fetch the current gamma ramp */
saved_gamma_ramp_length = getGammaRampLengthOfDisplay(env, disp, screen);
if (saved_gamma_ramp_length > 0) {
saved_ramp = (unsigned short *)malloc(sizeof(unsigned short)*3*saved_gamma_ramp_length);
if (!XF86VidModeGetGammaRamp(disp, screen, saved_gamma_ramp_length, saved_ramp,
saved_ramp + saved_gamma_ramp_length, saved_ramp + saved_gamma_ramp_length*2))
freeSavedGammaRamps();
}
XCloseDisplay(disp);
return newMode;
}
static void freeCurrentGamma(void) {
if (current_ramp != NULL) {
free(current_ramp);
current_ramp = NULL;
current_gamma_ramp_length = 0;
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetCurrentGammaRamp(JNIEnv *env, jclass unused) {
int ramp_size = getGammaRampLengthOfDisplay(env, getDisplay(), getCurrentScreen());
jobject ramp_buffer = newJavaManagedByteBuffer(env, sizeof(unsigned short)*3*ramp_size);
if (ramp_buffer == NULL) {
throwException(env, "Could not allocate gamma ramp buffer");
return NULL;
}
unsigned short *ramp = (unsigned short *)(*env)->GetDirectBufferAddress(env, ramp_buffer);
if (!XF86VidModeGetGammaRamp(getDisplay(), getCurrentScreen(), ramp_size, ramp,
ramp + ramp_size, ramp + ramp_size*2)) {
throwException(env, "Could not get the current gamma ramp");
return NULL;
}
return ramp_buffer;
}
static void setCurrentGamma(Display *disp, int screen, JNIEnv *env) {
if (current_gamma_ramp_length == 0)
static void setGamma(JNIEnv *env, Display *disp, int screen, jobject ramp_buffer, bool throw_on_error) {
unsigned short *ramp_ptr = (unsigned short *)(*env)->GetDirectBufferAddress(env, ramp_buffer);
jlong capacity = (*env)->GetDirectBufferCapacity(env, ramp_buffer);
int size = capacity/(sizeof(unsigned short)*3);
if (size == 0)
return;
if (XF86VidModeSetGammaRamp(disp, screen, current_gamma_ramp_length, current_ramp, current_ramp, current_ramp) == False) {
if (env != NULL)
if (XF86VidModeSetGammaRamp(disp, screen, size, ramp_ptr, ramp_ptr + size, ramp_ptr + size*2) == False) {
if (throw_on_error)
throwException(env, "Could not set gamma ramp.");
else
printfDebugJava(env, "Could not set gamma ramp");
printfDebugJava(env, "Could not set gamma ramp.");
}
}
void temporaryRestoreMode(JNIEnv *env, int screen, jint extension) {
void temporaryRestoreMode(JNIEnv *env, int screen, jint extension, jobject saved_gamma_ramp) {
Display *disp = XOpenDisplay(NULL);
if (disp == NULL) {
printfDebugJava(env, "Could not open display");
@ -376,9 +373,9 @@ void temporaryRestoreMode(JNIEnv *env, int screen, jint extension) {
}
if (!setMode(env, disp, screen, extension, current_width, current_height, current_freq, false))
printfDebugJava(env, "Could not restore mode");
setCurrentGamma(disp, screen, NULL);
XCloseDisplay(disp);
// Don't propagate error to caller
setGamma(env, disp, screen, saved_gamma_ramp, false);
XCloseDisplay(disp);
}
void switchDisplayMode(JNIEnv * env, jobject mode, int screen, jint extension) {
@ -403,7 +400,7 @@ void switchDisplayMode(JNIEnv * env, jobject mode, int screen, jint extension) {
XCloseDisplay(disp);
}
void resetDisplayMode(JNIEnv *env, int screen, jint extension, bool temporary) {
void resetDisplayMode(JNIEnv *env, int screen, jint extension, jobject gamma_ramp, bool temporary) {
Display *disp = XOpenDisplay(NULL);
if (disp == NULL) {
printfDebugJava(env, "Failed to contact X Server");
@ -412,11 +409,7 @@ void resetDisplayMode(JNIEnv *env, int screen, jint extension, bool temporary) {
if (!setMode(env, disp, screen, extension, saved_width, saved_height, saved_freq, temporary)) {
printfDebugJava(env, "Failed to reset mode");
}
if (saved_gamma_ramp_length > 0) {
XF86VidModeSetGammaRamp(disp, screen, saved_gamma_ramp_length, saved_ramp, saved_ramp +
saved_gamma_ramp_length, saved_ramp + saved_gamma_ramp_length*2);
}
// decDisplay();
setGamma(env, disp, screen, gamma_ramp, false);
XCloseDisplay(disp);
}
@ -456,19 +449,6 @@ void setGammaRamp(JNIEnv *env, jobject gamma_ramp_buffer, int screen) {
throwException(env, "Could not open display");
return;
}
freeCurrentGamma();
current_gamma_ramp_length = getGammaRampLengthOfDisplay(env, disp, screen);
if (current_gamma_ramp_length == 0) {
throwException(env, "Gamma ramp not supported");
return;
}
const float *gamma_ramp = (const float *)(*env)->GetDirectBufferAddress(env, gamma_ramp_buffer);
current_ramp = (unsigned short *)malloc(sizeof(unsigned short)*current_gamma_ramp_length);
int i;
for (i = 0; i < current_gamma_ramp_length; i++) {
float scaled_gamma = gamma_ramp[i]*0xffff;
current_ramp[i] = (unsigned short)round(scaled_gamma);
}
setCurrentGamma(disp, screen, env);
setGamma(env, disp, screen, gamma_ramp_buffer, true);
XCloseDisplay(disp);
}

View File

@ -49,10 +49,10 @@ extern int getScreenModeWidth(void);
extern int getScreenModeHeight(void);
extern jobject initDisplay(JNIEnv *env, int screen, jint extension);
extern void switchDisplayMode(JNIEnv * env, jobject mode, int screen, jint extension);
extern void resetDisplayMode(JNIEnv *env, int screen, jint extension, bool temporary);
extern void resetDisplayMode(JNIEnv *env, int screen, jint extension, jobject gamma_ramp, bool temporary);
extern jobjectArray getAvailableDisplayModes(JNIEnv * env, int screen, jint extension);
extern int getGammaRampLength(JNIEnv *env, int screen);
extern int getGammaRampLengthOfDisplay(JNIEnv *env, Display *disp, int screen);
extern void setGammaRamp(JNIEnv *env, jobject gamma_ramp_buffer, int screen);
extern void temporaryRestoreMode(JNIEnv *env, int screen, jint extension);
extern void temporaryRestoreMode(JNIEnv *env, int screen, jint extension, jobject gamma_ramp);
#endif

View File

@ -182,7 +182,7 @@ static void setDecorations(int dec) {
XChangeProperty (getDisplay(), getCurrentWindow(), motif_hints_atom, motif_hints_atom, 32, PropModeReplace, (unsigned char *)&motif_hints, sizeof(MotifWmHints)/sizeof(long));
}
static bool releaseInput(JNIEnv *env, jint extension, jint window_mode) {
static bool releaseInput(JNIEnv *env, jint extension, jint window_mode, jobject gamma_ramp) {
if (isLegacyFullscreen(window_mode) || input_released)
return false;
input_released = true;
@ -190,19 +190,19 @@ static bool releaseInput(JNIEnv *env, jint extension, jint window_mode) {
updateInputGrab(window_mode);
if (window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM) {
XIconifyWindow(getDisplay(), getCurrentWindow(), getCurrentScreen());
resetDisplayMode(env, getCurrentScreen(), extension, true);
resetDisplayMode(env, getCurrentScreen(), extension, gamma_ramp, true);
}
return true;
}
static void acquireInput(JNIEnv *env, jint extension, jint window_mode) {
static void acquireInput(JNIEnv *env, jint extension, jint window_mode, jobject gamma_ramp) {
if (isLegacyFullscreen(window_mode) || !input_released)
return;
input_released = false;
setRepeatMode(env, AutoRepeatModeOff);
updateInputGrab(window_mode);
if (window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM) {
temporaryRestoreMode(env, getCurrentScreen(), extension);
temporaryRestoreMode(env, getCurrentScreen(), extension, gamma_ramp);
}
}
@ -229,20 +229,20 @@ void setGrab(jint window_mode, bool new_grab) {
}
}
static void checkInput(JNIEnv *env, jint extension, jint window_mode) {
static void checkInput(JNIEnv *env, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma) {
Window win;
int revert_mode;
XGetInputFocus(getDisplay(), &win, &revert_mode);
if (win == current_win) {
acquireInput(env, extension, window_mode);
acquireInput(env, extension, window_mode, current_gamma);
focused = true;
} else {
releaseInput(env, extension, window_mode);
releaseInput(env, extension, window_mode, saved_gamma);
focused = false;
}
}
void handleMessages(JNIEnv *env, jint extension, jint window_mode) {
void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma) {
XEvent event;
/* Window win;
int revert_mode;*/
@ -293,7 +293,7 @@ void handleMessages(JNIEnv *env, jint extension, jint window_mode) {
break;
}
}
checkInput(env, extension, window_mode);
checkInput(env, extension, window_mode, saved_gamma, current_gamma);
}
static void setWindowTitle(const char *title) {
@ -454,9 +454,9 @@ int getWindowHeight(void) {
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUpdate
(JNIEnv *env, jclass clazz, jint extension, jint window_mode)
(JNIEnv *env, jclass clazz, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma)
{
handleMessages(env, extension, window_mode);
handleMessages(env, extension, window_mode, saved_gamma, current_gamma);
}
JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetAvailableDisplayModes(JNIEnv *env, jclass clazz, jint extension) {
@ -467,12 +467,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSwitchDisplayMode(JNI
switchDisplayMode(env, mode, getCurrentScreen(), extension);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nResetDisplayMode(JNIEnv *env, jclass clazz, jint extension) {
resetDisplayMode(env, getCurrentScreen(), extension, false);
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nResetDisplayMode(JNIEnv *env, jclass clazz, jint extension, jobject gamma_ramp) {
resetDisplayMode(env, getCurrentScreen(), extension, gamma_ramp, false);
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetGammaRampLength(JNIEnv *env, jclass clazz) {
return (jint)getGammaRampLength(env, getCurrentScreen());
return (jint)getGammaRampLengthOfDisplay(env, getDisplay(), getCurrentScreen());
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetGammaRamp(JNIEnv *env, jclass clazz, jobject gamma_buffer) {