NOTE
The X protocol restricts an unmapped window from holding the input focus.
Another way to grab keyboard focus for a window is to grab all the input for that window.
This can be accomplished in various ways, including the use of the FULLSCREEN package
described in Chapter 15, Nonvisual Objects. However, a much more convenient method is to
use the WIN_GRAB_ALL_INPUT attribute. Setting this attribute to TRUE causes a grab that
forces all input to be directed to that window. Setting it to FALSE releases the grab.
This is useful when you want to display a dialog box having panel items and confirmation or
cancel buttons that the user must respond to before interacting with any other portion of the
application. In this case, you should set the grab on the panel. Be sure to reset this attribute
once it is no longer needed. Also, be careful when you code the segment of the program that
uses the grab, or you might generate a grab you cannot get out of.
6.6.1.3 Selection events
Selection events may be delivered to a window’s event procedure if the window owns a
selection or is making selection requests. Generally, these events should be ignored if the
application is using XView’s
SELECTION package. If the application is doing its own selec-
tions by calling Xlib functions directly, then these events will be of interest.
6.7 Interpreting Client Messages
Client messages may be delivered to your event handler for a variety of reasons. For
instance, the event may have been sent by another source using XSendEvent() or
xv_send_message(), which would imply that the sender of the message had loaded
some arbitrary information into client-message format and sent it to you directly. In this
case, the sender assumes you know how to interpret the information in the message.
6.7.1 Sending and Reading Client Messages
xv_send_message() is used to send client messages to other windows. The form for this
function is:
Xv_private int
xv_send_message(window, addressee, msg_type, format, data, len)
Xv_object window;
Xv_opaque addressee;
char *msg_type;
int format;
Xv_opaque *data;
int len;
130 XView Programming Manual
This function sends the message encoded in data to the addressee window. If the
addressee parameter is an X window, then the message is sent to that window. Otherwise,
the addressee may be either PointerWindow or InputFocus to correspond to the
window under which the pointer happens to be lying or the window which happens to have
the current focus. This depends on whether the user has click-to-type or focus-follows-
mouse mode in the window manager.
The window parameter is an XView window/object from which the event is being sent.
This is only used to extract the Display *. The format may be 8, 16, or 32. The value 8
is typically used to represent string values. len is the number of elements in the data. The
size of one element is defined by the value of format.
The actual XEvent that is generated is XClientMessageEvent. When the Notifier
detects the event, before passing it on to your event handler, it checks to see if the message
content represents a drag and drop operation. If so, then the event action is set to the appro-
priate action. The XEvent structure’s ie_xevent field remains unchanged.
If the client message is not a drag and drop operation, then you are responsible for decipher-
ing the message. Clearly, this is something you have to be expecting, or there is no way to
tell what to do with the information. Thus, you can create your own protocol between cli-
ents. You can determine the content of the message using xv_get() and the attributes:
WIN_MESSAGE_DATA
WIN_MESSAGE_TYPE
WIN_MESSAGE_FORMAT
Alternatively, you can obtain this information by accessing the data directly from the
XEvent portion of the Event. These attributes map directly to the XClientMes-
sageEvent data structure in <X11/Xlib.h>. Therefore, you could reference the appropriate
fields in the ie_xevent pointer from the Event structure passed to the callback function.
Using the type, format and data of the client message, you can read the message content. See
Volume One, Xlib Programming Manual, for more information about unwrapping a client
message.
6.8 Reading Input Directly
You can read input immediately using xv_input_readevent(). This function, which
returns the window associated with the event read, takes the form:
Xv_object
xv_input_readevent(window, event, block, type, im)
Xv_object window;
Event *event;
int block, type;
Inputmask *im;
The window parameter identifies the window you want to read the events from. If NULL,
XNextEvent() returns the window that received the next event. In this case, you should
probably have a server grab for the window from which you are reading the event. Other-
wise, you will have to propagate the received event to the appropriate window later.
Handling Input
Handling Input 131
The event parameter is a pointer to an Event type that is filled in when the function
returns. The block parameter indicates whether or not the function should wait if there are
no events pending to be read. If block is FALSE and there are no events, the function
returns immediately without having read an event.
The type parameter tells whether to use the input mask already set in the window or
whether to use the input mask specified by the im parameter. The Inputmask is declared
in <xview/win_input.h>:
typedef struct inputmask {
short im_flags;
char im_keycode[IM_MASKSIZE];
} Inputmask;
The structure consists of an input code array and flags that indicate which user actions belong
in the input queue. To initialize the input mask im call the function bzero():
bzero((char *)&im, sizeof(im));
The following macros are used to manipulate XView event codes in an Inputmask:
win_setinputcodebit(im, code)
win_unsetinputcodebit(im, code)
Here, code is an XView code as described earlier. The flags field may be set to any of the
following bits:
IM_NEGEVENT Send input negative events (release or “up” events), too. This includes all
keyboard keys and mouse buttons.
IM_ASCII Enable ASCII codes 0 through 127—equivalent to WIN_ASCII_EVENTS.
IM_META Enable the META codes 128-255—equivalent to WIN_META_EVENTS.
IM_NEGASCII Enable release or “up” ASCII codes 0 through 127—this is more specific
than IM_NEGEVENT above. It is primarily used to unset the code bits once
ASCII bits have been set.
IM_NEGMETA
Enable release, or “up”
META codes 128 through 255—used to unset these
code bits.
IM_TOP Enable TOP function keys.
IM_NEGTOP Enable release events for TOP function keys.
With these macros, we set the Inputmask that is passed to xv_read_inputevent().
As it turns out, this method can also be used to set the input mask for regular windows. This
is not the recommended method for providing the input mask, but it can be done by specify-
ing the attribute
WIN_INPUT_MASK:
Inputmask im;
win_setinputcodebit(im, WIN_MOUSE_BUTTONS);
win_setinputcodebit(im, WIN_ASCII_EVENTS);
im.im_flags &˜ IN_NEGEVENTS;
xv_set(window, WIN_INPUT_MASK, &im, NULL);
132 XView Programming Manual
Similarly, you can get the input mask in the same way:
Inputmask *im;
im = (Inputmask *)xv_get(window, WIN_INPUT_MASK);
6.9 Sample Program
This section provides a sample program that demonstrates most of what has been discussed in
this chapter. In Example 6-1, the canvas window where the events occur may be split into
several views. Each new view handles its own events and therefore handles its own graphic
rendering into its paint window.
The intent is for the user to split the views several times and move the mouse between the
views. Each view prints the events it receives in its own window at the upper-right corner.
New views created from a split view may not be positioned correctly to see the text describ-
ing the events. It is not possible to scroll individual views programmatically to arbitrary
locations, so the user must do so manually.
Pay careful attention to which window receives events so as to get a feeling for how the key-
board focus is handled. In some cases, the keyboard focus does not follow the mouse—a par-
ticular view may continue to receive keyboard focus even though the mouse is no longer in
that subwindow. Usually, selecting the SELECT mouse button forces the focus to be directed
to that view window.
Example 6-1. The canvas_input.c program
/*
* canvas_input.c --
* Display a canvas whose views may be split repeatedly. The event
* handler is installed for each view, so events are displayed in
* each paint window.
*/
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/scrollbar.h>
#include <xview/xv_xrect.h>
Canvas canvas;
Frame frame;
char msg[128];
void init_split(), my_event_proc(), my_repaint_proc();
main(argc,argv)
int argc;
char *argv[ ];
{
/*
* Initialize, create base frame (with footers) and create canvas.
*/
Handling Input
Handling Input 133
Example 6-1. The canvas_input.c program (continued)
xv_init(XV_INIT_ARGS, argc, argv, NULL);
frame = (Frame)xv_create(NULL,FRAME,
FRAME_LABEL, "Split View Windows.",
FRAME_SHOW_FOOTER, TRUE,
NULL);
canvas = (Canvas)xv_create(frame,CANVAS,
CANVAS_X_PAINT_WINDOW, TRUE,
OPENWIN_SPLIT,
OPENWIN_SPLIT_INIT_PROC, init_split,
NULL,
CANVAS_REPAINT_PROC, my_repaint_proc,
NULL);
(void) xv_create(canvas, SCROLLBAR,
SCROLLBAR_SPLITTABLE, TRUE,
SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
NULL);
(void) xv_create(canvas, SCROLLBAR,
SCROLLBAR_SPLITTABLE, TRUE,
SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
NULL);
/*
* Set input mask
*/
xv_set(canvas_paint_window(canvas),
WIN_CONSUME_EVENTS,
WIN_NO_EVENTS,
WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
NULL,
WIN_EVENT_PROC, my_event_proc,
NULL);
xv_main_loop(frame);
}
/*
* when a viewport is split, this routine is called.
*/
void
init_split(splitview, newview, pos)
Xv_Window splitview, newview;
int pos;
{
Xv_Window view;
int i = 0;
/*
* Determine view # from the new view and set its scrollbar to 0,0
*/
OPENWIN_EACH_VIEW(canvas, view)
if (view == splitview) {
/* identify the view # of the view the user just split. */
sprintf(msg, "Split view #%d", i+1);
xv_set(frame, FRAME_LEFT_FOOTER, msg, NULL);
134 XView Programming Manual
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.