LINUX: Implemented reference counted display connection to let Cursors be created and destroyed without a window or a mouse
This commit is contained in:
parent
4779a2e29f
commit
cc367fa4b5
|
@ -81,10 +81,23 @@
|
|||
*/
|
||||
extern int getWindowHeight(void);
|
||||
|
||||
/*
|
||||
* Increment display usage (and possible open it).
|
||||
* Return the display handle.
|
||||
* If the function fails, it will return NULL
|
||||
* and throw a java exception through the env argument
|
||||
*/
|
||||
extern Display *incDisplay(JNIEnv *env);
|
||||
|
||||
/*
|
||||
* Decrement display usage and possibly release it
|
||||
*/
|
||||
extern void decDisplay(void);
|
||||
|
||||
/*
|
||||
* get the current display
|
||||
*/
|
||||
extern Display *getCurrentDisplay(void);
|
||||
extern Display *getDisplay(void);
|
||||
|
||||
/*
|
||||
* get the current screen
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <jni.h>
|
||||
#include "org_lwjgl_Display.h"
|
||||
#include "common_tools.h"
|
||||
#include "Window.h"
|
||||
|
||||
static int saved_width;
|
||||
static int saved_height;
|
||||
|
@ -134,11 +135,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_init
|
|||
int num_modes;
|
||||
XF86VidModeModeInfo **avail_modes;
|
||||
int screen;
|
||||
Display *disp = XOpenDisplay(NULL);
|
||||
if (disp == NULL) {
|
||||
printfDebug("Could not open X connection\n");
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
}
|
||||
screen = DefaultScreen(disp);
|
||||
|
||||
if (!getDisplayModes(disp, screen, &num_modes, &avail_modes)) {
|
||||
|
@ -165,7 +164,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_init
|
|||
if (!XF86VidModeGetGammaRamp(disp, screen, gamma_ramp_length, r_ramp, g_ramp, b_ramp))
|
||||
freeSavedGammaRamps();
|
||||
}
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode(JNIEnv * env, jclass clazz, jobject mode) {
|
||||
|
@ -179,57 +178,50 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setDisplayMode(JNIEnv * env, jclas
|
|||
int width = env->GetIntField(mode, fid_width);
|
||||
int height = env->GetIntField(mode, fid_height);
|
||||
int screen;
|
||||
Display *disp = XOpenDisplay(NULL);
|
||||
Display *disp = incDisplay(env);
|
||||
|
||||
if (disp == NULL) {
|
||||
throwException(env, "Could not open X connection.");
|
||||
if (disp == NULL)
|
||||
return;
|
||||
}
|
||||
screen = DefaultScreen(disp);
|
||||
if (setMode(disp, screen, width, height, true)) {
|
||||
jfieldID fid_initialMode = env->GetStaticFieldID(clazz, "mode", "Lorg/lwjgl/DisplayMode;");
|
||||
env->SetStaticObjectField(clazz, fid_initialMode, mode);
|
||||
} else
|
||||
throwException(env, "Could not switch mode.");
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_Display_resetDisplayMode(JNIEnv * env, jclass clazz) {
|
||||
int screen;
|
||||
Display *disp = XOpenDisplay(NULL);
|
||||
|
||||
if (disp == NULL) {
|
||||
printfDebug("Could not open X connection\n");
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
}
|
||||
screen = DefaultScreen(disp);
|
||||
setMode(disp, screen, saved_width, saved_height, false);
|
||||
if (gamma_ramp_length > 0) {
|
||||
XF86VidModeSetGammaRamp(disp, screen, gamma_ramp_length, r_ramp, g_ramp, b_ramp);
|
||||
freeSavedGammaRamps();
|
||||
}
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_nGetAvailableDisplayModes
|
||||
(JNIEnv * env, jclass clazz)
|
||||
{
|
||||
int num_modes, i;
|
||||
Display *disp = XOpenDisplay(NULL);
|
||||
int screen;
|
||||
XF86VidModeModeInfo **avail_modes;
|
||||
Display *disp = incDisplay(env);
|
||||
|
||||
if (disp == NULL) {
|
||||
printfDebug("Could not open X connection\n");
|
||||
if (disp == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen = DefaultScreen(disp);
|
||||
int bpp = XDefaultDepth(disp, screen);
|
||||
|
||||
if (!getDisplayModes(disp, screen, &num_modes, &avail_modes)) {
|
||||
printfDebug("Could not get display modes\n");
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
return NULL;
|
||||
}
|
||||
// Allocate an array of DisplayModes big enough
|
||||
|
@ -242,7 +234,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_nGetAvailableDisplayModes
|
|||
env->SetObjectArrayElement(ret, i, displayMode);
|
||||
}
|
||||
XFree(avail_modes);
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -259,11 +251,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setGammaRamp(JNIEnv *env, jclass c
|
|||
throwException(env, "gamma ramp length == 0.");
|
||||
return;
|
||||
}
|
||||
Display * disp = XOpenDisplay(NULL);
|
||||
if (disp == NULL) {
|
||||
throwException(env, "Could not open X connection.");
|
||||
Display * disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
}
|
||||
int screen = DefaultScreen(disp);
|
||||
const float *gamma_ramp = (const float *)env->GetDirectBufferAddress(gamma_ramp_buffer);
|
||||
unsigned short *ramp;
|
||||
|
@ -275,7 +265,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_setGammaRamp(JNIEnv *env, jclass c
|
|||
if (XF86VidModeSetGammaRamp(disp, screen, gamma_ramp_length, ramp, ramp, ramp) == False) {
|
||||
throwException(env, "Could not set gamma ramp.");
|
||||
}
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_lwjgl_Display_getAdapter
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor
|
||||
(JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset)
|
||||
{
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return 0;
|
||||
XcursorPixel *pixels = (XcursorPixel *)env->GetDirectBufferAddress(image_buffer) + images_offset;
|
||||
int stride = width*height;
|
||||
XcursorImages *cursor_images = XcursorImagesCreate(num_images);
|
||||
|
@ -65,7 +68,7 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor
|
|||
cursor_image->pixels = &(pixels[stride*i]);
|
||||
cursor_images->images[i] = cursor_image;
|
||||
}
|
||||
Cursor cursor = XcursorImagesLoadCursor(getCurrentDisplay(), cursor_images);
|
||||
Cursor cursor = XcursorImagesLoadCursor(disp, cursor_images);
|
||||
XcursorImagesDestroy(cursor_images);
|
||||
return cursor;
|
||||
}
|
||||
|
@ -79,5 +82,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Cursor_nDestroyCursor
|
|||
(JNIEnv *env, jclass clazz, jlong cursor_handle)
|
||||
{
|
||||
Cursor cursor = (Cursor)cursor_handle;
|
||||
XFreeCursor(getCurrentDisplay(), cursor);
|
||||
XFreeCursor(getDisplay(), cursor);
|
||||
decDisplay();
|
||||
}
|
||||
|
|
|
@ -74,17 +74,17 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs(JNIEnv * env, jclas
|
|||
static void setRepeatMode(int mode) {
|
||||
XKeyboardControl repeat_mode;
|
||||
repeat_mode.auto_repeat_mode = mode;
|
||||
XChangeKeyboardControl(getCurrentDisplay(), KBAutoRepeatMode, &repeat_mode);
|
||||
XChangeKeyboardControl(getDisplay(), KBAutoRepeatMode, &repeat_mode);
|
||||
}
|
||||
|
||||
static void grabKeyboard(void) {
|
||||
if (isFullscreen() || !isNativeCursor()) {
|
||||
if (!keyboard_grabbed) {
|
||||
int result = XGrabKeyboard(getCurrentDisplay(), getCurrentWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
int result = XGrabKeyboard(getDisplay(), getCurrentWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
if (result == GrabSuccess) {
|
||||
keyboard_grabbed = true;
|
||||
setRepeatMode(AutoRepeatModeOff);
|
||||
XFlush(getCurrentDisplay());
|
||||
XFlush(getDisplay());
|
||||
}
|
||||
}
|
||||
} else
|
||||
|
@ -94,8 +94,8 @@ static void grabKeyboard(void) {
|
|||
static void ungrabKeyboard(void) {
|
||||
if (keyboard_grabbed) {
|
||||
keyboard_grabbed = false;
|
||||
XUngrabKeyboard(getCurrentDisplay(), CurrentTime);
|
||||
XFlush(getCurrentDisplay());
|
||||
XUngrabKeyboard(getDisplay(), CurrentTime);
|
||||
XFlush(getDisplay());
|
||||
}
|
||||
setRepeatMode(AutoRepeatModeDefault);
|
||||
}
|
||||
|
@ -128,6 +128,9 @@ void releaseKeyboard(void) {
|
|||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
||||
(JNIEnv * env, jclass clazz)
|
||||
{
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
for (int i = 0; i < KEYBOARD_SIZE; i++)
|
||||
key_map[i] = i;
|
||||
key_map[0x6b] = 0xdb; // Left doze key
|
||||
|
@ -169,6 +172,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
|
|||
{
|
||||
ungrabKeyboard();
|
||||
created = false;
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
static unsigned char getKeycode(XKeyEvent *event) {
|
||||
|
|
|
@ -103,19 +103,19 @@ static void centerCursor() {
|
|||
|
||||
static bool blankCursor(void) {
|
||||
unsigned int best_width, best_height;
|
||||
if (XQueryBestCursor(getCurrentDisplay(), getCurrentWindow(), 1, 1, &best_width, &best_height) == 0) {
|
||||
if (XQueryBestCursor(getDisplay(), getCurrentWindow(), 1, 1, &best_width, &best_height) == 0) {
|
||||
printfDebug("Could not query best cursor size\n");
|
||||
return false;
|
||||
}
|
||||
Pixmap mask = XCreatePixmap(getCurrentDisplay(), getCurrentWindow(), best_width, best_height, 1);
|
||||
Pixmap mask = XCreatePixmap(getDisplay(), getCurrentWindow(), best_width, best_height, 1);
|
||||
XGCValues gc_values;
|
||||
gc_values.foreground = 0;
|
||||
GC gc = XCreateGC(getCurrentDisplay(), mask, GCForeground, &gc_values);
|
||||
XFillRectangle(getCurrentDisplay(), mask, gc, 0, 0, best_width, best_height);
|
||||
XFreeGC(getCurrentDisplay(), gc);
|
||||
GC gc = XCreateGC(getDisplay(), mask, GCForeground, &gc_values);
|
||||
XFillRectangle(getDisplay(), mask, gc, 0, 0, best_width, best_height);
|
||||
XFreeGC(getDisplay(), gc);
|
||||
XColor dummy_color;
|
||||
blank_cursor = XCreatePixmapCursor(getCurrentDisplay(), mask, mask, &dummy_color, &dummy_color, 0, 0);
|
||||
XFreePixmap(getCurrentDisplay(), mask);
|
||||
blank_cursor = XCreatePixmapCursor(getDisplay(), mask, mask, &dummy_color, &dummy_color, 0, 0);
|
||||
XFreePixmap(getDisplay(), mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -128,13 +128,13 @@ static void grabPointer(void) {
|
|||
if (!pointer_grabbed) {
|
||||
int result;
|
||||
int grab_mask = PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||
result = XGrabPointer(getCurrentDisplay(), getCurrentWindow(), False, grab_mask, GrabModeAsync,
|
||||
result = XGrabPointer(getDisplay(), getCurrentWindow(), False, grab_mask, GrabModeAsync,
|
||||
GrabModeAsync, getCurrentWindow(), current_cursor, CurrentTime);
|
||||
if (result == GrabSuccess) {
|
||||
pointer_grabbed = true;
|
||||
// make sure we have a centered window
|
||||
XF86VidModeSetViewPort(getCurrentDisplay(), getCurrentScreen(), 0, 0);
|
||||
XFlush(getCurrentDisplay());
|
||||
XF86VidModeSetViewPort(getDisplay(), getCurrentScreen(), 0, 0);
|
||||
XFlush(getDisplay());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,8 +143,8 @@ static void grabPointer(void) {
|
|||
static void ungrabPointer(void) {
|
||||
if (pointer_grabbed) {
|
||||
pointer_grabbed = false;
|
||||
XUngrabPointer(getCurrentDisplay(), CurrentTime);
|
||||
XFlush(getCurrentDisplay());
|
||||
XUngrabPointer(getDisplay(), CurrentTime);
|
||||
XFlush(getDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,11 +171,11 @@ void releasePointer(void) {
|
|||
static void doWarpPointer(void ) {
|
||||
int i;
|
||||
centerCursor();
|
||||
XWarpPointer(getCurrentDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y);
|
||||
XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y);
|
||||
XEvent event;
|
||||
// Try to catch the warp pointer event
|
||||
for (i = 0; i < WARP_RETRY; i++) {
|
||||
XMaskEvent(getCurrentDisplay(), PointerMotionMask, &event);
|
||||
XMaskEvent(getDisplay(), PointerMotionMask, &event);
|
||||
if (event.xmotion.x > current_x - POINTER_WARP_BORDER &&
|
||||
event.xmotion.x < current_x + POINTER_WARP_BORDER &&
|
||||
event.xmotion.y > current_y - POINTER_WARP_BORDER &&
|
||||
|
@ -206,8 +206,8 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetNativeCursorCaps
|
|||
int caps = 0;
|
||||
if (!isXcursorLoaded())
|
||||
return caps;
|
||||
XcursorBool argb_supported = XcursorSupportsARGB(getCurrentDisplay());
|
||||
XcursorBool anim_supported = XcursorSupportsAnim(getCurrentDisplay());
|
||||
XcursorBool argb_supported = XcursorSupportsARGB(getDisplay());
|
||||
XcursorBool anim_supported = XcursorSupportsAnim(getDisplay());
|
||||
if (argb_supported)
|
||||
caps |= org_lwjgl_input_Mouse_CURSOR_8_BIT_ALPHA | org_lwjgl_input_Mouse_CURSOR_ONE_BIT_TRANSPARENCY;
|
||||
if (anim_supported)
|
||||
|
@ -229,13 +229,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor
|
|||
doWarpPointer();
|
||||
native_cursor = true;
|
||||
}
|
||||
XDefineCursor(getCurrentDisplay(), getCurrentWindow(), cursor);
|
||||
XDefineCursor(getDisplay(), getCurrentWindow(), cursor);
|
||||
current_cursor = cursor;
|
||||
updateInput();
|
||||
} else {
|
||||
if (native_cursor) {
|
||||
current_cursor = blank_cursor;
|
||||
XUndefineCursor(getCurrentDisplay(), getCurrentWindow());
|
||||
XUndefineCursor(getDisplay(), getCurrentWindow());
|
||||
native_cursor = false;
|
||||
updateInput();
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize
|
|||
{
|
||||
unsigned int width_return = 0;
|
||||
unsigned int height_return = 0;
|
||||
XQueryBestCursor(getCurrentDisplay(), getCurrentWindow(), 1, 1, &width_return, &height_return);
|
||||
XQueryBestCursor(getDisplay(), getCurrentWindow(), 1, 1, &width_return, &height_return);
|
||||
return width_return > height_return ? width_return : height_return;
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMaxCursorSize
|
|||
{
|
||||
unsigned int width_return = 0;
|
||||
unsigned int height_return = 0;
|
||||
XQueryBestCursor(getCurrentDisplay(), getCurrentWindow(), 0xffffffff, 0xffffffff, &width_return, &height_return);
|
||||
XQueryBestCursor(getDisplay(), getCurrentWindow(), 0xffffffff, 0xffffffff, &width_return, &height_return);
|
||||
return width_return > height_return ? height_return : width_return;
|
||||
}
|
||||
|
||||
|
@ -281,6 +281,9 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetButtonCount(JNIEnv *, jcla
|
|||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate
|
||||
(JNIEnv * env, jclass clazz)
|
||||
{
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
int i;
|
||||
current_z = last_z = 0;
|
||||
for (i = 0; i < NUM_BUTTONS; i++)
|
||||
|
@ -306,9 +309,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy
|
|||
{
|
||||
closeXcursor();
|
||||
ungrabPointer();
|
||||
XFreeCursor(getCurrentDisplay(), blank_cursor);
|
||||
XFreeCursor(getDisplay(), blank_cursor);
|
||||
created = false;
|
||||
should_grab = false;
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
static unsigned char mapButton(XButtonEvent *event) {
|
||||
|
|
|
@ -85,7 +85,9 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate
|
|||
jint samples,
|
||||
jobject pixelFormatCaps, jint pixelFormatCapsSize, jobject pBufferAttribs, jint pBufferAttribsSize)
|
||||
{
|
||||
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return 0;
|
||||
int bpe = convertToBPE(bpp);
|
||||
int attrib_list[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DOUBLEBUFFER, False,
|
||||
|
@ -106,34 +108,34 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate
|
|||
attrib_list[20] = GLX_SAMPLES_ARB;
|
||||
attrib_list[21] = samples;
|
||||
}
|
||||
GLXFBConfig *configs = glXChooseFBConfig(getCurrentDisplay(), getCurrentScreen(), attrib_list, &num_configs);
|
||||
GLXFBConfig *configs = glXChooseFBConfig(disp, getCurrentScreen(), attrib_list, &num_configs);
|
||||
if (num_configs == 0) {
|
||||
XFree(configs);
|
||||
throwException(env, "No matching pixel format");
|
||||
return -1;
|
||||
}
|
||||
int max;
|
||||
glXGetFBConfigAttrib(getCurrentDisplay(), configs[0], GLX_MAX_PBUFFER_WIDTH, &max);
|
||||
glXGetFBConfigAttrib(disp, configs[0], GLX_MAX_PBUFFER_WIDTH, &max);
|
||||
if (max < width) {
|
||||
XFree(configs);
|
||||
throwException(env, "Width too large");
|
||||
return -1;
|
||||
}
|
||||
glXGetFBConfigAttrib(getCurrentDisplay(), configs[0], GLX_MAX_PBUFFER_HEIGHT, &max);
|
||||
glXGetFBConfigAttrib(disp, configs[0], GLX_MAX_PBUFFER_HEIGHT, &max);
|
||||
if (max < height) {
|
||||
XFree(configs);
|
||||
throwException(env, "Height too large");
|
||||
return -1;
|
||||
}
|
||||
GLXContext context = glXCreateNewContext(getCurrentDisplay(), configs[0], GLX_RGBA_TYPE, getCurrentContext(), True);
|
||||
GLXContext context = glXCreateNewContext(disp, configs[0], GLX_RGBA_TYPE, getCurrentContext(), True);
|
||||
if (context == NULL) {
|
||||
XFree(configs);
|
||||
throwException(env, "Could not create a GLX context");
|
||||
return false;
|
||||
}
|
||||
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL");
|
||||
if (!allow_software_acceleration && glXIsDirect(getCurrentDisplay(), context) == False) {
|
||||
glXDestroyContext(getCurrentDisplay(), context);
|
||||
if (!allow_software_acceleration && glXIsDirect(disp, context) == False) {
|
||||
glXDestroyContext(disp, context);
|
||||
XFree(configs);
|
||||
throwException(env, "Could not create a direct GLX context");
|
||||
return false;
|
||||
|
@ -143,7 +145,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate
|
|||
GLX_PRESERVED_CONTENTS, True,
|
||||
GLX_LARGEST_PBUFFER, False};
|
||||
|
||||
GLXPbuffer buffer = glXCreatePbuffer(getCurrentDisplay(), configs[0], buffer_attribs);
|
||||
GLXPbuffer buffer = glXCreatePbuffer(disp, configs[0], buffer_attribs);
|
||||
XFree(configs);
|
||||
PbufferInfo *buffer_info = (PbufferInfo *)malloc(sizeof(PbufferInfo));
|
||||
buffer_info->buffer = buffer;
|
||||
|
@ -162,7 +164,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nMakeCurrent
|
|||
PbufferInfo *buffer_info = (PbufferInfo *)handle;
|
||||
GLXPbuffer buffer = buffer_info->buffer;
|
||||
GLXContext context = buffer_info->context;
|
||||
if (glXMakeContextCurrent(getCurrentDisplay(), buffer, buffer, context) == False) {
|
||||
if (glXMakeContextCurrent(getDisplay(), buffer, buffer, context) == False) {
|
||||
printfDebug("Could not make pbuffer current");
|
||||
}
|
||||
}
|
||||
|
@ -178,9 +180,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nDestroy
|
|||
PbufferInfo *buffer_info = (PbufferInfo *)handle;
|
||||
GLXPbuffer buffer = buffer_info->buffer;
|
||||
GLXContext context = buffer_info->context;
|
||||
glXDestroyPbuffer(getCurrentDisplay(), buffer);
|
||||
glXDestroyContext(getCurrentDisplay(), context);
|
||||
glXDestroyPbuffer(getDisplay(), buffer);
|
||||
glXDestroyContext(getDisplay(), context);
|
||||
free(buffer_info);
|
||||
decDisplay();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nSetAttrib
|
||||
|
|
|
@ -59,7 +59,6 @@ static GLXContext context = NULL; // OpenGL rendering context
|
|||
static GLXWindow glx_window;
|
||||
|
||||
static Atom delete_atom;
|
||||
static Display *current_disp;
|
||||
static Window current_win;
|
||||
static int current_screen;
|
||||
static bool current_fullscreen;
|
||||
|
@ -74,11 +73,36 @@ static bool minimized;
|
|||
static bool focused;
|
||||
static bool closerequested;
|
||||
|
||||
static void waitMapped(Display *disp, Window win) {
|
||||
static Display *display_connection = NULL;
|
||||
static int display_connection_usage = 0;
|
||||
|
||||
Display *getDisplay(void) {
|
||||
return display_connection;
|
||||
}
|
||||
|
||||
Display *incDisplay(JNIEnv *env) {
|
||||
if (display_connection_usage == 0) {
|
||||
display_connection = XOpenDisplay(NULL);
|
||||
if (display_connection == NULL) {
|
||||
throwException(env, "Could not open X display");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
display_connection_usage++;
|
||||
return display_connection;
|
||||
}
|
||||
|
||||
void decDisplay(void) {
|
||||
display_connection_usage--;
|
||||
if (display_connection_usage == 0)
|
||||
XCloseDisplay(display_connection);
|
||||
}
|
||||
|
||||
static void waitMapped(Window win) {
|
||||
XEvent event;
|
||||
|
||||
do {
|
||||
XMaskEvent(disp, StructureNotifyMask, &event);
|
||||
XMaskEvent(getDisplay(), StructureNotifyMask, &event);
|
||||
} while ((event.type != MapNotify) || (event.xmap.event != win));
|
||||
}
|
||||
|
||||
|
@ -118,22 +142,22 @@ static void handleMessages() {
|
|||
XEvent event;
|
||||
Window win;
|
||||
int revert_mode;
|
||||
while (XPending(current_disp) > 0) {
|
||||
XNextEvent(current_disp, &event);
|
||||
while (XPending(getDisplay()) > 0) {
|
||||
XNextEvent(getDisplay(), &event);
|
||||
switch (event.type) {
|
||||
case ClientMessage:
|
||||
if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
|
||||
closerequested = true;
|
||||
break;
|
||||
case FocusOut:
|
||||
XGetInputFocus(current_disp, &win, &revert_mode);
|
||||
XGetInputFocus(getDisplay(), &win, &revert_mode);
|
||||
if (win != current_win) {
|
||||
releaseInput();
|
||||
focused = false;
|
||||
}
|
||||
break;
|
||||
case FocusIn:
|
||||
XGetInputFocus(current_disp, &win, &revert_mode);
|
||||
XGetInputFocus(getDisplay(), &win, &revert_mode);
|
||||
if (win == current_win) {
|
||||
acquireInput();
|
||||
focused = true;
|
||||
|
@ -147,7 +171,6 @@ static void handleMessages() {
|
|||
minimized = true;
|
||||
break;
|
||||
case Expose:
|
||||
// XSetInputFocus(current_disp, current_win, RevertToParent, CurrentTime);
|
||||
dirty = true;
|
||||
break;
|
||||
case ButtonPress:
|
||||
|
@ -168,7 +191,7 @@ static void handleMessages() {
|
|||
}
|
||||
|
||||
static void setWindowTitle(const char *title) {
|
||||
XStoreName(current_disp, current_win, title);
|
||||
XStoreName(getDisplay(), current_win, title);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle
|
||||
|
@ -179,7 +202,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle
|
|||
env->ReleaseStringUTFChars(title_obj, title);
|
||||
}
|
||||
|
||||
static void createWindow(JNIEnv* env, Display *disp, int screen, XVisualInfo *vis_info, jstring title, int x, int y, int width, int height, bool fullscreen, bool undecorated) {
|
||||
static void createWindow(JNIEnv* env, int screen, XVisualInfo *vis_info, jstring title, int x, int y, int width, int height, bool fullscreen, bool undecorated) {
|
||||
dirty = true;
|
||||
focused = true;
|
||||
minimized = false;
|
||||
|
@ -191,15 +214,14 @@ static void createWindow(JNIEnv* env, Display *disp, int screen, XVisualInfo *vi
|
|||
Colormap cmap;
|
||||
int attribmask;
|
||||
|
||||
current_disp = disp;
|
||||
current_screen = screen;
|
||||
input_released = false;
|
||||
current_fullscreen = fullscreen;
|
||||
current_width = width;
|
||||
current_height = height;
|
||||
|
||||
root_win = RootWindow(disp, screen);
|
||||
cmap = XCreateColormap(disp, root_win, vis_info->visual, AllocNone);
|
||||
root_win = RootWindow(getDisplay(), screen);
|
||||
cmap = XCreateColormap(getDisplay(), root_win, vis_info->visual, AllocNone);
|
||||
attribs.colormap = cmap;
|
||||
attribs.event_mask = ExposureMask | FocusChangeMask | VisibilityChangeMask| StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
|
||||
attribs.background_pixel = 0xFF000000;
|
||||
|
@ -208,8 +230,8 @@ static void createWindow(JNIEnv* env, Display *disp, int screen, XVisualInfo *vi
|
|||
attribmask |= CWOverrideRedirect;
|
||||
attribs.override_redirect = True;
|
||||
}
|
||||
win = XCreateWindow(disp, root_win, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs);
|
||||
XFreeColormap(disp, cmap);
|
||||
win = XCreateWindow(getDisplay(), root_win, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs);
|
||||
XFreeColormap(getDisplay(), cmap);
|
||||
printfDebug("Created window\n");
|
||||
current_win = win;
|
||||
Java_org_lwjgl_opengl_Window_nSetTitle(env, NULL, title);
|
||||
|
@ -219,23 +241,18 @@ static void createWindow(JNIEnv* env, Display *disp, int screen, XVisualInfo *vi
|
|||
size_hints->max_width = width;
|
||||
size_hints->min_height = height;
|
||||
size_hints->max_height = height;
|
||||
XSetWMNormalHints(disp, win, size_hints);
|
||||
XSetWMNormalHints(getDisplay(), win, size_hints);
|
||||
XFree(size_hints);
|
||||
delete_atom = XInternAtom(disp, "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(disp, win, &delete_atom, 1);
|
||||
XMapRaised(disp, win);
|
||||
waitMapped(disp, win);
|
||||
XClearWindow(disp, win);
|
||||
XSync(disp, True);
|
||||
delete_atom = XInternAtom(getDisplay(), "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(getDisplay(), win, &delete_atom, 1);
|
||||
XMapRaised(getDisplay(), win);
|
||||
waitMapped(win);
|
||||
XClearWindow(getDisplay(), win);
|
||||
XSync(getDisplay(), True);
|
||||
}
|
||||
|
||||
static void destroyWindow() {
|
||||
XDestroyWindow(current_disp, current_win);
|
||||
current_disp = NULL;
|
||||
}
|
||||
|
||||
Display *getCurrentDisplay(void) {
|
||||
return current_disp;
|
||||
XDestroyWindow(getDisplay(), current_win);
|
||||
}
|
||||
|
||||
int getCurrentScreen(void) {
|
||||
|
@ -278,16 +295,16 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nMakeCurrent
|
|||
|
||||
void makeCurrent(void) {
|
||||
if (USEGLX13)
|
||||
glXMakeContextCurrent(getCurrentDisplay(), glx_window, glx_window, context);
|
||||
glXMakeContextCurrent(getDisplay(), glx_window, glx_window, context);
|
||||
else
|
||||
glXMakeCurrent(getCurrentDisplay(), getCurrentWindow(), context);
|
||||
glXMakeCurrent(getDisplay(), getCurrentWindow(), context);
|
||||
}
|
||||
|
||||
static void releaseContext(void) {
|
||||
if (USEGLX13)
|
||||
glXMakeContextCurrent(getCurrentDisplay(), None, None, NULL);
|
||||
glXMakeContextCurrent(getDisplay(), None, None, NULL);
|
||||
else
|
||||
glXMakeCurrent(getCurrentDisplay(), None, NULL);
|
||||
glXMakeCurrent(getDisplay(), None, NULL);
|
||||
}
|
||||
|
||||
int convertToBPE(int bpp) {
|
||||
|
@ -309,7 +326,7 @@ GLXContext getCurrentContext(void) {
|
|||
return context;
|
||||
}
|
||||
|
||||
static GLXFBConfig *chooseVisualGLX13(Display *disp, int screen, int bpp, int depth, int alpha, int stencil, int samples) {
|
||||
static GLXFBConfig *chooseVisualGLX13(int screen, int bpp, int depth, int alpha, int stencil, int samples) {
|
||||
int bpe = convertToBPE(bpp);
|
||||
int attriblist[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
|
@ -330,7 +347,7 @@ static GLXFBConfig *chooseVisualGLX13(Display *disp, int screen, int bpp, int de
|
|||
attriblist[20] = GLX_SAMPLES_ARB;
|
||||
attriblist[21] = samples;
|
||||
}
|
||||
GLXFBConfig* configs = glXChooseFBConfig(disp, screen, attriblist, &num_formats);
|
||||
GLXFBConfig* configs = glXChooseFBConfig(getDisplay(), screen, attriblist, &num_formats);
|
||||
if (num_formats > 0)
|
||||
return configs;
|
||||
else {
|
||||
|
@ -340,7 +357,7 @@ static GLXFBConfig *chooseVisualGLX13(Display *disp, int screen, int bpp, int de
|
|||
}
|
||||
}
|
||||
|
||||
static XVisualInfo *chooseVisual(Display *disp, int screen, int bpp, int depth, int alpha, int stencil, int samples) {
|
||||
static XVisualInfo *chooseVisual(int screen, int bpp, int depth, int alpha, int stencil, int samples) {
|
||||
int bpe = convertToBPE(bpp);
|
||||
int attriblist[] = {GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
|
@ -359,22 +376,22 @@ static XVisualInfo *chooseVisual(Display *disp, int screen, int bpp, int depth,
|
|||
attriblist[16] = GLX_SAMPLES_ARB;
|
||||
attriblist[17] = samples;
|
||||
}
|
||||
return glXChooseVisual(disp, screen, attriblist);
|
||||
return glXChooseVisual(getDisplay(), screen, attriblist);
|
||||
}
|
||||
|
||||
static void dumpVisualInfo(Display *disp, XVisualInfo *vis_info) {
|
||||
static void dumpVisualInfo(XVisualInfo *vis_info) {
|
||||
int alpha, depth, stencil, r, g, b;
|
||||
int sample_buffers = 0;
|
||||
int samples = 0;
|
||||
glXGetConfig(disp, vis_info, GLX_RED_SIZE, &r);
|
||||
glXGetConfig(disp, vis_info, GLX_GREEN_SIZE, &g);
|
||||
glXGetConfig(disp, vis_info, GLX_BLUE_SIZE, &b);
|
||||
glXGetConfig(disp, vis_info, GLX_ALPHA_SIZE, &alpha);
|
||||
glXGetConfig(disp, vis_info, GLX_DEPTH_SIZE, &depth);
|
||||
glXGetConfig(disp, vis_info, GLX_STENCIL_SIZE, &stencil);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_RED_SIZE, &r);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_GREEN_SIZE, &g);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_BLUE_SIZE, &b);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_ALPHA_SIZE, &alpha);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_DEPTH_SIZE, &depth);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_STENCIL_SIZE, &stencil);
|
||||
if (extgl_Extensions.GLX_ARB_multisample) {
|
||||
glXGetConfig(disp, vis_info, GLX_SAMPLE_BUFFERS_ARB, &sample_buffers);
|
||||
glXGetConfig(disp, vis_info, GLX_SAMPLES_ARB, &samples);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_SAMPLE_BUFFERS_ARB, &sample_buffers);
|
||||
glXGetConfig(getDisplay(), vis_info, GLX_SAMPLES_ARB, &samples);
|
||||
}
|
||||
printf("Pixel format info: r = %d, g = %d, b = %d, a = %d, depth = %d, stencil = %d, sample buffers = %d, samples = %d\n", r, g, b, alpha, depth, stencil, sample_buffers, samples);
|
||||
}
|
||||
|
@ -382,73 +399,72 @@ static void dumpVisualInfo(Display *disp, XVisualInfo *vis_info) {
|
|||
static void destroy(void) {
|
||||
releaseContext();
|
||||
if (USEGLX13)
|
||||
glXDestroyWindow(getCurrentDisplay(), glx_window);
|
||||
glXDestroyContext(getCurrentDisplay(), context);
|
||||
glXDestroyWindow(getDisplay(), glx_window);
|
||||
glXDestroyContext(getDisplay(), context);
|
||||
context = NULL;
|
||||
Display *disp = getCurrentDisplay();
|
||||
destroyWindow();
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
extgl_Close();
|
||||
}
|
||||
|
||||
static bool initWindowGLX13(JNIEnv *env, Display *disp, int screen, jstring title, int x, int y, int width, int height, int bpp, int depth, int alpha, int stencil, int samples, bool fscreen, bool undecorated) {
|
||||
GLXFBConfig *configs = chooseVisualGLX13(disp, screen, bpp, depth, alpha, stencil, samples);
|
||||
static bool initWindowGLX13(JNIEnv *env, int screen, jstring title, int x, int y, int width, int height, int bpp, int depth, int alpha, int stencil, int samples, bool fscreen, bool undecorated) {
|
||||
GLXFBConfig *configs = chooseVisualGLX13(screen, bpp, depth, alpha, stencil, samples);
|
||||
if (configs == NULL) {
|
||||
throwException(env, "Could not find a matching pixel format");
|
||||
return false;
|
||||
}
|
||||
context = glXCreateNewContext(disp, configs[0], GLX_RGBA_TYPE, NULL, True);
|
||||
context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, NULL, True);
|
||||
if (context == NULL) {
|
||||
XFree(configs);
|
||||
throwException(env, "Could not create a GLX context");
|
||||
return false;
|
||||
}
|
||||
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL");
|
||||
if (!allow_software_acceleration && (glXIsDirect(disp, context) == False)) {
|
||||
glXDestroyContext(disp, context);
|
||||
if (!allow_software_acceleration && (glXIsDirect(getDisplay(), context) == False)) {
|
||||
glXDestroyContext(getDisplay(), context);
|
||||
XFree(configs);
|
||||
throwException(env, "Could not create a direct GLX context");
|
||||
return false;
|
||||
}
|
||||
XVisualInfo * vis_info = glXGetVisualFromFBConfig(disp, configs[0]);
|
||||
XVisualInfo * vis_info = glXGetVisualFromFBConfig(getDisplay(), configs[0]);
|
||||
if (vis_info == NULL) {
|
||||
glXDestroyContext(disp, context);
|
||||
glXDestroyContext(getDisplay(), context);
|
||||
XFree(configs);
|
||||
throwException(env, "Could not create visual info from FB config");
|
||||
return false;
|
||||
}
|
||||
createWindow(env, disp, screen, vis_info, title, x, y, width, height, fscreen, undecorated);
|
||||
glx_window = glXCreateWindow(disp, configs[0], getCurrentWindow(), NULL);
|
||||
createWindow(env, screen, vis_info, title, x, y, width, height, fscreen, undecorated);
|
||||
glx_window = glXCreateWindow(getDisplay(), configs[0], getCurrentWindow(), NULL);
|
||||
makeCurrent();
|
||||
if (isDebugEnabled())
|
||||
dumpVisualInfo(disp, vis_info);
|
||||
dumpVisualInfo(vis_info);
|
||||
XFree(configs);
|
||||
XFree(vis_info);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool initWindowGLX(JNIEnv *env, Display *disp, int screen, jstring title, int x, int y, int width, int height, int bpp, int depth, int alpha, int stencil, int samples, bool fscreen, bool undecorated) {
|
||||
XVisualInfo *vis_info = chooseVisual(disp, screen, bpp, depth, alpha, stencil, samples);
|
||||
static bool initWindowGLX(JNIEnv *env, int screen, jstring title, int x, int y, int width, int height, int bpp, int depth, int alpha, int stencil, int samples, bool fscreen, bool undecorated) {
|
||||
XVisualInfo *vis_info = chooseVisual(screen, bpp, depth, alpha, stencil, samples);
|
||||
if (vis_info == NULL) {
|
||||
throwException(env, "Could not find a matching pixel format");
|
||||
return false;
|
||||
}
|
||||
if (isDebugEnabled())
|
||||
dumpVisualInfo(disp, vis_info);
|
||||
context = glXCreateContext(disp, vis_info, NULL, True);
|
||||
dumpVisualInfo(vis_info);
|
||||
context = glXCreateContext(getDisplay(), vis_info, NULL, True);
|
||||
if (context == NULL) {
|
||||
XFree(vis_info);
|
||||
throwException(env, "Could not create a GLX context");
|
||||
return false;
|
||||
}
|
||||
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL");
|
||||
if (!allow_software_acceleration && glXIsDirect(disp, context) == False) {
|
||||
glXDestroyContext(disp, context);
|
||||
if (!allow_software_acceleration && glXIsDirect(getDisplay(), context) == False) {
|
||||
glXDestroyContext(getDisplay(), context);
|
||||
XFree(vis_info);
|
||||
throwException(env, "Could not create a direct GLX context");
|
||||
return false;
|
||||
}
|
||||
createWindow(env, disp, screen, vis_info, title, x, y, width, height, fscreen, undecorated);
|
||||
createWindow(env, screen, vis_info, title, x, y, width, height, fscreen, undecorated);
|
||||
makeCurrent();
|
||||
XFree(vis_info);
|
||||
return true;
|
||||
|
@ -458,7 +474,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate
|
|||
(JNIEnv * env, jclass clazz, jstring title, jint x, jint y, jint width, jint height, jboolean fullscreen, jint bpp, jint alpha, jint depth, jint stencil, jint samples)
|
||||
{
|
||||
int screen;
|
||||
Display *disp;
|
||||
bool fscreen = false;
|
||||
if (fullscreen == JNI_TRUE)
|
||||
fscreen = true;
|
||||
|
@ -468,26 +483,24 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate
|
|||
throwException(env, "Could not load gl libs");
|
||||
return;
|
||||
}
|
||||
disp = XOpenDisplay(NULL);
|
||||
if (disp == NULL) {
|
||||
throwException(env, "Could not open X display");
|
||||
Display *disp = incDisplay(env);
|
||||
if (disp == NULL)
|
||||
return;
|
||||
}
|
||||
screen = XDefaultScreen(disp);
|
||||
if (!extgl_InitGLX(env, disp, screen)) {
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
extgl_Close();
|
||||
throwException(env, "Could not init GLX");
|
||||
return;
|
||||
}
|
||||
bool create_success;
|
||||
if (USEGLX13) {
|
||||
create_success = initWindowGLX13(env, disp, screen, title, x, y, width, height, bpp, depth, alpha, stencil, samples, fscreen, isUndecorated);
|
||||
create_success = initWindowGLX13(env, screen, title, x, y, width, height, bpp, depth, alpha, stencil, samples, fscreen, isUndecorated);
|
||||
} else {
|
||||
create_success = initWindowGLX(env, disp, screen, title, x, y, width, height, bpp, depth, alpha, stencil, samples, fscreen, isUndecorated);
|
||||
create_success = initWindowGLX(env, screen, title, x, y, width, height, bpp, depth, alpha, stencil, samples, fscreen, isUndecorated);
|
||||
}
|
||||
if (!create_success) {
|
||||
XCloseDisplay(disp);
|
||||
decDisplay();
|
||||
extgl_Close();
|
||||
return;
|
||||
}
|
||||
|
@ -513,9 +526,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_swapBuffers(JNIEnv * env, jc
|
|||
{
|
||||
dirty = false;
|
||||
if (USEGLX13)
|
||||
glXSwapBuffers(getCurrentDisplay(), glx_window);
|
||||
glXSwapBuffers(getDisplay(), glx_window);
|
||||
else
|
||||
glXSwapBuffers(getCurrentDisplay(), getCurrentWindow());
|
||||
glXSwapBuffers(getDisplay(), getCurrentWindow());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue