The ezxdisp library mainly consists of functions for creating/deleting a window, drawing 2D/3D objects on the window, and handling keyboard/mouse events. This document describes how to use these functions.
All ezxdisp functions are declared in 'ezxdisp.h'. Your program should include the header.
If 'ezxdisp.h' is in './include' directory and 'libezx.a' is in './lib' directory, a typical compile command would look like this:
gcc -I./include foobar.c -o foobar -L./lib -lezx -lX11 -lm
gcc -I./include foobar.c -o foobar -L./lib -lmingw32 -lezx -mwindows
To create a new window, use ezx_init(). This function takes the width, height, and title of the window as its arguments, and returns a pointer to ezx_t structure. This pointer is used in the first argument of the other ezxdisp functions. If ezx_init() fails, NULL is returned.
To destroy the window, use ezx_quit(). This function releases all of the resources (e.g., allocated memory) associated with the window and closes the window.
Example:
#include <stdio.h> #include "ezxdisp.h" int main(int argc, char *argv[]) { ezx_t *e; e = ezx_init(200, 200, "no title"); getchar(); ezx_quit(e); return 0; }
ezxdisp offers a set of functions to draw 2D graphics objects:
These functions take a pointer to ezx_color_t structure as one of its arguments. It is used to specify the color of the 2D object. The definition of the ezx_color_t structure is as follows:
typedef struct {
double r, g, b; // red, green, and blue values of the color, they are in the range of 0.0-1.0
} ezx_color_t;
Also, the predefined constants are available: ezx_black, ezx_white, ezx_grey25, ezx_grey50, ezx_grey75, ezx_blue, ezx_red, ezx_green, ezx_yellow, ezx_purple, ezx_pink, ezx_cyan, ezx_brown, and ezx_orange.
When one of the above function is called, a new 2D object data (type of 2D object and its parameter values) is added to the list of 2D object data managed by the window (without displaying the 2D object). To display all of the 2D objects added to the window, call ezx_redraw().
Example:
#include <stdio.h> #include "ezxdisp.h" int main(int argc, char *argv[]) { ezx_t *e; e = ezx_init(200, 200, "no title"); ezx_line_2d(e, 0, 0, 200, 200, &ezx_red, 1); ezx_circle_2d(e, 50, 100, 20, &ezx_black, 1); ezx_fillrect_2d(e, 120, 40, 170, 160, &ezx_blue); ezx_redraw(e); getchar(); ezx_quit(e); return 0; }
To remove all of the 2D object data added to the window, call ezx_wipe().
Example:
#include <stdio.h>
#include <stdlib.h>
#include "ezxdisp.h"
int main(int argc, char *argv[])
{
ezx_t *e;
int width=200, height=200;
e = ezx_init(width, height, "no title");
for (;;) {
ezx_wipe(e);
ezx_fillcircle_2d(e, rand()%width, rand()%height, 10, &ezx_blue);
ezx_redraw(e);
}
}
Each window has multiple layers, and each layer manages its own list of 2D object data (Fig. 1).
When one of the drawing function (e.g., ezx_line_2d()) called, its 2D object data is added to the list of the 2D object data managed by the current layer. To change the current layer, use ezx_select_layer(), which takes the layer number you want to select. Note that when ezx_init() function returns, the layer 0 is implicitly set as the current layer. There are 8 layers available (this number is defined in ezxdisp.h as EZX_NLAYERS).
We can use ezx_wipe_layer() to remove all of the 2D object data managed by a specific layer.
Example:
#include <stdio.h> #include <stdlib.h> #include "ezxdisp.h" int main(int argc, char *argv[]) { ezx_t *e; int width=200, height=200; e = ezx_init(width, height, "no title"); ezx_line_2d(e, 0, 0, width, height, &ezx_grey50, 1); ezx_line_2d(e, 0, height, width, 0, &ezx_grey50, 1); ezx_select_layer(e, 1); for (;;) { ezx_wipe_layer(e, 1); ezx_fillcircle_2d(e, rand()%width, rand()%height, 10, &ezx_blue); ezx_redraw(e); } }
Each window maintains an event queue which is composed of a series of event data (event type and specific information based on the type) which are generated by events occurred in the window. The supported event types are mouse button press/release event, keyboard press/release event, mouse motion event, and window close event. Note that mouse motion events occur if and only if any mouse button is pressed (i.e., while dragging the mouse).
To catch mouse button press events, use ezx_pushbutton(). This function returns the button code pressed and sets the x-y coordinates of the mouse pointer to the variables passed as arguments. The button code is one of EZX_BUTTON_LEFT, EZX_BUTTON_MIDDLE, EZX_BUTTON_RIGHT, EZX_BUTTON_WHEELUP, or EZX_BUTTON_WHEELDOWN. If there is no event data generated by button press event in the event queue, this function blocks until the next button press event occurs.
Example:
#include <stdio.h>
#include "ezxdisp.h"
int main(int argc, char *argv[])
{
ezx_t *e;
int b, x, y;
e = ezx_init(200, 200, "no title");
for (;;) {
b = ezx_pushbutton(e, &x, &y);
if (b == EZX_BUTTON_LEFT) break;
}
printf("The left button was pressed at the location (%d,%d).\n", x, y);
ezx_quit(e);
return 0;
}
More general event handling can be achieved by using ezx_next_event(). This function removes the next event data from the event queue and stores it to the variable of ezx_event_t union which is passed as one of its arguments. If there is no event data in the event queue, this function blocks until the next event occurs. The event type is identified by the type field of ezx_event_t union. To access the event specific information, the following fields are available depending on the event type.
The mouse button code takes the same values as the return value of ezx_pushbutton() (described above). The key code is an ascii code or one of EZX_KEY_HOME, EZX_KEY_LEFT, EZX_KEY_UP, EZX_KEY_RIGHT, or EZX_KEY_DOWN. The button.state, key.state, and motion.state fields indicate the state (pressed or not) of the shift and control keys and the mouse buttons when the event occurred, which are the bitwise inclusive OR of one or more of the key or button masks: EZX_SHIFT_MASK, EZX_CONTROL_MASK, EZX_BUTTON_LMASK, EZX_BUTTON_MMASK, and EZX_BUTTON_RMASK.
Example:
#include <stdio.h>
#include "ezxdisp.h"
int main(int argc, char *argv[])
{
ezx_t *e;
ezx_event_t event;
e = ezx_init(200, 200, "no title");
for (;;) {
ezx_next_event(e, &event);
switch (event.type) {
case EZX_BUTTON_PRESS:
case EZX_BUTTON_RELEASE:
printf("button event (b=%d)\n", event.button.b);
break;
case EZX_KEY_PRESS:
case EZX_KEY_RELEASE:
printf("key event (k=%d)\n", event.key.k);
break;
case EZX_MOTION_NOTIFY:
printf("mouse motion event (x=%d, y=%d)\n", event.motion.x, event.motion.y);
break;
case EZX_CLOSE:
ezx_quit(e);
return 0;
}
}
}
Sorry, not documented yet...
#define EZX_NLAYER 8
typedef struct ezx_s ezx_t;
ezx_t is an opaque data type.
typedef struct {
double r, g, b; // red, green, and blue values of the color, they are in the range of 0.0-1.0
} ezx_color_t;
The following predefined colors are available: ezx_black, ezx_white, ezx_grey25, ezx_grey50, ezx_grey75, ezx_blue, ezx_red, ezx_green, ezx_yellow, ezx_purple, ezx_pink, ezx_cyan, ezx_brown, and ezx_orange.
typedef union { enum ezx_event_type { EZX_BUTTON_PRESS, EZX_BUTTON_RELEASE, EZX_KEY_PRESS, EZX_KEY_RELEASE, EZX_MOTION_NOTIFY, EZX_CLOSE } type; struct ezx_button_event { enum ezx_event_type type; /* EZX_BUTTON_PRESS or EZX_BUTTON_RELEASE */ unsigned int b; int x, y; unsigned int state; } button; struct ezx_key_event { enum ezx_event_type type; /* EZX_KEY_PRESS or EZX_KEY_RELEASE */ unsigned int k; int x, y; unsigned int state; } key; struct ezx_motion_event { enum ezx_event_type type; /* EZX_MOTION_NOTIFY */ int x, y; unsigned int state; } motion; } ezx_event_t;
ezx_t *ezx_init(int size_x, int size_y, char *window_name);
void ezx_quit(ezx_t *e);
void ezx_set_background(ezx_t *e, const ezx_color_t *col);
void ezx_redraw(ezx_t *e);
void ezx_wipe(ezx_t *e);
void ezx_select_layer(ezx_t *e, int lay);
void ezx_wipe_layer(ezx_t *e, int lay);
void ezx_window_name(ezx_t *e, char *window_name);
int ezx_isclosed(ezx_t *e);
int ezx_sensebutton(ezx_t *e, int *x, int *y);
int ezx_pushbutton(ezx_t *e, int *x, int *y);
void ezx_next_event(ezx_t *ezx, ezx_event_t *event);
typedef struct { int x, y; } ezx_point2d_t;
void ezx_point_2d(ezx_t *e, int x, int y, const ezx_color_t *col);
void ezx_line_2d(ezx_t *e, int x0, int y0, int x1, int y1, const ezx_color_t *col, int width);
void ezx_lines_2d(ezx_t *e, ezx_point2d_t *points, int npoints, const ezx_color_t *col, int width);
void ezx_poly_2d(ezx_t *e,ezx_point2d_t *points, int npoints, const ezx_color_t *col);
void ezx_str_2d(ezx_t *e, int x, int y, char *str, const ezx_color_t *col);
void ezx_rect_2d(ezx_t *e, int x0, int y0, int x1, int y1, const ezx_color_t *col, int width); void ezx_fillrect_2d(ezx_t *e, int x0, int y0, int x1, int y1, const ezx_color_t *col);
void ezx_circle_2d(ezx_t *e, int x, int y, int r, const ezx_color_t *col, int width); void ezx_fillcircle_2d(ezx_t *e, int x, int y, int r, const ezx_color_t *col);
void ezx_arc_2d(ezx_t *e, int x, int y, int w, int h, double angle1, double angle2, const ezx_color_t *col, int width); void ezx_fillarc_2d(ezx_t *e, int x, int y, int w, int h, double angle1, double angle2, const ezx_color_t *col);