Results 1 to 9 of 9
I want to log it when a key being pressed.Here is the code:
Code:
#include <X11/Xlib.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
int main() {
Display *display = XOpenDisplay(NULL);
assert(display);
...
- 05-22-2008 #1Just Joined!
- Join Date
- May 2008
- Posts
- 5
Can not get the xevent with XNextEvent function?
I want to log it when a key being pressed.Here is the code:
But I can not get any xevent,how to do the things correctly?Code:#include <X11/Xlib.h> #include <assert.h> #include <unistd.h> #include <stdio.h> int main() { Display *display = XOpenDisplay(NULL); assert(display); Screen *screen=XDefaultScreenOfDisplay(display); int width=XWidthOfScreen(screen); int height=XHeightOfScreen(screen); printf("width:%d,height:%d\n", width, height); int f=1; while (f) { if (XPending(display)) { int eq=XEventsQueued(display, QueuedAlready); printf("events num in queue:%d\n", eq); XEvent e; XNextEvent(display, &e); printf("event type:%d\n", e.type); if (e.type == KeyPress) { XKeyEvent y=e.xkey; unsigned int keycode=y.keycode; unsigned int state=y.state; printf("keycode:%d,state:%d\n", keycode, state); break; } } } return 0; }
- 05-22-2008 #2
You can't receive events for any given window without indicating which events you wish to receive for that window. One way to do that is with XSelectInput().
To make sure you get all the events of interest for any given window, be sure to specify which events you wish to receive for it before you map it.
If you really mean the code you've posted to run as it is, it looks like you want to grab all KeyPress events, regardless of the window they're in. In that case, I imagine you can specify the root window in your XSelectInput(), but I've never done this. Since it doesn't make sense to map the root window, I imagine you can simply use XSelectInput() without mapping the root window, and you simply take your chances as to which KeyPress events have been missed before the XSelectInput() takes effect.
Hope this helps.--
Bill
Old age and treachery will overcome youth and skill.
- 05-22-2008 #3Just Joined!
- Join Date
- May 2008
- Posts
- 5
- 05-25-2008 #4Just Joined!
- Join Date
- May 2008
- Posts
- 5
I hava changed my code to this,but when the program is running,whaterver anykey I pressed,there is still nothing in output...
Code:#include <X11/Xlib.h> #include <assert.h> #include <unistd.h> #include <stdio.h> int main() { // Open the display Display *display = XOpenDisplay(NULL); assert(display); Screen *screen=XDefaultScreenOfDisplay(display); int width=XWidthOfScreen(screen); int height=XHeightOfScreen(screen); printf("width:%d,height:%d\n", width, height); Window window=XRootWindowOfScreen(screen); XWindowAttributes attributes; XGetWindowAttributes(display,window,&attributes); printf("map_state:%d,width:%d,height:%d\n",attributes.map_state,attributes.width,attributes.height); XSelectInput(display,window,KeyPress); int f=1; while (f) { if (XPending(display)) { int eq=XEventsQueued(display, QueuedAlready); printf("events num in queue:%d\n", eq); XEvent e; XNextEvent(display, &e); printf("event type:%d\n", e.type); if (e.type == KeyPress) { XKeyEvent y=e.xkey; unsigned int keycode=y.keycode; unsigned int state=y.state; printf("keycode:%d,state:%d\n", keycode, state); break; } } } return 0; }
- 05-25-2008 #5
I had previously said:
Boy, was I ever wrong!I imagine you can specify the root window in your XSelectInput(), but I've never done this.
But first, just for future reference, please know that your XSelectInput() call should look something like this:
not this:Code:XSelectInput(display,window,KeyPressMask); /* good */
Now. The reason that waiting for events on the root window won't do what you want is twofold.Code:XSelectInput(display,window,KeyPress); /* bad */
First, not all events propagate from a given window to all its ancestors. This is controlled by the do_not_propagate_mask member of the window attributes structure.
And I thought, fine, let's test this approach anyway by running the program (as corrected for KeyPressMask) with the cursor sitting on just the root window. It still didn't work. That leads us to the second reason:
Second, your window manager may set the input focus to a particular window, or to no window at all if it wishes. It does this using XSetInputFocus(). If it sets the input focus to no window at all, then no window (not even the root window) will get KeyPress events.
To find out which window has the input focus, you can use XGetInputFocus(). If you wish to be notified when that window no longer has focus, you can enable FocusOut events on that window.
Even so, you won't be able to make this bulletproof. There is no guarantee that you can switch from one window to another before the user slips in a keystroke or two.--
Bill
Old age and treachery will overcome youth and skill.
- 05-26-2008 #6Just Joined!
- Join Date
- May 2008
- Posts
- 5
Thanks very much,where is a focus window indeed,and when I listen on that window,I got the key press event!

Code:Window fw; int state; XGetInputFocus(display,&fw,&state); XGetWindowAttributes(display,fw,&attributes); printf("focus window---->map_state:%d,width:%d,height:%d\n",attributes.map_state,attributes.width,attributes.height); XSelectInput(display,fw,KeyPressMask);
- 05-26-2008 #7
Now you have me curious! What happens when the mouse pointer is not inside any window (except the root window)?
And which window manager are you running?--
Bill
Old age and treachery will overcome youth and skill.
- 05-31-2008 #8Just Joined!
- Join Date
- May 2008
- Posts
- 5
I use gnome,and I use the code below to log the key press event:
It's working,but when I add the mouse button click event through xselectinput:Code:void addListener(Display* display, Window r) { //get children list unsigned int listnum; Window parent; Window root; Window *wa; XQueryTree(display, r, &root, &parent, &wa, &listnum); if (wa==NULL) { return; } int i=0; printf("listnum:%d\n", listnum); for (i=0; i<listnum; i++) { Window w=wa[i]; //printf("alive here?\n"); XWindowAttributes tattributes; XGetWindowAttributes(display, w, &tattributes); printf("map_state:%d,width:%d,height:%d\n", tattributes.map_state, tattributes.width, tattributes.height); if (tattributes.map_state==2) { XSelectInput(display, w, KeyPressMask); } if (tattributes.map_state==2) { XGrabPointer(display,w,False,ButtonPressMask,GrabModeAsync,GrabModeAsync,None,None,CurrentTime); } addListener(display, w); } }
xlib throw a BadAccess exception.Code:XSelectInput(display, w, KeyPressMask|ButtonPressMask);
I found "Only one client at a time can select a ButtonPress event, which is associated with the event mask ButtonPressMask." in Xlib Programming Manual: XSelectInput
so I change my code to:
But I found that the buttonpressevent has been consumed by my code,the applications can not receive the event any more.Code:XGrabPointer(display,w,False,ButtonPressMask,GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
How can I log all the mouse button click event happens in the display and dont affect the applications?
Thanks in advance!
- 05-31-2008 #9The official answer is "You can't."How can I log all the mouse button click event happens in the display and not affect the applications?
If you are really determined to do this, however, I see two options.
- Use strace while running the X server. You will need to become familiar with the X Protocol. (See the O'Reilly book X Protocol Reference Manual.)
- Hack the source for X itself and make your copy non-standard.
In either case, the yellow brick road you choose to follow will be a long, hard yellow brick road. I can see this requiring months of fulltime work to research, design, code, debug, and document. In the process, you will become the world's resident expert on the topic of non-intrusive grabbing of mouse events.
I really, really hope you decide not to do this.--
Bill
Old age and treachery will overcome youth and skill.



