Created
July 10, 2014 17:16
-
-
Save javiercantero/ae87e91896870062981d to your computer and use it in GitHub Desktop.
Little app to lock the keyboard input of a libOIS linked application (this include games like FreeOrion but also the OISConsole demo packed with the library). You can restore the keyboard input simply by terminate the app killing it or sending a ESC key. This program simulates the functionality of xscreensaver to eaversdrop theKeyPress events of…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <X11/Xlib.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
/* taken from xscreensaver's timers.c */ | |
/* --------------------------------------------------------------------------- | |
* this function tries to eavesdrop all the keyboard activity of any window of | |
* the X server (to determine if a user is active or not and launch the | |
* screensaver if needed). The comment inside is from xscreensaver author. See | |
* xscreensaver sources for more info. -- jcantero | |
-----------------------------------------------------------------------------*/ | |
void notice_events(Display *display, Window window, Window this_app, Bool top_p) | |
{ | |
XWindowAttributes attrs; | |
unsigned long events; | |
Window root, parent, *kids; | |
unsigned int nkids; | |
if ( window == this_app ) | |
return; /* don't touch this app */ | |
if ( !XQueryTree(display, window, &root, &parent, &kids, &nkids) ) | |
return; | |
/*if (window == root) | |
top_p = False;*/ | |
XGetWindowAttributes(display, window, &attrs); | |
events = ((attrs.all_event_masks | attrs.do_not_propagate_mask) | |
& KeyPressMask); | |
/* Select for SubstructureNotify on all windows. | |
Select for KeyPress on all windows that already have it selected. | |
Note that we can't select for ButtonPress, because of X braindamage: | |
only one client at a time may select for ButtonPress on a given | |
window, though any number can select for KeyPress. Someone explain | |
*that* to me. | |
So, if the user spends a while clicking the mouse without ever moving | |
the mouse or touching the keyboard, we won't know that they've been | |
active, and the screensaver will come on. That sucks, but I don't | |
know how to get around it. | |
Since X presents mouse wheels as clicks, this applies to those, too: | |
scrolling through a document using only the mouse wheel doesn't | |
count as activity... Fortunately, /proc/interrupts helps, on | |
systems that have it. Oh, if it's a PS/2 mouse, not serial or USB. | |
This sucks! | |
*/ | |
XSelectInput( display, window, SubstructureNotifyMask | events ); | |
if ( top_p && (events & KeyPressMask) ) | |
{ | |
/* Only mention one window per tree (hack hack). */ | |
printf( "selected KeyPress on 0x%lX\n", (unsigned long) window); | |
/*top_p = False;*/ | |
} | |
if ( kids ) | |
{ | |
while ( nkids ) | |
notice_events(display, kids[--nkids], this_app, top_p); | |
XFree((char *) kids); | |
} | |
} | |
/* --------------------------------------------------------------------------- | |
* this is a pretty stardard example of the most simple X application with | |
* keyboard events, plus a call to the previous function notice_events(). | |
* Note that notice_events() is launched inmediately here, while in | |
* xscreensaver there is a delay due to the timer (see notice_events_timer() | |
* and start_notice_events_timer() in timers.c) -- jcantero | |
-----------------------------------------------------------------------------*/ | |
int main() | |
{ | |
Display *display; | |
Window window; | |
Window root; | |
XEvent event; | |
int s; | |
display = XOpenDisplay(NULL); | |
if (display == NULL) | |
{ | |
fprintf(stderr, "Cannot open display\n"); | |
exit(1); | |
} | |
s = DefaultScreen(display); | |
root = DefaultRootWindow(display); | |
window = XCreateSimpleWindow(display, RootWindow(display, s), 10, 10, 200, 100, 1, | |
BlackPixel(display, s), WhitePixel(display, s)); | |
XSelectInput(display, window, KeyPressMask | KeyReleaseMask ); | |
XMapWindow(display, window); | |
notice_events(display, root, window, True); | |
/* event loop */ | |
while (1) | |
{ | |
if ( XPending(display) > 0 ) | |
{ | |
XNextEvent(display, &event); | |
/* keyboard events */ | |
if (event.type == KeyPress) | |
{ | |
printf( "KeyPress: %x\n", event.xkey.keycode ); | |
/* exit on ESC key press */ | |
if ( event.xkey.keycode == 0x09 ) | |
break; | |
} | |
else if (event.type == KeyRelease) | |
{ | |
printf( "KeyRelease: %x\n", event.xkey.keycode ); | |
} | |
} | |
} | |
XDestroyWindow( display, window ); | |
XCloseDisplay( display ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment