blob: e996ac8eae251c971292ce206211f411393c7968 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Stdwin module */
26
27/* Stdwin itself is a module, not a separate object type.
28 Object types defined here:
29 wp: a window
30 dp: a drawing structure (only one can exist at a time)
31 mp: a menu
32 tp: a textedit block
33*/
34
35/* Rules for translating C stdwin function calls into Python stwin:
36 - All names drop their initial letter 'w'
37 - Functions with a window as first parameter are methods of window objects
38 - There is no equivalent for wclose(); just delete the window object
39 (all references to it!) (XXX maybe this is a bad idea)
40 - w.begindrawing() returns a drawing object
41 - There is no equivalent for wenddrawing(win); just delete the drawing
42 object (all references to it!) (XXX maybe this is a bad idea)
43 - Functions that may only be used inside wbegindrawing / wendddrawing
44 are methods of the drawing object; this includes the text measurement
45 functions (which however have doubles as module functions).
46 - Methods of the drawing object drop an initial 'draw' from their name
47 if they have it, e.g., wdrawline() --> d.line()
48 - The obvious type conversions: int --> intobject; string --> stringobject
49 - A text parameter followed by a length parameter is only a text (string)
50 parameter in Python
51 - A point or other pair of horizontal and vertical coordinates is always
52 a pair of integers in Python
53 - Two points forming a rectangle or endpoints of a line segment are a
54 pair of points in Python
55 - The arguments to d.elarc() are three points.
56 - The functions wgetclip() and wsetclip() are translated into
57 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
58 a bad word for what these functions do (clipping has a different
59 meaning in the drawing world), while cutbuffer is standard X jargon.
Guido van Rossum01769f01990-10-30 13:39:00 +000060 XXX This must change again in the light of changes to stdwin!
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 - For textedit, similar rules hold, but they are less strict.
62 XXX more?
63*/
64
Guido van Rossum3f5da241990-12-20 15:06:42 +000065#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068
Guido van Rossum3f5da241990-12-20 15:06:42 +000069#include "stdwin.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070
71/* Window and menu object types declared here because of forward references */
72
73typedef struct {
74 OB_HEAD
75 object *w_title;
76 WINDOW *w_win;
77 object *w_attr; /* Attributes dictionary */
78} windowobject;
79
80extern typeobject Windowtype; /* Really static, forward */
81
82#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
83
84typedef struct {
85 OB_HEAD
86 MENU *m_menu;
87 int m_id;
88 object *m_attr; /* Attributes dictionary */
89} menuobject;
90
91extern typeobject Menutype; /* Really static, forward */
92
93#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
94
95
96/* Strongly stdwin-specific argument handlers */
97
98static int
99getmousedetail(v, ep)
100 object *v;
101 EVENT *ep;
102{
103 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 4)
104 return err_badarg();
105 return getintintarg(gettupleitem(v, 0),
106 &ep->u.where.h, &ep->u.where.v) &&
107 getintarg(gettupleitem(v, 1), &ep->u.where.clicks) &&
108 getintarg(gettupleitem(v, 2), &ep->u.where.button) &&
109 getintarg(gettupleitem(v, 3), &ep->u.where.mask);
110}
111
112static int
113getmenudetail(v, ep)
114 object *v;
115 EVENT *ep;
116{
117 object *mp;
118 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2)
119 return err_badarg();
120 mp = gettupleitem(v, 0);
121 if (mp == NULL || !is_menuobject(mp))
122 return err_badarg();
123 ep->u.m.id = ((menuobject *)mp) -> m_id;
124 return getintarg(gettupleitem(v, 1), &ep->u.m.item);
125}
126
127static int
128geteventarg(v, ep)
129 object *v;
130 EVENT *ep;
131{
132 object *wp, *detail;
133 int a[4];
134 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3)
135 return err_badarg();
136 if (!getintarg(gettupleitem(v, 0), &ep->type))
137 return 0;
138 wp = gettupleitem(v, 1);
139 if (wp == None)
140 ep->window = NULL;
141 else if (wp == NULL || !is_windowobject(wp))
142 return err_badarg();
143 else
144 ep->window = ((windowobject *)wp) -> w_win;
145 detail = gettupleitem(v, 2);
146 switch (ep->type) {
147 case WE_CHAR:
148 if (!is_stringobject(detail) || getstringsize(detail) != 1)
149 return err_badarg();
150 ep->u.character = getstringvalue(detail)[0];
151 return 1;
152 case WE_COMMAND:
153 return getintarg(detail, &ep->u.command);
154 case WE_DRAW:
155 if (!getrectarg(detail, a))
156 return 0;
157 ep->u.area.left = a[0];
158 ep->u.area.top = a[1];
159 ep->u.area.right = a[2];
160 ep->u.area.bottom = a[3];
161 return 1;
162 case WE_MOUSE_DOWN:
163 case WE_MOUSE_UP:
164 case WE_MOUSE_MOVE:
165 return getmousedetail(detail, ep);
166 case WE_MENU:
167 return getmenudetail(detail, ep);
168 default:
169 return 1;
170 }
171}
172
173
174/* Return construction tools */
175
176static object *
177makepoint(a, b)
178 int a, b;
179{
180 object *v;
181 object *w;
182 if ((v = newtupleobject(2)) == NULL)
183 return NULL;
184 if ((w = newintobject((long)a)) == NULL ||
185 settupleitem(v, 0, w) != 0 ||
186 (w = newintobject((long)b)) == NULL ||
187 settupleitem(v, 1, w) != 0) {
188 DECREF(v);
189 return NULL;
190 }
191 return v;
192}
193
194static object *
195makerect(a, b, c, d)
196 int a, b, c, d;
197{
198 object *v;
199 object *w;
200 if ((v = newtupleobject(2)) == NULL)
201 return NULL;
202 if ((w = makepoint(a, b)) == NULL ||
203 settupleitem(v, 0, w) != 0 ||
204 (w = makepoint(c, d)) == NULL ||
205 settupleitem(v, 1, w) != 0) {
206 DECREF(v);
207 return NULL;
208 }
209 return v;
210}
211
212static object *
213makemouse(hor, ver, clicks, button, mask)
214 int hor, ver, clicks, button, mask;
215{
216 object *v;
217 object *w;
218 if ((v = newtupleobject(4)) == NULL)
219 return NULL;
220 if ((w = makepoint(hor, ver)) == NULL ||
221 settupleitem(v, 0, w) != 0 ||
222 (w = newintobject((long)clicks)) == NULL ||
223 settupleitem(v, 1, w) != 0 ||
224 (w = newintobject((long)button)) == NULL ||
225 settupleitem(v, 2, w) != 0 ||
226 (w = newintobject((long)mask)) == NULL ||
227 settupleitem(v, 3, w) != 0) {
228 DECREF(v);
229 return NULL;
230 }
231 return v;
232}
233
234static object *
235makemenu(mp, item)
236 object *mp;
237 int item;
238{
239 object *v;
240 object *w;
241 if ((v = newtupleobject(2)) == NULL)
242 return NULL;
243 INCREF(mp);
244 if (settupleitem(v, 0, mp) != 0 ||
245 (w = newintobject((long)item)) == NULL ||
246 settupleitem(v, 1, w) != 0) {
247 DECREF(v);
248 return NULL;
249 }
250 return v;
251}
252
253
254/* Drawing objects */
255
256typedef struct {
257 OB_HEAD
258 windowobject *d_ref;
259} drawingobject;
260
261static drawingobject *Drawing; /* Set to current drawing object, or NULL */
262
263/* Drawing methods */
264
Guido van Rossum3c284741991-11-27 14:54:54 +0000265static object *
266drawing_close(dp)
267 drawingobject *dp;
268{
269 if (dp->d_ref != NULL) {
270 wenddrawing(dp->d_ref->w_win);
271 Drawing = NULL;
272 DECREF(dp->d_ref);
273 dp->d_ref = NULL;
274 }
275 INCREF(None);
276 return None;
277}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278static void
279drawing_dealloc(dp)
280 drawingobject *dp;
281{
Guido van Rossum3c284741991-11-27 14:54:54 +0000282 if (dp->d_ref != NULL) {
283 wenddrawing(dp->d_ref->w_win);
284 Drawing = NULL;
285 DECREF(dp->d_ref);
286 dp->d_ref = NULL;
287 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 free((char *)dp);
289}
290
291static object *
292drawing_generic(dp, args, func)
293 drawingobject *dp;
294 object *args;
295 void (*func) FPROTO((int, int, int, int));
296{
297 int a[4];
298 if (!getrectarg(args, a))
299 return NULL;
300 (*func)(a[0], a[1], a[2], a[3]);
301 INCREF(None);
302 return None;
303}
304
305static object *
306drawing_line(dp, args)
307 drawingobject *dp;
308 object *args;
309{
Guido van Rossumbf109731991-03-06 13:14:12 +0000310 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311}
312
313static object *
314drawing_xorline(dp, args)
315 drawingobject *dp;
316 object *args;
317{
Guido van Rossumbf109731991-03-06 13:14:12 +0000318 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319}
320
321static object *
322drawing_circle(dp, args)
323 drawingobject *dp;
324 object *args;
325{
326 int a[3];
327 if (!getpointintarg(args, a))
328 return NULL;
329 wdrawcircle(a[0], a[1], a[2]);
330 INCREF(None);
331 return None;
332}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000333
Guido van Rossum27201061991-04-16 08:43:03 +0000334static object *
335drawing_fillcircle(dp, args)
336 drawingobject *dp;
337 object *args;
338{
339 int a[3];
340 if (!getpointintarg(args, a))
341 return NULL;
342 wfillcircle(a[0], a[1], a[2]);
343 INCREF(None);
344 return None;
345}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346
347static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000348drawing_xorcircle(dp, args)
349 drawingobject *dp;
350 object *args;
351{
352 int a[3];
353 if (!getpointintarg(args, a))
354 return NULL;
355 wxorcircle(a[0], a[1], a[2]);
356 INCREF(None);
357 return None;
358}
359
360static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361drawing_elarc(dp, args)
362 drawingobject *dp;
363 object *args;
364{
365 int a[6];
366 if (!get3pointarg(args, a))
367 return NULL;
368 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
369 INCREF(None);
370 return None;
371}
372
373static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000374drawing_fillelarc(dp, args)
375 drawingobject *dp;
376 object *args;
377{
378 int a[6];
379 if (!get3pointarg(args, a))
380 return NULL;
381 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
382 INCREF(None);
383 return None;
384}
385
386static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000387drawing_xorelarc(dp, args)
388 drawingobject *dp;
389 object *args;
390{
391 int a[6];
392 if (!get3pointarg(args, a))
393 return NULL;
394 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
395 INCREF(None);
396 return None;
397}
398
399static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400drawing_box(dp, args)
401 drawingobject *dp;
402 object *args;
403{
Guido van Rossumbf109731991-03-06 13:14:12 +0000404 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
407static object *
408drawing_erase(dp, args)
409 drawingobject *dp;
410 object *args;
411{
Guido van Rossumbf109731991-03-06 13:14:12 +0000412 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
415static object *
416drawing_paint(dp, args)
417 drawingobject *dp;
418 object *args;
419{
Guido van Rossumbf109731991-03-06 13:14:12 +0000420 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421}
422
423static object *
424drawing_invert(dp, args)
425 drawingobject *dp;
426 object *args;
427{
Guido van Rossumbf109731991-03-06 13:14:12 +0000428 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000429}
430
Guido van Rossum27201061991-04-16 08:43:03 +0000431static POINT *
432getpointsarray(v, psize)
433 object *v;
434 int *psize;
435{
436 int n = -1;
437 object * (*getitem) PROTO((object *, int));
438 int i;
439 POINT *points;
440
441 if (v == NULL)
442 ;
443 else if (is_listobject(v)) {
444 n = getlistsize(v);
445 getitem = getlistitem;
446 }
447 else if (is_tupleobject(v)) {
448 n = gettuplesize(v);
449 getitem = gettupleitem;
450 }
451
452 if (n <= 0) {
453 (void) err_badarg();
454 return NULL;
455 }
456
457 points = NEW(POINT, n);
458 if (points == NULL) {
459 (void) err_nomem();
460 return NULL;
461 }
462
463 for (i = 0; i < n; i++) {
464 object *w = (*getitem)(v, i);
465 int a[2];
466 if (!getpointarg(w, a)) {
467 DEL(points);
468 return NULL;
469 }
470 points[i].h = a[0];
471 points[i].v = a[1];
472 }
473
474 *psize = n;
475 return points;
476}
477
478static object *
479drawing_poly(dp, args)
480 drawingobject *dp;
481 object *args;
482{
483 int n;
484 POINT *points = getpointsarray(args, &n);
485 if (points == NULL)
486 return NULL;
487 wdrawpoly(n, points);
488 DEL(points);
489 INCREF(None);
490 return None;
491}
492
493static object *
494drawing_fillpoly(dp, args)
495 drawingobject *dp;
496 object *args;
497{
498 int n;
499 POINT *points = getpointsarray(args, &n);
500 if (points == NULL)
501 return NULL;
502 wfillpoly(n, points);
503 DEL(points);
504 INCREF(None);
505 return None;
506}
507
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000509drawing_xorpoly(dp, args)
510 drawingobject *dp;
511 object *args;
512{
513 int n;
514 POINT *points = getpointsarray(args, &n);
515 if (points == NULL)
516 return NULL;
517 wxorpoly(n, points);
518 DEL(points);
519 INCREF(None);
520 return None;
521}
522
523static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000524drawing_cliprect(dp, args)
525 drawingobject *dp;
526 object *args;
527{
Guido van Rossumbf109731991-03-06 13:14:12 +0000528 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529}
530
531static object *
532drawing_noclip(dp, args)
533 drawingobject *dp;
534 object *args;
535{
536 if (!getnoarg(args))
537 return NULL;
538 wnoclip();
539 INCREF(None);
540 return None;
541}
542
543static object *
544drawing_shade(dp, args)
545 drawingobject *dp;
546 object *args;
547{
548 int a[5];
549 if (!getrectintarg(args, a))
550 return NULL;
551 wshade(a[0], a[1], a[2], a[3], a[4]);
552 INCREF(None);
553 return None;
554}
555
556static object *
557drawing_text(dp, args)
558 drawingobject *dp;
559 object *args;
560{
561 int a[2];
562 object *s;
563 if (!getpointstrarg(args, a, &s))
564 return NULL;
565 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
566 INCREF(None);
567 return None;
568}
569
570/* The following four are also used as stdwin functions */
571
572static object *
573drawing_lineheight(dp, args)
574 drawingobject *dp;
575 object *args;
576{
577 if (!getnoarg(args))
578 return NULL;
579 return newintobject((long)wlineheight());
580}
581
582static object *
583drawing_baseline(dp, args)
584 drawingobject *dp;
585 object *args;
586{
587 if (!getnoarg(args))
588 return NULL;
589 return newintobject((long)wbaseline());
590}
591
592static object *
593drawing_textwidth(dp, args)
594 drawingobject *dp;
595 object *args;
596{
597 object *s;
598 if (!getstrarg(args, &s))
599 return NULL;
600 return newintobject(
601 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
602}
603
604static object *
605drawing_textbreak(dp, args)
606 drawingobject *dp;
607 object *args;
608{
609 object *s;
610 int a;
611 if (!getstrintarg(args, &s, &a))
612 return NULL;
613 return newintobject(
614 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
615}
616
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000617static object *
618drawing_setfont(self, args)
619 drawingobject *self;
620 object *args;
621{
Guido van Rossum50429a11991-04-04 15:24:07 +0000622 object *font, *style;
623 int size;
624 if (args == NULL) {
625 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000626 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000627 }
628 if (is_stringobject(args)) {
629 font = args;
630 style = NULL;
631 size = 0;
632 }
633 else if (is_tupleobject(args)) {
634 int n = gettuplesize(args);
635 if (n == 2) {
636 if (!getstrintarg(args, &font, &size))
637 return NULL;
638 style = NULL;
639 }
640 else if (!getstrstrintarg(args, &font, &style, &size))
641 return NULL;
642 }
643 else {
644 err_badarg();
645 return NULL;
646 }
Guido van Rossum246b9d81991-06-03 10:55:14 +0000647 wsetfont(getstringvalue(font));
Guido van Rossum50429a11991-04-04 15:24:07 +0000648 if (style != NULL) {
649 switch (*getstringvalue(style)) {
650 case 'b':
651 wsetbold();
652 break;
653 case 'i':
654 wsetitalic();
655 break;
656 case 'o':
657 wsetbolditalic();
658 break;
659 case 'u':
660 wsetunderline();
661 break;
662 default:
663 wsetplain();
664 break;
665 }
666 }
667 if (size != 0)
668 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000669 INCREF(None);
670 return None;
671}
672
673static object *
674drawing_getbgcolor(self, args)
675 object *self;
676 object *args;
677{
678 if (!getnoarg(args))
679 return NULL;
680 return newintobject((long)wgetbgcolor());
681}
682
683static object *
684drawing_getfgcolor(self, args)
685 object *self;
686 object *args;
687{
688 if (!getnoarg(args))
689 return NULL;
690 return newintobject((long)wgetfgcolor());
691}
692
693static object *
694drawing_setbgcolor(self, args)
695 object *self;
696 object *args;
697{
698 long color;
699 if (!getlongarg(args, &color))
700 return NULL;
701 wsetbgcolor((COLOR)color);
702 INCREF(None);
703 return None;
704}
705
706static object *
707drawing_setfgcolor(self, args)
708 object *self;
709 object *args;
710{
711 long color;
712 if (!getlongarg(args, &color))
713 return NULL;
714 wsetfgcolor((COLOR)color);
715 INCREF(None);
716 return None;
717}
718
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719static struct methodlist drawing_methods[] = {
720 {"box", drawing_box},
721 {"circle", drawing_circle},
722 {"cliprect", drawing_cliprect},
Guido van Rossum3c284741991-11-27 14:54:54 +0000723 {"close", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724 {"elarc", drawing_elarc},
Guido van Rossum3c284741991-11-27 14:54:54 +0000725 {"enddrawing", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000727 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000728 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000729 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000730 {"invert", drawing_invert},
731 {"line", drawing_line},
732 {"noclip", drawing_noclip},
733 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000734 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000735 {"shade", drawing_shade},
736 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000737 {"xorcircle", drawing_xorcircle},
738 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000740 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741
742 /* Text measuring methods: */
743 {"baseline", drawing_baseline},
744 {"lineheight", drawing_lineheight},
745 {"textbreak", drawing_textbreak},
746 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000747
748 /* Font setting methods: */
749 {"setfont", drawing_setfont},
750
751 /* Color methods: */
752 {"getbgcolor", drawing_getbgcolor},
753 {"getfgcolor", drawing_getfgcolor},
754 {"setbgcolor", drawing_setbgcolor},
755 {"setfgcolor", drawing_setfgcolor},
756
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757 {NULL, NULL} /* sentinel */
758};
759
760static object *
761drawing_getattr(wp, name)
762 drawingobject *wp;
763 char *name;
764{
765 return findmethod(drawing_methods, (object *)wp, name);
766}
767
Guido van Rossum541c8c01991-05-05 20:13:41 +0000768typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769 OB_HEAD_INIT(&Typetype)
770 0, /*ob_size*/
771 "drawing", /*tp_name*/
772 sizeof(drawingobject), /*tp_size*/
773 0, /*tp_itemsize*/
774 /* methods */
775 drawing_dealloc, /*tp_dealloc*/
776 0, /*tp_print*/
777 drawing_getattr, /*tp_getattr*/
778 0, /*tp_setattr*/
779 0, /*tp_compare*/
780 0, /*tp_repr*/
781};
782
783
784/* Text(edit) objects */
785
786typedef struct {
787 OB_HEAD
788 TEXTEDIT *t_text;
789 windowobject *t_ref;
790 object *t_attr; /* Attributes dictionary */
791} textobject;
792
793extern typeobject Texttype; /* Really static, forward */
794
795static textobject *
796newtextobject(wp, left, top, right, bottom)
797 windowobject *wp;
798 int left, top, right, bottom;
799{
800 textobject *tp;
801 tp = NEWOBJ(textobject, &Texttype);
802 if (tp == NULL)
803 return NULL;
804 tp->t_attr = NULL;
805 INCREF(wp);
806 tp->t_ref = wp;
807 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
808 if (tp->t_text == NULL) {
809 DECREF(tp);
810 return (textobject *) err_nomem();
811 }
812 return tp;
813}
814
815/* Text(edit) methods */
816
817static void
818text_dealloc(tp)
819 textobject *tp;
820{
821 if (tp->t_text != NULL)
822 tefree(tp->t_text);
Guido van Rossum3c284741991-11-27 14:54:54 +0000823 XDECREF(tp->t_attr);
824 XDECREF(tp->t_ref);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825 DEL(tp);
826}
827
828static object *
Guido van Rossum3c284741991-11-27 14:54:54 +0000829text_close(tp, args)
830 textobject *tp;
831 object *args;
832{
833 if (tp->t_text != NULL) {
834 tefree(tp->t_text);
835 tp->t_text = NULL;
836 }
837 if (tp->t_attr != NULL) {
838 DECREF(tp->t_attr);
839 tp->t_attr = NULL;
840 }
841 if (tp->t_ref != NULL) {
842 DECREF(tp->t_ref);
843 tp->t_ref = NULL;
844 }
845 INCREF(None);
846 return None;
847}
848
849static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850text_arrow(self, args)
851 textobject *self;
852 object *args;
853{
854 int code;
855 if (!getintarg(args, &code))
856 return NULL;
857 tearrow(self->t_text, code);
858 INCREF(None);
859 return None;
860}
861
862static object *
863text_draw(self, args)
864 textobject *self;
865 object *args;
866{
867 register TEXTEDIT *tp = self->t_text;
868 int a[4];
869 int left, top, right, bottom;
870 if (!getrectarg(args, a))
871 return NULL;
872 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000873 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874 return NULL;
875 }
876 /* Clip to text area and ignore if area is empty */
877 left = tegetleft(tp);
878 top = tegettop(tp);
879 right = tegetright(tp);
880 bottom = tegetbottom(tp);
881 if (a[0] < left) a[0] = left;
882 if (a[1] < top) a[1] = top;
883 if (a[2] > right) a[2] = right;
884 if (a[3] > bottom) a[3] = bottom;
885 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000886 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000887 tedrawnew(tp, a[0], a[1], a[2], a[3]);
888 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889 }
890 INCREF(None);
891 return None;
892}
893
894static object *
895text_event(self, args)
896 textobject *self;
897 object *args;
898{
899 register TEXTEDIT *tp = self->t_text;
900 EVENT e;
901 if (!geteventarg(args, &e))
902 return NULL;
903 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000904 /* Cheat at the margins */
905 int width, height;
906 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000907 if (e.u.where.h < 0 && tegetleft(tp) == 0)
908 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000909 else if (e.u.where.h > width && tegetright(tp) == width)
910 e.u.where.h = width;
911 if (e.u.where.v < 0 && tegettop(tp) == 0)
912 e.u.where.v = 0;
913 else if (e.u.where.v > height && tegetright(tp) == height)
914 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 }
916 return newintobject((long) teevent(tp, &e));
917}
918
919static object *
920text_getfocus(self, args)
921 textobject *self;
922 object *args;
923{
924 if (!getnoarg(args))
925 return NULL;
926 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
927}
928
929static object *
930text_getfocustext(self, args)
931 textobject *self;
932 object *args;
933{
934 int f1, f2;
935 char *text;
936 if (!getnoarg(args))
937 return NULL;
938 f1 = tegetfoc1(self->t_text);
939 f2 = tegetfoc2(self->t_text);
940 text = tegettext(self->t_text);
941 return newsizedstringobject(text + f1, f2-f1);
942}
943
944static object *
945text_getrect(self, args)
946 textobject *self;
947 object *args;
948{
949 if (!getnoarg(args))
950 return NULL;
951 return makerect(tegetleft(self->t_text),
952 tegettop(self->t_text),
953 tegetright(self->t_text),
954 tegetbottom(self->t_text));
955}
956
957static object *
958text_gettext(self, args)
959 textobject *self;
960 object *args;
961{
962 if (!getnoarg(args))
963 return NULL;
964 return newsizedstringobject(tegettext(self->t_text),
965 tegetlen(self->t_text));
966}
967
968static object *
969text_move(self, args)
970 textobject *self;
971 object *args;
972{
973 int a[4];
974 if (!getrectarg(args, a))
975 return NULL;
976 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
977 INCREF(None);
978 return None;
979}
980
981static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000982text_replace(self, args)
983 textobject *self;
984 object *args;
985{
986 object *text;
987 if (!getstrarg(args, &text))
988 return NULL;
989 tereplace(self->t_text, getstringvalue(text));
990 INCREF(None);
991 return None;
992}
993
994static object *
995text_setactive(self, args)
996 textobject *self;
997 object *args;
998{
999 int flag;
1000 if (!getintarg(args, &flag))
1001 return NULL;
1002 tesetactive(self->t_text, flag);
1003 INCREF(None);
1004 return None;
1005}
1006
1007static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001008text_setfocus(self, args)
1009 textobject *self;
1010 object *args;
1011{
1012 int a[2];
1013 if (!getpointarg(args, a))
1014 return NULL;
1015 tesetfocus(self->t_text, a[0], a[1]);
1016 INCREF(None);
1017 return None;
1018}
1019
1020static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001021text_settext(self, args)
1022 textobject *self;
1023 object *args;
1024{
1025 object *text;
1026 char *buf;
1027 int size;
1028 if (!getstrarg(args, &text))
1029 return NULL;
1030 size = getstringsize(text);
1031 if ((buf = NEW(char, size)) == NULL) {
1032 err_set(MemoryError);
1033 return NULL;
1034 }
1035 memcpy(buf, getstringvalue(text), size);
1036 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1037 INCREF(None);
1038 return None;
1039}
1040
1041static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001042text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001043 textobject *self;
1044 object *args;
1045{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001046 int a[4];
1047 if (args == None)
1048 tenoview(self->t_text);
1049 else {
1050 if (!getrectarg(args, a))
1051 return NULL;
1052 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1053 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 INCREF(None);
1055 return None;
1056}
1057
1058static struct methodlist text_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001059 {"arrow", text_arrow},
1060 {"close", text_close},
1061 {"draw", text_draw},
1062 {"event", text_event},
1063 {"getfocus", text_getfocus},
1064 {"getfocustext", text_getfocustext},
1065 {"getrect", text_getrect},
1066 {"gettext", text_gettext},
1067 {"move", text_move},
1068 {"replace", text_replace},
1069 {"setactive", text_setactive},
1070 {"setfocus", text_setfocus},
1071 {"settext", text_settext},
1072 {"setview", text_setview},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001073 {NULL, NULL} /* sentinel */
1074};
1075
1076static object *
1077text_getattr(tp, name)
1078 textobject *tp;
1079 char *name;
1080{
Guido van Rossum85f50761991-10-20 20:22:50 +00001081 object *v = NULL;
1082 if (strcmp(name, "__dict__") == 0) {
1083 v = tp->t_attr;
1084 if (v == NULL)
1085 v = None;
1086 }
1087 else if (tp->t_attr != NULL) {
1088 v = dictlookup(tp->t_attr, name);
1089 }
1090 if (v != NULL) {
1091 INCREF(v);
1092 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001093 }
1094 return findmethod(text_methods, (object *)tp, name);
1095}
1096
1097static int
1098text_setattr(tp, name, v)
1099 textobject *tp;
1100 char *name;
1101 object *v;
1102{
1103 if (tp->t_attr == NULL) {
1104 tp->t_attr = newdictobject();
1105 if (tp->t_attr == NULL)
1106 return -1;
1107 }
1108 if (v == NULL)
1109 return dictremove(tp->t_attr, name);
1110 else
1111 return dictinsert(tp->t_attr, name, v);
1112}
1113
Guido van Rossum541c8c01991-05-05 20:13:41 +00001114typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001115 OB_HEAD_INIT(&Typetype)
1116 0, /*ob_size*/
1117 "textedit", /*tp_name*/
1118 sizeof(textobject), /*tp_size*/
1119 0, /*tp_itemsize*/
1120 /* methods */
1121 text_dealloc, /*tp_dealloc*/
1122 0, /*tp_print*/
1123 text_getattr, /*tp_getattr*/
1124 text_setattr, /*tp_setattr*/
1125 0, /*tp_compare*/
1126 0, /*tp_repr*/
1127};
1128
1129
1130/* Menu objects */
1131
Guido van Rossum2d14e211991-02-19 12:26:49 +00001132#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001133#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001134static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135
1136static menuobject *
1137newmenuobject(title)
1138 object *title;
1139{
1140 int id;
1141 MENU *menu;
1142 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001143 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001144 if (menulist[id] == NULL)
1145 break;
1146 }
Guido van Rossum27201061991-04-16 08:43:03 +00001147 if (id >= MAXNMENU) {
1148 err_setstr(MemoryError, "creating too many menus");
1149 return NULL;
1150 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001151 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152 if (menu == NULL)
1153 return (menuobject *) err_nomem();
1154 mp = NEWOBJ(menuobject, &Menutype);
1155 if (mp != NULL) {
1156 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001157 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158 mp->m_attr = NULL;
1159 menulist[id] = mp;
1160 }
1161 else
1162 wmenudelete(menu);
1163 return mp;
1164}
1165
1166/* Menu methods */
1167
1168static void
1169menu_dealloc(mp)
1170 menuobject *mp;
1171{
1172
Guido van Rossum2d14e211991-02-19 12:26:49 +00001173 int id = mp->m_id - IDOFFSET;
1174 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001175 menulist[id] = NULL;
1176 }
1177 wmenudelete(mp->m_menu);
1178 if (mp->m_attr != NULL)
1179 DECREF(mp->m_attr);
1180 DEL(mp);
1181}
1182
1183static object *
1184menu_additem(self, args)
1185 menuobject *self;
1186 object *args;
1187{
1188 object *text;
1189 int shortcut;
1190 if (is_tupleobject(args)) {
1191 object *v;
1192 if (!getstrstrarg(args, &text, &v))
1193 return NULL;
1194 if (getstringsize(v) != 1) {
1195 err_badarg();
1196 return NULL;
1197 }
1198 shortcut = *getstringvalue(v) & 0xff;
1199 }
1200 else {
1201 if (!getstrarg(args, &text))
1202 return NULL;
1203 shortcut = -1;
1204 }
1205 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1206 INCREF(None);
1207 return None;
1208}
1209
1210static object *
1211menu_setitem(self, args)
1212 menuobject *self;
1213 object *args;
1214{
1215 int index;
1216 object *text;
1217 if (!getintstrarg(args, &index, &text))
1218 return NULL;
1219 wmenusetitem(self->m_menu, index, getstringvalue(text));
1220 INCREF(None);
1221 return None;
1222}
1223
1224static object *
1225menu_enable(self, args)
1226 menuobject *self;
1227 object *args;
1228{
1229 int index;
1230 int flag;
1231 if (!getintintarg(args, &index, &flag))
1232 return NULL;
1233 wmenuenable(self->m_menu, index, flag);
1234 INCREF(None);
1235 return None;
1236}
1237
1238static object *
1239menu_check(self, args)
1240 menuobject *self;
1241 object *args;
1242{
1243 int index;
1244 int flag;
1245 if (!getintintarg(args, &index, &flag))
1246 return NULL;
1247 wmenucheck(self->m_menu, index, flag);
1248 INCREF(None);
1249 return None;
1250}
1251
1252static struct methodlist menu_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001253 {"additem", menu_additem},
1254 {"setitem", menu_setitem},
1255 {"enable", menu_enable},
1256 {"check", menu_check},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001257 {NULL, NULL} /* sentinel */
1258};
1259
1260static object *
1261menu_getattr(mp, name)
1262 menuobject *mp;
1263 char *name;
1264{
Guido van Rossum85f50761991-10-20 20:22:50 +00001265 object *v = NULL;
1266 if (strcmp(name, "__dict__") == 0) {
1267 v = mp->m_attr;
1268 if (v == NULL)
1269 v = None;
1270 }
1271 else if (mp->m_attr != NULL) {
1272 v = dictlookup(mp->m_attr, name);
1273 }
1274 if (v != NULL) {
1275 INCREF(v);
1276 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001277 }
1278 return findmethod(menu_methods, (object *)mp, name);
1279}
1280
1281static int
1282menu_setattr(mp, name, v)
1283 menuobject *mp;
1284 char *name;
1285 object *v;
1286{
1287 if (mp->m_attr == NULL) {
1288 mp->m_attr = newdictobject();
1289 if (mp->m_attr == NULL)
1290 return -1;
1291 }
1292 if (v == NULL)
1293 return dictremove(mp->m_attr, name);
1294 else
1295 return dictinsert(mp->m_attr, name, v);
1296}
1297
Guido van Rossum541c8c01991-05-05 20:13:41 +00001298typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299 OB_HEAD_INIT(&Typetype)
1300 0, /*ob_size*/
1301 "menu", /*tp_name*/
1302 sizeof(menuobject), /*tp_size*/
1303 0, /*tp_itemsize*/
1304 /* methods */
1305 menu_dealloc, /*tp_dealloc*/
1306 0, /*tp_print*/
1307 menu_getattr, /*tp_getattr*/
1308 menu_setattr, /*tp_setattr*/
1309 0, /*tp_compare*/
1310 0, /*tp_repr*/
1311};
1312
1313
1314/* Windows */
1315
1316#define MAXNWIN 50
1317static windowobject *windowlist[MAXNWIN];
1318
1319/* Window methods */
1320
1321static void
1322window_dealloc(wp)
1323 windowobject *wp;
1324{
1325 if (wp->w_win != NULL) {
1326 int tag = wgettag(wp->w_win);
1327 if (tag >= 0 && tag < MAXNWIN)
1328 windowlist[tag] = NULL;
1329 else
1330 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1331 tag);
1332 wclose(wp->w_win);
1333 }
1334 DECREF(wp->w_title);
1335 if (wp->w_attr != NULL)
1336 DECREF(wp->w_attr);
1337 free((char *)wp);
1338}
1339
Guido van Rossumd783a461991-06-07 22:35:42 +00001340static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341window_print(wp, fp, flags)
1342 windowobject *wp;
1343 FILE *fp;
1344 int flags;
1345{
Guido van Rossum3c284741991-11-27 14:54:54 +00001346 fprintf(fp, "<%s window titled '%s'>",
1347 wp->w_win == NULL ? "closed" : "open",
1348 getstringvalue(wp->w_title));
Guido van Rossumd783a461991-06-07 22:35:42 +00001349 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
1351
1352static object *
Guido van Rossum3c284741991-11-27 14:54:54 +00001353window_close(wp, args)
1354 windowobject *wp;
1355 object *args;
1356{
1357 if (wp->w_win != NULL) {
1358 int tag = wgettag(wp->w_win);
1359 if (tag >= 0 && tag < MAXNWIN)
1360 windowlist[tag] = NULL;
1361 wclose(wp->w_win);
1362 wp->w_win = NULL;
1363 }
1364 INCREF(None);
1365 return None;
1366}
1367
1368static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369window_begindrawing(wp, args)
1370 windowobject *wp;
1371 object *args;
1372{
1373 drawingobject *dp;
1374 if (!getnoarg(args))
1375 return NULL;
1376 if (Drawing != NULL) {
1377 err_setstr(RuntimeError, "already drawing");
1378 return NULL;
1379 }
1380 dp = NEWOBJ(drawingobject, &Drawingtype);
1381 if (dp == NULL)
1382 return NULL;
1383 Drawing = dp;
1384 INCREF(wp);
1385 dp->d_ref = wp;
1386 wbegindrawing(wp->w_win);
1387 return (object *)dp;
1388}
1389
1390static object *
1391window_change(wp, args)
1392 windowobject *wp;
1393 object *args;
1394{
1395 int a[4];
1396 if (!getrectarg(args, a))
1397 return NULL;
1398 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1399 INCREF(None);
1400 return None;
1401}
1402
1403static object *
1404window_gettitle(wp, args)
1405 windowobject *wp;
1406 object *args;
1407{
1408 if (!getnoarg(args))
1409 return NULL;
1410 INCREF(wp->w_title);
1411 return wp->w_title;
1412}
1413
1414static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001415window_getwinpos(wp, args)
1416 windowobject *wp;
1417 object *args;
1418{
1419 int h, v;
1420 if (!getnoarg(args))
1421 return NULL;
1422 wgetwinpos(wp->w_win, &h, &v);
1423 return makepoint(h, v);
1424}
1425
1426static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427window_getwinsize(wp, args)
1428 windowobject *wp;
1429 object *args;
1430{
1431 int width, height;
1432 if (!getnoarg(args))
1433 return NULL;
1434 wgetwinsize(wp->w_win, &width, &height);
1435 return makepoint(width, height);
1436}
1437
1438static object *
1439window_getdocsize(wp, args)
1440 windowobject *wp;
1441 object *args;
1442{
1443 int width, height;
1444 if (!getnoarg(args))
1445 return NULL;
1446 wgetdocsize(wp->w_win, &width, &height);
1447 return makepoint(width, height);
1448}
1449
1450static object *
1451window_getorigin(wp, args)
1452 windowobject *wp;
1453 object *args;
1454{
1455 int width, height;
1456 if (!getnoarg(args))
1457 return NULL;
1458 wgetorigin(wp->w_win, &width, &height);
1459 return makepoint(width, height);
1460}
1461
1462static object *
1463window_scroll(wp, args)
1464 windowobject *wp;
1465 object *args;
1466{
1467 int a[6];
1468 if (!getrectpointarg(args, a))
1469 return NULL;
1470 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1471 INCREF(None);
1472 return None;
1473}
1474
1475static object *
1476window_setdocsize(wp, args)
1477 windowobject *wp;
1478 object *args;
1479{
1480 int a[2];
1481 if (!getpointarg(args, a))
1482 return NULL;
1483 wsetdocsize(wp->w_win, a[0], a[1]);
1484 INCREF(None);
1485 return None;
1486}
1487
1488static object *
1489window_setorigin(wp, args)
1490 windowobject *wp;
1491 object *args;
1492{
1493 int a[2];
1494 if (!getpointarg(args, a))
1495 return NULL;
1496 wsetorigin(wp->w_win, a[0], a[1]);
1497 INCREF(None);
1498 return None;
1499}
1500
1501static object *
1502window_settitle(wp, args)
1503 windowobject *wp;
1504 object *args;
1505{
1506 object *title;
1507 if (!getstrarg(args, &title))
1508 return NULL;
1509 DECREF(wp->w_title);
1510 INCREF(title);
1511 wp->w_title = title;
1512 wsettitle(wp->w_win, getstringvalue(title));
1513 INCREF(None);
1514 return None;
1515}
1516
1517static object *
1518window_show(wp, args)
1519 windowobject *wp;
1520 object *args;
1521{
1522 int a[4];
1523 if (!getrectarg(args, a))
1524 return NULL;
1525 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1526 INCREF(None);
1527 return None;
1528}
1529
1530static object *
1531window_settimer(wp, args)
1532 windowobject *wp;
1533 object *args;
1534{
1535 int a;
1536 if (!getintarg(args, &a))
1537 return NULL;
1538 wsettimer(wp->w_win, a);
1539 INCREF(None);
1540 return None;
1541}
1542
1543static object *
1544window_menucreate(self, args)
1545 windowobject *self;
1546 object *args;
1547{
1548 menuobject *mp;
1549 object *title;
1550 if (!getstrarg(args, &title))
1551 return NULL;
1552 wmenusetdeflocal(1);
1553 mp = newmenuobject(title);
1554 if (mp == NULL)
1555 return NULL;
1556 wmenuattach(self->w_win, mp->m_menu);
1557 return (object *)mp;
1558}
1559
1560static object *
1561window_textcreate(self, args)
1562 windowobject *self;
1563 object *args;
1564{
1565 textobject *tp;
1566 int a[4];
1567 if (!getrectarg(args, a))
1568 return NULL;
1569 return (object *)
1570 newtextobject(self, a[0], a[1], a[2], a[3]);
1571}
1572
Guido van Rossum5b10f451990-10-30 16:01:48 +00001573static object *
1574window_setselection(self, args)
1575 windowobject *self;
1576 object *args;
1577{
1578 int sel;
1579 object *str;
1580 int ok;
1581 if (!getintstrarg(args, &sel, &str))
1582 return NULL;
1583 ok = wsetselection(self->w_win, sel,
1584 getstringvalue(str), (int)getstringsize(str));
1585 return newintobject(ok);
1586}
1587
1588static object *
1589window_setwincursor(self, args)
1590 windowobject *self;
1591 object *args;
1592{
1593 object *str;
1594 CURSOR *c;
1595 if (!getstrarg(args, &str))
1596 return NULL;
1597 c = wfetchcursor(getstringvalue(str));
1598 if (c == NULL) {
1599 err_setstr(RuntimeError, "no such cursor");
1600 return NULL;
1601 }
1602 wsetwincursor(self->w_win, c);
1603 INCREF(None);
1604 return None;
1605}
1606
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001607#ifdef CWI_HACKS
1608static object *
1609window_getxwindowid(self, args)
1610 windowobject *self;
1611 object *args;
1612{
1613 long wid = wgetxwindowid(self->w_win);
1614 return newintobject(wid);
1615}
1616#endif
1617
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001618static struct methodlist window_methods[] = {
1619 {"begindrawing",window_begindrawing},
1620 {"change", window_change},
Guido van Rossum3c284741991-11-27 14:54:54 +00001621 {"close", window_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001622 {"getdocsize", window_getdocsize},
1623 {"getorigin", window_getorigin},
1624 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001625 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001626 {"getwinsize", window_getwinsize},
1627 {"menucreate", window_menucreate},
1628 {"scroll", window_scroll},
1629 {"setdocsize", window_setdocsize},
1630 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001631 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001632 {"settimer", window_settimer},
1633 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001634 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001635 {"show", window_show},
1636 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001637#ifdef CWI_HACKS
1638 {"getxwindowid",window_getxwindowid},
1639#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001640 {NULL, NULL} /* sentinel */
1641};
1642
1643static object *
1644window_getattr(wp, name)
1645 windowobject *wp;
1646 char *name;
1647{
Guido van Rossum85f50761991-10-20 20:22:50 +00001648 object *v = NULL;
1649 if (strcmp(name, "__dict__") == 0) {
1650 v = wp->w_attr;
1651 if (v == NULL)
1652 v = None;
1653 }
1654 else if (wp->w_attr != NULL) {
1655 v = dictlookup(wp->w_attr, name);
1656 }
1657 if (v != NULL) {
1658 INCREF(v);
1659 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001660 }
1661 return findmethod(window_methods, (object *)wp, name);
1662}
1663
1664static int
1665window_setattr(wp, name, v)
1666 windowobject *wp;
1667 char *name;
1668 object *v;
1669{
1670 if (wp->w_attr == NULL) {
1671 wp->w_attr = newdictobject();
1672 if (wp->w_attr == NULL)
1673 return -1;
1674 }
1675 if (v == NULL)
1676 return dictremove(wp->w_attr, name);
1677 else
1678 return dictinsert(wp->w_attr, name, v);
1679}
1680
Guido van Rossum541c8c01991-05-05 20:13:41 +00001681typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001682 OB_HEAD_INIT(&Typetype)
1683 0, /*ob_size*/
1684 "window", /*tp_name*/
1685 sizeof(windowobject), /*tp_size*/
1686 0, /*tp_itemsize*/
1687 /* methods */
1688 window_dealloc, /*tp_dealloc*/
1689 window_print, /*tp_print*/
1690 window_getattr, /*tp_getattr*/
1691 window_setattr, /*tp_setattr*/
1692 0, /*tp_compare*/
1693 0, /*tp_repr*/
1694};
1695
1696/* Stdwin methods */
1697
1698static object *
1699stdwin_open(sw, args)
1700 object *sw;
1701 object *args;
1702{
1703 int tag;
1704 object *title;
1705 windowobject *wp;
1706 if (!getstrarg(args, &title))
1707 return NULL;
1708 for (tag = 0; tag < MAXNWIN; tag++) {
1709 if (windowlist[tag] == NULL)
1710 break;
1711 }
Guido van Rossum27201061991-04-16 08:43:03 +00001712 if (tag >= MAXNWIN) {
1713 err_setstr(MemoryError, "creating too many windows");
1714 return NULL;
1715 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001716 wp = NEWOBJ(windowobject, &Windowtype);
1717 if (wp == NULL)
1718 return NULL;
1719 INCREF(title);
1720 wp->w_title = title;
1721 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1722 wp->w_attr = NULL;
1723 if (wp->w_win == NULL) {
1724 DECREF(wp);
1725 return NULL;
1726 }
1727 windowlist[tag] = wp;
1728 wsettag(wp->w_win, tag);
1729 return (object *)wp;
1730}
1731
1732static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001733window2object(win)
1734 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001735{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001736 object *w;
1737 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001738 w = None;
1739 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001740 int tag = wgettag(win);
1741 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1742 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001743 w = None;
1744 else
1745 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001746#ifdef sgi
1747 /* XXX Trap for unexplained weird bug */
1748 if ((long)w == (long)0x80000001) {
1749 err_setstr(SystemError,
1750 "bad pointer in stdwin.getevent()");
1751 return NULL;
1752 }
1753#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001754 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001755 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001756 return w;
1757}
1758
1759static object *
1760stdwin_get_poll_event(poll, args)
1761 int poll;
1762 object *args;
1763{
1764 EVENT e;
1765 object *v, *w;
1766 if (!getnoarg(args))
1767 return NULL;
1768 if (Drawing != NULL) {
1769 err_setstr(RuntimeError, "cannot getevent() while drawing");
1770 return NULL;
1771 }
1772 again:
1773 if (poll) {
1774 if (!wpollevent(&e)) {
1775 INCREF(None);
1776 return None;
1777 }
1778 }
1779 else
1780 wgetevent(&e);
1781 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1782 /* Turn keyboard interrupts into exceptions */
1783 err_set(KeyboardInterrupt);
1784 return NULL;
1785 }
1786 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1787 /* Turn WC_CLOSE commands into WE_CLOSE events */
1788 e.type = WE_CLOSE;
1789 }
1790 v = newtupleobject(3);
1791 if (v == NULL)
1792 return NULL;
1793 if ((w = newintobject((long)e.type)) == NULL) {
1794 DECREF(v);
1795 return NULL;
1796 }
1797 settupleitem(v, 0, w);
1798 settupleitem(v, 1, window2object(e.window));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001799 switch (e.type) {
1800 case WE_CHAR:
1801 {
1802 char c[1];
1803 c[0] = e.u.character;
1804 w = newsizedstringobject(c, 1);
1805 }
1806 break;
1807 case WE_COMMAND:
1808 w = newintobject((long)e.u.command);
1809 break;
1810 case WE_DRAW:
1811 w = makerect(e.u.area.left, e.u.area.top,
1812 e.u.area.right, e.u.area.bottom);
1813 break;
1814 case WE_MOUSE_DOWN:
1815 case WE_MOUSE_MOVE:
1816 case WE_MOUSE_UP:
1817 w = makemouse(e.u.where.h, e.u.where.v,
1818 e.u.where.clicks,
1819 e.u.where.button,
1820 e.u.where.mask);
1821 break;
1822 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001823 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1824 menulist[e.u.m.id - IDOFFSET] != NULL)
1825 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum246b9d81991-06-03 10:55:14 +00001826 else {
1827 /* Ghost menu event.
1828 Can occur only on the Mac if another part
1829 of the aplication has installed a menu;
1830 like the THINK C console library. */
1831 DECREF(v);
1832 goto again;
1833 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001834 w = makemenu(w, e.u.m.item);
1835 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001836 case WE_LOST_SEL:
1837 w = newintobject((long)e.u.sel);
1838 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001839 default:
1840 w = None;
1841 INCREF(w);
1842 break;
1843 }
1844 if (w == NULL) {
1845 DECREF(v);
1846 return NULL;
1847 }
1848 settupleitem(v, 2, w);
1849 return v;
1850}
1851
1852static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001853stdwin_getevent(sw, args)
1854 object *sw;
1855 object *args;
1856{
1857 return stdwin_get_poll_event(0, args);
1858}
1859
1860static object *
1861stdwin_pollevent(sw, args)
1862 object *sw;
1863 object *args;
1864{
1865 return stdwin_get_poll_event(1, args);
1866}
1867
1868static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001869stdwin_setdefwinpos(sw, args)
1870 object *sw;
1871 object *args;
1872{
1873 int a[2];
1874 if (!getpointarg(args, a))
1875 return NULL;
1876 wsetdefwinpos(a[0], a[1]);
1877 INCREF(None);
1878 return None;
1879}
1880
1881static object *
1882stdwin_setdefwinsize(sw, args)
1883 object *sw;
1884 object *args;
1885{
1886 int a[2];
1887 if (!getpointarg(args, a))
1888 return NULL;
1889 wsetdefwinsize(a[0], a[1]);
1890 INCREF(None);
1891 return None;
1892}
1893
1894static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001895stdwin_setdefscrollbars(sw, args)
1896 object *sw;
1897 object *args;
1898{
1899 int a[2];
1900 if (!getpointarg(args, a))
1901 return NULL;
1902 wsetdefscrollbars(a[0], a[1]);
1903 INCREF(None);
1904 return None;
1905}
1906
1907static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001908stdwin_getdefwinpos(self, args)
1909 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001910 object *args;
1911{
1912 int h, v;
1913 if (!getnoarg(args))
1914 return NULL;
1915 wgetdefwinpos(&h, &v);
1916 return makepoint(h, v);
1917}
1918
1919static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001920stdwin_getdefwinsize(self, args)
1921 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001922 object *args;
1923{
1924 int width, height;
1925 if (!getnoarg(args))
1926 return NULL;
1927 wgetdefwinsize(&width, &height);
1928 return makepoint(width, height);
1929}
1930
1931static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001932stdwin_getdefscrollbars(self, args)
1933 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001934 object *args;
1935{
1936 int h, v;
1937 if (!getnoarg(args))
1938 return NULL;
1939 wgetdefscrollbars(&h, &v);
1940 return makepoint(h, v);
1941}
1942
1943static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001944stdwin_menucreate(self, args)
1945 object *self;
1946 object *args;
1947{
1948 object *title;
1949 if (!getstrarg(args, &title))
1950 return NULL;
1951 wmenusetdeflocal(0);
1952 return (object *)newmenuobject(title);
1953}
1954
1955static object *
1956stdwin_askfile(self, args)
1957 object *self;
1958 object *args;
1959{
1960 object *prompt, *dflt;
1961 int new, ret;
1962 char buf[256];
1963 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1964 return NULL;
1965 strncpy(buf, getstringvalue(dflt), sizeof buf);
1966 buf[sizeof buf - 1] = '\0';
1967 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1968 if (!ret) {
1969 err_set(KeyboardInterrupt);
1970 return NULL;
1971 }
1972 return newstringobject(buf);
1973}
1974
1975static object *
1976stdwin_askync(self, args)
1977 object *self;
1978 object *args;
1979{
1980 object *prompt;
1981 int new, ret;
1982 if (!getstrintarg(args, &prompt, &new))
1983 return NULL;
1984 ret = waskync(getstringvalue(prompt), new);
1985 if (ret < 0) {
1986 err_set(KeyboardInterrupt);
1987 return NULL;
1988 }
1989 return newintobject((long)ret);
1990}
1991
1992static object *
1993stdwin_askstr(self, args)
1994 object *self;
1995 object *args;
1996{
1997 object *prompt, *dflt;
1998 int ret;
1999 char buf[256];
2000 if (!getstrstrarg(args, &prompt, &dflt))
2001 return NULL;
2002 strncpy(buf, getstringvalue(dflt), sizeof buf);
2003 buf[sizeof buf - 1] = '\0';
2004 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
2005 if (!ret) {
2006 err_set(KeyboardInterrupt);
2007 return NULL;
2008 }
2009 return newstringobject(buf);
2010}
2011
2012static object *
2013stdwin_message(self, args)
2014 object *self;
2015 object *args;
2016{
2017 object *msg;
2018 if (!getstrarg(args, &msg))
2019 return NULL;
2020 wmessage(getstringvalue(msg));
2021 INCREF(None);
2022 return None;
2023}
2024
2025static object *
2026stdwin_fleep(self, args)
2027 object *self;
2028 object *args;
2029{
2030 if (!getnoarg(args))
2031 return NULL;
2032 wfleep();
2033 INCREF(None);
2034 return None;
2035}
2036
2037static object *
2038stdwin_setcutbuffer(self, args)
2039 object *self;
2040 object *args;
2041{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002042 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002043 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00002044 if (!getintstrarg(args, &i, &str))
2045 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002046 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047 INCREF(None);
2048 return None;
2049}
2050
2051static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002052stdwin_getactive(self, args)
2053 object *self;
2054 object *args;
2055{
2056 return window2object(wgetactive());
2057}
2058
2059static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060stdwin_getcutbuffer(self, args)
2061 object *self;
2062 object *args;
2063{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002064 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002065 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002066 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002067 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002069 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002070 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002071 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002072 len = 0;
2073 }
2074 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002075}
2076
Guido van Rossum5b10f451990-10-30 16:01:48 +00002077static object *
2078stdwin_rotatecutbuffers(self, args)
2079 object *self;
2080 object *args;
2081{
2082 int i;
2083 if (!getintarg(args, &i))
2084 return NULL;
2085 wrotatecutbuffers(i);
2086 INCREF(None);
2087 return None;
2088}
2089
2090static object *
2091stdwin_getselection(self, args)
2092 object *self;
2093 object *args;
2094{
2095 int sel;
2096 char *data;
2097 int len;
2098 if (!getintarg(args, &sel))
2099 return NULL;
2100 data = wgetselection(sel, &len);
2101 if (data == NULL) {
2102 data = "";
2103 len = 0;
2104 }
2105 return newsizedstringobject(data, len);
2106}
2107
2108static object *
2109stdwin_resetselection(self, args)
2110 object *self;
2111 object *args;
2112{
2113 int sel;
2114 if (!getintarg(args, &sel))
2115 return NULL;
2116 wresetselection(sel);
2117 INCREF(None);
2118 return None;
2119}
2120
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002121static object *
2122stdwin_fetchcolor(self, args)
2123 object *self;
2124 object *args;
2125{
2126 object *colorname;
2127 if (!getstrarg(args, &colorname))
2128 return NULL;
2129 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
2130}
2131
Guido van Rossum541c8c01991-05-05 20:13:41 +00002132static object *
2133stdwin_getscrsize(self, args)
2134 object *self;
2135 object *args;
2136{
2137 int width, height;
2138 if (!getnoarg(args))
2139 return NULL;
2140 wgetscrsize(&width, &height);
2141 return makepoint(width, height);
2142}
2143
2144static object *
2145stdwin_getscrmm(self, args)
2146 object *self;
2147 object *args;
2148{
2149 int width, height;
2150 if (!getnoarg(args))
2151 return NULL;
2152 wgetscrmm(&width, &height);
2153 return makepoint(width, height);
2154}
2155
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002156static struct methodlist stdwin_methods[] = {
2157 {"askfile", stdwin_askfile},
2158 {"askstr", stdwin_askstr},
2159 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002160 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002161 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002162 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002163 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002164 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002165 {"getdefwinpos", stdwin_getdefwinpos},
2166 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002167 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002168 {"getscrmm", stdwin_getscrmm},
2169 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002170 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002171 {"menucreate", stdwin_menucreate},
2172 {"message", stdwin_message},
2173 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002174 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002175 {"resetselection", stdwin_resetselection},
2176 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002177 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002178 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002179 {"setdefwinpos", stdwin_setdefwinpos},
2180 {"setdefwinsize", stdwin_setdefwinsize},
2181
2182 /* Text measuring methods borrow code from drawing objects: */
2183 {"baseline", drawing_baseline},
2184 {"lineheight", drawing_lineheight},
2185 {"textbreak", drawing_textbreak},
2186 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002187
2188 /* Same for font setting methods: */
2189 {"setfont", drawing_setfont},
2190
2191 /* Same for color setting/getting methods: */
2192 {"getbgcolor", drawing_getbgcolor},
2193 {"getfgcolor", drawing_getfgcolor},
2194 {"setbgcolor", drawing_setbgcolor},
2195 {"setfgcolor", drawing_setfgcolor},
2196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002197 {NULL, NULL} /* sentinel */
2198};
2199
2200void
2201initstdwin()
2202{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002203 static int inited;
2204 if (!inited) {
2205 winit();
2206 inited = 1;
2207 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002208 initmodule("stdwin", stdwin_methods);
2209}