Improved pointer and keyboard handling under windowed mode

This commit is contained in:
Elias Naur 2002-11-20 10:33:37 +00:00
parent cd04bdf33b
commit f188a1400b
3 changed files with 102 additions and 21 deletions

View File

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

View File

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

View File

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