Improved pointer and keyboard handling under windowed mode
This commit is contained in:
parent
cd04bdf33b
commit
f188a1400b
|
@ -55,6 +55,7 @@
|
||||||
Display * disp;
|
Display * disp;
|
||||||
int screen;
|
int screen;
|
||||||
int current_fullscreen;
|
int current_fullscreen;
|
||||||
|
int current_focused;
|
||||||
Window win;
|
Window win;
|
||||||
XF86VidModeModeInfo **avail_modes;
|
XF86VidModeModeInfo **avail_modes;
|
||||||
XVisualInfo * vis_info;
|
XVisualInfo * vis_info;
|
||||||
|
@ -67,18 +68,29 @@ void waitMapped(Display *disp, Window win) {
|
||||||
} while ((event.type != MapNotify) || (event.xmap.event != win));
|
} while ((event.type != MapNotify) || (event.xmap.event != win));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isFocused(void) {
|
||||||
|
XEvent event;
|
||||||
|
while (XCheckMaskEvent(disp, EnterWindowMask | LeaveWindowMask, &event)) {
|
||||||
|
if (event.type == EnterNotify)
|
||||||
|
current_focused = 1;
|
||||||
|
else if (event.type == LeaveNotify)
|
||||||
|
current_focused = 0;
|
||||||
|
}
|
||||||
|
return current_focused;
|
||||||
|
}
|
||||||
|
|
||||||
int getDisplayModes(Display *disp, int screen, int *num_modes, XF86VidModeModeInfo ***avail_modes) {
|
int getDisplayModes(Display *disp, int screen, int *num_modes, XF86VidModeModeInfo ***avail_modes) {
|
||||||
int event_base, error_base, xvid_ver, xvid_rev;
|
int event_base, error_base, xvid_ver, xvid_rev;
|
||||||
|
|
||||||
if (!XF86VidModeQueryExtension(disp, &event_base, &error_base)) {
|
if (!XF86VidModeQueryExtension(disp, &event_base, &error_base)) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("XF86VidMode extention not available\n");
|
printf("XF86VidMode extension not available\n");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
XF86VidModeQueryVersion(disp, &xvid_ver, &xvid_rev);
|
XF86VidModeQueryVersion(disp, &xvid_ver, &xvid_rev);
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("XF86VidMode extention version %i.%i\n", xvid_ver, xvid_rev);
|
printf("XF86VidMode extension version %i.%i\n", xvid_ver, xvid_rev);
|
||||||
#endif
|
#endif
|
||||||
XF86VidModeGetAllModeLines(disp, screen, num_modes, avail_modes);
|
XF86VidModeGetAllModeLines(disp, screen, num_modes, avail_modes);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -94,6 +106,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
||||||
int num_modes, i;
|
int num_modes, i;
|
||||||
|
|
||||||
current_fullscreen = fullscreen;
|
current_fullscreen = fullscreen;
|
||||||
|
current_focused = 0;
|
||||||
disp = XOpenDisplay(NULL);
|
disp = XOpenDisplay(NULL);
|
||||||
if (disp == NULL) {
|
if (disp == NULL) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -122,9 +135,8 @@ 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 = ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
|
attribs.event_mask = StructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
|
||||||
attribs.background_pixel = 0xFF000000;
|
attribs.background_pixel = 0xFF000000;
|
||||||
attribs.event_mask = StructureNotifyMask;
|
|
||||||
attribmask = CWColormap | CWBackPixel | CWEventMask;
|
attribmask = CWColormap | CWBackPixel | CWEventMask;
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
attribmask |= CWOverrideRedirect;
|
attribmask |= CWOverrideRedirect;
|
||||||
|
@ -134,9 +146,9 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Created window\n");
|
printf("Created window\n");
|
||||||
#endif
|
#endif
|
||||||
|
XMapRaised(disp, win);
|
||||||
|
waitMapped(disp, win);
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
XMapRaised(disp, win);
|
|
||||||
waitMapped(disp, win);
|
|
||||||
for ( i = 0; i < num_modes; ++i ) {
|
for ( i = 0; i < num_modes; ++i ) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Mode %d: %dx%d\n", i, avail_modes[i]->hdisplay, avail_modes[i]->vdisplay);
|
printf("Mode %d: %dx%d\n", i, avail_modes[i]->hdisplay, avail_modes[i]->vdisplay);
|
||||||
|
@ -155,13 +167,10 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XF86VidModeSetViewPort(disp, screen, 0, 0);
|
XF86VidModeSetViewPort(disp, screen, 0, 0);
|
||||||
} else {
|
|
||||||
XMapWindow(disp, win);
|
|
||||||
waitMapped(disp, win);
|
|
||||||
}
|
}
|
||||||
XClearWindow(disp, win);
|
XClearWindow(disp, win);
|
||||||
XSync(disp, True);
|
XSync(disp, True);
|
||||||
|
isFocused();
|
||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,13 @@ jfieldID fid_readBuffer;
|
||||||
jfieldID fid_readBufferAddress;
|
jfieldID fid_readBufferAddress;
|
||||||
unsigned char key_buf[KEYBOARD_SIZE];
|
unsigned char key_buf[KEYBOARD_SIZE];
|
||||||
|
|
||||||
|
int keyboard_grabbed;
|
||||||
|
|
||||||
extern Display *disp;
|
extern Display *disp;
|
||||||
extern Window win;
|
extern Window win;
|
||||||
|
extern int current_fullscreen;
|
||||||
|
|
||||||
|
extern int isFocused(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_input_Keyboard
|
* Class: org_lwjgl_input_Keyboard
|
||||||
|
@ -74,6 +79,34 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs
|
||||||
fid_readBufferAddress = env->GetStaticFieldID(clazz, "readBufferAddress", "I");
|
fid_readBufferAddress = env->GetStaticFieldID(clazz, "readBufferAddress", "I");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int grabKeyboard(void) {
|
||||||
|
int result = XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
if (result == GrabSuccess)
|
||||||
|
keyboard_grabbed = 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ungrabKeyboard(void) {
|
||||||
|
keyboard_grabbed = 0;
|
||||||
|
XUngrabKeyboard(disp, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int updateKeyboardGrab(void) {
|
||||||
|
if (current_fullscreen) {
|
||||||
|
if (!keyboard_grabbed)
|
||||||
|
return grabKeyboard();
|
||||||
|
} else {
|
||||||
|
if (isFocused()) {
|
||||||
|
if (!keyboard_grabbed)
|
||||||
|
return grabKeyboard();
|
||||||
|
} else {
|
||||||
|
if (keyboard_grabbed)
|
||||||
|
ungrabKeyboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GrabSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_input_Keyboard
|
* Class: org_lwjgl_input_Keyboard
|
||||||
* Method: nCreate
|
* Method: nCreate
|
||||||
|
@ -82,8 +115,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs
|
||||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
int result = XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
keyboard_grabbed = 0;
|
||||||
if (result != GrabSuccess) {
|
if (updateKeyboardGrab() != GrabSuccess) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Could not grab keyboard\n");
|
printf("Could not grab keyboard\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,13 +134,14 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Keyboard_nCreate
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
XUngrabKeyboard(disp, CurrentTime);
|
ungrabKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
int checkKeyEvents(unsigned char *result_buf) {
|
int checkKeyEvents(unsigned char *result_buf) {
|
||||||
XEvent event;
|
XEvent event;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int buf_count = 0;
|
int buf_count = 0;
|
||||||
|
updateKeyboardGrab();
|
||||||
while (XCheckMaskEvent(disp, KeyPressMask | KeyReleaseMask, &event)) {
|
while (XCheckMaskEvent(disp, KeyPressMask | KeyReleaseMask, &event)) {
|
||||||
unsigned char keycode = (unsigned char)((event.xkey.keycode - 8) & 0xff);
|
unsigned char keycode = (unsigned char)((event.xkey.keycode - 8) & 0xff);
|
||||||
if (result_buf != NULL) {
|
if (result_buf != NULL) {
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
|
|
||||||
extern Display *disp;
|
extern Display *disp;
|
||||||
extern Window win;
|
extern Window win;
|
||||||
|
extern int current_fullscreen;
|
||||||
|
|
||||||
|
int pointer_grabbed;
|
||||||
|
|
||||||
jfieldID fid_button;
|
jfieldID fid_button;
|
||||||
jfieldID fid_dx;
|
jfieldID fid_dx;
|
||||||
|
@ -66,6 +69,8 @@ unsigned char buttons[NUM_BUTTONS];
|
||||||
|
|
||||||
Cursor blank_cursor;
|
Cursor blank_cursor;
|
||||||
|
|
||||||
|
extern int isFocused(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_input_Mouse
|
* Class: org_lwjgl_input_Mouse
|
||||||
* Method: initIDs
|
* Method: initIDs
|
||||||
|
@ -113,10 +118,42 @@ int blankCursor(void) {
|
||||||
XColor dummy_color;
|
XColor dummy_color;
|
||||||
blank_cursor = XCreatePixmapCursor(disp, mask, mask, &dummy_color, &dummy_color, 0, 0);
|
blank_cursor = XCreatePixmapCursor(disp, mask, mask, &dummy_color, &dummy_color, 0, 0);
|
||||||
XFreePixmap(disp, mask);
|
XFreePixmap(disp, mask);
|
||||||
XDefineCursor(disp, win, blank_cursor);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int grabPointer(void) {
|
||||||
|
int result;
|
||||||
|
int mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||||
|
if (current_fullscreen)
|
||||||
|
result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, win, blank_cursor, CurrentTime);
|
||||||
|
else
|
||||||
|
result = XGrabPointer(disp, win, False, mask, GrabModeAsync, GrabModeAsync, None, blank_cursor, CurrentTime);
|
||||||
|
if (result == GrabSuccess)
|
||||||
|
pointer_grabbed = 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ungrabPointer(void) {
|
||||||
|
pointer_grabbed = 0;
|
||||||
|
XUngrabPointer(disp, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int updatePointerGrab(void) {
|
||||||
|
if (current_fullscreen) {
|
||||||
|
if (!pointer_grabbed)
|
||||||
|
return grabPointer();
|
||||||
|
} else {
|
||||||
|
if (isFocused()) {
|
||||||
|
if (!pointer_grabbed)
|
||||||
|
return grabPointer();
|
||||||
|
} else {
|
||||||
|
if (pointer_grabbed)
|
||||||
|
ungrabPointer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GrabSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_input_Mouse
|
* Class: org_lwjgl_input_Mouse
|
||||||
* Method: nCreate
|
* Method: nCreate
|
||||||
|
@ -126,19 +163,19 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nCreate
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
current_x = current_y = current_z = last_x = last_y = last_z = 0;
|
|
||||||
|
current_x = current_y = current_z = last_x = last_y = last_z = pointer_grabbed = 0;
|
||||||
for (i = 0; i < NUM_BUTTONS; i++)
|
for (i = 0; i < NUM_BUTTONS; i++)
|
||||||
buttons[i] = 0;
|
buttons[i] = 0;
|
||||||
if (!blankCursor()) {
|
if (!blankCursor()) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Could not blank cursor\n");
|
printf("Could create blank cursor\n");
|
||||||
#endif
|
#endif
|
||||||
return JNI_FALSE;
|
return JNI_FALSE;
|
||||||
}
|
}
|
||||||
int result = XGrabPointer(disp, win, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
|
if (updatePointerGrab() != GrabSuccess) {
|
||||||
if (result != GrabSuccess) {
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Could not grab mouse\n");
|
printf("Could not grab pointer\n");
|
||||||
#endif
|
#endif
|
||||||
return JNI_FALSE;
|
return JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -172,14 +209,15 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nHasZValue(JNIEnv *env, jc
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
XUndefineCursor(disp, win);
|
if (pointer_grabbed)
|
||||||
|
ungrabPointer();
|
||||||
XFreeCursor(disp, blank_cursor);
|
XFreeCursor(disp, blank_cursor);
|
||||||
XUngrabPointer(disp, CurrentTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int checkPointer() {
|
int checkPointer() {
|
||||||
XEvent event;
|
XEvent event;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
updatePointerGrab();
|
||||||
while (XCheckMaskEvent(disp, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &event)) {
|
while (XCheckMaskEvent(disp, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &event)) {
|
||||||
count++;
|
count++;
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
|
Loading…
Reference in New Issue