aboutsummaryrefslogtreecommitdiffstats
path: root/sgiglblink.c
diff options
context:
space:
mode:
Diffstat (limited to 'sgiglblink.c')
-rw-r--r--sgiglblink.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/sgiglblink.c b/sgiglblink.c
new file mode 100644
index 0000000..63f5492
--- /dev/null
+++ b/sgiglblink.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright 1997-2002 - Harold Zatz <hzatz@alumni.caltech.edu>
+ *
+ * This file is part of datalink.
+ *
+ * Datalink is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Datalink is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with datalink (see COPYING); if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+ * sgiglblink: SGI / Open GL program from writing to Timex datalink watches
+ * Note the Open GL implimentation must support switching the buffers durring
+ * the vertical retrace. This program is SGI specific in the way it selects a
+ * 60Hz screen refresh. Alternate code just doesn't exist.
+ */
+
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <signal.h>
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+struct packet
+{
+ char *data;
+ unsigned char size;
+ struct packet *next;
+};
+
+static int attribList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
+
+Display *display;
+Window window;
+int width;
+int height;
+
+#define SPACE 28
+
+send(int sync0, unsigned char b0, int sync1, unsigned char b1)
+{
+ unsigned int mask = 1, scanline = 150;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_LINES);
+
+ if (sync0)
+ {
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ } else
+ scanline += 2;
+
+ scanline += SPACE;
+
+ while (mask != 256)
+ {
+ if (!(b0 & mask))
+ {
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ } else
+ scanline += 2;
+
+ mask <<= 1;
+ scanline += SPACE;
+ }
+
+ mask = 1;
+ scanline = 598;
+
+ if (sync1)
+ {
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ } else
+ scanline += 2;
+
+ scanline += SPACE;
+
+ while (mask != 256)
+ {
+ if (!(b1 & mask))
+ {
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ glVertex2d(0, height - scanline);
+ glVertex2d(width - 1, height - scanline++);
+ } else
+ scanline += 2;
+
+ mask <<= 1;
+ scanline += SPACE;
+ }
+
+ glEnd();
+
+ glXSwapBuffers(display, window);
+}
+
+main(int argc, char **argv)
+{
+ int fd, status, i;
+ unsigned char size;
+ struct packet *last = 0, *cur, *first = 0;
+ XVisualInfo *visualInfo;
+ XEvent event;
+ XSetWindowAttributes attribs;
+ GLXContext context;
+
+ /* Check proper number of args. */
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: %s data_file\n", argv[0]);
+ exit(-1);
+ }
+
+ /* Open the data file. */
+ if ((fd = open(argv[1], O_RDONLY)) == -1)
+ {
+ fprintf(stderr, "Could not open %s for reading.\n",
+ argv[1]);
+ exit(-1);
+ }
+
+ /* Build some packets. */
+ while (status = read(fd, &size, 1) == 1)
+ {
+ cur = (struct packet *) malloc(sizeof(struct packet));
+
+ if (cur == 0)
+ {
+ fprintf(stderr,
+ "Could not allocate packet memory.\n");
+ exit(-1);
+ }
+
+ cur->data = (char *) malloc(size);
+ cur->data[0] = size;
+ if (read(fd, cur->data + 1, size - 1) != size - 1)
+ {
+ fprintf(stderr, "Could not read packet data.\n");
+ exit(-1);
+ }
+
+ if (cur == 0)
+ {
+ fprintf(stderr,
+ "Could not allocate packet data memory.\n");
+ exit(-1);
+ }
+
+ cur->size = size;
+ cur->next = 0;
+
+ if (last)
+ last->next = cur;
+ else
+ first = cur;
+
+ last = cur;
+ }
+
+ if (status != 0)
+ {
+ fprintf(stderr, "File error reading from %s.\n", argv[1]);
+ exit(-1);
+ }
+
+ close(fd);
+
+ /* Build a window. */
+ display = XOpenDisplay(0);
+ if (!display)
+ {
+ fprintf(stderr, "Can't open display\n");
+ exit(-1);
+ }
+
+ /* Set the monitor to a 60 Hz scanrate. */
+ system("/usr/gfx/setmon -n 60HZ");
+
+ /* Get a visual. */
+ visualInfo = glXChooseVisual(display, 0, attribList);
+
+ /* Get a colormap for that visual. */
+ attribs.colormap = XCreateColormap(display,
+ DefaultRootWindow(display),
+ visualInfo->visual, AllocNone);
+
+ /* We want no borders. */
+ attribs.border_pixel = 0;
+
+ /* We don't want the window manager mucking with us. */
+ attribs.override_redirect = 1;
+
+ width = XDisplayWidth(display, 0);
+ height = XDisplayHeight(display, 0);
+
+ /* Build a window filling the display in that visual. */
+ window = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, width, height, 0,
+ visualInfo->depth, InputOutput,
+ visualInfo->visual,
+ CWBorderPixel | CWColormap |
+ CWOverrideRedirect, &attribs);
+
+ /* Build a gl context. */
+ context = glXCreateContext(display, visualInfo, 0, True);
+ glXMakeCurrent(display, window, context);
+ glOrtho(0, width - 1, 0, height - 1, 0, 1);
+
+ /* Map and raise the window. */
+ XMapRaised(display, window);
+ XFlush(display);
+
+ /* Send sync stuff... */
+ for (i = 0; i < 400; i++)
+ send(1, 0x55, 1, 0x55);
+
+ for (i = 0; i < 10; i++)
+ send(0, 0xff, 0, 0xff);
+
+ for (i = 0; i < 50; i++)
+ send(1, 0xaa, 0, 0xff);
+
+ for (i = 0; i < 10; i++)
+ send(0, 0xff, 0, 0xff);
+
+ /* Send the packets. */
+ for (cur = first; cur; cur = cur->next)
+ {
+ for (i = 0; i < cur->size; i += 2)
+ if (i - 1 == cur->size)
+ send(1, cur->data[i], 0, 0xff);
+ else
+ send(1, cur->data[i], 1, cur->data[i + 1]);
+
+ for (i = 0; i < 10; i++)
+ send(0, 0xff, 0, 0xff);
+ }
+
+ /* Set the monitor back to a 72 Hz scanrate. */
+ system("/usr/gfx/setmon -n 72HZ");
+}