Note: In addition to mouse devices, Silicon Graphics systems support various other input devices (for example, spaceballs). You can integrate them with your OpenGL program using the X input extension. For more information, see the X Input Extension Library Specification available online through IRIS Insight.
Example 3-3 : Event Handling With Xlib
static int process_input(Display *dpy) { XEvent event; Bool redraw = 0; static int mstate, omx, omy, mx, my; do { char buf[31]; KeySym keysym; XNextEvent(dpy, &event); switch(event.type) { case Expose: redraw = 1; break; case ConfigureNotify: glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); redraw = 1; break; case KeyPress: (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL); switch (keysym) { case XK_Escape: exit(EXIT_SUCCESS); default: break; } case ButtonPress: if (event.xbutton.button == Button2) { mstate |= 2; mx = event.xbutton.x; my = event.xbutton.y; } else if (event.xbutton.button == Button1) { mstate |= 1; mx = event.xbutton.x; my = event.xbutton.y; } break; case ButtonRelease: if (event.xbutton.button == Button2) mstate &= ~2; else if (event.xbutton.button == Button1) mstate &= ~1; break; case MotionNotify: if (mstate) { omx = mx; omy = my; mx = event.xbutton.x; my = event.xbutton.y; update_view(mstate, omx,mx,omy,my); redraw = 1; } break; default: break; } } while (XPending(dpy)); return redraw; }The process_input() function is then used by the main loop:
while (1) { if (process_input(dpy)) { draw_scene(); ... } }
If redrawing is not an acceptable solution, the OpenGL program can do all your rendering into a GLXPixmap instead of directly to the window; then, any time the program needs to redraw the window, you can simply copy the GLXPixmap's contents into the window using XCopyArea(). For more information, see "Using Pixmaps".
Caution: Rendering to a GLXPixmap is much slower than rendering to a window. For example, on a RealityEngine, rendering to a pixmap is perhaps 5% the speed of rendering to a window. When handling X events for OpenGL programs, remember that Expose events come in batches. When you expose a window that is partly covered by two or more other windows, two or more Expose events are generated, one for each exposed region. Each one indicates a simple rectangle in the window to be redrawn. If you are going to redraw the entire window, read the entire batch of Expose events. It is wasteful and inefficient to redraw the window for each Expose event.