Improve implementation with better underlying data structure
[python.git] / Modules / cstubs
blob53bd4ab310698b171b34d3cdd35f6e3a6d8113ac
2 /*
3 Input used to generate the Python module "glmodule.c".
4 The stub generator is a Python script called "cgen.py".
6 Each definition must be contained on one line:
8 <returntype> <name> <type> <arg> <type> <arg>
10 <returntype> can be: void, short, long (XXX maybe others?)
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
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.
36  * An attempt has been made to make this module switch threads on qread
37  * calls. It is far from safe, though.
38  */
40 #include <gl.h>
41 #include <device.h>
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
51 #include "Python.h"
52 #include "cgensupport.h"
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.
61 % qread
63 static PyObject *
64 gl_qread(self, args)
65         PyObject *self;
66         PyObject *args;
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         }
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.
93 % varray
95 static PyObject *
96 gl_varray(self, args)
97         PyObject *self;
98         PyObject *args;
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;
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.
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).
173 static PyObject *gen_nvarray(); /* Forward */
175 % nvarray
177 static PyObject *
178 gl_nvarray(self, args)
179         PyObject *self;
180         PyObject *args;
182         return gen_nvarray(args, 0);
185 % vnarray
187 static PyObject *
188 gl_vnarray(self, args)
189         PyObject *self;
190         PyObject *args;
192         return gen_nvarray(args, 1);
195 /* Generic, internal version of {nv,nv}array: inorm indicates the
196    argument order, 0: normal first, 1: vector first. */
198 static PyObject *
199 gen_nvarray(args, inorm)
200         PyObject *args;
201         int inorm;
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;
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]
248 % nurbssurface
250 static PyObject *
251 gl_nurbssurface(self, args)
252         PyObject *self;
253         PyObject *args;
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;
334 /* nurbscurve(knots, ctlpoints, order, type).
335    The length of ctlpoints is len(knots)-order. */
337 %nurbscurve
339 static PyObject *
340 gl_nurbscurve(self, args)
341         PyObject *self;
342         PyObject *args;
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;
397 /* pwlcurve(points, type).
398    Points is a list of points. Type must be N_ST. */
400 %pwlcurve
402 static PyObject *
403 gl_pwlcurve(self, args)
404         PyObject *self;
405         PyObject *args;
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;
443 /* Picking and Selecting */
445 static short *pickbuffer = NULL;
446 static long pickbuffersize;
448 static PyObject *
449 pick_select(args, func)
450         PyObject *args;
451         void (*func)();
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;
468 static PyObject *
469 endpick_select(args, func)
470         PyObject *args;
471         long (*func)();
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;
509 extern void pick(), gselect();
510 extern long endpick(), endselect();
512 %pick
513 static PyObject *gl_pick(self, args) PyObject *self, *args; {
514         return pick_select(args, pick);
517 %endpick
518 static PyObject *gl_endpick(self, args) PyObject *self, *args; {
519         return endpick_select(args, endpick);
522 %gselect
523 static PyObject *gl_gselect(self, args) PyObject *self, *args; {
524         return pick_select(args, gselect);
527 %endselect
528 static PyObject *gl_endselect(self, args) PyObject *self, *args; {
529         return endpick_select(args, endselect);
533 /* XXX The generator botches this one.  Here's a quick hack to fix it. */
535 /* XXX The generator botches this one.  Here's a quick hack to fix it. */
537 % getmatrix float r[16]
539 static PyObject *
540 gl_getmatrix(self, args)
541         PyObject *self;
542         PyObject *args;
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;
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... */
567 % altgetmatrix float r[4][4]
569 static PyObject *
570 gl_altgetmatrix(self, args)
571         PyObject *self;
572         PyObject *args;
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;
603 % lrectwrite
605 static PyObject *
606 gl_lrectwrite(self, args)
607         PyObject *self;
608         PyObject *args;
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;
645 % lrectread
647 static PyObject *
648 gl_lrectread(self, args)
649         PyObject *self;
650         PyObject *args;
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;
674 % readdisplay
676 static PyObject *
677 gl_readdisplay(self, args)
678         PyObject *self;
679         PyObject *args;
681         short x1, y1, x2, y2;
682         unsigned long *parray, hints;
683         long size, size_ret;
684         PyObject *rv;
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;
703 /* Desperately needed, here are tools to compress and decompress
704    the data manipulated by lrectread/lrectwrite.
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
712    gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
713                 is the inverse; the numeric arguments must be *the same*.
715    Both work best if width and height are multiples of packfactor
716    (in fact unpackrect will leave garbage bytes).
719 % packrect
721 static PyObject *
722 gl_packrect(self, args)
723         PyObject *self;
724         PyObject *args;
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;
772 % unpackrect
774 static unsigned long unpacktab[256];
775 static int unpacktab_inited = 0;
777 static PyObject *
778 gl_unpackrect(self, args)
779         PyObject *self;
780         PyObject *args;
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;
847 % gversion
848 static PyObject *
849 gl_gversion(self, args)
850         PyObject *self;
851         PyObject *args;
853         char buf[20];
854         gversion(buf);
855         return PyString_FromString(buf);
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;
866         __GLclear( );
867         Py_INCREF(Py_None);
868         return Py_None;
871 /* End of manually written stubs */
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
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
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
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
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
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
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]
1040 # Methods that have strings.  
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
1049 # Methods that have 1 long (# of elements) and an array 
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]
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]
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]
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]
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
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
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
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
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]
1140 void rpatch             float s[4*4] float s[4*4] float s[4*4] float s[4*4]
1142 # routines that send 4 floats
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
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
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
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
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]
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
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
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
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
1240 #   For these we receive arrays of stuff
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]
1249 #   New 4D routines
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
1273 # New Personal Iris/GT Routines
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
1351 #   uses doubles
1353 void v2d                double s[2]
1354 void v3d                double s[3]
1355 void v4d                double s[4]
1357 # Why isn't this here?
1359 void pixmode            long s long s
1361 # New in IRIX 4.0
1363 long qgetfd
1364 void dither             long s