more interfaces
authorclaus
Mon, 22 Aug 1994 15:14:25 +0200
changeset 64 b401612eb99c
parent 63 b9d17e2b6c92
child 65 7efd5bb4c298
more interfaces
GLXWorkstat.st
GLXWorkstation.st
--- a/GLXWorkstat.st	Fri Aug 12 01:45:37 1994 +0200
+++ b/GLXWorkstat.st	Mon Aug 22 15:14:25 1994 +0200
@@ -21,7 +21,7 @@
 COPYRIGHT (c) 1993 by Claus Gittinger
               All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.13 1994-08-22 13:14:25 claus Exp $
 '!
 
 %{
@@ -87,6 +87,9 @@
 
 #define SETWIN(aGLXWindowId)                             \
     if (_INST(activeWindow) != aGLXWindowId) {           \
+        if (! _isSmallInteger(aGLXWindowId)) {           \
+            RETURN (false);                              \
+        }                                                \
         if (GLXwinset(myDpy, MKWIN(aGLXWindowId)) < 0) { \
             RETURN (false);                              \
         }                                                \
@@ -202,7 +205,7 @@
         + (_intVal(_ClassInstPtr(_qClass(object))->c_ninstvars)) * sizeof(OBJ))
 
 /*
- * helper for rotation - call rot() for floats or fractions; rotate for integers
+ * helper for rotation - call rot()
  */
 static OBJ
 doRotate(angle, axis)
@@ -214,7 +217,8 @@
 
     if (__isFloat(angle)) {
         f_angle = (float)(_floatVal(angle));
-        rot(f_angle, axis);
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     if (__isFraction(angle)
@@ -225,12 +229,14 @@
         n = (float)(_intVal(_FractionInstPtr(angle)->f_numerator));
         d = (float)(_intVal(_FractionInstPtr(angle)->f_denominator));
         f_angle = n / d;
-        rot(f_angle, axis);
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     if (_isSmallInteger(angle)) {
-        a_angle = (Angle)(_intVal(angle));
-        rotate(a_angle, axis);
+        f_angle = (float)(_intVal(angle));
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     return false;
@@ -591,7 +597,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+$Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.13 1994-08-22 13:14:25 claus Exp $
 "
 !
 
@@ -604,26 +610,34 @@
     It provides an interface to either a real GL (on SGI workstations)
     or a simulated VGL (i.e. GL-light; low nicotine).
     The GL simulation is derived from the PD vogl library, with slight
-    modifiactions to support multiple GL views.
+    modifictions to support multiple GL views.
 
     Most of the hard work was done by Jeff (thanks indeed) ...
 
-    I do really not know what most of these functions do - for more
+
+    Some notes:
+
+    I do not really know what most of these functions do - for more
     detail, see the GL man pages (on SGI) or the doc provided with VGL.
 
     The interface offered here provides a very very low level (i.e one-to-one)
     interface to GL functions. More high-level stuff is required, to make
     3D drawing be more object-oriented. 
-    (see a bit of this in clients/IRIS-specials)
+    (see a bit of this in 'clients/IRIS-specials')
 
     Some functions are duplicated, Jeff and I developed those in parallel -
-    those will be merged - that is certain ...
+    those will be merged and duplicates removed ...
 
     Also, in a hurry to implement all those methods, many do no or only
     limited argument checking - make certain, that you pass the correct
     arguments.
 
-    $Header: /cvs/stx/stx/libview/Attic/GLXWorkstat.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+    There might be some confusion in the v3[sifd] functions: basically they
+    all do the same, and could be mapped onto one st-method (such as vertex3).
+    However, the C-functions expect different argument types - I dont know if
+    one or another of these functions suffers from any performance penalties.
+    Therefore, I leave the direct 1-to-1 mapping; GL experts might know more
+    about this (I use v3f in all of my code).
 
     written june 93 by claus
     VGL stuff dec 93
@@ -631,6 +645,8 @@
 
     Since this is a demo (consider it a free add-on goody) there is 
     *** NO WARRANTY ** for this.
+
+    Notice: this should be rewritten to use the openGL library functions
 "
 ! !
 
@@ -650,6 +666,20 @@
     RETURN ( true );
 #endif
 %}
+!
+
+supportsLight
+    "return true, if this gl workstation supports light (i.e.
+     if its a real GL)"
+%{  /* NOCONTEXT */
+
+#ifdef VGL
+    RETURN ( false );
+#endif
+#ifdef GLX
+    RETURN ( true );
+#endif
+%}
 ! !
 
 !GLXWorkstation methodsFor:'window creation'!
@@ -720,7 +750,7 @@
 %}
 ! !
 
-!GLXWorkstation methodsFor:'glx access'!
+!GLXWorkstation methodsFor:'viewing'!
 
 glxPerspectiveFovy:fovy aspect:aspect near:near far:far in:aGLXWindowId
     "define perspective projection"
@@ -768,6 +798,119 @@
 %}
 !
 
+glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
+    "define viewing transformation"
+
+%{  /* NOCONTEXT */
+
+    Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
+    Angle a_twist;
+
+    _COORD_ (vx, f_vx)
+    _COORD_ (vy, f_vy)
+    _COORD_ (vz, f_vz)
+    _COORD_ (px, f_px)
+    _COORD_ (py, f_py)
+    _COORD_ (pz, f_pz)
+    _ANGLE_ (twist, a_twist)
+    SETWIN(aGLXWindowId)
+    lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
+    RETURN (true);
+%}
+! 
+
+glxOrthoLeft: left right: right bottom: bottom top: top near: near far: far in: aGLXWindowId
+    "define orthogonal projection"
+
+%{  /* NOCONTEXT */
+    float f_left, f_right, f_bottom, f_top,
+          f_near, f_far;
+
+    _FLOAT_(left, f_left)
+    _FLOAT_(right, f_right)
+    _FLOAT_(bottom, f_bottom)
+    _FLOAT_(top, f_top)
+    _FLOAT_(near, f_near)
+    _FLOAT_(far, f_far)
+    SETWIN(aGLXWindowId)
+    ortho(f_left, f_right, f_bottom, f_top, f_near, f_far);
+    RETURN (true);
+%}
+!
+
+glxOrtho2Left: left right: right bottom: bottom top: top in: aGLXWindowId
+    "define 2D orthogonal projection"
+
+%{  /* NOCONTEXT */
+    float f_left, f_right, f_top, f_bottom;
+
+    SETWIN(aGLXWindowId)
+    _FLOAT_(left, f_left)
+    _FLOAT_(right, f_right)
+    _FLOAT_(bottom, f_bottom)
+    _FLOAT_(top, f_top)
+    ortho2(f_left, f_right, f_bottom, f_top);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxReshapeViewPortIn: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    reshapeviewport();
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'transformations'!
+
+glxTranslateX:x in:aGLXWindowId
+    "translate current matrix on X axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_x;
+
+    _COORD_ (x, c_x)
+    SETWIN(aGLXWindowId)
+    translate(c_x, (Coord)0, (Coord)0);
+    RETURN (true);
+%}
+!
+
+glxTranslateY:y in:aGLXWindowId
+    "translate current matrix on Y axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_y;
+
+    _COORD_ (y, c_y)
+    SETWIN(aGLXWindowId)
+    translate((Coord)0, c_y, (Coord)0);
+    RETURN (true);
+%}
+!
+
+glxTranslateZ:z in:aGLXWindowId
+    "translate current matrix on Z axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_z;
+
+    _COORD_ (z, c_z)
+    SETWIN(aGLXWindowId)
+    translate((Coord)0, (Coord)0, c_z);
+    RETURN (true);
+%}
+!
+
 glxTranslateX:x y:y z:z in:aGLXWindowId
     "translate current matrix, given individual x, y and z values"
 
@@ -799,6 +942,48 @@
 %}
 !
 
