home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / cstubs < prev    next >
Encoding:
Text File  |  2000-10-25  |  32.4 KB  |  1,365 lines

  1.  
  2. /*
  3. Input used to generate the Python module "glmodule.c".
  4. The stub generator is a Python script called "cgen.py".
  5.  
  6. Each definition must be contained on one line:
  7.  
  8. <returntype> <name> <type> <arg> <type> <arg>
  9.  
  10. <returntype> can be: void, short, long (XXX maybe others?)
  11.  
  12. <type> can be: char, string, short, float, long, or double
  13.     string indicates a null terminated string;
  14.     if <type> is char and <arg> begins with a *, the * is stripped
  15.     and <type> is changed into string
  16.  
  17. <arg> has the form <mode> or <mode>[<subscript>]
  18.     where <mode> can be
  19.         s: arg is sent
  20.         r: arg is received        (arg is a pointer)
  21.     and <subscript> can be (N and I are numbers):
  22.         N
  23.         argI
  24.         retval
  25.         N*argI
  26.         N*I
  27.         N*retval
  28.     In the case where the subscript consists of two parts
  29.     separated by *, the first part is the width of the matrix, and
  30.     the second part is the length of the matrix.  This order is
  31.     opposite from the order used in C to declare a two-dimensional
  32.     matrix.
  33. */
  34.  
  35. /*
  36.  * An attempt has been made to make this module switch threads on qread
  37.  * calls. It is far from safe, though.
  38.  */
  39.  
  40. #include <gl.h>
  41. #include <device.h>
  42.  
  43. #ifdef __sgi
  44. extern int devport();
  45. extern int textwritemask();
  46. extern int pagewritemask();
  47. extern int gewrite();
  48. extern int gettp();
  49. #endif
  50.  
  51. #include "Python.h"
  52. #include "cgensupport.h"
  53.  
  54. /*
  55. Some stubs are too complicated for the stub generator.
  56. We can include manually written versions of them here.
  57. A line starting with '%' gives the name of the function so the stub
  58. generator can include it in the table of functions.
  59. */
  60.  
  61. % qread
  62.  
  63. static PyObject *
  64. gl_qread(self, args)
  65.     PyObject *self;
  66.     PyObject *args;
  67. {
  68.     long retval;
  69.     short arg1 ;
  70.     Py_BEGIN_ALLOW_THREADS
  71.     retval = qread( & arg1 );
  72.     Py_END_ALLOW_THREADS
  73.     { PyObject *v = PyTuple_New( 2 );
  74.       if (v == NULL) return NULL;
  75.       PyTuple_SetItem(v, 0, mknewlongobject(retval));
  76.       PyTuple_SetItem(v, 1, mknewshortobject(arg1));
  77.       return v;
  78.     }
  79. }
  80.  
  81.  
  82. /*
  83. varray -- an array of v.. calls.
  84. The argument is an array (maybe list or tuple) of points.
  85. Each point must be a tuple or list of coordinates (x, y, z).
  86. The points may be 2- or 3-dimensional but must all have the
  87. same dimension.  Float and int values may be mixed however.
  88. The points are always converted to 3D double precision points
  89. by assuming z=0.0 if necessary (as indicated in the man page),
  90. and for each point v3d() is called.
  91. */
  92.  
  93. % varray
  94.  
  95. static PyObject *
  96. gl_varray(self, args)
  97.     PyObject *self;
  98.     PyObject *args;
  99. {
  100.     PyObject *v, *w=NULL;
  101.     int i, n, width;
  102.     double vec[3];
  103.     PyObject * (*getitem)(PyObject *, int);
  104.     
  105.     if (!PyArg_GetObject(args, 1, 0, &v))
  106.         return NULL;
  107.     
  108.     if (PyList_Check(v)) {
  109.         n = PyList_Size(v);
  110.         getitem = PyList_GetItem;
  111.     }
  112.     else if (PyTuple_Check(v)) {
  113.         n = PyTuple_Size(v);
  114.         getitem = PyTuple_GetItem;
  115.     }
  116.     else {
  117.         PyErr_BadArgument();
  118.         return NULL;
  119.     }
  120.     
  121.     if (n == 0) {
  122.         Py_INCREF(Py_None);
  123.         return Py_None;
  124.     }
  125.     if (n > 0)
  126.         w = (*getitem)(v, 0);
  127.     
  128.     width = 0;
  129.     if (w == NULL) {
  130.     }
  131.     else if (PyList_Check(w)) {
  132.         width = PyList_Size(w);
  133.     }
  134.     else if (PyTuple_Check(w)) {
  135.         width = PyTuple_Size(w);
  136.     }
  137.     
  138.     switch (width) {
  139.     case 2:
  140.         vec[2] = 0.0;
  141.         /* Fall through */
  142.     case 3:
  143.         break;
  144.     default:
  145.         PyErr_BadArgument();
  146.         return NULL;
  147.     }
  148.     
  149.     for (i = 0; i < n; i++) {
  150.         w = (*getitem)(v, i);
  151.         if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
  152.             return NULL;
  153.         v3d(vec);
  154.     }
  155.     
  156.     Py_INCREF(Py_None);
  157.     return Py_None;
  158. }
  159.  
  160. /*
  161. vnarray, nvarray -- an array of n3f and v3f calls.
  162. The argument is an array (list or tuple) of pairs of points and normals.
  163. Each pair is a tuple (NOT a list) of a point and a normal for that point.
  164. Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
  165. Three coordinates must be given.  Float and int values may be mixed.
  166. For each pair, n3f() is called for the normal, and then v3f() is called
  167. for the vector.
  168.  
  169. vnarray and nvarray differ only in the order of the vector and normal in
  170. the pair: vnarray expects (v, n) while nvarray expects (n, v).
  171. */
  172.  
  173. static PyObject *gen_nvarray(); /* Forward */
  174.  
  175. % nvarray
  176.  
  177. static PyObject *
  178. gl_nvarray(self, args)
  179.     PyObject *self;
  180.     PyObject *args;
  181. {
  182.     return gen_nvarray(args, 0);
  183. }
  184.  
  185. % vnarray
  186.  
  187. static PyObject *
  188. gl_vnarray(self, args)
  189.     PyObject *self;
  190.     PyObject *args;
  191. {
  192.     return gen_nvarray(args, 1);
  193. }
  194.  
  195. /* Generic, internal version of {nv,nv}array: inorm indicates the
  196.    argument order, 0: normal first, 1: vector first. */
  197.  
  198. static PyObject *
  199. gen_nvarray(args, inorm)
  200.     PyObject *args;
  201.     int inorm;
  202. {
  203.     PyObject *v, *w, *wnorm, *wvec;
  204.     int i, n;
  205.     float norm[3], vec[3];
  206.     PyObject * (*getitem)(PyObject *, int);
  207.     
  208.     if (!PyArg_GetObject(args, 1, 0, &v))
  209.         return NULL;
  210.     
  211.     if (PyList_Check(v)) {
  212.         n = PyList_Size(v);
  213.         getitem = PyList_GetItem;
  214.     }
  215.     else if (PyTuple_Check(v)) {
  216.         n = PyTuple_Size(v);
  217.         getitem = PyTuple_GetItem;
  218.     }
  219.     else {
  220.         PyErr_BadArgument();
  221.         return NULL;
  222.     }
  223.     
  224.     for (i = 0; i < n; i++) {
  225.         w = (*getitem)(v, i);
  226.         if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
  227.             PyErr_BadArgument();
  228.             return NULL;
  229.         }
  230.         wnorm = PyTuple_GetItem(w, inorm);
  231.         wvec = PyTuple_GetItem(w, 1 - inorm);
  232.         if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
  233.             !PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
  234.             return NULL;
  235.         n3f(norm);
  236.         v3f(vec);
  237.     }
  238.     
  239.     Py_INCREF(Py_None);
  240.     return Py_None;
  241. }
  242.  
  243. /* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
  244.    The dimensions of ctl[] are computed as follows:
  245.    [len(s_knots) - s_order], [len(t_knots) - t_order]
  246. */
  247.  
  248. % nurbssurface
  249.  
  250. static PyObject *
  251. gl_nurbssurface(self, args)
  252.     PyObject *self;
  253.     PyObject *args;
  254. {
  255.     long arg1 ;
  256.     double * arg2 ;
  257.     long arg3 ;
  258.     double * arg4 ;
  259.     double *arg5 ;
  260.     long arg6 ;
  261.     long arg7 ;
  262.     long arg8 ;
  263.     long ncoords;
  264.     long s_byte_stride, t_byte_stride;
  265.     long s_nctl, t_nctl;
  266.     long s, t;
  267.     PyObject *v, *w, *pt;
  268.     double *pnext;
  269.     if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
  270.         return NULL;
  271.     if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
  272.         return PyErr_NoMemory();
  273.     }
  274.     if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
  275.         return NULL;
  276.     if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
  277.         return NULL;
  278.     if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
  279.         return PyErr_NoMemory();
  280.     }
  281.     if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
  282.         return NULL;
  283.     if (!PyArg_GetLong(args, 6, 3, &arg6))
  284.         return NULL;
  285.     if (!PyArg_GetLong(args, 6, 4, &arg7))
  286.         return NULL;
  287.     if (!PyArg_GetLong(args, 6, 5, &arg8))
  288.         return NULL;
  289.     if (arg8 == N_XYZ)
  290.         ncoords = 3;
  291.     else if (arg8 == N_XYZW)
  292.         ncoords = 4;
  293.     else {
  294.         PyErr_BadArgument();
  295.         return NULL;
  296.     }
  297.     s_nctl = arg1 - arg6;
  298.     t_nctl = arg3 - arg7;
  299.     if (!PyArg_GetObject(args, 6, 2, &v))
  300.         return NULL;
  301.     if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
  302.         PyErr_BadArgument();
  303.         return NULL;
  304.     }
  305.     if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
  306.         return PyErr_NoMemory();
  307.     }
  308.     pnext = arg5;
  309.     for (s = 0; s < s_nctl; s++) {
  310.         w = PyList_GetItem(v, s);
  311.         if (w == NULL || !PyList_Check(w) ||
  312.                     PyList_Size(w) != t_nctl) {
  313.             PyErr_BadArgument();
  314.             return NULL;
  315.         }
  316.         for (t = 0; t < t_nctl; t++) {
  317.             pt = PyList_GetItem(w, t);
  318.             if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
  319.                 return NULL;
  320.             pnext += ncoords;
  321.         }
  322.     }
  323.     s_byte_stride = sizeof(double) * ncoords;
  324.     t_byte_stride = s_byte_stride * s_nctl;
  325.     nurbssurface( arg1 , arg2 , arg3 , arg4 ,
  326.         s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
  327.     PyMem_DEL(arg2);
  328.     PyMem_DEL(arg4);
  329.     PyMem_DEL(arg5);
  330.     Py_INCREF(Py_None);
  331.     return Py_None;
  332. }
  333.  
  334. /* nurbscurve(knots, ctlpoints, order, type).
  335.    The length of ctlpoints is len(knots)-order. */
  336.  
  337. %nurbscurve
  338.  
  339. static PyObject *
  340. gl_nurbscurve(self, args)
  341.     PyObject *self;
  342.     PyObject *args;
  343. {
  344.     long arg1 ;
  345.     double * arg2 ;
  346.     long arg3 ;
  347.     double * arg4 ;
  348.     long arg5 ;
  349.     long arg6 ;
  350.     int ncoords, npoints;
  351.     int i;
  352.     PyObject *v;
  353.     double *pnext;
  354.     if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
  355.         return NULL;
  356.     if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
  357.         return PyErr_NoMemory();
  358.     }
  359.     if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
  360.         return NULL;
  361.     if (!PyArg_GetLong(args, 4, 2, &arg5))
  362.         return NULL;
  363.     if (!PyArg_GetLong(args, 4, 3, &arg6))
  364.         return NULL;
  365.     if (arg6 == N_ST)
  366.         ncoords = 2;
  367.     else if (arg6 == N_STW)
  368.         ncoords = 3;
  369.     else {
  370.         PyErr_BadArgument();
  371.         return NULL;
  372.     }
  373.     npoints = arg1 - arg5;
  374.     if (!PyArg_GetObject(args, 4, 1, &v))
  375.         return NULL;
  376.     if (!PyList_Check(v) || PyList_Size(v) != npoints) {
  377.         PyErr_BadArgument();
  378.         return NULL;
  379.     }
  380.     if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
  381.         return PyErr_NoMemory();
  382.     }
  383.     pnext = arg4;
  384.     for (i = 0; i < npoints; i++) {
  385.         if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
  386.             return NULL;
  387.         pnext += ncoords;
  388.     }
  389.     arg3 = (sizeof(double)) * ncoords;
  390.     nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
  391.     PyMem_DEL(arg2);
  392.     PyMem_DEL(arg4);
  393.     Py_INCREF(Py_None);
  394.     return Py_None;
  395. }
  396.  
  397. /* pwlcurve(points, type).
  398.    Points is a list of points. Type must be N_ST. */
  399.  
  400. %pwlcurve
  401.  
  402. static PyObject *
  403. gl_pwlcurve(self, args)
  404.     PyObject *self;
  405.     PyObject *args;
  406. {
  407.     PyObject *v;
  408.     long type;
  409.     double *data, *pnext;
  410.     long npoints, ncoords;
  411.     int i;
  412.     if (!PyArg_GetObject(args, 2, 0, &v))
  413.         return NULL;
  414.     if (!PyArg_GetLong(args, 2, 1, &type))
  415.         return NULL;
  416.     if (!PyList_Check(v)) {
  417.         PyErr_BadArgument();
  418.         return NULL;
  419.     }
  420.     npoints = PyList_Size(v);
  421.     if (type == N_ST)
  422.         ncoords = 2;
  423.     else {
  424.         PyErr_BadArgument();
  425.         return NULL;
  426.     }
  427.     if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
  428.         return PyErr_NoMemory();
  429.     }
  430.     pnext = data;
  431.     for (i = 0; i < npoints; i++) {
  432.         if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
  433.             return NULL;
  434.         pnext += ncoords;
  435.     }
  436.     pwlcurve(npoints, data, sizeof(double)*ncoords, type);
  437.     PyMem_DEL(data);
  438.     Py_INCREF(Py_None);
  439.     return Py_None;
  440. }
  441.  
  442.  
  443. /* Picking and Selecting */
  444.  
  445. static short *pickbuffer = NULL;
  446. static long pickbuffersize;
  447.  
  448. static PyObject *
  449. pick_select(args, func)
  450.     PyObject *args;
  451.     void (*func)();
  452. {
  453.     if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
  454.         return NULL;
  455.     if (pickbuffer != NULL) {
  456.         PyErr_SetString(PyExc_RuntimeError,
  457.             "pick/gselect: already picking/selecting");
  458.         return NULL;
  459.     }
  460.     if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
  461.         return PyErr_NoMemory();
  462.     }
  463.     (*func)(pickbuffer, pickbuffersize);
  464.     Py_INCREF(Py_None);
  465.     return Py_None;
  466. }
  467.  
  468. static PyObject *
  469. endpick_select(args, func)
  470.     PyObject *args;
  471.     long (*func)();
  472. {
  473.     PyObject *v, *w;
  474.     int i, nhits, n;
  475.     if (!PyArg_NoArgs(args))
  476.         return NULL;
  477.     if (pickbuffer == NULL) {
  478.         PyErr_SetString(PyExc_RuntimeError,
  479.             "endpick/endselect: not in pick/select mode");
  480.         return NULL;
  481.     }
  482.     nhits = (*func)(pickbuffer);
  483.     if (nhits < 0) {
  484.         nhits = -nhits; /* How to report buffer overflow otherwise? */
  485.     }
  486.     /* Scan the buffer to see how many integers */
  487.     n = 0;
  488.     for (; nhits > 0; nhits--) {
  489.         n += 1 + pickbuffer[n];
  490.     }
  491.     v = PyList_New(n);
  492.     if (v == NULL)
  493.         return NULL;
  494.     /* XXX Could do it nicer and interpret the data structure here,
  495.        returning a list of lists. But this can be done in Python... */
  496.     for (i = 0; i < n; i++) {
  497.         w = PyInt_FromLong((long)pickbuffer[i]);
  498.         if (w == NULL) {
  499.             Py_DECREF(v);
  500.             return NULL;
  501.         }
  502.         PyList_SetItem(v, i, w);
  503.     }
  504.     PyMem_DEL(pickbuffer);
  505.     pickbuffer = NULL;
  506.     return v;
  507. }
  508.  
  509. extern void pick(), gselect();
  510. extern long endpick(), endselect();
  511.  
  512. %pick
  513. static PyObject *gl_pick(self, args) PyObject *self, *args; {
  514.     return pick_select(args, pick);
  515. }
  516.  
  517. %endpick
  518. static PyObject *gl_endpick(self, args) PyObject *self, *args; {
  519.     return endpick_select(args, endpick);
  520. }
  521.  
  522. %gselect
  523. static PyObject *gl_gselect(self, args) PyObject *self, *args; {
  524.     return pick_select(args, gselect);
  525. }
  526.  
  527. %endselect
  528. static PyObject *gl_endselect(self, args) PyObject *self, *args; {
  529.     return endpick_select(args, endselect);
  530. }
  531.  
  532.  
  533. /* XXX The generator botches this one.  Here's a quick hack to fix it. */
  534.  
  535. /* XXX The generator botches this one.  Here's a quick hack to fix it. */
  536.  
  537. % getmatrix float r[16]
  538.  
  539. static PyObject *
  540. gl_getmatrix(self, args)
  541.     PyObject *self;
  542.     PyObject *args;
  543. {
  544.     Matrix arg1;
  545.     PyObject *v, *w;
  546.     int i, j;
  547.     getmatrix( arg1 );
  548.     v = PyList_New(16);
  549.     if (v == NULL) {
  550.         return PyErr_NoMemory();
  551.     }
  552.     for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
  553.         w = mknewfloatobject(arg1[i][j]);
  554.         if (w == NULL) {
  555.             Py_DECREF(v);
  556.             return NULL;
  557.         }
  558.         PyList_SetItem(v, i*4+j, w);
  559.     }
  560.     return v;
  561. }
  562.  
  563. /* Here's an alternate version that returns a 4x4 matrix instead of
  564.    a vector.  Unfortunately it is incompatible with loadmatrix and
  565.    multmatrix... */
  566.  
  567. % altgetmatrix float r[4][4]
  568.  
  569. static PyObject *
  570. gl_altgetmatrix(self, args)
  571.     PyObject *self;
  572.     PyObject *args;
  573. {
  574.     Matrix arg1;
  575.     PyObject *v, *w;
  576.     int i, j;
  577.     getmatrix( arg1 );
  578.     v = PyList_New(4);
  579.     if (v == NULL) {
  580.         return NULL;
  581.     }
  582.     for (i = 0; i < 4; i++) {
  583.         w = PyList_New(4);
  584.         if (w == NULL) {
  585.             Py_DECREF(v);
  586.             return NULL;
  587.         }
  588.         PyList_SetItem(v, i, w);
  589.     }
  590.     for (i = 0; i < 4; i++) {
  591.         for (j = 0; j < 4; j++) {
  592.             w = mknewfloatobject(arg1[i][j]);
  593.             if (w == NULL) {
  594.                 Py_DECREF(v);
  595.                 return NULL;
  596.             }
  597.             PyList_SetItem(PyList_GetItem(v, i), j, w);
  598.         }
  599.     }
  600.     return v;
  601. }
  602.  
  603. % lrectwrite
  604.  
  605. static PyObject *
  606. gl_lrectwrite(self, args)
  607.     PyObject *self;
  608.     PyObject *args;
  609. {
  610.     short x1 ;
  611.     short y1 ;
  612.     short x2 ;
  613.     short y2 ;
  614.     string parray ;
  615.     PyObject *s;
  616. #if 0
  617.     int pixcount;
  618. #endif
  619.     if (!PyArg_GetShort(args, 5, 0, &x1))
  620.         return NULL;
  621.     if (!PyArg_GetShort(args, 5, 1, &y1))
  622.         return NULL;
  623.     if (!PyArg_GetShort(args, 5, 2, &x2))
  624.         return NULL;
  625.     if (!PyArg_GetShort(args, 5, 3, &y2))
  626.         return NULL;
  627.     if (!PyArg_GetString(args, 5, 4, &parray))
  628.         return NULL;
  629.     if (!PyArg_GetObject(args, 5, 4, &s))
  630.         return NULL;
  631. #if 0
  632. /* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
  633.     pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
  634.     if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
  635.         PyErr_SetString(PyExc_RuntimeError,
  636.                "string arg to lrectwrite has wrong size");
  637.         return NULL;
  638.     }
  639. #endif
  640.     lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
  641.     Py_INCREF(Py_None);
  642.     return Py_None;
  643. }
  644.  
  645. % lrectread
  646.  
  647. static PyObject *
  648. gl_lrectread(self, args)
  649.     PyObject *self;
  650.     PyObject *args;
  651. {
  652.     short x1 ;
  653.     short y1 ;
  654.     short x2 ;
  655.     short y2 ;
  656.     PyObject *parray;
  657.     int pixcount;
  658.     if (!PyArg_GetShort(args, 4, 0, &x1))
  659.         return NULL;
  660.     if (!PyArg_GetShort(args, 4, 1, &y1))
  661.         return NULL;
  662.     if (!PyArg_GetShort(args, 4, 2, &x2))
  663.         return NULL;
  664.     if (!PyArg_GetShort(args, 4, 3, &y2))
  665.         return NULL;
  666.     pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
  667.     parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
  668.     if (parray == NULL)
  669.         return NULL; /* No memory */
  670.     lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
  671.     return parray;
  672. }
  673.  
  674. % readdisplay
  675.  
  676. static PyObject *
  677. gl_readdisplay(self, args)
  678.     PyObject *self;
  679.         PyObject *args;
  680. {
  681.         short x1, y1, x2, y2;
  682.     unsigned long *parray, hints;
  683.     long size, size_ret;
  684.     PyObject *rv;
  685.  
  686.     if ( !PyArg_Parse(args, "hhhhl", &x1, &y1, &x2, &y2, &hints) )
  687.       return 0;
  688.     size = (long)(x2+1-x1) * (long)(y2+1-y1);
  689.     rv = PyString_FromStringAndSize((char *)NULL, size*sizeof(long));
  690.     if ( rv == NULL )
  691.       return NULL;
  692.     parray = (unsigned long *)PyString_AsString(rv);
  693.     size_ret = readdisplay(x1, y1, x2, y2, parray, hints);
  694.     if ( size_ret != size ) {
  695.         printf("gl_readdisplay: got %ld pixels, expected %ld\n",
  696.            size_ret, size);
  697.         PyErr_SetString(PyExc_RuntimeError, "readdisplay returned unexpected length");
  698.         return NULL;
  699.     }
  700.     return rv;
  701. }
  702.  
  703. /* Desperately needed, here are tools to compress and decompress
  704.    the data manipulated by lrectread/lrectwrite.
  705.  
  706.    gl.packrect(width, height, packfactor, bigdata) --> smalldata
  707.         makes 'bigdata' 4*(packfactor**2) times smaller by:
  708.         - turning it into B/W (a factor 4)
  709.         - replacing squares of size pacfactor by one
  710.           representative
  711.  
  712.    gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
  713.         is the inverse; the numeric arguments must be *the same*.
  714.  
  715.    Both work best if width and height are multiples of packfactor
  716.    (in fact unpackrect will leave garbage bytes).
  717. */
  718.  
  719. % packrect
  720.  
  721. static PyObject *
  722. gl_packrect(self, args)
  723.     PyObject *self;
  724.     PyObject *args;
  725. {
  726.     long width, height, packfactor;
  727.     char *s;
  728.     PyObject *unpacked, *packed;
  729.     int pixcount, packedcount, x, y, r, g, b;
  730.     unsigned long pixel;
  731.     unsigned char *p;
  732.     unsigned long *parray;
  733.     if (!PyArg_GetLong(args, 4, 0, &width))
  734.         return NULL;
  735.     if (!PyArg_GetLong(args, 4, 1, &height))
  736.         return NULL;
  737.     if (!PyArg_GetLong(args, 4, 2, &packfactor))
  738.         return NULL;
  739.     if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
  740.         return NULL;
  741.     if (!PyArg_GetObject(args, 4, 3, &unpacked))
  742.         return NULL;
  743.     if (width <= 0 || height <= 0 || packfactor <= 0) {
  744.         PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
  745.         return NULL;
  746.     }
  747.     pixcount = width*height;
  748.     packedcount = ((width+packfactor-1)/packfactor) *
  749.         ((height+packfactor-1)/packfactor);
  750.     if (PyString_Size(unpacked) != pixcount*sizeof(long)) {
  751.         PyErr_SetString(PyExc_RuntimeError,
  752.                "string arg to packrect has wrong size");
  753.         return NULL;
  754.     }
  755.     packed = PyString_FromStringAndSize((char *)NULL, packedcount);
  756.     if (packed == NULL)
  757.         return NULL;
  758.     parray = (unsigned long *) PyString_AsString(unpacked);
  759.     p = (unsigned char *) PyString_AsString(packed);
  760.     for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
  761.         for (x = 0; x < width; x += packfactor) {
  762.             pixel = parray[x];
  763.             r = pixel & 0xff;
  764.             g = (pixel >> 8) & 0xff;
  765.             b = (pixel >> 16) & 0xff;
  766.             *p++ = (30*r+59*g+11*b) / 100;
  767.         }
  768.     }
  769.     return packed;
  770. }
  771.  
  772. % unpackrect
  773.  
  774. static unsigned long unpacktab[256];
  775. static int unpacktab_inited = 0;
  776.  
  777. static PyObject *
  778. gl_unpackrect(self, args)
  779.     PyObject *self;
  780.     PyObject *args;
  781. {
  782.     long width, height, packfactor;
  783.     char *s;
  784.     PyObject *unpacked, *packed;
  785.     int pixcount, packedcount;
  786.     register unsigned char *p;
  787.     register unsigned long *parray;
  788.     if (!unpacktab_inited) {
  789.         register int white;
  790.         for (white = 256; --white >= 0; )
  791.             unpacktab[white] = white * 0x010101L;
  792.         unpacktab_inited++;
  793.     }
  794.     if (!PyArg_GetLong(args, 4, 0, &width))
  795.         return NULL;
  796.     if (!PyArg_GetLong(args, 4, 1, &height))
  797.         return NULL;
  798.     if (!PyArg_GetLong(args, 4, 2, &packfactor))
  799.         return NULL;
  800.     if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
  801.         return NULL;
  802.     if (!PyArg_GetObject(args, 4, 3, &packed))
  803.         return NULL;
  804.     if (width <= 0 || height <= 0 || packfactor <= 0) {
  805.         PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
  806.         return NULL;
  807.     }
  808.     pixcount = width*height;
  809.     packedcount = ((width+packfactor-1)/packfactor) *
  810.         ((height+packfactor-1)/packfactor);
  811.     if (PyString_Size(packed) != packedcount) {
  812.         PyErr_SetString(PyExc_RuntimeError,
  813.                "string arg to unpackrect has wrong size");
  814.         return NULL;
  815.     }
  816.     unpacked = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
  817.     if (unpacked == NULL)
  818.         return NULL;
  819.     parray = (unsigned long *) PyString_AsString(unpacked);
  820.     p = (unsigned char *) PyString_AsString(packed);
  821.     if (packfactor == 1 && width*height > 0) {
  822.         /* Just expand bytes to longs */
  823.         register int x = width * height;
  824.         do {
  825.             *parray++ = unpacktab[*p++];
  826.         } while (--x >= 0);
  827.     }
  828.     else {
  829.         register int y;
  830.         for (y = 0; y < height-packfactor+1;
  831.              y += packfactor, parray += packfactor*width) {
  832.             register int x;
  833.             for (x = 0; x < width-packfactor+1; x += packfactor) {
  834.                 register unsigned long pixel = unpacktab[*p++];
  835.                 register int i;
  836.                 for (i = packfactor*width; (i-=width) >= 0;) {
  837.                     register int j;
  838.                     for (j = packfactor; --j >= 0; )
  839.                         parray[i+x+j] = pixel;
  840.                 }
  841.             }
  842.         }
  843.     }
  844.     return unpacked;
  845. }
  846.  
  847. % gversion
  848. static PyObject *
  849. gl_gversion(self, args)
  850.     PyObject *self;
  851.     PyObject *args;
  852. {
  853.     char buf[20];
  854.     gversion(buf);
  855.     return PyString_FromString(buf);
  856. }
  857.  
  858.  
  859. /* void clear - Manual because of clash with termcap */
  860. %clear
  861. static PyObject *
  862. gl_clear(self, args)
  863.     PyObject *self;
  864.     PyObject *args;
  865. {
  866.     __GLclear( );
  867.     Py_INCREF(Py_None);
  868.     return Py_None;
  869. }
  870.  
  871. /* End of manually written stubs */
  872.  
  873. %%
  874.  
  875. long     getshade
  876. if !solaris    void     devport     short s long s
  877. void     rdr2i         long s long s
  878. void    rectfs         short s short s short s short s
  879. void     rects         short s short s short s short s
  880. void     rmv2i         long s long s
  881. void    noport
  882. void    popviewport
  883. void    clearhitcode
  884. void    closeobj
  885. void    cursoff
  886. void    curson
  887. void    doublebuffer
  888. void     finish
  889. void    gconfig
  890. void    ginit
  891. void    greset
  892. void    multimap
  893. void    onemap
  894. void    popattributes
  895. void    popmatrix
  896. void    pushattributes
  897. void    pushmatrix
  898. void    pushviewport
  899. void    qreset
  900. void    RGBmode
  901. void    singlebuffer
  902. void    swapbuffers
  903. void    gsync
  904. void    gflush
  905. void    tpon
  906. void    tpoff
  907. void    clkon
  908. void    clkoff
  909. void    ringbell
  910. #void    callfunc
  911. void    gbegin
  912. void    textinit
  913. void    initnames
  914. void    pclos
  915. void    popname
  916. if !solaris    void    spclos
  917. void    zclear
  918. void    screenspace
  919. void    reshapeviewport
  920. void    winpush
  921. void    winpop
  922. void    foreground
  923. void    endfullscrn
  924. if !solaris    void    endpupmode
  925. void    fullscrn
  926. if !solaris    void    pupmode
  927. void    winconstraints
  928. void    pagecolor     short s
  929. void    textcolor     short s
  930. void     color           short s
  931. void    curveit        short s
  932. void    font        short s
  933. void     linewidth    short s
  934. void    setlinestyle    short s
  935. void    setmap        short s
  936. void    swapinterval    short s
  937. void    writemask    short s
  938. if !solaris    void    textwritemask    short s
  939. void    qdevice        short s
  940. void    unqdevice    short s
  941. void    curvebasis    short s
  942. void    curveprecision    short s
  943. void    loadname    short s
  944. void    passthrough    short s
  945. void    pushname    short s
  946. void    setmonitor    short s
  947. if !solaris    void    setshade    short s
  948. void    setpattern    short s
  949. if !solaris    void    pagewritemask    short s
  950. #
  951. void    callobj        long s
  952. void    delobj        long s
  953. void     editobj        long s
  954. void    makeobj        long s
  955. void    maketag        long s
  956. void    chunksize    long s
  957. void    compactify    long s
  958. void    deltag        long s
  959. void    lsrepeat    long s
  960. void    objinsert    long s
  961. void     objreplace    long s
  962. void    winclose    long s
  963. void    blanktime    long s
  964. void     freepup        long s
  965. # This is not in the library!?
  966. ###void    pupcolor    long s
  967. #
  968. void    backbuffer    long s
  969. void     frontbuffer    long s
  970. if !solaris    void    lsbackup    long s
  971. void    resetls        long s
  972. void    lampon        long s
  973. void    lampoff        long s
  974. void    setbell        long s
  975. void    blankscreen    long s
  976. void     depthcue    long s
  977. void    zbuffer        long s
  978. void    backface    long s
  979. #
  980. void     cmov2i        long s long s
  981. void     draw2i        long s long s
  982. void    move2i        long s long s
  983. void    pnt2i        long s long s
  984. void     patchbasis    long s long s
  985. void     patchprecision    long s long s
  986. void    pdr2i        long s long s
  987. void    pmv2i        long s long s
  988. void    rpdr2i        long s long s
  989. void    rpmv2i        long s long s
  990. void    xfpt2i        long s long s
  991. void    objdelete    long s long s
  992. void    patchcurves    long s long s
  993. void    minsize        long s long s
  994. void     maxsize        long s long s
  995. void    keepaspect    long s long s
  996. void    prefsize    long s long s
  997. void    stepunit    long s long s
  998. void     fudge        long s long s
  999. void     winmove        long s long s
  1000. #
  1001. void     attachcursor    short s short s
  1002. void     deflinestyle    short s short s
  1003. void     noise        short s short s
  1004. void     picksize    short s short s
  1005. void     qenter        short s short s
  1006. void     setdepth    short s short s
  1007. void     cmov2s        short s short s
  1008. void     draw2s        short s    short s
  1009. void     move2s        short s short s
  1010. void     pdr2s        short s short s
  1011. void     pmv2s        short s short s
  1012. void     pnt2s        short s short s
  1013. void     rdr2s        short s short s
  1014. void     rmv2s        short s short s
  1015. void     rpdr2s        short s short s
  1016. void     rpmv2s        short s short s
  1017. void     xfpt2s        short s short s
  1018. #
  1019. void cmov2        float s float s
  1020. void draw2        float s float s
  1021. void move2        float s float s
  1022. void pnt2        float s float s
  1023. void pdr2        float s float s
  1024. void pmv2        float s float s
  1025. void rdr2        float s float s
  1026. void rmv2        float s float s
  1027. void rpdr2        float s float s
  1028. void rpmv2        float s float s
  1029. void xfpt2        float s float s
  1030. #
  1031. void loadmatrix        float s[4*4]
  1032. # Really [4][4]
  1033. void multmatrix        float s[4*4]
  1034. # Really [4][4]
  1035. void crv            float s[3*4]
  1036. # Really [4][3]
  1037. void rcrv            float s[4*4]
  1038. # Really [4][4]
  1039. #
  1040. # Methods that have strings.  
  1041. #
  1042. void addtopup        long s char *s long s
  1043. void charstr        char *s
  1044. void getport         char *s
  1045. long strwidth        char *s
  1046. long winopen        char *s
  1047. void wintitle        char *s
  1048. #
  1049. # Methods that have 1 long (# of elements) and an array 
  1050. #
  1051. void polf        long s float s[3*arg1]
  1052. void polf2        long s float s[2*arg1]
  1053. void poly        long s float s[3*arg1]
  1054. void poly2        long s float s[2*arg1]
  1055. void crvn        long s float s[3*arg1]
  1056. void rcrvn        long s float s[4*arg1]
  1057. #
  1058. void polf2i        long s long s[2*arg1]
  1059. void polfi        long s long s[3*arg1]
  1060. void poly2i        long s long s[2*arg1]
  1061. void polyi        long s long s[3*arg1]
  1062. #
  1063. void polf2s        long s short s[2*arg1]
  1064. void polfs        long s short s[3*arg1]
  1065. void polys        long s short s[3*arg1]
  1066. void poly2s        long s short s[2*arg1]
  1067. #
  1068. void defcursor        short s u_short s[128]
  1069. # Is this useful?
  1070. void writepixels    short s u_short s[arg1]
  1071. # Should be unsigned short...
  1072. void defbasis        long s float s[4*4]
  1073. if !solaris    void gewrite        short s short s[arg1]
  1074. #
  1075. void rotate        short s char s
  1076. # This is not in the library!?
  1077. ###void setbutton        short s char s
  1078. void rot        float s char s
  1079. #
  1080. void circfi        long s long s long s
  1081. void circi        long s long s long s
  1082. void cmovi        long s long s long s
  1083. void drawi        long s long s long s
  1084. void movei        long s long s long s
  1085. void pnti         long s long s long s
  1086. void newtag        long s long s long s
  1087. void pdri          long s long s long s
  1088. void pmvi          long s long s long s
  1089. void rdri          long s long s long s
  1090. void rmvi          long s long s long s
  1091. void rpdri         long s long s long s
  1092. void rpmvi         long s long s long s
  1093. void xfpti         long s long s long s
  1094. #
  1095. void circ        float s float s float s
  1096. void circf        float s float s float s
  1097. void cmov        float s float s float s
  1098. void draw        float s float s float s
  1099. void move        float s float s float s
  1100. void pnt        float s float s float s
  1101. void scale        float s float s float s
  1102. void translate        float s float s float s
  1103. void pdr        float s float s float s
  1104. void pmv        float s float s float s
  1105. void rdr        float s float s float s
  1106. void rmv        float s float s float s
  1107. void rpdr        float s float s float s
  1108. void rpmv        float s float s float s
  1109. void xfpt        float s float s float s
  1110. #
  1111. void RGBcolor        short s short s short s
  1112. void RGBwritemask    short s short s short s
  1113. void setcursor        short s short s short s
  1114. void tie        short s short s short s
  1115. void circfs        short s short s short s
  1116. void circs        short s short s short s
  1117. void cmovs        short s short s short s
  1118. void draws        short s short s short s
  1119. void moves        short s short s short s
  1120. void pdrs        short s short s short s
  1121. void pmvs        short s short s short s
  1122. void pnts        short s short s short s
  1123. void rdrs        short s short s short s
  1124. void rmvs        short s short s short s
  1125. void rpdrs        short s short s short s
  1126. void rpmvs        short s short s short s
  1127. void xfpts        short s short s short s
  1128. void curorigin        short s short s short s
  1129. void cyclemap        short s short s short s
  1130. #
  1131. void patch        float s[4*4] float s[4*4] float s[4*4]
  1132. void splf        long s float s[3*arg1] u_short s[arg1]
  1133. void splf2        long s float s[2*arg1] u_short s[arg1]
  1134. void splfi        long s long s[3*arg1] u_short s[arg1]
  1135. void splf2i        long s long s[2*arg1] u_short s[arg1]
  1136. void splfs        long s short s[3*arg1] u_short s[arg1]
  1137. void splf2s        long s short s[2*arg1] u_short s[arg1]
  1138. ###void defpattern        short s short s u_short s[arg2*arg2/16]
  1139. #
  1140. void rpatch        float s[4*4] float s[4*4] float s[4*4] float s[4*4]
  1141. #
  1142. # routines that send 4 floats
  1143. #
  1144. void ortho2        float s float s float s float s
  1145. void rect        float s float s float s float s
  1146. void rectf        float s float s float s float s
  1147. void xfpt4        float s float s float s float s
  1148. #
  1149. void textport        short s short s short s short s
  1150. void mapcolor        short s short s short s short s
  1151. void scrmask        short s short s short s short s
  1152. void setvaluator    short s short s short s short s
  1153. void viewport        short s short s short s short s
  1154. void shaderange        short s short s short s short s
  1155. void xfpt4s        short s short s short s short s
  1156. void rectfi        long s long s long s long s
  1157. void recti        long s long s long s long s
  1158. void xfpt4i        long s long s long s long s
  1159. void prefposition    long s long s long s long s
  1160. #
  1161. void arc        float s float s float s short s short s
  1162. void arcf        float s float s float s short s short s
  1163. void arcfi        long s long s long s short s short s
  1164. void arci        long s long s long s short s short s
  1165. #
  1166. void bbox2        short s short s float s float s float s float s
  1167. void bbox2i        short s short s long s long s long s long s
  1168. void bbox2s        short s short s short s short s short s short s
  1169. void blink        short s short s short s short s short s
  1170. void ortho        float s float s float s float s float s float s
  1171. void window        float s float s float s float s float s float s
  1172. void lookat        float s float s float s float s float s float s short s
  1173. #
  1174. void perspective    short s float s float s float s
  1175. void polarview        float s short s short s short s
  1176. # XXX getichararray not supported
  1177. #void writeRGB        short s char s[arg1] char s[arg1] char s[arg1]
  1178. #
  1179. void arcfs        short s short s short s short s short s
  1180. void arcs        short s short s short s short s short s
  1181. void rectcopy        short s short s short s short s short s short s
  1182. if !solaris    void RGBcursor        short s short s short s short s short s short s short s
  1183. #
  1184. long getbutton        short s
  1185. long getcmmode
  1186. long getlsbackup
  1187. long getresetls
  1188. long getdcm
  1189. long getzbuffer
  1190. long ismex
  1191. long isobj        long s
  1192. long isqueued        short s
  1193. long istag        long s
  1194. #
  1195. long genobj
  1196. long gentag
  1197. long getbuffer
  1198. long getcolor
  1199. long getdisplaymode
  1200. long getfont
  1201. long getheight
  1202. long gethitcode
  1203. long getlstyle
  1204. long getlwidth
  1205. long getmap
  1206. long getplanes
  1207. long getwritemask
  1208. long qtest
  1209. long getlsrepeat
  1210. long getmonitor
  1211. long getopenobj
  1212. long getpattern
  1213. long winget
  1214. long winattach
  1215. long getothermonitor
  1216. long newpup
  1217. #
  1218. long getvaluator    short s
  1219. void winset        long s
  1220. long dopup        long s
  1221. void getdepth        short r short r
  1222. void getcpos        short r short r
  1223. void getsize        long r long r
  1224. void getorigin        long r long r
  1225. void getviewport    short r short r short r short r
  1226. if !solaris    void gettp        short r short r short r short r
  1227. void getgpos        float r float r float r float r
  1228. void winposition    long s long s long s long s
  1229. void gRGBcolor        short r short r short r
  1230. void gRGBmask        short r short r short r
  1231. void getscrmask    short r short r short r short r
  1232. ###void gRGBcursor    short r short r short r short r short r short r short r short r
  1233. void getmcolor        short s short r short r short r
  1234. void mapw        long s short s short s float r float r float r float r float r float r
  1235. void mapw2        long s short s short s float r float r
  1236. ###void defrasterfont    short s short s short s Fontchar s[arg3] short s short s[4*arg5]
  1237. ###long qread        short r
  1238. void getcursor        short r u_short r u_short r long r
  1239. #
  1240. #   For these we receive arrays of stuff
  1241. #
  1242. ###void getdev         long s short s[arg1] short r[arg1]
  1243. #XXX not generated correctly yet
  1244. #void getmatrix        float r[16]
  1245. ###long readpixels        short s short r[retval]
  1246. ###long readRGB        short s char r[retval] char r[retval] char r[retval]
  1247. ###long blkqread        short s short r[arg1]
  1248. #
  1249. #   New 4D routines
  1250. #
  1251. void cmode
  1252. void concave        long s
  1253. void curstype        long s
  1254. void drawmode        long s
  1255. void gammaramp        short s[256] short s[256] short s[256]
  1256. long getbackface
  1257. long getdescender
  1258. long getdrawmode
  1259. long getmmode
  1260. long getsm
  1261. long getvideo        long s
  1262. void imakebackground
  1263. void lmbind        short s short s
  1264. void lmdef        long s long s long s float s[arg3]
  1265. void mmode        long s
  1266. void normal        float s[3]
  1267. void overlay        long s
  1268. void RGBrange        short s short s short s short s short s short s short s short s
  1269. if !solaris    void setvideo         long s long s
  1270. void shademodel        long s
  1271. void underlay        long s
  1272. #
  1273. # New Personal Iris/GT Routines
  1274. #
  1275. void bgnclosedline
  1276. void bgnline
  1277. void bgnpoint
  1278. void bgnpolygon
  1279. void bgnsurface
  1280. void bgntmesh
  1281. void bgntrim
  1282. void endclosedline
  1283. void endline
  1284. void endpoint
  1285. void endpolygon
  1286. void endsurface
  1287. void endtmesh
  1288. void endtrim
  1289. void blendfunction    long s long s
  1290. void c3f        float s[3]
  1291. void c3i        long  s[3]
  1292. void c3s        short s[3]
  1293. void c4f        float s[4]
  1294. void c4i        long  s[4]
  1295. void c4s        short s[4]
  1296. void colorf        float s
  1297. void cpack        long s
  1298. void czclear        long s long s
  1299. void dglclose        long s
  1300. long dglopen        char *s long s
  1301. long getgdesc        long s
  1302. void getnurbsproperty    long s float r
  1303. void glcompat        long s long s
  1304. void iconsize         long s long s
  1305. void icontitle        char *s
  1306. void lRGBrange        short s short s short s short s short s short s long s long s
  1307. void linesmooth        long s
  1308. void lmcolor        long s
  1309. void logicop        long s
  1310. ###long lrectread         short s short s short s short s long r[retval]
  1311. ###void lrectwrite        short s short s short s short s long s[(arg2-arg1+1)*(arg4-arg3+1)]
  1312. ### Now manual, with string last arg
  1313. ###long rectread         short s short s short s short s short r[retval]
  1314. ###void rectwrite        short s short s short s short s short s[(arg2-arg1+1)*(arg4-arg3+1)]
  1315. void lsetdepth        long s long s
  1316. void lshaderange    short s short s long s long s
  1317. void n3f        float s[3]
  1318. void noborder
  1319. void pntsmooth        long s
  1320. void readsource        long s
  1321. void rectzoom        float s float s
  1322. void sbox        float s float s float s float s
  1323. void sboxi        long s long s long s long s
  1324. void sboxs        short s short s short s short s
  1325. void sboxf        float s float s float s float s
  1326. void sboxfi        long s long s long s long s
  1327. void sboxfs        short s short s short s short s
  1328. void setnurbsproperty    long s float s
  1329. void setpup         long s long s long s
  1330. void smoothline        long s
  1331. void subpixel        long s
  1332. void swaptmesh
  1333. long swinopen        long s
  1334. void v2f        float s[2]
  1335. void v2i        long  s[2]
  1336. void v2s        short s[2]
  1337. void v3f        float s[3]
  1338. void v3i        long  s[3]
  1339. void v3s        short s[3]
  1340. void v4f        float s[4]
  1341. void v4i        long  s[4]
  1342. void v4s        short s[4]
  1343. void videocmd        long s
  1344. long windepth        long s
  1345. void wmpack        long s
  1346. void zdraw        long s
  1347. void zfunction        long s
  1348. void zsource        long s
  1349. void zwritemask        long s
  1350. #
  1351. #   uses doubles
  1352. #
  1353. void v2d        double s[2]
  1354. void v3d        double s[3]
  1355. void v4d        double s[4]
  1356. #
  1357. # Why isn't this here?
  1358. #
  1359. void pixmode        long s long s
  1360. #
  1361. # New in IRIX 4.0
  1362. #
  1363. long qgetfd
  1364. void dither        long s
  1365.