Internally, event handling is based on Xlib's event queuing mechanism. EZwgl does not queue events itself. It just reads events continuousely from Xlib's event queue and processes them when they arrive. In between, it checks and processes timer events and file events.
The following is the event mask used to create widget windows for most of the widgets in EZwgl.
In other words, most EZ widgets accept keyboard, button, pointer motion, enter/leave Window, exposure and window configuration events.KeyPressMask | ButtonReleaseMask | ExposureMask | ButtonPressMask | StructureNotifyMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
X events are handled by event handlers. Each widget
has a default event handler. This event handler
defines the default behavior of a widget in response to user
inputs. If needed, one can register one or more
private event handlers to a widget. The private
event handers are invoked before the default event handler.
A private event handler can disable the default event handler
completely by using EZ_RemoveEvent
after an event
has been handled.
Event handlers are registered by
void EZ_AddEventHandler(EZ_Widget *widget, EZ_EventHandler hdlr, void *data, int where); typedef void (*EZ_EventHandler)(EZ_Widget *widget, void *data, int etype, XEvent *event);
EZwgl keeps a few global variables to remember the mouse-button-state, pointer-position and last pressed-key. These global variables simplifies the complexity of writing simple event handlers. For sophisticated event handlers, unfortunately, one has to decipher XEvents.
int EZ_PointerCoordinates[2]
This variable
holds the coordinate of the pointer relative to
the upper-left corner of the widget window.
int EZ_PressedKey
. This variable holds the keycode
translation of the last pressed key.
int EZ_ButtonState
. This variable holds
current state of all mouse buttons. There are three
macros associated with this variable. They report the
state of a specific button.
EZ_Button1Down()
EZ_Button2Down()
EZ_Button3Down()
int EZ_MouseX, EZ_MouseY
. These
two variable hold the current pointer location
in an widget window. The position is measured
relative to the lower-left corner of the widget
window, offseted by the border width. These two variables
are meant for 3DCanvas widgets, they are the screen coordinates
of the pointer in the current viewport.
The next table lists the symbolic names for some of the X events the event dispatcher passes to private event handlers.
Symbolic name | Corresponding X event |
EZ_BUTTON1_PRESS | ButtonPress, xbutton=Button1 |
EZ_BUTTON2_PRESS | ButtonPress, xbutton=Button2 |
EZ_BUTTON3_PRESS | ButtonPress, xbutton=Button3 |
EZ_BUTTON1_RELEASE | ButtonRelease, xbutton=Button1 |
EZ_BUTTON2_RELEASE | ButtonRelease, xbutton=Button2 |
EZ_BUTTON3_RELEASE | ButtonRelease, xbutton=Button3 |
EZ_REDRAW | Expose (for 3DCanvas only) |
EZ_RESIZE | ConfigureNotify (for 3DCanvas only) |
EZ_KEY_PRESS | KeyPress (see below) |
EZ_ENTER_WINDOW | EnterNotify |
EZ_LEAVE_WINDOW | LeaveNotify |
EZ_POINTER_MOTION | MotionNotify |
For EZ_KEY_PRESS
events, the global variable EZ_PressedKey
holds
the keycode translation of the corresponding keysym. The next table lists
the symbolic names of keycode translations for keysyms corresponding to
function keys and other special keys.
Symbolic Name | Corresponding keysym |
EZ_PAGE_UP_KEY | XK_Prior |
EZ_PAGE_DOWN_KEY | XK_Next |
EZ_HOME_KEY | XK_Home |
EZ_LEFT_KEY | XK_Left or XK_KP_Left |
EZ_RIGHT_KEY | XK_Right or XK_KP_Right |
EZ_UP_KEY | XK_Up or XK_KP_Up |
EZ_DOWN_KEY | XK_Down or XK_KP_Down |
EZ_BEGIN_KEY | XK_Begin |
EZ_END_KEY | XK_End |
EZ_F1_KEY | XK_F1 |
EZ_F2_KEY | XK_F2 |
EZ_F3_KEY | XK_F3 |
EZ_F4_KEY | XK_F4 |
EZ_F5_KEY | XK_F5 |
EZ_F6_KEY | XK_F6 |
EZ_F7_KEY | XK_F7 |
EZ_F8_KEY | XK_F8 |
EZ_F9_KEY | XK_F9 |
EZ_F10_KEY | XK_F10 |
EZ_F11_KEY | XK_F11 |
EZ_F12_KEY | XK_F12 |
Listed below is a simple event handler. All it does is to display the event info.
#include "EZ.h"
static void sampleEHandler(EZ_Widget *widget, void *data, int etype, XEvent *xev)
{
EZ_Widget *label = (EZ_Widget *)data;
char str[256];
switch(etype)
{
case EZ_BUTTON1_PRESS:
sprintf(str, "Button1Press: (x,y)=(%d, %d)",
EZ_PointerCoordinates[0],EZ_PointerCoordinates[1]);
break;
case EZ_BUTTON1_RELEASE:
sprintf(str, "Button1Release: (x,y)=(%d, %d)",
EZ_PointerCoordinates[0],EZ_PointerCoordinates[1]);
break;
case EZ_POINTER_MOTION:
sprintf(str, "PointerMotion: (x,y)=(%d, %d)",
EZ_PointerCoordinates[0],EZ_PointerCoordinates[1]);
break;
case EZ_KEY_PRESS:
sprintf(str,"KeyPress: key=%c, keycode=%d", EZ_PressedKey,EZ_PressedKey);
break;
case EZ_LEAVE_WINDOW:
sprintf(str, "LeaveWindow");
break;
case EZ_ENTER_WINDOW:
sprintf(str, "EnterWindow");
break;
case EZ_REDRAW:
sprintf(str, "Redraw");
break;
default:
str[0]=0;
break;
}
if(str[0]) EZ_ConfigureWidget(label, EZ_LABEL_STRING, str, 0);
}
main(int ac, char **av)
{
EZ_Widget *frame, *label;
EZ_Initialize(ac,av,0);
frame = EZ_CreateWidget(EZ_WIDGET_FRAME, NULL,
EZ_ORIENTATION, EZ_VERTICAL_BOTTOM,
EZ_SIZE, 400, 300,
0);
label = EZ_CreateWidget(EZ_WIDGET_LABEL, frame,
EZ_EXPAND, True,
EZ_PROPAGATE, False,
EZ_BORDER_WIDTH, 2,
EZ_BORDER_TYPE, EZ_BORDER_SUNKEN,
EZ_TEXT_LINE_LENGTH, 80,
EZ_FOREGROUND, "red",
EZ_BACKGROUND, "bisque2",
0);
EZ_AddEventHandler(frame, sampleEventHandler, label, 0);
EZ_DisplayWidget(frame);
EZ_EventMainLoop();
}
/************************************** ExampleEHandler *****************************/
EZwgl provides a command for sending events to widgets.
void EZ_EnterEvent(EZ_Widget *widget, int eType, int *values);
This function enters the specified event. etype
must be one
of
EZ_REDRAW
,
EZ_RESIZE
,
EZ_BUTTON1_PRESS
,
EZ_BUTTON2_PRESS
,
EZ_BUTTON3_PRESS
,
EZ_BUTTON1_RELEASE
,
EZ_BUTTON2_RELEASE
,
EZ_BUTTON3_RELEASE
,
EZ_POINTER_MOTION
,
EZ_ENTER_WINDOW
,
EZ_LEAVE_WINDOW
and
EZ_KEY_PRESS
.
For events of type EZ_BUTTON?_PRESS
,
EZ_BUTTON?_RELEASE
or EZ_POINTER_MOTION
,
values
, if not NULL
is an array of two integers
which specifies the pointer location. For
EZ_KEY_PRESS
event, values
, if not NULL
is a pointer to an integer which specifies the keycode for
the key that is being pressed.
Care must be taken if you send events to
a composite widget. You have to send the event to
the right internal widget in order to have it handled.
This function behave differently for 3DCanvas
widget. See
EZ_GLEnterEvent
.