+glxScaleX:x in:aGLXWindowId
+    "scale in x direction"
+
+%{  /* NOCONTEXT */
+
+    float f_x;
+
+    _FLOAT_ (x, f_x)
+    SETWIN(aGLXWindowId)
+    scale(f_x, (float)0, (float)0);
+    RETURN (true);
+%}
+!
+
+glxScaleY:y in:aGLXWindowId
+    "scale in y direction"
+
+%{  /* NOCONTEXT */
+
+    float f_y;
+
+    _FLOAT_ (y, f_y)
+    SETWIN(aGLXWindowId)
+    scale((float)0, f_y, (float)0);
+    RETURN (true);
+%}
+!
+
+glxScaleZ:z in:aGLXWindowId
+    "scale in z direction"
+
+%{  /* NOCONTEXT */
+
+    float f_z;
+
+    _FLOAT_ (z, f_z)
+    SETWIN(aGLXWindowId)
+    scale((float)0, (float)0, f_z);
+    RETURN (true);
+%}
+!
+
 glxScaleX:x y:y z:z in:aGLXWindowId
     "scale & mirror current matrix, given individual x, y and z values"
 
@@ -832,7 +1017,7 @@
 
 glxRotateX:angle in:aGLXWindowId
     "rotate the current matrix on x axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -845,7 +1030,7 @@
 
 glxRotateY:angle in:aGLXWindowId
     "rotate the current matrix on y axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -858,7 +1043,7 @@
 
 glxRotateZ:angle in:aGLXWindowId
     "rotate the current matrix on z axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -872,7 +1057,7 @@
 glxRotate:angle axis:axis in:aGLXWindowId
     "rotate the current matrix around the axis given by the axis arg,
      which must be one of the symbols: #x, #y or #z.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -895,7 +1080,7 @@
 
 glxRotateX:xAngle y:yAngle z:zAngle in:aGLXWindowId
     "rotate the current matrix on all axes, given individual x, y and z values.
-     The values may be floats (degrees) or integers (tenth of a degree)."
+     The values are in degrees"
 
 %{  /* NOCONTEXT */
 
@@ -911,8 +1096,8 @@
 !
 
 glxRotate:arrayOf3Floats in:aGLXWindowId
-    "rotate current matrix, given a 3-element vector.
-     The elements of the array must be floats (degrees)."
+    "rotate current matrix, given a 3-element vector (or more).
+     The elements of the array are degrees."
 
 %{  /* NOCONTEXT */
 
@@ -928,27 +1113,105 @@
 %}
 !
 
-glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
-    "define viewing transformation"
-
-%{  /* NOCONTEXT */
-
-    Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
-    Angle a_twist;
-
-    _COORD_ (vx, f_vx)
-    _COORD_ (vy, f_vy)
-    _COORD_ (vz, f_vz)
-    _COORD_ (px, f_px)
-    _COORD_ (py, f_py)
-    _COORD_ (pz, f_pz)
-    _ANGLE_ (twist, a_twist)
-    SETWIN(aGLXWindowId)
-    lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
-    RETURN (true);
-%}
+glxRotateIX:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'x');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIY:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'y');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIZ:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'z');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
 !
 
+glxRotateI:angle axis:axis in:aGLXWindowId
+    "rotate the current matrix around the axis given by the axis arg,
+     which must be one of the symbols: #x, #y or #z.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    char c_axis;
+
+    if (axis == @symbol(x))
+        c_axis = 'x';
+    else if (axis == @symbol(y))
+        c_axis = 'y';
+    else if (axis == @symbol(z))
+        c_axis = 'z';
+    else {
+        RETURN (false);
+    }
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), c_axis);
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIX:xAngle y:yAngle z:zAngle in:aGLXWindowId
+    "rotate the current matrix on all axes, given individual x, y and z values.
+     The values are integers specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(xAngle)
+     && _isSmallInteger(yAngle)
+     && _isSmallInteger(zAngle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(xAngle), 'x');
+        rotate(_intVal(yAngle), 'y');
+        rotate(_intVal(zAngle), 'z');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'materials & lights'!
+
 glxLmdef:what index:index np:np props:props in:aGLXWindowId
     "define a material, light source or lighting model;
      props must be a FloatArray or a subclass of FloatArray"
@@ -1040,7 +1303,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'color'!
 
 glxColor:index in:aGLXWindowId
     "set color, for non gouraud shading, we dont care if the
@@ -1081,7 +1346,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'clearing'!
 
 glxClearIn:aGLXWindowId
     "clear to current color"
@@ -1107,7 +1374,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'matrix stack'!
 
 glxPushmatrixIn:aGLXWindowId
     "push down transformation stack"
@@ -1133,6 +1402,69 @@
     ^ false
 !
 
+glxGetMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array (a matrix) of 16 floats. The current matrix
+     will be stored into that."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+
+    SETWIN(aGLXWindowId)
+    getmatrix(matrix);
+    if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
+%}
+.
+    ^ true
+!
+
+glxLoadMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array(a matrix) of 16 floats. The current matrix
+     will be loaded from that."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+    Matrix *m;
+
+    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
+    SETWIN(aGLXWindowId)
+    loadmatrix(*m);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxMultMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array(a matrix) of 16 floats containing a
+     matrix to multiply into the current matrix."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+    Matrix *m;
+
+    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
+    SETWIN(aGLXWindowId)
+    multmatrix(*m);
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'double buffering'!
+
+glxDoubleBufferIn:aGLXWindowId
+    "set double buffer mode"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    doublebuffer();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
 glxSwapBuffersIn:aGLXWindowId
     "swap double buffers"
 
@@ -1145,6 +1477,164 @@
     ^ false
 !
 
+glxFrontBufferIn:aGLXWindowId
+    "switch to front buffer - turning backbuffer off"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    backbuffer(FALSE);
+#endif
+    frontbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackBufferIn:aGLXWindowId
+    "switch to back buffer - turning frontbuffer off"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    frontbuffer(FALSE);
+#endif
+    backbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackbuffer: b in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    backbuffer(_booleanVal(b));
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxFrontbuffer: b in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    frontbuffer(_booleanVal(b));
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'zbuffer'!
+
+glxZbuffer:aBoolean in:aGLXWindowId
+    "enable/disable z-buffer operation"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zbuffer(aBoolean == false ? FALSE : TRUE);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZbsize: planes in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef FULL_GLX
+    SETWIN(aGLXWindowId)
+    zbsize(_longVal(planes));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZdraw: b in: aGLXWindowId
+    "enable/disable drawing into the z-buffer"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zdraw(_booleanVal(b));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZfunction: func in: aGLXWindowId
+    "set the z-buffer comparison function.
+     func may be either the numeric value or a symbol (preferred)"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    long f;
+
+    SETWIN(aGLXWindowId)
+    if (func == @symbol(NEVER))
+        f = ZF_NEVER;
+    else if (func == @symbol(LESS))
+        f = ZF_LESS;
+    else if (func == @symbol(EQUAL))
+        f = ZF_EQUAL;
+    else if (func == @symbol(LEQUAL))
+        f = ZF_LEQUAL;
+    else if (func == @symbol(GREATER))
+        f = ZF_GREATER;
+    else if (func == @symbol(NOTEQUAL))
+        f = ZF_NOTEQUAL;
+    else if (func == @symbol(GEQUAL))
+        f = ZF_GEQUAL;
+    else if (func == @symbol(ALWAYS))
+        f = ZF_ALWAYS;
+    else
+        f = _longVal(func);
+    zfunction(f);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZsource: src in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zsource(_longVal(src));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZwritemask: mask in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zwritemask((ulong)_intVal(mask));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'misc'!
+
 glxRGBmodeIn:aGLXWindowId
     "set true color mode (no colormap)"
 
@@ -1159,18 +1649,6 @@
     ^ false
 !
 
-glxDoubleBufferIn:aGLXWindowId
-    "set double buffer mode"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    doublebuffer();
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
 glxGconfigIn:aGLXWindowId
     "must be sent after RGBmode, doubleBuffer etc. to have these
      changes really take effect. See GLX manual.
@@ -1185,20 +1663,6 @@
     ^ false
 !
 
-glxZbuffer:aBoolean in:aGLXWindowId
-    "enable/disable z-buffer operation"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zbuffer(aBoolean == false ? FALSE : TRUE);
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
 glxNmode:aSymbol in:aGLXWindowId
     "set normalize mode: #auto, #normalize"
 
@@ -1243,31 +1707,9 @@
 %}
 .
     ^ false
