From e3eeff94b081af76d85449bfcc4f3e264b61dda1 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 12 Feb 2003 17:12:01 +0000 Subject: [PATCH] Added preliminary alt-tab support on linux --- src/native/linux/org_lwjgl_Display.cpp | 39 ++++++------ src/native/linux/org_lwjgl_input_Keyboard.cpp | 46 ++++++++------- src/native/linux/org_lwjgl_input_Mouse.cpp | 59 +++++++------------ 3 files changed, 68 insertions(+), 76 deletions(-) diff --git a/src/native/linux/org_lwjgl_Display.cpp b/src/native/linux/org_lwjgl_Display.cpp index 24fef078..a252100d 100644 --- a/src/native/linux/org_lwjgl_Display.cpp +++ b/src/native/linux/org_lwjgl_Display.cpp @@ -57,8 +57,8 @@ Window win; static jfieldID fid_close; static bool current_fullscreen; -static bool current_focused; static bool current_minimized; +static bool input_released; static int win_width; static int win_height; static XF86VidModeModeInfo **avail_modes; @@ -72,6 +72,10 @@ extern void handlePointerMotion(XMotionEvent *); extern void handleButtonPress(XButtonEvent *); extern void handleButtonRelease(XButtonEvent *); extern void handleKeyEvent(XKeyEvent *); +extern void releaseKeyboard(void); +extern void releasePointer(void); +extern void acquireKeyboard(void); +extern void acquirePointer(void); struct pixelformat { int bpp; @@ -199,6 +203,15 @@ void waitMapped(Display *disp, Window win) { } while ((event.type != MapNotify) || (event.xmap.event != win)); } +bool releaseInput(void) { + if (current_fullscreen) + return false; + releaseKeyboard(); + releasePointer(); + input_released = true; + return true; +} + void handleMessages(void) { XEvent event; while (XPending(disp) > 0) { @@ -208,11 +221,11 @@ void handleMessages(void) { if ((event.xclient.format == 32) && (event.xclient.data.l[0] == delete_atom)) saved_env->SetStaticBooleanField(saved_clazz, fid_close, JNI_TRUE); break; - case EnterNotify: - current_focused = true; - break; - case LeaveNotify: - current_focused = false; + case FocusIn: + if (input_released) { + acquireKeyboard(); + acquirePointer(); + } break; case MapNotify: current_minimized = false; @@ -272,15 +285,6 @@ int getDisplayModes(Display *disp, int screen, int *num_modes, XF86VidModeModeIn return 1; } -bool isFullscreen(void) { - return current_fullscreen; -} - -bool isFocused() { - handleMessages(); - return current_focused; -} - bool isMinimized() { handleMessages(); return current_minimized; @@ -325,7 +329,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c else current_fullscreen = false; current_minimized = false; - current_focused = false; + input_released = false; disp = XOpenDisplay(NULL); if (disp == NULL) { #ifdef _DEBUG @@ -359,7 +363,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c cmap = XCreateColormap(disp, root_win, vis_info->visual, AllocNone); attribs.colormap = cmap; - attribs.event_mask = VisibilityChangeMask| StructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; + attribs.event_mask = FocusChangeMask | VisibilityChangeMask| StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; attribs.background_pixel = 0xFF000000; attribmask = CWColormap | CWBackPixel | CWEventMask; if (fullscreen) { @@ -407,7 +411,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c } XClearWindow(disp, win); XSync(disp, True); - isFocused(); return JNI_TRUE; } diff --git a/src/native/linux/org_lwjgl_input_Keyboard.cpp b/src/native/linux/org_lwjgl_input_Keyboard.cpp index 97d1429f..ce9e06c9 100644 --- a/src/native/linux/org_lwjgl_input_Keyboard.cpp +++ b/src/native/linux/org_lwjgl_input_Keyboard.cpp @@ -62,13 +62,12 @@ static int list_end = 0; static bool keyboard_grabbed; static bool buffer_enabled; static bool translation_enabled; +static bool created = false; extern Display *disp; extern Window win; -extern bool isFullscreen(void); - -extern bool isFocused(void); +extern bool releaseInput(void); extern void handleMessages(void); /* @@ -101,20 +100,16 @@ void ungrabKeyboard(void) { XUngrabKeyboard(disp, CurrentTime); } -int updateKeyboardGrab() { - if (isFullscreen()) { - if (!keyboard_grabbed) - return grabKeyboard(); - } else { - if (isFocused()) { - if (!keyboard_grabbed) - return grabKeyboard(); - } else { - if (keyboard_grabbed) - ungrabKeyboard(); - } - } - return GrabSuccess; +void acquireKeyboard(void) { + if (!created) + return; + grabKeyboard(); +} + +void releaseKeyboard(void) { + if (!created) + return; + ungrabKeyboard(); } /* @@ -129,7 +124,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate translation_enabled = false; buffer_enabled = false; - if (updateKeyboardGrab() != GrabSuccess) { + if (grabKeyboard() != GrabSuccess) { #ifdef _DEBUG printf("Could not grab keyboard\n"); #endif @@ -157,6 +152,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate key_map[0x68] = 0xb5; // Numpad divide memset(key_buf, 0, KEYBOARD_SIZE*sizeof(unsigned char)); + created = true; return JNI_TRUE; } @@ -170,6 +166,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy { if (keyboard_grabbed) ungrabKeyboard(); + created = false; } XKeyEvent *nextEventElement(void) { @@ -238,6 +235,17 @@ void handleKeyEvent(XKeyEvent *event) { unsigned char keycode = getKeycode(event); unsigned char state = eventState(event); key_buf[keycode] = state; + if (key_buf[org_lwjgl_input_Keyboard_KEY_LMENU] == 1 || + key_buf[org_lwjgl_input_Keyboard_KEY_RMENU] == 1) { + if (key_buf[org_lwjgl_input_Keyboard_KEY_TAB] == 1) { + if (releaseInput()) { + key_buf[org_lwjgl_input_Keyboard_KEY_RMENU] = 0; + key_buf[org_lwjgl_input_Keyboard_KEY_LMENU] = 0; + key_buf[org_lwjgl_input_Keyboard_KEY_TAB] = 0; + return; + } + } + } if (buffer_enabled) putEventElement(event); } @@ -253,7 +261,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll XEvent event; unsigned char state; - updateKeyboardGrab(); handleMessages(); memcpy((unsigned char*)buf, key_buf, KEYBOARD_SIZE*sizeof(unsigned char)); @@ -273,7 +280,6 @@ JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead int state; int num_events = 0; - updateKeyboardGrab(); handleMessages(); while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && (key_event = nextEventElement()) != NULL) { diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 94aa5f4d..f9a6d29b 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -55,13 +55,12 @@ extern Display *disp; extern Window win; extern int screen; -extern bool isFullscreen(void); -extern bool isFocused(void); extern int getWindowWidth(void); extern int getWindowHeight(void); extern void handleMessages(void); static bool pointer_grabbed; +static bool created = false; static jfieldID fid_has_wheel = NULL; static jfieldID fid_button_count = NULL; @@ -124,13 +123,10 @@ int blankCursor(void) { int grabPointer(void) { int result; - int mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; - if (isFullscreen()) { - result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, win, blank_cursor, CurrentTime); - XWarpPointer(disp, None, win, 0, 0, 0, 0, current_x, current_y); - XF86VidModeSetViewPort(disp, screen, 0, 0); // make sure we have a centered window - } else - result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, None, blank_cursor, CurrentTime); + int mask = FocusChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; + result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, win, blank_cursor, CurrentTime); + XWarpPointer(disp, None, win, 0, 0, 0, 0, current_x, current_y); + XF86VidModeSetViewPort(disp, screen, 0, 0); // make sure we have a centered window if (result == GrabSuccess) pointer_grabbed = true; return result; @@ -141,20 +137,16 @@ void ungrabPointer(void) { XUngrabPointer(disp, CurrentTime); } -int updatePointerGrab(JNIEnv *env, jclass clazz) { - if (isFullscreen()) { - if (!pointer_grabbed) - return grabPointer(); - } else { - if (isFocused()) { - if (!pointer_grabbed) - return grabPointer(); - } else { - if (pointer_grabbed) - ungrabPointer(); - } - } - return GrabSuccess; +void acquirePointer(void) { + if (!created) + return; + grabPointer(); +} + +void releasePointer(void) { + if (!created) + return; + ungrabPointer(); } /* @@ -180,12 +172,13 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nCreate #endif return JNI_FALSE; } - if (updatePointerGrab(env, clazz) != GrabSuccess) { + if (grabPointer() != GrabSuccess) { #ifdef _DEBUG printf("Could not grab pointer\n"); #endif return JNI_FALSE; } + created = true; return JNI_TRUE; } @@ -200,6 +193,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy if (pointer_grabbed) ungrabPointer(); XFreeCursor(disp, blank_cursor); + created = false; } void handleButtonPress(XButtonEvent *event) { @@ -248,6 +242,8 @@ void handlePointerMotion(XMotionEvent *event) { void warpPointer(void) { int i; + if (!pointer_grabbed) + return; // Reset pointer to middle of screen if inside a certain inner border if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER || current_x > getWindowWidth() - POINTER_WARP_BORDER || current_y > getWindowHeight() - POINTER_WARP_BORDER) { @@ -282,7 +278,6 @@ void warpPointer(void) { JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll (JNIEnv * env, jclass clazz) { - updatePointerGrab(env, clazz); handleMessages(); int moved_x = current_x - last_x; int moved_y = current_y - last_y; @@ -295,17 +290,5 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll last_z = current_z; jbooleanArray buttons_array = (jbooleanArray)env->GetStaticObjectField(clazz, fid_buttons); env->SetBooleanArrayRegion(buttons_array, 0, NUM_BUTTONS, buttons); - if (isFullscreen()) - warpPointer(); -} - - -/* - * Class: org_lwjgl_input_Mouse - * Method: nEnableBuffer - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nEnableBuffer - (JNIEnv * env, jclass clazz) { - printf("*** FIXME: nEnableBuffer not implemented!\n*"); + warpPointer(); }