From cc367fa4b5c5545586a649a41c275cf98eba3689 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 7 Apr 2004 07:46:03 +0000 Subject: [PATCH] LINUX: Implemented reference counted display connection to let Cursors be created and destroyed without a window or a mouse --- src/native/linux/Window.h | 15 +- src/native/linux/org_lwjgl_Display.cpp | 44 ++--- src/native/linux/org_lwjgl_input_Cursor.cpp | 8 +- src/native/linux/org_lwjgl_input_Keyboard.cpp | 14 +- src/native/linux/org_lwjgl_input_Mouse.cpp | 46 ++--- src/native/linux/org_lwjgl_opengl_Pbuffer.cpp | 25 +-- src/native/linux/org_lwjgl_opengl_Window.cpp | 167 ++++++++++-------- 7 files changed, 175 insertions(+), 144 deletions(-) diff --git a/src/native/linux/Window.h b/src/native/linux/Window.h index a4991edb..d387dfb6 100644 --- a/src/native/linux/Window.h +++ b/src/native/linux/Window.h @@ -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 diff --git a/src/native/linux/org_lwjgl_Display.cpp b/src/native/linux/org_lwjgl_Display.cpp index 7b057f11..b1806e0a 100644 --- a/src/native/linux/org_lwjgl_Display.cpp +++ b/src/native/linux/org_lwjgl_Display.cpp @@ -49,6 +49,7 @@ #include #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 diff --git a/src/native/linux/org_lwjgl_input_Cursor.cpp b/src/native/linux/org_lwjgl_input_Cursor.cpp index 8a897251..adc2f4a6 100644 --- a/src/native/linux/org_lwjgl_input_Cursor.cpp +++ b/src/native/linux/org_lwjgl_input_Cursor.cpp @@ -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(); } diff --git a/src/native/linux/org_lwjgl_input_Keyboard.cpp b/src/native/linux/org_lwjgl_input_Keyboard.cpp index 4b72acaf..b24e4289 100644 --- a/src/native/linux/org_lwjgl_input_Keyboard.cpp +++ b/src/native/linux/org_lwjgl_input_Keyboard.cpp @@ -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) { diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 71474638..32102819 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -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) { diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index d51c1af2..787f8961 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -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 diff --git a/src/native/linux/org_lwjgl_opengl_Window.cpp b/src/native/linux/org_lwjgl_opengl_Window.cpp index 1a471cc9..4ceeb8b2 100644 --- a/src/native/linux/org_lwjgl_opengl_Window.cpp +++ b/src/native/linux/org_lwjgl_opengl_Window.cpp @@ -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()); }