Added preliminary alt-tab support on linux

This commit is contained in:
Elias Naur 2003-02-12 17:12:01 +00:00
parent 68045ce08f
commit e3eeff94b0
3 changed files with 68 additions and 76 deletions

View File

@ -57,8 +57,8 @@ Window win;
static jfieldID fid_close; static jfieldID fid_close;
static bool current_fullscreen; static bool current_fullscreen;
static bool current_focused;
static bool current_minimized; static bool current_minimized;
static bool input_released;
static int win_width; static int win_width;
static int win_height; static int win_height;
static XF86VidModeModeInfo **avail_modes; static XF86VidModeModeInfo **avail_modes;
@ -72,6 +72,10 @@ extern void handlePointerMotion(XMotionEvent *);
extern void handleButtonPress(XButtonEvent *); extern void handleButtonPress(XButtonEvent *);
extern void handleButtonRelease(XButtonEvent *); extern void handleButtonRelease(XButtonEvent *);
extern void handleKeyEvent(XKeyEvent *); extern void handleKeyEvent(XKeyEvent *);
extern void releaseKeyboard(void);
extern void releasePointer(void);
extern void acquireKeyboard(void);
extern void acquirePointer(void);
struct pixelformat { struct pixelformat {
int bpp; int bpp;
@ -199,6 +203,15 @@ void waitMapped(Display *disp, Window win) {
} while ((event.type != MapNotify) || (event.xmap.event != 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) { void handleMessages(void) {
XEvent event; XEvent event;
while (XPending(disp) > 0) { while (XPending(disp) > 0) {
@ -208,11 +221,11 @@ void handleMessages(void) {
if ((event.xclient.format == 32) && (event.xclient.data.l[0] == delete_atom)) if ((event.xclient.format == 32) && (event.xclient.data.l[0] == delete_atom))
saved_env->SetStaticBooleanField(saved_clazz, fid_close, JNI_TRUE); saved_env->SetStaticBooleanField(saved_clazz, fid_close, JNI_TRUE);
break; break;
case EnterNotify: case FocusIn:
current_focused = true; if (input_released) {
break; acquireKeyboard();
case LeaveNotify: acquirePointer();
current_focused = false; }
break; break;
case MapNotify: case MapNotify:
current_minimized = false; current_minimized = false;
@ -272,15 +285,6 @@ int getDisplayModes(Display *disp, int screen, int *num_modes, XF86VidModeModeIn
return 1; return 1;
} }
bool isFullscreen(void) {
return current_fullscreen;
}
bool isFocused() {
handleMessages();
return current_focused;
}
bool isMinimized() { bool isMinimized() {
handleMessages(); handleMessages();
return current_minimized; return current_minimized;
@ -325,7 +329,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
else else
current_fullscreen = false; current_fullscreen = false;
current_minimized = false; current_minimized = false;
current_focused = false; input_released = false;
disp = XOpenDisplay(NULL); disp = XOpenDisplay(NULL);
if (disp == NULL) { if (disp == NULL) {
#ifdef _DEBUG #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); cmap = XCreateColormap(disp, root_win, vis_info->visual, AllocNone);
attribs.colormap = cmap; 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; attribs.background_pixel = 0xFF000000;
attribmask = CWColormap | CWBackPixel | CWEventMask; attribmask = CWColormap | CWBackPixel | CWEventMask;
if (fullscreen) { if (fullscreen) {
@ -407,7 +411,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
} }
XClearWindow(disp, win); XClearWindow(disp, win);
XSync(disp, True); XSync(disp, True);
isFocused();
return JNI_TRUE; return JNI_TRUE;
} }

View File

@ -62,13 +62,12 @@ static int list_end = 0;
static bool keyboard_grabbed; static bool keyboard_grabbed;
static bool buffer_enabled; static bool buffer_enabled;
static bool translation_enabled; static bool translation_enabled;
static bool created = false;
extern Display *disp; extern Display *disp;
extern Window win; extern Window win;
extern bool isFullscreen(void); extern bool releaseInput(void);
extern bool isFocused(void);
extern void handleMessages(void); extern void handleMessages(void);
/* /*
@ -101,20 +100,16 @@ void ungrabKeyboard(void) {
XUngrabKeyboard(disp, CurrentTime); XUngrabKeyboard(disp, CurrentTime);
} }
int updateKeyboardGrab() { void acquireKeyboard(void) {
if (isFullscreen()) { if (!created)
if (!keyboard_grabbed) return;
return grabKeyboard(); grabKeyboard();
} else { }
if (isFocused()) {
if (!keyboard_grabbed) void releaseKeyboard(void) {
return grabKeyboard(); if (!created)
} else { return;
if (keyboard_grabbed) ungrabKeyboard();
ungrabKeyboard();
}
}
return GrabSuccess;
} }
/* /*
@ -129,7 +124,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate
translation_enabled = false; translation_enabled = false;
buffer_enabled = false; buffer_enabled = false;
if (updateKeyboardGrab() != GrabSuccess) { if (grabKeyboard() != GrabSuccess) {
#ifdef _DEBUG #ifdef _DEBUG
printf("Could not grab keyboard\n"); printf("Could not grab keyboard\n");
#endif #endif
@ -157,6 +152,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate
key_map[0x68] = 0xb5; // Numpad divide key_map[0x68] = 0xb5; // Numpad divide
memset(key_buf, 0, KEYBOARD_SIZE*sizeof(unsigned char)); memset(key_buf, 0, KEYBOARD_SIZE*sizeof(unsigned char));
created = true;
return JNI_TRUE; return JNI_TRUE;
} }
@ -170,6 +166,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
{ {
if (keyboard_grabbed) if (keyboard_grabbed)
ungrabKeyboard(); ungrabKeyboard();
created = false;
} }
XKeyEvent *nextEventElement(void) { XKeyEvent *nextEventElement(void) {
@ -238,6 +235,17 @@ void handleKeyEvent(XKeyEvent *event) {
unsigned char keycode = getKeycode(event); unsigned char keycode = getKeycode(event);
unsigned char state = eventState(event); unsigned char state = eventState(event);
key_buf[keycode] = state; 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) if (buffer_enabled)
putEventElement(event); putEventElement(event);
} }
@ -253,7 +261,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll
XEvent event; XEvent event;
unsigned char state; unsigned char state;
updateKeyboardGrab();
handleMessages(); handleMessages();
memcpy((unsigned char*)buf, key_buf, KEYBOARD_SIZE*sizeof(unsigned char)); 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 state;
int num_events = 0; int num_events = 0;
updateKeyboardGrab();
handleMessages(); handleMessages();
while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && (key_event = nextEventElement()) != NULL) { while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && (key_event = nextEventElement()) != NULL) {

View File

@ -55,13 +55,12 @@
extern Display *disp; extern Display *disp;
extern Window win; extern Window win;
extern int screen; extern int screen;
extern bool isFullscreen(void);
extern bool isFocused(void);
extern int getWindowWidth(void); extern int getWindowWidth(void);
extern int getWindowHeight(void); extern int getWindowHeight(void);
extern void handleMessages(void); extern void handleMessages(void);
static bool pointer_grabbed; static bool pointer_grabbed;
static bool created = false;
static jfieldID fid_has_wheel = NULL; static jfieldID fid_has_wheel = NULL;
static jfieldID fid_button_count = NULL; static jfieldID fid_button_count = NULL;
@ -124,13 +123,10 @@ int blankCursor(void) {
int grabPointer(void) { int grabPointer(void) {
int result; int result;
int mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; int mask = FocusChangeMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
if (isFullscreen()) { result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, win, blank_cursor, CurrentTime);
result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, win, blank_cursor, CurrentTime); XWarpPointer(disp, None, win, 0, 0, 0, 0, current_x, current_y);
XWarpPointer(disp, None, win, 0, 0, 0, 0, current_x, current_y); XF86VidModeSetViewPort(disp, screen, 0, 0); // make sure we have a centered window
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);
if (result == GrabSuccess) if (result == GrabSuccess)
pointer_grabbed = true; pointer_grabbed = true;
return result; return result;
@ -141,20 +137,16 @@ void ungrabPointer(void) {
XUngrabPointer(disp, CurrentTime); XUngrabPointer(disp, CurrentTime);
} }
int updatePointerGrab(JNIEnv *env, jclass clazz) { void acquirePointer(void) {
if (isFullscreen()) { if (!created)
if (!pointer_grabbed) return;
return grabPointer(); grabPointer();
} else { }
if (isFocused()) {
if (!pointer_grabbed) void releasePointer(void) {
return grabPointer(); if (!created)
} else { return;
if (pointer_grabbed) ungrabPointer();
ungrabPointer();
}
}
return GrabSuccess;
} }
/* /*
@ -180,12 +172,13 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nCreate
#endif #endif
return JNI_FALSE; return JNI_FALSE;
} }
if (updatePointerGrab(env, clazz) != GrabSuccess) { if (grabPointer() != GrabSuccess) {
#ifdef _DEBUG #ifdef _DEBUG
printf("Could not grab pointer\n"); printf("Could not grab pointer\n");
#endif #endif
return JNI_FALSE; return JNI_FALSE;
} }
created = true;
return JNI_TRUE; return JNI_TRUE;
} }
@ -200,6 +193,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy
if (pointer_grabbed) if (pointer_grabbed)
ungrabPointer(); ungrabPointer();
XFreeCursor(disp, blank_cursor); XFreeCursor(disp, blank_cursor);
created = false;
} }
void handleButtonPress(XButtonEvent *event) { void handleButtonPress(XButtonEvent *event) {
@ -248,6 +242,8 @@ void handlePointerMotion(XMotionEvent *event) {
void warpPointer(void) { void warpPointer(void) {
int i; int i;
if (!pointer_grabbed)
return;
// Reset pointer to middle of screen if inside a certain inner border // Reset pointer to middle of screen if inside a certain inner border
if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER || if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER ||
current_x > getWindowWidth() - POINTER_WARP_BORDER || current_y > getWindowHeight() - 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 JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll
(JNIEnv * env, jclass clazz) (JNIEnv * env, jclass clazz)
{ {
updatePointerGrab(env, clazz);
handleMessages(); handleMessages();
int moved_x = current_x - last_x; int moved_x = current_x - last_x;
int moved_y = current_y - last_y; int moved_y = current_y - last_y;
@ -295,17 +290,5 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll
last_z = current_z; last_z = current_z;
jbooleanArray buttons_array = (jbooleanArray)env->GetStaticObjectField(clazz, fid_buttons); jbooleanArray buttons_array = (jbooleanArray)env->GetStaticObjectField(clazz, fid_buttons);
env->SetBooleanArrayRegion(buttons_array, 0, NUM_BUTTONS, buttons); env->SetBooleanArrayRegion(buttons_array, 0, NUM_BUTTONS, buttons);
if (isFullscreen()) warpPointer();
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*");
} }