summaryrefslogtreecommitdiff
path: root/progs/miniglx
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-08-06 17:47:15 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-08-06 17:47:15 +0000
commita7ea785a104a2254ace3b17ff0bde8231295f0fa (patch)
treea62b678f19e4114fe522c3ba83bb404c15199c2a /progs/miniglx
parentfb4d5492e01dffc83ce9129263409eebf4b220aa (diff)
miniglx test programs
Diffstat (limited to 'progs/miniglx')
-rw-r--r--progs/miniglx/Makefile30
-rw-r--r--progs/miniglx/glfbdevtest.c478
-rw-r--r--progs/miniglx/manytex.c381
-rw-r--r--progs/miniglx/miniglxsample.c127
-rw-r--r--progs/miniglx/miniglxtest.c194
-rw-r--r--progs/miniglx/sample_server.c112
-rw-r--r--progs/miniglx/sample_server2.c227
-rw-r--r--progs/miniglx/texline.c268
8 files changed, 1817 insertions, 0 deletions
diff --git a/progs/miniglx/Makefile b/progs/miniglx/Makefile
new file mode 100644
index 0000000000..48923ebcff
--- /dev/null
+++ b/progs/miniglx/Makefile
@@ -0,0 +1,30 @@
+
+# Simple makefile for compiling test programs on Linux
+# These programs aren't intended to be included with the normal
+# distro. They're not too interesting but they're good for testing.
+
+
+CC = gcc
+CFLAGS = -g -I../include
+LIBS = -L../lib -lGL -lGLU -lglut -lm -Wl,-rpath,../lib
+
+PROGS = miniglxtest miniglxsample sample_server sample_server2 manytex texline
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c:
+ $(CC) $(CFLAGS) $< $(LIBS) -o $@
+
+
+##### TARGETS #####
+
+default: $(PROGS)
+
+clean:
+ rm -f $(PROGS)
+ rm -f *.o
+
diff --git a/progs/miniglx/glfbdevtest.c b/progs/miniglx/glfbdevtest.c
new file mode 100644
index 0000000000..c82ca6e5f6
--- /dev/null
+++ b/progs/miniglx/glfbdevtest.c
@@ -0,0 +1,478 @@
+/* $Id: glfbdevtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * Test the GLFBDev interface. Only tested with radeonfb driver!!!!
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <linux/fb.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <GL/glut.h>
+#include "GL/glfbdev.h"
+
+#define DEFAULT_DEPTH 8
+
+static struct fb_fix_screeninfo FixedInfo;
+static struct fb_var_screeninfo VarInfo, OrigVarInfo;
+static int DesiredDepth = 0;
+static int OriginalVT = -1;
+static int ConsoleFD = -1;
+static int FrameBufferFD = -1;
+static caddr_t FrameBuffer = (caddr_t) -1;
+static caddr_t MMIOAddress = (caddr_t) -1;
+
+
+static void
+print_fixed_info(const struct fb_fix_screeninfo *fixed, const char *s)
+{
+ static const char *visuals[] = {
+ "MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
+ "DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
+ };
+
+ printf("%s info -----------------------\n", s);
+ printf("id = %16s\n", fixed->id);
+ printf("smem_start = 0x%x\n", fixed->smem_start);
+ printf("smem_len = %d (0x%x)\n", fixed->smem_len, fixed->smem_len);
+ printf("type = 0x%x\n", fixed->type);
+ printf("type_aux = 0x%x\n", fixed->type_aux);
+ printf("visual = 0x%x (%s)\n", fixed->visual, visuals[fixed->visual]);
+ printf("xpanstep = %d\n", fixed->xpanstep);
+ printf("ypanstep = %d\n", fixed->ypanstep);
+ printf("ywrapstep = %d\n", fixed->ywrapstep);
+ printf("line_length = %d\n", fixed->line_length);
+ printf("mmio_start = 0x%x\n", fixed->mmio_start);
+ printf("mmio_len = %d (0x%x)\n", fixed->mmio_len, fixed->mmio_len);
+ printf("accel = 0x%x\n", fixed->accel);
+}
+
+
+static void
+print_var_info(const struct fb_var_screeninfo *var, const char *s)
+{
+ printf("%s info -----------------------\n", s);
+ printf("xres = %d\n", var->xres);
+ printf("yres = %d\n", var->yres);
+ printf("xres_virtual = %d\n", var->xres_virtual);
+ printf("yres_virtual = %d\n", var->yres_virtual);
+ printf("xoffset = %d\n", var->xoffset);
+ printf("yoffset = %d\n", var->yoffset);
+ printf("bits_per_pixel = %d\n", var->bits_per_pixel);
+ printf("grayscale = %d\n", var->grayscale);
+
+ printf("red.offset = %d length = %d msb_right = %d\n",
+ var->red.offset, var->red.length, var->red.msb_right);
+ printf("green.offset = %d length = %d msb_right = %d\n",
+ var->green.offset, var->green.length, var->green.msb_right);
+ printf("blue.offset = %d length = %d msb_right = %d\n",
+ var->blue.offset, var->blue.length, var->blue.msb_right);
+ printf("transp.offset = %d length = %d msb_right = %d\n",
+ var->transp.offset, var->transp.length, var->transp.msb_right);
+
+ printf("nonstd = %d\n", var->nonstd);
+ printf("activate = %d\n", var->activate);
+ printf("height = %d mm\n", var->height);
+ printf("width = %d mm\n", var->width);
+ printf("accel_flags = 0x%x\n", var->accel_flags);
+ printf("pixclock = %d\n", var->pixclock);
+ printf("left_margin = %d\n", var->left_margin);
+ printf("right_margin = %d\n", var->right_margin);
+ printf("upper_margin = %d\n", var->upper_margin);
+ printf("lower_margin = %d\n", var->lower_margin);
+ printf("hsync_len = %d\n", var->hsync_len);
+ printf("vsync_len = %d\n", var->vsync_len);
+ printf("sync = %d\n", var->sync);
+ printf("vmode = %d\n", var->vmode);
+}
+
+
+static void
+signal_handler(int signumber)
+{
+ signal(signumber, SIG_IGN); /* prevent recursion! */
+ fprintf(stderr, "error: got signal %d (exiting)\n", signumber);
+ exit(1);
+}
+
+
+static void
+initialize_fbdev( void )
+{
+ char ttystr[1000];
+ int fd, vtnumber, ttyfd;
+ int sz;
+
+ if (geteuid()) {
+ fprintf(stderr, "error: you need to be root\n");
+ exit(1);
+ }
+
+#if 1
+ /* open the framebuffer device */
+ FrameBufferFD = open("/dev/fb0", O_RDWR);
+ if (FrameBufferFD < 0) {
+ fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
+ exit(1);
+ }
+#endif
+
+ /* open /dev/tty0 and get the vt number */
+ if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) {
+ fprintf(stderr, "error opening /dev/tty0\n");
+ exit(1);
+ }
+ if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) {
+ fprintf(stderr, "error: couldn't get a free vt\n");
+ exit(1);
+ }
+ close(fd);
+
+ /* open the console tty */
+ sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */
+ ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0);
+ if (ConsoleFD < 0) {
+ fprintf(stderr, "error couldn't open console fd\n");
+ exit(1);
+ }
+
+ /* save current vt number */
+ {
+ struct vt_stat vts;
+ if (ioctl(ConsoleFD, VT_GETSTATE, &vts) == 0)
+ OriginalVT = vts.v_active;
+ }
+
+ /* disconnect from controlling tty */
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd >= 0) {
+ ioctl(ttyfd, TIOCNOTTY, 0);
+ close(ttyfd);
+ }
+
+ /* some magic to restore the vt when we exit */
+ {
+ struct vt_mode vt;
+ if (ioctl(ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
+ printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
+ if (ioctl(ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
+ printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
+
+ if (ioctl(ConsoleFD, VT_GETMODE, &vt) < 0) {
+ fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ vt.mode = VT_PROCESS;
+ vt.relsig = SIGUSR1;
+ vt.acqsig = SIGUSR1;
+ if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) {
+ fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ /* go into graphics mode */
+ if (ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) {
+ fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+
+#if 0
+ /* open the framebuffer device */
+ FrameBufferFD = open("/dev/fb0", O_RDWR);
+ if (FrameBufferFD < 0) {
+ fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
+ exit(1);
+ }
+#endif
+
+ /* Get the fixed screen info */
+ if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
+ fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ print_fixed_info(&FixedInfo, "Fixed");
+
+
+ /* get the variable screen info */
+ if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
+ fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ print_var_info(&OrigVarInfo, "Orig Var");
+
+ /* operate on a copy */
+ VarInfo = OrigVarInfo;
+
+ /* set the depth, resolution, etc */
+ DesiredDepth = 32;
+ if (DesiredDepth)
+ VarInfo.bits_per_pixel = DesiredDepth;
+
+ if (VarInfo.bits_per_pixel == 16) {
+ VarInfo.red.offset = 11;
+ VarInfo.green.offset = 5;
+ VarInfo.blue.offset = 0;
+ VarInfo.red.length = 5;
+ VarInfo.green.length = 6;
+ VarInfo.blue.length = 5;
+ VarInfo.transp.offset = 0;
+ VarInfo.transp.length = 0;
+ }
+ else if (VarInfo.bits_per_pixel == 32) {
+ VarInfo.red.offset = 16;
+ VarInfo.green.offset = 8;
+ VarInfo.blue.offset = 0;
+ VarInfo.transp.offset = 24;
+ VarInfo.red.length = 8;
+ VarInfo.green.length = 8;
+ VarInfo.blue.length = 8;
+ VarInfo.transp.length = 8;
+ }
+ /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
+ VarInfo.xres_virtual = VarInfo.xres = 1280;
+ VarInfo.yres_virtual = VarInfo.yres = 1024;
+ VarInfo.pixclock = 7408;
+ VarInfo.left_margin = 248;
+ VarInfo.right_margin = 16;
+ VarInfo.upper_margin = 38;
+ VarInfo.lower_margin = 1;
+ VarInfo.hsync_len = 144;
+ VarInfo.vsync_len = 3;
+
+ VarInfo.xoffset = 0;
+ VarInfo.yoffset = 0;
+ VarInfo.nonstd = 0;
+ VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
+
+ /* set new variable screen info */
+ if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
+ fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ print_var_info(&VarInfo, "New Var");
+
+ if (FixedInfo.visual != FB_VISUAL_TRUECOLOR &&
+ FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) {
+ fprintf(stderr, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo.visual);
+ exit(1);
+ }
+
+ /* initialize colormap */
+ if (FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) {
+ struct fb_cmap cmap;
+ unsigned short red[256], green[256], blue[256];
+ int i;
+
+ /* we're assuming 256 entries here */
+ printf("initializing directcolor colormap\n");
+ cmap.start = 0;
+ cmap.len = 256;
+ cmap.red = red;
+ cmap.green = green;
+ cmap.blue = blue;
+ cmap.transp = NULL;
+ for (i = 0; i < cmap.len; i++) {
+ red[i] = green[i] = blue[i] = (i << 8) | i;
+ }
+ if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) {
+ fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i);
+ }
+ }
+
+ /*
+ * fbdev says the frame buffer is at offset zero, and the mmio region
+ * is immediately after.
+ */
+
+ /* mmap the framebuffer into our address space */
+ FrameBuffer = (caddr_t) mmap(0, /* start */
+ FixedInfo.smem_len, /* bytes */
+ PROT_READ | PROT_WRITE, /* prot */
+ MAP_SHARED, /* flags */
+ FrameBufferFD, /* fd */
+ 0 /* offset */);
+ if (FrameBuffer == (caddr_t) - 1) {
+ fprintf(stderr, "error: unable to mmap framebuffer: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ printf("FrameBuffer = %p\n", FrameBuffer);
+
+#if 1
+ /* mmap the MMIO region into our address space */
+ MMIOAddress = (caddr_t) mmap(0, /* start */
+ FixedInfo.mmio_len, /* bytes */
+ PROT_READ | PROT_WRITE, /* prot */
+ MAP_SHARED, /* flags */
+ FrameBufferFD, /* fd */
+ FixedInfo.smem_len /* offset */);
+ if (MMIOAddress == (caddr_t) - 1) {
+ fprintf(stderr, "error: unable to mmap mmio region: %s\n",
+ strerror(errno));
+ }
+ printf("MMIOAddress = %p\n", MMIOAddress);
+
+ /* try out some simple MMIO register reads */
+ if (1)
+ {
+ typedef unsigned int CARD32;
+ typedef unsigned char CARD8;
+#define RADEON_CONFIG_MEMSIZE 0x00f8
+#define RADEON_MEM_SDRAM_MODE_REG 0x0158
+#define MMIO_IN32(base, offset) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
+#define INREG(addr) MMIO_IN32(MMIOAddress, addr)
+ int sz, type;
+ const char *typeStr[] = {"SDR", "DDR", "64-bit SDR"};
+ sz = INREG(RADEON_CONFIG_MEMSIZE);
+ type = INREG(RADEON_MEM_SDRAM_MODE_REG);
+ printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz, sz / 1024 / 1024);
+ printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
+ type >> 30, typeStr[type>>30]);
+ }
+#endif
+
+}
+
+
+static void
+shutdown_fbdev( void )
+{
+ struct vt_mode VT;
+
+ printf("cleaning up...\n");
+ /* restore original variable screen info */
+ if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) {
+ fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ munmap(MMIOAddress, FixedInfo.mmio_len);
+ munmap(FrameBuffer, FixedInfo.smem_len);
+ close(FrameBufferFD);
+
+ /* restore text mode */
+ ioctl(ConsoleFD, KDSETMODE, KD_TEXT);
+
+ /* set vt */
+ if (ioctl(ConsoleFD, VT_GETMODE, &VT) != -1) {
+ VT.mode = VT_AUTO;
+ ioctl(ConsoleFD, VT_SETMODE, &VT);
+ }
+
+ /* restore original vt */
+ if (OriginalVT >= 0) {
+ ioctl(ConsoleFD, VT_ACTIVATE, OriginalVT);
+ OriginalVT = -1;
+ }
+
+ close(ConsoleFD);
+}
+
+
+static void
+gltest( void )
+{
+ static const int attribs[] = {
+ GLFBDEV_DOUBLE_BUFFER,
+ GLFBDEV_DEPTH_SIZE, 16,
+ GLFBDEV_NONE
+ };
+ GLFBDevContextPtr ctx;
+ GLFBDevBufferPtr buf;
+ GLFBDevVisualPtr vis;
+ int bytes, r, g, b, a;
+ float ang;
+
+ printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
+ printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
+
+ /* framebuffer size */
+ bytes = VarInfo.xres_virtual * VarInfo.yres_virtual * VarInfo.bits_per_pixel / 8;
+
+ vis = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs );
+ assert(vis);
+
+ buf = glFBDevCreateBuffer( &FixedInfo, &VarInfo, vis, FrameBuffer, NULL, bytes );
+ assert(buf);
+
+ ctx = glFBDevCreateContext( vis, NULL );
+ assert(buf);
+
+ b = glFBDevMakeCurrent( ctx, buf, buf );
+ assert(b);
+
+ /*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
+ glGetIntegerv(GL_RED_BITS, &r);
+ glGetIntegerv(GL_GREEN_BITS, &g);
+ glGetIntegerv(GL_BLUE_BITS, &b);
+ glGetIntegerv(GL_ALPHA_BITS, &a);
+ printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
+ r, g, b, a);
+
+ glClearColor(0.5, 0.5, 1.0, 0);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1, 1, -1, 1, 2, 30);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -15);
+ glViewport(0, 0, VarInfo.xres_virtual, VarInfo.yres_virtual);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ for (ang = 0; ang <= 180; ang += 15) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glPushMatrix();
+ glRotatef(ang, 1, 0, 0);
+ glutSolidTorus(1, 3, 40, 20);
+ glPopMatrix();
+ glFBDevSwapBuffers(buf);
+ }
+
+ /* clean up */
+ b = glFBDevMakeCurrent( NULL, NULL, NULL);
+ assert(b);
+
+ glFBDevDestroyContext(ctx);
+ glFBDevDestroyBuffer(buf);
+ glFBDevDestroyVisual(vis);
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+ signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
+ signal(SIGSEGV, signal_handler); /* catch segfaults */
+
+ initialize_fbdev();
+ gltest();
+ shutdown_fbdev();
+
+ return 0;
+}
diff --git a/progs/miniglx/manytex.c b/progs/miniglx/manytex.c
new file mode 100644
index 0000000000..3801963f9d
--- /dev/null
+++ b/progs/miniglx/manytex.c
@@ -0,0 +1,381 @@
+/* $Id: manytex.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * test handling of many texture maps
+ * Also tests texture priority and residency.
+ *
+ * Brian Paul
+ * August 2, 2000
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static GLint NumTextures = 20;
+static GLuint *TextureID = NULL;
+static GLint *TextureWidth = NULL, *TextureHeight = NULL;
+static GLboolean *TextureResidency = NULL;
+static GLint TexWidth = 128, TexHeight = 128;
+static GLfloat Zrot = 0;
+static GLboolean Anim = GL_TRUE;
+static GLint WinWidth = 500, WinHeight = 400;
+static GLboolean MipMap = GL_FALSE;
+static GLboolean LinearFilter = GL_FALSE;
+static GLboolean RandomSize = GL_FALSE;
+static GLint Rows, Columns;
+static GLint LowPriorityCount = 0;
+
+
+static void Idle( void )
+{
+ Zrot += 1.0;
+ glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+ GLfloat spacing = WinWidth / Columns;
+ GLfloat size = spacing * 0.4;
+ GLint i;
+
+ /* test residency */
+ if (0)
+ {
+ GLboolean b;
+ GLint i, resident;
+ b = glAreTexturesResident(NumTextures, TextureID, TextureResidency);
+ if (b) {
+ printf("all resident\n");
+ }
+ else {
+ resident = 0;
+ for (i = 0; i < NumTextures; i++) {
+ if (TextureResidency[i]) {
+ resident++;
+ }
+ }
+ printf("%d of %d texture resident\n", resident, NumTextures);
+ }
+ }
+
+ /* render the textured quads */
+ glClear( GL_COLOR_BUFFER_BIT );
+ for (i = 0; i < NumTextures; i++) {
+ GLint row = i / Columns;
+ GLint col = i % Columns;
+ GLfloat x = col * spacing + spacing * 0.5;
+ GLfloat y = row * spacing + spacing * 0.5;
+
+ GLfloat maxDim = (TextureWidth[i] > TextureHeight[i])
+ ? TextureWidth[i] : TextureHeight[i];
+ GLfloat w = TextureWidth[i] / maxDim;
+ GLfloat h = TextureHeight[i] / maxDim;
+
+ glPushMatrix();
+ glTranslatef(x, y, 0.0);
+ glRotatef(Zrot, 0, 0, 1);
+ glScalef(size, size, 1);
+
+ glBindTexture(GL_TEXTURE_2D, TextureID[i]);
+ glBegin(GL_POLYGON);
+#if 0
+ glTexCoord2f(0, 0); glVertex2f(-1, -1);
+ glTexCoord2f(1, 0); glVertex2f( 1, -1);
+ glTexCoord2f(1, 1); glVertex2f( 1, 1);
+ glTexCoord2f(0, 1); glVertex2f(-1, 1);
+#else
+ glTexCoord2f(0, 0); glVertex2f(-w, -h);
+ glTexCoord2f(1, 0); glVertex2f( w, -h);
+ glTexCoord2f(1, 1); glVertex2f( w, h);
+ glTexCoord2f(0, 1); glVertex2f(-w, h);
+#endif
+ glEnd();
+ glPopMatrix();
+ }
+
+ glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport( 0, 0, width, height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+}
+
+
+/*
+ * Return a random int in [min, max].
+ */
+static int RandomInt(int min, int max)
+{
+ int i = rand();
+ int j = i % (max - min + 1);
+ return min + j;
+}
+
+
+
+static void Init( void )
+{
+ GLint i;
+
+ if (RandomSize) {
+ printf("Creating %d %s random-size textures, ", NumTextures,
+ MipMap ? "Mipmapped" : "non-Mipmapped");
+ }
+ else {
+ printf("Creating %d %s %d x %d textures, ", NumTextures,
+ MipMap ? "Mipmapped" : "non-Mipmapped",
+ TexWidth, TexHeight);
+ }
+
+ if (LinearFilter) {
+ printf("bilinear filtering\n");
+ }
+ else {
+ printf("nearest filtering\n");
+ }
+
+
+ /* compute number of rows and columns of rects */
+ {
+ GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures;
+ GLfloat edgeLen = sqrt(area);
+
+ Columns = WinWidth / edgeLen;
+ Rows = (NumTextures + Columns - 1) / Columns;
+ printf("Rows: %d Cols: %d\n", Rows, Columns);
+ }
+
+
+ if (!TextureID) {
+ TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures);
+ assert(TextureID);
+ glGenTextures(NumTextures, TextureID);
+ }
+
+ if (!TextureResidency) {
+ TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures);
+ assert(TextureResidency);
+ }
+
+ if (!TextureWidth) {
+ TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures);
+ assert(TextureWidth);
+ }
+ if (!TextureHeight) {
+ TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures);
+ assert(TextureHeight);
+ }
+
+ for (i = 0; i < NumTextures; i++) {
+ GLubyte color[4];
+ GLubyte *texImage;
+ GLint j, row, col;
+
+ row = i / Columns;
+ col = i % Columns;
+
+ glBindTexture(GL_TEXTURE_2D, TextureID[i]);
+
+ if (i < LowPriorityCount)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
+
+ if (RandomSize) {
+#if 0
+ int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2;
+ TexWidth = 1 << k;
+ TexHeight = 1 << k;
+#else
+ TexWidth = 1 << RandomInt(2, 7);
+ TexHeight = 1 << RandomInt(2, 7);
+ printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight);
+#endif
+ }
+
+ TextureWidth[i] = TexWidth;
+ TextureHeight[i] = TexHeight;
+
+ texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
+ assert(texImage);
+
+ /* determine texture color */
+ color[0] = (GLint) (255.0 * ((float) col / (Columns - 1)));
+ color[1] = 127;
+ color[2] = (GLint) (255.0 * ((float) row / (Rows - 1)));
+ color[3] = 255;
+
+ /* fill in solid-colored teximage */
+ for (j = 0; j < TexWidth * TexHeight; j++) {
+ texImage[j*4+0] = color[0];
+ texImage[j*4+1] = color[1];
+ texImage[j*4+2] = color[2];
+ texImage[j*4+3] = color[3];
+ }
+
+ if (MipMap) {
+ GLint level = 0;
+ GLint w = TexWidth, h = TexHeight;
+ while (1) {
+ glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texImage);
+ if (w == 1 && h == 1)
+ break;
+ if (w > 1)
+ w /= 2;
+ if (h > 1)
+ h /= 2;
+ level++;
+ /*printf("%d: %d x %d\n", level, w, h);*/
+ }
+ if (LinearFilter) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ }
+ else {
+ /* Set corners to white */
+ int k = 0;
+ texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
+ k = (TexWidth - 1) * 4;
+ texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
+ k = (TexWidth * TexHeight - TexWidth) * 4;
+ texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
+ k = (TexWidth * TexHeight - 1) * 4;
+ texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texImage);
+ if (LinearFilter) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ }
+
+ free(texImage);
+ }
+
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 's':
+ Idle();
+ break;
+ case 'z':
+ Zrot -= step;
+ break;
+ case 'Z':
+ Zrot += step;
+ break;
+ case ' ':
+ Init();
+ break;
+ case 27:
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+int main( int argc, char *argv[] )
+{
+ GLint i;
+
+ glutInit( &argc, argv );
+ glutInitWindowPosition( 0, 0 );
+ glutInitWindowSize( WinWidth, WinHeight );
+ glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+ glutCreateWindow(argv[0]);
+ glutReshapeFunc( Reshape );
+ glutKeyboardFunc( Key );
+ glutDisplayFunc( Display );
+ if (Anim)
+ glutIdleFunc(Idle);
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-n") == 0) {
+ NumTextures = atoi(argv[i+1]);
+ if (NumTextures <= 0) {
+ printf("Error, bad number of textures\n");
+ return 1;
+ }
+ i++;
+ }
+ else if (strcmp(argv[i], "-mipmap") == 0) {
+ MipMap = GL_TRUE;
+ }
+ else if (strcmp(argv[i], "-linear") == 0) {
+ LinearFilter = GL_TRUE;
+ }
+ else if (strcmp(argv[i], "-size") == 0) {
+ TexWidth = atoi(argv[i+1]);
+ TexHeight = atoi(argv[i+2]);
+ assert(TexWidth >= 1);
+ assert(TexHeight >= 1);
+ i += 2;
+ }
+ else if (strcmp(argv[i], "-randomsize") == 0) {
+ RandomSize = GL_TRUE;
+ }
+ else if (strcmp(argv[i], "-lowpri") == 0) {
+ LowPriorityCount = atoi(argv[i+1]);
+ i++;
+ }
+ else {
+ printf("Usage:\n");
+ printf(" manytex [options]\n");
+ printf("Options:\n");
+ printf(" -n <number of texture objects>\n");
+ printf(" -size <width> <height> - specify texture size\n");
+ printf(" -randomsize - use random size textures\n");
+ printf(" -mipmap - generate mipmaps\n");
+ printf(" -linear - use linear filtering instead of nearest\n");
+ printf(" -lowpri <n> - Set lower priority on <n> textures\n");
+ return 0;
+ }
+ }
+
+ Init();
+
+ glutMainLoop();
+
+ return 0;
+}
diff --git a/progs/miniglx/miniglxsample.c b/progs/miniglx/miniglxsample.c
new file mode 100644
index 0000000000..bea845c8ff
--- /dev/null
+++ b/progs/miniglx/miniglxsample.c
@@ -0,0 +1,127 @@
+
+#define USE_MINIGLX 1 /* 1 = use Mini GLX, 0 = use Xlib/GLX */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/gl.h>
+
+#if USE_MINIGLX
+#include <GL/miniglx.h>
+#else
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+#endif
+
+static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ glBegin( GL_QUADS );
+ glVertex2f( x1, y1 );
+ glVertex2f( x2, y1 );
+ glVertex2f( x2, y2 );
+ glVertex2f( x1, y2 );
+ glEnd();
+}
+
+
+/*
+ * Create a simple double-buffered RGBA window.
+ */
+static Window
+MakeWindow(Display * dpy, unsigned int width, unsigned int height)
+{
+ int visAttributes[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+ XSetWindowAttributes attr;
+ unsigned long attrMask;
+ Window root;
+ Window win;
+ GLXContext ctx;
+ XVisualInfo *visinfo;
+
+ root = RootWindow(dpy, 0);
+
+ /* Choose GLX visual / pixel format */
+ visinfo = glXChooseVisual(dpy, 0, visAttributes);
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* Create the window */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
+ attrMask = CWBackPixel | CWBorderPixel | CWColormap;
+ win = XCreateWindow(dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, attrMask, &attr);
+ if (!win) {
+ printf("Error: XCreateWindow failed\n");
+ exit(1);
+ }
+
+ /* Display the window */
+ XMapWindow(dpy, win);
+
+ /* Create GLX rendering context */
+ ctx = glXCreateContext(dpy, visinfo, NULL, True);
+ if (!ctx) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ /* Bind the rendering context and window */
+ glXMakeCurrent(dpy, win, ctx);
+
+ glViewport(0, 0, width, height);
+
+ return win;
+}
+
+
+/*
+ * Draw a few frames of a rotating square.
+ */
+static void
+DrawFrames(Display * dpy, Window win)
+{
+ int angle;
+ glShadeModel(GL_FLAT);
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ for (angle = 0; angle < 360; angle += 10) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 0.0);
+ glPushMatrix();
+ glRotatef(angle, 0, 0, 1);
+ _subset_Rectf(-0.8, -0.8, 0.8, 0.8);
+ glPopMatrix();
+ glXSwapBuffers(dpy, win);
+ sleep(1);
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ Window win;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ printf("Error: XOpenDisplay failed\n");
+ return 1;
+ }
+
+ win = MakeWindow(dpy, 300, 300);
+
+ DrawFrames(dpy, win);
+
+ return 0;
+}
diff --git a/progs/miniglx/miniglxtest.c b/progs/miniglx/miniglxtest.c
new file mode 100644
index 0000000000..911bf4cb86
--- /dev/null
+++ b/progs/miniglx/miniglxtest.c
@@ -0,0 +1,194 @@
+/* $Id: miniglxtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * Test the mini GLX interface.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/gl.h>
+#define USE_MINI_GLX 1
+#if USE_MINI_GLX
+#include <GL/miniglx.h>
+#else
+#include <GL/glx.h>
+#endif
+
+#define FRONTBUFFER 1
+#define NR 6
+#define DO_SLEEPS 1
+#define NR_DISPLAYS 2
+
+GLXContext ctx;
+
+
+static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ glBegin( GL_QUADS );
+ glVertex2f( x1, y1 );
+ glVertex2f( x2, y1 );
+ glVertex2f( x2, y2 );
+ glVertex2f( x1, y2 );
+ glEnd();
+}
+
+
+
+static void redraw( Display *dpy, Window w, int rot )
+{
+ printf("Redraw event\n");
+
+#if FRONTBUFFER
+ glDrawBuffer( GL_FRONT );
+#else
+/* glDrawBuffer( GL_BACK ); */
+#endif
+
+ glClearColor( rand()/(float)RAND_MAX,
+ rand()/(float)RAND_MAX,
+ rand()/(float)RAND_MAX,
+ 1);
+
+ glClear( GL_COLOR_BUFFER_BIT );
+
+#if 1
+ glColor3f( rand()/(float)RAND_MAX,
+ rand()/(float)RAND_MAX,
+ rand()/(float)RAND_MAX );
+ glPushMatrix();
+ glRotatef(rot, 0, 0, 1);
+ glScalef(.5, .5, .5);
+ _subset_Rectf( -1, -1, 1, 1 );
+ glPopMatrix();
+#endif
+
+#if FRONTBUFFER
+ glFlush();
+#else
+ glXSwapBuffers( dpy, w );
+#endif
+ glFinish();
+}
+
+
+static Window make_rgb_db_window( Display *dpy,
+ unsigned int width, unsigned int height )
+{
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+#if !FRONT_BUFFER
+ GLX_DOUBLEBUFFER,
+#endif
+ None };
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ XVisualInfo *visinfo;
+
+ scrnum = 0;
+ root = RootWindow( dpy, scrnum );
+
+ if (!(visinfo = glXChooseVisual( dpy, scrnum, attrib ))) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ if(!(ctx = glXCreateContext( dpy, visinfo, NULL, True ))) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+ if (!win) {
+ printf("Error: XCreateWindow failed\n");
+ exit(1);
+ }
+
+ glXMakeCurrent( dpy, win, ctx );
+
+ glViewport(0, 0, width, height);
+
+ return win;
+}
+
+
+static void event_loop( Display *dpy, Window win )
+{
+ int i;
+
+ printf("Hang on... drawing %d frames\n", NR);
+ for (i = 0; i < NR; i++) {
+ redraw( dpy, win, i*10 );
+ if (DO_SLEEPS) {
+ printf("sleep(1)\n");
+ sleep(1);
+ }
+ }
+}
+
+
+int foo( )
+{
+ Display *dpy;
+ Window win;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ printf("Error: XOpenDisplay failed\n");
+ return 1;
+ }
+
+ win = make_rgb_db_window( dpy, 800, 600);
+
+ srand(getpid());
+
+ glShadeModel( GL_FLAT );
+ glClearColor( 0.5, 0.5, 0.5, 1.0 );
+
+ XMapWindow( dpy, win );
+
+ {
+ XEvent e;
+ while (1) {
+ XNextEvent( dpy, &e );
+ if (e.type == MapNotify && e.xmap.window == win) {
+ break;
+ }
+ }
+ }
+
+ event_loop( dpy, win );
+
+ glXDestroyContext( dpy, ctx );
+ XDestroyWindow( dpy, win );
+
+ XCloseDisplay( dpy );
+
+ return 0;
+}
+
+
+int main()
+{
+ int i;
+ for (i = 0 ; i < NR_DISPLAYS ; i++) {
+ if (foo() != 0)
+ break;
+ }
+
+ return 0;
+}
diff --git a/progs/miniglx/sample_server.c b/progs/miniglx/sample_server.c
new file mode 100644
index 0000000000..039c04fa40
--- /dev/null
+++ b/progs/miniglx/sample_server.c
@@ -0,0 +1,112 @@
+/* $Id: sample_server.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * Sample server that just keeps first available window mapped.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/gl.h>
+#include <GL/miniglx.h>
+
+struct client {
+ struct client *next;
+ Window windowid;
+ int mappable;
+};
+
+struct client *clients = 0, *mapped_client = 0;
+
+
+static struct client *find_client( Window id )
+{
+ struct client *c;
+
+ for (c = clients ; c ; c = c->next)
+ if (c->windowid == id)
+ return c;
+
+ return 0;
+}
+
+int main( int argc, char *argv[] )
+{
+ Display *dpy;
+ XEvent ev;
+
+ dpy = __miniglx_StartServer(NULL);
+ if (!dpy) {
+ fprintf(stderr, "Error: __miniglx_StartServer failed\n");
+ return 1;
+ }
+
+ while (XNextEvent( dpy, &ev )) {
+ struct client *c;
+
+ switch (ev.type) {
+ case MapRequest:
+ fprintf(stderr, "MapRequest\n");
+ c = find_client(ev.xmaprequest.window);
+ if (!c) break;
+ c->mappable = True;
+ break;
+
+ case UnmapNotify:
+ fprintf(stderr, "UnmapNotify\n");
+ c = find_client(ev.xunmap.window);
+ if (!c) break;
+ c->mappable = False;
+ if (c == mapped_client)
+ mapped_client = 0;
+ break;
+
+ case CreateNotify:
+ fprintf(stderr, "CreateNotify\n");
+ c = malloc(sizeof(*c));
+ c->next = clients;
+ c->windowid = ev.xcreatewindow.window;
+ c->mappable = False;
+ clients = c;
+ break;
+
+ case DestroyNotify:
+ fprintf(stderr, "DestroyNotify\n");
+ c = find_client(ev.xdestroywindow.window);
+ if (!c) break;
+ if (c == clients)
+ clients = c->next;
+ else {
+ struct client *t;
+ for (t = clients ; t->next != c ; t = t->next)
+ ;
+ t->next = c->next;
+ }
+
+ if (c == mapped_client)
+ mapped_client = 0;
+
+ free(c);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Search for first mappable client if none already mapped.
+ */
+ if (!mapped_client) {
+ for (c = clients ; c ; c = c->next) {
+ if (c->mappable) {
+ XMapWindow( dpy, c->windowid );
+ mapped_client = c;
+ break;
+ }
+ }
+ }
+ }
+
+ XCloseDisplay( dpy );
+
+ return 0;
+}
diff --git a/progs/miniglx/sample_server2.c b/progs/miniglx/sample_server2.c
new file mode 100644
index 0000000000..3508a21950
--- /dev/null
+++ b/progs/miniglx/sample_server2.c
@@ -0,0 +1,227 @@
+/* $Id: sample_server2.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * Sample server that just keeps first available window mapped.
+ *
+ * It also reads and echos anything that happens on stdin as an
+ * example of tracking events from sources other than miniglx clients.
+ *
+ * It reads & writes without blocking, so that eg. piping a lot of
+ * text to stdin and then hitting 'ctrl-S' on the output stream won't
+ * cause it to stop handling miniglx events.
+ *
+ * See select_tut in the linux manual pages for a good overview of the
+ * select(2) system call.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/gl.h>
+#include <GL/miniglx.h>
+#include <errno.h>
+#include <assert.h>
+
+struct client {
+ struct client *next;
+ Window windowid;
+ int mappable;
+};
+
+struct client *clients = 0, *mapped_client = 0;
+
+#define BUFSZ 4096
+char rbuf[BUFSZ];
+int rbuf_count;
+
+
+static struct client *find_client( Window id )
+{
+ struct client *c;
+
+ for (c = clients ; c ; c = c->next)
+ if (c->windowid == id)
+ return c;
+
+ return 0;
+}
+
+int main( int argc, char *argv[] )
+{
+ Display *dpy;
+ XEvent ev;
+ int autostart = 0;
+
+ if (argc == 2 && strcmp(argv[1], "-autostart") == 0)
+ autostart = 1;
+
+ dpy = __miniglx_StartServer(NULL);
+ if (!dpy) {
+ fprintf(stderr, "Error: __miniglx_StartServer failed\n");
+ return 1;
+ }
+
+ /* How is vt switching communicated through the XNextEvent interface?
+ */
+ while (1) {
+ int r, n;
+ struct timeval tv;
+ fd_set rfds, wfds;
+ int bored = 0;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ if (rbuf_count) {
+ FD_SET( 1, &wfds ); /* notify when we can write out buffer */
+ n = 1;
+ }
+ else {
+ FD_SET( 0, &rfds ); /* else notify when new data to read */
+ n = 0;
+ }
+
+ /* __miniglx_Select waits until any of these file groups becomes
+ * readable/writable/etc (like regular select), until timeout
+ * expires (like regular select), until a signal is received
+ * (like regular select) or until an event is available for
+ * XCheckMaskEvent().
+ */
+ r = __miniglx_Select( dpy, n+1, &rfds, &wfds, 0, &tv );
+
+ /* This can happen if select() is interrupted by a signal:
+ */
+ if (r < 0 && errno != EINTR && errno != EAGAIN) {
+ perror ("select()");
+ exit (1);
+ }
+
+ if (tv.tv_sec == 0 && tv.tv_usec == 0)
+ bored = 1;
+
+ /* Check and handle events on our local file descriptors
+ */
+ if (FD_ISSET( 0, &rfds )) {
+ /* Something on stdin */
+ assert(rbuf_count == 0);
+ r = read(0, rbuf, BUFSZ);
+ if (r < 1) {
+ perror("read");
+ abort();
+ }
+ rbuf_count = r;
+ }
+
+ if (FD_ISSET( 1, &wfds )) {
+ /* Can write to stdout */
+ assert(rbuf_count > 0);
+ r = write(1, rbuf, rbuf_count);
+ if (r < 1) {
+ perror("write");
+ abort();
+ }
+ rbuf_count -= r;
+ if (rbuf_count)
+ memmove(rbuf + r, rbuf, rbuf_count);
+ }
+
+
+ /* Check and handle events generated by miniglx:
+ */
+ while (XCheckMaskEvent( dpy, ~0, &ev )) {
+ struct client *c;
+ bored = 0;
+
+ fprintf(stderr, "Received event %d\n", ev.type);
+
+ switch (ev.type) {
+ case CreateNotify:
+ fprintf(stderr, "CreateNotify -- new client\n");
+ c = malloc(sizeof(*c));
+ c->next = clients;
+ c->windowid = ev.xcreatewindow.window;
+ c->mappable = False;
+ clients = c;
+ break;
+
+ case DestroyNotify:
+ fprintf(stderr, "DestroyNotify\n");
+ c = find_client(ev.xdestroywindow.window);
+ if (!c) break;
+ if (c == clients)
+ clients = c->next;
+ else {
+ struct client *t;
+ for (t = clients ; t->next != c ; t = t->next)
+ ;
+ t->next = c->next;
+ }
+
+ if (c == mapped_client)
+ mapped_client = 0;
+
+ free(c);
+ break;
+
+ case MapRequest:
+ fprintf(stderr, "MapRequest\n");
+ c = find_client(ev.xmaprequest.window);
+ if (!c) break;
+ c->mappable = True;
+ break;
+
+ case UnmapNotify:
+ fprintf(stderr, "UnmapNotify\n");
+ c = find_client(ev.xunmap.window);
+ if (!c) break;
+ c->mappable = False;
+ if (c == mapped_client)
+ mapped_client = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ /* Search for first mappable client if none already mapped.
+ */
+ if (!mapped_client) {
+ struct client *c;
+ for (c = clients ; c ; c = c->next) {
+ if (c->mappable) {
+ XMapWindow( dpy, c->windowid );
+ mapped_client = c;
+ break;
+ }
+ }
+ if (!clients && autostart) {
+ system("nohup ./texline &");
+ system("nohup ./manytex &");
+ }
+ }
+ else if (bored) {
+ struct client *c;
+ /* bored of mapped client now, let's try & find another one */
+ for (c = mapped_client->next ; c && !c->mappable ; c = c->next)
+ ;
+ if (!c)
+ for (c = clients ; c && !c->mappable ; c = c->next)
+ ;
+ if (c && c != mapped_client) {
+ XUnmapWindow( dpy, mapped_client->windowid );
+ XMapWindow( dpy, c->windowid );
+ mapped_client = c;
+ }
+ else
+ fprintf(stderr, "I'm bored!\n");
+ }
+ }
+
+ XCloseDisplay( dpy );
+
+ return 0;
+}
diff --git a/progs/miniglx/texline.c b/progs/miniglx/texline.c
new file mode 100644
index 0000000000..d2a97d2876
--- /dev/null
+++ b/progs/miniglx/texline.c
@@ -0,0 +1,268 @@
+/* $Id: texline.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
+
+/*
+ * Test textured lines.
+ *
+ * Brian Paul
+ * September 2000
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "../util/readtex.c" /* I know, this is a hack. */
+
+#define TEXTURE_FILE "../images/girl.rgb"
+
+static GLboolean Antialias = GL_FALSE;
+static GLboolean Animate = GL_FALSE;
+static GLint Texture = 1;
+static GLboolean Stipple = GL_FALSE;
+static GLfloat LineWidth = 1.0;
+
+static GLfloat Xrot = -60.0, Yrot = 0.0, Zrot = 0.0;
+static GLfloat DYrot = 1.0;
+static GLboolean Points = GL_FALSE;
+static GLfloat Scale = 1.0;
+
+static void Idle( void )
+{
+ if (Animate) {
+ Zrot += DYrot;
+ glutPostRedisplay();
+ }
+}
+
+
+static void Display( void )
+{
+ GLfloat x, y, s, t;
+
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ glPushMatrix();
+ glRotatef(Xrot, 1.0, 0.0, 0.0);
+ glRotatef(Yrot, 0.0, 1.0, 0.0);
+ glRotatef(Zrot, 0.0, 0.0, 1.0);
+ glScalef(Scale, Scale, Scale);
+
+ if (Texture)
+ glColor3f(1, 1, 1);
+
+ if (Points) {
+ glBegin(GL_POINTS);
+ for (t = 0.0; t <= 1.0; t += 0.025) {
+ for (s = 0.0; s <= 1.0; s += 0.025) {
+ x = s * 2.0 - 1.0;
+ y = t * 2.0 - 1.0;
+ if (!Texture)
+ glColor3f(1, 0, 1);
+ glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s);
+ glTexCoord2f(s, t);
+ glVertex2f(x, y);
+ }
+ }
+ glEnd();
+ }
+ else {
+ glBegin(GL_LINES);
+ for (t = 0.0; t <= 1.0; t += 0.025) {
+ x = t * 2.0 - 1.0;
+ if (!Texture)
+ glColor3f(1, 0, 1);
+ glTexCoord2f(t, 0.0);
+ glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t);
+ glVertex2f(x, -1.0);
+ if (!Texture)
+ glColor3f(0, 1, 0);
+ glTexCoord2f(t, 1.0);
+ glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t);
+ glVertex2f(x, 1.0);
+ }
+ glEnd();
+ }
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+ GLfloat ar = (float) width / height;
+ glViewport( 0, 0, width, height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -ar, ar, -1.0, 1.0, 10.0, 100.0 );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -12.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'a':
+ Antialias = !Antialias;
+ if (Antialias) {
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_POINT_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else {
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_POINT_SMOOTH);
+ glDisable(GL_BLEND);
+ }
+ break;
+ case 't':
+ Texture++;
+ if (Texture > 2)
+ Texture = 0;
+ if (Texture == 0) {
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glDisable(GL_TEXTURE_2D);
+ }
+ else if (Texture == 1) {
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glDisable(GL_TEXTURE_2D);
+ }
+ else {
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glEnable(GL_TEXTURE_2D);
+ }
+ break;
+ case 'w':
+ LineWidth -= 0.25;
+ if (LineWidth < 0.25)
+ LineWidth = 0.25;
+ glLineWidth(LineWidth);
+ glPointSize(LineWidth);
+ break;
+ case 'W':
+ LineWidth += 0.25;
+ if (LineWidth > 8.0)
+ LineWidth = 8.0;
+ glLineWidth(LineWidth);
+ glPointSize(LineWidth);
+ break;
+ case 'p':
+ Points = !Points;
+ break;
+ case 's':
+ Stipple = !Stipple;
+ if (Stipple)
+ glEnable(GL_LINE_STIPPLE);
+ else
+ glDisable(GL_LINE_STIPPLE);
+ break;
+ case ' ':
+ Animate = !Animate;
+ if (Animate)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 27:
+ exit(0);
+ break;
+ }
+ printf("LineWidth, PointSize = %f\n", LineWidth);
+ glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+ float step = 3.0;
+ (void) x;
+ (void) y;
+
+ switch (key) {
+ case GLUT_KEY_UP:
+ Xrot += step;
+ break;
+ case GLUT_KEY_DOWN:
+ Xrot -= step;
+ break;
+ case GLUT_KEY_LEFT:
+ Yrot += step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Yrot -= step;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void Init( int argc, char *argv[] )
+{
+ GLuint u;
+ for (u = 0; u < 2; u++) {
+ glActiveTextureARB(GL_TEXTURE0_ARB + u);
+ glBindTexture(GL_TEXTURE_2D, 10+u);
+ if (u == 0)
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ if (u == 0)
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ else
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
+ printf("Error: couldn't load texture image\n");
+ exit(1);
+ }
+ }
+
+ glLineStipple(1, 0xff);
+
+ if (argc > 1 && strcmp(argv[1], "-info")==0) {
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+ printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+ }
+}
+
+
+int main( int argc, char *argv[] )
+{
+ glutInit( &argc, argv );
+ glutInitWindowSize( 400, 300 );
+
+ glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+
+ glutCreateWindow(argv[0] );
+
+ Init(argc, argv);
+
+ glutReshapeFunc( Reshape );
+ glutKeyboardFunc( Key );
+ glutSpecialFunc( SpecialKey );
+ glutDisplayFunc( Display );
+ if (Animate)
+ glutIdleFunc( Idle );
+
+ glutMainLoop();
+ return 0;
+}