Added preliminary alt-tab support on linux
This commit is contained in:
parent
68045ce08f
commit
e3eeff94b0
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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*");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue