*** empty log message ***
authorclaus
Sat, 08 Jan 1994 18:17:39 +0100
changeset 24 e810b1be068b
parent 23 4a7e02de7b72
child 25 125b89c0c366
*** empty log message ***
Form.st
GC.st
GLXWorkstat.st
GLXWorkstation.st
GraphicsContext.st
Image.st
Make.proto
NXWorkst.st
NeXTWorkstation.st
PseudoV.st
ResourcePack.st
RsrcPack.st
StandardSystemView.st
StdSysV.st
--- a/Form.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/Form.st	Sat Jan 08 18:17:39 1994 +0100
@@ -17,7 +17,7 @@
 
                            AdditionalBitmapDirectoryNames
                            BlackAndWhiteColorMap DitherPatterns
-                           lobby'
+                           Lobby'
        poolDictionaries:''
        category:'Graphics-Display Objects'
 !
@@ -27,7 +27,7 @@
 COPYRIGHT (c) 1989 by Claus Gittinger
               All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/Form.st,v 1.5 1993-12-11 01:28:44 claus Exp $
+$Header: /cvs/stx/stx/libview/Form.st,v 1.6 1994-01-08 17:15:36 claus Exp $
 written spring/summer 89 by claus
 '!
 
@@ -35,14 +35,14 @@
 
 initialize
     "initialize set of dictionaries to look for bitmaps
-     and lobby to keep track of dead forms"
+     and Lobby to keep track of dead forms"
 
     AdditionalBitmapDirectoryNames isNil ifTrue:[
         super initialize.
 
         AdditionalBitmapDirectoryNames := #('/usr/lib/X11/bitmaps').
     
-        lobby := Registry new.
+        Lobby := Registry new.
 
         "want to be informed when returning from snapshot"
         ObjectMemory addDependent:self.
@@ -53,11 +53,11 @@
     "recreate all forms on aDevice; called by Workstation, to
      have all background bitmaps at hand, when views are restored"
 
-    lobby contentsDo:[:aForm |
+    Lobby contentsDo:[:aForm |
         (aForm device == aDevice) ifTrue:[
             "now, try to recreate it"
             aForm recreate.
-            lobby changed:aForm
+            Lobby changed:aForm
         ]
     ]
 !
@@ -70,9 +70,9 @@
     ].
     (something == #restarted) ifTrue:[
         "remove all left-over device info"
-        lobby contentsDo:[:aForm |
+        Lobby contentsDo:[:aForm |
             aForm restored.
-            lobby changed:self
+            Lobby changed:self
         ]
     ]
 ! !
@@ -876,7 +876,7 @@
      (will fill up stream-queue on some stupid (i.e. sco) systems"
 
     super initGC.
-    lobby changed:self.
+    Lobby changed:self.
     self setGraphicsExposures:false
 !
 
@@ -910,7 +910,7 @@
 
     super readBinaryContentsFrom: stream manager: manager.
     self restored.
-    lobby register:self
+    Lobby register:self
 ! !
 
 !Form methodsFor:'inspecting'!
@@ -968,7 +968,7 @@
     ].
     localColorMap := BlackAndWhiteColorMap.
     realized := true.
-    lobby register:self
+    Lobby register:self
 !
 
 width:w height:h depth:d
@@ -981,7 +981,7 @@
     drawableId isNil ifTrue:[^ nil].
     realized := true.
     depth := d.
-    lobby register:self
+    Lobby register:self
 !
 
 width:w height:h fromArray:anArray
@@ -1032,7 +1032,7 @@
     ].
     localColorMap := BlackAndWhiteColorMap.
     realized := true.
-    lobby register:self
+    Lobby register:self
 !
 
 width:w height:h offset:offs fromArray:anArray
@@ -1059,7 +1059,7 @@
             BlackAndWhiteColorMap := Array with:(Color white) with:(Color black)
         ].
         localColorMap := BlackAndWhiteColorMap.
-        lobby register:self.
+        Lobby register:self.
         ^ self
     ].
     ^ nil
--- a/GC.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/GC.st	Sat Jan 08 18:17:39 1994 +0100
@@ -43,7 +43,7 @@
 implemented by subclasses (some subclasses also redefine the others for
 more performance)
 
-$Header: /cvs/stx/stx/libview/Attic/GC.st,v 1.5 1993-12-11 01:28:58 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/GC.st,v 1.6 1994-01-08 17:15:42 claus Exp $
 
 Instance variables:
 
@@ -525,9 +525,23 @@
 drawForm:aForm x:x y:y
     "draw a form at x/y; if the form has depth 1, 1's in the form are
      drawn in current fg, 0's are ignored.
-     If the form has depth ~~ 1, it is copied as is onto the receiver"
+     If the form has depth ~~ 1, the result is undefined"
+
+    |fg bg f|
+
+    fg := foreground.
+    bg := background.
+    f := function.
 
+    self foreground:(Color noColor) background:(Color allColor) function:#and.
+    self drawOpaqueForm:aForm x:x y:y.
+    self foreground:fg background:(Color noColor) function:#or.
+    self drawOpaqueForm:aForm x:x y:y.
+    self foreground:fg background:fg function:f.
+
+"
     ^ self subclassResponsibility
+"
 !
 
 drawOpaqueForm:aForm x:x y:y
@@ -576,16 +590,16 @@
     self displayString:aString x:aPoint x y:aPoint y
 !
 
-drawPointX:x y:y
+displayPointX:x y:y
     "draw a point at x/y"
 
     self displayLineFromX:x y:y toX:x y:y
 !
 
-drawPoint:aPoint
+displayPoint:aPoint
     "draw a pixel"
 
-    self drawPointX:(aPoint x) y:(aPoint y)
+    self displayPointX:(aPoint x) y:(aPoint y)
 !
 
 displayLineFrom:point1 to:point2
--- a/GLXWorkstat.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/GLXWorkstat.st	Sat Jan 08 18:17:39 1994 +0100
@@ -22,21 +22,27 @@
 COPYRIGHT (c) 1993 by Claus Gittinger
               All Rights Reserved
 
-this class just to give a hint of what could be ...
-
-$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.5 1993-12-19 23:42:20 claus Exp $
-written june 93 by claus
+$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.6 1994-01-08 17:16:42 claus Exp $
+written dec 93 by claus
 '!
 
 %{
-#ifdef GLX
-
+/*
+ * on SGI, this class is compiled with -DGLX, while
+ * for simulation, this is compiled with -DVGL
+ */
 /*
  * this is stupid, GLX defines String, which is also defined here ...
  */
-# define String GLX_String
+#define String GLX_String
+
+#ifdef GLX
 # include <gl/glws.h>
 # include <gl/sphere.h>
+#else
+# include <vogl.h>
+# include <X11/Xlib.h>
+#endif
 
 typedef enum {
     GLXcolorIndexSingleBuffer,
@@ -46,10 +52,9 @@
 } GLXWindowType;
 
 extern Window GLXCreateWindow(Display*,Window,int,int,int,int,int,GLXWindowType);
+
 #undef String
 
-#endif
-
 /*
  * some defines - tired of typing ...
  */
@@ -82,7 +87,14 @@
         dst = (float)(_floatVal(arg));  \
     else if (_isSmallInteger(arg))      \
         dst = (float)(_intVal(arg));    \
-    else break;
+    else if (_isFraction(arg)             \
+          && _isSmallInteger(_FractionInstPtr(arg)->f_numerator)      \
+          && _isSmallInteger(_FractionInstPtr(arg)->f_denominator)) { \
+        float n, d;                                                   \
+        n = (float)(_intVal(_FractionInstPtr(arg)->f_numerator));     \
+        d = (float)(_intVal(_FractionInstPtr(arg)->f_denominator));   \
+        dst = n / d;                                                  \
+    } else break;
 
 #define _ANGLE_(arg, dst)               \
     if (_isSmallInteger(arg))           \
@@ -94,6 +106,14 @@
         dst = (int)(_intVal(arg));      \
     else break;
 
+/*
+ * helper to fetch count floats from the object obj
+ * space is provided in vec.
+ * returns a pointer to the floats,
+ * which is obj itself, if it is a FloatArray
+ * the object may be a FloatArray, DoubleArray or an array of
+ * floats/smallintegers
+ */
 static float *
 getFloatsFromInto(obj, vec, count)
    OBJ obj;
@@ -115,11 +135,17 @@
 
     switch (_intVal(_ClassInstPtr(cls)->c_flags) & ARRAYMASK) {
       case FLOATARRAY:
-        /* best speed for float array - the data is already as we want it */
+        /* 
+         * best speed for float array 
+         * - the data is already as we want it 
+         */
         if (nByte < (count * sizeof(float))) return (float *)0;
         return (float *)pElem;
 
       case DOUBLEARRAY:
+        /*
+         * for double array, have to copy-and-cast
+         */
         if (nByte < (count * sizeof(double))) return (float *)0;
         for (i=0; i<count; i++) {
             vec[i] = *((double *)pElem);
@@ -128,13 +154,28 @@
         return vec;
 
       case POINTERARRAY:
+        /*
+         * for other array, have to fetch, check and store
+         * the elements can be floats, smallintegers or fractions
+         */
         if (nByte < (count * sizeof(OBJ))) return (float *)0;
         /* get elements one-by-one */
         for (i=0; i<count; i++) {
             o = *(OBJ *)pElem;
-            if (_isFloat(o)) vec[i] = _floatVal(o);
-            else if (_isSmallInteger(o)) vec[i] = (float)(_intVal(o));
-            else return 0;
+            if (_isFloat(o)) {
+                vec[i] = _floatVal(o);
+            } else if (_isSmallInteger(o)) {
+                vec[i] = (float)(_intVal(o));
+            } else if (_isFraction(o) 
+                    && _isSmallInteger(_FractionInstPtr(o)->f_numerator)
+                    && _isSmallInteger(_FractionInstPtr(o)->f_denominator)) {
+                float n, d;
+
+                n = (float)(_intVal(_FractionInstPtr(o)->f_numerator));
+                d = (float)(_intVal(_FractionInstPtr(o)->f_denominator));
+                vec[i] = n / d;
+            } else 
+                return 0;
             pElem += sizeof(OBJ);
         }
         return vec;
@@ -183,6 +224,9 @@
     return 0;
 }
 
+/*
+ * helper to fetch a matrix with 16 floats from an object
+ */
 static Matrix*
 getFloatsFromMatrixInto(obj, mp)
     OBJ obj;
@@ -229,8 +273,21 @@
         for (i=0; i<4; i++) {
             for (j=0; j<4; j++) {
                 o = _ArrayInstPtr(obj)->a_element[x];
-                if (! _isFloat(o)) return (Matrix *)0;
-                (*mp)[i][j] = _floatVal(o);
+                if (_isFloat(o)) {
+                    (*mp)[i][j] = _floatVal(o);
+                } else if (_isSmallInteger(o)) {
+                    (*mp)[i][j] = (float)(_intVal(o));
+                } else if (_isFraction(o) 
+                        && _isSmallInteger(_FractionInstPtr(o)->f_numerator)
+                        && _isSmallInteger(_FractionInstPtr(o)->f_denominator)) {
+                    float n, d;
+
+                    n = (float)(_intVal(_FractionInstPtr(o)->f_numerator));
+                    d = (float)(_intVal(_FractionInstPtr(o)->f_denominator));
+                    (*mp)[i][j] = n / d;
+                } else {
+                    return (Matrix *)0;
+                }
                 x++;
             }
         }
@@ -239,8 +296,60 @@
     return (Matrix *)0;
 }
 
+/*
+ * helper for rotation
+ */
+static OBJ
+doRotate(angle, axis)
+    OBJ angle;
+    char axis;
+{
+    Angle a_angle;
+    float f_angle;
+
+    if (_isFloat(angle)) {
+        f_angle = (float)(_floatVal(angle));
+        rot(f_angle, axis);
+        return (true);
+    }
+    if (_isFraction(angle)
+     && _isSmallInteger(_FractionInstPtr(angle)->f_numerator)
+     && _isSmallInteger(_FractionInstPtr(angle)->f_denominator)) {
+        float n, d;
+
+        n = (float)(_intVal(_FractionInstPtr(angle)->f_numerator));
+        d = (float)(_intVal(_FractionInstPtr(angle)->f_denominator));
+        f_angle = n / d;
+        rot(f_angle, axis);
+        return (true);
+    }
+    if (_isSmallInteger(angle)) {
+        a_angle = (Angle)(_intVal(angle));
+        rotate(a_angle, axis);
+        return (true);
+    }
+    return false;
+}
+
 %}
 
+!GLXWorkstation methodsFor:'queries'!
+
+supportsRGB
+    "return true, if this gl workstation supports rgb
+     (in addition to indexed) colors."
+
+%{  /* NOCONTEXT */
+
+#ifdef VGL
+    RETURN ( false );
+#endif
+#ifdef GLX
+    RETURN ( true );
+#endif
+%}
+! !
+
 !GLXWorkstation methodsFor:'window creation'!
 
 createGLXWindowFor:aView left:xpos top:ypos width:wwidth height:wheight type:glxType
@@ -261,7 +370,6 @@
     ].
 
 %{
-#ifdef GLX
     Display *dpy = myDpy;
     int screen = _intVal(_INST(screen));
     Window newWindow, parentWindow;
@@ -299,7 +407,6 @@
 
         windowId = MKOBJ(newWindow);
     }
-#endif
 %}
 .
     windowId notNil ifTrue:[
@@ -316,22 +423,13 @@
 %}
 ! !
 
-!GLXWorkstation methodsFor:'queries'!
-
-supportsRGB
-    ^ true
-! !
-
 !GLXWorkstation methodsFor:'glx access'!
 
-glxPerspectiveFovy:fovy aspect:aspect 
-              near:near far:far
-                in:aGLXWindowId
+glxPerspectiveFovy:fovy aspect:aspect near:near far:far in:aGLXWindowId
     "define perspective projection"
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Angle a_fovy;
     Coord c_near, c_far;
     float f_aspect;
@@ -343,10 +441,31 @@
         _COORD_ (far, c_far);
         SETWIN(aGLXWindowId)
         perspective(a_fovy, f_aspect, c_near, c_far);
+        RETURN (true);
+    } while(0);
+%}
+.
+    ^ false
+!
+
+glxWindowLeft:left right:right top:top bottom:bottom near:near far:far in:aGLXWindowId
+    "define perspective viewing pyramid"
+
+%{  /* NOCONTEXT */
+    Coord c_left, c_right, c_top, c_bot, c_near, c_far;
+
+    do {
+        _COORD_ (left, c_left);
+        _COORD_ (right, c_right);
+        _COORD_ (top, c_top);
+        _COORD_ (bottom, c_bot);
+        _COORD_ (near, c_near);
+        _COORD_ (far, c_far);
+        SETWIN(aGLXWindowId)
+        window(c_left, c_right, c_bot, c_top, c_near, c_far);
 
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -357,7 +476,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Coord c_x, c_y, c_z;
 
     do {
@@ -368,7 +486,6 @@
         translate(c_x, c_y, c_z);
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -379,7 +496,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     float f_x, f_y, f_z;
 
     do {
@@ -390,7 +506,42 @@
         scale(f_x, f_y, f_z);
         RETURN (true);
     } while(0);
-#endif
+%}
+.
+    ^ false
+!
+
+glxRotateX:angle in:aGLXWindowId
+    "rotate the current matrix on x axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'x'));
+%}
+.
+    ^ false
+!
+
+glxRotateY:angle in:aGLXWindowId
+    "rotate the current matrix on y axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'y'));
+%}
+.
+    ^ false
+!
+
+glxRotateZ:angle in:aGLXWindowId
+    "rotate the current matrix on z axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'z'));
 %}
 .
     ^ false
@@ -405,9 +556,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
-    Angle a_angle;
-    float f_angle;
     char c_axis;
 
     do {
@@ -420,33 +568,34 @@
         else break;
 
         SETWIN(aGLXWindowId)
-        if (_isFloat(angle)) {
-            f_angle = (float)(_floatVal(angle));
-            rot(f_angle, c_axis);
-            RETURN (true);
-        } else {
-            if (_isSmallInteger(angle)) {
-                a_angle = (Angle)(_intVal(angle));
-                rotate(a_angle, c_axis);
-                RETURN (true);
-            }
-        }
+        RETURN ( doRotate(angle, c_axis) );
     } while(0);
-#endif
 %}
 .
     ^ false
 !
 
-glxLookatVx:vx vy:vy vz:vz 
-         px:px py:py pz:pz 
-      twist:twist
-         in:aGLXWindowId
+glxRotateX:xAngle y:yAngle z:zAngle in:aGLXWindowId
+    "rotate the current matrix on all axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    if ( doRotate(xAngle, 'x') == true) {
+        if ( doRotate(yAngle, 'y') == true) {
+            RETURN (doRotate(zAngle, 'z'));
+        }
+    }
+%}
+.
+    ^ false
+!
+
+glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
     "define viewing transformation"
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
     Angle a_twist;
 
@@ -462,7 +611,6 @@
         lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -573,7 +721,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     SETWIN(aGLXWindowId)
     if (_isSmallInteger(index)) {
         color((Colorindex)(_intVal(index)));
@@ -583,7 +730,6 @@
         colorf((float)(_floatVal(index)));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -593,7 +739,6 @@
     "set color, args must be integer values"
 
 %{  /* NOCONTEXT */
-
 #ifdef GLX
     short s_r, s_g, s_b;
 
@@ -615,11 +760,9 @@
     "clear to current color"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     clear();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -643,11 +786,9 @@
     "push down transformation stack"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     pushmatrix();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -657,11 +798,9 @@
     "pop transformation stack"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     popmatrix();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -671,11 +810,39 @@
     "swap double buffers"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     swapbuffers();
     RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxFrontBufferIn:aGLXWindowId
+    "switch to front buffer"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    backbuffer(FALSE);
 #endif
+    frontbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackBufferIn:aGLXWindowId
+    "switch to back buffer"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    frontbuffer(FALSE);
+#endif
+    backbuffer(TRUE);
+    RETURN (true);
 %}
 .
     ^ false
@@ -699,11 +866,9 @@
     "set double buffer mode"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     doublebuffer();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -714,11 +879,9 @@
      changes really take effect. See GLX manual"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     gconfig();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -738,15 +901,13 @@
     ^ false
 !
 
-glxBackface:aBoolean in:aGLXWindowId
+glxBackFace:aBoolean in:aGLXWindowId
     "enable/disable backface"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
+    SETWIN(aGLXWindowId)                                     
     backface(aBoolean == false ? FALSE : TRUE);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -810,11 +971,9 @@
     "start a polygon"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnpolygon();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -824,11 +983,9 @@
     "end a polygon"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endpolygon();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -838,11 +995,9 @@
     "start a point-group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnpoint();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -852,25 +1007,21 @@
     "end a point group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endpoint();
     RETURN (true);
-#endif
 %}
 .
     ^ false
 !
 
-glxBeginCloseLineIn:aGLXWindowId
+glxBeginClosedLineIn:aGLXWindowId
     "start a closed line"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnclosedline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -880,11 +1031,9 @@
     "end a closed line"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endclosedline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -894,11 +1043,9 @@
     "start a line group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -908,11 +1055,9 @@
     "end a line group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -922,11 +1067,9 @@
     "start a triangle mesh"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgntmesh();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -936,11 +1079,9 @@
     "end a triangle mesh"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endtmesh();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -978,11 +1119,9 @@
     "start a quadrilateral strip"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnqstrip();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -992,11 +1131,9 @@
     "end a quadrilateral strip"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endqstrip();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1030,6 +1167,97 @@
     ^ false
 !
 
