Clarify portability and main program.
[python/dscho.git] / Modules / stdwinmodule.c
bloba27204744304eeb1b90923168d0244b7e5de0d01
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Stdwin module */
34 /* Stdwin itself is a module, not a separate object type.
35 Object types defined here:
36 wp: a window
37 dp: a drawing structure (only one can exist at a time)
38 mp: a menu
39 tp: a textedit block
40 bp: a bitmap
43 /* Rules for translating C stdwin function calls into Python stwin:
44 - All names drop their initial letter 'w'
45 - Functions with a window as first parameter are methods of window objects
46 - There is no equivalent for wclose(); just delete the window object
47 (all references to it!) (XXX maybe this is a bad idea)
48 - w.begindrawing() returns a drawing object
49 - There is no equivalent for wenddrawing(win); just delete the drawing
50 object (all references to it!) (XXX maybe this is a bad idea)
51 - Functions that may only be used inside wbegindrawing / wendddrawing
52 are methods of the drawing object; this includes the text measurement
53 functions (which however have doubles as module functions).
54 - Methods of the drawing object drop an initial 'draw' from their name
55 if they have it, e.g., wdrawline() --> d.line()
56 - The obvious type conversions: int --> intobject; string --> stringobject
57 - A text parameter followed by a length parameter is only a text (string)
58 parameter in Python
59 - A point or other pair of horizontal and vertical coordinates is always
60 a pair of integers in Python
61 - Two points forming a rectangle or endpoints of a line segment are a
62 pair of points in Python
63 - The arguments to d.elarc() are three points.
64 - The functions wgetclip() and wsetclip() are translated into
65 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
66 a bad word for what these functions do (clipping has a different
67 meaning in the drawing world), while cutbuffer is standard X jargon.
68 XXX This must change again in the light of changes to stdwin!
69 - For textedit, similar rules hold, but they are less strict.
70 XXX more?
73 #include "Python.h"
75 #ifdef macintosh
76 #include "macglue.h"
77 #endif
79 #ifdef macintosh
80 #include ":::stdwin:H:stdwin.h"
81 #else /* !macintosh */
82 #include "stdwin.h"
83 #define HAVE_BITMAPS
84 #endif /* !macintosh */
86 #ifdef WITH_THREAD
88 #include "pythread.h"
90 static type_lock StdwinLock; /* Lock held when interpreter not locked */
92 #define BGN_STDWIN Py_BEGIN_ALLOW_THREADS acquire_lock(StdwinLock, 1);
93 #define RET_STDWIN release_lock(StdwinLock); Py_BLOCK_THREADS
94 #define END_STDWIN release_lock(StdwinLock); Py_END_ALLOW_THREADS
96 #else
98 #define BGN_STDWIN Py_BEGIN_ALLOW_THREADS
99 #define RET_STDWIN Py_BLOCK_THREADS
100 #define END_STDWIN Py_END_ALLOW_THREADS
102 #endif
104 #define getintarg(v,a) PyArg_Parse(v, "i", a)
105 #define getlongarg(v,a) PyArg_Parse(v, "l", a)
106 #define getstrarg(v,a) PyArg_Parse(v, "s", a)
107 #define getpointarg(v, a) PyArg_Parse(v, "(ii)", a, (a)+1)
108 #define get3pointarg(v, a) PyArg_Parse(v, "((ii)(ii)(ii))", \
109 a, a+1, a+2, a+3, a+4, a+5)
110 #define getrectarg(v, a) PyArg_Parse(v, "((ii)(ii))", a, a+1, a+2, a+3)
111 #define getrectintarg(v, a) PyArg_Parse(v, "(((ii)(ii))i)", \
112 a, a+1, a+2, a+3, a+4)
113 #define getpointintarg(v, a) PyArg_Parse(v, "((ii)i)", a, a+1, a+2)
114 #define getrectpointarg(v, a) PyArg_Parse(v, "(((ii)(ii))(ii))", \
115 a, a+1, a+2, a+3, a+4, a+5)
117 static PyObject *StdwinError; /* Exception stdwin.error */
119 /* Window and menu object types declared here because of forward references */
121 typedef struct {
122 PyObject_HEAD
123 PyObject *w_title;
124 WINDOW *w_win;
125 PyObject *w_attr; /* Attributes dictionary */
126 } windowobject;
128 staticforward PyTypeObject Windowtype;
130 #define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
132 typedef struct {
133 PyObject_HEAD
134 MENU *m_menu;
135 int m_id;
136 PyObject *m_attr; /* Attributes dictionary */
137 } menuobject;
139 staticforward PyTypeObject Menutype;
141 #define is_menuobject(mp) ((mp)->ob_type == &Menutype)
143 typedef struct {
144 PyObject_HEAD
145 BITMAP *b_bitmap;
146 PyObject *b_attr; /* Attributes dictionary */
147 } bitmapobject;
149 staticforward PyTypeObject Bitmaptype;
151 #define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
154 /* Strongly stdwin-specific argument handlers */
156 static int
157 getmenudetail(v, ep)
158 PyObject *v;
159 EVENT *ep;
161 menuobject *mp;
162 if (!PyArg_Parse(v, "(Oi)", &mp, &ep->u.m.item))
163 return 0;
164 if (!is_menuobject(mp))
165 return PyErr_BadArgument();
166 ep->u.m.id = mp->m_id;
167 return 1;
170 static int
171 geteventarg(v, ep)
172 PyObject *v;
173 EVENT *ep;
175 PyObject *wp, *detail;
176 int a[4];
177 if (!PyArg_Parse(v, "(iOO)", &ep->type, &wp, &detail))
178 return 0;
179 if (is_windowobject(wp))
180 ep->window = ((windowobject *)wp) -> w_win;
181 else if (wp == Py_None)
182 ep->window = NULL;
183 else
184 return PyErr_BadArgument();
185 switch (ep->type) {
186 case WE_CHAR: {
187 char c;
188 if (!PyArg_Parse(detail, "c", &c))
189 return 0;
190 ep->u.character = c;
191 return 1;
193 case WE_COMMAND:
194 return getintarg(detail, &ep->u.command);
195 case WE_DRAW:
196 if (!getrectarg(detail, a))
197 return 0;
198 ep->u.area.left = a[0];
199 ep->u.area.top = a[1];
200 ep->u.area.right = a[2];
201 ep->u.area.bottom = a[3];
202 return 1;
203 case WE_MOUSE_DOWN:
204 case WE_MOUSE_UP:
205 case WE_MOUSE_MOVE:
206 return PyArg_Parse(detail, "((ii)iii)",
207 &ep->u.where.h, &ep->u.where.v,
208 &ep->u.where.clicks,
209 &ep->u.where.button,
210 &ep->u.where.mask);
211 case WE_MENU:
212 return getmenudetail(detail, ep);
213 case WE_KEY:
214 return PyArg_Parse(detail, "(ii)",
215 &ep->u.key.code, &ep->u.key.mask);
216 default:
217 return 1;
222 /* Return construction tools */
224 static PyObject *
225 makepoint(a, b)
226 int a, b;
228 return Py_BuildValue("(ii)", a, b);
231 static PyObject *
232 makerect(a, b, c, d)
233 int a, b, c, d;
235 return Py_BuildValue("((ii)(ii))", a, b, c, d);
239 /* Drawing objects */
241 typedef struct {
242 PyObject_HEAD
243 windowobject *d_ref;
244 } drawingobject;
246 static drawingobject *Drawing; /* Set to current drawing object, or NULL */
248 /* Drawing methods */
250 static PyObject *
251 drawing_close(dp)
252 drawingobject *dp;
254 if (dp->d_ref != NULL) {
255 wenddrawing(dp->d_ref->w_win);
256 Drawing = NULL;
257 Py_DECREF(dp->d_ref);
258 dp->d_ref = NULL;
260 Py_INCREF(Py_None);
261 return Py_None;
264 static void
265 drawing_dealloc(dp)
266 drawingobject *dp;
268 if (dp->d_ref != NULL) {
269 wenddrawing(dp->d_ref->w_win);
270 Drawing = NULL;
271 Py_DECREF(dp->d_ref);
272 dp->d_ref = NULL;
274 free((char *)dp);
277 static PyObject *
278 drawing_generic(dp, args, func)
279 drawingobject *dp;
280 PyObject *args;
281 void (*func) Py_FPROTO((int, int, int, int));
283 int a[4];
284 if (!getrectarg(args, a))
285 return NULL;
286 (*func)(a[0], a[1], a[2], a[3]);
287 Py_INCREF(Py_None);
288 return Py_None;
291 static PyObject *
292 drawing_line(dp, args)
293 drawingobject *dp;
294 PyObject *args;
296 return drawing_generic(dp, args, wdrawline);
299 static PyObject *
300 drawing_xorline(dp, args)
301 drawingobject *dp;
302 PyObject *args;
304 return drawing_generic(dp, args, wxorline);
307 static PyObject *
308 drawing_circle(dp, args)
309 drawingobject *dp;
310 PyObject *args;
312 int a[3];
313 if (!getpointintarg(args, a))
314 return NULL;
315 wdrawcircle(a[0], a[1], a[2]);
316 Py_INCREF(Py_None);
317 return Py_None;
320 static PyObject *
321 drawing_fillcircle(dp, args)
322 drawingobject *dp;
323 PyObject *args;
325 int a[3];
326 if (!getpointintarg(args, a))
327 return NULL;
328 wfillcircle(a[0], a[1], a[2]);
329 Py_INCREF(Py_None);
330 return Py_None;
333 static PyObject *
334 drawing_xorcircle(dp, args)
335 drawingobject *dp;
336 PyObject *args;
338 int a[3];
339 if (!getpointintarg(args, a))
340 return NULL;
341 wxorcircle(a[0], a[1], a[2]);
342 Py_INCREF(Py_None);
343 return Py_None;
346 static PyObject *
347 drawing_elarc(dp, args)
348 drawingobject *dp;
349 PyObject *args;
351 int a[6];
352 if (!get3pointarg(args, a))
353 return NULL;
354 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
355 Py_INCREF(Py_None);
356 return Py_None;
359 static PyObject *
360 drawing_fillelarc(dp, args)
361 drawingobject *dp;
362 PyObject *args;
364 int a[6];
365 if (!get3pointarg(args, a))
366 return NULL;
367 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
368 Py_INCREF(Py_None);
369 return Py_None;
372 static PyObject *
373 drawing_xorelarc(dp, args)
374 drawingobject *dp;
375 PyObject *args;
377 int a[6];
378 if (!get3pointarg(args, a))
379 return NULL;
380 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
381 Py_INCREF(Py_None);
382 return Py_None;
385 static PyObject *
386 drawing_box(dp, args)
387 drawingobject *dp;
388 PyObject *args;
390 return drawing_generic(dp, args, wdrawbox);
393 static PyObject *
394 drawing_erase(dp, args)
395 drawingobject *dp;
396 PyObject *args;
398 return drawing_generic(dp, args, werase);
401 static PyObject *
402 drawing_paint(dp, args)
403 drawingobject *dp;
404 PyObject *args;
406 return drawing_generic(dp, args, wpaint);
409 static PyObject *
410 drawing_invert(dp, args)
411 drawingobject *dp;
412 PyObject *args;
414 return drawing_generic(dp, args, winvert);
417 static POINT *
418 getpointsarray(v, psize)
419 PyObject *v;
420 int *psize;
422 int n = -1;
423 PyObject * (*getitem) Py_PROTO((PyObject *, int));
424 int i;
425 POINT *points;
427 if (v == NULL)
429 else if (PyList_Check(v)) {
430 n = PyList_Size(v);
431 getitem = PyList_GetItem;
433 else if (PyTuple_Check(v)) {
434 n = PyTuple_Size(v);
435 getitem = PyTuple_GetItem;
438 if (n <= 0) {
439 (void) PyErr_BadArgument();
440 return NULL;
443 points = PyMem_NEW(POINT, n);
444 if (points == NULL) {
445 (void) PyErr_NoMemory();
446 return NULL;
449 for (i = 0; i < n; i++) {
450 PyObject *w = (*getitem)(v, i);
451 int a[2];
452 if (!getpointarg(w, a)) {
453 PyMem_DEL(points);
454 return NULL;
456 points[i].h = a[0];
457 points[i].v = a[1];
460 *psize = n;
461 return points;
464 static PyObject *
465 drawing_poly(dp, args)
466 drawingobject *dp;
467 PyObject *args;
469 int n;
470 POINT *points = getpointsarray(args, &n);
471 if (points == NULL)
472 return NULL;
473 wdrawpoly(n, points);
474 PyMem_DEL(points);
475 Py_INCREF(Py_None);
476 return Py_None;
479 static PyObject *
480 drawing_fillpoly(dp, args)
481 drawingobject *dp;
482 PyObject *args;
484 int n;
485 POINT *points = getpointsarray(args, &n);
486 if (points == NULL)
487 return NULL;
488 wfillpoly(n, points);
489 PyMem_DEL(points);
490 Py_INCREF(Py_None);
491 return Py_None;
494 static PyObject *
495 drawing_xorpoly(dp, args)
496 drawingobject *dp;
497 PyObject *args;
499 int n;
500 POINT *points = getpointsarray(args, &n);
501 if (points == NULL)
502 return NULL;
503 wxorpoly(n, points);
504 PyMem_DEL(points);
505 Py_INCREF(Py_None);
506 return Py_None;
509 static PyObject *
510 drawing_cliprect(dp, args)
511 drawingobject *dp;
512 PyObject *args;
514 return drawing_generic(dp, args, wcliprect);
517 static PyObject *
518 drawing_noclip(dp, args)
519 drawingobject *dp;
520 PyObject *args;
522 if (!PyArg_NoArgs(args))
523 return NULL;
524 wnoclip();
525 Py_INCREF(Py_None);
526 return Py_None;
529 static PyObject *
530 drawing_shade(dp, args)
531 drawingobject *dp;
532 PyObject *args;
534 int a[5];
535 if (!getrectintarg(args, a))
536 return NULL;
537 wshade(a[0], a[1], a[2], a[3], a[4]);
538 Py_INCREF(Py_None);
539 return Py_None;
542 static PyObject *
543 drawing_text(dp, args)
544 drawingobject *dp;
545 PyObject *args;
547 int h, v, size;
548 char *text;
549 if (!PyArg_Parse(args, "((ii)t#)", &h, &v, &text, &size))
550 return NULL;
551 wdrawtext(h, v, text, size);
552 Py_INCREF(Py_None);
553 return Py_None;
556 /* The following four are also used as stdwin functions */
558 static PyObject *
559 drawing_lineheight(dp, args)
560 drawingobject *dp;
561 PyObject *args;
563 if (!PyArg_NoArgs(args))
564 return NULL;
565 return PyInt_FromLong((long)wlineheight());
568 static PyObject *
569 drawing_baseline(dp, args)
570 drawingobject *dp;
571 PyObject *args;
573 if (!PyArg_NoArgs(args))
574 return NULL;
575 return PyInt_FromLong((long)wbaseline());
578 static PyObject *
579 drawing_textwidth(dp, args)
580 drawingobject *dp;
581 PyObject *args;
583 char *text;
584 int size;
585 if (!PyArg_Parse(args, "t#", &text, &size))
586 return NULL;
587 return PyInt_FromLong((long)wtextwidth(text, size));
590 static PyObject *
591 drawing_textbreak(dp, args)
592 drawingobject *dp;
593 PyObject *args;
595 char *text;
596 int size, width;
597 if (!PyArg_Parse(args, "(t#i)", &text, &size, &width))
598 return NULL;
599 return PyInt_FromLong((long)wtextbreak(text, size, width));
602 static PyObject *
603 drawing_setfont(self, args)
604 drawingobject *self;
605 PyObject *args;
607 char *font;
608 char style = '\0';
609 int size = 0;
610 if (args == NULL || !PyTuple_Check(args)) {
611 if (!PyArg_Parse(args, "z", &font))
612 return NULL;
614 else {
615 int n = PyTuple_Size(args);
616 if (n == 2) {
617 if (!PyArg_Parse(args, "(zi)", &font, &size))
618 return NULL;
620 else if (!PyArg_Parse(args, "(zic)", &font, &size, &style)) {
621 PyErr_Clear();
622 if (!PyArg_Parse(args, "(zci)", &font, &style, &size))
623 return NULL;
626 if (font != NULL) {
627 if (!wsetfont(font)) {
628 PyErr_SetString(StdwinError, "font not found");
629 return NULL;
632 if (size != 0)
633 wsetsize(size);
634 switch (style) {
635 case 'b':
636 wsetbold();
637 break;
638 case 'i':
639 wsetitalic();
640 break;
641 case 'o':
642 wsetbolditalic();
643 break;
644 case 'u':
645 wsetunderline();
646 break;
647 case 'p':
648 wsetplain();
649 break;
651 Py_INCREF(Py_None);
652 return Py_None;
655 static PyObject *
656 drawing_getbgcolor(self, args)
657 PyObject *self;
658 PyObject *args;
660 if (!PyArg_NoArgs(args))
661 return NULL;
662 return PyInt_FromLong((long)wgetbgcolor());
665 static PyObject *
666 drawing_getfgcolor(self, args)
667 PyObject *self;
668 PyObject *args;
670 if (!PyArg_NoArgs(args))
671 return NULL;
672 return PyInt_FromLong((long)wgetfgcolor());
675 static PyObject *
676 drawing_setbgcolor(self, args)
677 PyObject *self;
678 PyObject *args;
680 long color;
681 if (!getlongarg(args, &color))
682 return NULL;
683 wsetbgcolor((COLOR)color);
684 Py_INCREF(Py_None);
685 return Py_None;
688 static PyObject *
689 drawing_setfgcolor(self, args)
690 PyObject *self;
691 PyObject *args;
693 long color;
694 if (!getlongarg(args, &color))
695 return NULL;
696 wsetfgcolor((COLOR)color);
697 Py_INCREF(Py_None);
698 return Py_None;
701 #ifdef HAVE_BITMAPS
703 static PyObject *
704 drawing_bitmap(self, args)
705 PyObject *self;
706 PyObject *args;
708 int h, v;
709 PyObject *bp;
710 PyObject *mask = NULL;
711 if (!PyArg_Parse(args, "((ii)O)", &h, &v, &bp)) {
712 PyErr_Clear();
713 if (!PyArg_Parse(args, "((ii)OO)", &h, &v, &bp, &mask))
714 return NULL;
715 if (mask == Py_None)
716 mask = NULL;
717 else if (!is_bitmapobject(mask)) {
718 PyErr_BadArgument();
719 return NULL;
722 if (!is_bitmapobject(bp)) {
723 PyErr_BadArgument();
724 return NULL;
726 if (((bitmapobject *)bp)->b_bitmap == NULL ||
727 mask != NULL && ((bitmapobject *)mask)->b_bitmap == NULL) {
728 PyErr_SetString(StdwinError, "bitmap object already close");
729 return NULL;
731 if (mask == NULL)
732 wdrawbitmap(h, v, ((bitmapobject *)bp)->b_bitmap, ALLBITS);
733 else
734 wdrawbitmap(h, v,
735 ((bitmapobject *)bp)->b_bitmap,
736 ((bitmapobject *)bp)->b_bitmap);
737 Py_INCREF(Py_None);
738 return Py_None;
741 #endif /* HAVE_BITMAPS */
743 static PyMethodDef drawing_methods[] = {
744 #ifdef HAVE_BITMAPS
745 {"bitmap", (PyCFunction)drawing_bitmap},
746 #endif
747 {"box", (PyCFunction)drawing_box},
748 {"circle", (PyCFunction)drawing_circle},
749 {"cliprect", (PyCFunction)drawing_cliprect},
750 {"close", (PyCFunction)drawing_close},
751 {"elarc", (PyCFunction)drawing_elarc},
752 {"enddrawing", (PyCFunction)drawing_close},
753 {"erase", (PyCFunction)drawing_erase},
754 {"fillcircle", (PyCFunction)drawing_fillcircle},
755 {"fillelarc", (PyCFunction)drawing_fillelarc},
756 {"fillpoly", (PyCFunction)drawing_fillpoly},
757 {"invert", (PyCFunction)drawing_invert},
758 {"line", (PyCFunction)drawing_line},
759 {"noclip", (PyCFunction)drawing_noclip},
760 {"paint", (PyCFunction)drawing_paint},
761 {"poly", (PyCFunction)drawing_poly},
762 {"shade", (PyCFunction)drawing_shade},
763 {"text", (PyCFunction)drawing_text},
764 {"xorcircle", (PyCFunction)drawing_xorcircle},
765 {"xorelarc", (PyCFunction)drawing_xorelarc},
766 {"xorline", (PyCFunction)drawing_xorline},
767 {"xorpoly", (PyCFunction)drawing_xorpoly},
769 /* Text measuring methods: */
770 {"baseline", (PyCFunction)drawing_baseline},
771 {"lineheight", (PyCFunction)drawing_lineheight},
772 {"textbreak", (PyCFunction)drawing_textbreak},
773 {"textwidth", (PyCFunction)drawing_textwidth},
775 /* Font setting methods: */
776 {"setfont", (PyCFunction)drawing_setfont},
778 /* Color methods: */
779 {"getbgcolor", (PyCFunction)drawing_getbgcolor},
780 {"getfgcolor", (PyCFunction)drawing_getfgcolor},
781 {"setbgcolor", (PyCFunction)drawing_setbgcolor},
782 {"setfgcolor", (PyCFunction)drawing_setfgcolor},
784 {NULL, NULL} /* sentinel */
787 static PyObject *
788 drawing_getattr(dp, name)
789 drawingobject *dp;
790 char *name;
792 if (dp->d_ref == NULL) {
793 PyErr_SetString(StdwinError, "drawing object already closed");
794 return NULL;
796 return Py_FindMethod(drawing_methods, (PyObject *)dp, name);
799 PyTypeObject Drawingtype = {
800 PyObject_HEAD_INIT(&PyType_Type)
801 0, /*ob_size*/
802 "drawing", /*tp_name*/
803 sizeof(drawingobject), /*tp_size*/
804 0, /*tp_itemsize*/
805 /* methods */
806 (destructor)drawing_dealloc, /*tp_dealloc*/
807 0, /*tp_print*/
808 (getattrfunc)drawing_getattr, /*tp_getattr*/
809 0, /*tp_setattr*/
810 0, /*tp_compare*/
811 0, /*tp_repr*/
815 /* Text(edit) objects */
817 typedef struct {
818 PyObject_HEAD
819 TEXTEDIT *t_text;
820 windowobject *t_ref;
821 PyObject *t_attr; /* Attributes dictionary */
822 } textobject;
824 staticforward PyTypeObject Texttype;
826 static textobject *
827 newtextobject(wp, left, top, right, bottom)
828 windowobject *wp;
829 int left, top, right, bottom;
831 textobject *tp;
832 tp = PyObject_NEW(textobject, &Texttype);
833 if (tp == NULL)
834 return NULL;
835 tp->t_attr = NULL;
836 Py_INCREF(wp);
837 tp->t_ref = wp;
838 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
839 if (tp->t_text == NULL) {
840 Py_DECREF(tp);
841 return (textobject *) PyErr_NoMemory();
843 return tp;
846 /* Text(edit) methods */
848 static void
849 text_dealloc(tp)
850 textobject *tp;
852 if (tp->t_text != NULL)
853 tefree(tp->t_text);
854 Py_XDECREF(tp->t_attr);
855 Py_XDECREF(tp->t_ref);
856 PyMem_DEL(tp);
859 static PyObject *
860 text_close(tp, args)
861 textobject *tp;
862 PyObject *args;
864 if (tp->t_text != NULL) {
865 tefree(tp->t_text);
866 tp->t_text = NULL;
868 if (tp->t_attr != NULL) {
869 Py_DECREF(tp->t_attr);
870 tp->t_attr = NULL;
872 if (tp->t_ref != NULL) {
873 Py_DECREF(tp->t_ref);
874 tp->t_ref = NULL;
876 Py_INCREF(Py_None);
877 return Py_None;
880 static PyObject *
881 text_arrow(self, args)
882 textobject *self;
883 PyObject *args;
885 int code;
886 if (!getintarg(args, &code))
887 return NULL;
888 tearrow(self->t_text, code);
889 Py_INCREF(Py_None);
890 return Py_None;
893 static PyObject *
894 text_draw(self, args)
895 textobject *self;
896 PyObject *args;
898 register TEXTEDIT *tp = self->t_text;
899 int a[4];
900 int left, top, right, bottom;
901 if (!getrectarg(args, a))
902 return NULL;
903 if (Drawing != NULL) {
904 PyErr_SetString(StdwinError, "already drawing");
905 return NULL;
907 /* Clip to text area and ignore if area is empty */
908 left = tegetleft(tp);
909 top = tegettop(tp);
910 right = tegetright(tp);
911 bottom = tegetbottom(tp);
912 if (a[0] < left) a[0] = left;
913 if (a[1] < top) a[1] = top;
914 if (a[2] > right) a[2] = right;
915 if (a[3] > bottom) a[3] = bottom;
916 if (a[0] < a[2] && a[1] < a[3]) {
917 wbegindrawing(self->t_ref->w_win);
918 tedrawnew(tp, a[0], a[1], a[2], a[3]);
919 wenddrawing(self->t_ref->w_win);
921 Py_INCREF(Py_None);
922 return Py_None;
925 static PyObject *
926 text_event(self, args)
927 textobject *self;
928 PyObject *args;
930 register TEXTEDIT *tp = self->t_text;
931 EVENT e;
932 if (!geteventarg(args, &e))
933 return NULL;
934 if (e.type == WE_MOUSE_DOWN) {
935 /* Cheat at the margins */
936 int width, height;
937 wgetdocsize(e.window, &width, &height);
938 if (e.u.where.h < 0 && tegetleft(tp) == 0)
939 e.u.where.h = 0;
940 else if (e.u.where.h > width && tegetright(tp) == width)
941 e.u.where.h = width;
942 if (e.u.where.v < 0 && tegettop(tp) == 0)
943 e.u.where.v = 0;
944 else if (e.u.where.v > height && tegetright(tp) == height)
945 e.u.where.v = height;
947 return PyInt_FromLong((long) teevent(tp, &e));
950 static PyObject *
951 text_getfocus(self, args)
952 textobject *self;
953 PyObject *args;
955 if (!PyArg_NoArgs(args))
956 return NULL;
957 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
960 static PyObject *
961 text_getfocustext(self, args)
962 textobject *self;
963 PyObject *args;
965 int f1, f2;
966 char *text;
967 if (!PyArg_NoArgs(args))
968 return NULL;
969 f1 = tegetfoc1(self->t_text);
970 f2 = tegetfoc2(self->t_text);
971 text = tegettext(self->t_text);
972 return PyString_FromStringAndSize(text + f1, f2-f1);
975 static PyObject *
976 text_getrect(self, args)
977 textobject *self;
978 PyObject *args;
980 if (!PyArg_NoArgs(args))
981 return NULL;
982 return makerect(tegetleft(self->t_text),
983 tegettop(self->t_text),
984 tegetright(self->t_text),
985 tegetbottom(self->t_text));
988 static PyObject *
989 text_gettext(self, args)
990 textobject *self;
991 PyObject *args;
993 if (!PyArg_NoArgs(args))
994 return NULL;
995 return PyString_FromStringAndSize(tegettext(self->t_text),
996 tegetlen(self->t_text));
999 static PyObject *
1000 text_move(self, args)
1001 textobject *self;
1002 PyObject *args;
1004 int a[4];
1005 if (!getrectarg(args, a))
1006 return NULL;
1007 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
1008 Py_INCREF(Py_None);
1009 return Py_None;
1012 static PyObject *
1013 text_replace(self, args)
1014 textobject *self;
1015 PyObject *args;
1017 char *text;
1018 if (!getstrarg(args, &text))
1019 return NULL;
1020 tereplace(self->t_text, text);
1021 Py_INCREF(Py_None);
1022 return Py_None;
1025 static PyObject *
1026 text_setactive(self, args)
1027 textobject *self;
1028 PyObject *args;
1030 int flag;
1031 if (!getintarg(args, &flag))
1032 return NULL;
1033 tesetactive(self->t_text, flag);
1034 Py_INCREF(Py_None);
1035 return Py_None;
1038 static PyObject *
1039 text_setfocus(self, args)
1040 textobject *self;
1041 PyObject *args;
1043 int a[2];
1044 if (!getpointarg(args, a))
1045 return NULL;
1046 tesetfocus(self->t_text, a[0], a[1]);
1047 Py_INCREF(Py_None);
1048 return Py_None;
1051 static PyObject *
1052 text_settext(self, args)
1053 textobject *self;
1054 PyObject *args;
1056 char *text;
1057 char *buf;
1058 int size;
1059 if (!PyArg_Parse(args, "t#", &text, &size))
1060 return NULL;
1061 if ((buf = PyMem_NEW(char, size)) == NULL) {
1062 return PyErr_NoMemory();
1064 memcpy(buf, text, size);
1065 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1066 Py_INCREF(Py_None);
1067 return Py_None;
1070 static PyObject *
1071 text_setview(self, args)
1072 textobject *self;
1073 PyObject *args;
1075 int a[4];
1076 if (args == Py_None)
1077 tenoview(self->t_text);
1078 else {
1079 if (!getrectarg(args, a))
1080 return NULL;
1081 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1083 Py_INCREF(Py_None);
1084 return Py_None;
1087 static PyMethodDef text_methods[] = {
1088 {"arrow", (PyCFunction)text_arrow},
1089 {"close", (PyCFunction)text_close},
1090 {"draw", (PyCFunction)text_draw},
1091 {"event", (PyCFunction)text_event},
1092 {"getfocus", (PyCFunction)text_getfocus},
1093 {"getfocustext",(PyCFunction)text_getfocustext},
1094 {"getrect", (PyCFunction)text_getrect},
1095 {"gettext", (PyCFunction)text_gettext},
1096 {"move", (PyCFunction)text_move},
1097 {"replace", (PyCFunction)text_replace},
1098 {"setactive", (PyCFunction)text_setactive},
1099 {"setfocus", (PyCFunction)text_setfocus},
1100 {"settext", (PyCFunction)text_settext},
1101 {"setview", (PyCFunction)text_setview},
1102 {NULL, NULL} /* sentinel */
1105 static PyObject *
1106 text_getattr(tp, name)
1107 textobject *tp;
1108 char *name;
1110 PyObject *v = NULL;
1111 if (tp->t_ref == NULL) {
1112 PyErr_SetString(StdwinError, "text object already closed");
1113 return NULL;
1115 if (strcmp(name, "__dict__") == 0) {
1116 v = tp->t_attr;
1117 if (v == NULL)
1118 v = Py_None;
1120 else if (tp->t_attr != NULL) {
1121 v = PyDict_GetItemString(tp->t_attr, name);
1123 if (v != NULL) {
1124 Py_INCREF(v);
1125 return v;
1127 return Py_FindMethod(text_methods, (PyObject *)tp, name);
1130 static int
1131 text_setattr(tp, name, v)
1132 textobject *tp;
1133 char *name;
1134 PyObject *v;
1136 if (tp->t_attr == NULL) {
1137 tp->t_attr = PyDict_New();
1138 if (tp->t_attr == NULL)
1139 return -1;
1141 if (v == NULL) {
1142 int rv = PyDict_DelItemString(tp->t_attr, name);
1143 if (rv < 0)
1144 PyErr_SetString(PyExc_AttributeError,
1145 "delete non-existing text object attribute");
1146 return rv;
1148 else
1149 return PyDict_SetItemString(tp->t_attr, name, v);
1152 statichere PyTypeObject Texttype = {
1153 PyObject_HEAD_INIT(&PyType_Type)
1154 0, /*ob_size*/
1155 "textedit", /*tp_name*/
1156 sizeof(textobject), /*tp_size*/
1157 0, /*tp_itemsize*/
1158 /* methods */
1159 (destructor)text_dealloc, /*tp_dealloc*/
1160 0, /*tp_print*/
1161 (getattrfunc)text_getattr, /*tp_getattr*/
1162 (setattrfunc)text_setattr, /*tp_setattr*/
1163 0, /*tp_compare*/
1164 0, /*tp_repr*/
1168 /* Menu objects */
1170 #define IDOFFSET 10 /* Menu IDs we use start here */
1171 #define MAXNMENU 200 /* Max #menus we allow */
1172 static menuobject *menulist[MAXNMENU];
1174 static menuobject *newmenuobject Py_PROTO((char *));
1175 static menuobject *
1176 newmenuobject(title)
1177 char *title;
1179 int id;
1180 MENU *menu;
1181 menuobject *mp;
1182 for (id = 0; id < MAXNMENU; id++) {
1183 if (menulist[id] == NULL)
1184 break;
1186 if (id >= MAXNMENU) {
1187 PyErr_SetString(StdwinError, "creating too many menus");
1188 return NULL;
1190 menu = wmenucreate(id + IDOFFSET, title);
1191 if (menu == NULL)
1192 return (menuobject *) PyErr_NoMemory();
1193 mp = PyObject_NEW(menuobject, &Menutype);
1194 if (mp != NULL) {
1195 mp->m_menu = menu;
1196 mp->m_id = id + IDOFFSET;
1197 mp->m_attr = NULL;
1198 menulist[id] = mp;
1200 else
1201 wmenudelete(menu);
1202 return mp;
1205 /* Menu methods */
1207 static void
1208 menu_dealloc(mp)
1209 menuobject *mp;
1212 int id = mp->m_id - IDOFFSET;
1213 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1214 menulist[id] = NULL;
1216 if (mp->m_menu != NULL)
1217 wmenudelete(mp->m_menu);
1218 Py_XDECREF(mp->m_attr);
1219 PyMem_DEL(mp);
1222 static PyObject *
1223 menu_close(mp, args)
1224 menuobject *mp;
1225 PyObject *args;
1227 int id = mp->m_id - IDOFFSET;
1228 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1229 menulist[id] = NULL;
1231 mp->m_id = -1;
1232 if (mp->m_menu != NULL)
1233 wmenudelete(mp->m_menu);
1234 mp->m_menu = NULL;
1235 Py_XDECREF(mp->m_attr);
1236 mp->m_attr = NULL;
1237 Py_INCREF(Py_None);
1238 return Py_None;
1241 static PyObject *
1242 menu_additem(self, args)
1243 menuobject *self;
1244 PyObject *args;
1246 char *text;
1247 int shortcut = -1;
1248 if (PyTuple_Check(args)) {
1249 char c;
1250 if (!PyArg_Parse(args, "(sc)", &text, &c))
1251 return NULL;
1252 shortcut = c;
1254 else if (!getstrarg(args, &text))
1255 return NULL;
1256 wmenuadditem(self->m_menu, text, shortcut);
1257 Py_INCREF(Py_None);
1258 return Py_None;
1261 static PyObject *
1262 menu_setitem(self, args)
1263 menuobject *self;
1264 PyObject *args;
1266 int index;
1267 char *text;
1268 if (!PyArg_Parse(args, "(is)", &index, &text))
1269 return NULL;
1270 wmenusetitem(self->m_menu, index, text);
1271 Py_INCREF(Py_None);
1272 return Py_None;
1275 static PyObject *
1276 menu_enable(self, args)
1277 menuobject *self;
1278 PyObject *args;
1280 int index;
1281 int flag;
1282 if (!PyArg_Parse(args, "(ii)", &index, &flag))
1283 return NULL;
1284 wmenuenable(self->m_menu, index, flag);
1285 Py_INCREF(Py_None);
1286 return Py_None;
1289 static PyObject *
1290 menu_check(self, args)
1291 menuobject *self;
1292 PyObject *args;
1294 int index;
1295 int flag;
1296 if (!PyArg_Parse(args, "(ii)", &index, &flag))
1297 return NULL;
1298 wmenucheck(self->m_menu, index, flag);
1299 Py_INCREF(Py_None);
1300 return Py_None;
1303 static PyMethodDef menu_methods[] = {
1304 {"additem", (PyCFunction)menu_additem},
1305 {"setitem", (PyCFunction)menu_setitem},
1306 {"enable", (PyCFunction)menu_enable},
1307 {"check", (PyCFunction)menu_check},
1308 {"close", (PyCFunction)menu_close},
1309 {NULL, NULL} /* sentinel */
1312 static PyObject *
1313 menu_getattr(mp, name)
1314 menuobject *mp;
1315 char *name;
1317 PyObject *v = NULL;
1318 if (mp->m_menu == NULL) {
1319 PyErr_SetString(StdwinError, "menu object already closed");
1320 return NULL;
1322 if (strcmp(name, "__dict__") == 0) {
1323 v = mp->m_attr;
1324 if (v == NULL)
1325 v = Py_None;
1327 else if (mp->m_attr != NULL) {
1328 v = PyDict_GetItemString(mp->m_attr, name);
1330 if (v != NULL) {
1331 Py_INCREF(v);
1332 return v;
1334 return Py_FindMethod(menu_methods, (PyObject *)mp, name);
1337 static int
1338 menu_setattr(mp, name, v)
1339 menuobject *mp;
1340 char *name;
1341 PyObject *v;
1343 if (mp->m_attr == NULL) {
1344 mp->m_attr = PyDict_New();
1345 if (mp->m_attr == NULL)
1346 return -1;
1348 if (v == NULL) {
1349 int rv = PyDict_DelItemString(mp->m_attr, name);
1350 if (rv < 0)
1351 PyErr_SetString(PyExc_AttributeError,
1352 "delete non-existing menu object attribute");
1353 return rv;
1355 else
1356 return PyDict_SetItemString(mp->m_attr, name, v);
1359 statichere PyTypeObject Menutype = {
1360 PyObject_HEAD_INIT(&PyType_Type)
1361 0, /*ob_size*/
1362 "menu", /*tp_name*/
1363 sizeof(menuobject), /*tp_size*/
1364 0, /*tp_itemsize*/
1365 /* methods */
1366 (destructor)menu_dealloc, /*tp_dealloc*/
1367 0, /*tp_print*/
1368 (getattrfunc)menu_getattr, /*tp_getattr*/
1369 (setattrfunc)menu_setattr, /*tp_setattr*/
1370 0, /*tp_compare*/
1371 0, /*tp_repr*/
1375 #ifdef HAVE_BITMAPS
1377 /* Bitmaps objects */
1379 static bitmapobject *newbitmapobject Py_PROTO((int, int));
1380 static bitmapobject *
1381 newbitmapobject(width, height)
1382 int width, height;
1384 BITMAP *bitmap;
1385 bitmapobject *bp;
1386 bitmap = wnewbitmap(width, height);
1387 if (bitmap == NULL)
1388 return (bitmapobject *) PyErr_NoMemory();
1389 bp = PyObject_NEW(bitmapobject, &Bitmaptype);
1390 if (bp != NULL) {
1391 bp->b_bitmap = bitmap;
1392 bp->b_attr = NULL;
1394 else
1395 wfreebitmap(bitmap);
1396 return bp;
1399 /* Bitmap methods */
1401 static void
1402 bitmap_dealloc(bp)
1403 bitmapobject *bp;
1405 if (bp->b_bitmap != NULL)
1406 wfreebitmap(bp->b_bitmap);
1407 Py_XDECREF(bp->b_attr);
1408 PyMem_DEL(bp);
1411 static PyObject *
1412 bitmap_close(bp, args)
1413 bitmapobject *bp;
1414 PyObject *args;
1416 if (bp->b_bitmap != NULL)
1417 wfreebitmap(bp->b_bitmap);
1418 bp->b_bitmap = NULL;
1419 Py_XDECREF(bp->b_attr);
1420 bp->b_attr = NULL;
1421 Py_INCREF(Py_None);
1422 return Py_None;
1425 static PyObject *
1426 bitmap_setbit(self, args)
1427 bitmapobject *self;
1428 PyObject *args;
1430 int a[3];
1431 if (!getpointintarg(args, a))
1432 return NULL;
1433 wsetbit(self->b_bitmap, a[0], a[1], a[2]);
1434 Py_INCREF(Py_None);
1435 return Py_None;
1438 static PyObject *
1439 bitmap_getbit(self, args)
1440 bitmapobject *self;
1441 PyObject *args;
1443 int a[2];
1444 if (!getpointarg(args, a))
1445 return NULL;
1446 return PyInt_FromLong((long) wgetbit(self->b_bitmap, a[0], a[1]));
1449 static PyObject *
1450 bitmap_getsize(self, args)
1451 bitmapobject *self;
1452 PyObject *args;
1454 int width, height;
1455 if (!PyArg_NoArgs(args))
1456 return NULL;
1457 wgetbitmapsize(self->b_bitmap, &width, &height);
1458 return Py_BuildValue("(ii)", width, height);
1461 static PyMethodDef bitmap_methods[] = {
1462 {"close", (PyCFunction)bitmap_close},
1463 {"getsize", (PyCFunction)bitmap_getsize},
1464 {"getbit", (PyCFunction)bitmap_getbit},
1465 {"setbit", (PyCFunction)bitmap_setbit},
1466 {NULL, NULL} /* sentinel */
1469 static PyObject *
1470 bitmap_getattr(bp, name)
1471 bitmapobject *bp;
1472 char *name;
1474 PyObject *v = NULL;
1475 if (bp->b_bitmap == NULL) {
1476 PyErr_SetString(StdwinError, "bitmap object already closed");
1477 return NULL;
1479 if (strcmp(name, "__dict__") == 0) {
1480 v = bp->b_attr;
1481 if (v == NULL)
1482 v = Py_None;
1484 else if (bp->b_attr != NULL) {
1485 v = PyDict_GetItemString(bp->b_attr, name);
1487 if (v != NULL) {
1488 Py_INCREF(v);
1489 return v;
1491 return Py_FindMethod(bitmap_methods, (PyObject *)bp, name);
1494 static int
1495 bitmap_setattr(bp, name, v)
1496 bitmapobject *bp;
1497 char *name;
1498 PyObject *v;
1500 if (bp->b_attr == NULL) {
1501 bp->b_attr = PyDict_New();
1502 if (bp->b_attr == NULL)
1503 return -1;
1505 if (v == NULL) {
1506 int rv = PyDict_DelItemString(bp->b_attr, name);
1507 if (rv < 0)
1508 PyErr_SetString(PyExc_AttributeError,
1509 "delete non-existing bitmap object attribute");
1510 return rv;
1512 else
1513 return PyDict_SetItemString(bp->b_attr, name, v);
1516 statichere PyTypeObject Bitmaptype = {
1517 PyObject_HEAD_INIT(&PyType_Type)
1518 0, /*ob_size*/
1519 "bitmap", /*tp_name*/
1520 sizeof(bitmapobject), /*tp_size*/
1521 0, /*tp_itemsize*/
1522 /* methods */
1523 (destructor)bitmap_dealloc, /*tp_dealloc*/
1524 0, /*tp_print*/
1525 (getattrfunc)bitmap_getattr, /*tp_getattr*/
1526 (setattrfunc)bitmap_setattr, /*tp_setattr*/
1527 0, /*tp_compare*/
1528 0, /*tp_repr*/
1531 #endif /* HAVE_BITMAPS */
1534 /* Windows */
1536 #define MAXNWIN 50
1537 static windowobject *windowlist[MAXNWIN];
1539 /* Window methods */
1541 static void
1542 window_dealloc(wp)
1543 windowobject *wp;
1545 if (wp->w_win != NULL) {
1546 int tag = wgettag(wp->w_win);
1547 if (tag >= 0 && tag < MAXNWIN)
1548 windowlist[tag] = NULL;
1549 else
1550 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1551 tag);
1552 wclose(wp->w_win);
1554 Py_DECREF(wp->w_title);
1555 if (wp->w_attr != NULL)
1556 Py_DECREF(wp->w_attr);
1557 free((char *)wp);
1560 static PyObject *
1561 window_close(wp, args)
1562 windowobject *wp;
1563 PyObject *args;
1565 if (wp->w_win != NULL) {
1566 int tag = wgettag(wp->w_win);
1567 if (tag >= 0 && tag < MAXNWIN)
1568 windowlist[tag] = NULL;
1569 wclose(wp->w_win);
1570 wp->w_win = NULL;
1572 Py_INCREF(Py_None);
1573 return Py_None;
1576 static PyObject *
1577 window_begindrawing(wp, args)
1578 windowobject *wp;
1579 PyObject *args;
1581 drawingobject *dp;
1582 if (!PyArg_NoArgs(args))
1583 return NULL;
1584 if (Drawing != NULL) {
1585 PyErr_SetString(StdwinError, "already drawing");
1586 return NULL;
1588 dp = PyObject_NEW(drawingobject, &Drawingtype);
1589 if (dp == NULL)
1590 return NULL;
1591 Drawing = dp;
1592 Py_INCREF(wp);
1593 dp->d_ref = wp;
1594 wbegindrawing(wp->w_win);
1595 return (PyObject *)dp;
1598 static PyObject *
1599 window_change(wp, args)
1600 windowobject *wp;
1601 PyObject *args;
1603 int a[4];
1604 if (!getrectarg(args, a))
1605 return NULL;
1606 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1607 Py_INCREF(Py_None);
1608 return Py_None;
1611 static PyObject *
1612 window_gettitle(wp, args)
1613 windowobject *wp;
1614 PyObject *args;
1616 if (!PyArg_NoArgs(args))
1617 return NULL;
1618 Py_INCREF(wp->w_title);
1619 return wp->w_title;
1622 static PyObject *
1623 window_getwinpos(wp, args)
1624 windowobject *wp;
1625 PyObject *args;
1627 int h, v;
1628 if (!PyArg_NoArgs(args))
1629 return NULL;
1630 wgetwinpos(wp->w_win, &h, &v);
1631 return makepoint(h, v);
1634 static PyObject *
1635 window_getwinsize(wp, args)
1636 windowobject *wp;
1637 PyObject *args;
1639 int width, height;
1640 if (!PyArg_NoArgs(args))
1641 return NULL;
1642 wgetwinsize(wp->w_win, &width, &height);
1643 return makepoint(width, height);
1646 static PyObject *
1647 window_setwinpos(wp, args)
1648 windowobject *wp;
1649 PyObject *args;
1651 int a[2];
1652 if (!getpointarg(args, a))
1653 return NULL;
1654 wsetwinpos(wp->w_win, a[0], a[1]);
1655 Py_INCREF(Py_None);
1656 return Py_None;
1659 static PyObject *
1660 window_setwinsize(wp, args)
1661 windowobject *wp;
1662 PyObject *args;
1664 int a[2];
1665 if (!getpointarg(args, a))
1666 return NULL;
1667 wsetwinsize(wp->w_win, a[0], a[1]);
1668 Py_INCREF(Py_None);
1669 return Py_None;
1672 static PyObject *
1673 window_getdocsize(wp, args)
1674 windowobject *wp;
1675 PyObject *args;
1677 int width, height;
1678 if (!PyArg_NoArgs(args))
1679 return NULL;
1680 wgetdocsize(wp->w_win, &width, &height);
1681 return makepoint(width, height);
1684 static PyObject *
1685 window_getorigin(wp, args)
1686 windowobject *wp;
1687 PyObject *args;
1689 int width, height;
1690 if (!PyArg_NoArgs(args))
1691 return NULL;
1692 wgetorigin(wp->w_win, &width, &height);
1693 return makepoint(width, height);
1696 static PyObject *
1697 window_scroll(wp, args)
1698 windowobject *wp;
1699 PyObject *args;
1701 int a[6];
1702 if (!getrectpointarg(args, a))
1703 return NULL;
1704 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1705 Py_INCREF(Py_None);
1706 return Py_None;
1709 static PyObject *
1710 window_setdocsize(wp, args)
1711 windowobject *wp;
1712 PyObject *args;
1714 int a[2];
1715 if (!getpointarg(args, a))
1716 return NULL;
1717 wsetdocsize(wp->w_win, a[0], a[1]);
1718 Py_INCREF(Py_None);
1719 return Py_None;
1722 static PyObject *
1723 window_setorigin(wp, args)
1724 windowobject *wp;
1725 PyObject *args;
1727 int a[2];
1728 if (!getpointarg(args, a))
1729 return NULL;
1730 wsetorigin(wp->w_win, a[0], a[1]);
1731 Py_INCREF(Py_None);
1732 return Py_None;
1735 static PyObject *
1736 window_settitle(wp, args)
1737 windowobject *wp;
1738 PyObject *args;
1740 PyObject *title;
1741 if (!PyArg_Parse(args, "S", &title))
1742 return NULL;
1743 Py_DECREF(wp->w_title);
1744 Py_INCREF(title);
1745 wp->w_title = title;
1746 wsettitle(wp->w_win, PyString_AsString(title));
1747 Py_INCREF(Py_None);
1748 return Py_None;
1751 static PyObject *
1752 window_show(wp, args)
1753 windowobject *wp;
1754 PyObject *args;
1756 int a[4];
1757 if (!getrectarg(args, a))
1758 return NULL;
1759 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1760 Py_INCREF(Py_None);
1761 return Py_None;
1764 static PyObject *
1765 window_settimer(wp, args)
1766 windowobject *wp;
1767 PyObject *args;
1769 int a;
1770 if (!getintarg(args, &a))
1771 return NULL;
1772 wsettimer(wp->w_win, a);
1773 Py_INCREF(Py_None);
1774 return Py_None;
1777 static PyObject *
1778 window_menucreate(self, args)
1779 windowobject *self;
1780 PyObject *args;
1782 menuobject *mp;
1783 char *title;
1784 if (!getstrarg(args, &title))
1785 return NULL;
1786 wmenusetdeflocal(1);
1787 mp = newmenuobject(title);
1788 if (mp == NULL)
1789 return NULL;
1790 wmenuattach(self->w_win, mp->m_menu);
1791 return (PyObject *)mp;
1794 static PyObject *
1795 window_textcreate(self, args)
1796 windowobject *self;
1797 PyObject *args;
1799 int a[4];
1800 if (!getrectarg(args, a))
1801 return NULL;
1802 return (PyObject *)newtextobject(self, a[0], a[1], a[2], a[3]);
1805 static PyObject *
1806 window_setselection(self, args)
1807 windowobject *self;
1808 PyObject *args;
1810 int sel, size, ok;
1811 char *text;
1812 if (!PyArg_Parse(args, "(it#)", &sel, &text, &size))
1813 return NULL;
1814 ok = wsetselection(self->w_win, sel, text, size);
1815 return PyInt_FromLong(ok);
1818 static PyObject *
1819 window_setwincursor(self, args)
1820 windowobject *self;
1821 PyObject *args;
1823 char *name;
1824 CURSOR *c;
1825 if (!PyArg_Parse(args, "z", &name))
1826 return NULL;
1827 if (name == NULL)
1828 c = NULL;
1829 else {
1830 c = wfetchcursor(name);
1831 if (c == NULL) {
1832 PyErr_SetString(StdwinError, "no such cursor");
1833 return NULL;
1836 wsetwincursor(self->w_win, c);
1837 Py_INCREF(Py_None);
1838 return Py_None;
1841 static PyObject *
1842 window_setactive(self, args)
1843 windowobject *self;
1844 PyObject *args;
1846 if (!PyArg_NoArgs(args))
1847 return NULL;
1848 wsetactive(self->w_win);
1849 Py_INCREF(Py_None);
1850 return Py_None;
1853 #ifdef CWI_HACKS
1854 static PyObject *
1855 window_getxwindowid(self, args)
1856 windowobject *self;
1857 PyObject *args;
1859 long wid = wgetxwindowid(self->w_win);
1860 return PyInt_FromLong(wid);
1862 #endif
1864 static PyMethodDef window_methods[] = {
1865 {"begindrawing",(PyCFunction)window_begindrawing},
1866 {"change", (PyCFunction)window_change},
1867 {"close", (PyCFunction)window_close},
1868 {"getdocsize", (PyCFunction)window_getdocsize},
1869 {"getorigin", (PyCFunction)window_getorigin},
1870 {"gettitle", (PyCFunction)window_gettitle},
1871 {"getwinpos", (PyCFunction)window_getwinpos},
1872 {"getwinsize", (PyCFunction)window_getwinsize},
1873 {"menucreate", (PyCFunction)window_menucreate},
1874 {"scroll", (PyCFunction)window_scroll},
1875 {"setactive", (PyCFunction)window_setactive},
1876 {"setdocsize", (PyCFunction)window_setdocsize},
1877 {"setorigin", (PyCFunction)window_setorigin},
1878 {"setselection",(PyCFunction)window_setselection},
1879 {"settimer", (PyCFunction)window_settimer},
1880 {"settitle", (PyCFunction)window_settitle},
1881 {"setwincursor",(PyCFunction)window_setwincursor},
1882 {"setwinpos", (PyCFunction)window_setwinpos},
1883 {"setwinsize", (PyCFunction)window_setwinsize},
1884 {"show", (PyCFunction)window_show},
1885 {"textcreate", (PyCFunction)window_textcreate},
1886 #ifdef CWI_HACKS
1887 {"getxwindowid",(PyCFunction)window_getxwindowid},
1888 #endif
1889 {NULL, NULL} /* sentinel */
1892 static PyObject *
1893 window_getattr(wp, name)
1894 windowobject *wp;
1895 char *name;
1897 PyObject *v = NULL;
1898 if (wp->w_win == NULL) {
1899 PyErr_SetString(StdwinError, "window already closed");
1900 return NULL;
1902 if (strcmp(name, "__dict__") == 0) {
1903 v = wp->w_attr;
1904 if (v == NULL)
1905 v = Py_None;
1907 else if (wp->w_attr != NULL) {
1908 v = PyDict_GetItemString(wp->w_attr, name);
1910 if (v != NULL) {
1911 Py_INCREF(v);
1912 return v;
1914 return Py_FindMethod(window_methods, (PyObject *)wp, name);
1917 static int
1918 window_setattr(wp, name, v)
1919 windowobject *wp;
1920 char *name;
1921 PyObject *v;
1923 if (wp->w_attr == NULL) {
1924 wp->w_attr = PyDict_New();
1925 if (wp->w_attr == NULL)
1926 return -1;
1928 if (v == NULL) {
1929 int rv = PyDict_DelItemString(wp->w_attr, name);
1930 if (rv < 0)
1931 PyErr_SetString(PyExc_AttributeError,
1932 "delete non-existing menu object attribute");
1933 return rv;
1935 else
1936 return PyDict_SetItemString(wp->w_attr, name, v);
1939 statichere PyTypeObject Windowtype = {
1940 PyObject_HEAD_INIT(&PyType_Type)
1941 0, /*ob_size*/
1942 "window", /*tp_name*/
1943 sizeof(windowobject), /*tp_size*/
1944 0, /*tp_itemsize*/
1945 /* methods */
1946 (destructor)window_dealloc, /*tp_dealloc*/
1947 0, /*tp_print*/
1948 (getattrfunc)window_getattr, /*tp_getattr*/
1949 (setattrfunc)window_setattr, /*tp_setattr*/
1950 0, /*tp_compare*/
1951 0, /*tp_repr*/
1954 /* Stdwin methods */
1956 static PyObject *
1957 stdwin_done(sw, args)
1958 PyObject *sw;
1959 PyObject *args;
1961 if (!PyArg_NoArgs(args))
1962 return NULL;
1963 wdone();
1964 /* XXX There is no protection against continued use of
1965 XXX stdwin functions or objects after this call is made.
1966 XXX Use at own risk */
1967 Py_INCREF(Py_None);
1968 return Py_None;
1971 static PyObject *
1972 stdwin_open(sw, args)
1973 PyObject *sw;
1974 PyObject *args;
1976 int tag;
1977 PyObject *title;
1978 windowobject *wp;
1979 if (!PyArg_Parse(args, "S", &title))
1980 return NULL;
1981 for (tag = 0; tag < MAXNWIN; tag++) {
1982 if (windowlist[tag] == NULL)
1983 break;
1985 if (tag >= MAXNWIN) {
1986 PyErr_SetString(StdwinError, "creating too many windows");
1987 return NULL;
1989 wp = PyObject_NEW(windowobject, &Windowtype);
1990 if (wp == NULL)
1991 return NULL;
1992 Py_INCREF(title);
1993 wp->w_title = title;
1994 wp->w_win = wopen(PyString_AsString(title), (void (*)()) NULL);
1995 wp->w_attr = NULL;
1996 if (wp->w_win == NULL) {
1997 Py_DECREF(wp);
1998 return NULL;
2000 windowlist[tag] = wp;
2001 wsettag(wp->w_win, tag);
2002 return (PyObject *)wp;
2005 static PyObject *
2006 window2object(win)
2007 WINDOW *win;
2009 PyObject *w;
2010 if (win == NULL)
2011 w = Py_None;
2012 else {
2013 int tag = wgettag(win);
2014 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
2015 windowlist[tag]->w_win != win)
2016 w = Py_None;
2017 else
2018 w = (PyObject *)windowlist[tag];
2020 Py_INCREF(w);
2021 return w;
2024 static PyObject *
2025 stdwin_get_poll_event(poll, args)
2026 int poll;
2027 PyObject *args;
2029 EVENT e;
2030 PyObject *u, *v, *w;
2031 if (!PyArg_NoArgs(args))
2032 return NULL;
2033 if (Drawing != NULL) {
2034 PyErr_SetString(StdwinError,
2035 "cannot getevent() while drawing");
2036 return NULL;
2038 again:
2039 BGN_STDWIN
2040 if (poll) {
2041 if (!wpollevent(&e)) {
2042 RET_STDWIN
2043 Py_INCREF(Py_None);
2044 return Py_None;
2047 else
2048 wgetevent(&e);
2049 END_STDWIN
2050 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
2051 /* Turn keyboard interrupts into exceptions */
2052 PyErr_SetNone(PyExc_KeyboardInterrupt);
2053 return NULL;
2055 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
2056 /* Turn WC_CLOSE commands into WE_CLOSE events */
2057 e.type = WE_CLOSE;
2059 v = window2object(e.window);
2060 switch (e.type) {
2061 case WE_CHAR:
2063 char c[1];
2064 c[0] = e.u.character;
2065 w = PyString_FromStringAndSize(c, 1);
2067 break;
2068 case WE_COMMAND:
2069 w = PyInt_FromLong((long)e.u.command);
2070 break;
2071 case WE_DRAW:
2072 w = makerect(e.u.area.left, e.u.area.top,
2073 e.u.area.right, e.u.area.bottom);
2074 break;
2075 case WE_MOUSE_DOWN:
2076 case WE_MOUSE_MOVE:
2077 case WE_MOUSE_UP:
2078 w = Py_BuildValue("((ii)iii)",
2079 e.u.where.h, e.u.where.v,
2080 e.u.where.clicks,
2081 e.u.where.button,
2082 e.u.where.mask);
2083 break;
2084 case WE_MENU:
2085 if (e.u.m.id >= IDOFFSET &&
2086 e.u.m.id < IDOFFSET+MAXNMENU &&
2087 menulist[e.u.m.id - IDOFFSET] != NULL)
2089 w = Py_BuildValue("(Oi)",
2090 menulist[e.u.m.id - IDOFFSET],
2091 e.u.m.item);
2093 else {
2094 /* Ghost menu event.
2095 Can occur only on the Mac if another part
2096 of the aplication has installed a menu;
2097 like the THINK C console library. */
2098 Py_DECREF(v);
2099 goto again;
2101 break;
2102 case WE_KEY:
2103 w = Py_BuildValue("(ii)", e.u.key.code, e.u.key.mask);
2104 break;
2105 case WE_LOST_SEL:
2106 w = PyInt_FromLong((long)e.u.sel);
2107 break;
2108 default:
2109 w = Py_None;
2110 Py_INCREF(w);
2111 break;
2113 if (w == NULL) {
2114 Py_DECREF(v);
2115 return NULL;
2117 u = Py_BuildValue("(iOO)", e.type, v, w);
2118 Py_XDECREF(v);
2119 Py_XDECREF(w);
2120 return u;
2123 static PyObject *
2124 stdwin_getevent(sw, args)
2125 PyObject *sw;
2126 PyObject *args;
2128 return stdwin_get_poll_event(0, args);
2131 static PyObject *
2132 stdwin_pollevent(sw, args)
2133 PyObject *sw;
2134 PyObject *args;
2136 return stdwin_get_poll_event(1, args);
2139 static PyObject *
2140 stdwin_setdefwinpos(sw, args)
2141 PyObject *sw;
2142 PyObject *args;
2144 int a[2];
2145 if (!getpointarg(args, a))
2146 return NULL;
2147 wsetdefwinpos(a[0], a[1]);
2148 Py_INCREF(Py_None);
2149 return Py_None;
2152 static PyObject *
2153 stdwin_setdefwinsize(sw, args)
2154 PyObject *sw;
2155 PyObject *args;
2157 int a[2];
2158 if (!getpointarg(args, a))
2159 return NULL;
2160 wsetdefwinsize(a[0], a[1]);
2161 Py_INCREF(Py_None);
2162 return Py_None;
2165 static PyObject *
2166 stdwin_setdefscrollbars(sw, args)
2167 PyObject *sw;
2168 PyObject *args;
2170 int a[2];
2171 if (!getpointarg(args, a))
2172 return NULL;
2173 wsetdefscrollbars(a[0], a[1]);
2174 Py_INCREF(Py_None);
2175 return Py_None;
2178 static PyObject *
2179 stdwin_getdefwinpos(self, args)
2180 PyObject *self;
2181 PyObject *args;
2183 int h, v;
2184 if (!PyArg_NoArgs(args))
2185 return NULL;
2186 wgetdefwinpos(&h, &v);
2187 return makepoint(h, v);
2190 static PyObject *
2191 stdwin_getdefwinsize(self, args)
2192 PyObject *self;
2193 PyObject *args;
2195 int width, height;
2196 if (!PyArg_NoArgs(args))
2197 return NULL;
2198 wgetdefwinsize(&width, &height);
2199 return makepoint(width, height);
2202 static PyObject *
2203 stdwin_getdefscrollbars(self, args)
2204 PyObject *self;
2205 PyObject *args;
2207 int h, v;
2208 if (!PyArg_NoArgs(args))
2209 return NULL;
2210 wgetdefscrollbars(&h, &v);
2211 return makepoint(h, v);
2214 static PyObject *
2215 stdwin_menucreate(self, args)
2216 PyObject *self;
2217 PyObject *args;
2219 char *title;
2220 if (!getstrarg(args, &title))
2221 return NULL;
2222 wmenusetdeflocal(0);
2223 return (PyObject *)newmenuobject(title);
2226 static PyObject *
2227 stdwin_askfile(self, args)
2228 PyObject *self;
2229 PyObject *args;
2231 char *prompt, *dflt;
2232 int new, ret;
2233 char buf[256];
2234 if (!PyArg_Parse(args, "(ssi)", &prompt, &dflt, &new))
2235 return NULL;
2236 strncpy(buf, dflt, sizeof buf);
2237 buf[sizeof buf - 1] = '\0';
2238 BGN_STDWIN
2239 ret = waskfile(prompt, buf, sizeof buf, new);
2240 END_STDWIN
2241 if (!ret) {
2242 PyErr_SetNone(PyExc_KeyboardInterrupt);
2243 return NULL;
2245 return PyString_FromString(buf);
2248 static PyObject *
2249 stdwin_askync(self, args)
2250 PyObject *self;
2251 PyObject *args;
2253 char *prompt;
2254 int new, ret;
2255 if (!PyArg_Parse(args, "(si)", &prompt, &new))
2256 return NULL;
2257 BGN_STDWIN
2258 ret = waskync(prompt, new);
2259 END_STDWIN
2260 if (ret < 0) {
2261 PyErr_SetNone(PyExc_KeyboardInterrupt);
2262 return NULL;
2264 return PyInt_FromLong((long)ret);
2267 static PyObject *
2268 stdwin_askstr(self, args)
2269 PyObject *self;
2270 PyObject *args;
2272 char *prompt, *dflt;
2273 int ret;
2274 char buf[256];
2275 if (!PyArg_Parse(args, "(ss)", &prompt, &dflt))
2276 return NULL;
2277 strncpy(buf, dflt, sizeof buf);
2278 buf[sizeof buf - 1] = '\0';
2279 BGN_STDWIN
2280 ret = waskstr(prompt, buf, sizeof buf);
2281 END_STDWIN
2282 if (!ret) {
2283 PyErr_SetNone(PyExc_KeyboardInterrupt);
2284 return NULL;
2286 return PyString_FromString(buf);
2289 static PyObject *
2290 stdwin_message(self, args)
2291 PyObject *self;
2292 PyObject *args;
2294 char *msg;
2295 if (!getstrarg(args, &msg))
2296 return NULL;
2297 BGN_STDWIN
2298 wmessage(msg);
2299 END_STDWIN
2300 Py_INCREF(Py_None);
2301 return Py_None;
2304 static PyObject *
2305 stdwin_fleep(self, args)
2306 PyObject *self;
2307 PyObject *args;
2309 if (!PyArg_NoArgs(args))
2310 return NULL;
2311 wfleep();
2312 Py_INCREF(Py_None);
2313 return Py_None;
2316 static PyObject *
2317 stdwin_setcutbuffer(self, args)
2318 PyObject *self;
2319 PyObject *args;
2321 int i, size;
2322 char *str;
2323 if (!PyArg_Parse(args, "(it#)", &i, &str, &size))
2324 return NULL;
2325 wsetcutbuffer(i, str, size);
2326 Py_INCREF(Py_None);
2327 return Py_None;
2330 static PyObject *
2331 stdwin_getactive(self, args)
2332 PyObject *self;
2333 PyObject *args;
2335 return window2object(wgetactive());
2338 static PyObject *
2339 stdwin_getcutbuffer(self, args)
2340 PyObject *self;
2341 PyObject *args;
2343 int i;
2344 char *str;
2345 int len;
2346 if (!getintarg(args, &i))
2347 return NULL;
2348 str = wgetcutbuffer(i, &len);
2349 if (str == NULL) {
2350 str = "";
2351 len = 0;
2353 return PyString_FromStringAndSize(str, len);
2356 static PyObject *
2357 stdwin_rotatecutbuffers(self, args)
2358 PyObject *self;
2359 PyObject *args;
2361 int i;
2362 if (!getintarg(args, &i))
2363 return NULL;
2364 wrotatecutbuffers(i);
2365 Py_INCREF(Py_None);
2366 return Py_None;
2369 static PyObject *
2370 stdwin_getselection(self, args)
2371 PyObject *self;
2372 PyObject *args;
2374 int sel;
2375 char *data;
2376 int len;
2377 if (!getintarg(args, &sel))
2378 return NULL;
2379 data = wgetselection(sel, &len);
2380 if (data == NULL) {
2381 data = "";
2382 len = 0;
2384 return PyString_FromStringAndSize(data, len);
2387 static PyObject *
2388 stdwin_resetselection(self, args)
2389 PyObject *self;
2390 PyObject *args;
2392 int sel;
2393 if (!getintarg(args, &sel))
2394 return NULL;
2395 wresetselection(sel);
2396 Py_INCREF(Py_None);
2397 return Py_None;
2400 static PyObject *
2401 stdwin_fetchcolor(self, args)
2402 PyObject *self;
2403 PyObject *args;
2405 char *colorname;
2406 COLOR color;
2407 if (!getstrarg(args, &colorname))
2408 return NULL;
2409 color = wfetchcolor(colorname);
2410 #ifdef BADCOLOR
2411 if (color == BADCOLOR) {
2412 PyErr_SetString(StdwinError, "color name not found");
2413 return NULL;
2415 #endif
2416 return PyInt_FromLong((long)color);
2419 static PyObject *
2420 stdwin_getscrsize(self, args)
2421 PyObject *self;
2422 PyObject *args;
2424 int width, height;
2425 if (!PyArg_NoArgs(args))
2426 return NULL;
2427 wgetscrsize(&width, &height);
2428 return makepoint(width, height);
2431 static PyObject *
2432 stdwin_getscrmm(self, args)
2433 PyObject *self;
2434 PyObject *args;
2436 int width, height;
2437 if (!PyArg_NoArgs(args))
2438 return NULL;
2439 wgetscrmm(&width, &height);
2440 return makepoint(width, height);
2443 #ifdef unix
2444 static PyObject *
2445 stdwin_connectionnumber(self, args)
2446 PyObject *self;
2447 PyObject *args;
2449 if (!PyArg_NoArgs(args))
2450 return NULL;
2451 return PyInt_FromLong((long) wconnectionnumber());
2453 #endif
2455 static PyObject *
2456 stdwin_listfontnames(self, args)
2457 PyObject *self;
2458 PyObject *args;
2460 char *pattern;
2461 char **fontnames;
2462 int count;
2463 PyObject *list;
2464 if (!PyArg_Parse(args, "z", &pattern))
2465 return NULL;
2466 fontnames = wlistfontnames(pattern, &count);
2467 list = PyList_New(count);
2468 if (list != NULL) {
2469 int i;
2470 for (i = 0; i < count; i++) {
2471 PyObject *v = PyString_FromString(fontnames[i]);
2472 if (v == NULL) {
2473 Py_DECREF(list);
2474 list = NULL;
2475 break;
2477 PyList_SetItem(list, i, v);
2480 return list;
2483 #ifdef HAVE_BITMAPS
2484 static PyObject *
2485 stdwin_newbitmap(self, args)
2486 PyObject *self;
2487 PyObject *args;
2489 int width, height;
2490 bitmapobject *bp;
2491 if (!PyArg_Parse(args, "(ii)", &width, &height))
2492 return NULL;
2493 return (PyObject *)newbitmapobject(width, height);
2495 #endif
2497 static PyMethodDef stdwin_methods[] = {
2498 {"askfile", stdwin_askfile},
2499 {"askstr", stdwin_askstr},
2500 {"askync", stdwin_askync},
2501 {"done", stdwin_done},
2502 {"fetchcolor", stdwin_fetchcolor},
2503 #ifdef unix
2504 {"fileno", stdwin_connectionnumber},
2505 {"connectionnumber", stdwin_connectionnumber},
2506 #endif
2507 {"fleep", stdwin_fleep},
2508 {"getactive", stdwin_getactive},
2509 {"getcutbuffer", stdwin_getcutbuffer},
2510 {"getdefscrollbars", stdwin_getdefscrollbars},
2511 {"getdefwinpos", stdwin_getdefwinpos},
2512 {"getdefwinsize", stdwin_getdefwinsize},
2513 {"getevent", stdwin_getevent},
2514 {"getscrmm", stdwin_getscrmm},
2515 {"getscrsize", stdwin_getscrsize},
2516 {"getselection", stdwin_getselection},
2517 {"listfontnames", stdwin_listfontnames},
2518 {"menucreate", stdwin_menucreate},
2519 {"message", stdwin_message},
2520 #ifdef HAVE_BITMAPS
2521 {"newbitmap", stdwin_newbitmap},
2522 #endif
2523 {"open", stdwin_open},
2524 {"pollevent", stdwin_pollevent},
2525 {"resetselection", stdwin_resetselection},
2526 {"rotatecutbuffers", stdwin_rotatecutbuffers},
2527 {"setcutbuffer", stdwin_setcutbuffer},
2528 {"setdefscrollbars", stdwin_setdefscrollbars},
2529 {"setdefwinpos", stdwin_setdefwinpos},
2530 {"setdefwinsize", stdwin_setdefwinsize},
2532 /* Text measuring methods borrow code from drawing objects: */
2533 {"baseline", (PyCFunction)drawing_baseline},
2534 {"lineheight", (PyCFunction)drawing_lineheight},
2535 {"textbreak", (PyCFunction)drawing_textbreak},
2536 {"textwidth", (PyCFunction)drawing_textwidth},
2538 /* Same for font setting methods: */
2539 {"setfont", (PyCFunction)drawing_setfont},
2541 /* Same for color setting/getting methods: */
2542 {"getbgcolor", (PyCFunction)drawing_getbgcolor},
2543 {"getfgcolor", (PyCFunction)drawing_getfgcolor},
2544 {"setbgcolor", (PyCFunction)drawing_setbgcolor},
2545 {"setfgcolor", (PyCFunction)drawing_setfgcolor},
2547 {NULL, NULL} /* sentinel */
2550 #ifndef macintosh
2551 static int
2552 checkstringlist(args, ps, pn)
2553 PyObject *args;
2554 char ***ps;
2555 int *pn;
2557 int i, n;
2558 char **s;
2559 if (!PyList_Check(args)) {
2560 PyErr_SetString(PyExc_TypeError, "list of strings expected");
2561 return 0;
2563 n = PyList_Size(args);
2564 s = PyMem_NEW(char *, n+1);
2565 if (s == NULL) {
2566 PyErr_NoMemory();
2567 return 0;
2569 for (i = 0; i < n; i++) {
2570 PyObject *item = PyList_GetItem(args, i);
2571 if (!PyString_Check(item)) {
2572 PyErr_SetString(PyExc_TypeError,
2573 "list of strings expected");
2574 return 0;
2576 s[i] = PyString_AsString(item);
2578 s[n] = NULL; /* In case caller wants a NULL-terminated list */
2579 *ps = s;
2580 *pn = n;
2581 return 1;
2584 static int
2585 putbackstringlist(list, s, n)
2586 PyObject *list;
2587 char **s;
2588 int n;
2590 int oldsize = PyList_Size(list);
2591 PyObject *newlist;
2592 int i;
2593 if (n == oldsize)
2594 return 1;
2595 newlist = PyList_New(n);
2596 for (i = 0; i < n && newlist != NULL; i++) {
2597 PyObject *item = PyString_FromString(s[i]);
2598 if (item == NULL) {
2599 Py_DECREF(newlist);
2600 newlist = NULL;
2602 else
2603 PyList_SetItem(newlist, i, item);
2605 if (newlist == NULL)
2606 return 0;
2607 (*list->ob_type->tp_as_sequence->sq_ass_slice)
2608 (list, 0, oldsize, newlist);
2609 Py_DECREF(newlist);
2610 return 1;
2612 #endif /* macintosh */
2614 void
2615 initstdwin()
2617 PyObject *m, *d;
2618 static int inited = 0;
2620 if (!inited) {
2621 #ifdef macintosh
2622 winit();
2623 PyMac_DoYieldEnabled = 0;
2624 #else
2625 char buf[1000];
2626 int argc = 0;
2627 char **argv = NULL;
2628 PyObject *sys_argv = PySys_GetObject("argv");
2629 if (sys_argv != NULL) {
2630 if (!checkstringlist(sys_argv, &argv, &argc))
2631 PyErr_Clear();
2633 if (argc > 0) {
2634 /* If argv[0] has a ".py" suffix, remove the suffix */
2635 char *p = strrchr(argv[0], '.');
2636 if (p != NULL && strcmp(p, ".py") == 0) {
2637 int n = p - argv[0];
2638 if (n >= sizeof(buf))
2639 n = sizeof(buf)-1;
2640 strncpy(buf, argv[0], n);
2641 buf[n] = '\0';
2642 argv[0] = buf;
2645 winitargs(&argc, &argv);
2646 if (argv != NULL) {
2647 if (!putbackstringlist(sys_argv, argv, argc))
2648 PyErr_Clear();
2650 #endif
2651 inited = 1;
2653 m = Py_InitModule("stdwin", stdwin_methods);
2654 d = PyModule_GetDict(m);
2656 /* Initialize stdwin.error exception */
2657 StdwinError = PyErr_NewException("stdwin.error", NULL, NULL);
2658 if (StdwinError == NULL ||
2659 PyDict_SetItemString(d, "error", StdwinError) != 0)
2660 return;
2661 #ifdef WITH_THREAD
2662 StdwinLock = allocate_lock();
2663 #endif