## 12.2 The 3DCanvas Widget

The EZ graphics library is realized through the 3DCanvas widget. To each 3DCanvas widget, there is an associated data structure called the graphics context which contains the entire state attributes of the graphics library. An application can have as many 3DCanvases as it needs. However, there is only one active 3DCanvas at any given instant. Implicitly, the active 3DCanvas is set to the last created 3DCanvas.

Start with release 1.38, borders for 3DCanvas widget has been removed. Supporting of border causes various unpleasent problems.

To use the graphics library, one must first create some 3DCanvases and display them. The graphics library comes to existence only after an active 3DCanvas has been displayed.

If more than one 3DCanvases are needed. Use `EZ_Set3DCanvas` to set the active 3DCanvas. This function performs a graphics context switch.

Events for 3DCanvas are handled exactly the same as for the other widget in EZwgl. The difference is that 3DCanvas does not have a default event handler while other widgets do.

One should register at least one private event handler for each 3DCanvas an application creates. The private event handler should provide means to handle at least the `EZ_REDRAW` and the `EZ_RESIZE` events.

Event handlers are registered via `EZ_AddEventHander` or by

Here is an example of event handlers.

    void SampleEventHandler(EZ_Widget *canvas, void *vd, int et, XEvent *xev)
    {
      switch(et) {
           case EZ_REDRAW:
           case EZ_RESIZE:
             /* redraw objects in canvas */
             break;
           case EZ_KEY_PRESS:
             /* do something  */
             break;
           default:
             break;
       }
    }

EZwgl provides three additional commands for an application manipulate events for 3DCanvas widgets.

`void EZ_GLResetEvents(EZ_Widget *canvas)`

This function clears the event queue for the `canvas`. If `canvas` is `NULL`, it clears the event queue for the current active 3DCanvas widget.

`void EZ_GLEnterEvent(EZ_Widget *canvas, int eType, int *values)`

This function enters the specified event to `canvas` or the current active 3DCanvas if `canvas` is `NULL`. `eType` is one of

    EZ_REDRAW
    EZ_RESIZE
    EZ_KEY_PRESS
    EZ_BUTTON1_PRESS               EZ_BUTTON1_RELEASE
    EZ_BUTTON2_PRESS               EZ_BUTTON2_RELEASE
    EZ_BUTTON3_PRESS               EZ_BUTTON3_RELEASE
    EZ_ENTER_WINDOW                EZ_LEAVE_WINDOW
    EZ_POINTER_MOTION

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 in the current viewport. (Origin is at the lower-left corner!) 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.

The window coordinate system for a 3DCanvas is different from that of other widgets. For a 3DCanvas, the origin is the lower-left corner of the widget window while for other widgets, the origin is the upper-lefte corner of the widget window.

`int EZ_GLNextEvent(EZ_Widget *canvas, XEvent *xevent)`

This function checks Xlib's event queue for any outstanding events. If the event queue is empty, it waits for the next event to arrive. It then removes the first event on the queue and copy it to `event` if `event` is not `NULL`. If the removed event belongs to `canvas`, it returns the corresponding type. If the event does belong to `canvas`, it dispatches the event to the relevent widget and returns `0`.

The EZ graphics library also provides a user convenience routine to save the contents of a 3DCanvas window.

    void EZ_Save3DCanvas2PPMImage(EZ_Widget *canvas, chae *file_name);
    void EZ_Save3DCanvas2PS(EZ_Widget *canvas, char *fileName);
    void EZ_Save3DCanvas2PSA(EZ_Widget *canvas, int mode, int dpi,
                    float scale, char *fileName);

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