--- /dev/null
+/*
+ * GLX overlay test/demo.
+ *
+ * Brian Paul
+ * 18 July 2005
+ */
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <X11/keysym.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int WinWidth = 300, WinHeight = 300;
+static Window NormalWindow = 0;
+static Window OverlayWindow = 0;
+static GLXContext NormalContext = 0;
+static GLXContext OverlayContext = 0;
+static GLboolean RGBOverlay = GL_FALSE;
+static GLfloat Angle = 0.0;
+
+
+static void
+RedrawNormal(Display *dpy)
+{
+ glXMakeCurrent(dpy, NormalWindow, NormalContext);
+ glViewport(0, 0, WinWidth, WinHeight);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 0.0);
+ glPushMatrix();
+ glRotatef(Angle, 0, 0, 1);
+ glRectf(-0.8, -0.8, 0.8, 0.8);
+ glPopMatrix();
+ glXSwapBuffers(dpy, NormalWindow);
+}
+
+
+static void
+RedrawOverlay(Display *dpy)
+{
+ glXMakeCurrent(dpy, OverlayWindow, OverlayContext);
+ glViewport(0, 0, WinWidth, WinHeight);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glClear(GL_COLOR_BUFFER_BIT);
+ if (RGBOverlay) {
+ glColor3f(0.0, 1.0, 1.0);
+ }
+ else {
+ glIndexi(2);
+ }
+ glBegin(GL_LINES);
+ glVertex2f(-1, -1);
+ glVertex2f(1, 1);
+ glVertex2f(1, -1);
+ glVertex2f(-1, 1);
+ glEnd();
+ glXSwapBuffers(dpy, OverlayWindow);
+}
+
+
+static Window
+MakeWindow(Display *dpy, XVisualInfo *visinfo, Window parent,
+ unsigned int width, unsigned int height)
+{
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+
+ scrnum = DefaultScreen(dpy);
+ root = RootWindow(dpy, scrnum);
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow(dpy, parent, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr);
+ return win;
+}
+
+
+static void
+MakeNormalWindow(Display *dpy)
+{
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ int scrnum;
+ Window root;
+ XVisualInfo *visinfo;
+
+ scrnum = DefaultScreen(dpy);
+ root = RootWindow(dpy, scrnum);
+
+ visinfo = glXChooseVisual(dpy, scrnum, attrib);
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ NormalWindow = MakeWindow(dpy, visinfo, root, WinWidth, WinHeight);
+ assert(NormalWindow);
+
+ NormalContext = glXCreateContext(dpy, visinfo, NULL, True);
+ assert(NormalContext);
+}
+
+
+static void
+MakeOverlayWindow(Display *dpy)
+{
+ int rgbAttribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_LEVEL, 1,
+ None
+ };
+ int indexAttribs[] = {
+ /*GLX_RGBA, leave this out */
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_LEVEL, 1,
+ None
+ };
+ int scrnum;
+ Window root;
+ XVisualInfo *visinfo;
+
+ scrnum = DefaultScreen(dpy);
+ root = RootWindow(dpy, scrnum);
+
+ visinfo = glXChooseVisual(dpy, scrnum, rgbAttribs);
+ if (visinfo) {
+ printf("Found RGB overlay visual 0x%x\n", (int) visinfo->visualid);
+ RGBOverlay = GL_TRUE;
+ }
+ else {
+ visinfo = glXChooseVisual(dpy, scrnum, indexAttribs);
+ if (visinfo) {
+ printf("Found Color Index overlay visual 0x%x\n",
+ (int) visinfo->visualid);
+ /* XXX setup the colormap entries! */
+ }
+ else {
+ printf("Error: couldn't get an overlay visual!\n");
+ exit(1);
+ }
+ }
+
+ OverlayWindow = MakeWindow(dpy, visinfo, NormalWindow, WinWidth, WinHeight);
+ assert(OverlayWindow);
+
+ OverlayContext = glXCreateContext(dpy, visinfo, NULL, True);
+ assert(OverlayContext);
+}
+
+
+static void
+EventLoop(Display *dpy)
+{
+ XEvent event;
+
+ while (1) {
+ XNextEvent(dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ RedrawNormal(dpy);
+ RedrawOverlay(dpy);
+ break;
+ case ConfigureNotify:
+ WinWidth = event.xconfigure.width;
+ WinHeight = event.xconfigure.height;
+ if (event.xconfigure.window == NormalWindow)
+ XResizeWindow(dpy, OverlayWindow, WinWidth, WinHeight);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return;
+ }
+ else if (buffer[0] == ' ') {
+ Angle += 5.0;
+ RedrawNormal(dpy);
+ }
+ }
+ break;
+ default:
+ ; /* nothing */
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy = XOpenDisplay(NULL);
+
+ assert(dpy);
+
+ MakeNormalWindow(dpy);
+ MakeOverlayWindow(dpy);
+
+ XMapWindow(dpy, NormalWindow);
+ XMapWindow(dpy, OverlayWindow);
+
+ EventLoop(dpy);
+
+ glXDestroyContext(dpy, OverlayContext);
+ glXDestroyContext(dpy, NormalContext);
+ XDestroyWindow(dpy, OverlayWindow);
+ XDestroyWindow(dpy, NormalWindow);
+
+ return 0;
+}