+glxMoveX:x y:y z:z in:aGLXWindowId
+    "arguments must specify a point"
+
+%{  /* NOCONTEXT */
+    if (_isFloat(x) && _isFloat(y) && _isFloat(z)) {
+        SETWIN(aGLXWindowId)                                     
+        move( (float)_floatVal(x), (float)_floatVal(y), (float)_floatVal(z) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxMove:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the point"
+
+%{  /* NOCONTEXT */
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    move( v[0], v[1], v[2] );
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxDrawX:x y:y z:z in:aGLXWindowId
+    "arguments must specify a point"
+
+%{  /* NOCONTEXT */
+
+    if (_isFloat(x) && _isFloat(y) && _isFloat(z)) {
+        SETWIN(aGLXWindowId)                                     
+        draw( (float)_floatVal(x), (float)_floatVal(y), (float)_floatVal(z) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxDraw:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the point"
+
+%{  /* NOCONTEXT */
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    draw( v[0], v[1], v[2]);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxRectX1:x1 y1:y1 x2:x2 y2:y2 in:aGLXWindowId
+    "arguments must specify 2 opposite corners of the rectangle"
+
+%{  /* NOCONTEXT */
+    float f_x1, f_x2, f_y1, f_y2;
+
+    if (_isFloat(x1) && _isFloat(x2) && _isFloat(y1) && _isFloat(y2)) {
+        SETWIN(aGLXWindowId)                                     
+        rect( (float)_floatVal(x1), (float)_floatVal(y1), (float)_floatVal(x2), (float)_floatVal(y2) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRectFX1:x1 y1:y1 x2:x2 y2:y2 in:aGLXWindowId
+    "arguments must specify 2 opposite corners of the filled rectangle"
+
+%{  /* NOCONTEXT */
+    float f_x1, f_x2, f_y1, f_y2;
+
+    if (_isFloat(x1) && _isFloat(x2) && _isFloat(y1) && _isFloat(y2)) {
+        SETWIN(aGLXWindowId)                                     
+        rectf( (float)_floatVal(x1), (float)_floatVal(y1), (float)_floatVal(x2), (float)_floatVal(y2) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
 glxSphDraw:arrayOf4Floats in:aGLXWindowId
     "argument must be an array(a matrix) of 4 floats containing the
      sphere"
@@ -1050,8 +1278,8 @@
 
 glxDefBasis:id mat:aMatrix in:aGLXWindowId
     "define the basis"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1061,7 +1289,6 @@
         defbasis((short)(_intVal(id)), *m);
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1069,14 +1296,13 @@
 
 glxPatchCurvesU:u v:v in:aGLXWindowId
     "set the number of curves in a patch"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchcurves((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1084,14 +1310,13 @@
 
 glxPatchPrecisionU:u v:v in:aGLXWindowId
     "set the patch precision"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchprecision((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1099,14 +1324,13 @@
 
 glxPatchBasisU:u v:v in:aGLXWindowId
     "set the current basis matrices"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchbasis((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1116,7 +1340,6 @@
     "arguments must be arrays of 16 floats containing the patch"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrixX, matrixY, matrixZ;
     Matrix *mX, *mY, *mZ;
 
@@ -1126,7 +1349,6 @@
     SETWIN(aGLXWindowId)
     patch(*mX, *mY, *mZ);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1137,14 +1359,12 @@
      matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
 
     SETWIN(aGLXWindowId)
     getmatrix(matrix);
     if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1155,7 +1375,6 @@
      transformation matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1163,7 +1382,6 @@
     SETWIN(aGLXWindowId)
     loadmatrix(*m);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1174,7 +1392,6 @@
      matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1182,15 +1399,57 @@
     SETWIN(aGLXWindowId)
     multmatrix(*m);
     RETURN (true);
-#endif
+%}
+.
+    ^ false
+!
+
+glxMakeObject:id in:aGLXWindowId
+    "start object definition"
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(id)) {
+        SETWIN(aGLXWindowId)
+        makeobj(_intVal(id));
+        RETURN (true);
+    }
 %}
 .
     ^ false
 !
 
+glxCloseObjectIn:aGLXWindowId
+    "end object defnition"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    closeobj();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxCallObject:id in:aGLXWindowId
+    "do objects definition"
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(id)) {
+        SETWIN(aGLXWindowId)
+        callobj(_intVal(id));
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+ 
 glxN3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the
-     current vertex normal"
+    "argument must be an indexable object with 3 floats,
+     containing the current vertex normal"
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -1207,7 +1466,8 @@
 !
 
 glxC3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the color"
+    "argument must be an indexable object with 3 floats,
+     containing the color"
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -1224,17 +1484,16 @@
 !
 
 glxV3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the vertex"
+    "argument must be an indexable object with 3 floats,
+     containing the vertex"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     float vec[3], *v;
 
     if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
     SETWIN(aGLXWindowId)
     v3f(v);
     RETURN (true);
-#endif
 %}
 .
     ^ false
--- a/GLXWorkstation.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/GLXWorkstation.st	Sat Jan 08 18:17:39 1994 +0100
@@ -22,21 +22,27 @@
 COPYRIGHT (c) 1993 by Claus Gittinger
               All Rights Reserved
 
-this class just to give a hint of what could be ...
-
-$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.5 1993-12-19 23:42:20 claus Exp $
-written june 93 by claus
+$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.6 1994-01-08 17:16:42 claus Exp $
+written dec 93 by claus
 '!
 
 %{
-#ifdef GLX
-
+/*
+ * on SGI, this class is compiled with -DGLX, while
+ * for simulation, this is compiled with -DVGL
+ */
 /*
  * this is stupid, GLX defines String, which is also defined here ...
  */
-# define String GLX_String
+#define String GLX_String
+
+#ifdef GLX
 # include <gl/glws.h>
 # include <gl/sphere.h>
+#else
+# include <vogl.h>
+# include <X11/Xlib.h>
+#endif
 
 typedef enum {
     GLXcolorIndexSingleBuffer,
@@ -46,10 +52,9 @@
 } GLXWindowType;
 
 extern Window GLXCreateWindow(Display*,Window,int,int,int,int,int,GLXWindowType);
+
 #undef String
 
-#endif
-
 /*
  * some defines - tired of typing ...
  */
@@ -82,7 +87,14 @@
         dst = (float)(_floatVal(arg));  \
     else if (_isSmallInteger(arg))      \
         dst = (float)(_intVal(arg));    \
-    else break;
+    else if (_isFraction(arg)             \
+          && _isSmallInteger(_FractionInstPtr(arg)->f_numerator)      \
+          && _isSmallInteger(_FractionInstPtr(arg)->f_denominator)) { \
+        float n, d;                                                   \
+        n = (float)(_intVal(_FractionInstPtr(arg)->f_numerator));     \
+        d = (float)(_intVal(_FractionInstPtr(arg)->f_denominator));   \
+        dst = n / d;                                                  \
+    } else break;
 
 #define _ANGLE_(arg, dst)               \
     if (_isSmallInteger(arg))           \
@@ -94,6 +106,14 @@
         dst = (int)(_intVal(arg));      \
     else break;
 
+/*
+ * helper to fetch count floats from the object obj
+ * space is provided in vec.
+ * returns a pointer to the floats,
+ * which is obj itself, if it is a FloatArray
+ * the object may be a FloatArray, DoubleArray or an array of
+ * floats/smallintegers
+ */
 static float *
 getFloatsFromInto(obj, vec, count)
    OBJ obj;
@@ -115,11 +135,17 @@
 
     switch (_intVal(_ClassInstPtr(cls)->c_flags) & ARRAYMASK) {
       case FLOATARRAY:
-        /* best speed for float array - the data is already as we want it */
+        /* 
+         * best speed for float array 
+         * - the data is already as we want it 
+         */
         if (nByte < (count * sizeof(float))) return (float *)0;
         return (float *)pElem;
 
       case DOUBLEARRAY:
+        /*
+         * for double array, have to copy-and-cast
+         */
         if (nByte < (count * sizeof(double))) return (float *)0;
         for (i=0; i<count; i++) {
             vec[i] = *((double *)pElem);
@@ -128,13 +154,28 @@
         return vec;
 
       case POINTERARRAY:
+        /*
+         * for other array, have to fetch, check and store
+         * the elements can be floats, smallintegers or fractions
+         */
         if (nByte < (count * sizeof(OBJ))) return (float *)0;
         /* get elements one-by-one */
         for (i=0; i<count; i++) {
             o = *(OBJ *)pElem;
-            if (_isFloat(o)) vec[i] = _floatVal(o);
-            else if (_isSmallInteger(o)) vec[i] = (float)(_intVal(o));
-            else return 0;
+            if (_isFloat(o)) {
+                vec[i] = _floatVal(o);
+            } else if (_isSmallInteger(o)) {
+                vec[i] = (float)(_intVal(o));
+            } else if (_isFraction(o) 
+                    && _isSmallInteger(_FractionInstPtr(o)->f_numerator)
+                    && _isSmallInteger(_FractionInstPtr(o)->f_denominator)) {
+                float n, d;
+
+                n = (float)(_intVal(_FractionInstPtr(o)->f_numerator));
+                d = (float)(_intVal(_FractionInstPtr(o)->f_denominator));
+                vec[i] = n / d;
+            } else 
+                return 0;
             pElem += sizeof(OBJ);
         }
         return vec;
@@ -183,6 +224,9 @@
     return 0;
 }
 
+/*
+ * helper to fetch a matrix with 16 floats from an object
+ */
 static Matrix*
 getFloatsFromMatrixInto(obj, mp)
     OBJ obj;
@@ -229,8 +273,21 @@
         for (i=0; i<4; i++) {
             for (j=0; j<4; j++) {
                 o = _ArrayInstPtr(obj)->a_element[x];
-                if (! _isFloat(o)) return (Matrix *)0;
-                (*mp)[i][j] = _floatVal(o);
+                if (_isFloat(o)) {
+                    (*mp)[i][j] = _floatVal(o);
+                } else if (_isSmallInteger(o)) {
+                    (*mp)[i][j] = (float)(_intVal(o));
+                } else if (_isFraction(o) 
+                        && _isSmallInteger(_FractionInstPtr(o)->f_numerator)
+                        && _isSmallInteger(_FractionInstPtr(o)->f_denominator)) {
+                    float n, d;
+
+                    n = (float)(_intVal(_FractionInstPtr(o)->f_numerator));
+                    d = (float)(_intVal(_FractionInstPtr(o)->f_denominator));
+                    (*mp)[i][j] = n / d;
+                } else {
+                    return (Matrix *)0;
+                }
                 x++;
             }
         }
@@ -239,8 +296,60 @@
     return (Matrix *)0;
 }
 
+/*
+ * helper for rotation
+ */
+static OBJ
+doRotate(angle, axis)
+    OBJ angle;
+    char axis;
+{
+    Angle a_angle;
+    float f_angle;
+
+    if (_isFloat(angle)) {
+        f_angle = (float)(_floatVal(angle));
+        rot(f_angle, axis);
+        return (true);
+    }
+    if (_isFraction(angle)
+     && _isSmallInteger(_FractionInstPtr(angle)->f_numerator)
+     && _isSmallInteger(_FractionInstPtr(angle)->f_denominator)) {
+        float n, d;
+
+        n = (float)(_intVal(_FractionInstPtr(angle)->f_numerator));
+        d = (float)(_intVal(_FractionInstPtr(angle)->f_denominator));
+        f_angle = n / d;
+        rot(f_angle, axis);
+        return (true);
+    }
+    if (_isSmallInteger(angle)) {
+        a_angle = (Angle)(_intVal(angle));
+        rotate(a_angle, axis);
+        return (true);
+    }
+    return false;
+}
+
 %}
 
+!GLXWorkstation methodsFor:'queries'!
+
+supportsRGB
+    "return true, if this gl workstation supports rgb
+     (in addition to indexed) colors."
+
+%{  /* NOCONTEXT */
+
+#ifdef VGL
+    RETURN ( false );
+#endif
+#ifdef GLX
+    RETURN ( true );
+#endif
+%}
+! !
+
 !GLXWorkstation methodsFor:'window creation'!
 
 createGLXWindowFor:aView left:xpos top:ypos width:wwidth height:wheight type:glxType
@@ -261,7 +370,6 @@
     ].
 
 %{
-#ifdef GLX
     Display *dpy = myDpy;
     int screen = _intVal(_INST(screen));
     Window newWindow, parentWindow;
@@ -299,7 +407,6 @@
 
         windowId = MKOBJ(newWindow);
     }
-#endif
 %}
 .
     windowId notNil ifTrue:[
@@ -316,22 +423,13 @@
 %}
 ! !
 
-!GLXWorkstation methodsFor:'queries'!
-
-supportsRGB
-    ^ true
-! !
-
 !GLXWorkstation methodsFor:'glx access'!
 
-glxPerspectiveFovy:fovy aspect:aspect 
-              near:near far:far
-                in:aGLXWindowId
+glxPerspectiveFovy:fovy aspect:aspect near:near far:far in:aGLXWindowId
     "define perspective projection"
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Angle a_fovy;
     Coord c_near, c_far;
     float f_aspect;
@@ -343,10 +441,31 @@
         _COORD_ (far, c_far);
         SETWIN(aGLXWindowId)
         perspective(a_fovy, f_aspect, c_near, c_far);
+        RETURN (true);
+    } while(0);
+%}
+.
+    ^ false
+!
+
+glxWindowLeft:left right:right top:top bottom:bottom near:near far:far in:aGLXWindowId
+    "define perspective viewing pyramid"
+
+%{  /* NOCONTEXT */
+    Coord c_left, c_right, c_top, c_bot, c_near, c_far;
+
+    do {
+        _COORD_ (left, c_left);
+        _COORD_ (right, c_right);
+        _COORD_ (top, c_top);
+        _COORD_ (bottom, c_bot);
+        _COORD_ (near, c_near);
+        _COORD_ (far, c_far);
+        SETWIN(aGLXWindowId)
+        window(c_left, c_right, c_bot, c_top, c_near, c_far);
 
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -357,7 +476,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Coord c_x, c_y, c_z;
 
     do {
@@ -368,7 +486,6 @@
         translate(c_x, c_y, c_z);
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -379,7 +496,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     float f_x, f_y, f_z;
 
     do {
@@ -390,7 +506,42 @@
         scale(f_x, f_y, f_z);
         RETURN (true);
     } while(0);
-#endif
+%}
+.
+    ^ false
+!
+
+glxRotateX:angle in:aGLXWindowId
+    "rotate the current matrix on x axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'x'));
+%}
+.
+    ^ false
+!
+
+glxRotateY:angle in:aGLXWindowId
+    "rotate the current matrix on y axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'y'));
+%}
+.
+    ^ false
+!
+
+glxRotateZ:angle in:aGLXWindowId
+    "rotate the current matrix on z axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    RETURN (doRotate(angle, 'z'));
 %}
 .
     ^ false
@@ -405,9 +556,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
-    Angle a_angle;
-    float f_angle;
     char c_axis;
 
     do {
@@ -420,33 +568,34 @@
         else break;
 
         SETWIN(aGLXWindowId)
-        if (_isFloat(angle)) {
-            f_angle = (float)(_floatVal(angle));
-            rot(f_angle, c_axis);
-            RETURN (true);
-        } else {
-            if (_isSmallInteger(angle)) {
-                a_angle = (Angle)(_intVal(angle));
-                rotate(a_angle, c_axis);
-                RETURN (true);
-            }
-        }
+        RETURN ( doRotate(angle, c_axis) );
     } while(0);
-#endif
 %}
 .
     ^ false
 !
 
-glxLookatVx:vx vy:vy vz:vz 
-         px:px py:py pz:pz 
-      twist:twist
-         in:aGLXWindowId
+glxRotateX:xAngle y:yAngle z:zAngle in:aGLXWindowId
+    "rotate the current matrix on all axis"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    if ( doRotate(xAngle, 'x') == true) {
+        if ( doRotate(yAngle, 'y') == true) {
+            RETURN (doRotate(zAngle, 'z'));
+        }
+    }
+%}
+.
+    ^ false
+!
+
+glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
     "define viewing transformation"
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
     Angle a_twist;
 
@@ -462,7 +611,6 @@
         lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
         RETURN (true);
     } while(0);
-#endif
 %}
 .
     ^ false
@@ -573,7 +721,6 @@
 
 %{  /* NOCONTEXT */
 
-#ifdef GLX
     SETWIN(aGLXWindowId)
     if (_isSmallInteger(index)) {
         color((Colorindex)(_intVal(index)));
@@ -583,7 +730,6 @@
         colorf((float)(_floatVal(index)));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -593,7 +739,6 @@
     "set color, args must be integer values"
 
 %{  /* NOCONTEXT */
-
 #ifdef GLX
     short s_r, s_g, s_b;
 
@@ -615,11 +760,9 @@
     "clear to current color"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     clear();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -643,11 +786,9 @@
     "push down transformation stack"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     pushmatrix();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -657,11 +798,9 @@
     "pop transformation stack"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     popmatrix();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -671,11 +810,39 @@
     "swap double buffers"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     swapbuffers();
     RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxFrontBufferIn:aGLXWindowId
+    "switch to front buffer"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    backbuffer(FALSE);
 #endif
+    frontbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackBufferIn:aGLXWindowId
+    "switch to back buffer"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    frontbuffer(FALSE);
+#endif
+    backbuffer(TRUE);
+    RETURN (true);
 %}
 .
     ^ false
@@ -699,11 +866,9 @@
     "set double buffer mode"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     doublebuffer();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -714,11 +879,9 @@
      changes really take effect. See GLX manual"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     gconfig();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -738,15 +901,13 @@
     ^ false
 !
 
-glxBackface:aBoolean in:aGLXWindowId
+glxBackFace:aBoolean in:aGLXWindowId
     "enable/disable backface"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
+    SETWIN(aGLXWindowId)                                     
     backface(aBoolean == false ? FALSE : TRUE);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -810,11 +971,9 @@
     "start a polygon"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnpolygon();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -824,11 +983,9 @@
     "end a polygon"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endpolygon();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -838,11 +995,9 @@
     "start a point-group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnpoint();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -852,25 +1007,21 @@
     "end a point group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endpoint();
     RETURN (true);
-#endif
 %}
 .
     ^ false
 !
 
-glxBeginCloseLineIn:aGLXWindowId
+glxBeginClosedLineIn:aGLXWindowId
     "start a closed line"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnclosedline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -880,11 +1031,9 @@
     "end a closed line"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endclosedline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -894,11 +1043,9 @@
     "start a line group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -908,11 +1055,9 @@
     "end a line group"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endline();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -922,11 +1067,9 @@
     "start a triangle mesh"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgntmesh();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -936,11 +1079,9 @@
     "end a triangle mesh"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endtmesh();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -978,11 +1119,9 @@
     "start a quadrilateral strip"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     bgnqstrip();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -992,11 +1131,9 @@
     "end a quadrilateral strip"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     SETWIN(aGLXWindowId)
     endqstrip();
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1030,6 +1167,97 @@
     ^ false
 !
 
+glxMoveX:x y:y z:z in:aGLXWindowId
+    "arguments must specify a point"
+
+%{  /* NOCONTEXT */
+    if (_isFloat(x) && _isFloat(y) && _isFloat(z)) {
+        SETWIN(aGLXWindowId)                                     
+        move( (float)_floatVal(x), (float)_floatVal(y), (float)_floatVal(z) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxMove:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the point"
+
+%{  /* NOCONTEXT */
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    move( v[0], v[1], v[2] );
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxDrawX:x y:y z:z in:aGLXWindowId
+    "arguments must specify a point"
+
+%{  /* NOCONTEXT */
+
+    if (_isFloat(x) && _isFloat(y) && _isFloat(z)) {
+        SETWIN(aGLXWindowId)                                     
+        draw( (float)_floatVal(x), (float)_floatVal(y), (float)_floatVal(z) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxDraw:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the point"
+
+%{  /* NOCONTEXT */
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    draw( v[0], v[1], v[2]);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxRectX1:x1 y1:y1 x2:x2 y2:y2 in:aGLXWindowId
+    "arguments must specify 2 opposite corners of the rectangle"
+
+%{  /* NOCONTEXT */
+    float f_x1, f_x2, f_y1, f_y2;
+
+    if (_isFloat(x1) && _isFloat(x2) && _isFloat(y1) && _isFloat(y2)) {
+        SETWIN(aGLXWindowId)                                     
+        rect( (float)_floatVal(x1), (float)_floatVal(y1), (float)_floatVal(x2), (float)_floatVal(y2) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRectFX1:x1 y1:y1 x2:x2 y2:y2 in:aGLXWindowId
+    "arguments must specify 2 opposite corners of the filled rectangle"
+
+%{  /* NOCONTEXT */
+    float f_x1, f_x2, f_y1, f_y2;
+
+    if (_isFloat(x1) && _isFloat(x2) && _isFloat(y1) && _isFloat(y2)) {
+        SETWIN(aGLXWindowId)                                     
+        rectf( (float)_floatVal(x1), (float)_floatVal(y1), (float)_floatVal(x2), (float)_floatVal(y2) );
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
 glxSphDraw:arrayOf4Floats in:aGLXWindowId
     "argument must be an array(a matrix) of 4 floats containing the
      sphere"
@@ -1050,8 +1278,8 @@
 
 glxDefBasis:id mat:aMatrix in:aGLXWindowId
     "define the basis"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1061,7 +1289,6 @@
         defbasis((short)(_intVal(id)), *m);
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1069,14 +1296,13 @@
 
 glxPatchCurvesU:u v:v in:aGLXWindowId
     "set the number of curves in a patch"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchcurves((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1084,14 +1310,13 @@
 
 glxPatchPrecisionU:u v:v in:aGLXWindowId
     "set the patch precision"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchprecision((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1099,14 +1324,13 @@
 
 glxPatchBasisU:u v:v in:aGLXWindowId
     "set the current basis matrices"
+
 %{  /* NOCONTEXT */
-#ifdef GLX
     if (_isSmallInteger(u) && _isSmallInteger(v)) {
         SETWIN(aGLXWindowId)
         patchbasis((long)_intVal(u), (long)_intVal(v));
         RETURN (true);
     }
-#endif
 %}
 .
     ^ false
@@ -1116,7 +1340,6 @@
     "arguments must be arrays of 16 floats containing the patch"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrixX, matrixY, matrixZ;
     Matrix *mX, *mY, *mZ;
 
@@ -1126,7 +1349,6 @@
     SETWIN(aGLXWindowId)
     patch(*mX, *mY, *mZ);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1137,14 +1359,12 @@
      matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
 
     SETWIN(aGLXWindowId)
     getmatrix(matrix);
     if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1155,7 +1375,6 @@
      transformation matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1163,7 +1382,6 @@
     SETWIN(aGLXWindowId)
     loadmatrix(*m);
     RETURN (true);
-#endif
 %}
 .
     ^ false
@@ -1174,7 +1392,6 @@
      matrix"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     Matrix matrix;
     Matrix *m;
 
@@ -1182,15 +1399,57 @@
     SETWIN(aGLXWindowId)
     multmatrix(*m);
     RETURN (true);
-#endif
+%}
+.
+    ^ false
+!
+
+glxMakeObject:id in:aGLXWindowId
+    "start object definition"
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(id)) {
+        SETWIN(aGLXWindowId)
+        makeobj(_intVal(id));
+        RETURN (true);
+    }
 %}
 .
     ^ false
 !
 
+glxCloseObjectIn:aGLXWindowId
+    "end object defnition"
+
+%{  /* NOCONTEXT */
+
+    SETWIN(aGLXWindowId)
+    closeobj();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxCallObject:id in:aGLXWindowId
+    "do objects definition"
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(id)) {
+        SETWIN(aGLXWindowId)
+        callobj(_intVal(id));
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+ 
 glxN3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the
-     current vertex normal"
+    "argument must be an indexable object with 3 floats,
+     containing the current vertex normal"
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -1207,7 +1466,8 @@
 !
 
 glxC3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the color"
+    "argument must be an indexable object with 3 floats,
+     containing the color"
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -1224,17 +1484,16 @@
 !
 
 glxV3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the vertex"
+    "argument must be an indexable object with 3 floats,
+     containing the vertex"
 
 %{  /* NOCONTEXT */
-#ifdef GLX
     float vec[3], *v;
 
     if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
     SETWIN(aGLXWindowId)
     v3f(v);
     RETURN (true);
-#endif
 %}
 .
     ^ false
--- a/GraphicsContext.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/GraphicsContext.st	Sat Jan 08 18:17:39 1994 +0100
@@ -43,7 +43,7 @@
 implemented by subclasses (some subclasses also redefine the others for
 more performance)
 
-$Header: /cvs/stx/stx/libview/GraphicsContext.st,v 1.5 1993-12-11 01:28:58 claus Exp $
+$Header: /cvs/stx/stx/libview/GraphicsContext.st,v 1.6 1994-01-08 17:15:42 claus Exp $
 
 Instance variables:
 
@@ -525,9 +525,23 @@
 drawForm:aForm x:x y:y
     "draw a form at x/y; if the form has depth 1, 1's in the form are
      drawn in current fg, 0's are ignored.
-     If the form has depth ~~ 1, it is copied as is onto the receiver"
+     If the form has depth ~~ 1, the result is undefined"
+
+    |fg bg f|
+
+    fg := foreground.
+    bg := background.
+    f := function.
 
+    self foreground:(Color noColor) background:(Color allColor) function:#and.
+    self drawOpaqueForm:aForm x:x y:y.
+    self foreground:fg background:(Color noColor) function:#or.
+    self drawOpaqueForm:aForm x:x y:y.
+    self foreground:fg background:fg function:f.
+
+"
     ^ self subclassResponsibility
+"
 !
 
 drawOpaqueForm:aForm x:x y:y
@@ -576,16 +590,16 @@
     self displayString:aString x:aPoint x y:aPoint y
 !
 
-drawPointX:x y:y
+displayPointX:x y:y
     "draw a point at x/y"
 
     self displayLineFromX:x y:y toX:x y:y
 !
 
-drawPoint:aPoint
+displayPoint:aPoint
     "draw a pixel"
 
-    self drawPointX:(aPoint x) y:(aPoint y)
+    self displayPointX:(aPoint x) y:(aPoint y)
 !
 
 displayLineFrom:point1 to:point2
--- a/Image.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/Image.st	Sat Jan 08 18:17:39 1994 +0100
@@ -16,7 +16,7 @@
                                 colorMap photometric 
                                 device deviceForm monoDeviceForm
                                 fullColorDeviceForm'
-         classVariableNames:'lobby
+         classVariableNames:'Lobby 
                              DitherAlgorithm NumberOfDitherColors
                              FileFormats'
          poolDictionaries:''
@@ -28,7 +28,7 @@
 COPYRIGHT (c) 1991 by Claus Gittinger
               All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/Image.st,v 1.6 1993-12-13 17:09:53 claus Exp $
+$Header: /cvs/stx/stx/libview/Image.st,v 1.7 1994-01-08 17:15:47 claus Exp $
 written Summer 91 by claus
 '!
 
@@ -104,7 +104,7 @@
 
 class variables:
 
-lobby               <Registry>      keeps track of known images
+Lobby               <Registry>      keeps track of known images
 DitherAlgorithm     <Symbol>        defines how to dither
 NumberOfDitherColors <Integer>      defines, how many dither colors to use
 FileFormats         <Dictionary>    associates filename extensions to
@@ -139,8 +139,8 @@
     "initialize class constants"
 
     "setup tracker of known pictures"
-    lobby isNil ifTrue:[
-        lobby := Registry new.
+    Lobby isNil ifTrue:[
+        Lobby := Registry new.
         ObjectMemory addDependent:self.
     ].
 
@@ -155,31 +155,39 @@
 
     "define reader classes"
     FileFormats isNil ifTrue:[
-        FileFormats := Dictionary new.
-        FileFormats at:'.xbm'  put:XBMReader.
-        FileFormats at:'.tiff' put:TIFFReader.
-        FileFormats at:'.tif'  put:TIFFReader.
-        FileFormats at:'.gif'  put:GIFReader.
-        FileFormats at:'.img'  put:IMGReader.
-        FileFormats at:'.pcx'  put:PCXReader.
-        FileFormats at:'.mac'  put:MacPaintReader.
-        FileFormats at:'.im8'  put:SunRasterReader.
-        FileFormats at:'.icon' put:SunRasterReader.
-        FileFormats at:'.face' put:FaceReader.
-        FileFormats at:'.g3'   put:G3FileReader.
-        FileFormats at:'.bmp'  put:WindowsIconReader.
-        FileFormats at:'.ico'  put:WindowsIconReader.
-        FileFormats at:'.BMP'  put:WindowsIconReader.
-        FileFormats at:'.ICO'  put:WindowsIconReader.
-        FileFormats at:'.jpg'  put:JPEGReader.
-        FileFormats at:'.jpeg' put:JPEGReader.
-        FileFormats at:'.ppm'  put:PBMReader.
-        FileFormats at:'.pbm'  put:PBMReader.
-        FileFormats at:'.pgm'  put:PBMReader.
-        FileFormats at:'.form' put:ST80FormReader.
+        self initializeFileFormatTable
     ].
 !
 
+initializeFileFormatTable
+    "initialize table to map from file extension to reader class"
+
+    FileFormats := Dictionary new.
+    FileFormats at:'.xbm'  put:XBMReader.
+    FileFormats at:'.tiff' put:TIFFReader.
+    FileFormats at:'.tif'  put:TIFFReader.
+    FileFormats at:'.gif'  put:GIFReader.
+    FileFormats at:'.img'  put:IMGReader.
+    FileFormats at:'.pcx'  put:PCXReader.
+    FileFormats at:'.mac'  put:MacPaintReader.
+    FileFormats at:'.im8'  put:SunRasterReader.
+    FileFormats at:'.icon' put:SunRasterReader.
+    FileFormats at:'.face' put:FaceReader.
+    FileFormats at:'.g3'   put:G3FileReader.
+    FileFormats at:'.bmp'  put:WindowsIconReader.
+    FileFormats at:'.ico'  put:WindowsIconReader.
+    FileFormats at:'.BMP'  put:WindowsIconReader.
+    FileFormats at:'.ICO'  put:WindowsIconReader.
+    FileFormats at:'.jpg'  put:JPEGReader.
+    FileFormats at:'.jpeg' put:JPEGReader.
+    FileFormats at:'.ppm'  put:PBMReader.
+    FileFormats at:'.pbm'  put:PBMReader.
+    FileFormats at:'.pgm'  put:PBMReader.
+    FileFormats at:'.form' put:ST80FormReader.
+
+    "Image initializeFileFormatTable"
+!
+
 fileFormats
     "return the collection of supported file formats"
 
@@ -189,7 +197,7 @@
 flushDeviceImages
     "simply unassign all pictures from their device"
 
-    lobby contentsDo:[:anImage |
+    Lobby contentsDo:[:anImage |
         anImage restored
     ]
 !
@@ -210,16 +218,48 @@
     ^ self fromScreen:(0@0 corner:(Display width@Display height))
 !
 
+fromScreenArea
+    "return an image of a part of the screen; let user specify screen
+     area."
+
+    ^ self fromScreen:(Rectangle fromUser)
+
+    "Image fromScreenArea"
+!
+
 fromScreen:aRectangle
     "return an image of a part of the screen"
 
+    ^ self fromScreen:aRectangle on:Display
+
+    "Image fromScreen:(0@0 corner:100@100)"
+!
+
+fromScreen:aRectangle on:aDisplay
+    "return an image of a part of the screen"
+
     |depth img|
 
-    depth := Display depth.
+    depth := aDisplay depth.
     img := (self implementorForDepth: depth) new.
-    ^ img fromScreen:aRectangle
+    ^ img fromScreen:aRectangle on:aDisplay
 
     "Image fromScreen:(0@0 corner:100@100)"
+!
+
+fromView:aView
+    "return an image taken from a view"
+
+    |org dev|
+
+    dev := aView device.
+    org := dev translatePoint:(0@0)
+                         from:(aView id)
+                           to:(DisplayRootView on:dev) id.
+    ^ self fromScreen:(org extent:aView extent) on:dev
+
+    "Image fromView:(Launcher allInstances first topView)"
+    "Image fromView:(SystemBrowser allInstances first topView)"
 ! !
 
 !Image class methodsFor:'reading from file'!
@@ -299,7 +339,7 @@
     deviceForm := nil.
     monoDeviceForm := nil.
     fullColorDeviceForm := nil.
-    lobby unregister:self
+    Lobby unregister:self
 !
 
 disposed
@@ -640,14 +680,15 @@
         ]
     ].
 
-    "dont know yet, how display pads, assume worst case"
+    "dont know yet, how display pads; assume worst case, 
+     offering enough space for 32 bit padding"
 
     w := width := aRectangle width.
     h := height := aRectangle height.
     x := aRectangle left.
     y := aRectangle top.
 
-    bytesPerLine := (w * bitsPerPixel + 31) // 8.
+    bytesPerLine := (w * bitsPerPixel + 31) // 32 * 4.
     inData := ByteArray uninitializedNew:(bytesPerLine * height).
 
     root := DisplayRootView on:aDevice.
@@ -667,6 +708,12 @@
             dstIndex := dstIndex + bytesPerLine.
             srcIndex := srcIndex + bytesPerLineIn
         ]
+    ] ifFalse:[
+        (bytesPerLine * height) ~~ inData size ifTrue:[
+            tmpData := inData.
+            inData := ByteArray uninitializedNew:(bytesPerLine * height).
+            inData replaceFrom:1 to:bytesPerLine * height with:tmpData startingAt:1
+        ]
     ].
 
     "info printNewline. "
@@ -738,10 +785,10 @@
     deviceForm notNil ifTrue:[
         device isNil ifTrue:[
             device := aDevice.
-            lobby register:self
+            Lobby register:self
         ] ifFalse:[
             device := aDevice.
-            lobby changed:self
+            Lobby changed:self
         ].
         deviceForm forgetBits
     ]
@@ -1024,7 +1071,6 @@
      x0            "{Class: SmallInteger }"
      w             "{Class: SmallInteger }"
      h             "{Class: SmallInteger }"
-     v             "{Class: SmallInteger }"
      run           "{Class: SmallInteger }" |
 
     Transcript showCr:'slow dithering ..'. Transcript endEntry.
@@ -1131,7 +1177,9 @@
     "return an 8-bit pseudo Form from the grey picture"
 
     |wideBits pictureDepth f map  
-     colorMap usedColors nUsed aColor nColors range|
+     colorMap usedColors nUsed aColor 
+     nColors "{ Class: SmallInteger }"
+     range clr id|
 
     pictureDepth := bitsPerSample at:1.
 
@@ -1172,10 +1220,18 @@
 
     "setup the translation map"
     map := ByteArray uninitializedNew:256.
-    1 to:(colorMap size) do:[:i |
+    nColors := colorMap size.
+    1 to:nColors do:[:i |
         aColor := colorMap at:i.
         aColor notNil ifTrue:[
-            map at:i put:(aColor on:aDevice) colorId
+            aColor := aColor on:aDevice.
+            colorMap at:i put:aColor.
+            id := aColor colorId.
+            id notNil ifTrue:[
+                map at:i put:id
+            ] ifFalse:[
+                map at:i put:0
+            ]
         ]
     ].
 
@@ -1202,7 +1258,7 @@
     "return a new image magnified by extent, aPoint.
      If non-integral magnify is asked for, pass the work on to 'hardMagnifyBy:'"
 
-    |mX mY srcOffset dstOffset dstStep first
+    |mX mY srcOffset dstOffset first
      newWidth newHeight newImage newBits bitsPerPixel newBytesPerRow oldBytesPerRow|
 
     mX := extent x.
@@ -1378,7 +1434,7 @@
     |w "{Class: SmallInteger }"
      h "{Class: SmallInteger }"
      c2 "{Class: SmallInteger }" 
-     value newImage newBits newBytesPerRow d|
+     newImage newBits newBytesPerRow d|
 
     d := degrees.
     [d < 0] whileTrue:[d := d + 360].
--- a/Make.proto	Sat Jan 08 18:12:58 1994 +0100
+++ b/Make.proto	Sat Jan 08 18:17:39 1994 +0100
@@ -70,7 +70,7 @@
 XWorkstat.o:    XWorkstat.st $(I)/DevWorkst.H $(OBJECT)
 NXWorkst.o:     NXWorkst.st $(I)/DevWorkst.H $(OBJECT)
 GLXWorkstat.o:  GLXWorkstat.st $(I)/XWorkstat.H $(I)/DevWorkst.H $(OBJECT)
-VGLWorkstat.o:  VGLWorkstat.st $(I)/XWorkstat.H $(I)/DevWorkst.H $(OBJECT)
+# VGLWorkstat.o:  VGLWorkstat.st $(I)/XWorkstat.H $(I)/DevWorkst.H $(OBJECT)
 WSensor.o:      WSensor.st $(OBJECT)
 WGroup.o:       WGroup.st $(OBJECT)
 WEvent.o:       WEvent.st $(OBJECT)
--- a/NXWorkst.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/NXWorkst.st	Sat Jan 08 18:17:39 1994 +0100
@@ -30,7 +30,7 @@
 
 All non-monochrome stuff is untested (I only have a monochroome station)
 
-$Header: /cvs/stx/stx/libview/Attic/NXWorkst.st,v 1.4 1993-12-11 01:31:31 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/NXWorkst.st,v 1.5 1994-01-08 17:15:52 claus Exp $
 written spring 92 by claus
 '!
 
@@ -790,7 +790,7 @@
     ^ self primitiveFailed
 !
 
-drawPointX:x y:y in:aDrawableId with:aGCId
+displayPointX:x y:y in:aDrawableId with:aGCId
     "draw a point" 
 
     ^ self primitiveFailed
--- a/NeXTWorkstation.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/NeXTWorkstation.st	Sat Jan 08 18:17:39 1994 +0100
@@ -30,7 +30,7 @@
 
 All non-monochrome stuff is untested (I only have a monochroome station)
 
-$Header: /cvs/stx/stx/libview/NeXTWorkstation.st,v 1.4 1993-12-11 01:31:31 claus Exp $
+$Header: /cvs/stx/stx/libview/NeXTWorkstation.st,v 1.5 1994-01-08 17:15:52 claus Exp $
 written spring 92 by claus
 '!
 
@@ -790,7 +790,7 @@
     ^ self primitiveFailed
 !
 
-drawPointX:x y:y in:aDrawableId with:aGCId
+displayPointX:x y:y in:aDrawableId with:aGCId
     "draw a point" 
 
     ^ self primitiveFailed
--- a/PseudoV.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/PseudoV.st	Sat Jan 08 18:17:39 1994 +0100
@@ -35,7 +35,7 @@
 delegate instead, if there is one. So you can change views behavior even if they
 where not initially designed for it.
 
-$Header: /cvs/stx/stx/libview/Attic/PseudoV.st,v 1.6 1993-12-20 17:28:58 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/PseudoV.st,v 1.7 1994-01-08 17:15:56 claus Exp $
 
 rewritten summer 92 by claus
 '!
@@ -156,14 +156,16 @@
         (viewBackground isKindOf:Form) ifTrue:[
             bgPixmap := viewBackground
         ] ifFalse:[
-            viewBackground := viewBackground on:device.
-            id := viewBackground colorId.
-            "a real color"
-            id notNil ifTrue:[
-                device setWindowBackground:id in:drawableId.
-                ^ self
+            viewBackground notNil ifTrue:[
+                viewBackground := viewBackground on:device.
+                id := viewBackground colorId.
+                "a real color"
+                id notNil ifTrue:[
+                    device setWindowBackground:id in:drawableId.
+                    ^ self
+                ].
+                bgPixmap := viewBackground ditherForm.
             ].
-            bgPixmap := viewBackground ditherForm.
         ].
 
         "a dithered color or bitmap or pixmap"
@@ -297,7 +299,13 @@
     ^ self
 !
 
-iconName:aLabel
+iconLabel
+    "return the views icon label - this is nil here"
+
+    ^ nil
+!
+
+iconLabel:aLabel
     "set the views icon label - ignored here"
 
     ^ self
@@ -309,12 +317,24 @@
     ^ nil
 !
 
+iconView:aView
+    "set the views icon view - ignored here"
+
+    ^ self
+!
+
 icon
     "return the views icon - this is nil here"
 
     ^ nil
 !
 
+icon:aBitmap
+    "set the views icon - ignored here"
+
+    ^ self
+!
+
 realized
     "return true, if the receiver is realized"
 
@@ -429,6 +449,22 @@
             device setBackingStore:how in:drawableId
         ]
     ]
+!
+
+preferedVisual
+    "return a non nil id, if a specific visual is wanted in this view.
+     Return nil if we do not care (i.e. the displays default is wanted). 
+     This is experimental and may change/vanish - do not use it."
+
+    ^ nil
+!
+
+preferedDepth
+    "return a non nil integer, if a specific depth is wanted in this view.
+     Return nil if we do not care (i.e. the displays default is wanted).
+     This is experimental and may change/vanish - do not use it."
+
+    ^ nil
 ! !
 
 !PseudoView methodsFor:'drawing'!
@@ -752,8 +788,6 @@
     "button was pressed - if its middle button and there is a menu,
      show it."
 
-    |menu menuSelector|
-
     (button == 2) ifTrue:[
         middleButtonMenu notNil ifTrue:[
             middleButtonMenu showAtPointer
--- a/ResourcePack.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/ResourcePack.st	Sat Jan 08 18:17:39 1994 +0100
@@ -12,7 +12,7 @@
 
 Dictionary subclass:#ResourcePack
          instanceVariableNames:'elements dependents fileName'
-         classVariableNames:'packs'
+         classVariableNames:'Packs'
          poolDictionaries:''
          category:'System-Support'
 !
@@ -25,18 +25,27 @@
 to allow easy customization of smalltalk code (i.e. internationalization)
 (replaces the obsolete Resource class)
 
-$Header: /cvs/stx/stx/libview/ResourcePack.st,v 1.4 1993-12-11 01:32:41 claus Exp $
+$Header: /cvs/stx/stx/libview/ResourcePack.st,v 1.5 1994-01-08 17:15:59 claus Exp $
 written spring 93 by claus
 '!
 
 !ResourcePack class methodsFor:'initialization'!
 
 initialize
-    packs isNil ifTrue:[
-        packs := WeakArray new:30
+    Packs isNil ifTrue:[
+        Packs := WeakArray new:30
     ].
 
     "ResourcePack initialize"
+!
+
+flushResources
+    "forget all cached resources - needed after a style change"
+
+    Packs := nil.
+    self initialize
+
+    "ResourcePack flushResources"
 ! !
 
 !ResourcePack class methodsFor:'instance creation'!
@@ -48,10 +57,10 @@
 
     "first look, if not already here"
 
-    packs isNil ifTrue:[
+    Packs isNil ifTrue:[
         self initialize
     ].
-    packs do:[:aPack |
+    Packs do:[:aPack |
         aPack notNil ifTrue:[
             aPack fileName = aFileName ifTrue:[
                 ^ aPack
@@ -66,13 +75,13 @@
     newPack fileName:aFileName.
     inStream close.
 
-    idx := packs identityIndexOf:nil.
+    idx := Packs identityIndexOf:nil.
     idx notNil ifTrue:[
-        packs at:idx put:newPack
+        Packs at:idx put:newPack
     ] ifFalse:[
-        temp := WeakArray new:(packs size).
-        temp replaceFrom:1 with:packs.
-        packs := temp
+        temp := WeakArray new:(Packs size).
+        temp replaceFrom:1 with:Packs.
+        Packs := temp
     ].
 
     ^ newPack
--- a/RsrcPack.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/RsrcPack.st	Sat Jan 08 18:17:39 1994 +0100
@@ -12,7 +12,7 @@
 
 Dictionary subclass:#ResourcePack
          instanceVariableNames:'elements dependents fileName'
-         classVariableNames:'packs'
+         classVariableNames:'Packs'
          poolDictionaries:''
          category:'System-Support'
 !
@@ -25,18 +25,27 @@
 to allow easy customization of smalltalk code (i.e. internationalization)
 (replaces the obsolete Resource class)
 
-$Header: /cvs/stx/stx/libview/Attic/RsrcPack.st,v 1.4 1993-12-11 01:32:41 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/RsrcPack.st,v 1.5 1994-01-08 17:15:59 claus Exp $
 written spring 93 by claus
 '!
 
 !ResourcePack class methodsFor:'initialization'!
 
 initialize
-    packs isNil ifTrue:[
-        packs := WeakArray new:30
+    Packs isNil ifTrue:[
+        Packs := WeakArray new:30
     ].
 
     "ResourcePack initialize"
+!
+
+flushResources
+    "forget all cached resources - needed after a style change"
+
+    Packs := nil.
+    self initialize
+
+    "ResourcePack flushResources"
 ! !
 
 !ResourcePack class methodsFor:'instance creation'!
@@ -48,10 +57,10 @@
 
     "first look, if not already here"
 
-    packs isNil ifTrue:[
+    Packs isNil ifTrue:[
         self initialize
     ].
-    packs do:[:aPack |
+    Packs do:[:aPack |
         aPack notNil ifTrue:[
             aPack fileName = aFileName ifTrue:[
                 ^ aPack
@@ -66,13 +75,13 @@
     newPack fileName:aFileName.
     inStream close.
 
-    idx := packs identityIndexOf:nil.
+    idx := Packs identityIndexOf:nil.
     idx notNil ifTrue:[
-        packs at:idx put:newPack
+        Packs at:idx put:newPack
     ] ifFalse:[
-        temp := WeakArray new:(packs size).
-        temp replaceFrom:1 with:packs.
-        packs := temp
+        temp := WeakArray new:(Packs size).
+        temp replaceFrom:1 with:Packs.
+        Packs := temp
     ].
 
     ^ newPack
--- a/StandardSystemView.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/StandardSystemView.st	Sat Jan 08 18:17:39 1994 +0100
@@ -11,7 +11,8 @@
 "
 
 View subclass:#StandardSystemView
-       instanceVariableNames:'label icon iconView minExtent maxExtent'
+       instanceVariableNames:'label icon iconView iconLabel
+                              minExtent maxExtent'
        classVariableNames:   ''
        poolDictionaries:''
        category:'Views-Basic'
@@ -25,7 +26,7 @@
 I represent topViews i.e. those views which have a title-label,
 an icon etc.
 
-$Header: /cvs/stx/stx/libview/StandardSystemView.st,v 1.6 1993-12-20 17:29:01 claus Exp $
+$Header: /cvs/stx/stx/libview/StandardSystemView.st,v 1.7 1994-01-08 17:16:02 claus Exp $
 written spring/summer 89 by claus
 '!
 
@@ -58,7 +59,7 @@
                  minExtent:minExtent
                  maxExtent:nil.
     newView model:aModel.
-    newView controller:(StandardSystemController new view:newView).
+    newView controller:(self defaultController new view:newView).
     ^ newView
 !
 
@@ -165,20 +166,57 @@
     ]
 !
 
+reinitialize
+    "this is called right after snapIn"
+
+    |myController|
+
+    "if I have already been reinited - return"
+    drawableId notNil ifTrue:[
+        ^ self
+    ].
+
+    myController := controller.
+    controller := nil.
+    self recreate.
+
+    "if I was mapped, do it again"
+    realized ifTrue:[
+        "if it was iconified, try to remap iconified"
+        shown ifFalse:[
+            device mapView:self id:drawableId iconified:true
+                       atX:left y:top width:width height:height
+        ] ifTrue:[
+            device mapView:self id:drawableId iconified:false
+                       atX:left y:top width:width height:height
+        ].
+
+        "and restart the window-group process"
+        windowGroup notNil ifTrue:[
+            windowGroup startup
+        ]
+    ].
+
+    "restore controller"
+    controller := myController
+!
+
 recreate
     "recreate the view after a snap-in"
 
-    icon notNil ifTrue:[
-        icon depth ~~ 1 ifTrue:[
-            icon := icon asMonochromeFormOn:device.
+    icon := self convertedIcon.
+    super recreate.
+    iconView notNil ifTrue:[
+        iconView create.
+        device setWindowIconWindow:iconView in:drawableId
+    ] ifFalse:[
+        (icon notNil and:[icon id notNil]) ifTrue:[
+            device setWindowIcon:icon in:drawableId
         ].
-        icon notNil ifTrue:[
-            icon := icon on:device.
-        ]
     ].
-    super recreate.
-    (icon notNil and:[icon id notNil]) ifTrue:[
-        device setWindowIcon:icon in:drawableId
+
+    iconLabel notNil ifTrue:[
+        device setIconName:iconLabel in:drawableId
     ]
 !
 
@@ -207,24 +245,43 @@
     ].
 ! !
 
+!StandardSystemView methodsFor:'private'!
+
+convertedIcon
+    "make certain, that the icon is a b&w bitmap;
+     do so by converting if appropriate.
+     Will add a device supportsDeepIcons and only convert when needed;
+     for now (since there are only Xdisplays) we always have to convert."
+
+    |deviceIcon|
+
+    icon isNil ifTrue:[^ nil].
+
+    icon depth ~~ 1 ifTrue:[
+        deviceIcon := icon asMonochromeFormOn:device.
+    ] ifFalse:[
+        deviceIcon := icon
+    ].
+    deviceIcon notNil ifTrue:[
+        deviceIcon := deviceIcon on:device
+    ].
+    ^ deviceIcon
+! !
+
 !StandardSystemView methodsFor:'realization'!
 
 create
     "create - make certain that icon is available"
 
-    icon notNil ifTrue:[
-        icon depth ~~ 1 ifTrue:[
-            icon := icon asMonochromeFormOn:device.
-        ].
-        icon notNil ifTrue:[
-            icon := icon on:device
-        ].
-    ].
+    icon := self convertedIcon.
     super create.
 
     iconView notNil ifTrue:[
         iconView create.
         device setWindowIconWindow:iconView in:drawableId
+    ].
+    iconLabel notNil ifTrue:[
+        device setIconName:iconLabel in:drawableId
     ]
 !
 
@@ -264,7 +321,24 @@
     ]
 !
 
+iconLabel
+    "return the name displayed in the icon"
+
+    ^ iconLabel
+!
+
+iconLabel:aString
+    "define the name to be displayed in the icon"
+
+    iconLabel := aString.
+    drawableId notNil ifTrue:[
+        device setIconName:aString in:drawableId
+    ]
+!
+
 name
+    "return the topViews label"
+
     ^ label
 !
 
@@ -277,31 +351,29 @@
 icon:aForm
     "define the form (bitmap) used as icon"
 
-    |invertedIcon|
+    |invertedIcon i|
 
     icon := aForm.
-
     icon notNil ifTrue:[
-        icon depth == 1 ifTrue:[
-            "icons assume 1s as black - invert icon if the device thinks different"
-            (device depth == 1 and:[device whitepixel ~~ 0]) ifTrue:[
-                icon := icon on:device.
-                invertedIcon := Form width:icon width height:icon height on:device.
-                invertedIcon function:#copyInverted.
-                invertedIcon copyFrom:icon x:0 y:0 toX:0 y:0 width:icon width height:icon height.
-                icon := invertedIcon
-            ]
-        ].
-
         drawableId notNil ifTrue:[
             icon depth ~~ 1 ifTrue:[
                 icon := icon asMonochromeFormOn:device.
             ].
-            icon := icon on:device.
-            icon notNil ifTrue:[
-                icon id notNil ifTrue:[
-                    device setWindowIcon:icon in:drawableId
+            "icons assume 1s as black - invert icon if the device thinks different"
+            (device depth == 1 and:[device whitepixel ~~ 0]) ifTrue:[
+                i := icon on:device.
+                i notNil ifTrue:[
+                    invertedIcon := Form width:icon width height:icon height on:device.
+                    invertedIcon function:#copy.
+                    invertedIcon foreground:Color noColor background:Color allColor.
+                    invertedIcon copyFrom:i x:0 y:0 toX:0 y:0 width:icon width height:icon height.
+                    i := invertedIcon.
                 ]
+            ] ifFalse:[
+                i := icon on:device.
+            ].
+            (i notNil and:[i id notNil]) ifTrue:[
+                device setWindowIcon:i in:drawableId
             ]
         ]
     ]
@@ -324,21 +396,19 @@
 !
 
 iconName:aString
-    "define the name to be displayed in the icon"
+    "this method will vanish soon ... - for backward compatibility"
 
-    drawableId notNil ifTrue:[
-        device setIconName:aString in:drawableId
-    ]
+    self iconLabel:aString
 !
 
 maximumSize:anExtent
-    "maxExtent: for ST-80 compatibility"
+    "same as maxExtent: for ST-80 compatibility"
 
     ^ self maxExtent:anExtent
 !
 
 minimumSize:anExtent
-    "minExtent: for ST-80 compatibility"
+    "same as minExtent: for ST-80 compatibility"
 
     ^ self minExtent:anExtent
 !
--- a/StdSysV.st	Sat Jan 08 18:12:58 1994 +0100
+++ b/StdSysV.st	Sat Jan 08 18:17:39 1994 +0100
@@ -11,7 +11,8 @@
 "
 
 View subclass:#StandardSystemView
-       instanceVariableNames:'label icon iconView minExtent maxExtent'
+       instanceVariableNames:'label icon iconView iconLabel
+                              minExtent maxExtent'
        classVariableNames:   ''
        poolDictionaries:''
        category:'Views-Basic'
@@ -25,7 +26,7 @@
 I represent topViews i.e. those views which have a title-label,
 an icon etc.
 
-$Header: /cvs/stx/stx/libview/Attic/StdSysV.st,v 1.6 1993-12-20 17:29:01 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/StdSysV.st,v 1.7 1994-01-08 17:16:02 claus Exp $
 written spring/summer 89 by claus
 '!
 
@@ -58,7 +59,7 @@
                  minExtent:minExtent
                  maxExtent:nil.
     newView model:aModel.
-    newView controller:(StandardSystemController new view:newView).
+    newView controller:(self defaultController new view:newView).
     ^ newView
 !
 
@@ -165,20 +166,57 @@
     ]
 !
 
+reinitialize
+    "this is called right after snapIn"
+
+    |myController|
+
+    "if I have already been reinited - return"
+    drawableId notNil ifTrue:[
+        ^ self
+    ].
+
+    myController := controller.
+    controller := nil.
+    self recreate.
+
+    "if I was mapped, do it again"
+    realized ifTrue:[
+        "if it was iconified, try to remap iconified"
+        shown ifFalse:[
+            device mapView:self id:drawableId iconified:true
+                       atX:left y:top width:width height:height
+        ] ifTrue:[
+            device mapView:self id:drawableId iconified:false
+                       atX:left y:top width:width height:height
+        ].
+
+        "and restart the window-group process"
+        windowGroup notNil ifTrue:[
+            windowGroup startup
+        ]
+    ].
+
+    "restore controller"
+    controller := myController
+!
+
 recreate
     "recreate the view after a snap-in"
 
-    icon notNil ifTrue:[
-        icon depth ~~ 1 ifTrue:[
-            icon := icon asMonochromeFormOn:device.
+    icon := self convertedIcon.
+    super recreate.
+    iconView notNil ifTrue:[
+        iconView create.
+        device setWindowIconWindow:iconView in:drawableId
+    ] ifFalse:[
+        (icon notNil and:[icon id notNil]) ifTrue:[
+            device setWindowIcon:icon in:drawableId
         ].
-        icon notNil ifTrue:[
-            icon := icon on:device.
-        ]
     ].
-    super recreate.
-    (icon notNil and:[icon id notNil]) ifTrue:[
-        device setWindowIcon:icon in:drawableId
+
+    iconLabel notNil ifTrue:[
+        device setIconName:iconLabel in:drawableId
     ]
 !
 
@@ -207,24 +245,43 @@
     ].
 ! !
 
+!StandardSystemView methodsFor:'private'!
+
+convertedIcon
+    "make certain, that the icon is a b&w bitmap;
+     do so by converting if appropriate.
+     Will add a device supportsDeepIcons and only convert when needed;
+     for now (since there are only Xdisplays) we always have to convert."
+
+    |deviceIcon|
+
+    icon isNil ifTrue:[^ nil].
+
+    icon depth ~~ 1 ifTrue:[
+        deviceIcon := icon asMonochromeFormOn:device.
+    ] ifFalse:[
+        deviceIcon := icon
+    ].
+    deviceIcon notNil ifTrue:[
+        deviceIcon := deviceIcon on:device
+    ].
+    ^ deviceIcon
+! !
+
 !StandardSystemView methodsFor:'realization'!
 
 create
     "create - make certain that icon is available"
 
-    icon notNil ifTrue:[
-        icon depth ~~ 1 ifTrue:[
-            icon := icon asMonochromeFormOn:device.
-        ].
-        icon notNil ifTrue:[
-            icon := icon on:device
-        ].
-    ].
+    icon := self convertedIcon.
     super create.
 
     iconView notNil ifTrue:[
         iconView create.
         device setWindowIconWindow:iconView in:drawableId
+    ].
+    iconLabel notNil ifTrue:[
+        device setIconName:iconLabel in:drawableId
     ]
 !
 
@@ -264,7 +321,24 @@
     ]
 !
 
+iconLabel
+    "return the name displayed in the icon"
+
+    ^ iconLabel
+!
+
+iconLabel:aString
+    "define the name to be displayed in the icon"
+
+    iconLabel := aString.
+    drawableId notNil ifTrue:[
+        device setIconName:aString in:drawableId
+    ]
+!
+
 name
+    "return the topViews label"
+
     ^ label
 !
 
@@ -277,31 +351,29 @@
 icon:aForm
     "define the form (bitmap) used as icon"
 
-    |invertedIcon|
+    |invertedIcon i|
 
     icon := aForm.
-
     icon notNil ifTrue:[
-        icon depth == 1 ifTrue:[
-            "icons assume 1s as black - invert icon if the device thinks different"
-            (device depth == 1 and:[device whitepixel ~~ 0]) ifTrue:[
-                icon := icon on:device.
-                invertedIcon := Form width:icon width height:icon height on:device.
-                invertedIcon function:#copyInverted.
-                invertedIcon copyFrom:icon x:0 y:0 toX:0 y:0 width:icon width height:icon height.
-                icon := invertedIcon
-            ]
-        ].
-
         drawableId notNil ifTrue:[
             icon depth ~~ 1 ifTrue:[
                 icon := icon asMonochromeFormOn:device.
             ].
-            icon := icon on:device.
-            icon notNil ifTrue:[
-                icon id notNil ifTrue:[
-                    device setWindowIcon:icon in:drawableId
+            "icons assume 1s as black - invert icon if the device thinks different"
+            (device depth == 1 and:[device whitepixel ~~ 0]) ifTrue:[
+                i := icon on:device.
+                i notNil ifTrue:[
+                    invertedIcon := Form width:icon width height:icon height on:device.
+                    invertedIcon function:#copy.
+                    invertedIcon foreground:Color noColor background:Color allColor.
+                    invertedIcon copyFrom:i x:0 y:0 toX:0 y:0 width:icon width height:icon height.
+                    i := invertedIcon.
                 ]
+            ] ifFalse:[
+                i := icon on:device.
+            ].
+            (i notNil and:[i id notNil]) ifTrue:[
+                device setWindowIcon:i in:drawableId
             ]
         ]
     ]
@@ -324,21 +396,19 @@
 !
 
 iconName:aString
-    "define the name to be displayed in the icon"
+    "this method will vanish soon ... - for backward compatibility"
 
-    drawableId notNil ifTrue:[
-        device setIconName:aString in:drawableId
-    ]
+    self iconLabel:aString
 !
 
 maximumSize:anExtent
-    "maxExtent: for ST-80 compatibility"
+    "same as maxExtent: for ST-80 compatibility"
 
     ^ self maxExtent:anExtent
 !
 
 minimumSize:anExtent
-    "minExtent: for ST-80 compatibility"
+    "same as minExtent: for ST-80 compatibility"
 
     ^ self minExtent:anExtent
 !