GLXWorkstation.st
changeset 151 8123ec03c52f
parent 134 1a09a1d7d28d
child 157 891eff44c2e7
equal deleted inserted replaced
150:5d0b9d669832 151:8123ec03c52f
    19 
    19 
    20 GLXWorkstation comment:'
    20 GLXWorkstation comment:'
    21 COPYRIGHT (c) 1993 by Claus Gittinger
    21 COPYRIGHT (c) 1993 by Claus Gittinger
    22 	      All Rights Reserved
    22 	      All Rights Reserved
    23 
    23 
    24 $Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.20 1995-05-03 00:03:20 claus Exp $
    24 $Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.21 1995-06-06 04:07:06 claus Exp $
    25 '!
    25 '!
    26 
    26 
    27 !GLXWorkstation class methodsFor:'documentation'!
    27 !GLXWorkstation class methodsFor:'documentation'!
    28 
    28 
    29 copyright
    29 copyright
    40 "
    40 "
    41 !
    41 !
    42 
    42 
    43 version
    43 version
    44 "
    44 "
    45 $Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.20 1995-05-03 00:03:20 claus Exp $
    45 $Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.21 1995-06-06 04:07:06 claus Exp $
    46 "
    46 "
    47 !
    47 !
    48 
    48 
    49 documentation
    49 documentation
    50 "
    50 "
   138     GLXcolorIndexDoubleBuffer,
   138     GLXcolorIndexDoubleBuffer,
   139     GLXrgbSingleBuffer,
   139     GLXrgbSingleBuffer,
   140     GLXrgbDoubleBuffer
   140     GLXrgbDoubleBuffer
   141 } GLXWindowType;
   141 } GLXWindowType;
   142 
   142 
       
   143 /*
   143 extern Window GLXCreateWindow();
   144 extern Window GLXCreateWindow();
       
   145 */
   144 
   146 
   145 #ifdef THISCONTEXT_IN_REGISTER
   147 #ifdef THISCONTEXT_IN_REGISTER
   146   extern OBJ __thisContext__;
   148   extern OBJ __thisContext__;
   147 # define ENTERGLX	__thisContext__ = __thisContext
   149 # define ENTERGLX       __thisContext__ = __thisContext
   148 # define LEAVEGLX	__thisContext__ = 0;
   150 # define LEAVEGLX       __thisContext__ = 0;
   149 #else
   151 #else
   150 # define ENTERGLX    /* nothing */
   152 # define ENTERGLX    /* nothing */
   151 # define LEAVEGLX     /* nothing */
   153 # define LEAVEGLX     /* nothing */
   152 #endif
   154 #endif
   153 
   155 
   291 ! !
   293 ! !
   292 
   294 
   293 !GLXWorkstation primitiveFunctions!
   295 !GLXWorkstation primitiveFunctions!
   294 
   296 
   295 %{
   297 %{
       
   298 
       
   299 /* 
       
   300  * begin moved from GLXsupport.c
       
   301  */
       
   302 
       
   303 /*
       
   304  * GLXsupport.c:
       
   305  *
       
   306  *   This file provides a helper function "GLXCreateWindow", which does
       
   307  * all the necessary magic to create an X window suitable for GL drawing 
       
   308  * to take place within.   see the definition of GLXCreateWindow for a 
       
   309  * description of how to call it.
       
   310  *
       
   311  * claus: I really had no time to look into all this,
       
   312  * this file has been just copied from a 4Dgifts demo ..
       
   313  * (will need more than a day to show more ...)
       
   314  */
       
   315 #if defined(GLX) || defined(VGL)
       
   316 
       
   317 #include        <X11/Xlib.h>
       
   318 #include        <X11/Xutil.h>
       
   319 #ifndef VGL
       
   320 # include        <gl/glws.h>  
       
   321 #endif
       
   322 #include        <signal.h>
       
   323 #include        <setjmp.h>
       
   324 #include        "stcIntern.h"
       
   325 
       
   326 /*
       
   327  * glxhelper.h:
       
   328  *
       
   329  *   List of drawing modes supported by GLXCreateWindow (in glxhelper.c).
       
   330  * More than this are possible with mixed model, but this is just an 
       
   331  * example.  You can either expand this list (and the corresponding code in 
       
   332  * GLXCreateWindow) or call the mixed model calls yourself, using 
       
   333  * GLXCreateWindow as an example.
       
   334  */
       
   335 
       
   336 static char *typeToName[] = {
       
   337     "color index single buffer",
       
   338     "color index double buffer",
       
   339     "rgb single buffer",
       
   340     "rgb double buffer",
       
   341 };
       
   342 
       
   343 #ifndef VGL
       
   344 /*
       
   345  * Dorky little helper function used to build up a GLXconfig array.
       
   346  */
       
   347 
       
   348 static void set_entry (GLXconfig* ptr, int b, int m, int a)
       
   349 {
       
   350     ptr->buffer = b;
       
   351     ptr->mode = m;
       
   352     ptr->arg = a;
       
   353 }
       
   354 #endif /* VGL */
       
   355 
       
   356 static JMP_BUF errorReturn;
       
   357 
       
   358 static void
       
   359 glAbort() {
       
   360     longjmp(errorReturn, 1);
       
   361 }
       
   362 
       
   363 /*
       
   364  * GLXCreateWindow(dpy, parent, x, y, w, h, boderWidth, type)
       
   365  *
       
   366  * Return value is the X window id of the newly created window.
       
   367  *
       
   368  * Arguments are:
       
   369  *      dpy             The X "Display*" returned by XOpenDisplay
       
   370  *      parent          The parent of the newly created window,
       
   371  *                      a typical value for this is
       
   372  *                      RootWindow(dpy, DefaultScreen(dpy))
       
   373  *      x,y             The location of the window to be created,
       
   374  *                      y coordinate is measured from the top down.
       
   375  *      w,h             size of the new window
       
   376  *      borderWidth     the X border size for this window, should probably
       
   377  *                      be zero.
       
   378  *      type            the GLXWindowType (see glxhelper.h) desribing the
       
   379  *                      typer of GL drawing to be done in this window
       
   380  */
       
   381 static Window 
       
   382 GLXCreateWindow(dpy, parent, x, y, w, h, borderWidth, type)
       
   383     Display* dpy;
       
   384     Window parent;
       
   385     GLXWindowType type;
       
   386 {
       
   387 #ifdef VGL
       
   388     Visual visual;
       
   389 #else
       
   390     GLXconfig params[50];
       
   391     GLXconfig* next;
       
   392     GLXconfig* retconfig;
       
   393     Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy));
       
   394     XVisualInfo *vis;
       
   395 #endif
       
   396     XVisualInfo template;
       
   397     XColor white;
       
   398     XSetWindowAttributes cwa;
       
   399     XWindowAttributes   pwa;
       
   400     int scr, i, nret;
       
   401     Window win;
       
   402     extern __XErrorHandler__();
       
   403 #ifdef IRIX5
       
   404     SIG_PF oldSig;
       
   405 #else
       
   406     void *oldSig;
       
   407 #endif
       
   408 
       
   409     if (setjmp(errorReturn)) {
       
   410 	printf("hard error in GL - return\n");
       
   411 	signal(SIGSEGV, oldSig);
       
   412 	return 0;
       
   413     }
       
   414     __CONT__
       
   415 
       
   416 #ifdef VGL
       
   417     /*
       
   418      * I know what VGL supports; its somewhat unclean to hard code it here
       
   419      */
       
   420     switch (type) {
       
   421       case GLXcolorIndexSingleBuffer:
       
   422       case GLXcolorIndexDoubleBuffer:
       
   423 	break;
       
   424 
       
   425       case GLXrgbSingleBuffer:
       
   426       case GLXrgbDoubleBuffer:
       
   427 	printf("Sorry, VGL can't support %s type of windows\n", typeToName[type]);
       
   428 	return 0;
       
   429     }
       
   430 
       
   431     scr = DefaultScreen(dpy);
       
   432     visual.visualid = CopyFromParent;
       
   433     cwa.border_pixel = 0;  /* Even if we don't use it, it must be something */
       
   434     if (w <= 0) {
       
   435 	printf("VGL: bad width: %d\n", w);
       
   436 	w = 1;
       
   437     }
       
   438     if (h <= 0) {
       
   439 	printf("VGL: bad height: %d\n", h);
       
   440 	h = 1;
       
   441     }
       
   442     win = XCreateWindow(dpy, parent, x, y, w, h,
       
   443 			     borderWidth, DisplayPlanes(dpy, scr), 
       
   444 			     InputOutput, &visual,
       
   445 			     CWBorderPixel, &cwa);
       
   446 
       
   447     /*
       
   448      * on iris, seg-violations occur in te GL, if too many
       
   449      * views are created ... just to make certain, we catch those
       
   450      * in GL too.
       
   451      */
       
   452     oldSig = signal(SIGSEGV, glAbort);
       
   453     i = GLXlink(dpy, win);
       
   454     signal(SIGSEGV, oldSig);
       
   455 
       
   456     if (i < 0) {
       
   457 	printf("GLXlink returned %d\n", i);
       
   458 	return 0;
       
   459     }
       
   460 #else /* not VGL */
       
   461     /*
       
   462      * This builds an array in "params" that describes for GLXgetconfig(3G)
       
   463      * the type of GL drawing that will be done.
       
   464      */
       
   465     next = params;
       
   466     switch (type) {
       
   467       case GLXcolorIndexSingleBuffer:
       
   468 	set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE);
       
   469 	set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
       
   470 	break;
       
   471       case GLXcolorIndexDoubleBuffer:
       
   472 	set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE);
       
   473 	set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
       
   474 	break;
       
   475       case GLXrgbSingleBuffer:
       
   476 	set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE);
       
   477 	set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
       
   478 	break;
       
   479       case GLXrgbDoubleBuffer:
       
   480 	set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE);
       
   481 	set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
       
   482 	break;
       
   483     }
       
   484     set_entry(next, 0, 0, 0); /* The input to GLXgetconfig is null terminated */
       
   485 
       
   486     /*
       
   487      * Get configuration data for a window based on above parameters
       
   488      * First we have to find out which screen the parent window is on,
       
   489      * then we can call GXLgetconfig()
       
   490      */
       
   491     XGetWindowAttributes(dpy, parent, &pwa);
       
   492     retconfig = GLXgetconfig(dpy, XScreenNumberOfScreen(pwa.screen), params);
       
   493     if (retconfig == 0) {
       
   494 	printf("Sorry, can't support %s type of windows\n", typeToName[type]);
       
   495 	return 0;
       
   496     }
       
   497 
       
   498     /*
       
   499      * Scan through config info, pulling info needed to create a window
       
   500      * that supports the rendering mode.
       
   501      */
       
   502     for (next = retconfig; next->buffer; next++) {
       
   503 	unsigned long buffer = next->buffer;
       
   504 	unsigned long mode = next->mode;
       
   505 	unsigned long value = next->arg;
       
   506 	switch (mode) {
       
   507 	  case GLX_COLORMAP:
       
   508 	    if (buffer == GLX_NORMAL) {
       
   509 		cmap = value;
       
   510 	    }
       
   511 	    break;
       
   512 	  case GLX_VISUAL:
       
   513 	    if (buffer == GLX_NORMAL) {
       
   514 		template.visualid = value;
       
   515 		template.screen = DefaultScreen(dpy);
       
   516 		vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
       
   517 					  &template, &nret);
       
   518 	    }
       
   519 	    break;
       
   520 	}
       
   521     }
       
   522 
       
   523     /*
       
   524      * Create the window
       
   525      */
       
   526     cwa.colormap = cmap;
       
   527     cwa.border_pixel = 0;  /* Even if we don't use it, it must be something */
       
   528     win = XCreateWindow(dpy, parent, x, y, w, h,
       
   529 			     borderWidth, vis->depth, InputOutput, vis->visual,
       
   530 			     CWColormap|CWBorderPixel, &cwa);
       
   531 
       
   532     /*
       
   533      * Rescan configuration info and find window slot that getconfig
       
   534      * provided.  Fill it in with the window we just created.
       
   535      */
       
   536     for (next = retconfig; next->buffer; next++) {
       
   537 	if ((next->buffer == GLX_NORMAL) && (next->mode == GLX_WINDOW)) {
       
   538 	    next->arg = win;
       
   539 	    break;
       
   540 	}
       
   541     }
       
   542 
       
   543     /*
       
   544      * Now "retconfig" contains all the information the GL needs to
       
   545      * configure the window and its own internal state.
       
   546      */
       
   547     /*
       
   548      * on iris, seg-violations occur in te GL, if too many
       
   549      * views are created ...
       
   550      */
       
   551     oldSig = signal(SIGSEGV, glAbort);
       
   552     i = GLXlink(dpy, retconfig);
       
   553     signal(SIGSEGV, oldSig);
       
   554 
       
   555     if (i < 0) {
       
   556 	printf("GLXlink returned %d\n", i);
       
   557 	return 0;
       
   558     }
       
   559 
       
   560     /*
       
   561      * The GL sets its own X error handlers, which exits - this is not what we want
       
   562      */
       
   563     XSetErrorHandler(__XErrorHandler__);
       
   564 #endif
       
   565     return win;
       
   566 }
       
   567 
       
   568 static
       
   569 GLXUnlinkWindow(dpy, win)
       
   570     Display* dpy;
       
   571     Window win;
       
   572 {
       
   573     /*
       
   574      * only needed for VGL - GLX does it automatically
       
   575      */
       
   576 #ifdef VGL
       
   577     GLXunlink(dpy, win);
       
   578 #endif
       
   579 }
       
   580 
       
   581 #endif /* GLX or VGL */
       
   582 
       
   583 /* 
       
   584  * end moved from GLXsupport.c
       
   585  */
       
   586 
   296 /*
   587 /*
   297  * helper for rotation - call rot()
   588  * helper for rotation - call rot()
   298  */
   589  */
   299 static OBJ
   590 static OBJ
   300 doRotate(angle, axis)
   591 doRotate(angle, axis)