--- a/GLXWorkstation.st Sun Jun 04 18:38:31 1995 +0200
+++ b/GLXWorkstation.st Tue Jun 06 06:09:07 1995 +0200
@@ -21,7 +21,7 @@
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.20 1995-05-03 00:03:20 claus Exp $
+$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.21 1995-06-06 04:07:06 claus Exp $
'!
!GLXWorkstation class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
version
"
-$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.20 1995-05-03 00:03:20 claus Exp $
+$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.21 1995-06-06 04:07:06 claus Exp $
"
!
@@ -140,12 +140,14 @@
GLXrgbDoubleBuffer
} GLXWindowType;
+/*
extern Window GLXCreateWindow();
+*/
#ifdef THISCONTEXT_IN_REGISTER
extern OBJ __thisContext__;
-# define ENTERGLX __thisContext__ = __thisContext
-# define LEAVEGLX __thisContext__ = 0;
+# define ENTERGLX __thisContext__ = __thisContext
+# define LEAVEGLX __thisContext__ = 0;
#else
# define ENTERGLX /* nothing */
# define LEAVEGLX /* nothing */
@@ -293,6 +295,295 @@
!GLXWorkstation primitiveFunctions!
%{
+
+/*
+ * begin moved from GLXsupport.c
+ */
+
+/*
+ * GLXsupport.c:
+ *
+ * This file provides a helper function "GLXCreateWindow", which does
+ * all the necessary magic to create an X window suitable for GL drawing
+ * to take place within. see the definition of GLXCreateWindow for a
+ * description of how to call it.
+ *
+ * claus: I really had no time to look into all this,
+ * this file has been just copied from a 4Dgifts demo ..
+ * (will need more than a day to show more ...)
+ */
+#if defined(GLX) || defined(VGL)
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifndef VGL
+# include <gl/glws.h>
+#endif
+#include <signal.h>
+#include <setjmp.h>
+#include "stcIntern.h"
+
+/*
+ * glxhelper.h:
+ *
+ * List of drawing modes supported by GLXCreateWindow (in glxhelper.c).
+ * More than this are possible with mixed model, but this is just an
+ * example. You can either expand this list (and the corresponding code in
+ * GLXCreateWindow) or call the mixed model calls yourself, using
+ * GLXCreateWindow as an example.
+ */
+
+static char *typeToName[] = {
+ "color index single buffer",
+ "color index double buffer",
+ "rgb single buffer",
+ "rgb double buffer",
+};
+
+#ifndef VGL
+/*
+ * Dorky little helper function used to build up a GLXconfig array.
+ */
+
+static void set_entry (GLXconfig* ptr, int b, int m, int a)
+{
+ ptr->buffer = b;
+ ptr->mode = m;
+ ptr->arg = a;
+}
+#endif /* VGL */
+
+static JMP_BUF errorReturn;
+
+static void
+glAbort() {
+ longjmp(errorReturn, 1);
+}
+
+/*
+ * GLXCreateWindow(dpy, parent, x, y, w, h, boderWidth, type)
+ *
+ * Return value is the X window id of the newly created window.
+ *
+ * Arguments are:
+ * dpy The X "Display*" returned by XOpenDisplay
+ * parent The parent of the newly created window,
+ * a typical value for this is
+ * RootWindow(dpy, DefaultScreen(dpy))
+ * x,y The location of the window to be created,
+ * y coordinate is measured from the top down.
+ * w,h size of the new window
+ * borderWidth the X border size for this window, should probably
+ * be zero.
+ * type the GLXWindowType (see glxhelper.h) desribing the
+ * typer of GL drawing to be done in this window
+ */
+static Window
+GLXCreateWindow(dpy, parent, x, y, w, h, borderWidth, type)
+ Display* dpy;
+ Window parent;
+ GLXWindowType type;
+{
+#ifdef VGL
+ Visual visual;
+#else
+ GLXconfig params[50];
+ GLXconfig* next;
+ GLXconfig* retconfig;
+ Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy));
+ XVisualInfo *vis;
+#endif
+ XVisualInfo template;
+ XColor white;
+ XSetWindowAttributes cwa;
+ XWindowAttributes pwa;
+ int scr, i, nret;
+ Window win;
+ extern __XErrorHandler__();
+#ifdef IRIX5
+ SIG_PF oldSig;
+#else
+ void *oldSig;
+#endif
+
+ if (setjmp(errorReturn)) {
+ printf("hard error in GL - return\n");
+ signal(SIGSEGV, oldSig);
+ return 0;
+ }
+ __CONT__
+
+#ifdef VGL
+ /*
+ * I know what VGL supports; its somewhat unclean to hard code it here
+ */
+ switch (type) {
+ case GLXcolorIndexSingleBuffer:
+ case GLXcolorIndexDoubleBuffer:
+ break;
+
+ case GLXrgbSingleBuffer:
+ case GLXrgbDoubleBuffer:
+ printf("Sorry, VGL can't support %s type of windows\n", typeToName[type]);
+ return 0;
+ }
+
+ scr = DefaultScreen(dpy);
+ visual.visualid = CopyFromParent;
+ cwa.border_pixel = 0; /* Even if we don't use it, it must be something */
+ if (w <= 0) {
+ printf("VGL: bad width: %d\n", w);
+ w = 1;
+ }
+ if (h <= 0) {
+ printf("VGL: bad height: %d\n", h);
+ h = 1;
+ }
+ win = XCreateWindow(dpy, parent, x, y, w, h,
+ borderWidth, DisplayPlanes(dpy, scr),
+ InputOutput, &visual,
+ CWBorderPixel, &cwa);
+
+ /*
+ * on iris, seg-violations occur in te GL, if too many
+ * views are created ... just to make certain, we catch those
+ * in GL too.
+ */
+ oldSig = signal(SIGSEGV, glAbort);
+ i = GLXlink(dpy, win);
+ signal(SIGSEGV, oldSig);
+
+ if (i < 0) {
+ printf("GLXlink returned %d\n", i);
+ return 0;
+ }
+#else /* not VGL */
+ /*
+ * This builds an array in "params" that describes for GLXgetconfig(3G)
+ * the type of GL drawing that will be done.
+ */
+ next = params;
+ switch (type) {
+ case GLXcolorIndexSingleBuffer:
+ set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE);
+ set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
+ break;
+ case GLXcolorIndexDoubleBuffer:
+ set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE);
+ set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
+ break;
+ case GLXrgbSingleBuffer:
+ set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE);
+ set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
+ break;
+ case GLXrgbDoubleBuffer:
+ set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE);
+ set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
+ break;
+ }
+ set_entry(next, 0, 0, 0); /* The input to GLXgetconfig is null terminated */
+
+ /*
+ * Get configuration data for a window based on above parameters
+ * First we have to find out which screen the parent window is on,
+ * then we can call GXLgetconfig()
+ */
+ XGetWindowAttributes(dpy, parent, &pwa);
+ retconfig = GLXgetconfig(dpy, XScreenNumberOfScreen(pwa.screen), params);
+ if (retconfig == 0) {
+ printf("Sorry, can't support %s type of windows\n", typeToName[type]);
+ return 0;
+ }
+
+ /*
+ * Scan through config info, pulling info needed to create a window
+ * that supports the rendering mode.
+ */
+ for (next = retconfig; next->buffer; next++) {
+ unsigned long buffer = next->buffer;
+ unsigned long mode = next->mode;
+ unsigned long value = next->arg;
+ switch (mode) {
+ case GLX_COLORMAP:
+ if (buffer == GLX_NORMAL) {
+ cmap = value;
+ }
+ break;
+ case GLX_VISUAL:
+ if (buffer == GLX_NORMAL) {
+ template.visualid = value;
+ template.screen = DefaultScreen(dpy);
+ vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
+ &template, &nret);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Create the window
+ */
+ cwa.colormap = cmap;
+ cwa.border_pixel = 0; /* Even if we don't use it, it must be something */
+ win = XCreateWindow(dpy, parent, x, y, w, h,
+ borderWidth, vis->depth, InputOutput, vis->visual,
+ CWColormap|CWBorderPixel, &cwa);
+
+ /*
+ * Rescan configuration info and find window slot that getconfig
+ * provided. Fill it in with the window we just created.
+ */
+ for (next = retconfig; next->buffer; next++) {
+ if ((next->buffer == GLX_NORMAL) && (next->mode == GLX_WINDOW)) {
+ next->arg = win;
+ break;
+ }
+ }
+
+ /*
+ * Now "retconfig" contains all the information the GL needs to
+ * configure the window and its own internal state.
+ */
+ /*
+ * on iris, seg-violations occur in te GL, if too many
+ * views are created ...
+ */
+ oldSig = signal(SIGSEGV, glAbort);
+ i = GLXlink(dpy, retconfig);
+ signal(SIGSEGV, oldSig);
+
+ if (i < 0) {
+ printf("GLXlink returned %d\n", i);
+ return 0;
+ }
+
+ /*
+ * The GL sets its own X error handlers, which exits - this is not what we want
+ */
+ XSetErrorHandler(__XErrorHandler__);
+#endif
+ return win;
+}
+
+static
+GLXUnlinkWindow(dpy, win)
+ Display* dpy;
+ Window win;
+{
+ /*
+ * only needed for VGL - GLX does it automatically
+ */
+#ifdef VGL
+ GLXunlink(dpy, win);
+#endif
+}
+
+#endif /* GLX or VGL */
+
+/*
+ * end moved from GLXsupport.c
+ */
+
/*
* helper for rotation - call rot()
*/