> > If we had such a generic redirection facility, then we could use it to > > redirect events sent to the Desktop window to the Root window. > > Good idea! When I get back I'll try to make a little program for it.
I did a little test, and for some reason I could not catch any keystrokes from the Desktop window on a Xubuntu system. If I tried listening in on a terminal window, that worked fine. Maybe it needs more than just an XSelectInput() to get input in the general case? -Olaf. -- ___ Olaf 'Rhialto' Seibert -- The Doctor: No, 'eureka' is Greek for \X/ rhialto/at/xs4all.nl -- 'this bath is too hot.'
/*
* Forward key and mouse button events from one window to another.
*
* This is useful to use a Desktop window as a Root window.
*/
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlocale.h>
#include <X11/Xlib.h>
char *ProgramName;
Display *dpy;
int screen;
static void
usage(void)
{
static const char *msg[] = {
" -display displayname X server to contact",
" -id windowid use existing window",
" -root use root window",
" -name string window name",
"",
NULL
};
const char **cpp;
fprintf(stderr, "usage: %s [-options ...]\n", ProgramName);
fprintf(stderr, "where options include:\n");
for(cpp = msg; *cpp; cpp++) {
fprintf(stderr, "%s\n", *cpp);
}
exit(1);
}
int
main(int argc, char **argv)
{
char *displayname = NULL;
int i;
Window w;
XWindowAttributes wattr;
long event_mask;
int done;
Window ws[2]; /* from-window, to-window */
int wi = 0;
char *name;
ProgramName = argv[0];
if(setlocale(LC_ALL, "") == NULL) {
fprintf(stderr, "%s: warning: could not set default locale\n",
ProgramName);
}
w = 0;
for(i = 1; i < argc; i++) {
char *arg = argv[i];
if(arg[0] == '-') {
switch(arg[1]) {
case 'd': /* -display host:dpy
*/
if(++i >= argc) {
usage();
}
displayname = argv[i];
continue;
case 'i': /* -id */
if(++i >= argc || wi > 1) {
usage();
}
sscanf(argv[i], "0x%lx", &w);
if(!w) {
sscanf(argv[i], "%lu", &w);
}
if(!w) {
usage();
}
ws[wi++] = w;
continue;
case 'n': /* -name */
if(++i >= argc || wi > 1) {
usage();
}
name = argv[i];
continue;
case 'r':
switch(arg[2]) {
case 'o': /* -root
*/
if(wi > 1) {
usage();
}
ws[wi++] = -1;
continue;
default:
usage();
}
continue;
default:
usage();
} /* end switch on - */
}
else {
usage();
}
} /* end for over argc */
dpy = XOpenDisplay(displayname);
if(!dpy) {
fprintf(stderr, "%s: unable to open display '%s'\n",
ProgramName, XDisplayName(displayname));
exit(1);
}
screen = DefaultScreen(dpy);
if(ws[0] == -1) {
ws[0] = RootWindow(dpy, screen);
}
if(ws[1] == -1) {
ws[1] = RootWindow(dpy, screen);
}
if(ws[0] == ws[1]) {
fprintf(stderr, "error: from-window and to-window must
differ.\n");
exit(1);
}
event_mask = KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask;
if(ws[0]) {
XGetWindowAttributes(dpy, ws[0], &wattr);
/* We can't select on button presses if someone else already
does... */
if(wattr.all_event_masks & ButtonPressMask) {
event_mask &= ~ButtonPressMask;
fprintf(stderr, "warning: can't forward button
presses.\n");
}
event_mask &= ~SubstructureRedirectMask;
printf("XSelectInput 0x%x %lx\n", ws[0], event_mask);
XSelectInput(dpy, ws[0], event_mask);
}
for(done = 0; !done;) {
XEvent event;
XNextEvent(dpy, &event);
switch(event.type) {
case KeyPress:
case KeyRelease:
printf("KeyPress/KeyRelease\n");
event.xkey.window = ws[1];
XSendEvent(dpy, ws[1], False, KeyPressMask,
&event);
break;
case ButtonPress:
case ButtonRelease:
printf("ButtonPress/ButtonRelease\n");
event.xbutton.window = ws[1];
XSendEvent(dpy, ws[1], False, KeyPressMask,
&event);
break;
default:
printf("some other event\n");
}
}
XCloseDisplay(dpy);
return 0;
}
pgpv25KA1vZNI.pgp
Description: PGP signature
