blob: 8a652e30290ec826818d79697ed38b0e2e1fa656 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Stdwin module */
26
27/* Stdwin itself is a module, not a separate object type.
28 Object types defined here:
29 wp: a window
30 dp: a drawing structure (only one can exist at a time)
31 mp: a menu
32 tp: a textedit block
33*/
34
35/* Rules for translating C stdwin function calls into Python stwin:
36 - All names drop their initial letter 'w'
37 - Functions with a window as first parameter are methods of window objects
38 - There is no equivalent for wclose(); just delete the window object
39 (all references to it!) (XXX maybe this is a bad idea)
40 - w.begindrawing() returns a drawing object
41 - There is no equivalent for wenddrawing(win); just delete the drawing
42 object (all references to it!) (XXX maybe this is a bad idea)
43 - Functions that may only be used inside wbegindrawing / wendddrawing
44 are methods of the drawing object; this includes the text measurement
45 functions (which however have doubles as module functions).
46 - Methods of the drawing object drop an initial 'draw' from their name
47 if they have it, e.g., wdrawline() --> d.line()
48 - The obvious type conversions: int --> intobject; string --> stringobject
49 - A text parameter followed by a length parameter is only a text (string)
50 parameter in Python
51 - A point or other pair of horizontal and vertical coordinates is always
52 a pair of integers in Python
53 - Two points forming a rectangle or endpoints of a line segment are a
54 pair of points in Python
55 - The arguments to d.elarc() are three points.
56 - The functions wgetclip() and wsetclip() are translated into
57 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
58 a bad word for what these functions do (clipping has a different
59 meaning in the drawing world), while cutbuffer is standard X jargon.
Guido van Rossum01769f01990-10-30 13:39:00 +000060 XXX This must change again in the light of changes to stdwin!
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 - For textedit, similar rules hold, but they are less strict.
62 XXX more?
63*/
64
Guido van Rossum3f5da241990-12-20 15:06:42 +000065#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068
Guido van Rossum3f5da241990-12-20 15:06:42 +000069#include "stdwin.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070
71/* Window and menu object types declared here because of forward references */
72
73typedef struct {
74 OB_HEAD
75 object *w_title;
76 WINDOW *w_win;
77 object *w_attr; /* Attributes dictionary */
78} windowobject;
79
80extern typeobject Windowtype; /* Really static, forward */
81
82#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
83
84typedef struct {
85 OB_HEAD
86 MENU *m_menu;
87 int m_id;
88 object *m_attr; /* Attributes dictionary */
89} menuobject;
90
91extern typeobject Menutype; /* Really static, forward */
92
93#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
94
95
96/* Strongly stdwin-specific argument handlers */
97
98static int
99getmousedetail(v, ep)
100 object *v;
101 EVENT *ep;
102{
103 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 4)
104 return err_badarg();
105 return getintintarg(gettupleitem(v, 0),
106 &ep->u.where.h, &ep->u.where.v) &&
107 getintarg(gettupleitem(v, 1), &ep->u.where.clicks) &&
108 getintarg(gettupleitem(v, 2), &ep->u.where.button) &&
109 getintarg(gettupleitem(v, 3), &ep->u.where.mask);
110}
111
112static int
113getmenudetail(v, ep)
114 object *v;
115 EVENT *ep;
116{
117 object *mp;
118 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2)
119 return err_badarg();
120 mp = gettupleitem(v, 0);
121 if (mp == NULL || !is_menuobject(mp))
122 return err_badarg();
123 ep->u.m.id = ((menuobject *)mp) -> m_id;
124 return getintarg(gettupleitem(v, 1), &ep->u.m.item);
125}
126
127static int
128geteventarg(v, ep)
129 object *v;
130 EVENT *ep;
131{
132 object *wp, *detail;
133 int a[4];
134 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3)
135 return err_badarg();
136 if (!getintarg(gettupleitem(v, 0), &ep->type))
137 return 0;
138 wp = gettupleitem(v, 1);
139 if (wp == None)
140 ep->window = NULL;
141 else if (wp == NULL || !is_windowobject(wp))
142 return err_badarg();
143 else
144 ep->window = ((windowobject *)wp) -> w_win;
145 detail = gettupleitem(v, 2);
146 switch (ep->type) {
147 case WE_CHAR:
148 if (!is_stringobject(detail) || getstringsize(detail) != 1)
149 return err_badarg();
150 ep->u.character = getstringvalue(detail)[0];
151 return 1;
152 case WE_COMMAND:
153 return getintarg(detail, &ep->u.command);
154 case WE_DRAW:
155 if (!getrectarg(detail, a))
156 return 0;
157 ep->u.area.left = a[0];
158 ep->u.area.top = a[1];
159 ep->u.area.right = a[2];
160 ep->u.area.bottom = a[3];
161 return 1;
162 case WE_MOUSE_DOWN:
163 case WE_MOUSE_UP:
164 case WE_MOUSE_MOVE:
165 return getmousedetail(detail, ep);
166 case WE_MENU:
167 return getmenudetail(detail, ep);
168 default:
169 return 1;
170 }
171}
172
173
174/* Return construction tools */
175
176static object *
177makepoint(a, b)
178 int a, b;
179{
180 object *v;
181 object *w;
182 if ((v = newtupleobject(2)) == NULL)
183 return NULL;
184 if ((w = newintobject((long)a)) == NULL ||
185 settupleitem(v, 0, w) != 0 ||
186 (w = newintobject((long)b)) == NULL ||
187 settupleitem(v, 1, w) != 0) {
188 DECREF(v);
189 return NULL;
190 }
191 return v;
192}
193
194static object *
195makerect(a, b, c, d)
196 int a, b, c, d;
197{
198 object *v;
199 object *w;
200 if ((v = newtupleobject(2)) == NULL)
201 return NULL;
202 if ((w = makepoint(a, b)) == NULL ||
203 settupleitem(v, 0, w) != 0 ||
204 (w = makepoint(c, d)) == NULL ||
205 settupleitem(v, 1, w) != 0) {
206 DECREF(v);
207 return NULL;
208 }
209 return v;
210}
211
212static object *
213makemouse(hor, ver, clicks, button, mask)
214 int hor, ver, clicks, button, mask;
215{
216 object *v;
217 object *w;
218 if ((v = newtupleobject(4)) == NULL)
219 return NULL;
220 if ((w = makepoint(hor, ver)) == NULL ||
221 settupleitem(v, 0, w) != 0 ||
222 (w = newintobject((long)clicks)) == NULL ||
223 settupleitem(v, 1, w) != 0 ||
224 (w = newintobject((long)button)) == NULL ||
225 settupleitem(v, 2, w) != 0 ||
226 (w = newintobject((long)mask)) == NULL ||
227 settupleitem(v, 3, w) != 0) {
228 DECREF(v);
229 return NULL;
230 }
231 return v;
232}
233
234static object *
235makemenu(mp, item)
236 object *mp;
237 int item;
238{
239 object *v;
240 object *w;
241 if ((v = newtupleobject(2)) == NULL)
242 return NULL;
243 INCREF(mp);
244 if (settupleitem(v, 0, mp) != 0 ||
245 (w = newintobject((long)item)) == NULL ||
246 settupleitem(v, 1, w) != 0) {
247 DECREF(v);
248 return NULL;
249 }
250 return v;
251}
252
253
254/* Drawing objects */
255
256typedef struct {
257 OB_HEAD
258 windowobject *d_ref;
259} drawingobject;
260
261static drawingobject *Drawing; /* Set to current drawing object, or NULL */
262
263/* Drawing methods */
264
265static void
266drawing_dealloc(dp)
267 drawingobject *dp;
268{
269 wenddrawing(dp->d_ref->w_win);
270 Drawing = NULL;
271 DECREF(dp->d_ref);
272 free((char *)dp);
273}
274
275static object *
276drawing_generic(dp, args, func)
277 drawingobject *dp;
278 object *args;
279 void (*func) FPROTO((int, int, int, int));
280{
281 int a[4];
282 if (!getrectarg(args, a))
283 return NULL;
284 (*func)(a[0], a[1], a[2], a[3]);
285 INCREF(None);
286 return None;
287}
288
289static object *
290drawing_line(dp, args)
291 drawingobject *dp;
292 object *args;
293{
Guido van Rossumbf109731991-03-06 13:14:12 +0000294 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295}
296
297static object *
298drawing_xorline(dp, args)
299 drawingobject *dp;
300 object *args;
301{
Guido van Rossumbf109731991-03-06 13:14:12 +0000302 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303}
304
305static object *
306drawing_circle(dp, args)
307 drawingobject *dp;
308 object *args;
309{
310 int a[3];
311 if (!getpointintarg(args, a))
312 return NULL;
313 wdrawcircle(a[0], a[1], a[2]);
314 INCREF(None);
315 return None;
316}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000317
Guido van Rossum27201061991-04-16 08:43:03 +0000318static object *
319drawing_fillcircle(dp, args)
320 drawingobject *dp;
321 object *args;
322{
323 int a[3];
324 if (!getpointintarg(args, a))
325 return NULL;
326 wfillcircle(a[0], a[1], a[2]);
327 INCREF(None);
328 return None;
329}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330
331static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000332drawing_xorcircle(dp, args)
333 drawingobject *dp;
334 object *args;
335{
336 int a[3];
337 if (!getpointintarg(args, a))
338 return NULL;
339 wxorcircle(a[0], a[1], a[2]);
340 INCREF(None);
341 return None;
342}
343
344static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345drawing_elarc(dp, args)
346 drawingobject *dp;
347 object *args;
348{
349 int a[6];
350 if (!get3pointarg(args, a))
351 return NULL;
352 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
353 INCREF(None);
354 return None;
355}
356
357static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000358drawing_fillelarc(dp, args)
359 drawingobject *dp;
360 object *args;
361{
362 int a[6];
363 if (!get3pointarg(args, a))
364 return NULL;
365 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
366 INCREF(None);
367 return None;
368}
369
370static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000371drawing_xorelarc(dp, args)
372 drawingobject *dp;
373 object *args;
374{
375 int a[6];
376 if (!get3pointarg(args, a))
377 return NULL;
378 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
379 INCREF(None);
380 return None;
381}
382
383static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384drawing_box(dp, args)
385 drawingobject *dp;
386 object *args;
387{
Guido van Rossumbf109731991-03-06 13:14:12 +0000388 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
391static object *
392drawing_erase(dp, args)
393 drawingobject *dp;
394 object *args;
395{
Guido van Rossumbf109731991-03-06 13:14:12 +0000396 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397}
398
399static object *
400drawing_paint(dp, args)
401 drawingobject *dp;
402 object *args;
403{
Guido van Rossumbf109731991-03-06 13:14:12 +0000404 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
407static object *
408drawing_invert(dp, args)
409 drawingobject *dp;
410 object *args;
411{
Guido van Rossumbf109731991-03-06 13:14:12 +0000412 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossum27201061991-04-16 08:43:03 +0000415static POINT *
416getpointsarray(v, psize)
417 object *v;
418 int *psize;
419{
420 int n = -1;
421 object * (*getitem) PROTO((object *, int));
422 int i;
423 POINT *points;
424
425 if (v == NULL)
426 ;
427 else if (is_listobject(v)) {
428 n = getlistsize(v);
429 getitem = getlistitem;
430 }
431 else if (is_tupleobject(v)) {
432 n = gettuplesize(v);
433 getitem = gettupleitem;
434 }
435
436 if (n <= 0) {
437 (void) err_badarg();
438 return NULL;
439 }
440
441 points = NEW(POINT, n);
442 if (points == NULL) {
443 (void) err_nomem();
444 return NULL;
445 }
446
447 for (i = 0; i < n; i++) {
448 object *w = (*getitem)(v, i);
449 int a[2];
450 if (!getpointarg(w, a)) {
451 DEL(points);
452 return NULL;
453 }
454 points[i].h = a[0];
455 points[i].v = a[1];
456 }
457
458 *psize = n;
459 return points;
460}
461
462static object *
463drawing_poly(dp, args)
464 drawingobject *dp;
465 object *args;
466{
467 int n;
468 POINT *points = getpointsarray(args, &n);
469 if (points == NULL)
470 return NULL;
471 wdrawpoly(n, points);
472 DEL(points);
473 INCREF(None);
474 return None;
475}
476
477static object *
478drawing_fillpoly(dp, args)
479 drawingobject *dp;
480 object *args;
481{
482 int n;
483 POINT *points = getpointsarray(args, &n);
484 if (points == NULL)
485 return NULL;
486 wfillpoly(n, points);
487 DEL(points);
488 INCREF(None);
489 return None;
490}
491
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000493drawing_xorpoly(dp, args)
494 drawingobject *dp;
495 object *args;
496{
497 int n;
498 POINT *points = getpointsarray(args, &n);
499 if (points == NULL)
500 return NULL;
501 wxorpoly(n, points);
502 DEL(points);
503 INCREF(None);
504 return None;
505}
506
507static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508drawing_cliprect(dp, args)
509 drawingobject *dp;
510 object *args;
511{
Guido van Rossumbf109731991-03-06 13:14:12 +0000512 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
515static object *
516drawing_noclip(dp, args)
517 drawingobject *dp;
518 object *args;
519{
520 if (!getnoarg(args))
521 return NULL;
522 wnoclip();
523 INCREF(None);
524 return None;
525}
526
527static object *
528drawing_shade(dp, args)
529 drawingobject *dp;
530 object *args;
531{
532 int a[5];
533 if (!getrectintarg(args, a))
534 return NULL;
535 wshade(a[0], a[1], a[2], a[3], a[4]);
536 INCREF(None);
537 return None;
538}
539
540static object *
541drawing_text(dp, args)
542 drawingobject *dp;
543 object *args;
544{
545 int a[2];
546 object *s;
547 if (!getpointstrarg(args, a, &s))
548 return NULL;
549 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
550 INCREF(None);
551 return None;
552}
553
554/* The following four are also used as stdwin functions */
555
556static object *
557drawing_lineheight(dp, args)
558 drawingobject *dp;
559 object *args;
560{
561 if (!getnoarg(args))
562 return NULL;
563 return newintobject((long)wlineheight());
564}
565
566static object *
567drawing_baseline(dp, args)
568 drawingobject *dp;
569 object *args;
570{
571 if (!getnoarg(args))
572 return NULL;
573 return newintobject((long)wbaseline());
574}
575
576static object *
577drawing_textwidth(dp, args)
578 drawingobject *dp;
579 object *args;
580{
581 object *s;
582 if (!getstrarg(args, &s))
583 return NULL;
584 return newintobject(
585 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
586}
587
588static object *
589drawing_textbreak(dp, args)
590 drawingobject *dp;
591 object *args;
592{
593 object *s;
594 int a;
595 if (!getstrintarg(args, &s, &a))
596 return NULL;
597 return newintobject(
598 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
599}
600
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000601static object *
602drawing_setfont(self, args)
603 drawingobject *self;
604 object *args;
605{
Guido van Rossum50429a11991-04-04 15:24:07 +0000606 object *font, *style;
607 int size;
608 if (args == NULL) {
609 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000610 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000611 }
612 if (is_stringobject(args)) {
613 font = args;
614 style = NULL;
615 size = 0;
616 }
617 else if (is_tupleobject(args)) {
618 int n = gettuplesize(args);
619 if (n == 2) {
620 if (!getstrintarg(args, &font, &size))
621 return NULL;
622 style = NULL;
623 }
624 else if (!getstrstrintarg(args, &font, &style, &size))
625 return NULL;
626 }
627 else {
628 err_badarg();
629 return NULL;
630 }
Guido van Rossum246b9d81991-06-03 10:55:14 +0000631 wsetfont(getstringvalue(font));
Guido van Rossum50429a11991-04-04 15:24:07 +0000632 if (style != NULL) {
633 switch (*getstringvalue(style)) {
634 case 'b':
635 wsetbold();
636 break;
637 case 'i':
638 wsetitalic();
639 break;
640 case 'o':
641 wsetbolditalic();
642 break;
643 case 'u':
644 wsetunderline();
645 break;
646 default:
647 wsetplain();
648 break;
649 }
650 }
651 if (size != 0)
652 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000653 INCREF(None);
654 return None;
655}
656
657static object *
658drawing_getbgcolor(self, args)
659 object *self;
660 object *args;
661{
662 if (!getnoarg(args))
663 return NULL;
664 return newintobject((long)wgetbgcolor());
665}
666
667static object *
668drawing_getfgcolor(self, args)
669 object *self;
670 object *args;
671{
672 if (!getnoarg(args))
673 return NULL;
674 return newintobject((long)wgetfgcolor());
675}
676
677static object *
678drawing_setbgcolor(self, args)
679 object *self;
680 object *args;
681{
682 long color;
683 if (!getlongarg(args, &color))
684 return NULL;
685 wsetbgcolor((COLOR)color);
686 INCREF(None);
687 return None;
688}
689
690static object *
691drawing_setfgcolor(self, args)
692 object *self;
693 object *args;
694{
695 long color;
696 if (!getlongarg(args, &color))
697 return NULL;
698 wsetfgcolor((COLOR)color);
699 INCREF(None);
700 return None;
701}
702
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703static struct methodlist drawing_methods[] = {
704 {"box", drawing_box},
705 {"circle", drawing_circle},
706 {"cliprect", drawing_cliprect},
707 {"elarc", drawing_elarc},
708 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000709 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000710 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000711 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000712 {"invert", drawing_invert},
713 {"line", drawing_line},
714 {"noclip", drawing_noclip},
715 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000716 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000717 {"shade", drawing_shade},
718 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000719 {"xorcircle", drawing_xorcircle},
720 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000722 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000723
724 /* Text measuring methods: */
725 {"baseline", drawing_baseline},
726 {"lineheight", drawing_lineheight},
727 {"textbreak", drawing_textbreak},
728 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000729
730 /* Font setting methods: */
731 {"setfont", drawing_setfont},
732
733 /* Color methods: */
734 {"getbgcolor", drawing_getbgcolor},
735 {"getfgcolor", drawing_getfgcolor},
736 {"setbgcolor", drawing_setbgcolor},
737 {"setfgcolor", drawing_setfgcolor},
738
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739 {NULL, NULL} /* sentinel */
740};
741
742static object *
743drawing_getattr(wp, name)
744 drawingobject *wp;
745 char *name;
746{
747 return findmethod(drawing_methods, (object *)wp, name);
748}
749
Guido van Rossum541c8c01991-05-05 20:13:41 +0000750typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000751 OB_HEAD_INIT(&Typetype)
752 0, /*ob_size*/
753 "drawing", /*tp_name*/
754 sizeof(drawingobject), /*tp_size*/
755 0, /*tp_itemsize*/
756 /* methods */
757 drawing_dealloc, /*tp_dealloc*/
758 0, /*tp_print*/
759 drawing_getattr, /*tp_getattr*/
760 0, /*tp_setattr*/
761 0, /*tp_compare*/
762 0, /*tp_repr*/
763};
764
765
766/* Text(edit) objects */
767
768typedef struct {
769 OB_HEAD
770 TEXTEDIT *t_text;
771 windowobject *t_ref;
772 object *t_attr; /* Attributes dictionary */
773} textobject;
774
775extern typeobject Texttype; /* Really static, forward */
776
777static textobject *
778newtextobject(wp, left, top, right, bottom)
779 windowobject *wp;
780 int left, top, right, bottom;
781{
782 textobject *tp;
783 tp = NEWOBJ(textobject, &Texttype);
784 if (tp == NULL)
785 return NULL;
786 tp->t_attr = NULL;
787 INCREF(wp);
788 tp->t_ref = wp;
789 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
790 if (tp->t_text == NULL) {
791 DECREF(tp);
792 return (textobject *) err_nomem();
793 }
794 return tp;
795}
796
797/* Text(edit) methods */
798
799static void
800text_dealloc(tp)
801 textobject *tp;
802{
803 if (tp->t_text != NULL)
804 tefree(tp->t_text);
805 if (tp->t_attr != NULL)
806 DECREF(tp->t_attr);
807 DECREF(tp->t_ref);
808 DEL(tp);
809}
810
811static object *
812text_arrow(self, args)
813 textobject *self;
814 object *args;
815{
816 int code;
817 if (!getintarg(args, &code))
818 return NULL;
819 tearrow(self->t_text, code);
820 INCREF(None);
821 return None;
822}
823
824static object *
825text_draw(self, args)
826 textobject *self;
827 object *args;
828{
829 register TEXTEDIT *tp = self->t_text;
830 int a[4];
831 int left, top, right, bottom;
832 if (!getrectarg(args, a))
833 return NULL;
834 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000835 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836 return NULL;
837 }
838 /* Clip to text area and ignore if area is empty */
839 left = tegetleft(tp);
840 top = tegettop(tp);
841 right = tegetright(tp);
842 bottom = tegetbottom(tp);
843 if (a[0] < left) a[0] = left;
844 if (a[1] < top) a[1] = top;
845 if (a[2] > right) a[2] = right;
846 if (a[3] > bottom) a[3] = bottom;
847 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849 tedrawnew(tp, a[0], a[1], a[2], a[3]);
850 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000851 }
852 INCREF(None);
853 return None;
854}
855
856static object *
857text_event(self, args)
858 textobject *self;
859 object *args;
860{
861 register TEXTEDIT *tp = self->t_text;
862 EVENT e;
863 if (!geteventarg(args, &e))
864 return NULL;
865 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000866 /* Cheat at the margins */
867 int width, height;
868 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869 if (e.u.where.h < 0 && tegetleft(tp) == 0)
870 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000871 else if (e.u.where.h > width && tegetright(tp) == width)
872 e.u.where.h = width;
873 if (e.u.where.v < 0 && tegettop(tp) == 0)
874 e.u.where.v = 0;
875 else if (e.u.where.v > height && tegetright(tp) == height)
876 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877 }
878 return newintobject((long) teevent(tp, &e));
879}
880
881static object *
882text_getfocus(self, args)
883 textobject *self;
884 object *args;
885{
886 if (!getnoarg(args))
887 return NULL;
888 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
889}
890
891static object *
892text_getfocustext(self, args)
893 textobject *self;
894 object *args;
895{
896 int f1, f2;
897 char *text;
898 if (!getnoarg(args))
899 return NULL;
900 f1 = tegetfoc1(self->t_text);
901 f2 = tegetfoc2(self->t_text);
902 text = tegettext(self->t_text);
903 return newsizedstringobject(text + f1, f2-f1);
904}
905
906static object *
907text_getrect(self, args)
908 textobject *self;
909 object *args;
910{
911 if (!getnoarg(args))
912 return NULL;
913 return makerect(tegetleft(self->t_text),
914 tegettop(self->t_text),
915 tegetright(self->t_text),
916 tegetbottom(self->t_text));
917}
918
919static object *
920text_gettext(self, args)
921 textobject *self;
922 object *args;
923{
924 if (!getnoarg(args))
925 return NULL;
926 return newsizedstringobject(tegettext(self->t_text),
927 tegetlen(self->t_text));
928}
929
930static object *
931text_move(self, args)
932 textobject *self;
933 object *args;
934{
935 int a[4];
936 if (!getrectarg(args, a))
937 return NULL;
938 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
939 INCREF(None);
940 return None;
941}
942
943static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000944text_replace(self, args)
945 textobject *self;
946 object *args;
947{
948 object *text;
949 if (!getstrarg(args, &text))
950 return NULL;
951 tereplace(self->t_text, getstringvalue(text));
952 INCREF(None);
953 return None;
954}
955
956static object *
957text_setactive(self, args)
958 textobject *self;
959 object *args;
960{
961 int flag;
962 if (!getintarg(args, &flag))
963 return NULL;
964 tesetactive(self->t_text, flag);
965 INCREF(None);
966 return None;
967}
968
969static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970text_setfocus(self, args)
971 textobject *self;
972 object *args;
973{
974 int a[2];
975 if (!getpointarg(args, a))
976 return NULL;
977 tesetfocus(self->t_text, a[0], a[1]);
978 INCREF(None);
979 return None;
980}
981
982static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000983text_settext(self, args)
984 textobject *self;
985 object *args;
986{
987 object *text;
988 char *buf;
989 int size;
990 if (!getstrarg(args, &text))
991 return NULL;
992 size = getstringsize(text);
993 if ((buf = NEW(char, size)) == NULL) {
994 err_set(MemoryError);
995 return NULL;
996 }
997 memcpy(buf, getstringvalue(text), size);
998 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
999 INCREF(None);
1000 return None;
1001}
1002
1003static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001004text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 textobject *self;
1006 object *args;
1007{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001008 int a[4];
1009 if (args == None)
1010 tenoview(self->t_text);
1011 else {
1012 if (!getrectarg(args, a))
1013 return NULL;
1014 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1015 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 INCREF(None);
1017 return None;
1018}
1019
1020static struct methodlist text_methods[] = {
1021 "arrow", text_arrow,
1022 "draw", text_draw,
1023 "event", text_event,
1024 "getfocus", text_getfocus,
1025 "getfocustext", text_getfocustext,
1026 "getrect", text_getrect,
1027 "gettext", text_gettext,
1028 "move", text_move,
1029 "replace", text_replace,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001030 "setactive", text_setactive,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001031 "setfocus", text_setfocus,
Guido van Rossum541c8c01991-05-05 20:13:41 +00001032 "settext", text_settext,
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001033 "setview", text_setview,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001034 {NULL, NULL} /* sentinel */
1035};
1036
1037static object *
1038text_getattr(tp, name)
1039 textobject *tp;
1040 char *name;
1041{
1042 if (tp->t_attr != NULL) {
1043 object *v = dictlookup(tp->t_attr, name);
1044 if (v != NULL) {
1045 INCREF(v);
1046 return v;
1047 }
1048 }
1049 return findmethod(text_methods, (object *)tp, name);
1050}
1051
1052static int
1053text_setattr(tp, name, v)
1054 textobject *tp;
1055 char *name;
1056 object *v;
1057{
1058 if (tp->t_attr == NULL) {
1059 tp->t_attr = newdictobject();
1060 if (tp->t_attr == NULL)
1061 return -1;
1062 }
1063 if (v == NULL)
1064 return dictremove(tp->t_attr, name);
1065 else
1066 return dictinsert(tp->t_attr, name, v);
1067}
1068
Guido van Rossum541c8c01991-05-05 20:13:41 +00001069typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070 OB_HEAD_INIT(&Typetype)
1071 0, /*ob_size*/
1072 "textedit", /*tp_name*/
1073 sizeof(textobject), /*tp_size*/
1074 0, /*tp_itemsize*/
1075 /* methods */
1076 text_dealloc, /*tp_dealloc*/
1077 0, /*tp_print*/
1078 text_getattr, /*tp_getattr*/
1079 text_setattr, /*tp_setattr*/
1080 0, /*tp_compare*/
1081 0, /*tp_repr*/
1082};
1083
1084
1085/* Menu objects */
1086
Guido van Rossum2d14e211991-02-19 12:26:49 +00001087#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001088#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001089static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090
1091static menuobject *
1092newmenuobject(title)
1093 object *title;
1094{
1095 int id;
1096 MENU *menu;
1097 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001098 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099 if (menulist[id] == NULL)
1100 break;
1101 }
Guido van Rossum27201061991-04-16 08:43:03 +00001102 if (id >= MAXNMENU) {
1103 err_setstr(MemoryError, "creating too many menus");
1104 return NULL;
1105 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001106 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107 if (menu == NULL)
1108 return (menuobject *) err_nomem();
1109 mp = NEWOBJ(menuobject, &Menutype);
1110 if (mp != NULL) {
1111 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001112 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113 mp->m_attr = NULL;
1114 menulist[id] = mp;
1115 }
1116 else
1117 wmenudelete(menu);
1118 return mp;
1119}
1120
1121/* Menu methods */
1122
1123static void
1124menu_dealloc(mp)
1125 menuobject *mp;
1126{
1127
Guido van Rossum2d14e211991-02-19 12:26:49 +00001128 int id = mp->m_id - IDOFFSET;
1129 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130 menulist[id] = NULL;
1131 }
1132 wmenudelete(mp->m_menu);
1133 if (mp->m_attr != NULL)
1134 DECREF(mp->m_attr);
1135 DEL(mp);
1136}
1137
1138static object *
1139menu_additem(self, args)
1140 menuobject *self;
1141 object *args;
1142{
1143 object *text;
1144 int shortcut;
1145 if (is_tupleobject(args)) {
1146 object *v;
1147 if (!getstrstrarg(args, &text, &v))
1148 return NULL;
1149 if (getstringsize(v) != 1) {
1150 err_badarg();
1151 return NULL;
1152 }
1153 shortcut = *getstringvalue(v) & 0xff;
1154 }
1155 else {
1156 if (!getstrarg(args, &text))
1157 return NULL;
1158 shortcut = -1;
1159 }
1160 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1161 INCREF(None);
1162 return None;
1163}
1164
1165static object *
1166menu_setitem(self, args)
1167 menuobject *self;
1168 object *args;
1169{
1170 int index;
1171 object *text;
1172 if (!getintstrarg(args, &index, &text))
1173 return NULL;
1174 wmenusetitem(self->m_menu, index, getstringvalue(text));
1175 INCREF(None);
1176 return None;
1177}
1178
1179static object *
1180menu_enable(self, args)
1181 menuobject *self;
1182 object *args;
1183{
1184 int index;
1185 int flag;
1186 if (!getintintarg(args, &index, &flag))
1187 return NULL;
1188 wmenuenable(self->m_menu, index, flag);
1189 INCREF(None);
1190 return None;
1191}
1192
1193static object *
1194menu_check(self, args)
1195 menuobject *self;
1196 object *args;
1197{
1198 int index;
1199 int flag;
1200 if (!getintintarg(args, &index, &flag))
1201 return NULL;
1202 wmenucheck(self->m_menu, index, flag);
1203 INCREF(None);
1204 return None;
1205}
1206
1207static struct methodlist menu_methods[] = {
1208 "additem", menu_additem,
1209 "setitem", menu_setitem,
1210 "enable", menu_enable,
1211 "check", menu_check,
1212 {NULL, NULL} /* sentinel */
1213};
1214
1215static object *
1216menu_getattr(mp, name)
1217 menuobject *mp;
1218 char *name;
1219{
1220 if (mp->m_attr != NULL) {
1221 object *v = dictlookup(mp->m_attr, name);
1222 if (v != NULL) {
1223 INCREF(v);
1224 return v;
1225 }
1226 }
1227 return findmethod(menu_methods, (object *)mp, name);
1228}
1229
1230static int
1231menu_setattr(mp, name, v)
1232 menuobject *mp;
1233 char *name;
1234 object *v;
1235{
1236 if (mp->m_attr == NULL) {
1237 mp->m_attr = newdictobject();
1238 if (mp->m_attr == NULL)
1239 return -1;
1240 }
1241 if (v == NULL)
1242 return dictremove(mp->m_attr, name);
1243 else
1244 return dictinsert(mp->m_attr, name, v);
1245}
1246
Guido van Rossum541c8c01991-05-05 20:13:41 +00001247typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001248 OB_HEAD_INIT(&Typetype)
1249 0, /*ob_size*/
1250 "menu", /*tp_name*/
1251 sizeof(menuobject), /*tp_size*/
1252 0, /*tp_itemsize*/
1253 /* methods */
1254 menu_dealloc, /*tp_dealloc*/
1255 0, /*tp_print*/
1256 menu_getattr, /*tp_getattr*/
1257 menu_setattr, /*tp_setattr*/
1258 0, /*tp_compare*/
1259 0, /*tp_repr*/
1260};
1261
1262
1263/* Windows */
1264
1265#define MAXNWIN 50
1266static windowobject *windowlist[MAXNWIN];
1267
1268/* Window methods */
1269
1270static void
1271window_dealloc(wp)
1272 windowobject *wp;
1273{
1274 if (wp->w_win != NULL) {
1275 int tag = wgettag(wp->w_win);
1276 if (tag >= 0 && tag < MAXNWIN)
1277 windowlist[tag] = NULL;
1278 else
1279 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1280 tag);
1281 wclose(wp->w_win);
1282 }
1283 DECREF(wp->w_title);
1284 if (wp->w_attr != NULL)
1285 DECREF(wp->w_attr);
1286 free((char *)wp);
1287}
1288
Guido van Rossumd783a461991-06-07 22:35:42 +00001289static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290window_print(wp, fp, flags)
1291 windowobject *wp;
1292 FILE *fp;
1293 int flags;
1294{
1295 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
Guido van Rossumd783a461991-06-07 22:35:42 +00001296 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
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 Rossum8dcbbac1991-07-27 21:42:24 +00001538#ifdef CWI_HACKS
1539static object *
1540window_getxwindowid(self, args)
1541 windowobject *self;
1542 object *args;
1543{
1544 long wid = wgetxwindowid(self->w_win);
1545 return newintobject(wid);
1546}
1547#endif
1548
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001549static struct methodlist window_methods[] = {
1550 {"begindrawing",window_begindrawing},
1551 {"change", window_change},
1552 {"getdocsize", window_getdocsize},
1553 {"getorigin", window_getorigin},
1554 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001555 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001556 {"getwinsize", window_getwinsize},
1557 {"menucreate", window_menucreate},
1558 {"scroll", window_scroll},
1559 {"setdocsize", window_setdocsize},
1560 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001561 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001562 {"settimer", window_settimer},
1563 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001564 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001565 {"show", window_show},
1566 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001567#ifdef CWI_HACKS
1568 {"getxwindowid",window_getxwindowid},
1569#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001570 {NULL, NULL} /* sentinel */
1571};
1572
1573static object *
1574window_getattr(wp, name)
1575 windowobject *wp;
1576 char *name;
1577{
1578 if (wp->w_attr != NULL) {
1579 object *v = dictlookup(wp->w_attr, name);
1580 if (v != NULL) {
1581 INCREF(v);
1582 return v;
1583 }
1584 }
1585 return findmethod(window_methods, (object *)wp, name);
1586}
1587
1588static int
1589window_setattr(wp, name, v)
1590 windowobject *wp;
1591 char *name;
1592 object *v;
1593{
1594 if (wp->w_attr == NULL) {
1595 wp->w_attr = newdictobject();
1596 if (wp->w_attr == NULL)
1597 return -1;
1598 }
1599 if (v == NULL)
1600 return dictremove(wp->w_attr, name);
1601 else
1602 return dictinsert(wp->w_attr, name, v);
1603}
1604
Guido van Rossum541c8c01991-05-05 20:13:41 +00001605typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001606 OB_HEAD_INIT(&Typetype)
1607 0, /*ob_size*/
1608 "window", /*tp_name*/
1609 sizeof(windowobject), /*tp_size*/
1610 0, /*tp_itemsize*/
1611 /* methods */
1612 window_dealloc, /*tp_dealloc*/
1613 window_print, /*tp_print*/
1614 window_getattr, /*tp_getattr*/
1615 window_setattr, /*tp_setattr*/
1616 0, /*tp_compare*/
1617 0, /*tp_repr*/
1618};
1619
1620/* Stdwin methods */
1621
1622static object *
1623stdwin_open(sw, args)
1624 object *sw;
1625 object *args;
1626{
1627 int tag;
1628 object *title;
1629 windowobject *wp;
1630 if (!getstrarg(args, &title))
1631 return NULL;
1632 for (tag = 0; tag < MAXNWIN; tag++) {
1633 if (windowlist[tag] == NULL)
1634 break;
1635 }
Guido van Rossum27201061991-04-16 08:43:03 +00001636 if (tag >= MAXNWIN) {
1637 err_setstr(MemoryError, "creating too many windows");
1638 return NULL;
1639 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001640 wp = NEWOBJ(windowobject, &Windowtype);
1641 if (wp == NULL)
1642 return NULL;
1643 INCREF(title);
1644 wp->w_title = title;
1645 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1646 wp->w_attr = NULL;
1647 if (wp->w_win == NULL) {
1648 DECREF(wp);
1649 return NULL;
1650 }
1651 windowlist[tag] = wp;
1652 wsettag(wp->w_win, tag);
1653 return (object *)wp;
1654}
1655
1656static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001657window2object(win)
1658 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001660 object *w;
1661 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001662 w = None;
1663 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001664 int tag = wgettag(win);
1665 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1666 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001667 w = None;
1668 else
1669 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001670#ifdef sgi
1671 /* XXX Trap for unexplained weird bug */
1672 if ((long)w == (long)0x80000001) {
1673 err_setstr(SystemError,
1674 "bad pointer in stdwin.getevent()");
1675 return NULL;
1676 }
1677#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001678 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001679 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001680 return w;
1681}
1682
1683static object *
1684stdwin_get_poll_event(poll, args)
1685 int poll;
1686 object *args;
1687{
1688 EVENT e;
1689 object *v, *w;
1690 if (!getnoarg(args))
1691 return NULL;
1692 if (Drawing != NULL) {
1693 err_setstr(RuntimeError, "cannot getevent() while drawing");
1694 return NULL;
1695 }
1696 again:
1697 if (poll) {
1698 if (!wpollevent(&e)) {
1699 INCREF(None);
1700 return None;
1701 }
1702 }
1703 else
1704 wgetevent(&e);
1705 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1706 /* Turn keyboard interrupts into exceptions */
1707 err_set(KeyboardInterrupt);
1708 return NULL;
1709 }
1710 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1711 /* Turn WC_CLOSE commands into WE_CLOSE events */
1712 e.type = WE_CLOSE;
1713 }
1714 v = newtupleobject(3);
1715 if (v == NULL)
1716 return NULL;
1717 if ((w = newintobject((long)e.type)) == NULL) {
1718 DECREF(v);
1719 return NULL;
1720 }
1721 settupleitem(v, 0, w);
1722 settupleitem(v, 1, window2object(e.window));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723 switch (e.type) {
1724 case WE_CHAR:
1725 {
1726 char c[1];
1727 c[0] = e.u.character;
1728 w = newsizedstringobject(c, 1);
1729 }
1730 break;
1731 case WE_COMMAND:
1732 w = newintobject((long)e.u.command);
1733 break;
1734 case WE_DRAW:
1735 w = makerect(e.u.area.left, e.u.area.top,
1736 e.u.area.right, e.u.area.bottom);
1737 break;
1738 case WE_MOUSE_DOWN:
1739 case WE_MOUSE_MOVE:
1740 case WE_MOUSE_UP:
1741 w = makemouse(e.u.where.h, e.u.where.v,
1742 e.u.where.clicks,
1743 e.u.where.button,
1744 e.u.where.mask);
1745 break;
1746 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001747 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1748 menulist[e.u.m.id - IDOFFSET] != NULL)
1749 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum246b9d81991-06-03 10:55:14 +00001750 else {
1751 /* Ghost menu event.
1752 Can occur only on the Mac if another part
1753 of the aplication has installed a menu;
1754 like the THINK C console library. */
1755 DECREF(v);
1756 goto again;
1757 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001758 w = makemenu(w, e.u.m.item);
1759 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001760 case WE_LOST_SEL:
1761 w = newintobject((long)e.u.sel);
1762 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763 default:
1764 w = None;
1765 INCREF(w);
1766 break;
1767 }
1768 if (w == NULL) {
1769 DECREF(v);
1770 return NULL;
1771 }
1772 settupleitem(v, 2, w);
1773 return v;
1774}
1775
1776static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001777stdwin_getevent(sw, args)
1778 object *sw;
1779 object *args;
1780{
1781 return stdwin_get_poll_event(0, args);
1782}
1783
1784static object *
1785stdwin_pollevent(sw, args)
1786 object *sw;
1787 object *args;
1788{
1789 return stdwin_get_poll_event(1, args);
1790}
1791
1792static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001793stdwin_setdefwinpos(sw, args)
1794 object *sw;
1795 object *args;
1796{
1797 int a[2];
1798 if (!getpointarg(args, a))
1799 return NULL;
1800 wsetdefwinpos(a[0], a[1]);
1801 INCREF(None);
1802 return None;
1803}
1804
1805static object *
1806stdwin_setdefwinsize(sw, args)
1807 object *sw;
1808 object *args;
1809{
1810 int a[2];
1811 if (!getpointarg(args, a))
1812 return NULL;
1813 wsetdefwinsize(a[0], a[1]);
1814 INCREF(None);
1815 return None;
1816}
1817
1818static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001819stdwin_setdefscrollbars(sw, args)
1820 object *sw;
1821 object *args;
1822{
1823 int a[2];
1824 if (!getpointarg(args, a))
1825 return NULL;
1826 wsetdefscrollbars(a[0], a[1]);
1827 INCREF(None);
1828 return None;
1829}
1830
1831static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001832stdwin_getdefwinpos(self, args)
1833 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001834 object *args;
1835{
1836 int h, v;
1837 if (!getnoarg(args))
1838 return NULL;
1839 wgetdefwinpos(&h, &v);
1840 return makepoint(h, v);
1841}
1842
1843static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001844stdwin_getdefwinsize(self, args)
1845 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001846 object *args;
1847{
1848 int width, height;
1849 if (!getnoarg(args))
1850 return NULL;
1851 wgetdefwinsize(&width, &height);
1852 return makepoint(width, height);
1853}
1854
1855static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001856stdwin_getdefscrollbars(self, args)
1857 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001858 object *args;
1859{
1860 int h, v;
1861 if (!getnoarg(args))
1862 return NULL;
1863 wgetdefscrollbars(&h, &v);
1864 return makepoint(h, v);
1865}
1866
1867static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001868stdwin_menucreate(self, args)
1869 object *self;
1870 object *args;
1871{
1872 object *title;
1873 if (!getstrarg(args, &title))
1874 return NULL;
1875 wmenusetdeflocal(0);
1876 return (object *)newmenuobject(title);
1877}
1878
1879static object *
1880stdwin_askfile(self, args)
1881 object *self;
1882 object *args;
1883{
1884 object *prompt, *dflt;
1885 int new, ret;
1886 char buf[256];
1887 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1888 return NULL;
1889 strncpy(buf, getstringvalue(dflt), sizeof buf);
1890 buf[sizeof buf - 1] = '\0';
1891 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1892 if (!ret) {
1893 err_set(KeyboardInterrupt);
1894 return NULL;
1895 }
1896 return newstringobject(buf);
1897}
1898
1899static object *
1900stdwin_askync(self, args)
1901 object *self;
1902 object *args;
1903{
1904 object *prompt;
1905 int new, ret;
1906 if (!getstrintarg(args, &prompt, &new))
1907 return NULL;
1908 ret = waskync(getstringvalue(prompt), new);
1909 if (ret < 0) {
1910 err_set(KeyboardInterrupt);
1911 return NULL;
1912 }
1913 return newintobject((long)ret);
1914}
1915
1916static object *
1917stdwin_askstr(self, args)
1918 object *self;
1919 object *args;
1920{
1921 object *prompt, *dflt;
1922 int ret;
1923 char buf[256];
1924 if (!getstrstrarg(args, &prompt, &dflt))
1925 return NULL;
1926 strncpy(buf, getstringvalue(dflt), sizeof buf);
1927 buf[sizeof buf - 1] = '\0';
1928 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1929 if (!ret) {
1930 err_set(KeyboardInterrupt);
1931 return NULL;
1932 }
1933 return newstringobject(buf);
1934}
1935
1936static object *
1937stdwin_message(self, args)
1938 object *self;
1939 object *args;
1940{
1941 object *msg;
1942 if (!getstrarg(args, &msg))
1943 return NULL;
1944 wmessage(getstringvalue(msg));
1945 INCREF(None);
1946 return None;
1947}
1948
1949static object *
1950stdwin_fleep(self, args)
1951 object *self;
1952 object *args;
1953{
1954 if (!getnoarg(args))
1955 return NULL;
1956 wfleep();
1957 INCREF(None);
1958 return None;
1959}
1960
1961static object *
1962stdwin_setcutbuffer(self, args)
1963 object *self;
1964 object *args;
1965{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001966 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001967 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001968 if (!getintstrarg(args, &i, &str))
1969 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001970 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001971 INCREF(None);
1972 return None;
1973}
1974
1975static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001976stdwin_getactive(self, args)
1977 object *self;
1978 object *args;
1979{
1980 return window2object(wgetactive());
1981}
1982
1983static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984stdwin_getcutbuffer(self, args)
1985 object *self;
1986 object *args;
1987{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001988 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001989 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001990 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001991 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001992 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001993 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001994 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001995 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001996 len = 0;
1997 }
1998 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001999}
2000
Guido van Rossum5b10f451990-10-30 16:01:48 +00002001static object *
2002stdwin_rotatecutbuffers(self, args)
2003 object *self;
2004 object *args;
2005{
2006 int i;
2007 if (!getintarg(args, &i))
2008 return NULL;
2009 wrotatecutbuffers(i);
2010 INCREF(None);
2011 return None;
2012}
2013
2014static object *
2015stdwin_getselection(self, args)
2016 object *self;
2017 object *args;
2018{
2019 int sel;
2020 char *data;
2021 int len;
2022 if (!getintarg(args, &sel))
2023 return NULL;
2024 data = wgetselection(sel, &len);
2025 if (data == NULL) {
2026 data = "";
2027 len = 0;
2028 }
2029 return newsizedstringobject(data, len);
2030}
2031
2032static object *
2033stdwin_resetselection(self, args)
2034 object *self;
2035 object *args;
2036{
2037 int sel;
2038 if (!getintarg(args, &sel))
2039 return NULL;
2040 wresetselection(sel);
2041 INCREF(None);
2042 return None;
2043}
2044
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002045static object *
2046stdwin_fetchcolor(self, args)
2047 object *self;
2048 object *args;
2049{
2050 object *colorname;
2051 if (!getstrarg(args, &colorname))
2052 return NULL;
2053 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
2054}
2055
Guido van Rossum541c8c01991-05-05 20:13:41 +00002056static object *
2057stdwin_getscrsize(self, args)
2058 object *self;
2059 object *args;
2060{
2061 int width, height;
2062 if (!getnoarg(args))
2063 return NULL;
2064 wgetscrsize(&width, &height);
2065 return makepoint(width, height);
2066}
2067
2068static object *
2069stdwin_getscrmm(self, args)
2070 object *self;
2071 object *args;
2072{
2073 int width, height;
2074 if (!getnoarg(args))
2075 return NULL;
2076 wgetscrmm(&width, &height);
2077 return makepoint(width, height);
2078}
2079
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002080static struct methodlist stdwin_methods[] = {
2081 {"askfile", stdwin_askfile},
2082 {"askstr", stdwin_askstr},
2083 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002084 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002085 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002086 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002088 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002089 {"getdefwinpos", stdwin_getdefwinpos},
2090 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002091 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002092 {"getscrmm", stdwin_getscrmm},
2093 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002094 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002095 {"menucreate", stdwin_menucreate},
2096 {"message", stdwin_message},
2097 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002098 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002099 {"resetselection", stdwin_resetselection},
2100 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002101 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002102 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103 {"setdefwinpos", stdwin_setdefwinpos},
2104 {"setdefwinsize", stdwin_setdefwinsize},
2105
2106 /* Text measuring methods borrow code from drawing objects: */
2107 {"baseline", drawing_baseline},
2108 {"lineheight", drawing_lineheight},
2109 {"textbreak", drawing_textbreak},
2110 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002111
2112 /* Same for font setting methods: */
2113 {"setfont", drawing_setfont},
2114
2115 /* Same for color setting/getting methods: */
2116 {"getbgcolor", drawing_getbgcolor},
2117 {"getfgcolor", drawing_getfgcolor},
2118 {"setbgcolor", drawing_setbgcolor},
2119 {"setfgcolor", drawing_setfgcolor},
2120
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002121 {NULL, NULL} /* sentinel */
2122};
2123
2124void
2125initstdwin()
2126{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002127 static int inited;
2128 if (!inited) {
2129 winit();
2130 inited = 1;
2131 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002132 initmodule("stdwin", stdwin_methods);
2133}