Linux: Move gamma ramps to java code
This commit is contained in:
parent
c9669d20c9
commit
debaaf6538
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue