blob: 494b15ea3015a93f7f30438d3ce999364b62944a [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
265static void
266drawing_dealloc(dp)
267 drawingobject *dp;
268{
269 wenddrawing(dp->d_ref->w_win);
270 Drawing = NULL;
271 DECREF(dp->d_ref);
272 free((char *)dp);
273}
274
275static object *
276drawing_generic(dp, args, func)
277 drawingobject *dp;
278 object *args;
279 void (*func) FPROTO((int, int, int, int));
280{
281 int a[4];
282 if (!getrectarg(args, a))
283 return NULL;
284 (*func)(a[0], a[1], a[2], a[3]);
285 INCREF(None);
286 return None;
287}
288
289static object *
290drawing_line(dp, args)
291 drawingobject *dp;
292 object *args;
293{
Guido van Rossumbf109731991-03-06 13:14:12 +0000294 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295}
296
297static object *
298drawing_xorline(dp, args)
299 drawingobject *dp;
300 object *args;
301{
Guido van Rossumbf109731991-03-06 13:14:12 +0000302 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303}
304
305static object *
306drawing_circle(dp, args)
307 drawingobject *dp;
308 object *args;
309{
310 int a[3];
311 if (!getpointintarg(args, a))
312 return NULL;
313 wdrawcircle(a[0], a[1], a[2]);
314 INCREF(None);
315 return None;
316}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000317
Guido van Rossum27201061991-04-16 08:43:03 +0000318static object *
319drawing_fillcircle(dp, args)
320 drawingobject *dp;
321 object *args;
322{
323 int a[3];
324 if (!getpointintarg(args, a))
325 return NULL;
326 wfillcircle(a[0], a[1], a[2]);
327 INCREF(None);
328 return None;
329}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330
331static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000332drawing_xorcircle(dp, args)
333 drawingobject *dp;
334 object *args;
335{
336 int a[3];
337 if (!getpointintarg(args, a))
338 return NULL;
339 wxorcircle(a[0], a[1], a[2]);
340 INCREF(None);
341 return None;
342}
343
344static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345drawing_elarc(dp, args)
346 drawingobject *dp;
347 object *args;
348{
349 int a[6];
350 if (!get3pointarg(args, a))
351 return NULL;
352 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
353 INCREF(None);
354 return None;
355}
356
357static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000358drawing_fillelarc(dp, args)
359 drawingobject *dp;
360 object *args;
361{
362 int a[6];
363 if (!get3pointarg(args, a))
364 return NULL;
365 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
366 INCREF(None);
367 return None;
368}
369
370static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000371drawing_xorelarc(dp, args)
372 drawingobject *dp;
373 object *args;
374{
375 int a[6];
376 if (!get3pointarg(args, a))
377 return NULL;
378 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
379 INCREF(None);
380 return None;
381}
382
383static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384drawing_box(dp, args)
385 drawingobject *dp;
386 object *args;
387{
Guido van Rossumbf109731991-03-06 13:14:12 +0000388 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
391static object *
392drawing_erase(dp, args)
393 drawingobject *dp;
394 object *args;
395{
Guido van Rossumbf109731991-03-06 13:14:12 +0000396 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397}
398
399static object *
400drawing_paint(dp, args)
401 drawingobject *dp;
402 object *args;
403{
Guido van Rossumbf109731991-03-06 13:14:12 +0000404 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
407static object *
408drawing_invert(dp, args)
409 drawingobject *dp;
410 object *args;
411{
Guido van Rossumbf109731991-03-06 13:14:12 +0000412 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossum27201061991-04-16 08:43:03 +0000415static POINT *
416getpointsarray(v, psize)
417 object *v;
418 int *psize;
419{
420 int n = -1;
421 object * (*getitem) PROTO((object *, int));
422 int i;
423 POINT *points;
424
425 if (v == NULL)
426 ;
427 else if (is_listobject(v)) {
428 n = getlistsize(v);
429 getitem = getlistitem;
430 }
431 else if (is_tupleobject(v)) {
432 n = gettuplesize(v);
433 getitem = gettupleitem;
434 }
435
436 if (n <= 0) {
437 (void) err_badarg();
438 return NULL;
439 }
440
441 points = NEW(POINT, n);
442 if (points == NULL) {
443 (void) err_nomem();
444 return NULL;
445 }
446
447 for (i = 0; i < n; i++) {
448 object *w = (*getitem)(v, i);
449 int a[2];
450 if (!getpointarg(w, a)) {
451 DEL(points);
452 return NULL;
453 }
454 points[i].h = a[0];
455 points[i].v = a[1];
456 }
457
458 *psize = n;
459 return points;
460}
461
462static object *
463drawing_poly(dp, args)
464 drawingobject *dp;
465 object *args;
466{
467 int n;
468 POINT *points = getpointsarray(args, &n);
469 if (points == NULL)
470 return NULL;
471 wdrawpoly(n, points);
472 DEL(points);
473 INCREF(None);
474 return None;
475}
476
477static object *
478drawing_fillpoly(dp, args)
479 drawingobject *dp;
480 object *args;
481{
482 int n;
483 POINT *points = getpointsarray(args, &n);
484 if (points == NULL)
485 return NULL;
486 wfillpoly(n, points);
487 DEL(points);
488 INCREF(None);
489 return None;
490}
491
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000493drawing_xorpoly(dp, args)
494 drawingobject *dp;
495 object *args;
496{
497 int n;
498 POINT *points = getpointsarray(args, &n);
499 if (points == NULL)
500 return NULL;
501 wxorpoly(n, points);
502 DEL(points);
503 INCREF(None);
504 return None;
505}
506
507static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508drawing_cliprect(dp, args)
509 drawingobject *dp;
510 object *args;
511{
Guido van Rossumbf109731991-03-06 13:14:12 +0000512 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
515static object *
516drawing_noclip(dp, args)
517 drawingobject *dp;
518 object *args;
519{
520 if (!getnoarg(args))
521 return NULL;
522 wnoclip();
523 INCREF(None);
524 return None;
525}
526
527static object *
528drawing_shade(dp, args)
529 drawingobject *dp;
530 object *args;
531{
532 int a[5];
533 if (!getrectintarg(args, a))
534 return NULL;
535 wshade(a[0], a[1], a[2], a[3], a[4]);
536 INCREF(None);
537 return None;
538}
539
540static object *
541drawing_text(dp, args)
542 drawingobject *dp;
543 object *args;
544{
545 int a[2];
546 object *s;
547 if (!getpointstrarg(args, a, &s))
548 return NULL;
549 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
550 INCREF(None);
551 return None;
552}
553
554/* The following four are also used as stdwin functions */
555
556static object *
557drawing_lineheight(dp, args)
558 drawingobject *dp;
559 object *args;
560{
561 if (!getnoarg(args))
562 return NULL;
563 return newintobject((long)wlineheight());
564}
565
566static object *
567drawing_baseline(dp, args)
568 drawingobject *dp;
569 object *args;
570{
571 if (!getnoarg(args))
572 return NULL;
573 return newintobject((long)wbaseline());
574}
575
576static object *
577drawing_textwidth(dp, args)
578 drawingobject *dp;
579 object *args;
580{
581 object *s;
582 if (!getstrarg(args, &s))
583 return NULL;
584 return newintobject(
585 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
586}
587
588static object *
589drawing_textbreak(dp, args)
590 drawingobject *dp;
591 object *args;
592{
593 object *s;
594 int a;
595 if (!getstrintarg(args, &s, &a))
596 return NULL;
597 return newintobject(
598 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
599}
600
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000601static object *
602drawing_setfont(self, args)
603 drawingobject *self;
604 object *args;
605{
Guido van Rossum50429a11991-04-04 15:24:07 +0000606 object *font, *style;
607 int size;
608 if (args == NULL) {
609 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000610 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000611 }
612 if (is_stringobject(args)) {
613 font = args;
614 style = NULL;
615 size = 0;
616 }
617 else if (is_tupleobject(args)) {
618 int n = gettuplesize(args);
619 if (n == 2) {
620 if (!getstrintarg(args, &font, &size))
621 return NULL;
622 style = NULL;
623 }
624 else if (!getstrstrintarg(args, &font, &style, &size))
625 return NULL;
626 }
627 else {
628 err_badarg();
629 return NULL;
630 }
Guido van Rossum246b9d81991-06-03 10:55:14 +0000631 wsetfont(getstringvalue(font));
Guido van Rossum50429a11991-04-04 15:24:07 +0000632 if (style != NULL) {
633 switch (*getstringvalue(style)) {
634 case 'b':
635 wsetbold();
636 break;
637 case 'i':
638 wsetitalic();
639 break;
640 case 'o':
641 wsetbolditalic();
642 break;
643 case 'u':
644 wsetunderline();
645 break;
646 default:
647 wsetplain();
648 break;
649 }
650 }
651 if (size != 0)
652 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000653 INCREF(None);
654 return None;
655}
656
657static object *
658drawing_getbgcolor(self, args)
659 object *self;
660 object *args;
661{
662 if (!getnoarg(args))
663 return NULL;
664 return newintobject((long)wgetbgcolor());
665}
666
667static object *
668drawing_getfgcolor(self, args)
669 object *self;
670 object *args;
671{
672 if (!getnoarg(args))
673 return NULL;
674 return newintobject((long)wgetfgcolor());
675}
676
677static object *
678drawing_setbgcolor(self, args)
679 object *self;
680 object *args;
681{
682 long color;
683 if (!getlongarg(args, &color))
684 return NULL;
685 wsetbgcolor((COLOR)color);
686 INCREF(None);
687 return None;
688}
689
690static object *
691drawing_setfgcolor(self, args)
692 object *self;
693 object *args;
694{
695 long color;
696 if (!getlongarg(args, &color))
697 return NULL;
698 wsetfgcolor((COLOR)color);
699 INCREF(None);
700 return None;
701}
702
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703static struct methodlist drawing_methods[] = {
704 {"box", drawing_box},
705 {"circle", drawing_circle},
706 {"cliprect", drawing_cliprect},
707 {"elarc", drawing_elarc},
708 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000709 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000710 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000711 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000712 {"invert", drawing_invert},
713 {"line", drawing_line},
714 {"noclip", drawing_noclip},
715 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000716 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000717 {"shade", drawing_shade},
718 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000719 {"xorcircle", drawing_xorcircle},
720 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000722 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000723
724 /* Text measuring methods: */
725 {"baseline", drawing_baseline},
726 {"lineheight", drawing_lineheight},
727 {"textbreak", drawing_textbreak},
728 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000729
730 /* Font setting methods: */
731 {"setfont", drawing_setfont},
732
733 /* Color methods: */
734 {"getbgcolor", drawing_getbgcolor},
735 {"getfgcolor", drawing_getfgcolor},
736 {"setbgcolor", drawing_setbgcolor},
737 {"setfgcolor", drawing_setfgcolor},
738
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739 {NULL, NULL} /* sentinel */
740};
741
742static object *
743drawing_getattr(wp, name)
744 drawingobject *wp;
745 char *name;
746{
747 return findmethod(drawing_methods, (object *)wp, name);
748}
749
Guido van Rossum541c8c01991-05-05 20:13:41 +0000750typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000751 OB_HEAD_INIT(&Typetype)
752 0, /*ob_size*/
753 "drawing", /*tp_name*/
754 sizeof(drawingobject), /*tp_size*/
755 0, /*tp_itemsize*/
756 /* methods */
757 drawing_dealloc, /*tp_dealloc*/
758 0, /*tp_print*/
759 drawing_getattr, /*tp_getattr*/
760 0, /*tp_setattr*/
761 0, /*tp_compare*/
762 0, /*tp_repr*/
763};
764
765
766/* Text(edit) objects */
767
768typedef struct {
769 OB_HEAD
770 TEXTEDIT *t_text;
771 windowobject *t_ref;
772 object *t_attr; /* Attributes dictionary */
773} textobject;
774
775extern typeobject Texttype; /* Really static, forward */
776
777static textobject *
778newtextobject(wp, left, top, right, bottom)
779 windowobject *wp;
780 int left, top, right, bottom;
781{
782 textobject *tp;
783 tp = NEWOBJ(textobject, &Texttype);
784 if (tp == NULL)
785 return NULL;
786 tp->t_attr = NULL;
787 INCREF(wp);
788 tp->t_ref = wp;
789 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
790 if (tp->t_text == NULL) {
791 DECREF(tp);
792 return (textobject *) err_nomem();
793 }
794 return tp;
795}
796
797/* Text(edit) methods */
798
799static void
800text_dealloc(tp)
801 textobject *tp;
802{
803 if (tp->t_text != NULL)
804 tefree(tp->t_text);
805 if (tp->t_attr != NULL)
806 DECREF(tp->t_attr);
807 DECREF(tp->t_ref);
808 DEL(tp);
809}
810
811static object *
812text_arrow(self, args)
813 textobject *self;
814 object *args;
815{
816 int code;
817 if (!getintarg(args, &code))
818 return NULL;
819 tearrow(self->t_text, code);
820 INCREF(None);
821 return None;
822}
823
824static object *
825text_draw(self, args)
826 textobject *self;
827 object *args;
828{
829 register TEXTEDIT *tp = self->t_text;
830 int a[4];
831 int left, top, right, bottom;
832 if (!getrectarg(args, a))
833 return NULL;
834 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000835 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836 return NULL;
837 }
838 /* Clip to text area and ignore if area is empty */
839 left = tegetleft(tp);
840 top = tegettop(tp);
841 right = tegetright(tp);
842 bottom = tegetbottom(tp);
843 if (a[0] < left) a[0] = left;
844 if (a[1] < top) a[1] = top;
845 if (a[2] > right) a[2] = right;
846 if (a[3] > bottom) a[3] = bottom;
847 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849 tedrawnew(tp, a[0], a[1], a[2], a[3]);
850 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000851 }
852 INCREF(None);
853 return None;
854}
855
856static object *
857text_event(self, args)
858 textobject *self;
859 object *args;
860{
861 register TEXTEDIT *tp = self->t_text;
862 EVENT e;
863 if (!geteventarg(args, &e))
864 return NULL;
865 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000866 /* Cheat at the margins */
867 int width, height;
868 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869 if (e.u.where.h < 0 && tegetleft(tp) == 0)
870 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000871 else if (e.u.where.h > width && tegetright(tp) == width)
872 e.u.where.h = width;
873 if (e.u.where.v < 0 && tegettop(tp) == 0)
874 e.u.where.v = 0;
875 else if (e.u.where.v > height && tegetright(tp) == height)
876 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877 }
878 return newintobject((long) teevent(tp, &e));
879}
880
881static object *
882text_getfocus(self, args)
883 textobject *self;
884 object *args;
885{
886 if (!getnoarg(args))
887 return NULL;
888 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
889}
890
891static object *
892text_getfocustext(self, args)
893 textobject *self;
894 object *args;
895{
896 int f1, f2;
897 char *text;
898 if (!getnoarg(args))
899 return NULL;
900 f1 = tegetfoc1(self->t_text);
901 f2 = tegetfoc2(self->t_text);
902 text = tegettext(self->t_text);
903 return newsizedstringobject(text + f1, f2-f1);
904}
905
906static object *
907text_getrect(self, args)
908 textobject *self;
909 object *args;
910{
911 if (!getnoarg(args))
912 return NULL;
913 return makerect(tegetleft(self->t_text),
914 tegettop(self->t_text),
915 tegetright(self->t_text),
916 tegetbottom(self->t_text));
917}
918
919static object *
920text_gettext(self, args)
921 textobject *self;
922 object *args;
923{
924 if (!getnoarg(args))
925 return NULL;
926 return newsizedstringobject(tegettext(self->t_text),
927 tegetlen(self->t_text));
928}
929
930static object *
931text_move(self, args)
932 textobject *self;
933 object *args;
934{
935 int a[4];
936 if (!getrectarg(args, a))
937 return NULL;
938 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
939 INCREF(None);
940 return None;
941}
942
943static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000944text_replace(self, args)
945 textobject *self;
946 object *args;
947{
948 object *text;
949 if (!getstrarg(args, &text))
950 return NULL;
951 tereplace(self->t_text, getstringvalue(text));
952 INCREF(None);
953 return None;
954}
955
956static object *
957text_setactive(self, args)
958 textobject *self;
959 object *args;
960{
961 int flag;
962 if (!getintarg(args, &flag))
963 return NULL;
964 tesetactive(self->t_text, flag);
965 INCREF(None);
966 return None;
967}
968
969static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970text_setfocus(self, args)
971 textobject *self;
972 object *args;
973{
974 int a[2];
975 if (!getpointarg(args, a))
976 return NULL;
977 tesetfocus(self->t_text, a[0], a[1]);
978 INCREF(None);
979 return None;
980}
981
982static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000983text_settext(self, args)
984 textobject *self;
985 object *args;
986{
987 object *text;
988 char *buf;
989 int size;
990 if (!getstrarg(args, &text))
991 return NULL;
992 size = getstringsize(text);
993 if ((buf = NEW(char, size)) == NULL) {
994 err_set(MemoryError);
995 return NULL;
996 }
997 memcpy(buf, getstringvalue(text), size);
998 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
999 INCREF(None);
1000 return None;
1001}
1002
1003static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001004text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 textobject *self;
1006 object *args;
1007{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001008 int a[4];
1009 if (args == None)
1010 tenoview(self->t_text);
1011 else {
1012 if (!getrectarg(args, a))
1013 return NULL;
1014 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1015 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 INCREF(None);
1017 return None;
1018}
1019
1020static struct methodlist text_methods[] = {
1021 "arrow", text_arrow,
1022 "draw", text_draw,
1023 "event", text_event,
1024 "getfocus", text_getfocus,
1025 "getfocustext", text_getfocustext,
1026 "getrect", text_getrect,
1027 "gettext", text_gettext,
1028 "move", text_move,
1029 "replace", text_replace,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001030 "setactive", text_setactive,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001031 "setfocus", text_setfocus,
Guido van Rossum541c8c01991-05-05 20:13:41 +00001032 "settext", text_settext,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001033 "setview", text_setview,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001034 {NULL, NULL} /* sentinel */
1035};
1036
1037static object *
1038text_getattr(tp, name)
1039 textobject *tp;
1040 char *name;
1041{
1042 if (tp->t_attr != NULL) {
1043 object *v = dictlookup(tp->t_attr, name);
1044 if (v != NULL) {
1045 INCREF(v);
1046 return v;
1047 }
1048 }
1049 return findmethod(text_methods, (object *)tp, name);
1050}
1051
1052static int
1053text_setattr(tp, name, v)
1054 textobject *tp;
1055 char *name;
1056 object *v;
1057{
1058 if (tp->t_attr == NULL) {
1059 tp->t_attr = newdictobject();
1060 if (tp->t_attr == NULL)
1061 return -1;
1062 }
1063 if (v == NULL)
1064 return dictremove(tp->t_attr, name);
1065 else
1066 return dictinsert(tp->t_attr, name, v);
1067}
1068
Guido van Rossum541c8c01991-05-05 20:13:41 +00001069typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070 OB_HEAD_INIT(&Typetype)
1071 0, /*ob_size*/
1072 "textedit", /*tp_name*/
1073 sizeof(textobject), /*tp_size*/
1074 0, /*tp_itemsize*/
1075 /* methods */
1076 text_dealloc, /*tp_dealloc*/
1077 0, /*tp_print*/
1078 text_getattr, /*tp_getattr*/
1079 text_setattr, /*tp_setattr*/
1080 0, /*tp_compare*/
1081 0, /*tp_repr*/
1082};
1083
1084
1085/* Menu objects */
1086
Guido van Rossum2d14e211991-02-19 12:26:49 +00001087#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001088#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001089static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090
1091static menuobject *
1092newmenuobject(title)
1093 object *title;
1094{
1095 int id;
1096 MENU *menu;
1097 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001098 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099 if (menulist[id] == NULL)
1100 break;
1101 }
Guido van Rossum27201061991-04-16 08:43:03 +00001102 if (id >= MAXNMENU) {
1103 err_setstr(MemoryError, "creating too many menus");
1104 return NULL;
1105 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001106 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107 if (menu == NULL)
1108 return (menuobject *) err_nomem();
1109 mp = NEWOBJ(menuobject, &Menutype);
1110 if (mp != NULL) {
1111 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001112 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113 mp->m_attr = NULL;
1114 menulist[id] = mp;
1115 }
1116 else
1117 wmenudelete(menu);
1118 return mp;
1119}
1120
1121/* Menu methods */
1122
1123static void
1124menu_dealloc(mp)
1125 menuobject *mp;
1126{
1127
Guido van Rossum2d14e211991-02-19 12:26:49 +00001128 int id = mp->m_id - IDOFFSET;
1129 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130 menulist[id] = NULL;
1131 }
1132 wmenudelete(mp->m_menu);
1133 if (mp->m_attr != NULL)
1134 DECREF(mp->m_attr);
1135 DEL(mp);
1136}
1137
1138static object *
1139menu_additem(self, args)
1140 menuobject *self;
1141 object *args;
1142{
1143 object *text;
1144 int shortcut;
1145 if (is_tupleobject(args)) {
1146 object *v;
1147 if (!getstrstrarg(args, &text, &v))
1148 return NULL;
1149 if (getstringsize(v) != 1) {
1150 err_badarg();
1151 return NULL;
1152 }
1153 shortcut = *getstringvalue(v) & 0xff;
1154 }
1155 else {
1156 if (!getstrarg(args, &text))
1157 return NULL;
1158 shortcut = -1;
1159 }
1160 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1161 INCREF(None);
1162 return None;
1163}
1164
1165static object *
1166menu_setitem(self, args)
1167 menuobject *self;
1168 object *args;
1169{
1170 int index;
1171 object *text;
1172 if (!getintstrarg(args, &index, &text))
1173 return NULL;
1174 wmenusetitem(self->m_menu, index, getstringvalue(text));
1175 INCREF(None);
1176 return None;
1177}
1178
1179static object *
1180menu_enable(self, args)
1181 menuobject *self;
1182 object *args;
1183{
1184 int index;
1185 int flag;
1186 if (!getintintarg(args, &index, &flag))
1187 return NULL;
1188 wmenuenable(self->m_menu, index, flag);
1189 INCREF(None);
1190 return None;
1191}
1192
1193static object *
1194menu_check(self, args)
1195 menuobject *self;
1196 object *args;
1197{
1198 int index;
1199 int flag;
1200 if (!getintintarg(args, &index, &flag))
1201 return NULL;
1202 wmenucheck(self->m_menu, index, flag);
1203 INCREF(None);
1204 return None;
1205}
1206
1207static struct methodlist menu_methods[] = {
1208 "additem", menu_additem,
1209 "setitem", menu_setitem,
1210 "enable", menu_enable,
1211 "check", menu_check,
1212 {NULL, NULL} /* sentinel */
1213};
1214
1215static object *
1216menu_getattr(mp, name)
1217 menuobject *mp;
1218 char *name;
1219{
1220 if (mp->m_attr != NULL) {
1221 object *v = dictlookup(mp->m_attr, name);
1222 if (v != NULL) {
1223 INCREF(v);
1224 return v;
1225 }
1226 }
1227 return findmethod(menu_methods, (object *)mp, name);
1228}
1229
1230static int
1231menu_setattr(mp, name, v)
1232 menuobject *mp;
1233 char *name;
1234 object *v;
1235{
1236 if (mp->m_attr == NULL) {
1237 mp->m_attr = newdictobject();
1238 if (mp->m_attr == NULL)
1239 return -1;
1240 }
1241 if (v == NULL)
1242 return dictremove(mp->m_attr, name);
1243 else
1244 return dictinsert(mp->m_attr, name, v);
1245}
1246
Guido van Rossum541c8c01991-05-05 20:13:41 +00001247typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001248 OB_HEAD_INIT(&Typetype)
1249 0, /*ob_size*/
1250 "menu", /*tp_name*/
1251 sizeof(menuobject), /*tp_size*/
1252 0, /*tp_itemsize*/
1253 /* methods */
1254 menu_dealloc, /*tp_dealloc*/
1255 0, /*tp_print*/
1256 menu_getattr, /*tp_getattr*/
1257 menu_setattr, /*tp_setattr*/
1258 0, /*tp_compare*/
1259 0, /*tp_repr*/
1260};
1261
1262
1263/* Windows */
1264
1265#define MAXNWIN 50
1266static windowobject *windowlist[MAXNWIN];
1267
1268/* Window methods */
1269
1270static void
1271window_dealloc(wp)
1272 windowobject *wp;
1273{
1274 if (wp->w_win != NULL) {
1275 int tag = wgettag(wp->w_win);
1276 if (tag >= 0 && tag < MAXNWIN)
1277 windowlist[tag] = NULL;
1278 else
1279 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1280 tag);
1281 wclose(wp->w_win);
1282 }
1283 DECREF(wp->w_title);
1284 if (wp->w_attr != NULL)
1285 DECREF(wp->w_attr);
1286 free((char *)wp);
1287}
1288
1289static void
1290window_print(wp, fp, flags)
1291 windowobject *wp;
1292 FILE *fp;
1293 int flags;
1294{
1295 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1296}
1297
1298static object *
1299window_begindrawing(wp, args)
1300 windowobject *wp;
1301 object *args;
1302{
1303 drawingobject *dp;
1304 if (!getnoarg(args))
1305 return NULL;
1306 if (Drawing != NULL) {
1307 err_setstr(RuntimeError, "already drawing");
1308 return NULL;
1309 }
1310 dp = NEWOBJ(drawingobject, &Drawingtype);
1311 if (dp == NULL)
1312 return NULL;
1313 Drawing = dp;
1314 INCREF(wp);
1315 dp->d_ref = wp;
1316 wbegindrawing(wp->w_win);
1317 return (object *)dp;
1318}
1319
1320static object *
1321window_change(wp, args)
1322 windowobject *wp;
1323 object *args;
1324{
1325 int a[4];
1326 if (!getrectarg(args, a))
1327 return NULL;
1328 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1329 INCREF(None);
1330 return None;
1331}
1332
1333static object *
1334window_gettitle(wp, args)
1335 windowobject *wp;
1336 object *args;
1337{
1338 if (!getnoarg(args))
1339 return NULL;
1340 INCREF(wp->w_title);
1341 return wp->w_title;
1342}
1343
1344static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001345window_getwinpos(wp, args)
1346 windowobject *wp;
1347 object *args;
1348{
1349 int h, v;
1350 if (!getnoarg(args))
1351 return NULL;
1352 wgetwinpos(wp->w_win, &h, &v);
1353 return makepoint(h, v);
1354}
1355
1356static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357window_getwinsize(wp, args)
1358 windowobject *wp;
1359 object *args;
1360{
1361 int width, height;
1362 if (!getnoarg(args))
1363 return NULL;
1364 wgetwinsize(wp->w_win, &width, &height);
1365 return makepoint(width, height);
1366}
1367
1368static object *
1369window_getdocsize(wp, args)
1370 windowobject *wp;
1371 object *args;
1372{
1373 int width, height;
1374 if (!getnoarg(args))
1375 return NULL;
1376 wgetdocsize(wp->w_win, &width, &height);
1377 return makepoint(width, height);
1378}
1379
1380static object *
1381window_getorigin(wp, args)
1382 windowobject *wp;
1383 object *args;
1384{
1385 int width, height;
1386 if (!getnoarg(args))
1387 return NULL;
1388 wgetorigin(wp->w_win, &width, &height);
1389 return makepoint(width, height);
1390}
1391
1392static object *
1393window_scroll(wp, args)
1394 windowobject *wp;
1395 object *args;
1396{
1397 int a[6];
1398 if (!getrectpointarg(args, a))
1399 return NULL;
1400 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1401 INCREF(None);
1402 return None;
1403}
1404
1405static object *
1406window_setdocsize(wp, args)
1407 windowobject *wp;
1408 object *args;
1409{
1410 int a[2];
1411 if (!getpointarg(args, a))
1412 return NULL;
1413 wsetdocsize(wp->w_win, a[0], a[1]);
1414 INCREF(None);
1415 return None;
1416}
1417
1418static object *
1419window_setorigin(wp, args)
1420 windowobject *wp;
1421 object *args;
1422{
1423 int a[2];
1424 if (!getpointarg(args, a))
1425 return NULL;
1426 wsetorigin(wp->w_win, a[0], a[1]);
1427 INCREF(None);
1428 return None;
1429}
1430
1431static object *
1432window_settitle(wp, args)
1433 windowobject *wp;
1434 object *args;
1435{
1436 object *title;
1437 if (!getstrarg(args, &title))
1438 return NULL;
1439 DECREF(wp->w_title);
1440 INCREF(title);
1441 wp->w_title = title;
1442 wsettitle(wp->w_win, getstringvalue(title));
1443 INCREF(None);
1444 return None;
1445}
1446
1447static object *
1448window_show(wp, args)
1449 windowobject *wp;
1450 object *args;
1451{
1452 int a[4];
1453 if (!getrectarg(args, a))
1454 return NULL;
1455 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1456 INCREF(None);
1457 return None;
1458}
1459
1460static object *
1461window_settimer(wp, args)
1462 windowobject *wp;
1463 object *args;
1464{
1465 int a;
1466 if (!getintarg(args, &a))
1467 return NULL;
1468 wsettimer(wp->w_win, a);
1469 INCREF(None);
1470 return None;
1471}
1472
1473static object *
1474window_menucreate(self, args)
1475 windowobject *self;
1476 object *args;
1477{
1478 menuobject *mp;
1479 object *title;
1480 if (!getstrarg(args, &title))
1481 return NULL;
1482 wmenusetdeflocal(1);
1483 mp = newmenuobject(title);
1484 if (mp == NULL)
1485 return NULL;
1486 wmenuattach(self->w_win, mp->m_menu);
1487 return (object *)mp;
1488}
1489
1490static object *
1491window_textcreate(self, args)
1492 windowobject *self;
1493 object *args;
1494{
1495 textobject *tp;
1496 int a[4];
1497 if (!getrectarg(args, a))
1498 return NULL;
1499 return (object *)
1500 newtextobject(self, a[0], a[1], a[2], a[3]);
1501}
1502
Guido van Rossum5b10f451990-10-30 16:01:48 +00001503static object *
1504window_setselection(self, args)
1505 windowobject *self;
1506 object *args;
1507{
1508 int sel;
1509 object *str;
1510 int ok;
1511 if (!getintstrarg(args, &sel, &str))
1512 return NULL;
1513 ok = wsetselection(self->w_win, sel,
1514 getstringvalue(str), (int)getstringsize(str));
1515 return newintobject(ok);
1516}
1517
1518static object *
1519window_setwincursor(self, args)
1520 windowobject *self;
1521 object *args;
1522{
1523 object *str;
1524 CURSOR *c;
1525 if (!getstrarg(args, &str))
1526 return NULL;
1527 c = wfetchcursor(getstringvalue(str));
1528 if (c == NULL) {
1529 err_setstr(RuntimeError, "no such cursor");
1530 return NULL;
1531 }
1532 wsetwincursor(self->w_win, c);
1533 INCREF(None);
1534 return None;
1535}
1536
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001537static struct methodlist window_methods[] = {
1538 {"begindrawing",window_begindrawing},
1539 {"change", window_change},
1540 {"getdocsize", window_getdocsize},
1541 {"getorigin", window_getorigin},
1542 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001543 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001544 {"getwinsize", window_getwinsize},
1545 {"menucreate", window_menucreate},
1546 {"scroll", window_scroll},
1547 {"setdocsize", window_setdocsize},
1548 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001549 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001550 {"settimer", window_settimer},
1551 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001552 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001553 {"show", window_show},
1554 {"textcreate", window_textcreate},
1555 {NULL, NULL} /* sentinel */
1556};
1557
1558static object *
1559window_getattr(wp, name)
1560 windowobject *wp;
1561 char *name;
1562{
1563 if (wp->w_attr != NULL) {
1564 object *v = dictlookup(wp->w_attr, name);
1565 if (v != NULL) {
1566 INCREF(v);
1567 return v;
1568 }
1569 }
1570 return findmethod(window_methods, (object *)wp, name);
1571}
1572
1573static int
1574window_setattr(wp, name, v)
1575 windowobject *wp;
1576 char *name;
1577 object *v;
1578{
1579 if (wp->w_attr == NULL) {
1580 wp->w_attr = newdictobject();
1581 if (wp->w_attr == NULL)
1582 return -1;
1583 }
1584 if (v == NULL)
1585 return dictremove(wp->w_attr, name);
1586 else
1587 return dictinsert(wp->w_attr, name, v);
1588}
1589
Guido van Rossum541c8c01991-05-05 20:13:41 +00001590typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591 OB_HEAD_INIT(&Typetype)
1592 0, /*ob_size*/
1593 "window", /*tp_name*/
1594 sizeof(windowobject), /*tp_size*/
1595 0, /*tp_itemsize*/
1596 /* methods */
1597 window_dealloc, /*tp_dealloc*/
1598 window_print, /*tp_print*/
1599 window_getattr, /*tp_getattr*/
1600 window_setattr, /*tp_setattr*/
1601 0, /*tp_compare*/
1602 0, /*tp_repr*/
1603};
1604
1605/* Stdwin methods */
1606
1607static object *
1608stdwin_open(sw, args)
1609 object *sw;
1610 object *args;
1611{
1612 int tag;
1613 object *title;
1614 windowobject *wp;
1615 if (!getstrarg(args, &title))
1616 return NULL;
1617 for (tag = 0; tag < MAXNWIN; tag++) {
1618 if (windowlist[tag] == NULL)
1619 break;
1620 }
Guido van Rossum27201061991-04-16 08:43:03 +00001621 if (tag >= MAXNWIN) {
1622 err_setstr(MemoryError, "creating too many windows");
1623 return NULL;
1624 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625 wp = NEWOBJ(windowobject, &Windowtype);
1626 if (wp == NULL)
1627 return NULL;
1628 INCREF(title);
1629 wp->w_title = title;
1630 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1631 wp->w_attr = NULL;
1632 if (wp->w_win == NULL) {
1633 DECREF(wp);
1634 return NULL;
1635 }
1636 windowlist[tag] = wp;
1637 wsettag(wp->w_win, tag);
1638 return (object *)wp;
1639}
1640
1641static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001642window2object(win)
1643 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001644{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001645 object *w;
1646 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647 w = None;
1648 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001649 int tag = wgettag(win);
1650 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1651 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001652 w = None;
1653 else
1654 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001655#ifdef sgi
1656 /* XXX Trap for unexplained weird bug */
1657 if ((long)w == (long)0x80000001) {
1658 err_setstr(SystemError,
1659 "bad pointer in stdwin.getevent()");
1660 return NULL;
1661 }
1662#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001663 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001665 return w;
1666}
1667
1668static object *
1669stdwin_get_poll_event(poll, args)
1670 int poll;
1671 object *args;
1672{
1673 EVENT e;
1674 object *v, *w;
1675 if (!getnoarg(args))
1676 return NULL;
1677 if (Drawing != NULL) {
1678 err_setstr(RuntimeError, "cannot getevent() while drawing");
1679 return NULL;
1680 }
1681 again:
1682 if (poll) {
1683 if (!wpollevent(&e)) {
1684 INCREF(None);
1685 return None;
1686 }
1687 }
1688 else
1689 wgetevent(&e);
1690 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1691 /* Turn keyboard interrupts into exceptions */
1692 err_set(KeyboardInterrupt);
1693 return NULL;
1694 }
1695 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1696 /* Turn WC_CLOSE commands into WE_CLOSE events */
1697 e.type = WE_CLOSE;
1698 }
1699 v = newtupleobject(3);
1700 if (v == NULL)
1701 return NULL;
1702 if ((w = newintobject((long)e.type)) == NULL) {
1703 DECREF(v);
1704 return NULL;
1705 }
1706 settupleitem(v, 0, w);
1707 settupleitem(v, 1, window2object(e.window));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001708 switch (e.type) {
1709 case WE_CHAR:
1710 {
1711 char c[1];
1712 c[0] = e.u.character;
1713 w = newsizedstringobject(c, 1);
1714 }
1715 break;
1716 case WE_COMMAND:
1717 w = newintobject((long)e.u.command);
1718 break;
1719 case WE_DRAW:
1720 w = makerect(e.u.area.left, e.u.area.top,
1721 e.u.area.right, e.u.area.bottom);
1722 break;
1723 case WE_MOUSE_DOWN:
1724 case WE_MOUSE_MOVE:
1725 case WE_MOUSE_UP:
1726 w = makemouse(e.u.where.h, e.u.where.v,
1727 e.u.where.clicks,
1728 e.u.where.button,
1729 e.u.where.mask);
1730 break;
1731 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001732 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1733 menulist[e.u.m.id - IDOFFSET] != NULL)
1734 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum246b9d81991-06-03 10:55:14 +00001735 else {
1736 /* Ghost menu event.
1737 Can occur only on the Mac if another part
1738 of the aplication has installed a menu;
1739 like the THINK C console library. */
1740 DECREF(v);
1741 goto again;
1742 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001743 w = makemenu(w, e.u.m.item);
1744 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001745 case WE_LOST_SEL:
1746 w = newintobject((long)e.u.sel);
1747 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748 default:
1749 w = None;
1750 INCREF(w);
1751 break;
1752 }
1753 if (w == NULL) {
1754 DECREF(v);
1755 return NULL;
1756 }
1757 settupleitem(v, 2, w);
1758 return v;
1759}
1760
1761static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001762stdwin_getevent(sw, args)
1763 object *sw;
1764 object *args;
1765{
1766 return stdwin_get_poll_event(0, args);
1767}
1768
1769static object *
1770stdwin_pollevent(sw, args)
1771 object *sw;
1772 object *args;
1773{
1774 return stdwin_get_poll_event(1, args);
1775}
1776
1777static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001778stdwin_setdefwinpos(sw, args)
1779 object *sw;
1780 object *args;
1781{
1782 int a[2];
1783 if (!getpointarg(args, a))
1784 return NULL;
1785 wsetdefwinpos(a[0], a[1]);
1786 INCREF(None);
1787 return None;
1788}
1789
1790static object *
1791stdwin_setdefwinsize(sw, args)
1792 object *sw;
1793 object *args;
1794{
1795 int a[2];
1796 if (!getpointarg(args, a))
1797 return NULL;
1798 wsetdefwinsize(a[0], a[1]);
1799 INCREF(None);
1800 return None;
1801}
1802
1803static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001804stdwin_setdefscrollbars(sw, args)
1805 object *sw;
1806 object *args;
1807{
1808 int a[2];
1809 if (!getpointarg(args, a))
1810 return NULL;
1811 wsetdefscrollbars(a[0], a[1]);
1812 INCREF(None);
1813 return None;
1814}
1815
1816static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001817stdwin_getdefwinpos(self, args)
1818 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001819 object *args;
1820{
1821 int h, v;
1822 if (!getnoarg(args))
1823 return NULL;
1824 wgetdefwinpos(&h, &v);
1825 return makepoint(h, v);
1826}
1827
1828static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001829stdwin_getdefwinsize(self, args)
1830 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001831 object *args;
1832{
1833 int width, height;
1834 if (!getnoarg(args))
1835 return NULL;
1836 wgetdefwinsize(&width, &height);
1837 return makepoint(width, height);
1838}
1839
1840static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001841stdwin_getdefscrollbars(self, args)
1842 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001843 object *args;
1844{
1845 int h, v;
1846 if (!getnoarg(args))
1847 return NULL;
1848 wgetdefscrollbars(&h, &v);
1849 return makepoint(h, v);
1850}
1851
1852static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001853stdwin_menucreate(self, args)
1854 object *self;
1855 object *args;
1856{
1857 object *title;
1858 if (!getstrarg(args, &title))
1859 return NULL;
1860 wmenusetdeflocal(0);
1861 return (object *)newmenuobject(title);
1862}
1863
1864static object *
1865stdwin_askfile(self, args)
1866 object *self;
1867 object *args;
1868{
1869 object *prompt, *dflt;
1870 int new, ret;
1871 char buf[256];
1872 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1873 return NULL;
1874 strncpy(buf, getstringvalue(dflt), sizeof buf);
1875 buf[sizeof buf - 1] = '\0';
1876 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1877 if (!ret) {
1878 err_set(KeyboardInterrupt);
1879 return NULL;
1880 }
1881 return newstringobject(buf);
1882}
1883
1884static object *
1885stdwin_askync(self, args)
1886 object *self;
1887 object *args;
1888{
1889 object *prompt;
1890 int new, ret;
1891 if (!getstrintarg(args, &prompt, &new))
1892 return NULL;
1893 ret = waskync(getstringvalue(prompt), new);
1894 if (ret < 0) {
1895 err_set(KeyboardInterrupt);
1896 return NULL;
1897 }
1898 return newintobject((long)ret);
1899}
1900
1901static object *
1902stdwin_askstr(self, args)
1903 object *self;
1904 object *args;
1905{
1906 object *prompt, *dflt;
1907 int ret;
1908 char buf[256];
1909 if (!getstrstrarg(args, &prompt, &dflt))
1910 return NULL;
1911 strncpy(buf, getstringvalue(dflt), sizeof buf);
1912 buf[sizeof buf - 1] = '\0';
1913 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1914 if (!ret) {
1915 err_set(KeyboardInterrupt);
1916 return NULL;
1917 }
1918 return newstringobject(buf);
1919}
1920
1921static object *
1922stdwin_message(self, args)
1923 object *self;
1924 object *args;
1925{
1926 object *msg;
1927 if (!getstrarg(args, &msg))
1928 return NULL;
1929 wmessage(getstringvalue(msg));
1930 INCREF(None);
1931 return None;
1932}
1933
1934static object *
1935stdwin_fleep(self, args)
1936 object *self;
1937 object *args;
1938{
1939 if (!getnoarg(args))
1940 return NULL;
1941 wfleep();
1942 INCREF(None);
1943 return None;
1944}
1945
1946static object *
1947stdwin_setcutbuffer(self, args)
1948 object *self;
1949 object *args;
1950{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001951 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001952 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001953 if (!getintstrarg(args, &i, &str))
1954 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001955 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001956 INCREF(None);
1957 return None;
1958}
1959
1960static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001961stdwin_getactive(self, args)
1962 object *self;
1963 object *args;
1964{
1965 return window2object(wgetactive());
1966}
1967
1968static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001969stdwin_getcutbuffer(self, args)
1970 object *self;
1971 object *args;
1972{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001973 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001975 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001976 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001977 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001978 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001979 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001980 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001981 len = 0;
1982 }
1983 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984}
1985
Guido van Rossum5b10f451990-10-30 16:01:48 +00001986static object *
1987stdwin_rotatecutbuffers(self, args)
1988 object *self;
1989 object *args;
1990{
1991 int i;
1992 if (!getintarg(args, &i))
1993 return NULL;
1994 wrotatecutbuffers(i);
1995 INCREF(None);
1996 return None;
1997}
1998
1999static object *
2000stdwin_getselection(self, args)
2001 object *self;
2002 object *args;
2003{
2004 int sel;
2005 char *data;
2006 int len;
2007 if (!getintarg(args, &sel))
2008 return NULL;
2009 data = wgetselection(sel, &len);
2010 if (data == NULL) {
2011 data = "";
2012 len = 0;
2013 }
2014 return newsizedstringobject(data, len);
2015}
2016
2017static object *
2018stdwin_resetselection(self, args)
2019 object *self;
2020 object *args;
2021{
2022 int sel;
2023 if (!getintarg(args, &sel))
2024 return NULL;
2025 wresetselection(sel);
2026 INCREF(None);
2027 return None;
2028}
2029
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002030static object *
2031stdwin_fetchcolor(self, args)
2032 object *self;
2033 object *args;
2034{
2035 object *colorname;
2036 if (!getstrarg(args, &colorname))
2037 return NULL;
2038 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
2039}
2040
Guido van Rossum541c8c01991-05-05 20:13:41 +00002041static object *
2042stdwin_getscrsize(self, args)
2043 object *self;
2044 object *args;
2045{
2046 int width, height;
2047 if (!getnoarg(args))
2048 return NULL;
2049 wgetscrsize(&width, &height);
2050 return makepoint(width, height);
2051}
2052
2053static object *
2054stdwin_getscrmm(self, args)
2055 object *self;
2056 object *args;
2057{
2058 int width, height;
2059 if (!getnoarg(args))
2060 return NULL;
2061 wgetscrmm(&width, &height);
2062 return makepoint(width, height);
2063}
2064
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002065static struct methodlist stdwin_methods[] = {
2066 {"askfile", stdwin_askfile},
2067 {"askstr", stdwin_askstr},
2068 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002069 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002070 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002071 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002072 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002073 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002074 {"getdefwinpos", stdwin_getdefwinpos},
2075 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002076 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002077 {"getscrmm", stdwin_getscrmm},
2078 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002079 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002080 {"menucreate", stdwin_menucreate},
2081 {"message", stdwin_message},
2082 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002083 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002084 {"resetselection", stdwin_resetselection},
2085 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002086 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002087 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002088 {"setdefwinpos", stdwin_setdefwinpos},
2089 {"setdefwinsize", stdwin_setdefwinsize},
2090
2091 /* Text measuring methods borrow code from drawing objects: */
2092 {"baseline", drawing_baseline},
2093 {"lineheight", drawing_lineheight},
2094 {"textbreak", drawing_textbreak},
2095 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002096
2097 /* Same for font setting methods: */
2098 {"setfont", drawing_setfont},
2099
2100 /* Same for color setting/getting methods: */
2101 {"getbgcolor", drawing_getbgcolor},
2102 {"getfgcolor", drawing_getfgcolor},
2103 {"setbgcolor", drawing_setbgcolor},
2104 {"setfgcolor", drawing_setfgcolor},
2105
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106 {NULL, NULL} /* sentinel */
2107};
2108
2109void
2110initstdwin()
2111{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002112 static int inited;
2113 if (!inited) {
2114 winit();
2115 inited = 1;
2116 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002117 initmodule("stdwin", stdwin_methods);
2118}