1
2/*
3Input used to generate the Python module "glmodule.c".
4The stub generator is a Python script called "cgen.py".
5
6Each 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
44extern int devport();
45extern int textwritemask();
46extern int pagewritemask();
47extern int gewrite();
48extern int gettp();
49#endif
50
51#include "Python.h"
52#include "cgensupport.h"
53
54/*
55Some stubs are too complicated for the stub generator.
56We can include manually written versions of them here.
57A line starting with '%' gives the name of the function so the stub
58generator can include it in the table of functions.
59*/
60
61% qread
62
63static PyObject *
64gl_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/*
83varray -- an array of v.. calls.
84The argument is an array (maybe list or tuple) of points.
85Each point must be a tuple or list of coordinates (x, y, z).
86The points may be 2- or 3-dimensional but must all have the
87same dimension.  Float and int values may be mixed however.
88The points are always converted to 3D double precision points
89by assuming z=0.0 if necessary (as indicated in the man page),
90and for each point v3d() is called.
91*/
92
93% varray
94
95static PyObject *
96gl_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/*
161vnarray, nvarray -- an array of n3f and v3f calls.
162The argument is an array (list or tuple) of pairs of points and normals.
163Each pair is a tuple (NOT a list) of a point and a normal for that point.
164Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
165Three coordinates must be given.  Float and int values may be mixed.
166For each pair, n3f() is called for the normal, and then v3f() is called
167for the vector.
168
169vnarray and nvarray differ only in the order of the vector and normal in
170the pair: vnarray expects (v, n) while nvarray expects (n, v).
171*/
172
173static PyObject *gen_nvarray(); /* Forward */
174
175% nvarray
176
177static PyObject *
178gl_nvarray(self, args)
179	PyObject *self;
180	PyObject *args;
181{
182	return gen_nvarray(args, 0);
183}
184
185% vnarray
186
187static PyObject *
188gl_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
198static PyObject *
199gen_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
250static PyObject *
251gl_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
339static PyObject *
340gl_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
402static PyObject *
403gl_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
445static short *pickbuffer = NULL;
446static long pickbuffersize;
447
448static PyObject *
449pick_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
468static PyObject *
469endpick_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
509extern void pick(), gselect();
510extern long endpick(), endselect();
511
512%pick
513static PyObject *gl_pick(self, args) PyObject *self, *args; {
514	return pick_select(args, pick);
515}
516
517%endpick
518static PyObject *gl_endpick(self, args) PyObject *self, *args; {
519	return endpick_select(args, endpick);
520}
521
522%gselect
523static PyObject *gl_gselect(self, args) PyObject *self, *args; {
524	return pick_select(args, gselect);
525}
526
527%endselect
528static 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
539static PyObject *
540gl_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
569static PyObject *
570gl_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
605static PyObject *
606gl_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
647static PyObject *
648gl_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
676static PyObject *
677gl_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
721static PyObject *
722gl_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
774static unsigned long unpacktab[256];
775static int unpacktab_inited = 0;
776
777static PyObject *
778gl_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
848static PyObject *
849gl_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
861static PyObject *
862gl_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
875long 	getshade
876if !solaris	void 	devport 	short s long s
877void 	rdr2i 		long s long s
878void	rectfs 		short s short s short s short s
879void 	rects 		short s short s short s short s
880void 	rmv2i 		long s long s
881void	noport
882void	popviewport
883void	clearhitcode
884void	closeobj
885void	cursoff
886void	curson
887void	doublebuffer
888void 	finish
889void	gconfig
890void	ginit
891void	greset
892void	multimap
893void	onemap
894void	popattributes
895void	popmatrix
896void	pushattributes
897void	pushmatrix
898void	pushviewport
899void	qreset
900void	RGBmode
901void	singlebuffer
902void	swapbuffers
903void	gsync
904void	gflush
905void	tpon
906void	tpoff
907void	clkon
908void	clkoff
909void	ringbell
910#void	callfunc
911void	gbegin
912void	textinit
913void	initnames
914void	pclos
915void	popname
916if !solaris	void	spclos
917void	zclear
918void	screenspace
919void	reshapeviewport
920void	winpush
921void	winpop
922void	foreground
923void	endfullscrn
924if !solaris	void	endpupmode
925void	fullscrn
926if !solaris	void	pupmode
927void	winconstraints
928void	pagecolor 	short s
929void	textcolor 	short s
930void 	color 	  	short s
931void	curveit		short s
932void	font		short s
933void 	linewidth	short s
934void    setlinestyle	short s
935void	setmap		short s
936void	swapinterval	short s
937void	writemask	short s
938if !solaris	void	textwritemask	short s
939void	qdevice		short s
940void	unqdevice	short s
941void	curvebasis	short s
942void	curveprecision	short s
943void	loadname	short s
944void	passthrough	short s
945void	pushname	short s
946void	setmonitor	short s
947if !solaris	void	setshade	short s
948void	setpattern	short s
949if !solaris	void	pagewritemask	short s
950#
951void	callobj		long s
952void	delobj		long s
953void 	editobj		long s
954void	makeobj		long s
955void	maketag		long s
956void	chunksize	long s
957void	compactify	long s
958void	deltag		long s
959void	lsrepeat	long s
960void	objinsert	long s
961void 	objreplace	long s
962void	winclose	long s
963void	blanktime	long s
964void 	freepup		long s
965# This is not in the library!?
966###void	pupcolor	long s
967#
968void	backbuffer	long s
969void 	frontbuffer	long s
970if !solaris	void	lsbackup	long s
971void	resetls		long s
972void	lampon		long s
973void	lampoff		long s
974void	setbell		long s
975void	blankscreen	long s
976void 	depthcue	long s
977void	zbuffer		long s
978void	backface	long s
979#
980void 	cmov2i		long s long s
981void 	draw2i		long s long s
982void	move2i		long s long s
983void	pnt2i		long s long s
984void 	patchbasis	long s long s
985void 	patchprecision	long s long s
986void	pdr2i		long s long s
987void	pmv2i		long s long s
988void	rpdr2i		long s long s
989void	rpmv2i		long s long s
990void	xfpt2i		long s long s
991void	objdelete	long s long s
992void	patchcurves	long s long s
993void	minsize		long s long s
994void 	maxsize		long s long s
995void	keepaspect	long s long s
996void	prefsize	long s long s
997void	stepunit	long s long s
998void 	fudge		long s long s
999void 	winmove		long s long s
1000#
1001void 	attachcursor	short s short s
1002void 	deflinestyle	short s short s
1003void 	noise		short s short s
1004void 	picksize	short s short s
1005void 	qenter		short s short s
1006void 	setdepth	short s short s
1007void 	cmov2s		short s short s
1008void 	draw2s		short s	short s
1009void 	move2s		short s short s
1010void 	pdr2s		short s short s
1011void 	pmv2s		short s short s
1012void 	pnt2s		short s short s
1013void 	rdr2s		short s short s
1014void 	rmv2s		short s short s
1015void 	rpdr2s		short s short s
1016void 	rpmv2s		short s short s
1017void 	xfpt2s		short s short s
1018#
1019void cmov2		float s float s
1020void draw2		float s float s
1021void move2		float s float s
1022void pnt2		float s float s
1023void pdr2		float s float s
1024void pmv2		float s float s
1025void rdr2		float s float s
1026void rmv2		float s float s
1027void rpdr2		float s float s
1028void rpmv2		float s float s
1029void xfpt2		float s float s
1030#
1031void loadmatrix		float s[4*4]
1032# Really [4][4]
1033void multmatrix		float s[4*4]
1034# Really [4][4]
1035void crv			float s[3*4]
1036# Really [4][3]
1037void rcrv			float s[4*4]
1038# Really [4][4]
1039#
1040# Methods that have strings.
1041#
1042void addtopup		long s char *s long s
1043void charstr		char *s
1044void getport	 	char *s
1045long strwidth		char *s
1046long winopen		char *s
1047void wintitle		char *s
1048#
1049# Methods that have 1 long (# of elements) and an array
1050#
1051void polf		long s float s[3*arg1]
1052void polf2		long s float s[2*arg1]
1053void poly		long s float s[3*arg1]
1054void poly2		long s float s[2*arg1]
1055void crvn		long s float s[3*arg1]
1056void rcrvn		long s float s[4*arg1]
1057#
1058void polf2i		long s long s[2*arg1]
1059void polfi		long s long s[3*arg1]
1060void poly2i		long s long s[2*arg1]
1061void polyi		long s long s[3*arg1]
1062#
1063void polf2s		long s short s[2*arg1]
1064void polfs		long s short s[3*arg1]
1065void polys		long s short s[3*arg1]
1066void poly2s		long s short s[2*arg1]
1067#
1068void defcursor		short s u_short s[128]
1069# Is this useful?
1070void writepixels	short s u_short s[arg1]
1071# Should be unsigned short...
1072void defbasis		long s float s[4*4]
1073if !solaris	void gewrite		short s short s[arg1]
1074#
1075void rotate		short s char s
1076# This is not in the library!?
1077###void setbutton		short s char s
1078void rot		float s char s
1079#
1080void circfi		long s long s long s
1081void circi		long s long s long s
1082void cmovi		long s long s long s
1083void drawi		long s long s long s
1084void movei		long s long s long s
1085void pnti 		long s long s long s
1086void newtag		long s long s long s
1087void pdri  		long s long s long s
1088void pmvi  		long s long s long s
1089void rdri  		long s long s long s
1090void rmvi  		long s long s long s
1091void rpdri 		long s long s long s
1092void rpmvi 		long s long s long s
1093void xfpti 		long s long s long s
1094#
1095void circ		float s float s float s
1096void circf		float s float s float s
1097void cmov		float s float s float s
1098void draw		float s float s float s
1099void move		float s float s float s
1100void pnt		float s float s float s
1101void scale		float s float s float s
1102void translate		float s float s float s
1103void pdr		float s float s float s
1104void pmv		float s float s float s
1105void rdr		float s float s float s
1106void rmv		float s float s float s
1107void rpdr		float s float s float s
1108void rpmv		float s float s float s
1109void xfpt		float s float s float s
1110#
1111void RGBcolor		short s short s short s
1112void RGBwritemask	short s short s short s
1113void setcursor		short s short s short s
1114void tie		short s short s short s
1115void circfs		short s short s short s
1116void circs		short s short s short s
1117void cmovs		short s short s short s
1118void draws		short s short s short s
1119void moves		short s short s short s
1120void pdrs		short s short s short s
1121void pmvs		short s short s short s
1122void pnts		short s short s short s
1123void rdrs		short s short s short s
1124void rmvs		short s short s short s
1125void rpdrs		short s short s short s
1126void rpmvs		short s short s short s
1127void xfpts		short s short s short s
1128void curorigin		short s short s short s
1129void cyclemap		short s short s short s
1130#
1131void patch		float s[4*4] float s[4*4] float s[4*4]
1132void splf		long s float s[3*arg1] u_short s[arg1]
1133void splf2		long s float s[2*arg1] u_short s[arg1]
1134void splfi		long s long s[3*arg1] u_short s[arg1]
1135void splf2i		long s long s[2*arg1] u_short s[arg1]
1136void splfs		long s short s[3*arg1] u_short s[arg1]
1137void 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#
1140void 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#
1144void ortho2		float s float s float s float s
1145void rect		float s float s float s float s
1146void rectf		float s float s float s float s
1147void xfpt4		float s float s float s float s
1148#
1149void textport		short s short s short s short s
1150void mapcolor		short s short s short s short s
1151void scrmask		short s short s short s short s
1152void setvaluator	short s short s short s short s
1153void viewport		short s short s short s short s
1154void shaderange		short s short s short s short s
1155void xfpt4s		short s short s short s short s
1156void rectfi		long s long s long s long s
1157void recti		long s long s long s long s
1158void xfpt4i		long s long s long s long s
1159void prefposition	long s long s long s long s
1160#
1161void arc		float s float s float s short s short s
1162void arcf		float s float s float s short s short s
1163void arcfi		long s long s long s short s short s
1164void arci		long s long s long s short s short s
1165#
1166void bbox2		short s short s float s float s float s float s
1167void bbox2i		short s short s long s long s long s long s
1168void bbox2s		short s short s short s short s short s short s
1169void blink		short s short s short s short s short s
1170void ortho		float s float s float s float s float s float s
1171void window		float s float s float s float s float s float s
1172void lookat		float s float s float s float s float s float s short s
1173#
1174void perspective	short s float s float s float s
1175void 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#
1179void arcfs		short s short s short s short s short s
1180void arcs		short s short s short s short s short s
1181void rectcopy		short s short s short s short s short s short s
1182if !solaris	void RGBcursor		short s short s short s short s short s short s short s
1183#
1184long getbutton		short s
1185long getcmmode
1186long getlsbackup
1187long getresetls
1188long getdcm
1189long getzbuffer
1190long ismex
1191long isobj		long s
1192long isqueued		short s
1193long istag		long s
1194#
1195long genobj
1196long gentag
1197long getbuffer
1198long getcolor
1199long getdisplaymode
1200long getfont
1201long getheight
1202long gethitcode
1203long getlstyle
1204long getlwidth
1205long getmap
1206long getplanes
1207long getwritemask
1208long qtest
1209long getlsrepeat
1210long getmonitor
1211long getopenobj
1212long getpattern
1213long winget
1214long winattach
1215long getothermonitor
1216long newpup
1217#
1218long getvaluator	short s
1219void winset		long s
1220long dopup		long s
1221void getdepth		short r short r
1222void getcpos		short r short r
1223void getsize		long r long r
1224void getorigin		long r long r
1225void getviewport	short r short r short r short r
1226if !solaris	void gettp		short r short r short r short r
1227void getgpos		float r float r float r float r
1228void winposition	long s long s long s long s
1229void gRGBcolor		short r short r short r
1230void gRGBmask		short r short r short r
1231void 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
1233void getmcolor		short s short r short r short r
1234void mapw		long s short s short s float r float r float r float r float r float r
1235void 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
1238void 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#
1251void cmode
1252void concave		long s
1253void curstype		long s
1254void drawmode		long s
1255void gammaramp		short s[256] short s[256] short s[256]
1256long getbackface
1257long getdescender
1258long getdrawmode
1259long getmmode
1260long getsm
1261long getvideo		long s
1262void imakebackground
1263void lmbind		short s short s
1264void lmdef		long s long s long s float s[arg3]
1265void mmode		long s
1266void normal		float s[3]
1267void overlay		long s
1268void RGBrange		short s short s short s short s short s short s short s short s
1269if !solaris	void setvideo 		long s long s
1270void shademodel		long s
1271void underlay		long s
1272#
1273# New Personal Iris/GT Routines
1274#
1275void bgnclosedline
1276void bgnline
1277void bgnpoint
1278void bgnpolygon
1279void bgnsurface
1280void bgntmesh
1281void bgntrim
1282void endclosedline
1283void endline
1284void endpoint
1285void endpolygon
1286void endsurface
1287void endtmesh
1288void endtrim
1289void blendfunction	long s long s
1290void c3f		float s[3]
1291void c3i		long  s[3]
1292void c3s		short s[3]
1293void c4f		float s[4]
1294void c4i		long  s[4]
1295void c4s		short s[4]
1296void colorf		float s
1297void cpack		long s
1298void czclear		long s long s
1299void dglclose		long s
1300long dglopen		char *s long s
1301long getgdesc		long s
1302void getnurbsproperty	long s float r
1303void glcompat		long s long s
1304void iconsize 		long s long s
1305void icontitle		char *s
1306void lRGBrange		short s short s short s short s short s short s long s long s
1307void linesmooth		long s
1308void lmcolor		long s
1309void 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)]
1315void lsetdepth		long s long s
1316void lshaderange	short s short s long s long s
1317void n3f		float s[3]
1318void noborder
1319void pntsmooth		long s
1320void readsource		long s
1321void rectzoom		float s float s
1322void sbox		float s float s float s float s
1323void sboxi		long s long s long s long s
1324void sboxs		short s short s short s short s
1325void sboxf		float s float s float s float s
1326void sboxfi		long s long s long s long s
1327void sboxfs		short s short s short s short s
1328void setnurbsproperty	long s float s
1329void setpup 		long s long s long s
1330void smoothline		long s
1331void subpixel		long s
1332void swaptmesh
1333long swinopen		long s
1334void v2f		float s[2]
1335void v2i		long  s[2]
1336void v2s		short s[2]
1337void v3f		float s[3]
1338void v3i		long  s[3]
1339void v3s		short s[3]
1340void v4f		float s[4]
1341void v4i		long  s[4]
1342void v4s		short s[4]
1343void videocmd		long s
1344long windepth		long s
1345void wmpack		long s
1346void zdraw		long s
1347void zfunction		long s
1348void zsource		long s
1349void zwritemask		long s
1350#
1351#   uses doubles
1352#
1353void v2d		double s[2]
1354void v3d		double s[3]
1355void v4d		double s[4]
1356#
1357# Why isn't this here?
1358#
1359void pixmode		long s long s
1360#
1361# New in IRIX 4.0
1362#
1363long qgetfd
1364void dither		long s
1365