EZwgl (7.1 X Events)

## 7.1 X Events

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.

     KeyPressMask | ButtonReleaseMask | ExposureMask | ButtonPressMask |
     StructureNotifyMask | ButtonMotionMask | EnterWindowMask |
     LeaveWindowMask | PointerMotionMask | KeymapStateMask

In other words, most EZ widgets accept keyboard, button, pointer motion, enter/leave Window, exposure and window configuration events.

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);

### 7.1.1 Write Simple Event Handlers

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.

### Global Variables

- `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.

### Symbolic Event Names

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

### A Simple Event Handler

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 *****************************/

### Enter Events

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`.

HTML Documentation Maintainance:`Arturo Espinosa <arturo@nuclecu.unam.mx>`