I am replying to my own message because I have figured out how to do
this.
the events I was interested in were only key press events and this is a
description of how I did it.
1. Get the focus window.
2. Query this window to see if there are any children.
3. SelectInput on this window and on its children.
4. XCheckWindowEvents() on ths parent and children windows.
Point 4 is optional as you may want to do something different with the
events you get.
Note: you can't get some events from other windows e.g. ButtonPress and
a few others.
The source code follows if you want the lot goto
http://snet.wit.ie/BlindPenguin
if (!unmapped) /* if the xzoom window is mapped */
{
XGetInputFocus(dpy, with_focas, ret);
}
if (*with_focas != *with_focas2)
{
XSelectInput(dpy, *with_focas, KeyPressMask|KeyReleaseMask);
if (!XGetWindowAttributes(dpy, *with_focas, &focas_attrib))
{
printf("\nCan't get window attributes.\n");
}
if (XGetWindowAttributes(dpy, *with_focas, &focas_attrib))
{
(void) XTranslateCoordinates (dpy, *with_focas, focas_attrib.root,
-focas_attrib.border_width,
-focas_attrib.border_width,
&AbsUperFocasX, &AbsUperFocasY, &junkwin);
/* There is no need to get the attributes of the child as the chile is
contained
within the focas window. */
} /* end if XGetWindowAttributes() */
if (!XQueryTree(dpy, *with_focas, &junkwin, &junkwin, &focas_child,
&nchildren))
{/* No children */}
else
{
while (child_i < nchildren)
{
XSelectInput(dpy, focas_child[child_i], KeyPressMask|KeyReleaseMask);
child_i++;
} /* end while */
} /* end else */
*with_focas2 = *with_focas;
} /* end if (*with_focas != *with_focas2)*/
if (*with_focas != win)
{
if(XCheckWindowEvent(dpy, *with_focas, KeyPressMask|KeyReleaseMask,
&event))
{
switch(event.type)
{
case KeyPress:
break;
case KeyRelease:
/*
This code is based on the assumption that a user will move the pinter
that they wish to type in
and then they will not move it again until they wish to leave. The
statements are designed to
catch the navigation keys. The behaviour is based on standard text
editors and is not as flexible
as it should be. The position of the mouse when it enters the window is
used as a starting point
for the calculations of cursor positions.
To make the tracking a little more comfortable the magnified area only
scrolls
after 3 key strokes.
*/
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0))
{
case XK_Left:
if ( xgrab - 10 > AbsUperFocasX)
{
xgrab -= 10;
dx2 = dx;
}
if (xgrab < 0)
{
xgrab = 0;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_Right:
if ( xgrab + 10 < AbsUperFocasX + focas_attrib.width )
{
xgrab += 10;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_Down:
if ( ygrab + 10 < AbsUperFocasY + focas_attrib.height )
{
ygrab += 10;
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
break;
case XK_Up:
if ( ygrab - 10 > AbsUperFocasY)
{
ygrab -= 10;
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
if (ygrab < 0)
{
ygrab = 0;
dy2 = dy;
}
break;
case XK_Return:
if ( ygrab + 10 < AbsUperFocasY + focas_attrib.height )
{
ygrab += 10;
xgrab = AbsUperFocasX + 10; /* When Return is pressed the usual result
is
to start on a new line. AbsUperFocasX holds
the position of the start of the line and 10
pixals is a reasonable offset to make things
look a bit better.
*/
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_BackSpace:
if ( xgrab - 10 > AbsUperFocasX)
{
xgrab -= 8;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
xgrab += scroll;
break;
case XK_Tab:
if ( xgrab + 20 < AbsUperFocasX + focas_attrib.width)
{
xgrab += 15;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
default:
/* This catches ordinary keystrokes */
if ( xgrab + 10 < AbsUperFocasX + focas_attrib.width)
{
if (key_strokes > 2)
{
xgrab += 8;
key_strokes = 0;
}
key_strokes++;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
} /* end switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0)) */
break;
default:
break;
} /* end switch event.type */
} /* end if XCheckWindowEvent for focus */
for (child_i =0; child_i < (int) nchildren; child_i++)
{
if(XCheckWindowEvent(dpy, focas_child[child_i],
KeyPressMask|KeyReleaseMask, &event))
{
switch(event.type)
{
case KeyPress:
break;
case KeyRelease:
/*
This code is based on the assumption that a user will move the pinter
that they wish to type in
and then they will not move it again until they wish to leave. The
statements are designed to
catch the navigation keys. The behaviour is based on standard text
editors and is not as flexible
as it should be. The position of the mouse when it enters the window is
used as a starting point
for the calculations of cursor positions.
*/
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0))
{
case XK_Left:
if ( xgrab - 10 > AbsUperFocasX)
{
xgrab -= 10;
dx2 = dx;
}
if (xgrab < 0)
{
xgrab = 0;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_Right:
if ( xgrab + 10 < AbsUperFocasX + focas_attrib.width)
{
xgrab += 10;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_Down:
if ( ygrab + 10 < AbsUperFocasY + focas_attrib.height )
{
ygrab += 10;
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
break;
case XK_Up:
if ( ygrab - 10 > AbsUperFocasY)
{
ygrab -= 10;
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
if (ygrab < 0)
{
ygrab = 0;
dy2 = dy;
}
break;
case XK_Return:
if ( ygrab + 10 < AbsUperFocasY + focas_attrib.height)
{
ygrab += 10;
xgrab = AbsUperFocasX + 10; /* When Return is pressed the usual result
is
to start on a new line. AbsUperFocasX holds
the position of the start of the line and 10
pixals is a reasonable offset to make things
look a bit better.
*/
dx2 = dx;
}
if(ygrab > HeightOfScreen(scr)-height[SRC])
{
ygrab = HeightOfScreen(scr)-height[SRC];
dy2 = dy;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
case XK_BackSpace:
if ( xgrab - 10 > AbsUperFocasX)
{
xgrab -= 8;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
xgrab += scroll;
break;
case XK_Tab:
if ( xgrab + 20 < AbsUperFocasX + focas_attrib.width)
{
xgrab += 15;
dx2 = dx;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
default:
/* This catches ordinary keystrokes */
if ( xgrab + 10 < AbsUperFocasX + focas_attrib.width)
{
if (key_strokes > 2)
{
xgrab += 8;
key_strokes = 0;
}
key_strokes++;
}
if(xgrab > WidthOfScreen(scr)-width[SRC])
{
xgrab = WidthOfScreen(scr)-width[SRC];
dx2 = dx;
}
break;
} /* end switch(XKeycodeToKeysym(dpy, event.xkey.keycode, 0)) */
break;
default:
break;
} /* end switch */
} /* end if XCheckWindowEvent for child */
} /* end of for child_i */
} /* end if *with_focas != win */
In article <8bv57p$86...@nnrp1.deja.com>,
kosullivan_xlib <kosulli...@snet.wit.ie> wrote:
> I was on about this befor and I tried the suggestion that I got back
and
> some of it was good but SelectInput() causes errors when it is applied
> to
> the root window. The root window seems to think that you are trying
to
> change its assributes so your program crashes. The following was
> something I came up with and for some reason it doesn't work the
program
> can process its own events but it gets nothing from the root window.
I
> have not tried the function with any other window and I know that the
> root
> window is listening to ButtonPress events.
> root_win = RootWindow(display, root_screen); /* Sets a window
structure
> equal to root window. There is nothing wrong with this statement
> because
> I have used it in a QueryTre() function successfully */
> /* there is a continuous loop here */
> /* after the program has processed its own events it does the
following
> */
> if(!XCheckWindowEvent(display, root_win,
> ButtonPressMask|PointerMotionMask, &report2))
> {/* nothing to do because there are no events */}
> /* XCheckWindowEvent() is used because it checks the event que and
> if it doesn't find anything it returns False and doesn't balck
allowing
> the program to do what it has to do with out waiting for events. */
> else
> {
> printf("\n Something happended ont the root window \n");
> switch (report2.type)
> {
> case ButtonPress:
> printf("\nButton Press on root window \n");
> break;
> case MotionNotify:
> XQueryPointer (display, win, &rep_root, &rep_child,
> &rep_rootx, &rep_rooty, &dx, &dy, &rep_mask);
...
read more »