-!
-
-glxBeginPolygonIn:aGLXWindowId
-    "start a polygon"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    bgnpolygon();
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxEndPolygonIn:aGLXWindowId
-    "end a polygon"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    endpolygon();
-    RETURN (true);
-%}
-.
-    ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'flat drawing'!
 
 glxBeginPointIn:aGLXWindowId
     "start a point-group"
@@ -1293,12 +1735,6 @@
     ^ false
 !
 
-glxBeginCloseLineIn:aGLXWindowId
-    "will vanish"
-
-    self glxBeginClosedLineIn:aGLXWindowId
-!
-
 glxBeginClosedLineIn:aGLXWindowId
     "start a closed line"
 
@@ -1347,6 +1783,30 @@
     ^ false
 !
 
+glxBeginPolygonIn:aGLXWindowId
+    "start a polygon"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    bgnpolygon();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxEndPolygonIn:aGLXWindowId
+    "end a polygon"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    endpolygon();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
 glxBeginTriangleMeshIn:aGLXWindowId
     "start a triangle mesh"
 
@@ -1371,34 +1831,6 @@
     ^ false
 !
 
-glxBeginSurfaceIn:aGLXWindowId
-    "start a NURBS surface def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    bgnsurface();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
-glxEndSurfaceIn:aGLXWindowId
-    "end a NURBS surface def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    endsurface();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
 glxBeginQuadrilateralStripIn:aGLXWindowId
     "start a quadrilateral strip"
 
@@ -1421,35 +1853,9 @@
 %}
 .
     ^ false
-!
-
-glxBeginCurveIn:aGLXWindowId
-    "start a NURBS curve def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    bgncurve();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
-glxEndCurveIn:aGLXWindowId
-    "end a NURBS curve def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    endcurve();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'sphere drawing'!
 
 glxSphDraw:arrayOf4Floats in:aGLXWindowId
     "argument must be an array(a matrix) of 4 floats containing the
@@ -1467,7 +1873,29 @@
 %}
 .
     ^ false
-!
+! 
+
+glxSphDrawX:x y:y z:z radius:r in:aGLXWindowId
+    "arguments must be convertable to floats - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    float vec[4];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    _FLOAT_(z, vec[2])
+    _FLOAT_(r, vec[3])
+    SETWIN(aGLXWindowId)
+    sphdraw(vec);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'patches & surfaces'!
 
 glxDefBasis:id mat:aMatrix in:aGLXWindowId
     "define the basis"
@@ -1547,67 +1975,55 @@
     ^ false
 !
 
-glxGetMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-
-    SETWIN(aGLXWindowId)
-    getmatrix(matrix);
-    if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
-    RETURN (true);
+glxBeginCurveIn:aGLXWindowId
+    "start a NURBS curve def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    bgncurve();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxLoadMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     transformation matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-    Matrix *m;
-
-    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
-    SETWIN(aGLXWindowId)
-    loadmatrix(*m);
-    RETURN (true);
+glxEndCurveIn:aGLXWindowId
+    "end a NURBS curve def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    endcurve();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxMultMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-    Matrix *m;
-
-    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
-    SETWIN(aGLXWindowId)
-    multmatrix(*m);
-    RETURN (true);
+glxBeginSurfaceIn:aGLXWindowId
+    "start a NURBS surface def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    bgnsurface();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxN3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the
-     current vertex normal - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    float vec[3], *v;
-
-    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    n3f(v);
+glxEndSurfaceIn:aGLXWindowId
+    "end a NURBS surface def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    endsurface();
     RETURN (true);
 #endif
 %}
@@ -1656,39 +2072,231 @@
 %}
 .
     ^ false
