LINUX: Improved input handling

This commit is contained in:
Elias Naur 2004-04-13 12:13:32 +00:00
parent a9506354ee
commit 0011e75a6e
4 changed files with 33 additions and 23 deletions

View File

@ -56,6 +56,8 @@
extern void resetCursor(int x, int y);
extern Atom getWarpAtom(void);
/*
* Various functions to release/acquire keyboard and mouse
*/
@ -67,7 +69,6 @@
extern void updateKeyboardGrab(void);
extern void setGrab(bool);
extern bool shouldGrab(void);
extern bool isGrabbed(void);
/*
* get the current window width

View File

@ -80,7 +80,7 @@ static void ungrabKeyboard(void) {
void updateKeyboardGrab(void) {
if (!created)
return;
if (shouldGrab()) {
if (isFullscreen() || shouldGrab()) {
grabKeyboard();
} else {
ungrabKeyboard();

View File

@ -119,7 +119,7 @@ static bool blankCursor(void) {
static void updateCursor(void) {
Cursor cursor;
if (isGrabbed())
if (shouldGrab())
cursor = blank_cursor;
else
cursor = current_cursor;
@ -152,7 +152,7 @@ static void ungrabPointer(void) {
void updatePointerGrab(void) {
if (!created)
return;
if (shouldGrab()) {
if (isFullscreen() || shouldGrab()) {
grabPointer();
} else {
ungrabPointer();
@ -162,13 +162,15 @@ void updatePointerGrab(void) {
static void doWarpPointer(void ) {
XEvent ignore_warp_guard;
ignore_warp_guard.type = MotionNotify;
ignore_warp_guard.type = ClientMessage;
ignore_warp_guard.xclient.message_type = getWarpAtom();
ignore_warp_guard.xclient.format = 8;
// Tell event loop to start ignoring motion events
ignore_warp_guard.xmotion.state = 1;
ignore_warp_guard.xclient.data.b[0] = 1;
XSendEvent(getDisplay(), getCurrentWindow(), False, 0, &ignore_warp_guard);
XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, getWindowWidth()/2, getWindowHeight()/2);
// Tell event loop to stop ignoring motion events
ignore_warp_guard.xmotion.state = 0;
ignore_warp_guard.xclient.data.b[0] = 0;
XSendEvent(getDisplay(), getCurrentWindow(), False, 0, &ignore_warp_guard);
/* centerCursor();
@ -189,7 +191,7 @@ static void doWarpPointer(void ) {
}
static void warpPointer(void) {
if (!pointer_grabbed || !isGrabbed())
if (!pointer_grabbed || !shouldGrab())
return;
// Reset pointer to middle of screen if outside a certain inner border
if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER ||

View File

@ -76,6 +76,7 @@ static bool grab;
static bool ignore_motion_events;
static Display *display_connection = NULL;
static Atom warp_atom;
static int display_connection_usage = 0;
Display *getDisplay(void) {
@ -89,11 +90,16 @@ Display *incDisplay(JNIEnv *env) {
throwException(env, "Could not open X display");
return NULL;
}
warp_atom = XInternAtom(getDisplay(), "ignore_warp_atom", False);
}
display_connection_usage++;
return display_connection;
}
Atom getWarpAtom(void) {
return warp_atom;
}
void decDisplay(void) {
display_connection_usage--;
if (display_connection_usage == 0)
@ -140,12 +146,8 @@ bool isFullscreen(void) {
return current_fullscreen;
}
bool isGrabbed(void) {
return grab;
}
bool shouldGrab(void) {
return current_fullscreen || (!input_released && grab);
return !input_released && grab;
}
void setGrab(bool new_grab) {
@ -154,16 +156,22 @@ void setGrab(bool new_grab) {
}
static void handleMotion(XMotionEvent *event) {
if (event->send_event == True) {
// We got a warp ignore message
ignore_motion_events = event->state == 1 ? true : false;
} else if (ignore_motion_events) {
if (ignore_motion_events) {
resetCursor(event->x, event->y);
} else {
handlePointerMotion(event);
}
}
static void checkInput(void) {
Window win;
int revert_mode;
XGetInputFocus(getDisplay(), &win, &revert_mode);
if (win == current_win) {
acquireInput();
focused = true;
}
}
static void handleMessages() {
XEvent event;
Window win;
@ -172,7 +180,9 @@ static void handleMessages() {
XNextEvent(getDisplay(), &event);
switch (event.type) {
case ClientMessage:
if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
if (event.xclient.message_type == warp_atom) {
ignore_motion_events = event.xclient.data.b[0] == 1 ? true : false;
} else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
closerequested = true;
break;
case FocusOut:
@ -183,11 +193,7 @@ static void handleMessages() {
}
break;
case FocusIn:
XGetInputFocus(getDisplay(), &win, &revert_mode);
if (win == current_win) {
acquireInput();
focused = true;
}
checkInput();
break;
case MapNotify:
dirty = true;
@ -200,6 +206,7 @@ static void handleMessages() {
dirty = true;
break;
case ButtonPress:
checkInput();
handleButtonPress(&(event.xbutton));
break;
case ButtonRelease: