EZwgl (2.2 Structure of an EZwgl Application)

## 2.2 Structure of an EZwgl Application

An EZwgl program should contain the following components.

- Include the header file `EZ.h`.

- Initialize the library by calling `EZ_Initialize` or `EZ_InitializeXrm`.

- Create and configure widgets by using `EZ_CreateWidget` or `EZ_CreateWidgetXrm`.

- Register widget callbacks and/or event handlers by using `EZ_AddWidgetCallBack` and `EZ_AddEventHandler`.

- Map your widgets by invoking `EZ_DisplayWidget` on your toplevel widgets.

- Processing events by using `EZ_EventMainLoop` or `EZ_ServiceEvents` or `EZ_WaitAndServiceNextEvent`.

### 2.2.1 Hello World

Listed below is a simple "Hello World" program. It demonstrates the steps outlined above for writting an EZwgl application. When run, this program displays a toplevel push button labeled "Hello World". If the widget window is resized, the position of the lable will be adjusted accordingly. If you press the left mouse button (Button1) over the widget window, it exits.

    /************************** Example 1 *********************************/
    #include "EZ.h"                               /* the header file      */

    void cleanExit(EZ_Widget *widget, void *dat)  /* push button callback */
    {
      EZ_Shutdown();/* shutdown EZWGL */
      exit(0);      /* and exit       */
    }

    main(int argc, char **argv)
    {
      EZ_Widget *hello;

      EZ_Initialize(argc,argv,0);       /* initialize EZWGL    */

              /* create a button and set its foreground red    */
      hello = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, NULL,
                              EZ_LABEL_STRING, "Hello World",
                              EZ_FOREGROUND, "red",
                              0);

      EZ_AddWidgetCallBack(hello,       /* register call back  */
            EZ_CALLBACK, cleanExit, NULL, 0);

      EZ_DisplayWidget(hello);          /* show the button     */

      EZ_EventMainLoop();               /* handle mouse inputs */
    }
    /************************** Example 1 *********************************/

### 2.2.2 The EZwgl Header File

The one and only header file `EZ.h` must be included in all source files of an EZwgl application.

    #include "EZ.h"

This files contains type definitions, symbolic constants and forward declarations needed by all applications.

### 2.2.3 Initialization

The first order of business of an EZwgl application is to initialize the EZwgl library. This is achieved by calling

`EZ_Initialize(int argc, char **argv, int initGL);`

or

    EZ_InitializeXrm(char *className,
                     XrmOptionDescRec *optsTable,  int noptions,
                     int *argc_in_out,  char **argv_in_out,
                     char *fallbackResrc,  int initgl);

These two functions parse the command line arguments, opens the X server connection and initialize the internal data structure for EZwgl.

### 2.2.4 Creating and Configuring Widgets

The next two functions are responsible for allocating and initializing widgets.

    EZ_Widget *EZ_CreateWidget(int type, EZ_Widget *parent, ...);

    EZ_Widget *EZ_CreateWidgetXrm(int type, EZ_Widget *parent,
                        char *instanceName, char *ClassName, ...);

These functions create a widget of the given type and initialize widget using the supplied configuration options. They are also responsible for scanning the resource database and configure the widget according to its resources. Configuration options passed to these two functions can be regarded as fallback resources as they will be overriden by application defaults.

### 2.2.5 Registering Callbacks and Event Handlers

Callbacks and event handlers are the only means that an application interacts with EZ widgets. When the user acts on a widget, e.g. pressing a checkButton, the callbacks or the event handlers for the corresponding widget, if any, will be invoked.

Callbacks and event handlers are registered by using

    void EZ_AddWidgetCallBack(EZ_Widget *widget, int which_list,
                    EZ_CallBack callback, void *data,int where);

    void EZ_AddEventHandler(EZ_Widget *widget, EZ_EventHandler hdlr,
                            void *data, int where);

We have already used callbacks in our first example. The procedure `cleanExit` will be executed when the left mouse button is pressed and released over the button.

There are four procedure lists for each widget.

- a list of normal callbacks,

- a list of destroy callbacks,

- a list of motion callbacks, and

- a list of event handlers.

Normal callbacks are invoked when the default action has occured on a widget, e.g., press a push button, a double click on a listbox item or drag a slider button.

Destroy callbacks are invoked at the time a widget is being destroyed. This is useful if your application attaches a complex data structure to a widget, it provides a convenient way to clean up your complex data structure associated with a widget, e.g. free allocated memory.

Motion callbacks are available only for Entry, Slider, Scrollbar, Dial, OptionalEntry, FreeLabel, ListBox, FancyListBox, WorkArea, ListTree, gradient bar, histogram and spread sheet widgets. They are invoked whenever the text changes or the selection of a widget changes or the location of a FreeLabel changes etc.

Event handlers are used to define or alter the behavior of a widget to user events. Private event handlers are called before the default event handler. A private event handler may remove an event it handles by using `EZ_RemoveEvent`, which prevents the event in question from being dispatched to other handlers, including the default handler.

### 2.2.6 Prototypes for Callbacks and Event Handlers

Normal callbacks, motion callbacks and destroy callbacks have the following prototype:

`void callback(EZ_Widget *widget, void *data)`

where `widget` is the widget that `callback` is registered to. `data` is a pointer to a client data that will be passed to `callback` when invoked.

Event handlers have the prototype

     void eventHandler(EZ_Widget *widget, void *data,
                              int eType, XEvent *xevent);

where `widget` is the widget that `eventHandler` is registered to; `data` is a pointer to a client data that will be passed to the event handler; `eType` is the internal EZ event type; and `xevent` is the pointer to the actual X event, it contains all the information about the event. Normally, actions of your event handler should be based on `xevent`. However, if your event handler just wants to check whether a key has been pressed or the the state of a button, you may find that using `eType` is more convenient than deciphering `xevent`.

### 2.2.7 Displaying a Widget

Once a widget has been created, it can be displayed by invoking

`void EZ_DisplayWidget(EZ_Widget *widget);`

The first time this function is called on a widget, it performs two tasks:

- Traverses the whole widget tree, computes and finalizes the geometry of all widgets on the widget tree.

- Creates X windows for all widgets on the widget tree and maps them to the screen.

If it is called on a widget which has been previously displayed. The behavior depends on whether or not `widget` is current viewable. If it is, then this function updates as necessory the geometry of `widget` and updates the display. If `widget` is not currently viewable, the behavior is the following:

- If `widget` is a toplevel widget, then its window is remapped.

- If `widget` is not a toplevel widget, and one ancestor of `widget` is not viewable, then this function does nothing visually.

- If `widget` is not a toplevel widget, and all its ancestors are viewable, then the widget window is remapped.

### 2.2.8 Processing Events

After an application has created and displayed its widgets, it is ready to process events. There are three routines that can be used for event processing.

`void EZ_EventMainLoop(void);`

`void EZ_ServiceEvents(void)`

`void EZ_WaitAndServiceNextEvent(void)`

The first function is the main event loop. It is an infinite loop that waits and processes user inputs. It will call as necessary the callbacks and event handlers registered with EZ widget library. It never returns.

The second function checks the event queue, processes them if there are any, and returns. This function is useful for the "polling" style programming, especially for interactive graphics applications.

The third function checks the event queue, if there are no events on the queue, it waits for the next event to arrive. It processes the first event on the queue and then returns.

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