-
-! 
-
-glxOrthoLeft: left right: right bottom: bottom top: top near: near far: far in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float f_left, f_right, f_bottom, f_top,
-          f_near, f_far;
-
-    _FLOAT_(left, f_left)
-    _FLOAT_(right, f_right)
-    _FLOAT_(bottom, f_bottom)
-    _FLOAT_(top, f_top)
-    _FLOAT_(near, f_near)
-    _FLOAT_(far, f_far)
-    SETWIN(aGLXWindowId)
-    ortho(f_left, f_right, f_bottom, f_top, f_near, f_far);
-    RETURN (true);
-%}
+! !
+
+!GLXWorkstation methodsFor:'arcs and circles '!
+
+glxArcX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _COORD_(x, c_x)
+    _COORD_(y, c_y)
+    _COORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arc(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+! 
+
+glxArciX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _ICOORD_(x, c_x)
+    _ICOORD_(y, c_y)
+    _ICOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arci(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _SCOORD_(x, c_x)
+    _SCOORD_(y, c_y)
+    _SCOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcs(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _COORD_(x, c_x)
+    _COORD_(y, c_y)
+    _COORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcf(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfiX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _ICOORD_(x, c_x)
+    _ICOORD_(y, c_y)
+    _ICOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang);
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcfi(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _SCOORD_(x, c_x)
+    _SCOORD_(y, c_y)
+    _SCOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcfs(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
 !
 
-glxReshapeViewPortIn: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    reshapeviewport();
+glxCircX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+
+    _COORD_ (x, c_x)
+    _COORD_ (y, c_y)
+    _COORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circ(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCirciX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+
+    _ICOORD_ (x, c_x)
+    _ICOORD_ (y, c_y)
+    _ICOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circi(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircsX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+
+    _SCOORD_ (x, c_x)
+    _SCOORD_ (y, c_y)
+    _SCOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circs(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+
+    _COORD_ (x, c_x)
+    _COORD_ (y, c_y)
+    _COORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circf(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfiX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+
+    _ICOORD_ (x, c_x)
+    _ICOORD_ (y, c_y)
+    _ICOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circfi(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfsX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+
+    _SCOORD_ (x, c_x)
+    _SCOORD_ (y, c_y)
+    _SCOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circfs(c_x, c_y, c_radius);
     RETURN (true);
 %}
 .
     ^ false
 ! !
 
-!GLXWorkstation methodsFor:'new glx access'!
+!GLXWorkstation methodsFor:'unspecified rest '!
 
 glxAcbufOp: op value: value in: aGLXWindowId
 
@@ -1729,118 +2337,6 @@
     ^ false
 ! 
 
-glxArcX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _COORD_(x, c_x)
-    _COORD_(y, c_y)
-    _COORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arc(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-! 
-
-glxArciX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _ICOORD_(x, c_x)
-    _ICOORD_(y, c_y)
-    _ICOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arci(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _SCOORD_(x, c_x)
-    _SCOORD_(y, c_y)
-    _SCOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcs(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _COORD_(x, c_x)
-    _COORD_(y, c_y)
-    _COORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcf(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfiX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _ICOORD_(x, c_x)
-    _ICOORD_(y, c_y)
-    _ICOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang);
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcfi(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _SCOORD_(x, c_x)
-    _SCOORD_(y, c_y)
-    _SCOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcfs(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxBackface: b in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -1852,58 +2348,6 @@
     ^ false
 ! 
 
-glxFrontBufferIn:aGLXWindowId
-    "switch to front buffer - turning backbuffer off"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-#ifdef GLX
-    backbuffer(FALSE);
-#endif
-    frontbuffer(TRUE);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxBackBufferIn:aGLXWindowId
-    "switch to back buffer - turning frontbuffer off"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-#ifdef GLX
-    frontbuffer(FALSE);
-#endif
-    backbuffer(TRUE);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxBackbuffer: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    backbuffer(_booleanVal(b));
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxFrontbuffer: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    frontbuffer(_booleanVal(b));
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxBbox2Xmin: xmin ymin: ymin x1: x1 y1: y1 x2: x2 y2: y2 in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -2198,102 +2642,6 @@
     ^ false
 !
 
-glxCircX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-
-    _COORD_ (x, c_x)
-    _COORD_ (y, c_y)
-    _COORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circ(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCirciX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-
-    _ICOORD_ (x, c_x)
-    _ICOORD_ (y, c_y)
-    _ICOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circi(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircsX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-
-    _SCOORD_ (x, c_x)
-    _SCOORD_ (y, c_y)
-    _SCOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circs(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-
-    _COORD_ (x, c_x)
-    _COORD_ (y, c_y)
-    _COORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circf(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfiX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-
-    _ICOORD_ (x, c_x)
-    _ICOORD_ (y, c_y)
-    _ICOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circfi(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfsX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-
-    _SCOORD_ (x, c_x)
-    _SCOORD_ (y, c_y)
-    _SCOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circfs(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxClearhitcodeIn: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -4128,23 +4476,6 @@
     ^ false
 ! 
 
-glxOrtho2Left: left right: right bottom: bottom top: top in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float f_left, f_right, f_top, f_bottom;
-
-    SETWIN(aGLXWindowId)
-    _FLOAT_(left, f_left)
-    _FLOAT_(right, f_right)
-    _FLOAT_(bottom, f_bottom)
-    _FLOAT_(top, f_top)
-    ortho2(f_left, f_right, f_bottom, f_top);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
 glxOverlayPlanes: planes in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -6175,195 +6506,9 @@
 %}
 .
     ^ false
-! 
-
-glxV2s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[2], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
 !
 
-glxV2i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[2], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV2f: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float vec[2], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV2d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[2], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[3], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[3], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3f: v in: aGLXWindowId
-    "pass a vector; v must be a 3-element float-vector"
-
-%{  /* NOCONTEXT */
-    float vec[3], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxVxf:x yf:y zf:z in: aGLXWindowId
-    "pass a vector from individual x, y and z values"
-
-%{  /* NOCONTEXT */
-    float vec[3];
-
-    _FLOAT_(x, vec[0])
-    _FLOAT_(y, vec[1])
-    _FLOAT_(z, vec[2])
-    SETWIN(aGLXWindowId)
-    v3f(vec);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[3], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[4], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[4], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4f: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float vec[4], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[4], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxVideocmd: cmd in: aGLXWindowId
+glxVideocmd:cmd in:aGLXWindowId
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -6376,7 +6521,7 @@
     ^ false
 ! 
 
-glxViewportLeft: left right: right bottom: bottom top: top in: aGLXWindowId
+glxViewportLeft:left right:right bottom:bottom top:top in:aGLXWindowId
 
 %{  /* NOCONTEXT */
     SETWIN(aGLXWindowId)
@@ -6384,11 +6529,9 @@
              _screencoordVal(bottom), _screencoordVal(top));
     RETURN (true);
 %}
-.
-    ^ false
-! 
-
-glxWinclose: gwid in: aGLXWindowId
+! 
+
+glxWinclose:gwid in:aGLXWindowId
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -6689,69 +6832,271 @@
 %}
 .
     ^ false
-! 
-
-glxZbsize: planes in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef FULL_GLX
-    SETWIN(aGLXWindowId)
-    zbsize(_longVal(planes));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZdraw: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zdraw(_booleanVal(b));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZfunction: func in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zfunction(_longVal(func));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZsource: src in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zsource(_longVal(src));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZwritemask: mask in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zwritemask((ulong)_intVal(mask));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
 ! !
+
+!GLXWorkstation methodsFor:'vertex data transfer '!
+
+glxV2s:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 shorts; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    short vec[2], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2i:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 longs; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    long vec[2], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2f:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 floats; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    float vec[2], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2d:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 doubles; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    double vec[2], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2d(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2fX:x y:y in:aGLXWindowId
+    "pass a vertex from individual x and y values; z is taken as 0.0"
+
+%{  /* NOCONTEXT */
+    float vec[2];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    SETWIN(aGLXWindowId)
+    v2f(vec);
+    RETURN (true);
+%}
+!
+
+glxV3s:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 3 shorts"
+
+%{  /* NOCONTEXT */
+    short vec[3], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3i:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 3 longs"
+
+%{  /* NOCONTEXT */
+    long vec[3], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3f:v in:aGLXWindowId
+    "pass a vertex; v must be a 3-element float-vector"
+
+%{  /* NOCONTEXT */
+    float vec[3], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3fX:x y:y z:z in: aGLXWindowId
+    "pass a vector from individual x, y and z (float) values"
+
+%{  /* NOCONTEXT */
+    float vec[3];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    _FLOAT_(z, vec[2])
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVOriginIn:aGLXWindowId
+    "pass a 0.0/0.0/0.0 vector.
+     This is the same as v3f:#(0.0 0.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 0.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitXIn:aGLXWindowId
+    "pass a 1.0/0.0/0.0 vector.
+     This is the same as v3f:#(1.0 0.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {1.0, 0.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitYIn:aGLXWindowId
+    "pass a 0.0/1.0/0.0 vector.
+     This is the same as v3f:#(0.0 1.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 1.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitZIn:aGLXWindowId
+    "pass a 0.0/0.0/1.0 vector.
+     This is the same as v3f:#(0.0 0.0 1.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 0.0, 1.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxV3d:v in:aGLXWindowId
+    "pass a vertex; v must be a 3-element double-vector"
+
+%{  /* NOCONTEXT */
+    double vec[3], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3d(c_v);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxN3f:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the
+     current vertex normal - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    n3f(v);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+!
+
+glxV4s:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element short-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    short vec[4], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4i:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element int-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    long vec[4], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4f:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element float-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    float vec[4], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4d:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element double-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    double vec[4], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4d(c_v);
+    RETURN (true);
+%}
+! !
--- a/GLXWorkstation.st	Fri Aug 12 01:45:37 1994 +0200
+++ b/GLXWorkstation.st	Mon Aug 22 15:14:25 1994 +0200
@@ -21,7 +21,7 @@
 COPYRIGHT (c) 1993 by Claus Gittinger
               All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.13 1994-08-22 13:14:25 claus Exp $
 '!
 
 %{
@@ -87,6 +87,9 @@
 
 #define SETWIN(aGLXWindowId)                             \
     if (_INST(activeWindow) != aGLXWindowId) {           \
+        if (! _isSmallInteger(aGLXWindowId)) {           \
+            RETURN (false);                              \
+        }                                                \
         if (GLXwinset(myDpy, MKWIN(aGLXWindowId)) < 0) { \
             RETURN (false);                              \
         }                                                \
@@ -202,7 +205,7 @@
         + (_intVal(_ClassInstPtr(_qClass(object))->c_ninstvars)) * sizeof(OBJ))
 
 /*
- * helper for rotation - call rot() for floats or fractions; rotate for integers
+ * helper for rotation - call rot()
  */
 static OBJ
 doRotate(angle, axis)
@@ -214,7 +217,8 @@
 
     if (__isFloat(angle)) {
         f_angle = (float)(_floatVal(angle));
-        rot(f_angle, axis);
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     if (__isFraction(angle)
@@ -225,12 +229,14 @@
         n = (float)(_intVal(_FractionInstPtr(angle)->f_numerator));
         d = (float)(_intVal(_FractionInstPtr(angle)->f_denominator));
         f_angle = n / d;
-        rot(f_angle, axis);
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     if (_isSmallInteger(angle)) {
-        a_angle = (Angle)(_intVal(angle));
-        rotate(a_angle, axis);
+        f_angle = (float)(_intVal(angle));
+        if (f_angle != 0.0)
+            rot(f_angle, axis);
         return (true);
     }
     return false;
@@ -591,7 +597,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.13 1994-08-22 13:14:25 claus Exp $
 "
 !
 
@@ -604,26 +610,34 @@
     It provides an interface to either a real GL (on SGI workstations)
     or a simulated VGL (i.e. GL-light; low nicotine).
     The GL simulation is derived from the PD vogl library, with slight
-    modifiactions to support multiple GL views.
+    modifictions to support multiple GL views.
 
     Most of the hard work was done by Jeff (thanks indeed) ...
 
-    I do really not know what most of these functions do - for more
+
+    Some notes:
+
+    I do not really know what most of these functions do - for more
     detail, see the GL man pages (on SGI) or the doc provided with VGL.
 
     The interface offered here provides a very very low level (i.e one-to-one)
     interface to GL functions. More high-level stuff is required, to make
     3D drawing be more object-oriented. 
-    (see a bit of this in clients/IRIS-specials)
+    (see a bit of this in 'clients/IRIS-specials')
 
     Some functions are duplicated, Jeff and I developed those in parallel -
-    those will be merged - that is certain ...
+    those will be merged and duplicates removed ...
 
     Also, in a hurry to implement all those methods, many do no or only
     limited argument checking - make certain, that you pass the correct
     arguments.
 
-    $Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.12 1994-08-11 23:42:03 claus Exp $
+    There might be some confusion in the v3[sifd] functions: basically they
+    all do the same, and could be mapped onto one st-method (such as vertex3).
+    However, the C-functions expect different argument types - I dont know if
+    one or another of these functions suffers from any performance penalties.
+    Therefore, I leave the direct 1-to-1 mapping; GL experts might know more
+    about this (I use v3f in all of my code).
 
     written june 93 by claus
     VGL stuff dec 93
@@ -631,6 +645,8 @@
 
     Since this is a demo (consider it a free add-on goody) there is 
     *** NO WARRANTY ** for this.
+
+    Notice: this should be rewritten to use the openGL library functions
 "
 ! !
 
@@ -650,6 +666,20 @@
     RETURN ( true );
 #endif
 %}
+!
+
+supportsLight
+    "return true, if this gl workstation supports light (i.e.
+     if its a real GL)"
+%{  /* NOCONTEXT */
+
+#ifdef VGL
+    RETURN ( false );
+#endif
+#ifdef GLX
+    RETURN ( true );
+#endif
+%}
 ! !
 
 !GLXWorkstation methodsFor:'window creation'!
@@ -720,7 +750,7 @@
 %}
 ! !
 
-!GLXWorkstation methodsFor:'glx access'!
+!GLXWorkstation methodsFor:'viewing'!
 
 glxPerspectiveFovy:fovy aspect:aspect near:near far:far in:aGLXWindowId
     "define perspective projection"
@@ -768,6 +798,119 @@
 %}
 !
 
+glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
+    "define viewing transformation"
+
+%{  /* NOCONTEXT */
+
+    Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
+    Angle a_twist;
+
+    _COORD_ (vx, f_vx)
+    _COORD_ (vy, f_vy)
+    _COORD_ (vz, f_vz)
+    _COORD_ (px, f_px)
+    _COORD_ (py, f_py)
+    _COORD_ (pz, f_pz)
+    _ANGLE_ (twist, a_twist)
+    SETWIN(aGLXWindowId)
+    lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
+    RETURN (true);
+%}
+! 
+
+glxOrthoLeft: left right: right bottom: bottom top: top near: near far: far in: aGLXWindowId
+    "define orthogonal projection"
+
+%{  /* NOCONTEXT */
+    float f_left, f_right, f_bottom, f_top,
+          f_near, f_far;
+
+    _FLOAT_(left, f_left)
+    _FLOAT_(right, f_right)
+    _FLOAT_(bottom, f_bottom)
+    _FLOAT_(top, f_top)
+    _FLOAT_(near, f_near)
+    _FLOAT_(far, f_far)
+    SETWIN(aGLXWindowId)
+    ortho(f_left, f_right, f_bottom, f_top, f_near, f_far);
+    RETURN (true);
+%}
+!
+
+glxOrtho2Left: left right: right bottom: bottom top: top in: aGLXWindowId
+    "define 2D orthogonal projection"
+
+%{  /* NOCONTEXT */
+    float f_left, f_right, f_top, f_bottom;
+
+    SETWIN(aGLXWindowId)
+    _FLOAT_(left, f_left)
+    _FLOAT_(right, f_right)
+    _FLOAT_(bottom, f_bottom)
+    _FLOAT_(top, f_top)
+    ortho2(f_left, f_right, f_bottom, f_top);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxReshapeViewPortIn: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    reshapeviewport();
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'transformations'!
+
+glxTranslateX:x in:aGLXWindowId
+    "translate current matrix on X axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_x;
+
+    _COORD_ (x, c_x)
+    SETWIN(aGLXWindowId)
+    translate(c_x, (Coord)0, (Coord)0);
+    RETURN (true);
+%}
+!
+
+glxTranslateY:y in:aGLXWindowId
+    "translate current matrix on Y axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_y;
+
+    _COORD_ (y, c_y)
+    SETWIN(aGLXWindowId)
+    translate((Coord)0, c_y, (Coord)0);
+    RETURN (true);
+%}
+!
+
+glxTranslateZ:z in:aGLXWindowId
+    "translate current matrix on Z axis"
+
+%{  /* NOCONTEXT */
+
+    Coord c_z;
+
+    _COORD_ (z, c_z)
+    SETWIN(aGLXWindowId)
+    translate((Coord)0, (Coord)0, c_z);
+    RETURN (true);
+%}
+!
+
 glxTranslateX:x y:y z:z in:aGLXWindowId
     "translate current matrix, given individual x, y and z values"
 
@@ -799,6 +942,48 @@
 %}
 !
 
+glxScaleX:x in:aGLXWindowId
+    "scale in x direction"
+
+%{  /* NOCONTEXT */
+
+    float f_x;
+
+    _FLOAT_ (x, f_x)
+    SETWIN(aGLXWindowId)
+    scale(f_x, (float)0, (float)0);
+    RETURN (true);
+%}
+!
+
+glxScaleY:y in:aGLXWindowId
+    "scale in y direction"
+
+%{  /* NOCONTEXT */
+
+    float f_y;
+
+    _FLOAT_ (y, f_y)
+    SETWIN(aGLXWindowId)
+    scale((float)0, f_y, (float)0);
+    RETURN (true);
+%}
+!
+
+glxScaleZ:z in:aGLXWindowId
+    "scale in z direction"
+
+%{  /* NOCONTEXT */
+
+    float f_z;
+
+    _FLOAT_ (z, f_z)
+    SETWIN(aGLXWindowId)
+    scale((float)0, (float)0, f_z);
+    RETURN (true);
+%}
+!
+
 glxScaleX:x y:y z:z in:aGLXWindowId
     "scale & mirror current matrix, given individual x, y and z values"
 
@@ -832,7 +1017,7 @@
 
 glxRotateX:angle in:aGLXWindowId
     "rotate the current matrix on x axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -845,7 +1030,7 @@
 
 glxRotateY:angle in:aGLXWindowId
     "rotate the current matrix on y axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -858,7 +1043,7 @@
 
 glxRotateZ:angle in:aGLXWindowId
     "rotate the current matrix on z axis.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -872,7 +1057,7 @@
 glxRotate:angle axis:axis in:aGLXWindowId
     "rotate the current matrix around the axis given by the axis arg,
      which must be one of the symbols: #x, #y or #z.
-     The angle may be a float (degrees) or integer (tenth of a degree)."
+     The angle is in degrees."
 
 %{  /* NOCONTEXT */
 
@@ -895,7 +1080,7 @@
 
 glxRotateX:xAngle y:yAngle z:zAngle in:aGLXWindowId
     "rotate the current matrix on all axes, given individual x, y and z values.
-     The values may be floats (degrees) or integers (tenth of a degree)."
+     The values are in degrees"
 
 %{  /* NOCONTEXT */
 
@@ -911,8 +1096,8 @@
 !
 
 glxRotate:arrayOf3Floats in:aGLXWindowId
-    "rotate current matrix, given a 3-element vector.
-     The elements of the array must be floats (degrees)."
+    "rotate current matrix, given a 3-element vector (or more).
+     The elements of the array are degrees."
 
 %{  /* NOCONTEXT */
 
@@ -928,27 +1113,105 @@
 %}
 !
 
-glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist in:aGLXWindowId
-    "define viewing transformation"
-
-%{  /* NOCONTEXT */
-
-    Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
-    Angle a_twist;
-
-    _COORD_ (vx, f_vx)
-    _COORD_ (vy, f_vy)
-    _COORD_ (vz, f_vz)
-    _COORD_ (px, f_px)
-    _COORD_ (py, f_py)
-    _COORD_ (pz, f_pz)
-    _ANGLE_ (twist, a_twist)
-    SETWIN(aGLXWindowId)
-    lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
-    RETURN (true);
-%}
+glxRotateIX:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'x');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIY:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'y');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIZ:angle in:aGLXWindowId
+    "rotate the current matrix on x axis.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), 'z');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
 !
 
+glxRotateI:angle axis:axis in:aGLXWindowId
+    "rotate the current matrix around the axis given by the axis arg,
+     which must be one of the symbols: #x, #y or #z.
+     The angle is an integer specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    char c_axis;
+
+    if (axis == @symbol(x))
+        c_axis = 'x';
+    else if (axis == @symbol(y))
+        c_axis = 'y';
+    else if (axis == @symbol(z))
+        c_axis = 'z';
+    else {
+        RETURN (false);
+    }
+
+    if (_isSmallInteger(angle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(angle), c_axis);
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+!
+
+glxRotateIX:xAngle y:yAngle z:zAngle in:aGLXWindowId
+    "rotate the current matrix on all axes, given individual x, y and z values.
+     The values are integers specifying tenths of a degree."
+
+%{  /* NOCONTEXT */
+
+    if (_isSmallInteger(xAngle)
+     && _isSmallInteger(yAngle)
+     && _isSmallInteger(zAngle)) {
+        SETWIN(aGLXWindowId)
+        rotate(_intVal(xAngle), 'x');
+        rotate(_intVal(yAngle), 'y');
+        rotate(_intVal(zAngle), 'z');
+        RETURN (true);
+    }
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'materials & lights'!
+
 glxLmdef:what index:index np:np props:props in:aGLXWindowId
     "define a material, light source or lighting model;
      props must be a FloatArray or a subclass of FloatArray"
@@ -1040,7 +1303,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'color'!
 
 glxColor:index in:aGLXWindowId
     "set color, for non gouraud shading, we dont care if the
@@ -1081,7 +1346,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'clearing'!
 
 glxClearIn:aGLXWindowId
     "clear to current color"
@@ -1107,7 +1374,9 @@
 %}
 .
     ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'matrix stack'!
 
 glxPushmatrixIn:aGLXWindowId
     "push down transformation stack"
@@ -1133,6 +1402,69 @@
     ^ false
 !
 
+glxGetMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array (a matrix) of 16 floats. The current matrix
+     will be stored into that."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+
+    SETWIN(aGLXWindowId)
+    getmatrix(matrix);
+    if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
+%}
+.
+    ^ true
+!
+
+glxLoadMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array(a matrix) of 16 floats. The current matrix
+     will be loaded from that."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+    Matrix *m;
+
+    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
+    SETWIN(aGLXWindowId)
+    loadmatrix(*m);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxMultMatrix:arrayOf16Floats in:aGLXWindowId
+    "argument must be an array(a matrix) of 16 floats containing a
+     matrix to multiply into the current matrix."
+
+%{  /* NOCONTEXT */
+    Matrix matrix;
+    Matrix *m;
+
+    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
+    SETWIN(aGLXWindowId)
+    multmatrix(*m);
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'double buffering'!
+
+glxDoubleBufferIn:aGLXWindowId
+    "set double buffer mode"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    doublebuffer();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
 glxSwapBuffersIn:aGLXWindowId
     "swap double buffers"
 
@@ -1145,6 +1477,164 @@
     ^ false
 !
 
+glxFrontBufferIn:aGLXWindowId
+    "switch to front buffer - turning backbuffer off"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    backbuffer(FALSE);
+#endif
+    frontbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackBufferIn:aGLXWindowId
+    "switch to back buffer - turning frontbuffer off"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+#ifdef GLX
+    frontbuffer(FALSE);
+#endif
+    backbuffer(TRUE);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxBackbuffer: b in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    backbuffer(_booleanVal(b));
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxFrontbuffer: b in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    frontbuffer(_booleanVal(b));
+    RETURN (true);
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'zbuffer'!
+
+glxZbuffer:aBoolean in:aGLXWindowId
+    "enable/disable z-buffer operation"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zbuffer(aBoolean == false ? FALSE : TRUE);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZbsize: planes in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef FULL_GLX
+    SETWIN(aGLXWindowId)
+    zbsize(_longVal(planes));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZdraw: b in: aGLXWindowId
+    "enable/disable drawing into the z-buffer"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zdraw(_booleanVal(b));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZfunction: func in: aGLXWindowId
+    "set the z-buffer comparison function.
+     func may be either the numeric value or a symbol (preferred)"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    long f;
+
+    SETWIN(aGLXWindowId)
+    if (func == @symbol(NEVER))
+        f = ZF_NEVER;
+    else if (func == @symbol(LESS))
+        f = ZF_LESS;
+    else if (func == @symbol(EQUAL))
+        f = ZF_EQUAL;
+    else if (func == @symbol(LEQUAL))
+        f = ZF_LEQUAL;
+    else if (func == @symbol(GREATER))
+        f = ZF_GREATER;
+    else if (func == @symbol(NOTEQUAL))
+        f = ZF_NOTEQUAL;
+    else if (func == @symbol(GEQUAL))
+        f = ZF_GEQUAL;
+    else if (func == @symbol(ALWAYS))
+        f = ZF_ALWAYS;
+    else
+        f = _longVal(func);
+    zfunction(f);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZsource: src in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zsource(_longVal(src));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! 
+
+glxZwritemask: mask in: aGLXWindowId
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    zwritemask((ulong)_intVal(mask));
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'misc'!
+
 glxRGBmodeIn:aGLXWindowId
     "set true color mode (no colormap)"
 
@@ -1159,18 +1649,6 @@
     ^ false
 !
 
-glxDoubleBufferIn:aGLXWindowId
-    "set double buffer mode"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    doublebuffer();
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
 glxGconfigIn:aGLXWindowId
     "must be sent after RGBmode, doubleBuffer etc. to have these
      changes really take effect. See GLX manual.
@@ -1185,20 +1663,6 @@
     ^ false
 !
 
-glxZbuffer:aBoolean in:aGLXWindowId
-    "enable/disable z-buffer operation"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zbuffer(aBoolean == false ? FALSE : TRUE);
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
 glxNmode:aSymbol in:aGLXWindowId
     "set normalize mode: #auto, #normalize"
 
@@ -1243,31 +1707,9 @@
 %}
 .
     ^ false
-!
-
-glxBeginPolygonIn:aGLXWindowId
-    "start a polygon"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    bgnpolygon();
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxEndPolygonIn:aGLXWindowId
-    "end a polygon"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    endpolygon();
-    RETURN (true);
-%}
-.
-    ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'flat drawing'!
 
 glxBeginPointIn:aGLXWindowId
     "start a point-group"
@@ -1293,12 +1735,6 @@
     ^ false
 !
 
-glxBeginCloseLineIn:aGLXWindowId
-    "will vanish"
-
-    self glxBeginClosedLineIn:aGLXWindowId
-!
-
 glxBeginClosedLineIn:aGLXWindowId
     "start a closed line"
 
@@ -1347,6 +1783,30 @@
     ^ false
 !
 
+glxBeginPolygonIn:aGLXWindowId
+    "start a polygon"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    bgnpolygon();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxEndPolygonIn:aGLXWindowId
+    "end a polygon"
+
+%{  /* NOCONTEXT */
+    SETWIN(aGLXWindowId)
+    endpolygon();
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
 glxBeginTriangleMeshIn:aGLXWindowId
     "start a triangle mesh"
 
@@ -1371,34 +1831,6 @@
     ^ false
 !
 
-glxBeginSurfaceIn:aGLXWindowId
-    "start a NURBS surface def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    bgnsurface();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
-glxEndSurfaceIn:aGLXWindowId
-    "end a NURBS surface def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    endsurface();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
 glxBeginQuadrilateralStripIn:aGLXWindowId
     "start a quadrilateral strip"
 
@@ -1421,35 +1853,9 @@
 %}
 .
     ^ false
-!
-
-glxBeginCurveIn:aGLXWindowId
-    "start a NURBS curve def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    bgncurve();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
-
-glxEndCurveIn:aGLXWindowId
-    "end a NURBS curve def - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    endcurve();
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-!
+! !
+
+!GLXWorkstation methodsFor:'sphere drawing'!
 
 glxSphDraw:arrayOf4Floats in:aGLXWindowId
     "argument must be an array(a matrix) of 4 floats containing the
@@ -1467,7 +1873,29 @@
 %}
 .
     ^ false
-!
+! 
+
+glxSphDrawX:x y:y z:z radius:r in:aGLXWindowId
+    "arguments must be convertable to floats - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    float vec[4];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    _FLOAT_(z, vec[2])
+    _FLOAT_(r, vec[3])
+    SETWIN(aGLXWindowId)
+    sphdraw(vec);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+! !
+
+!GLXWorkstation methodsFor:'patches & surfaces'!
 
 glxDefBasis:id mat:aMatrix in:aGLXWindowId
     "define the basis"
@@ -1547,67 +1975,55 @@
     ^ false
 !
 
-glxGetMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-
-    SETWIN(aGLXWindowId)
-    getmatrix(matrix);
-    if (! putFloatsFromInto(matrix, arrayOf16Floats, 16)) RETURN(false);
-    RETURN (true);
+glxBeginCurveIn:aGLXWindowId
+    "start a NURBS curve def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    bgncurve();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxLoadMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     transformation matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-    Matrix *m;
-
-    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
-    SETWIN(aGLXWindowId)
-    loadmatrix(*m);
-    RETURN (true);
+glxEndCurveIn:aGLXWindowId
+    "end a NURBS curve def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    endcurve();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxMultMatrix:arrayOf16Floats in:aGLXWindowId
-    "argument must be an array(a matrix) of 16 floats containing the
-     matrix"
-
-%{  /* NOCONTEXT */
-    Matrix matrix;
-    Matrix *m;
-
-    if (! (m = getFloatsFromMatrixInto(arrayOf16Floats, &matrix))) RETURN (false);
-    SETWIN(aGLXWindowId)
-    multmatrix(*m);
-    RETURN (true);
+glxBeginSurfaceIn:aGLXWindowId
+    "start a NURBS surface def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    bgnsurface();
+    RETURN (true);
+#endif
 %}
 .
     ^ false
 !
 
-glxN3f:arrayOf3Floats in:aGLXWindowId
-    "argument must be an array of 3 floats containing the
-     current vertex normal - in real GL only"
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    float vec[3], *v;
-
-    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    n3f(v);
+glxEndSurfaceIn:aGLXWindowId
+    "end a NURBS surface def - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    SETWIN(aGLXWindowId)
+    endsurface();
     RETURN (true);
 #endif
 %}
@@ -1656,39 +2072,231 @@
 %}
 .
     ^ false
-
-! 
-
-glxOrthoLeft: left right: right bottom: bottom top: top near: near far: far in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float f_left, f_right, f_bottom, f_top,
-          f_near, f_far;
-
-    _FLOAT_(left, f_left)
-    _FLOAT_(right, f_right)
-    _FLOAT_(bottom, f_bottom)
-    _FLOAT_(top, f_top)
-    _FLOAT_(near, f_near)
-    _FLOAT_(far, f_far)
-    SETWIN(aGLXWindowId)
-    ortho(f_left, f_right, f_bottom, f_top, f_near, f_far);
-    RETURN (true);
-%}
+! !
+
+!GLXWorkstation methodsFor:'arcs and circles '!
+
+glxArcX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _COORD_(x, c_x)
+    _COORD_(y, c_y)
+    _COORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arc(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+! 
+
+glxArciX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _ICOORD_(x, c_x)
+    _ICOORD_(y, c_y)
+    _ICOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arci(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw an arc"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _SCOORD_(x, c_x)
+    _SCOORD_(y, c_y)
+    _SCOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcs(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _COORD_(x, c_x)
+    _COORD_(y, c_y)
+    _COORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcf(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfiX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _ICOORD_(x, c_x)
+    _ICOORD_(y, c_y)
+    _ICOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang);
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcfi(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxArcfsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
+    "draw a filled arc"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+    Angle a_startang, a_endang;
+
+    _SCOORD_(x, c_x)
+    _SCOORD_(y, c_y)
+    _SCOORD_(radius, c_radius)
+    _ANGLE_(startang, a_startang)
+    _ANGLE_(endang, a_endang)
+    SETWIN(aGLXWindowId)
+    arcfs(c_x, c_y, c_radius, a_startang, a_endang);
+    RETURN (true);
+%}
+.
+    ^ false
 !
 
-glxReshapeViewPortIn: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    reshapeviewport();
+glxCircX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+
+    _COORD_ (x, c_x)
+    _COORD_ (y, c_y)
+    _COORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circ(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCirciX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+
+    _ICOORD_ (x, c_x)
+    _ICOORD_ (y, c_y)
+    _ICOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circi(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircsX: x y: y radius: radius in: aGLXWindowId
+    "draw a circle"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+
+    _SCOORD_ (x, c_x)
+    _SCOORD_ (y, c_y)
+    _SCOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circs(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Coord c_x, c_y, c_radius;
+
+    _COORD_ (x, c_x)
+    _COORD_ (y, c_y)
+    _COORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circf(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfiX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Icoord c_x, c_y, c_radius;
+
+    _ICOORD_ (x, c_x)
+    _ICOORD_ (y, c_y)
+    _ICOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circfi(c_x, c_y, c_radius);
+    RETURN (true);
+%}
+.
+    ^ false
+! 
+
+glxCircfsX: x y: y radius: radius in: aGLXWindowId
+    "draw a filled circle"
+
+%{  /* NOCONTEXT */
+    Scoord c_x, c_y, c_radius;
+
+    _SCOORD_ (x, c_x)
+    _SCOORD_ (y, c_y)
+    _SCOORD_ (radius, c_radius)
+    SETWIN(aGLXWindowId)
+    circfs(c_x, c_y, c_radius);
     RETURN (true);
 %}
 .
     ^ false
 ! !
 
-!GLXWorkstation methodsFor:'new glx access'!
+!GLXWorkstation methodsFor:'unspecified rest '!
 
 glxAcbufOp: op value: value in: aGLXWindowId
 
@@ -1729,118 +2337,6 @@
     ^ false
 ! 
 
-glxArcX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _COORD_(x, c_x)
-    _COORD_(y, c_y)
-    _COORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arc(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-! 
-
-glxArciX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _ICOORD_(x, c_x)
-    _ICOORD_(y, c_y)
-    _ICOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arci(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _SCOORD_(x, c_x)
-    _SCOORD_(y, c_y)
-    _SCOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcs(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _COORD_(x, c_x)
-    _COORD_(y, c_y)
-    _COORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcf(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfiX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _ICOORD_(x, c_x)
-    _ICOORD_(y, c_y)
-    _ICOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang);
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcfi(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxArcfsX: x y: y radius: radius startang: startang endang: endang in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-    Angle a_startang, a_endang;
-
-    _SCOORD_(x, c_x)
-    _SCOORD_(y, c_y)
-    _SCOORD_(radius, c_radius)
-    _ANGLE_(startang, a_startang)
-    _ANGLE_(endang, a_endang)
-    SETWIN(aGLXWindowId)
-    arcfs(c_x, c_y, c_radius, a_startang, a_endang);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxBackface: b in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -1852,58 +2348,6 @@
     ^ false
 ! 
 
-glxFrontBufferIn:aGLXWindowId
-    "switch to front buffer - turning backbuffer off"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-#ifdef GLX
-    backbuffer(FALSE);
-#endif
-    frontbuffer(TRUE);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxBackBufferIn:aGLXWindowId
-    "switch to back buffer - turning frontbuffer off"
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-#ifdef GLX
-    frontbuffer(FALSE);
-#endif
-    backbuffer(TRUE);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxBackbuffer: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    backbuffer(_booleanVal(b));
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxFrontbuffer: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    SETWIN(aGLXWindowId)
-    frontbuffer(_booleanVal(b));
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxBbox2Xmin: xmin ymin: ymin x1: x1 y1: y1 x2: x2 y2: y2 in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -2198,102 +2642,6 @@
     ^ false
 !
 
-glxCircX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-
-    _COORD_ (x, c_x)
-    _COORD_ (y, c_y)
-    _COORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circ(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCirciX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-
-    _ICOORD_ (x, c_x)
-    _ICOORD_ (y, c_y)
-    _ICOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circi(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircsX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-
-    _SCOORD_ (x, c_x)
-    _SCOORD_ (y, c_y)
-    _SCOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circs(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Coord c_x, c_y, c_radius;
-
-    _COORD_ (x, c_x)
-    _COORD_ (y, c_y)
-    _COORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circf(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfiX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Icoord c_x, c_y, c_radius;
-
-    _ICOORD_ (x, c_x)
-    _ICOORD_ (y, c_y)
-    _ICOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circfi(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
-glxCircfsX: x y: y radius: radius in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    Scoord c_x, c_y, c_radius;
-
-    _SCOORD_ (x, c_x)
-    _SCOORD_ (y, c_y)
-    _SCOORD_ (radius, c_radius)
-    SETWIN(aGLXWindowId)
-    circfs(c_x, c_y, c_radius);
-    RETURN (true);
-%}
-.
-    ^ false
-! 
-
 glxClearhitcodeIn: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -4128,23 +4476,6 @@
     ^ false
 ! 
 
-glxOrtho2Left: left right: right bottom: bottom top: top in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float f_left, f_right, f_top, f_bottom;
-
-    SETWIN(aGLXWindowId)
-    _FLOAT_(left, f_left)
-    _FLOAT_(right, f_right)
-    _FLOAT_(bottom, f_bottom)
-    _FLOAT_(top, f_top)
-    ortho2(f_left, f_right, f_bottom, f_top);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
 glxOverlayPlanes: planes in: aGLXWindowId
 
 %{  /* NOCONTEXT */
@@ -6175,195 +6506,9 @@
 %}
 .
     ^ false
-! 
-
-glxV2s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[2], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
 !
 
-glxV2i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[2], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV2f: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float vec[2], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV2d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[2], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 2))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v2d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[3], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[3], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3f: v in: aGLXWindowId
-    "pass a vector; v must be a 3-element float-vector"
-
-%{  /* NOCONTEXT */
-    float vec[3], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxVxf:x yf:y zf:z in: aGLXWindowId
-    "pass a vector from individual x, y and z values"
-
-%{  /* NOCONTEXT */
-    float vec[3];
-
-    _FLOAT_(x, vec[0])
-    _FLOAT_(y, vec[1])
-    _FLOAT_(z, vec[2])
-    SETWIN(aGLXWindowId)
-    v3f(vec);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV3d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[3], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 3))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v3d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4s: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    short vec[4], *c_v;
-
-    if (! (c_v = getShortsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4s(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4i: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    long vec[4], *c_v;
-
-    if (! (c_v = getLongsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4i(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4f: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    float vec[4], *c_v;
-
-    if (! (c_v = getFloatsFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4f(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxV4d: v in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-    double vec[4], *c_v;
-
-    if (! (c_v = getDoublesFromInto(v, vec, 4))) RETURN(false);
-    SETWIN(aGLXWindowId)
-    v4d(c_v);
-    RETURN (true);
-%}
-.
-    ^ false
-!
-
-glxVideocmd: cmd in: aGLXWindowId
+glxVideocmd:cmd in:aGLXWindowId
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -6376,7 +6521,7 @@
     ^ false
 ! 
 
-glxViewportLeft: left right: right bottom: bottom top: top in: aGLXWindowId
+glxViewportLeft:left right:right bottom:bottom top:top in:aGLXWindowId
 
 %{  /* NOCONTEXT */
     SETWIN(aGLXWindowId)
@@ -6384,11 +6529,9 @@
              _screencoordVal(bottom), _screencoordVal(top));
     RETURN (true);
 %}
-.
-    ^ false
-! 
-
-glxWinclose: gwid in: aGLXWindowId
+! 
+
+glxWinclose:gwid in:aGLXWindowId
 
 %{  /* NOCONTEXT */
 #ifdef GLX
@@ -6689,69 +6832,271 @@
 %}
 .
     ^ false
-! 
-
-glxZbsize: planes in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef FULL_GLX
-    SETWIN(aGLXWindowId)
-    zbsize(_longVal(planes));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZdraw: b in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zdraw(_booleanVal(b));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZfunction: func in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zfunction(_longVal(func));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZsource: src in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zsource(_longVal(src));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
-! 
-
-glxZwritemask: mask in: aGLXWindowId
-
-%{  /* NOCONTEXT */
-#ifdef GLX
-    SETWIN(aGLXWindowId)
-    zwritemask((ulong)_intVal(mask));
-    RETURN (true);
-#endif
-%}
-.
-    ^ false
 ! !
+
+!GLXWorkstation methodsFor:'vertex data transfer '!
+
+glxV2s:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 shorts; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    short vec[2], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2i:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 longs; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    long vec[2], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2f:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 floats; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    float vec[2], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2d:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 2 doubles; z is taken as 0"
+
+%{  /* NOCONTEXT */
+    double vec[2], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 2))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v2d(c_v);
+    RETURN (true);
+%}
+!
+
+glxV2fX:x y:y in:aGLXWindowId
+    "pass a vertex from individual x and y values; z is taken as 0.0"
+
+%{  /* NOCONTEXT */
+    float vec[2];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    SETWIN(aGLXWindowId)
+    v2f(vec);
+    RETURN (true);
+%}
+!
+
+glxV3s:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 3 shorts"
+
+%{  /* NOCONTEXT */
+    short vec[3], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3i:v in:aGLXWindowId
+    "pass a vertex; v must be a vector with 3 longs"
+
+%{  /* NOCONTEXT */
+    long vec[3], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3f:v in:aGLXWindowId
+    "pass a vertex; v must be a 3-element float-vector"
+
+%{  /* NOCONTEXT */
+    float vec[3], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV3fX:x y:y z:z in: aGLXWindowId
+    "pass a vector from individual x, y and z (float) values"
+
+%{  /* NOCONTEXT */
+    float vec[3];
+
+    _FLOAT_(x, vec[0])
+    _FLOAT_(y, vec[1])
+    _FLOAT_(z, vec[2])
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVOriginIn:aGLXWindowId
+    "pass a 0.0/0.0/0.0 vector.
+     This is the same as v3f:#(0.0 0.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 0.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitXIn:aGLXWindowId
+    "pass a 1.0/0.0/0.0 vector.
+     This is the same as v3f:#(1.0 0.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {1.0, 0.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitYIn:aGLXWindowId
+    "pass a 0.0/1.0/0.0 vector.
+     This is the same as v3f:#(0.0 1.0 0.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 1.0, 0.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxVUnitZIn:aGLXWindowId
+    "pass a 0.0/0.0/1.0 vector.
+     This is the same as v3f:#(0.0 0.0 1.0), but, since its so
+     common, this somewhat faster method has been provided"
+
+%{  /* NOCONTEXT */
+    static float vec[3] = {0.0, 0.0, 1.0};
+
+    SETWIN(aGLXWindowId)
+    v3f(vec);
+    RETURN (true);
+%}
+!
+
+glxV3d:v in:aGLXWindowId
+    "pass a vertex; v must be a 3-element double-vector"
+
+%{  /* NOCONTEXT */
+    double vec[3], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v3d(c_v);
+    RETURN (true);
+%}
+.
+    ^ false
+!
+
+glxN3f:arrayOf3Floats in:aGLXWindowId
+    "argument must be an array of 3 floats containing the
+     current vertex normal - in real GL only"
+
+%{  /* NOCONTEXT */
+#ifdef GLX
+    float vec[3], *v;
+
+    if (! (v = getFloatsFromInto(arrayOf3Floats, vec, 3))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    n3f(v);
+    RETURN (true);
+#endif
+%}
+.
+    ^ false
+!
+
+glxV4s:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element short-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    short vec[4], *c_v;
+
+    if (! (c_v = getShortsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4s(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4i:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element int-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    long vec[4], *c_v;
+
+    if (! (c_v = getLongsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4i(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4f:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element float-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    float vec[4], *c_v;
+
+    if (! (c_v = getFloatsFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4f(c_v);
+    RETURN (true);
+%}
+!
+
+glxV4d:v in:aGLXWindowId
+    "pass a vertex; v must be a 4-element double-vector,
+     containing x, y, z and w"
+
+%{  /* NOCONTEXT */
+    double vec[4], *c_v;
+
+    if (! (c_v = getDoublesFromInto(v, vec, 4))) RETURN(false);
+    SETWIN(aGLXWindowId)
+    v4d(c_v);
+    RETURN (true);
+%}
+! !