HP OpenVMS Systems Documentation |
VMS DECwindows Guide to Xlib (Release 4) Programming: MIT C Binding
Chapter 11
|
Example 11-1 Grabbing the Pointer |
---|
#include <decw$include/cursorfont.h> . . . /***** Create the windows *****/ static void doCreateWindows( ) { int window1W = 400; int window1H = 400; int window1X = (XWidthOfScreen(screen)-window1W)>>1; int window1Y = (XHeightOfScreen(screen)-window1H)>>1; int window2W = 200; int window2H = 200; int window2X = 50; int window2Y = 50; XSetWindowAttributes xswa; /* Create the window1 window */ xswa.background_pixel = doDefineColor(1); (1) xswa.event_mask = ButtonPressMask; window1 = XCreateWindow(dpy, XRootWindowOfScreen(screen), window1X, window1Y, window1W, window1H, 0, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); /* Create the window2 window */ xswa.background_pixel = doDefineColor(2); xswa.event_mask = ButtonPressMask; window2 = XCreateWindow(dpy, window1, window2X, window2Y, window2W, window2H, 4, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); } . . . /***** Handle events *****/ static void doHandleEvents( ) { XEvent event; for ( ; ; ) { XNextEvent(dpy, &event); switch (event.type) { case ButtonPress: doButtonPress(&event); break; case ButtonRelease: doButtonRelease(&event); break; } } } /***** Grabbing the Pointer *****/ static void doButtonPress(eventP) XEvent *eventP; { if (eventP -> xbutton.button == Button2) { new_cursor = XCreateFontCursor (dpy, XC_sailboat); (2) XGrabPointer(dpy, window2, 0, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, window2, new_cursor, CurrentTime); } if (eventP ->xbutton.button == Button3) { (3) XUngrabPointer(dpy, CurrentTime); sys$exit (1); } } /***** Write the message *****/ static void doButtonRelease( ) Xevent *eventP; { (4) if (eventP -> xbutton.button == Button1){ XDrawImageString(dpy, window2, gc, 40, 75, message[state] strlen(message[state])); } } |
XGrabPointer(display, window_id, owner_events, event_mask, pointer_mode, keyboard_mode, confine_id, cursor_id, time) |
Because the owner_events argument is set to 0,
pointer events are reported with respect to the grabbing window, and
only if selected by an event mask. Therefore, in the example, the
grabbing client will receive only button press and button release
events. (If owner_events were set to 1, pointer events
would be reported as usual to the client.)
Because the
pointer_mode and keyboard_mode
arguments are set to GrabModeAsync, all pointer and
keyboard events are unaffected by the grab and processing of both event
types continue as usual.
XUngrabPointer(display, time) |
Clients can also modify the parameters of an active pointer grab by calling the CHANGE ACTIVE POINTER GRAB routine as long as the following is true:
Use the GRAB BUTTON routine to passively grab control of a single mouse button.
Example 11-2 illustrates how to grab a single mouse button. The example creates two windows. The button grab occurs when MB2 and the shift are pressed simultaneously.
Because the GRAB BUTTON routine performs a passive grab, the grab terminates whenever the button is released. To deactivate a button grab before the button release, call UNGRAB BUTTON. The UNGRAB BUTTON routine does not affect any active grab.
Example 11-2 Grabbing a Button |
---|
. . . XSetWindowAttributes xswa; /* Create the window1 window */ (1) xswa.event_mask = ButtonPressMask; window1 = XCreateWindow(dpy, XRootWindowOfScreen(screen), window1X, window1Y, window1W, window1H, 0, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); /* Create the window2 window */ xswa.event_mask = ButtonPressMask; window2 = XCreateWindow(dpy, window1, window2X, window2Y, window2W, window2H, 4, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); } . . . /***** Grab Button 2 *****/ static void doGrabButton( ) { (2) XGrabButton(dpy, Button2, ShiftMask, window1, 0, Button2MotionMask, GrabModeAsync, GrabModeAsync, window1, None); } /***** Handle events *****/ static void doHandleEvents( ) { XEvent event; for ( ; ; ) { XNextEvent(dpy, &event); switch (event.type) { case MotionNotify: doMotionNotify(&event); break; case ButtonPress: doButtonPress(&event); break; } } } /***** Motion notify event ******/ static void doMotionNotify(eventP) XEvent *eventP; { (3) int x = eventP->xbutton.x; int y = eventP->xbutton.y; XMoveWindow(dpy, window2, x, y); } /***** Button press event *****/ static void doButtonPress(eventP) XEvent *eventP; { if (eventP ->xbutton.button == Button3) { sys$exit (1); } } |
XGrabButton(display, button, modifiers, window_id, owner_events, event_mask, pointer_mode, keyboard_mode, confine_id, cursor_id) |
The event_mask argument specifies that pointer
motion events that occur while MB2 is down are to be reported to the
grabbing client.
Because the arguments
pointer_mode and keyboard_mode are
set to GrabModeAsync, both pointer and keyboard events
are reported normally. During the grab, the pointer is confined to
window1.
To grab the keyboard, use the GRAB KEYBOARD routine. The GRAB KEYBOARD routine actively grabs the keyboard. Use the UNGRAB KEYBOARD to release the keyboard and any queued events if the client has the keyboard actively grabbed from either GRAB KEY or GRAB KEYBOARD.
To grab a single key, use the GRAB KEY routine. The GRAB KEY routine establishes a passive grab on the keyboard.
Example 11-3 illustrates grabbing a key. The example creates two windows. The grab occurs when the F1 and Ctrl keys are pressed simultaneously.
Example 11-3 Grabbing a Key |
---|
#include <decw$include/keysym.h> . . . /***** Create the windows *****/ static void doCreateWindows( ) { int window1W = 400; int window1H = 400; int window1X = (XWidthOfScreen(screen)-window1W)>>1; int window1Y = (XHeightOfScreen(screen)-window1H)>>1; int window2W = 375; int window2H = 375; XSetWindowAttributes xswa; /* Create the window1 window */ xswa.event_mask = ButtonPressMask; window1 = XCreateWindow(dpy, XRootWindowOfScreen(screen), window1X, window1Y, window1W, window1H, 0, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); /* Create the window2 window */ xswa.event_mask = ButtonPressMask; window2 = XCreateWindow(dpy, window1, window2X, window2Y, window2W, window2H, 4, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); } /***** Map the windows *****/ static void doMapWindows( ) { XMapWindow(dpy, window1); XMapWindow(dpy, window2); } /***** Grab the key ******/ static void doGrabKey( ) { (1) keycode_f1 = XKeysymToKeycode(dpy, XK_F1); (2) XGrabKey(dpy, keycode_f1, ControlMask, window2, 1, GrabModeAsync, GrabModeAsync); } /***** Handle events *****/ static void doHandleEvents( ) { XEvent event; for ( ; ; ) { XNextEvent(dpy, &event); switch (event.type) { case KeyPress: doKeyPress(&event); break; case ButtonPress: doButtonPress(&event); break; } } } /***** Key press event *****/ static void doKeyPress(eventP) XEvent *eventP; { (3) if (eventP ->xkey.keycode == keycode_f1){ XResizeWindow(dpy, window2, resize_w, resize_h); XDrawImageString(dpy, window1, gc, 100, 40, message[state], strlen(message[state])); XDrawImageString(dpy, window1, gc, 100, 60, message[state + 1], strlen(message[state + 1])); } } /***** Button press event *****/ static void doButtonPress(eventP) XEvent *eventP; { if (eventP ->xbutton.button == Button3) { sys$exit (1); } } |
keycode_return = XKeysymToKeycode(display, keysym_id) |
XGrabKey(display, keycode, modifiers, window_id, owner_events, pointer_mode, keyboard_mode) |
To allow events to be processed when the device has been frozen, use the ALLOW EVENTS routine. The ALLOW EVENTS routine is used to release some queued events if the client has caused a device to freeze. A device will freeze when the client performs a pointer or keyboard grab and specifies synchronous reporting of events. It will remain frozen until the client that issued the grab request issues an ALLOW EVENTS request.
The ALLOW EVENTS routine has the following format:
XAllowEvents(display, event_mode, time) |
In the following example, the client has established a grab on the pointer and has specified that all events are processed synchronously. By calling the ALLOW EVENTS routine and specifying the predefined value AsyncPointer for the event_mode argument, pointer event processing continues as usual.
. . . XGrabPointer(dpy, window1, 0, ButtonPressMask, GrabModeSync, GrabModeSync, none, window1, none, CurrentTime) XAllowEvents(dpy, AsyncPointer, CurrentTime) |
For more information about the ALLOW EVENTS routine and a list of the predefined arguments, see the X Window System.
Previous | Next | Contents | Index |