blob: 32f5f2272d5c61e87bc16c0a84424d4c3d8d67d6 [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 }
631 if (getstringsize(font) != 0)
632 wsetfont(getstringvalue(font));
633 if (style != NULL) {
634 switch (*getstringvalue(style)) {
635 case 'b':
636 wsetbold();
637 break;
638 case 'i':
639 wsetitalic();
640 break;
641 case 'o':
642 wsetbolditalic();
643 break;
644 case 'u':
645 wsetunderline();
646 break;
647 default:
648 wsetplain();
649 break;
650 }
651 }
652 if (size != 0)
653 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000654 INCREF(None);
655 return None;
656}
657
658static object *
659drawing_getbgcolor(self, args)
660 object *self;
661 object *args;
662{
663 if (!getnoarg(args))
664 return NULL;
665 return newintobject((long)wgetbgcolor());
666}
667
668static object *
669drawing_getfgcolor(self, args)
670 object *self;
671 object *args;
672{
673 if (!getnoarg(args))
674 return NULL;
675 return newintobject((long)wgetfgcolor());
676}
677
678static object *
679drawing_setbgcolor(self, args)
680 object *self;
681 object *args;
682{
683 long color;
684 if (!getlongarg(args, &color))
685 return NULL;
686 wsetbgcolor((COLOR)color);
687 INCREF(None);
688 return None;
689}
690
691static object *
692drawing_setfgcolor(self, args)
693 object *self;
694 object *args;
695{
696 long color;
697 if (!getlongarg(args, &color))
698 return NULL;
699 wsetfgcolor((COLOR)color);
700 INCREF(None);
701 return None;
702}
703
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704static struct methodlist drawing_methods[] = {
705 {"box", drawing_box},
706 {"circle", drawing_circle},
707 {"cliprect", drawing_cliprect},
708 {"elarc", drawing_elarc},
709 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000710 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000711 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000712 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713 {"invert", drawing_invert},
714 {"line", drawing_line},
715 {"noclip", drawing_noclip},
716 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000717 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000718 {"shade", drawing_shade},
719 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000720 {"xorcircle", drawing_xorcircle},
721 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000723 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724
725 /* Text measuring methods: */
726 {"baseline", drawing_baseline},
727 {"lineheight", drawing_lineheight},
728 {"textbreak", drawing_textbreak},
729 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000730
731 /* Font setting methods: */
732 {"setfont", drawing_setfont},
733
734 /* Color methods: */
735 {"getbgcolor", drawing_getbgcolor},
736 {"getfgcolor", drawing_getfgcolor},
737 {"setbgcolor", drawing_setbgcolor},
738 {"setfgcolor", drawing_setfgcolor},
739
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 {NULL, NULL} /* sentinel */
741};
742
743static object *
744drawing_getattr(wp, name)
745 drawingobject *wp;
746 char *name;
747{
748 return findmethod(drawing_methods, (object *)wp, name);
749}
750
Guido van Rossum541c8c01991-05-05 20:13:41 +0000751typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000752 OB_HEAD_INIT(&Typetype)
753 0, /*ob_size*/
754 "drawing", /*tp_name*/
755 sizeof(drawingobject), /*tp_size*/
756 0, /*tp_itemsize*/
757 /* methods */
758 drawing_dealloc, /*tp_dealloc*/
759 0, /*tp_print*/
760 drawing_getattr, /*tp_getattr*/
761 0, /*tp_setattr*/
762 0, /*tp_compare*/
763 0, /*tp_repr*/
764};
765
766
767/* Text(edit) objects */
768
769typedef struct {
770 OB_HEAD
771 TEXTEDIT *t_text;
772 windowobject *t_ref;
773 object *t_attr; /* Attributes dictionary */
774} textobject;
775
776extern typeobject Texttype; /* Really static, forward */
777
778static textobject *
779newtextobject(wp, left, top, right, bottom)
780 windowobject *wp;
781 int left, top, right, bottom;
782{
783 textobject *tp;
784 tp = NEWOBJ(textobject, &Texttype);
785 if (tp == NULL)
786 return NULL;
787 tp->t_attr = NULL;
788 INCREF(wp);
789 tp->t_ref = wp;
790 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
791 if (tp->t_text == NULL) {
792 DECREF(tp);
793 return (textobject *) err_nomem();
794 }
795 return tp;
796}
797
798/* Text(edit) methods */
799
800static void
801text_dealloc(tp)
802 textobject *tp;
803{
804 if (tp->t_text != NULL)
805 tefree(tp->t_text);
806 if (tp->t_attr != NULL)
807 DECREF(tp->t_attr);
808 DECREF(tp->t_ref);
809 DEL(tp);
810}
811
812static object *
813text_arrow(self, args)
814 textobject *self;
815 object *args;
816{
817 int code;
818 if (!getintarg(args, &code))
819 return NULL;
820 tearrow(self->t_text, code);
821 INCREF(None);
822 return None;
823}
824
825static object *
826text_draw(self, args)
827 textobject *self;
828 object *args;
829{
830 register TEXTEDIT *tp = self->t_text;
831 int a[4];
832 int left, top, right, bottom;
833 if (!getrectarg(args, a))
834 return NULL;
835 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000836 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000837 return NULL;
838 }
839 /* Clip to text area and ignore if area is empty */
840 left = tegetleft(tp);
841 top = tegettop(tp);
842 right = tegetright(tp);
843 bottom = tegetbottom(tp);
844 if (a[0] < left) a[0] = left;
845 if (a[1] < top) a[1] = top;
846 if (a[2] > right) a[2] = right;
847 if (a[3] > bottom) a[3] = bottom;
848 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850 tedrawnew(tp, a[0], a[1], a[2], a[3]);
851 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852 }
853 INCREF(None);
854 return None;
855}
856
857static object *
858text_event(self, args)
859 textobject *self;
860 object *args;
861{
862 register TEXTEDIT *tp = self->t_text;
863 EVENT e;
864 if (!geteventarg(args, &e))
865 return NULL;
866 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000867 /* Cheat at the margins */
868 int width, height;
869 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000870 if (e.u.where.h < 0 && tegetleft(tp) == 0)
871 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000872 else if (e.u.where.h > width && tegetright(tp) == width)
873 e.u.where.h = width;
874 if (e.u.where.v < 0 && tegettop(tp) == 0)
875 e.u.where.v = 0;
876 else if (e.u.where.v > height && tegetright(tp) == height)
877 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878 }
879 return newintobject((long) teevent(tp, &e));
880}
881
882static object *
883text_getfocus(self, args)
884 textobject *self;
885 object *args;
886{
887 if (!getnoarg(args))
888 return NULL;
889 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
890}
891
892static object *
893text_getfocustext(self, args)
894 textobject *self;
895 object *args;
896{
897 int f1, f2;
898 char *text;
899 if (!getnoarg(args))
900 return NULL;
901 f1 = tegetfoc1(self->t_text);
902 f2 = tegetfoc2(self->t_text);
903 text = tegettext(self->t_text);
904 return newsizedstringobject(text + f1, f2-f1);
905}
906
907static object *
908text_getrect(self, args)
909 textobject *self;
910 object *args;
911{
912 if (!getnoarg(args))
913 return NULL;
914 return makerect(tegetleft(self->t_text),
915 tegettop(self->t_text),
916 tegetright(self->t_text),
917 tegetbottom(self->t_text));
918}
919
920static object *
921text_gettext(self, args)
922 textobject *self;
923 object *args;
924{
925 if (!getnoarg(args))
926 return NULL;
927 return newsizedstringobject(tegettext(self->t_text),
928 tegetlen(self->t_text));
929}
930
931static object *
932text_move(self, args)
933 textobject *self;
934 object *args;
935{
936 int a[4];
937 if (!getrectarg(args, a))
938 return NULL;
939 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
940 INCREF(None);
941 return None;
942}
943
944static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000945text_replace(self, args)
946 textobject *self;
947 object *args;
948{
949 object *text;
950 if (!getstrarg(args, &text))
951 return NULL;
952 tereplace(self->t_text, getstringvalue(text));
953 INCREF(None);
954 return None;
955}
956
957static object *
958text_setactive(self, args)
959 textobject *self;
960 object *args;
961{
962 int flag;
963 if (!getintarg(args, &flag))
964 return NULL;
965 tesetactive(self->t_text, flag);
966 INCREF(None);
967 return None;
968}
969
970static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971text_setfocus(self, args)
972 textobject *self;
973 object *args;
974{
975 int a[2];
976 if (!getpointarg(args, a))
977 return NULL;
978 tesetfocus(self->t_text, a[0], a[1]);
979 INCREF(None);
980 return None;
981}
982
983static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000984text_settext(self, args)
985 textobject *self;
986 object *args;
987{
988 object *text;
989 char *buf;
990 int size;
991 if (!getstrarg(args, &text))
992 return NULL;
993 size = getstringsize(text);
994 if ((buf = NEW(char, size)) == NULL) {
995 err_set(MemoryError);
996 return NULL;
997 }
998 memcpy(buf, getstringvalue(text), size);
999 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1000 INCREF(None);
1001 return None;
1002}
1003
1004static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001005text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001006 textobject *self;
1007 object *args;
1008{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001009 int a[4];
1010 if (args == None)
1011 tenoview(self->t_text);
1012 else {
1013 if (!getrectarg(args, a))
1014 return NULL;
1015 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1016 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017 INCREF(None);
1018 return None;
1019}
1020
1021static struct methodlist text_methods[] = {
1022 "arrow", text_arrow,
1023 "draw", text_draw,
1024 "event", text_event,
1025 "getfocus", text_getfocus,
1026 "getfocustext", text_getfocustext,
1027 "getrect", text_getrect,
1028 "gettext", text_gettext,
1029 "move", text_move,
1030 "replace", text_replace,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001031 "setactive", text_setactive,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001032 "setfocus", text_setfocus,
Guido van Rossum541c8c01991-05-05 20:13:41 +00001033 "settext", text_settext,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001034 "setview", text_setview,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035 {NULL, NULL} /* sentinel */
1036};
1037
1038static object *
1039text_getattr(tp, name)
1040 textobject *tp;
1041 char *name;
1042{
1043 if (tp->t_attr != NULL) {
1044 object *v = dictlookup(tp->t_attr, name);
1045 if (v != NULL) {
1046 INCREF(v);
1047 return v;
1048 }
1049 }
1050 return findmethod(text_methods, (object *)tp, name);
1051}
1052
1053static int
1054text_setattr(tp, name, v)
1055 textobject *tp;
1056 char *name;
1057 object *v;
1058{
1059 if (tp->t_attr == NULL) {
1060 tp->t_attr = newdictobject();
1061 if (tp->t_attr == NULL)
1062 return -1;
1063 }
1064 if (v == NULL)
1065 return dictremove(tp->t_attr, name);
1066 else
1067 return dictinsert(tp->t_attr, name, v);
1068}
1069
Guido van Rossum541c8c01991-05-05 20:13:41 +00001070typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001071 OB_HEAD_INIT(&Typetype)
1072 0, /*ob_size*/
1073 "textedit", /*tp_name*/
1074 sizeof(textobject), /*tp_size*/
1075 0, /*tp_itemsize*/
1076 /* methods */
1077 text_dealloc, /*tp_dealloc*/
1078 0, /*tp_print*/
1079 text_getattr, /*tp_getattr*/
1080 text_setattr, /*tp_setattr*/
1081 0, /*tp_compare*/
1082 0, /*tp_repr*/
1083};
1084
1085
1086/* Menu objects */
1087
Guido van Rossum2d14e211991-02-19 12:26:49 +00001088#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001089#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001090static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001091
1092static menuobject *
1093newmenuobject(title)
1094 object *title;
1095{
1096 int id;
1097 MENU *menu;
1098 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001099 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001100 if (menulist[id] == NULL)
1101 break;
1102 }
Guido van Rossum27201061991-04-16 08:43:03 +00001103 if (id >= MAXNMENU) {
1104 err_setstr(MemoryError, "creating too many menus");
1105 return NULL;
1106 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001107 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108 if (menu == NULL)
1109 return (menuobject *) err_nomem();
1110 mp = NEWOBJ(menuobject, &Menutype);
1111 if (mp != NULL) {
1112 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001113 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114 mp->m_attr = NULL;
1115 menulist[id] = mp;
1116 }
1117 else
1118 wmenudelete(menu);
1119 return mp;
1120}
1121
1122/* Menu methods */
1123
1124static void
1125menu_dealloc(mp)
1126 menuobject *mp;
1127{
1128
Guido van Rossum2d14e211991-02-19 12:26:49 +00001129 int id = mp->m_id - IDOFFSET;
1130 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131 menulist[id] = NULL;
1132 }
1133 wmenudelete(mp->m_menu);
1134 if (mp->m_attr != NULL)
1135 DECREF(mp->m_attr);
1136 DEL(mp);
1137}
1138
1139static object *
1140menu_additem(self, args)
1141 menuobject *self;
1142 object *args;
1143{
1144 object *text;
1145 int shortcut;
1146 if (is_tupleobject(args)) {
1147 object *v;
1148 if (!getstrstrarg(args, &text, &v))
1149 return NULL;
1150 if (getstringsize(v) != 1) {
1151 err_badarg();
1152 return NULL;
1153 }
1154 shortcut = *getstringvalue(v) & 0xff;
1155 }
1156 else {
1157 if (!getstrarg(args, &text))
1158 return NULL;
1159 shortcut = -1;
1160 }
1161 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1162 INCREF(None);
1163 return None;
1164}
1165
1166static object *
1167menu_setitem(self, args)
1168 menuobject *self;
1169 object *args;
1170{
1171 int index;
1172 object *text;
1173 if (!getintstrarg(args, &index, &text))
1174 return NULL;
1175 wmenusetitem(self->m_menu, index, getstringvalue(text));
1176 INCREF(None);
1177 return None;
1178}
1179
1180static object *
1181menu_enable(self, args)
1182 menuobject *self;
1183 object *args;
1184{
1185 int index;
1186 int flag;
1187 if (!getintintarg(args, &index, &flag))
1188 return NULL;
1189 wmenuenable(self->m_menu, index, flag);
1190 INCREF(None);
1191 return None;
1192}
1193
1194static object *
1195menu_check(self, args)
1196 menuobject *self;
1197 object *args;
1198{
1199 int index;
1200 int flag;
1201 if (!getintintarg(args, &index, &flag))
1202 return NULL;
1203 wmenucheck(self->m_menu, index, flag);
1204 INCREF(None);
1205 return None;
1206}
1207
1208static struct methodlist menu_methods[] = {
1209 "additem", menu_additem,
1210 "setitem", menu_setitem,
1211 "enable", menu_enable,
1212 "check", menu_check,
1213 {NULL, NULL} /* sentinel */
1214};
1215
1216static object *
1217menu_getattr(mp, name)
1218 menuobject *mp;
1219 char *name;
1220{
1221 if (mp->m_attr != NULL) {
1222 object *v = dictlookup(mp->m_attr, name);
1223 if (v != NULL) {
1224 INCREF(v);
1225 return v;
1226 }
1227 }
1228 return findmethod(menu_methods, (object *)mp, name);
1229}
1230
1231static int
1232menu_setattr(mp, name, v)
1233 menuobject *mp;
1234 char *name;
1235 object *v;
1236{
1237 if (mp->m_attr == NULL) {
1238 mp->m_attr = newdictobject();
1239 if (mp->m_attr == NULL)
1240 return -1;
1241 }
1242 if (v == NULL)
1243 return dictremove(mp->m_attr, name);
1244 else
1245 return dictinsert(mp->m_attr, name, v);
1246}
1247
Guido van Rossum541c8c01991-05-05 20:13:41 +00001248typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249 OB_HEAD_INIT(&Typetype)
1250 0, /*ob_size*/
1251 "menu", /*tp_name*/
1252 sizeof(menuobject), /*tp_size*/
1253 0, /*tp_itemsize*/
1254 /* methods */
1255 menu_dealloc, /*tp_dealloc*/
1256 0, /*tp_print*/
1257 menu_getattr, /*tp_getattr*/
1258 menu_setattr, /*tp_setattr*/
1259 0, /*tp_compare*/
1260 0, /*tp_repr*/
1261};
1262
1263
1264/* Windows */
1265
1266#define MAXNWIN 50
1267static windowobject *windowlist[MAXNWIN];
1268
1269/* Window methods */
1270
1271static void
1272window_dealloc(wp)
1273 windowobject *wp;
1274{
1275 if (wp->w_win != NULL) {
1276 int tag = wgettag(wp->w_win);
1277 if (tag >= 0 && tag < MAXNWIN)
1278 windowlist[tag] = NULL;
1279 else
1280 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1281 tag);
1282 wclose(wp->w_win);
1283 }
1284 DECREF(wp->w_title);
1285 if (wp->w_attr != NULL)
1286 DECREF(wp->w_attr);
1287 free((char *)wp);
1288}
1289
1290static void
1291window_print(wp, fp, flags)
1292 windowobject *wp;
1293 FILE *fp;
1294 int flags;
1295{
1296 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1297}
1298
1299static object *
1300window_begindrawing(wp, args)
1301 windowobject *wp;
1302 object *args;
1303{
1304 drawingobject *dp;
1305 if (!getnoarg(args))
1306 return NULL;
1307 if (Drawing != NULL) {
1308 err_setstr(RuntimeError, "already drawing");
1309 return NULL;
1310 }
1311 dp = NEWOBJ(drawingobject, &Drawingtype);
1312 if (dp == NULL)
1313 return NULL;
1314 Drawing = dp;
1315 INCREF(wp);
1316 dp->d_ref = wp;
1317 wbegindrawing(wp->w_win);
1318 return (object *)dp;
1319}
1320
1321static object *
1322window_change(wp, args)
1323 windowobject *wp;
1324 object *args;
1325{
1326 int a[4];
1327 if (!getrectarg(args, a))
1328 return NULL;
1329 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1330 INCREF(None);
1331 return None;
1332}
1333
1334static object *
1335window_gettitle(wp, args)
1336 windowobject *wp;
1337 object *args;
1338{
1339 if (!getnoarg(args))
1340 return NULL;
1341 INCREF(wp->w_title);
1342 return wp->w_title;
1343}
1344
1345static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001346window_getwinpos(wp, args)
1347 windowobject *wp;
1348 object *args;
1349{
1350 int h, v;
1351 if (!getnoarg(args))
1352 return NULL;
1353 wgetwinpos(wp->w_win, &h, &v);
1354 return makepoint(h, v);
1355}
1356
1357static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358window_getwinsize(wp, args)
1359 windowobject *wp;
1360 object *args;
1361{
1362 int width, height;
1363 if (!getnoarg(args))
1364 return NULL;
1365 wgetwinsize(wp->w_win, &width, &height);
1366 return makepoint(width, height);
1367}
1368
1369static object *
1370window_getdocsize(wp, args)
1371 windowobject *wp;
1372 object *args;
1373{
1374 int width, height;
1375 if (!getnoarg(args))
1376 return NULL;
1377 wgetdocsize(wp->w_win, &width, &height);
1378 return makepoint(width, height);
1379}
1380
1381static object *
1382window_getorigin(wp, args)
1383 windowobject *wp;
1384 object *args;
1385{
1386 int width, height;
1387 if (!getnoarg(args))
1388 return NULL;
1389 wgetorigin(wp->w_win, &width, &height);
1390 return makepoint(width, height);
1391}
1392
1393static object *
1394window_scroll(wp, args)
1395 windowobject *wp;
1396 object *args;
1397{
1398 int a[6];
1399 if (!getrectpointarg(args, a))
1400 return NULL;
1401 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1402 INCREF(None);
1403 return None;
1404}
1405
1406static object *
1407window_setdocsize(wp, args)
1408 windowobject *wp;
1409 object *args;
1410{
1411 int a[2];
1412 if (!getpointarg(args, a))
1413 return NULL;
1414 wsetdocsize(wp->w_win, a[0], a[1]);
1415 INCREF(None);
1416 return None;
1417}
1418
1419static object *
1420window_setorigin(wp, args)
1421 windowobject *wp;
1422 object *args;
1423{
1424 int a[2];
1425 if (!getpointarg(args, a))
1426 return NULL;
1427 wsetorigin(wp->w_win, a[0], a[1]);
1428 INCREF(None);
1429 return None;
1430}
1431
1432static object *
1433window_settitle(wp, args)
1434 windowobject *wp;
1435 object *args;
1436{
1437 object *title;
1438 if (!getstrarg(args, &title))
1439 return NULL;
1440 DECREF(wp->w_title);
1441 INCREF(title);
1442 wp->w_title = title;
1443 wsettitle(wp->w_win, getstringvalue(title));
1444 INCREF(None);
1445 return None;
1446}
1447
1448static object *
1449window_show(wp, args)
1450 windowobject *wp;
1451 object *args;
1452{
1453 int a[4];
1454 if (!getrectarg(args, a))
1455 return NULL;
1456 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1457 INCREF(None);
1458 return None;
1459}
1460
1461static object *
1462window_settimer(wp, args)
1463 windowobject *wp;
1464 object *args;
1465{
1466 int a;
1467 if (!getintarg(args, &a))
1468 return NULL;
1469 wsettimer(wp->w_win, a);
1470 INCREF(None);
1471 return None;
1472}
1473
1474static object *
1475window_menucreate(self, args)
1476 windowobject *self;
1477 object *args;
1478{
1479 menuobject *mp;
1480 object *title;
1481 if (!getstrarg(args, &title))
1482 return NULL;
1483 wmenusetdeflocal(1);
1484 mp = newmenuobject(title);
1485 if (mp == NULL)
1486 return NULL;
1487 wmenuattach(self->w_win, mp->m_menu);
1488 return (object *)mp;
1489}
1490
1491static object *
1492window_textcreate(self, args)
1493 windowobject *self;
1494 object *args;
1495{
1496 textobject *tp;
1497 int a[4];
1498 if (!getrectarg(args, a))
1499 return NULL;
1500 return (object *)
1501 newtextobject(self, a[0], a[1], a[2], a[3]);
1502}
1503
Guido van Rossum5b10f451990-10-30 16:01:48 +00001504static object *
1505window_setselection(self, args)
1506 windowobject *self;
1507 object *args;
1508{
1509 int sel;
1510 object *str;
1511 int ok;
1512 if (!getintstrarg(args, &sel, &str))
1513 return NULL;
1514 ok = wsetselection(self->w_win, sel,
1515 getstringvalue(str), (int)getstringsize(str));
1516 return newintobject(ok);
1517}
1518
1519static object *
1520window_setwincursor(self, args)
1521 windowobject *self;
1522 object *args;
1523{
1524 object *str;
1525 CURSOR *c;
1526 if (!getstrarg(args, &str))
1527 return NULL;
1528 c = wfetchcursor(getstringvalue(str));
1529 if (c == NULL) {
1530 err_setstr(RuntimeError, "no such cursor");
1531 return NULL;
1532 }
1533 wsetwincursor(self->w_win, c);
1534 INCREF(None);
1535 return None;
1536}
1537
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001538static struct methodlist window_methods[] = {
1539 {"begindrawing",window_begindrawing},
1540 {"change", window_change},
1541 {"getdocsize", window_getdocsize},
1542 {"getorigin", window_getorigin},
1543 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001544 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001545 {"getwinsize", window_getwinsize},
1546 {"menucreate", window_menucreate},
1547 {"scroll", window_scroll},
1548 {"setdocsize", window_setdocsize},
1549 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001550 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001551 {"settimer", window_settimer},
1552 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001553 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001554 {"show", window_show},
1555 {"textcreate", window_textcreate},
1556 {NULL, NULL} /* sentinel */
1557};
1558
1559static object *
1560window_getattr(wp, name)
1561 windowobject *wp;
1562 char *name;
1563{
1564 if (wp->w_attr != NULL) {
1565 object *v = dictlookup(wp->w_attr, name);
1566 if (v != NULL) {
1567 INCREF(v);
1568 return v;
1569 }
1570 }
1571 return findmethod(window_methods, (object *)wp, name);
1572}
1573
1574static int
1575window_setattr(wp, name, v)
1576 windowobject *wp;
1577 char *name;
1578 object *v;
1579{
1580 if (wp->w_attr == NULL) {
1581 wp->w_attr = newdictobject();
1582 if (wp->w_attr == NULL)
1583 return -1;
1584 }
1585 if (v == NULL)
1586 return dictremove(wp->w_attr, name);
1587 else
1588 return dictinsert(wp->w_attr, name, v);
1589}
1590
Guido van Rossum541c8c01991-05-05 20:13:41 +00001591typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001592 OB_HEAD_INIT(&Typetype)
1593 0, /*ob_size*/
1594 "window", /*tp_name*/
1595 sizeof(windowobject), /*tp_size*/
1596 0, /*tp_itemsize*/
1597 /* methods */
1598 window_dealloc, /*tp_dealloc*/
1599 window_print, /*tp_print*/
1600 window_getattr, /*tp_getattr*/
1601 window_setattr, /*tp_setattr*/
1602 0, /*tp_compare*/
1603 0, /*tp_repr*/
1604};
1605
1606/* Stdwin methods */
1607
1608static object *
1609stdwin_open(sw, args)
1610 object *sw;
1611 object *args;
1612{
1613 int tag;
1614 object *title;
1615 windowobject *wp;
1616 if (!getstrarg(args, &title))
1617 return NULL;
1618 for (tag = 0; tag < MAXNWIN; tag++) {
1619 if (windowlist[tag] == NULL)
1620 break;
1621 }
Guido van Rossum27201061991-04-16 08:43:03 +00001622 if (tag >= MAXNWIN) {
1623 err_setstr(MemoryError, "creating too many windows");
1624 return NULL;
1625 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001626 wp = NEWOBJ(windowobject, &Windowtype);
1627 if (wp == NULL)
1628 return NULL;
1629 INCREF(title);
1630 wp->w_title = title;
1631 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1632 wp->w_attr = NULL;
1633 if (wp->w_win == NULL) {
1634 DECREF(wp);
1635 return NULL;
1636 }
1637 windowlist[tag] = wp;
1638 wsettag(wp->w_win, tag);
1639 return (object *)wp;
1640}
1641
1642static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001643stdwin_get_poll_event(poll, args)
1644 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001645 object *args;
1646{
1647 EVENT e;
1648 object *v, *w;
1649 if (!getnoarg(args))
1650 return NULL;
1651 if (Drawing != NULL) {
1652 err_setstr(RuntimeError, "cannot getevent() while drawing");
1653 return NULL;
1654 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001655/* again: */
1656 if (poll) {
1657 if (!wpollevent(&e)) {
1658 INCREF(None);
1659 return None;
1660 }
1661 }
1662 else
1663 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1665 /* Turn keyboard interrupts into exceptions */
1666 err_set(KeyboardInterrupt);
1667 return NULL;
1668 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001669/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001670 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1671 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001672*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001673 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1674 /* Turn WC_CLOSE commands into WE_CLOSE events */
1675 e.type = WE_CLOSE;
1676 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001677 v = newtupleobject(3);
1678 if (v == NULL)
1679 return NULL;
1680 if ((w = newintobject((long)e.type)) == NULL) {
1681 DECREF(v);
1682 return NULL;
1683 }
1684 settupleitem(v, 0, w);
1685 if (e.window == NULL)
1686 w = None;
1687 else {
1688 int tag = wgettag(e.window);
1689 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1690 w = None;
1691 else
1692 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001693#ifdef sgi
1694 /* XXX Trap for unexplained weird bug */
1695 if ((long)w == (long)0x80000001) {
1696 err_setstr(SystemError,
1697 "bad pointer in stdwin.getevent()");
1698 return NULL;
1699 }
1700#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001701 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001702 INCREF(w);
1703 settupleitem(v, 1, w);
1704 switch (e.type) {
1705 case WE_CHAR:
1706 {
1707 char c[1];
1708 c[0] = e.u.character;
1709 w = newsizedstringobject(c, 1);
1710 }
1711 break;
1712 case WE_COMMAND:
1713 w = newintobject((long)e.u.command);
1714 break;
1715 case WE_DRAW:
1716 w = makerect(e.u.area.left, e.u.area.top,
1717 e.u.area.right, e.u.area.bottom);
1718 break;
1719 case WE_MOUSE_DOWN:
1720 case WE_MOUSE_MOVE:
1721 case WE_MOUSE_UP:
1722 w = makemouse(e.u.where.h, e.u.where.v,
1723 e.u.where.clicks,
1724 e.u.where.button,
1725 e.u.where.mask);
1726 break;
1727 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001728 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1729 menulist[e.u.m.id - IDOFFSET] != NULL)
1730 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001731 else
1732 w = None;
1733 w = makemenu(w, e.u.m.item);
1734 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001735 case WE_LOST_SEL:
1736 w = newintobject((long)e.u.sel);
1737 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001738 default:
1739 w = None;
1740 INCREF(w);
1741 break;
1742 }
1743 if (w == NULL) {
1744 DECREF(v);
1745 return NULL;
1746 }
1747 settupleitem(v, 2, w);
1748 return v;
1749}
1750
1751static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001752stdwin_getevent(sw, args)
1753 object *sw;
1754 object *args;
1755{
1756 return stdwin_get_poll_event(0, args);
1757}
1758
1759static object *
1760stdwin_pollevent(sw, args)
1761 object *sw;
1762 object *args;
1763{
1764 return stdwin_get_poll_event(1, args);
1765}
1766
1767static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768stdwin_setdefwinpos(sw, args)
1769 object *sw;
1770 object *args;
1771{
1772 int a[2];
1773 if (!getpointarg(args, a))
1774 return NULL;
1775 wsetdefwinpos(a[0], a[1]);
1776 INCREF(None);
1777 return None;
1778}
1779
1780static object *
1781stdwin_setdefwinsize(sw, args)
1782 object *sw;
1783 object *args;
1784{
1785 int a[2];
1786 if (!getpointarg(args, a))
1787 return NULL;
1788 wsetdefwinsize(a[0], a[1]);
1789 INCREF(None);
1790 return None;
1791}
1792
1793static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001794stdwin_setdefscrollbars(sw, args)
1795 object *sw;
1796 object *args;
1797{
1798 int a[2];
1799 if (!getpointarg(args, a))
1800 return NULL;
1801 wsetdefscrollbars(a[0], a[1]);
1802 INCREF(None);
1803 return None;
1804}
1805
1806static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001807stdwin_getdefwinpos(self, args)
1808 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001809 object *args;
1810{
1811 int h, v;
1812 if (!getnoarg(args))
1813 return NULL;
1814 wgetdefwinpos(&h, &v);
1815 return makepoint(h, v);
1816}
1817
1818static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001819stdwin_getdefwinsize(self, args)
1820 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001821 object *args;
1822{
1823 int width, height;
1824 if (!getnoarg(args))
1825 return NULL;
1826 wgetdefwinsize(&width, &height);
1827 return makepoint(width, height);
1828}
1829
1830static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001831stdwin_getdefscrollbars(self, args)
1832 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001833 object *args;
1834{
1835 int h, v;
1836 if (!getnoarg(args))
1837 return NULL;
1838 wgetdefscrollbars(&h, &v);
1839 return makepoint(h, v);
1840}
1841
1842static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001843stdwin_menucreate(self, args)
1844 object *self;
1845 object *args;
1846{
1847 object *title;
1848 if (!getstrarg(args, &title))
1849 return NULL;
1850 wmenusetdeflocal(0);
1851 return (object *)newmenuobject(title);
1852}
1853
1854static object *
1855stdwin_askfile(self, args)
1856 object *self;
1857 object *args;
1858{
1859 object *prompt, *dflt;
1860 int new, ret;
1861 char buf[256];
1862 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1863 return NULL;
1864 strncpy(buf, getstringvalue(dflt), sizeof buf);
1865 buf[sizeof buf - 1] = '\0';
1866 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1867 if (!ret) {
1868 err_set(KeyboardInterrupt);
1869 return NULL;
1870 }
1871 return newstringobject(buf);
1872}
1873
1874static object *
1875stdwin_askync(self, args)
1876 object *self;
1877 object *args;
1878{
1879 object *prompt;
1880 int new, ret;
1881 if (!getstrintarg(args, &prompt, &new))
1882 return NULL;
1883 ret = waskync(getstringvalue(prompt), new);
1884 if (ret < 0) {
1885 err_set(KeyboardInterrupt);
1886 return NULL;
1887 }
1888 return newintobject((long)ret);
1889}
1890
1891static object *
1892stdwin_askstr(self, args)
1893 object *self;
1894 object *args;
1895{
1896 object *prompt, *dflt;
1897 int ret;
1898 char buf[256];
1899 if (!getstrstrarg(args, &prompt, &dflt))
1900 return NULL;
1901 strncpy(buf, getstringvalue(dflt), sizeof buf);
1902 buf[sizeof buf - 1] = '\0';
1903 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1904 if (!ret) {
1905 err_set(KeyboardInterrupt);
1906 return NULL;
1907 }
1908 return newstringobject(buf);
1909}
1910
1911static object *
1912stdwin_message(self, args)
1913 object *self;
1914 object *args;
1915{
1916 object *msg;
1917 if (!getstrarg(args, &msg))
1918 return NULL;
1919 wmessage(getstringvalue(msg));
1920 INCREF(None);
1921 return None;
1922}
1923
1924static object *
1925stdwin_fleep(self, args)
1926 object *self;
1927 object *args;
1928{
1929 if (!getnoarg(args))
1930 return NULL;
1931 wfleep();
1932 INCREF(None);
1933 return None;
1934}
1935
1936static object *
1937stdwin_setcutbuffer(self, args)
1938 object *self;
1939 object *args;
1940{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001941 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001942 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001943 if (!getintstrarg(args, &i, &str))
1944 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001945 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001946 INCREF(None);
1947 return None;
1948}
1949
1950static object *
1951stdwin_getcutbuffer(self, args)
1952 object *self;
1953 object *args;
1954{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001955 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001956 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001957 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001958 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001959 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001960 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001961 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001962 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001963 len = 0;
1964 }
1965 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001966}
1967
Guido van Rossum5b10f451990-10-30 16:01:48 +00001968static object *
1969stdwin_rotatecutbuffers(self, args)
1970 object *self;
1971 object *args;
1972{
1973 int i;
1974 if (!getintarg(args, &i))
1975 return NULL;
1976 wrotatecutbuffers(i);
1977 INCREF(None);
1978 return None;
1979}
1980
1981static object *
1982stdwin_getselection(self, args)
1983 object *self;
1984 object *args;
1985{
1986 int sel;
1987 char *data;
1988 int len;
1989 if (!getintarg(args, &sel))
1990 return NULL;
1991 data = wgetselection(sel, &len);
1992 if (data == NULL) {
1993 data = "";
1994 len = 0;
1995 }
1996 return newsizedstringobject(data, len);
1997}
1998
1999static object *
2000stdwin_resetselection(self, args)
2001 object *self;
2002 object *args;
2003{
2004 int sel;
2005 if (!getintarg(args, &sel))
2006 return NULL;
2007 wresetselection(sel);
2008 INCREF(None);
2009 return None;
2010}
2011
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002012static object *
2013stdwin_fetchcolor(self, args)
2014 object *self;
2015 object *args;
2016{
2017 object *colorname;
2018 if (!getstrarg(args, &colorname))
2019 return NULL;
2020 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
2021}
2022
Guido van Rossum541c8c01991-05-05 20:13:41 +00002023static object *
2024stdwin_getscrsize(self, args)
2025 object *self;
2026 object *args;
2027{
2028 int width, height;
2029 if (!getnoarg(args))
2030 return NULL;
2031 wgetscrsize(&width, &height);
2032 return makepoint(width, height);
2033}
2034
2035static object *
2036stdwin_getscrmm(self, args)
2037 object *self;
2038 object *args;
2039{
2040 int width, height;
2041 if (!getnoarg(args))
2042 return NULL;
2043 wgetscrmm(&width, &height);
2044 return makepoint(width, height);
2045}
2046
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047static struct methodlist stdwin_methods[] = {
2048 {"askfile", stdwin_askfile},
2049 {"askstr", stdwin_askstr},
2050 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002051 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002052 {"fleep", stdwin_fleep},
2053 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002054 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002055 {"getdefwinpos", stdwin_getdefwinpos},
2056 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002058 {"getscrmm", stdwin_getscrmm},
2059 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002060 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002061 {"menucreate", stdwin_menucreate},
2062 {"message", stdwin_message},
2063 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002064 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002065 {"resetselection", stdwin_resetselection},
2066 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002067 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002068 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002069 {"setdefwinpos", stdwin_setdefwinpos},
2070 {"setdefwinsize", stdwin_setdefwinsize},
2071
2072 /* Text measuring methods borrow code from drawing objects: */
2073 {"baseline", drawing_baseline},
2074 {"lineheight", drawing_lineheight},
2075 {"textbreak", drawing_textbreak},
2076 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002077
2078 /* Same for font setting methods: */
2079 {"setfont", drawing_setfont},
2080
2081 /* Same for color setting/getting methods: */
2082 {"getbgcolor", drawing_getbgcolor},
2083 {"getfgcolor", drawing_getfgcolor},
2084 {"setbgcolor", drawing_setbgcolor},
2085 {"setfgcolor", drawing_setfgcolor},
2086
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087 {NULL, NULL} /* sentinel */
2088};
2089
2090void
2091initstdwin()
2092{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002093 static int inited;
2094 if (!inited) {
2095 winit();
2096 inited = 1;
2097 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002098 initmodule("stdwin", stdwin_methods);
2099}