blob: f8c312e7fa5b420a9c9bf74fda9887e7282a22a1 [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{
Guido van Rossum85f50761991-10-20 20:22:50 +00001042 object *v = NULL;
1043 if (strcmp(name, "__dict__") == 0) {
1044 v = tp->t_attr;
1045 if (v == NULL)
1046 v = None;
1047 }
1048 else if (tp->t_attr != NULL) {
1049 v = dictlookup(tp->t_attr, name);
1050 }
1051 if (v != NULL) {
1052 INCREF(v);
1053 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 }
1055 return findmethod(text_methods, (object *)tp, name);
1056}
1057
1058static int
1059text_setattr(tp, name, v)
1060 textobject *tp;
1061 char *name;
1062 object *v;
1063{
1064 if (tp->t_attr == NULL) {
1065 tp->t_attr = newdictobject();
1066 if (tp->t_attr == NULL)
1067 return -1;
1068 }
1069 if (v == NULL)
1070 return dictremove(tp->t_attr, name);
1071 else
1072 return dictinsert(tp->t_attr, name, v);
1073}
1074
Guido van Rossum541c8c01991-05-05 20:13:41 +00001075typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001076 OB_HEAD_INIT(&Typetype)
1077 0, /*ob_size*/
1078 "textedit", /*tp_name*/
1079 sizeof(textobject), /*tp_size*/
1080 0, /*tp_itemsize*/
1081 /* methods */
1082 text_dealloc, /*tp_dealloc*/
1083 0, /*tp_print*/
1084 text_getattr, /*tp_getattr*/
1085 text_setattr, /*tp_setattr*/
1086 0, /*tp_compare*/
1087 0, /*tp_repr*/
1088};
1089
1090
1091/* Menu objects */
1092
Guido van Rossum2d14e211991-02-19 12:26:49 +00001093#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001094#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001095static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096
1097static menuobject *
1098newmenuobject(title)
1099 object *title;
1100{
1101 int id;
1102 MENU *menu;
1103 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001104 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105 if (menulist[id] == NULL)
1106 break;
1107 }
Guido van Rossum27201061991-04-16 08:43:03 +00001108 if (id >= MAXNMENU) {
1109 err_setstr(MemoryError, "creating too many menus");
1110 return NULL;
1111 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001112 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113 if (menu == NULL)
1114 return (menuobject *) err_nomem();
1115 mp = NEWOBJ(menuobject, &Menutype);
1116 if (mp != NULL) {
1117 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001118 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 mp->m_attr = NULL;
1120 menulist[id] = mp;
1121 }
1122 else
1123 wmenudelete(menu);
1124 return mp;
1125}
1126
1127/* Menu methods */
1128
1129static void
1130menu_dealloc(mp)
1131 menuobject *mp;
1132{
1133
Guido van Rossum2d14e211991-02-19 12:26:49 +00001134 int id = mp->m_id - IDOFFSET;
1135 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001136 menulist[id] = NULL;
1137 }
1138 wmenudelete(mp->m_menu);
1139 if (mp->m_attr != NULL)
1140 DECREF(mp->m_attr);
1141 DEL(mp);
1142}
1143
1144static object *
1145menu_additem(self, args)
1146 menuobject *self;
1147 object *args;
1148{
1149 object *text;
1150 int shortcut;
1151 if (is_tupleobject(args)) {
1152 object *v;
1153 if (!getstrstrarg(args, &text, &v))
1154 return NULL;
1155 if (getstringsize(v) != 1) {
1156 err_badarg();
1157 return NULL;
1158 }
1159 shortcut = *getstringvalue(v) & 0xff;
1160 }
1161 else {
1162 if (!getstrarg(args, &text))
1163 return NULL;
1164 shortcut = -1;
1165 }
1166 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1167 INCREF(None);
1168 return None;
1169}
1170
1171static object *
1172menu_setitem(self, args)
1173 menuobject *self;
1174 object *args;
1175{
1176 int index;
1177 object *text;
1178 if (!getintstrarg(args, &index, &text))
1179 return NULL;
1180 wmenusetitem(self->m_menu, index, getstringvalue(text));
1181 INCREF(None);
1182 return None;
1183}
1184
1185static object *
1186menu_enable(self, args)
1187 menuobject *self;
1188 object *args;
1189{
1190 int index;
1191 int flag;
1192 if (!getintintarg(args, &index, &flag))
1193 return NULL;
1194 wmenuenable(self->m_menu, index, flag);
1195 INCREF(None);
1196 return None;
1197}
1198
1199static object *
1200menu_check(self, args)
1201 menuobject *self;
1202 object *args;
1203{
1204 int index;
1205 int flag;
1206 if (!getintintarg(args, &index, &flag))
1207 return NULL;
1208 wmenucheck(self->m_menu, index, flag);
1209 INCREF(None);
1210 return None;
1211}
1212
1213static struct methodlist menu_methods[] = {
1214 "additem", menu_additem,
1215 "setitem", menu_setitem,
1216 "enable", menu_enable,
1217 "check", menu_check,
1218 {NULL, NULL} /* sentinel */
1219};
1220
1221static object *
1222menu_getattr(mp, name)
1223 menuobject *mp;
1224 char *name;
1225{
Guido van Rossum85f50761991-10-20 20:22:50 +00001226 object *v = NULL;
1227 if (strcmp(name, "__dict__") == 0) {
1228 v = mp->m_attr;
1229 if (v == NULL)
1230 v = None;
1231 }
1232 else if (mp->m_attr != NULL) {
1233 v = dictlookup(mp->m_attr, name);
1234 }
1235 if (v != NULL) {
1236 INCREF(v);
1237 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001238 }
1239 return findmethod(menu_methods, (object *)mp, name);
1240}
1241
1242static int
1243menu_setattr(mp, name, v)
1244 menuobject *mp;
1245 char *name;
1246 object *v;
1247{
1248 if (mp->m_attr == NULL) {
1249 mp->m_attr = newdictobject();
1250 if (mp->m_attr == NULL)
1251 return -1;
1252 }
1253 if (v == NULL)
1254 return dictremove(mp->m_attr, name);
1255 else
1256 return dictinsert(mp->m_attr, name, v);
1257}
1258
Guido van Rossum541c8c01991-05-05 20:13:41 +00001259typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001260 OB_HEAD_INIT(&Typetype)
1261 0, /*ob_size*/
1262 "menu", /*tp_name*/
1263 sizeof(menuobject), /*tp_size*/
1264 0, /*tp_itemsize*/
1265 /* methods */
1266 menu_dealloc, /*tp_dealloc*/
1267 0, /*tp_print*/
1268 menu_getattr, /*tp_getattr*/
1269 menu_setattr, /*tp_setattr*/
1270 0, /*tp_compare*/
1271 0, /*tp_repr*/
1272};
1273
1274
1275/* Windows */
1276
1277#define MAXNWIN 50
1278static windowobject *windowlist[MAXNWIN];
1279
1280/* Window methods */
1281
1282static void
1283window_dealloc(wp)
1284 windowobject *wp;
1285{
1286 if (wp->w_win != NULL) {
1287 int tag = wgettag(wp->w_win);
1288 if (tag >= 0 && tag < MAXNWIN)
1289 windowlist[tag] = NULL;
1290 else
1291 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1292 tag);
1293 wclose(wp->w_win);
1294 }
1295 DECREF(wp->w_title);
1296 if (wp->w_attr != NULL)
1297 DECREF(wp->w_attr);
1298 free((char *)wp);
1299}
1300
Guido van Rossumd783a461991-06-07 22:35:42 +00001301static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302window_print(wp, fp, flags)
1303 windowobject *wp;
1304 FILE *fp;
1305 int flags;
1306{
1307 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
Guido van Rossumd783a461991-06-07 22:35:42 +00001308 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309}
1310
1311static object *
1312window_begindrawing(wp, args)
1313 windowobject *wp;
1314 object *args;
1315{
1316 drawingobject *dp;
1317 if (!getnoarg(args))
1318 return NULL;
1319 if (Drawing != NULL) {
1320 err_setstr(RuntimeError, "already drawing");
1321 return NULL;
1322 }
1323 dp = NEWOBJ(drawingobject, &Drawingtype);
1324 if (dp == NULL)
1325 return NULL;
1326 Drawing = dp;
1327 INCREF(wp);
1328 dp->d_ref = wp;
1329 wbegindrawing(wp->w_win);
1330 return (object *)dp;
1331}
1332
1333static object *
1334window_change(wp, args)
1335 windowobject *wp;
1336 object *args;
1337{
1338 int a[4];
1339 if (!getrectarg(args, a))
1340 return NULL;
1341 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1342 INCREF(None);
1343 return None;
1344}
1345
1346static object *
1347window_gettitle(wp, args)
1348 windowobject *wp;
1349 object *args;
1350{
1351 if (!getnoarg(args))
1352 return NULL;
1353 INCREF(wp->w_title);
1354 return wp->w_title;
1355}
1356
1357static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001358window_getwinpos(wp, args)
1359 windowobject *wp;
1360 object *args;
1361{
1362 int h, v;
1363 if (!getnoarg(args))
1364 return NULL;
1365 wgetwinpos(wp->w_win, &h, &v);
1366 return makepoint(h, v);
1367}
1368
1369static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001370window_getwinsize(wp, args)
1371 windowobject *wp;
1372 object *args;
1373{
1374 int width, height;
1375 if (!getnoarg(args))
1376 return NULL;
1377 wgetwinsize(wp->w_win, &width, &height);
1378 return makepoint(width, height);
1379}
1380
1381static object *
1382window_getdocsize(wp, args)
1383 windowobject *wp;
1384 object *args;
1385{
1386 int width, height;
1387 if (!getnoarg(args))
1388 return NULL;
1389 wgetdocsize(wp->w_win, &width, &height);
1390 return makepoint(width, height);
1391}
1392
1393static object *
1394window_getorigin(wp, args)
1395 windowobject *wp;
1396 object *args;
1397{
1398 int width, height;
1399 if (!getnoarg(args))
1400 return NULL;
1401 wgetorigin(wp->w_win, &width, &height);
1402 return makepoint(width, height);
1403}
1404
1405static object *
1406window_scroll(wp, args)
1407 windowobject *wp;
1408 object *args;
1409{
1410 int a[6];
1411 if (!getrectpointarg(args, a))
1412 return NULL;
1413 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1414 INCREF(None);
1415 return None;
1416}
1417
1418static object *
1419window_setdocsize(wp, args)
1420 windowobject *wp;
1421 object *args;
1422{
1423 int a[2];
1424 if (!getpointarg(args, a))
1425 return NULL;
1426 wsetdocsize(wp->w_win, a[0], a[1]);
1427 INCREF(None);
1428 return None;
1429}
1430
1431static object *
1432window_setorigin(wp, args)
1433 windowobject *wp;
1434 object *args;
1435{
1436 int a[2];
1437 if (!getpointarg(args, a))
1438 return NULL;
1439 wsetorigin(wp->w_win, a[0], a[1]);
1440 INCREF(None);
1441 return None;
1442}
1443
1444static object *
1445window_settitle(wp, args)
1446 windowobject *wp;
1447 object *args;
1448{
1449 object *title;
1450 if (!getstrarg(args, &title))
1451 return NULL;
1452 DECREF(wp->w_title);
1453 INCREF(title);
1454 wp->w_title = title;
1455 wsettitle(wp->w_win, getstringvalue(title));
1456 INCREF(None);
1457 return None;
1458}
1459
1460static object *
1461window_show(wp, args)
1462 windowobject *wp;
1463 object *args;
1464{
1465 int a[4];
1466 if (!getrectarg(args, a))
1467 return NULL;
1468 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1469 INCREF(None);
1470 return None;
1471}
1472
1473static object *
1474window_settimer(wp, args)
1475 windowobject *wp;
1476 object *args;
1477{
1478 int a;
1479 if (!getintarg(args, &a))
1480 return NULL;
1481 wsettimer(wp->w_win, a);
1482 INCREF(None);
1483 return None;
1484}
1485
1486static object *
1487window_menucreate(self, args)
1488 windowobject *self;
1489 object *args;
1490{
1491 menuobject *mp;
1492 object *title;
1493 if (!getstrarg(args, &title))
1494 return NULL;
1495 wmenusetdeflocal(1);
1496 mp = newmenuobject(title);
1497 if (mp == NULL)
1498 return NULL;
1499 wmenuattach(self->w_win, mp->m_menu);
1500 return (object *)mp;
1501}
1502
1503static object *
1504window_textcreate(self, args)
1505 windowobject *self;
1506 object *args;
1507{
1508 textobject *tp;
1509 int a[4];
1510 if (!getrectarg(args, a))
1511 return NULL;
1512 return (object *)
1513 newtextobject(self, a[0], a[1], a[2], a[3]);
1514}
1515
Guido van Rossum5b10f451990-10-30 16:01:48 +00001516static object *
1517window_setselection(self, args)
1518 windowobject *self;
1519 object *args;
1520{
1521 int sel;
1522 object *str;
1523 int ok;
1524 if (!getintstrarg(args, &sel, &str))
1525 return NULL;
1526 ok = wsetselection(self->w_win, sel,
1527 getstringvalue(str), (int)getstringsize(str));
1528 return newintobject(ok);
1529}
1530
1531static object *
1532window_setwincursor(self, args)
1533 windowobject *self;
1534 object *args;
1535{
1536 object *str;
1537 CURSOR *c;
1538 if (!getstrarg(args, &str))
1539 return NULL;
1540 c = wfetchcursor(getstringvalue(str));
1541 if (c == NULL) {
1542 err_setstr(RuntimeError, "no such cursor");
1543 return NULL;
1544 }
1545 wsetwincursor(self->w_win, c);
1546 INCREF(None);
1547 return None;
1548}
1549
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001550#ifdef CWI_HACKS
1551static object *
1552window_getxwindowid(self, args)
1553 windowobject *self;
1554 object *args;
1555{
1556 long wid = wgetxwindowid(self->w_win);
1557 return newintobject(wid);
1558}
1559#endif
1560
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001561static struct methodlist window_methods[] = {
1562 {"begindrawing",window_begindrawing},
1563 {"change", window_change},
1564 {"getdocsize", window_getdocsize},
1565 {"getorigin", window_getorigin},
1566 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001567 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001568 {"getwinsize", window_getwinsize},
1569 {"menucreate", window_menucreate},
1570 {"scroll", window_scroll},
1571 {"setdocsize", window_setdocsize},
1572 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001573 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001574 {"settimer", window_settimer},
1575 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001576 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001577 {"show", window_show},
1578 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001579#ifdef CWI_HACKS
1580 {"getxwindowid",window_getxwindowid},
1581#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001582 {NULL, NULL} /* sentinel */
1583};
1584
1585static object *
1586window_getattr(wp, name)
1587 windowobject *wp;
1588 char *name;
1589{
Guido van Rossum85f50761991-10-20 20:22:50 +00001590 object *v = NULL;
1591 if (strcmp(name, "__dict__") == 0) {
1592 v = wp->w_attr;
1593 if (v == NULL)
1594 v = None;
1595 }
1596 else if (wp->w_attr != NULL) {
1597 v = dictlookup(wp->w_attr, name);
1598 }
1599 if (v != NULL) {
1600 INCREF(v);
1601 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602 }
1603 return findmethod(window_methods, (object *)wp, name);
1604}
1605
1606static int
1607window_setattr(wp, name, v)
1608 windowobject *wp;
1609 char *name;
1610 object *v;
1611{
1612 if (wp->w_attr == NULL) {
1613 wp->w_attr = newdictobject();
1614 if (wp->w_attr == NULL)
1615 return -1;
1616 }
1617 if (v == NULL)
1618 return dictremove(wp->w_attr, name);
1619 else
1620 return dictinsert(wp->w_attr, name, v);
1621}
1622
Guido van Rossum541c8c01991-05-05 20:13:41 +00001623typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001624 OB_HEAD_INIT(&Typetype)
1625 0, /*ob_size*/
1626 "window", /*tp_name*/
1627 sizeof(windowobject), /*tp_size*/
1628 0, /*tp_itemsize*/
1629 /* methods */
1630 window_dealloc, /*tp_dealloc*/
1631 window_print, /*tp_print*/
1632 window_getattr, /*tp_getattr*/
1633 window_setattr, /*tp_setattr*/
1634 0, /*tp_compare*/
1635 0, /*tp_repr*/
1636};
1637
1638/* Stdwin methods */
1639
1640static object *
1641stdwin_open(sw, args)
1642 object *sw;
1643 object *args;
1644{
1645 int tag;
1646 object *title;
1647 windowobject *wp;
1648 if (!getstrarg(args, &title))
1649 return NULL;
1650 for (tag = 0; tag < MAXNWIN; tag++) {
1651 if (windowlist[tag] == NULL)
1652 break;
1653 }
Guido van Rossum27201061991-04-16 08:43:03 +00001654 if (tag >= MAXNWIN) {
1655 err_setstr(MemoryError, "creating too many windows");
1656 return NULL;
1657 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001658 wp = NEWOBJ(windowobject, &Windowtype);
1659 if (wp == NULL)
1660 return NULL;
1661 INCREF(title);
1662 wp->w_title = title;
1663 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1664 wp->w_attr = NULL;
1665 if (wp->w_win == NULL) {
1666 DECREF(wp);
1667 return NULL;
1668 }
1669 windowlist[tag] = wp;
1670 wsettag(wp->w_win, tag);
1671 return (object *)wp;
1672}
1673
1674static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001675window2object(win)
1676 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001677{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001678 object *w;
1679 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001680 w = None;
1681 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001682 int tag = wgettag(win);
1683 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1684 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001685 w = None;
1686 else
1687 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001688#ifdef sgi
1689 /* XXX Trap for unexplained weird bug */
1690 if ((long)w == (long)0x80000001) {
1691 err_setstr(SystemError,
1692 "bad pointer in stdwin.getevent()");
1693 return NULL;
1694 }
1695#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001696 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001697 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001698 return w;
1699}
1700
1701static object *
1702stdwin_get_poll_event(poll, args)
1703 int poll;
1704 object *args;
1705{
1706 EVENT e;
1707 object *v, *w;
1708 if (!getnoarg(args))
1709 return NULL;
1710 if (Drawing != NULL) {
1711 err_setstr(RuntimeError, "cannot getevent() while drawing");
1712 return NULL;
1713 }
1714 again:
1715 if (poll) {
1716 if (!wpollevent(&e)) {
1717 INCREF(None);
1718 return None;
1719 }
1720 }
1721 else
1722 wgetevent(&e);
1723 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1724 /* Turn keyboard interrupts into exceptions */
1725 err_set(KeyboardInterrupt);
1726 return NULL;
1727 }
1728 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1729 /* Turn WC_CLOSE commands into WE_CLOSE events */
1730 e.type = WE_CLOSE;
1731 }
1732 v = newtupleobject(3);
1733 if (v == NULL)
1734 return NULL;
1735 if ((w = newintobject((long)e.type)) == NULL) {
1736 DECREF(v);
1737 return NULL;
1738 }
1739 settupleitem(v, 0, w);
1740 settupleitem(v, 1, window2object(e.window));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001741 switch (e.type) {
1742 case WE_CHAR:
1743 {
1744 char c[1];
1745 c[0] = e.u.character;
1746 w = newsizedstringobject(c, 1);
1747 }
1748 break;
1749 case WE_COMMAND:
1750 w = newintobject((long)e.u.command);
1751 break;
1752 case WE_DRAW:
1753 w = makerect(e.u.area.left, e.u.area.top,
1754 e.u.area.right, e.u.area.bottom);
1755 break;
1756 case WE_MOUSE_DOWN:
1757 case WE_MOUSE_MOVE:
1758 case WE_MOUSE_UP:
1759 w = makemouse(e.u.where.h, e.u.where.v,
1760 e.u.where.clicks,
1761 e.u.where.button,
1762 e.u.where.mask);
1763 break;
1764 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001765 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1766 menulist[e.u.m.id - IDOFFSET] != NULL)
1767 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum246b9d81991-06-03 10:55:14 +00001768 else {
1769 /* Ghost menu event.
1770 Can occur only on the Mac if another part
1771 of the aplication has installed a menu;
1772 like the THINK C console library. */
1773 DECREF(v);
1774 goto again;
1775 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001776 w = makemenu(w, e.u.m.item);
1777 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001778 case WE_LOST_SEL:
1779 w = newintobject((long)e.u.sel);
1780 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781 default:
1782 w = None;
1783 INCREF(w);
1784 break;
1785 }
1786 if (w == NULL) {
1787 DECREF(v);
1788 return NULL;
1789 }
1790 settupleitem(v, 2, w);
1791 return v;
1792}
1793
1794static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001795stdwin_getevent(sw, args)
1796 object *sw;
1797 object *args;
1798{
1799 return stdwin_get_poll_event(0, args);
1800}
1801
1802static object *
1803stdwin_pollevent(sw, args)
1804 object *sw;
1805 object *args;
1806{
1807 return stdwin_get_poll_event(1, args);
1808}
1809
1810static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001811stdwin_setdefwinpos(sw, args)
1812 object *sw;
1813 object *args;
1814{
1815 int a[2];
1816 if (!getpointarg(args, a))
1817 return NULL;
1818 wsetdefwinpos(a[0], a[1]);
1819 INCREF(None);
1820 return None;
1821}
1822
1823static object *
1824stdwin_setdefwinsize(sw, args)
1825 object *sw;
1826 object *args;
1827{
1828 int a[2];
1829 if (!getpointarg(args, a))
1830 return NULL;
1831 wsetdefwinsize(a[0], a[1]);
1832 INCREF(None);
1833 return None;
1834}
1835
1836static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001837stdwin_setdefscrollbars(sw, args)
1838 object *sw;
1839 object *args;
1840{
1841 int a[2];
1842 if (!getpointarg(args, a))
1843 return NULL;
1844 wsetdefscrollbars(a[0], a[1]);
1845 INCREF(None);
1846 return None;
1847}
1848
1849static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001850stdwin_getdefwinpos(self, args)
1851 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001852 object *args;
1853{
1854 int h, v;
1855 if (!getnoarg(args))
1856 return NULL;
1857 wgetdefwinpos(&h, &v);
1858 return makepoint(h, v);
1859}
1860
1861static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001862stdwin_getdefwinsize(self, args)
1863 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001864 object *args;
1865{
1866 int width, height;
1867 if (!getnoarg(args))
1868 return NULL;
1869 wgetdefwinsize(&width, &height);
1870 return makepoint(width, height);
1871}
1872
1873static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001874stdwin_getdefscrollbars(self, args)
1875 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001876 object *args;
1877{
1878 int h, v;
1879 if (!getnoarg(args))
1880 return NULL;
1881 wgetdefscrollbars(&h, &v);
1882 return makepoint(h, v);
1883}
1884
1885static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001886stdwin_menucreate(self, args)
1887 object *self;
1888 object *args;
1889{
1890 object *title;
1891 if (!getstrarg(args, &title))
1892 return NULL;
1893 wmenusetdeflocal(0);
1894 return (object *)newmenuobject(title);
1895}
1896
1897static object *
1898stdwin_askfile(self, args)
1899 object *self;
1900 object *args;
1901{
1902 object *prompt, *dflt;
1903 int new, ret;
1904 char buf[256];
1905 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1906 return NULL;
1907 strncpy(buf, getstringvalue(dflt), sizeof buf);
1908 buf[sizeof buf - 1] = '\0';
1909 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1910 if (!ret) {
1911 err_set(KeyboardInterrupt);
1912 return NULL;
1913 }
1914 return newstringobject(buf);
1915}
1916
1917static object *
1918stdwin_askync(self, args)
1919 object *self;
1920 object *args;
1921{
1922 object *prompt;
1923 int new, ret;
1924 if (!getstrintarg(args, &prompt, &new))
1925 return NULL;
1926 ret = waskync(getstringvalue(prompt), new);
1927 if (ret < 0) {
1928 err_set(KeyboardInterrupt);
1929 return NULL;
1930 }
1931 return newintobject((long)ret);
1932}
1933
1934static object *
1935stdwin_askstr(self, args)
1936 object *self;
1937 object *args;
1938{
1939 object *prompt, *dflt;
1940 int ret;
1941 char buf[256];
1942 if (!getstrstrarg(args, &prompt, &dflt))
1943 return NULL;
1944 strncpy(buf, getstringvalue(dflt), sizeof buf);
1945 buf[sizeof buf - 1] = '\0';
1946 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1947 if (!ret) {
1948 err_set(KeyboardInterrupt);
1949 return NULL;
1950 }
1951 return newstringobject(buf);
1952}
1953
1954static object *
1955stdwin_message(self, args)
1956 object *self;
1957 object *args;
1958{
1959 object *msg;
1960 if (!getstrarg(args, &msg))
1961 return NULL;
1962 wmessage(getstringvalue(msg));
1963 INCREF(None);
1964 return None;
1965}
1966
1967static object *
1968stdwin_fleep(self, args)
1969 object *self;
1970 object *args;
1971{
1972 if (!getnoarg(args))
1973 return NULL;
1974 wfleep();
1975 INCREF(None);
1976 return None;
1977}
1978
1979static object *
1980stdwin_setcutbuffer(self, args)
1981 object *self;
1982 object *args;
1983{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001984 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001985 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001986 if (!getintstrarg(args, &i, &str))
1987 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001988 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001989 INCREF(None);
1990 return None;
1991}
1992
1993static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001994stdwin_getactive(self, args)
1995 object *self;
1996 object *args;
1997{
1998 return window2object(wgetactive());
1999}
2000
2001static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002002stdwin_getcutbuffer(self, args)
2003 object *self;
2004 object *args;
2005{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002006 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002007 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002008 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002009 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002010 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002011 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002012 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002013 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002014 len = 0;
2015 }
2016 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017}
2018
Guido van Rossum5b10f451990-10-30 16:01:48 +00002019static object *
2020stdwin_rotatecutbuffers(self, args)
2021 object *self;
2022 object *args;
2023{
2024 int i;
2025 if (!getintarg(args, &i))
2026 return NULL;
2027 wrotatecutbuffers(i);
2028 INCREF(None);
2029 return None;
2030}
2031
2032static object *
2033stdwin_getselection(self, args)
2034 object *self;
2035 object *args;
2036{
2037 int sel;
2038 char *data;
2039 int len;
2040 if (!getintarg(args, &sel))
2041 return NULL;
2042 data = wgetselection(sel, &len);
2043 if (data == NULL) {
2044 data = "";
2045 len = 0;
2046 }
2047 return newsizedstringobject(data, len);
2048}
2049
2050static object *
2051stdwin_resetselection(self, args)
2052 object *self;
2053 object *args;
2054{
2055 int sel;
2056 if (!getintarg(args, &sel))
2057 return NULL;
2058 wresetselection(sel);
2059 INCREF(None);
2060 return None;
2061}
2062
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002063static object *
2064stdwin_fetchcolor(self, args)
2065 object *self;
2066 object *args;
2067{
2068 object *colorname;
2069 if (!getstrarg(args, &colorname))
2070 return NULL;
2071 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
2072}
2073
Guido van Rossum541c8c01991-05-05 20:13:41 +00002074static object *
2075stdwin_getscrsize(self, args)
2076 object *self;
2077 object *args;
2078{
2079 int width, height;
2080 if (!getnoarg(args))
2081 return NULL;
2082 wgetscrsize(&width, &height);
2083 return makepoint(width, height);
2084}
2085
2086static object *
2087stdwin_getscrmm(self, args)
2088 object *self;
2089 object *args;
2090{
2091 int width, height;
2092 if (!getnoarg(args))
2093 return NULL;
2094 wgetscrmm(&width, &height);
2095 return makepoint(width, height);
2096}
2097
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002098static struct methodlist stdwin_methods[] = {
2099 {"askfile", stdwin_askfile},
2100 {"askstr", stdwin_askstr},
2101 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002102 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002104 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002106 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002107 {"getdefwinpos", stdwin_getdefwinpos},
2108 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002109 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002110 {"getscrmm", stdwin_getscrmm},
2111 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002112 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002113 {"menucreate", stdwin_menucreate},
2114 {"message", stdwin_message},
2115 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002116 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002117 {"resetselection", stdwin_resetselection},
2118 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002119 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002120 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002121 {"setdefwinpos", stdwin_setdefwinpos},
2122 {"setdefwinsize", stdwin_setdefwinsize},
2123
2124 /* Text measuring methods borrow code from drawing objects: */
2125 {"baseline", drawing_baseline},
2126 {"lineheight", drawing_lineheight},
2127 {"textbreak", drawing_textbreak},
2128 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002129
2130 /* Same for font setting methods: */
2131 {"setfont", drawing_setfont},
2132
2133 /* Same for color setting/getting methods: */
2134 {"getbgcolor", drawing_getbgcolor},
2135 {"getfgcolor", drawing_getfgcolor},
2136 {"setbgcolor", drawing_setbgcolor},
2137 {"setfgcolor", drawing_setfgcolor},
2138
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002139 {NULL, NULL} /* sentinel */
2140};
2141
2142void
2143initstdwin()
2144{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002145 static int inited;
2146 if (!inited) {
2147 winit();
2148 inited = 1;
2149 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002150 initmodule("stdwin", stdwin_methods);
2151}