LINUX: Implemented reference counted display connection to let Cursors be created and destroyed without a window or a mouse

This commit is contained in:
Elias Naur 2004-04-07 07:46:03 +00:00
parent 4779a2e29f
commit cc367fa4b5
7 changed files with 175 additions and 144 deletions

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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());
}