blob: 07bb866b2f20b15efee75411131732d5149d13f6 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Stdwin module */
26
27/* Stdwin itself is a module, not a separate object type.
28 Object types defined here:
29 wp: a window
30 dp: a drawing structure (only one can exist at a time)
31 mp: a menu
32 tp: a textedit block
33*/
34
35/* Rules for translating C stdwin function calls into Python stwin:
36 - All names drop their initial letter 'w'
37 - Functions with a window as first parameter are methods of window objects
38 - There is no equivalent for wclose(); just delete the window object
39 (all references to it!) (XXX maybe this is a bad idea)
40 - w.begindrawing() returns a drawing object
41 - There is no equivalent for wenddrawing(win); just delete the drawing
42 object (all references to it!) (XXX maybe this is a bad idea)
43 - Functions that may only be used inside wbegindrawing / wendddrawing
44 are methods of the drawing object; this includes the text measurement
45 functions (which however have doubles as module functions).
46 - Methods of the drawing object drop an initial 'draw' from their name
47 if they have it, e.g., wdrawline() --> d.line()
48 - The obvious type conversions: int --> intobject; string --> stringobject
49 - A text parameter followed by a length parameter is only a text (string)
50 parameter in Python
51 - A point or other pair of horizontal and vertical coordinates is always
52 a pair of integers in Python
53 - Two points forming a rectangle or endpoints of a line segment are a
54 pair of points in Python
55 - The arguments to d.elarc() are three points.
56 - The functions wgetclip() and wsetclip() are translated into
57 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
58 a bad word for what these functions do (clipping has a different
59 meaning in the drawing world), while cutbuffer is standard X jargon.
Guido van Rossum01769f01990-10-30 13:39:00 +000060 XXX This must change again in the light of changes to stdwin!
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 - For textedit, similar rules hold, but they are less strict.
62 XXX more?
63*/
64
Guido van Rossum3f5da241990-12-20 15:06:42 +000065#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068
Guido van Rossum3f5da241990-12-20 15:06:42 +000069#include "stdwin.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070
71/* Window and menu object types declared here because of forward references */
72
73typedef struct {
74 OB_HEAD
75 object *w_title;
76 WINDOW *w_win;
77 object *w_attr; /* Attributes dictionary */
78} windowobject;
79
80extern typeobject Windowtype; /* Really static, forward */
81
82#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
83
84typedef struct {
85 OB_HEAD
86 MENU *m_menu;
87 int m_id;
88 object *m_attr; /* Attributes dictionary */
89} menuobject;
90
91extern typeobject Menutype; /* Really static, forward */
92
93#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
94
95
96/* Strongly stdwin-specific argument handlers */
97
98static int
99getmousedetail(v, ep)
100 object *v;
101 EVENT *ep;
102{
103 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 4)
104 return err_badarg();
105 return getintintarg(gettupleitem(v, 0),
106 &ep->u.where.h, &ep->u.where.v) &&
107 getintarg(gettupleitem(v, 1), &ep->u.where.clicks) &&
108 getintarg(gettupleitem(v, 2), &ep->u.where.button) &&
109 getintarg(gettupleitem(v, 3), &ep->u.where.mask);
110}
111
112static int
113getmenudetail(v, ep)
114 object *v;
115 EVENT *ep;
116{
117 object *mp;
118 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2)
119 return err_badarg();
120 mp = gettupleitem(v, 0);
121 if (mp == NULL || !is_menuobject(mp))
122 return err_badarg();
123 ep->u.m.id = ((menuobject *)mp) -> m_id;
124 return getintarg(gettupleitem(v, 1), &ep->u.m.item);
125}
126
127static int
128geteventarg(v, ep)
129 object *v;
130 EVENT *ep;
131{
132 object *wp, *detail;
133 int a[4];
134 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3)
135 return err_badarg();
136 if (!getintarg(gettupleitem(v, 0), &ep->type))
137 return 0;
138 wp = gettupleitem(v, 1);
139 if (wp == None)
140 ep->window = NULL;
141 else if (wp == NULL || !is_windowobject(wp))
142 return err_badarg();
143 else
144 ep->window = ((windowobject *)wp) -> w_win;
145 detail = gettupleitem(v, 2);
146 switch (ep->type) {
147 case WE_CHAR:
148 if (!is_stringobject(detail) || getstringsize(detail) != 1)
149 return err_badarg();
150 ep->u.character = getstringvalue(detail)[0];
151 return 1;
152 case WE_COMMAND:
153 return getintarg(detail, &ep->u.command);
154 case WE_DRAW:
155 if (!getrectarg(detail, a))
156 return 0;
157 ep->u.area.left = a[0];
158 ep->u.area.top = a[1];
159 ep->u.area.right = a[2];
160 ep->u.area.bottom = a[3];
161 return 1;
162 case WE_MOUSE_DOWN:
163 case WE_MOUSE_UP:
164 case WE_MOUSE_MOVE:
165 return getmousedetail(detail, ep);
166 case WE_MENU:
167 return getmenudetail(detail, ep);
168 default:
169 return 1;
170 }
171}
172
173
174/* Return construction tools */
175
176static object *
177makepoint(a, b)
178 int a, b;
179{
180 object *v;
181 object *w;
182 if ((v = newtupleobject(2)) == NULL)
183 return NULL;
184 if ((w = newintobject((long)a)) == NULL ||
185 settupleitem(v, 0, w) != 0 ||
186 (w = newintobject((long)b)) == NULL ||
187 settupleitem(v, 1, w) != 0) {
188 DECREF(v);
189 return NULL;
190 }
191 return v;
192}
193
194static object *
195makerect(a, b, c, d)
196 int a, b, c, d;
197{
198 object *v;
199 object *w;
200 if ((v = newtupleobject(2)) == NULL)
201 return NULL;
202 if ((w = makepoint(a, b)) == NULL ||
203 settupleitem(v, 0, w) != 0 ||
204 (w = makepoint(c, d)) == NULL ||
205 settupleitem(v, 1, w) != 0) {
206 DECREF(v);
207 return NULL;
208 }
209 return v;
210}
211
212static object *
213makemouse(hor, ver, clicks, button, mask)
214 int hor, ver, clicks, button, mask;
215{
216 object *v;
217 object *w;
218 if ((v = newtupleobject(4)) == NULL)
219 return NULL;
220 if ((w = makepoint(hor, ver)) == NULL ||
221 settupleitem(v, 0, w) != 0 ||
222 (w = newintobject((long)clicks)) == NULL ||
223 settupleitem(v, 1, w) != 0 ||
224 (w = newintobject((long)button)) == NULL ||
225 settupleitem(v, 2, w) != 0 ||
226 (w = newintobject((long)mask)) == NULL ||
227 settupleitem(v, 3, w) != 0) {
228 DECREF(v);
229 return NULL;
230 }
231 return v;
232}
233
234static object *
235makemenu(mp, item)
236 object *mp;
237 int item;
238{
239 object *v;
240 object *w;
241 if ((v = newtupleobject(2)) == NULL)
242 return NULL;
243 INCREF(mp);
244 if (settupleitem(v, 0, mp) != 0 ||
245 (w = newintobject((long)item)) == NULL ||
246 settupleitem(v, 1, w) != 0) {
247 DECREF(v);
248 return NULL;
249 }
250 return v;
251}
252
253
254/* Drawing objects */
255
256typedef struct {
257 OB_HEAD
258 windowobject *d_ref;
259} drawingobject;
260
261static drawingobject *Drawing; /* Set to current drawing object, or NULL */
262
263/* Drawing methods */
264
265static void
266drawing_dealloc(dp)
267 drawingobject *dp;
268{
269 wenddrawing(dp->d_ref->w_win);
270 Drawing = NULL;
271 DECREF(dp->d_ref);
272 free((char *)dp);
273}
274
275static object *
276drawing_generic(dp, args, func)
277 drawingobject *dp;
278 object *args;
279 void (*func) FPROTO((int, int, int, int));
280{
281 int a[4];
282 if (!getrectarg(args, a))
283 return NULL;
284 (*func)(a[0], a[1], a[2], a[3]);
285 INCREF(None);
286 return None;
287}
288
289static object *
290drawing_line(dp, args)
291 drawingobject *dp;
292 object *args;
293{
Guido van Rossumbf109731991-03-06 13:14:12 +0000294 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295}
296
297static object *
298drawing_xorline(dp, args)
299 drawingobject *dp;
300 object *args;
301{
Guido van Rossumbf109731991-03-06 13:14:12 +0000302 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303}
304
305static object *
306drawing_circle(dp, args)
307 drawingobject *dp;
308 object *args;
309{
310 int a[3];
311 if (!getpointintarg(args, a))
312 return NULL;
313 wdrawcircle(a[0], a[1], a[2]);
314 INCREF(None);
315 return None;
316}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000317
Guido van Rossum27201061991-04-16 08:43:03 +0000318static object *
319drawing_fillcircle(dp, args)
320 drawingobject *dp;
321 object *args;
322{
323 int a[3];
324 if (!getpointintarg(args, a))
325 return NULL;
326 wfillcircle(a[0], a[1], a[2]);
327 INCREF(None);
328 return None;
329}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330
331static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000332drawing_xorcircle(dp, args)
333 drawingobject *dp;
334 object *args;
335{
336 int a[3];
337 if (!getpointintarg(args, a))
338 return NULL;
339 wxorcircle(a[0], a[1], a[2]);
340 INCREF(None);
341 return None;
342}
343
344static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345drawing_elarc(dp, args)
346 drawingobject *dp;
347 object *args;
348{
349 int a[6];
350 if (!get3pointarg(args, a))
351 return NULL;
352 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
353 INCREF(None);
354 return None;
355}
356
357static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000358drawing_fillelarc(dp, args)
359 drawingobject *dp;
360 object *args;
361{
362 int a[6];
363 if (!get3pointarg(args, a))
364 return NULL;
365 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
366 INCREF(None);
367 return None;
368}
369
370static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000371drawing_xorelarc(dp, args)
372 drawingobject *dp;
373 object *args;
374{
375 int a[6];
376 if (!get3pointarg(args, a))
377 return NULL;
378 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
379 INCREF(None);
380 return None;
381}
382
383static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384drawing_box(dp, args)
385 drawingobject *dp;
386 object *args;
387{
Guido van Rossumbf109731991-03-06 13:14:12 +0000388 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
391static object *
392drawing_erase(dp, args)
393 drawingobject *dp;
394 object *args;
395{
Guido van Rossumbf109731991-03-06 13:14:12 +0000396 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397}
398
399static object *
400drawing_paint(dp, args)
401 drawingobject *dp;
402 object *args;
403{
Guido van Rossumbf109731991-03-06 13:14:12 +0000404 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
407static object *
408drawing_invert(dp, args)
409 drawingobject *dp;
410 object *args;
411{
Guido van Rossumbf109731991-03-06 13:14:12 +0000412 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossum27201061991-04-16 08:43:03 +0000415static POINT *
416getpointsarray(v, psize)
417 object *v;
418 int *psize;
419{
420 int n = -1;
421 object * (*getitem) PROTO((object *, int));
422 int i;
423 POINT *points;
424
425 if (v == NULL)
426 ;
427 else if (is_listobject(v)) {
428 n = getlistsize(v);
429 getitem = getlistitem;
430 }
431 else if (is_tupleobject(v)) {
432 n = gettuplesize(v);
433 getitem = gettupleitem;
434 }
435
436 if (n <= 0) {
437 (void) err_badarg();
438 return NULL;
439 }
440
441 points = NEW(POINT, n);
442 if (points == NULL) {
443 (void) err_nomem();
444 return NULL;
445 }
446
447 for (i = 0; i < n; i++) {
448 object *w = (*getitem)(v, i);
449 int a[2];
450 if (!getpointarg(w, a)) {
451 DEL(points);
452 return NULL;
453 }
454 points[i].h = a[0];
455 points[i].v = a[1];
456 }
457
458 *psize = n;
459 return points;
460}
461
462static object *
463drawing_poly(dp, args)
464 drawingobject *dp;
465 object *args;
466{
467 int n;
468 POINT *points = getpointsarray(args, &n);
469 if (points == NULL)
470 return NULL;
471 wdrawpoly(n, points);
472 DEL(points);
473 INCREF(None);
474 return None;
475}
476
477static object *
478drawing_fillpoly(dp, args)
479 drawingobject *dp;
480 object *args;
481{
482 int n;
483 POINT *points = getpointsarray(args, &n);
484 if (points == NULL)
485 return NULL;
486 wfillpoly(n, points);
487 DEL(points);
488 INCREF(None);
489 return None;
490}
491
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000493drawing_xorpoly(dp, args)
494 drawingobject *dp;
495 object *args;
496{
497 int n;
498 POINT *points = getpointsarray(args, &n);
499 if (points == NULL)
500 return NULL;
501 wxorpoly(n, points);
502 DEL(points);
503 INCREF(None);
504 return None;
505}
506
507static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508drawing_cliprect(dp, args)
509 drawingobject *dp;
510 object *args;
511{
Guido van Rossumbf109731991-03-06 13:14:12 +0000512 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
515static object *
516drawing_noclip(dp, args)
517 drawingobject *dp;
518 object *args;
519{
520 if (!getnoarg(args))
521 return NULL;
522 wnoclip();
523 INCREF(None);
524 return None;
525}
526
527static object *
528drawing_shade(dp, args)
529 drawingobject *dp;
530 object *args;
531{
532 int a[5];
533 if (!getrectintarg(args, a))
534 return NULL;
535 wshade(a[0], a[1], a[2], a[3], a[4]);
536 INCREF(None);
537 return None;
538}
539
540static object *
541drawing_text(dp, args)
542 drawingobject *dp;
543 object *args;
544{
545 int a[2];
546 object *s;
547 if (!getpointstrarg(args, a, &s))
548 return NULL;
549 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
550 INCREF(None);
551 return None;
552}
553
554/* The following four are also used as stdwin functions */
555
556static object *
557drawing_lineheight(dp, args)
558 drawingobject *dp;
559 object *args;
560{
561 if (!getnoarg(args))
562 return NULL;
563 return newintobject((long)wlineheight());
564}
565
566static object *
567drawing_baseline(dp, args)
568 drawingobject *dp;
569 object *args;
570{
571 if (!getnoarg(args))
572 return NULL;
573 return newintobject((long)wbaseline());
574}
575
576static object *
577drawing_textwidth(dp, args)
578 drawingobject *dp;
579 object *args;
580{
581 object *s;
582 if (!getstrarg(args, &s))
583 return NULL;
584 return newintobject(
585 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
586}
587
588static object *
589drawing_textbreak(dp, args)
590 drawingobject *dp;
591 object *args;
592{
593 object *s;
594 int a;
595 if (!getstrintarg(args, &s, &a))
596 return NULL;
597 return newintobject(
598 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
599}
600
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000601static object *
602drawing_setfont(self, args)
603 drawingobject *self;
604 object *args;
605{
Guido van Rossum50429a11991-04-04 15:24:07 +0000606 object *font, *style;
607 int size;
608 if (args == NULL) {
609 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000610 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000611 }
612 if (is_stringobject(args)) {
613 font = args;
614 style = NULL;
615 size = 0;
616 }
617 else if (is_tupleobject(args)) {
618 int n = gettuplesize(args);
619 if (n == 2) {
620 if (!getstrintarg(args, &font, &size))
621 return NULL;
622 style = NULL;
623 }
624 else if (!getstrstrintarg(args, &font, &style, &size))
625 return NULL;
626 }
627 else {
628 err_badarg();
629 return NULL;
630 }
631 if (getstringsize(font) != 0)
632 wsetfont(getstringvalue(font));
633 if (style != NULL) {
634 switch (*getstringvalue(style)) {
635 case 'b':
636 wsetbold();
637 break;
638 case 'i':
639 wsetitalic();
640 break;
641 case 'o':
642 wsetbolditalic();
643 break;
644 case 'u':
645 wsetunderline();
646 break;
647 default:
648 wsetplain();
649 break;
650 }
651 }
652 if (size != 0)
653 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000654 INCREF(None);
655 return None;
656}
657
658static object *
659drawing_getbgcolor(self, args)
660 object *self;
661 object *args;
662{
663 if (!getnoarg(args))
664 return NULL;
665 return newintobject((long)wgetbgcolor());
666}
667
668static object *
669drawing_getfgcolor(self, args)
670 object *self;
671 object *args;
672{
673 if (!getnoarg(args))
674 return NULL;
675 return newintobject((long)wgetfgcolor());
676}
677
678static object *
679drawing_setbgcolor(self, args)
680 object *self;
681 object *args;
682{
683 long color;
684 if (!getlongarg(args, &color))
685 return NULL;
686 wsetbgcolor((COLOR)color);
687 INCREF(None);
688 return None;
689}
690
691static object *
692drawing_setfgcolor(self, args)
693 object *self;
694 object *args;
695{
696 long color;
697 if (!getlongarg(args, &color))
698 return NULL;
699 wsetfgcolor((COLOR)color);
700 INCREF(None);
701 return None;
702}
703
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704static struct methodlist drawing_methods[] = {
705 {"box", drawing_box},
706 {"circle", drawing_circle},
707 {"cliprect", drawing_cliprect},
708 {"elarc", drawing_elarc},
709 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000710 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000711 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000712 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713 {"invert", drawing_invert},
714 {"line", drawing_line},
715 {"noclip", drawing_noclip},
716 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000717 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000718 {"shade", drawing_shade},
719 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000720 {"xorcircle", drawing_xorcircle},
721 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000723 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724
725 /* Text measuring methods: */
726 {"baseline", drawing_baseline},
727 {"lineheight", drawing_lineheight},
728 {"textbreak", drawing_textbreak},
729 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000730
731 /* Font setting methods: */
732 {"setfont", drawing_setfont},
733
734 /* Color methods: */
735 {"getbgcolor", drawing_getbgcolor},
736 {"getfgcolor", drawing_getfgcolor},
737 {"setbgcolor", drawing_setbgcolor},
738 {"setfgcolor", drawing_setfgcolor},
739
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 {NULL, NULL} /* sentinel */
741};
742
743static object *
744drawing_getattr(wp, name)
745 drawingobject *wp;
746 char *name;
747{
748 return findmethod(drawing_methods, (object *)wp, name);
749}
750
Guido van Rossum541c8c01991-05-05 20:13:41 +0000751typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000752 OB_HEAD_INIT(&Typetype)
753 0, /*ob_size*/
754 "drawing", /*tp_name*/
755 sizeof(drawingobject), /*tp_size*/
756 0, /*tp_itemsize*/
757 /* methods */
758 drawing_dealloc, /*tp_dealloc*/
759 0, /*tp_print*/
760 drawing_getattr, /*tp_getattr*/
761 0, /*tp_setattr*/
762 0, /*tp_compare*/
763 0, /*tp_repr*/
764};
765
766
767/* Text(edit) objects */
768
769typedef struct {
770 OB_HEAD
771 TEXTEDIT *t_text;
772 windowobject *t_ref;
773 object *t_attr; /* Attributes dictionary */
774} textobject;
775
776extern typeobject Texttype; /* Really static, forward */
777
778static textobject *
779newtextobject(wp, left, top, right, bottom)
780 windowobject *wp;
781 int left, top, right, bottom;
782{
783 textobject *tp;
784 tp = NEWOBJ(textobject, &Texttype);
785 if (tp == NULL)
786 return NULL;
787 tp->t_attr = NULL;
788 INCREF(wp);
789 tp->t_ref = wp;
790 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
791 if (tp->t_text == NULL) {
792 DECREF(tp);
793 return (textobject *) err_nomem();
794 }
795 return tp;
796}
797
798/* Text(edit) methods */
799
800static void
801text_dealloc(tp)
802 textobject *tp;
803{
804 if (tp->t_text != NULL)
805 tefree(tp->t_text);
806 if (tp->t_attr != NULL)
807 DECREF(tp->t_attr);
808 DECREF(tp->t_ref);
809 DEL(tp);
810}
811
812static object *
813text_arrow(self, args)
814 textobject *self;
815 object *args;
816{
817 int code;
818 if (!getintarg(args, &code))
819 return NULL;
820 tearrow(self->t_text, code);
821 INCREF(None);
822 return None;
823}
824
825static object *
826text_draw(self, args)
827 textobject *self;
828 object *args;
829{
830 register TEXTEDIT *tp = self->t_text;
831 int a[4];
832 int left, top, right, bottom;
833 if (!getrectarg(args, a))
834 return NULL;
835 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000836 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000837 return NULL;
838 }
839 /* Clip to text area and ignore if area is empty */
840 left = tegetleft(tp);
841 top = tegettop(tp);
842 right = tegetright(tp);
843 bottom = tegetbottom(tp);
844 if (a[0] < left) a[0] = left;
845 if (a[1] < top) a[1] = top;
846 if (a[2] > right) a[2] = right;
847 if (a[3] > bottom) a[3] = bottom;
848 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850 tedrawnew(tp, a[0], a[1], a[2], a[3]);
851 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852 }
853 INCREF(None);
854 return None;
855}
856
857static object *
858text_event(self, args)
859 textobject *self;
860 object *args;
861{
862 register TEXTEDIT *tp = self->t_text;
863 EVENT e;
864 if (!geteventarg(args, &e))
865 return NULL;
866 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000867 /* Cheat at the margins */
868 int width, height;
869 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000870 if (e.u.where.h < 0 && tegetleft(tp) == 0)
871 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000872 else if (e.u.where.h > width && tegetright(tp) == width)
873 e.u.where.h = width;
874 if (e.u.where.v < 0 && tegettop(tp) == 0)
875 e.u.where.v = 0;
876 else if (e.u.where.v > height && tegetright(tp) == height)
877 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878 }
879 return newintobject((long) teevent(tp, &e));
880}
881
882static object *
883text_getfocus(self, args)
884 textobject *self;
885 object *args;
886{
887 if (!getnoarg(args))
888 return NULL;
889 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
890}
891
892static object *
893text_getfocustext(self, args)
894 textobject *self;
895 object *args;
896{
897 int f1, f2;
898 char *text;
899 if (!getnoarg(args))
900 return NULL;
901 f1 = tegetfoc1(self->t_text);
902 f2 = tegetfoc2(self->t_text);
903 text = tegettext(self->t_text);
904 return newsizedstringobject(text + f1, f2-f1);
905}
906
907static object *
908text_getrect(self, args)
909 textobject *self;
910 object *args;
911{
912 if (!getnoarg(args))
913 return NULL;
914 return makerect(tegetleft(self->t_text),
915 tegettop(self->t_text),
916 tegetright(self->t_text),
917 tegetbottom(self->t_text));
918}
919
920static object *
921text_gettext(self, args)
922 textobject *self;
923 object *args;
924{
925 if (!getnoarg(args))
926 return NULL;
927 return newsizedstringobject(tegettext(self->t_text),
928 tegetlen(self->t_text));
929}
930
931static object *
932text_move(self, args)
933 textobject *self;
934 object *args;
935{
936 int a[4];
937 if (!getrectarg(args, a))
938 return NULL;
939 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
940 INCREF(None);
941 return None;
942}
943
944static object *
945text_setfocus(self, args)
946 textobject *self;
947 object *args;
948{
949 int a[2];
950 if (!getpointarg(args, a))
951 return NULL;
952 tesetfocus(self->t_text, a[0], a[1]);
953 INCREF(None);
954 return None;
955}
956
957static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000958text_settext(self, args)
959 textobject *self;
960 object *args;
961{
962 object *text;
963 char *buf;
964 int size;
965 if (!getstrarg(args, &text))
966 return NULL;
967 size = getstringsize(text);
968 if ((buf = NEW(char, size)) == NULL) {
969 err_set(MemoryError);
970 return NULL;
971 }
972 memcpy(buf, getstringvalue(text), size);
973 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
974 INCREF(None);
975 return None;
976}
977
978static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000979text_replace(self, args)
980 textobject *self;
981 object *args;
982{
983 object *text;
984 if (!getstrarg(args, &text))
985 return NULL;
986 tereplace(self->t_text, getstringvalue(text));
987 INCREF(None);
988 return None;
989}
990
991static struct methodlist text_methods[] = {
992 "arrow", text_arrow,
993 "draw", text_draw,
994 "event", text_event,
995 "getfocus", text_getfocus,
996 "getfocustext", text_getfocustext,
997 "getrect", text_getrect,
998 "gettext", text_gettext,
999 "move", text_move,
1000 "replace", text_replace,
1001 "setfocus", text_setfocus,
Guido van Rossum541c8c01991-05-05 20:13:41 +00001002 "settext", text_settext,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001003 {NULL, NULL} /* sentinel */
1004};
1005
1006static object *
1007text_getattr(tp, name)
1008 textobject *tp;
1009 char *name;
1010{
1011 if (tp->t_attr != NULL) {
1012 object *v = dictlookup(tp->t_attr, name);
1013 if (v != NULL) {
1014 INCREF(v);
1015 return v;
1016 }
1017 }
1018 return findmethod(text_methods, (object *)tp, name);
1019}
1020
1021static int
1022text_setattr(tp, name, v)
1023 textobject *tp;
1024 char *name;
1025 object *v;
1026{
1027 if (tp->t_attr == NULL) {
1028 tp->t_attr = newdictobject();
1029 if (tp->t_attr == NULL)
1030 return -1;
1031 }
1032 if (v == NULL)
1033 return dictremove(tp->t_attr, name);
1034 else
1035 return dictinsert(tp->t_attr, name, v);
1036}
1037
Guido van Rossum541c8c01991-05-05 20:13:41 +00001038typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001039 OB_HEAD_INIT(&Typetype)
1040 0, /*ob_size*/
1041 "textedit", /*tp_name*/
1042 sizeof(textobject), /*tp_size*/
1043 0, /*tp_itemsize*/
1044 /* methods */
1045 text_dealloc, /*tp_dealloc*/
1046 0, /*tp_print*/
1047 text_getattr, /*tp_getattr*/
1048 text_setattr, /*tp_setattr*/
1049 0, /*tp_compare*/
1050 0, /*tp_repr*/
1051};
1052
1053
1054/* Menu objects */
1055
Guido van Rossum2d14e211991-02-19 12:26:49 +00001056#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001057#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001058static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001059
1060static menuobject *
1061newmenuobject(title)
1062 object *title;
1063{
1064 int id;
1065 MENU *menu;
1066 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001067 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001068 if (menulist[id] == NULL)
1069 break;
1070 }
Guido van Rossum27201061991-04-16 08:43:03 +00001071 if (id >= MAXNMENU) {
1072 err_setstr(MemoryError, "creating too many menus");
1073 return NULL;
1074 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001075 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001076 if (menu == NULL)
1077 return (menuobject *) err_nomem();
1078 mp = NEWOBJ(menuobject, &Menutype);
1079 if (mp != NULL) {
1080 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001081 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001082 mp->m_attr = NULL;
1083 menulist[id] = mp;
1084 }
1085 else
1086 wmenudelete(menu);
1087 return mp;
1088}
1089
1090/* Menu methods */
1091
1092static void
1093menu_dealloc(mp)
1094 menuobject *mp;
1095{
1096
Guido van Rossum2d14e211991-02-19 12:26:49 +00001097 int id = mp->m_id - IDOFFSET;
1098 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099 menulist[id] = NULL;
1100 }
1101 wmenudelete(mp->m_menu);
1102 if (mp->m_attr != NULL)
1103 DECREF(mp->m_attr);
1104 DEL(mp);
1105}
1106
1107static object *
1108menu_additem(self, args)
1109 menuobject *self;
1110 object *args;
1111{
1112 object *text;
1113 int shortcut;
1114 if (is_tupleobject(args)) {
1115 object *v;
1116 if (!getstrstrarg(args, &text, &v))
1117 return NULL;
1118 if (getstringsize(v) != 1) {
1119 err_badarg();
1120 return NULL;
1121 }
1122 shortcut = *getstringvalue(v) & 0xff;
1123 }
1124 else {
1125 if (!getstrarg(args, &text))
1126 return NULL;
1127 shortcut = -1;
1128 }
1129 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1130 INCREF(None);
1131 return None;
1132}
1133
1134static object *
1135menu_setitem(self, args)
1136 menuobject *self;
1137 object *args;
1138{
1139 int index;
1140 object *text;
1141 if (!getintstrarg(args, &index, &text))
1142 return NULL;
1143 wmenusetitem(self->m_menu, index, getstringvalue(text));
1144 INCREF(None);
1145 return None;
1146}
1147
1148static object *
1149menu_enable(self, args)
1150 menuobject *self;
1151 object *args;
1152{
1153 int index;
1154 int flag;
1155 if (!getintintarg(args, &index, &flag))
1156 return NULL;
1157 wmenuenable(self->m_menu, index, flag);
1158 INCREF(None);
1159 return None;
1160}
1161
1162static object *
1163menu_check(self, args)
1164 menuobject *self;
1165 object *args;
1166{
1167 int index;
1168 int flag;
1169 if (!getintintarg(args, &index, &flag))
1170 return NULL;
1171 wmenucheck(self->m_menu, index, flag);
1172 INCREF(None);
1173 return None;
1174}
1175
1176static struct methodlist menu_methods[] = {
1177 "additem", menu_additem,
1178 "setitem", menu_setitem,
1179 "enable", menu_enable,
1180 "check", menu_check,
1181 {NULL, NULL} /* sentinel */
1182};
1183
1184static object *
1185menu_getattr(mp, name)
1186 menuobject *mp;
1187 char *name;
1188{
1189 if (mp->m_attr != NULL) {
1190 object *v = dictlookup(mp->m_attr, name);
1191 if (v != NULL) {
1192 INCREF(v);
1193 return v;
1194 }
1195 }
1196 return findmethod(menu_methods, (object *)mp, name);
1197}
1198
1199static int
1200menu_setattr(mp, name, v)
1201 menuobject *mp;
1202 char *name;
1203 object *v;
1204{
1205 if (mp->m_attr == NULL) {
1206 mp->m_attr = newdictobject();
1207 if (mp->m_attr == NULL)
1208 return -1;
1209 }
1210 if (v == NULL)
1211 return dictremove(mp->m_attr, name);
1212 else
1213 return dictinsert(mp->m_attr, name, v);
1214}
1215
Guido van Rossum541c8c01991-05-05 20:13:41 +00001216typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217 OB_HEAD_INIT(&Typetype)
1218 0, /*ob_size*/
1219 "menu", /*tp_name*/
1220 sizeof(menuobject), /*tp_size*/
1221 0, /*tp_itemsize*/
1222 /* methods */
1223 menu_dealloc, /*tp_dealloc*/
1224 0, /*tp_print*/
1225 menu_getattr, /*tp_getattr*/
1226 menu_setattr, /*tp_setattr*/
1227 0, /*tp_compare*/
1228 0, /*tp_repr*/
1229};
1230
1231
1232/* Windows */
1233
1234#define MAXNWIN 50
1235static windowobject *windowlist[MAXNWIN];
1236
1237/* Window methods */
1238
1239static void
1240window_dealloc(wp)
1241 windowobject *wp;
1242{
1243 if (wp->w_win != NULL) {
1244 int tag = wgettag(wp->w_win);
1245 if (tag >= 0 && tag < MAXNWIN)
1246 windowlist[tag] = NULL;
1247 else
1248 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1249 tag);
1250 wclose(wp->w_win);
1251 }
1252 DECREF(wp->w_title);
1253 if (wp->w_attr != NULL)
1254 DECREF(wp->w_attr);
1255 free((char *)wp);
1256}
1257
1258static void
1259window_print(wp, fp, flags)
1260 windowobject *wp;
1261 FILE *fp;
1262 int flags;
1263{
1264 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1265}
1266
1267static object *
1268window_begindrawing(wp, args)
1269 windowobject *wp;
1270 object *args;
1271{
1272 drawingobject *dp;
1273 if (!getnoarg(args))
1274 return NULL;
1275 if (Drawing != NULL) {
1276 err_setstr(RuntimeError, "already drawing");
1277 return NULL;
1278 }
1279 dp = NEWOBJ(drawingobject, &Drawingtype);
1280 if (dp == NULL)
1281 return NULL;
1282 Drawing = dp;
1283 INCREF(wp);
1284 dp->d_ref = wp;
1285 wbegindrawing(wp->w_win);
1286 return (object *)dp;
1287}
1288
1289static object *
1290window_change(wp, args)
1291 windowobject *wp;
1292 object *args;
1293{
1294 int a[4];
1295 if (!getrectarg(args, a))
1296 return NULL;
1297 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1298 INCREF(None);
1299 return None;
1300}
1301
1302static object *
1303window_gettitle(wp, args)
1304 windowobject *wp;
1305 object *args;
1306{
1307 if (!getnoarg(args))
1308 return NULL;
1309 INCREF(wp->w_title);
1310 return wp->w_title;
1311}
1312
1313static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001314window_getwinpos(wp, args)
1315 windowobject *wp;
1316 object *args;
1317{
1318 int h, v;
1319 if (!getnoarg(args))
1320 return NULL;
1321 wgetwinpos(wp->w_win, &h, &v);
1322 return makepoint(h, v);
1323}
1324
1325static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326window_getwinsize(wp, args)
1327 windowobject *wp;
1328 object *args;
1329{
1330 int width, height;
1331 if (!getnoarg(args))
1332 return NULL;
1333 wgetwinsize(wp->w_win, &width, &height);
1334 return makepoint(width, height);
1335}
1336
1337static object *
1338window_getdocsize(wp, args)
1339 windowobject *wp;
1340 object *args;
1341{
1342 int width, height;
1343 if (!getnoarg(args))
1344 return NULL;
1345 wgetdocsize(wp->w_win, &width, &height);
1346 return makepoint(width, height);
1347}
1348
1349static object *
1350window_getorigin(wp, args)
1351 windowobject *wp;
1352 object *args;
1353{
1354 int width, height;
1355 if (!getnoarg(args))
1356 return NULL;
1357 wgetorigin(wp->w_win, &width, &height);
1358 return makepoint(width, height);
1359}
1360
1361static object *
1362window_scroll(wp, args)
1363 windowobject *wp;
1364 object *args;
1365{
1366 int a[6];
1367 if (!getrectpointarg(args, a))
1368 return NULL;
1369 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1370 INCREF(None);
1371 return None;
1372}
1373
1374static object *
1375window_setdocsize(wp, args)
1376 windowobject *wp;
1377 object *args;
1378{
1379 int a[2];
1380 if (!getpointarg(args, a))
1381 return NULL;
1382 wsetdocsize(wp->w_win, a[0], a[1]);
1383 INCREF(None);
1384 return None;
1385}
1386
1387static object *
1388window_setorigin(wp, args)
1389 windowobject *wp;
1390 object *args;
1391{
1392 int a[2];
1393 if (!getpointarg(args, a))
1394 return NULL;
1395 wsetorigin(wp->w_win, a[0], a[1]);
1396 INCREF(None);
1397 return None;
1398}
1399
1400static object *
1401window_settitle(wp, args)
1402 windowobject *wp;
1403 object *args;
1404{
1405 object *title;
1406 if (!getstrarg(args, &title))
1407 return NULL;
1408 DECREF(wp->w_title);
1409 INCREF(title);
1410 wp->w_title = title;
1411 wsettitle(wp->w_win, getstringvalue(title));
1412 INCREF(None);
1413 return None;
1414}
1415
1416static object *
1417window_show(wp, args)
1418 windowobject *wp;
1419 object *args;
1420{
1421 int a[4];
1422 if (!getrectarg(args, a))
1423 return NULL;
1424 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1425 INCREF(None);
1426 return None;
1427}
1428
1429static object *
1430window_settimer(wp, args)
1431 windowobject *wp;
1432 object *args;
1433{
1434 int a;
1435 if (!getintarg(args, &a))
1436 return NULL;
1437 wsettimer(wp->w_win, a);
1438 INCREF(None);
1439 return None;
1440}
1441
1442static object *
1443window_menucreate(self, args)
1444 windowobject *self;
1445 object *args;
1446{
1447 menuobject *mp;
1448 object *title;
1449 if (!getstrarg(args, &title))
1450 return NULL;
1451 wmenusetdeflocal(1);
1452 mp = newmenuobject(title);
1453 if (mp == NULL)
1454 return NULL;
1455 wmenuattach(self->w_win, mp->m_menu);
1456 return (object *)mp;
1457}
1458
1459static object *
1460window_textcreate(self, args)
1461 windowobject *self;
1462 object *args;
1463{
1464 textobject *tp;
1465 int a[4];
1466 if (!getrectarg(args, a))
1467 return NULL;
1468 return (object *)
1469 newtextobject(self, a[0], a[1], a[2], a[3]);
1470}
1471
Guido van Rossum5b10f451990-10-30 16:01:48 +00001472static object *
1473window_setselection(self, args)
1474 windowobject *self;
1475 object *args;
1476{
1477 int sel;
1478 object *str;
1479 int ok;
1480 if (!getintstrarg(args, &sel, &str))
1481 return NULL;
1482 ok = wsetselection(self->w_win, sel,
1483 getstringvalue(str), (int)getstringsize(str));
1484 return newintobject(ok);
1485}
1486
1487static object *
1488window_setwincursor(self, args)
1489 windowobject *self;
1490 object *args;
1491{
1492 object *str;
1493 CURSOR *c;
1494 if (!getstrarg(args, &str))
1495 return NULL;
1496 c = wfetchcursor(getstringvalue(str));
1497 if (c == NULL) {
1498 err_setstr(RuntimeError, "no such cursor");
1499 return NULL;
1500 }
1501 wsetwincursor(self->w_win, c);
1502 INCREF(None);
1503 return None;
1504}
1505
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001506static struct methodlist window_methods[] = {
1507 {"begindrawing",window_begindrawing},
1508 {"change", window_change},
1509 {"getdocsize", window_getdocsize},
1510 {"getorigin", window_getorigin},
1511 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001512 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001513 {"getwinsize", window_getwinsize},
1514 {"menucreate", window_menucreate},
1515 {"scroll", window_scroll},
1516 {"setdocsize", window_setdocsize},
1517 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001518 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001519 {"settimer", window_settimer},
1520 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001521 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522 {"show", window_show},
1523 {"textcreate", window_textcreate},
1524 {NULL, NULL} /* sentinel */
1525};
1526
1527static object *
1528window_getattr(wp, name)
1529 windowobject *wp;
1530 char *name;
1531{
1532 if (wp->w_attr != NULL) {
1533 object *v = dictlookup(wp->w_attr, name);
1534 if (v != NULL) {
1535 INCREF(v);
1536 return v;
1537 }
1538 }
1539 return findmethod(window_methods, (object *)wp, name);
1540}
1541
1542static int
1543window_setattr(wp, name, v)
1544 windowobject *wp;
1545 char *name;
1546 object *v;
1547{
1548 if (wp->w_attr == NULL) {
1549 wp->w_attr = newdictobject();
1550 if (wp->w_attr == NULL)
1551 return -1;
1552 }
1553 if (v == NULL)
1554 return dictremove(wp->w_attr, name);
1555 else
1556 return dictinsert(wp->w_attr, name, v);
1557}
1558
Guido van Rossum541c8c01991-05-05 20:13:41 +00001559typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001560 OB_HEAD_INIT(&Typetype)
1561 0, /*ob_size*/
1562 "window", /*tp_name*/
1563 sizeof(windowobject), /*tp_size*/
1564 0, /*tp_itemsize*/
1565 /* methods */
1566 window_dealloc, /*tp_dealloc*/
1567 window_print, /*tp_print*/
1568 window_getattr, /*tp_getattr*/
1569 window_setattr, /*tp_setattr*/
1570 0, /*tp_compare*/
1571 0, /*tp_repr*/
1572};
1573
1574/* Stdwin methods */
1575
1576static object *
1577stdwin_open(sw, args)
1578 object *sw;
1579 object *args;
1580{
1581 int tag;
1582 object *title;
1583 windowobject *wp;
1584 if (!getstrarg(args, &title))
1585 return NULL;
1586 for (tag = 0; tag < MAXNWIN; tag++) {
1587 if (windowlist[tag] == NULL)
1588 break;
1589 }
Guido van Rossum27201061991-04-16 08:43:03 +00001590 if (tag >= MAXNWIN) {
1591 err_setstr(MemoryError, "creating too many windows");
1592 return NULL;
1593 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001594 wp = NEWOBJ(windowobject, &Windowtype);
1595 if (wp == NULL)
1596 return NULL;
1597 INCREF(title);
1598 wp->w_title = title;
1599 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1600 wp->w_attr = NULL;
1601 if (wp->w_win == NULL) {
1602 DECREF(wp);
1603 return NULL;
1604 }
1605 windowlist[tag] = wp;
1606 wsettag(wp->w_win, tag);
1607 return (object *)wp;
1608}
1609
1610static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001611stdwin_get_poll_event(poll, args)
1612 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001613 object *args;
1614{
1615 EVENT e;
1616 object *v, *w;
1617 if (!getnoarg(args))
1618 return NULL;
1619 if (Drawing != NULL) {
1620 err_setstr(RuntimeError, "cannot getevent() while drawing");
1621 return NULL;
1622 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001623/* again: */
1624 if (poll) {
1625 if (!wpollevent(&e)) {
1626 INCREF(None);
1627 return None;
1628 }
1629 }
1630 else
1631 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001632 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1633 /* Turn keyboard interrupts into exceptions */
1634 err_set(KeyboardInterrupt);
1635 return NULL;
1636 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001637/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001638 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1639 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001640*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001641 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1642 /* Turn WC_CLOSE commands into WE_CLOSE events */
1643 e.type = WE_CLOSE;
1644 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001645 v = newtupleobject(3);
1646 if (v == NULL)
1647 return NULL;
1648 if ((w = newintobject((long)e.type)) == NULL) {
1649 DECREF(v);
1650 return NULL;
1651 }
1652 settupleitem(v, 0, w);
1653 if (e.window == NULL)
1654 w = None;
1655 else {
1656 int tag = wgettag(e.window);
1657 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1658 w = None;
1659 else
1660 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001661#ifdef sgi
1662 /* XXX Trap for unexplained weird bug */
1663 if ((long)w == (long)0x80000001) {
1664 err_setstr(SystemError,
1665 "bad pointer in stdwin.getevent()");
1666 return NULL;
1667 }
1668#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001670 INCREF(w);
1671 settupleitem(v, 1, w);
1672 switch (e.type) {
1673 case WE_CHAR:
1674 {
1675 char c[1];
1676 c[0] = e.u.character;
1677 w = newsizedstringobject(c, 1);
1678 }
1679 break;
1680 case WE_COMMAND:
1681 w = newintobject((long)e.u.command);
1682 break;
1683 case WE_DRAW:
1684 w = makerect(e.u.area.left, e.u.area.top,
1685 e.u.area.right, e.u.area.bottom);
1686 break;
1687 case WE_MOUSE_DOWN:
1688 case WE_MOUSE_MOVE:
1689 case WE_MOUSE_UP:
1690 w = makemouse(e.u.where.h, e.u.where.v,
1691 e.u.where.clicks,
1692 e.u.where.button,
1693 e.u.where.mask);
1694 break;
1695 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001696 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1697 menulist[e.u.m.id - IDOFFSET] != NULL)
1698 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001699 else
1700 w = None;
1701 w = makemenu(w, e.u.m.item);
1702 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001703 case WE_LOST_SEL:
1704 w = newintobject((long)e.u.sel);
1705 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001706 default:
1707 w = None;
1708 INCREF(w);
1709 break;
1710 }
1711 if (w == NULL) {
1712 DECREF(v);
1713 return NULL;
1714 }
1715 settupleitem(v, 2, w);
1716 return v;
1717}
1718
1719static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001720stdwin_getevent(sw, args)
1721 object *sw;
1722 object *args;
1723{
1724 return stdwin_get_poll_event(0, args);
1725}
1726
1727static object *
1728stdwin_pollevent(sw, args)
1729 object *sw;
1730 object *args;
1731{
1732 return stdwin_get_poll_event(1, args);
1733}
1734
1735static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001736stdwin_setdefwinpos(sw, args)
1737 object *sw;
1738 object *args;
1739{
1740 int a[2];
1741 if (!getpointarg(args, a))
1742 return NULL;
1743 wsetdefwinpos(a[0], a[1]);
1744 INCREF(None);
1745 return None;
1746}
1747
1748static object *
1749stdwin_setdefwinsize(sw, args)
1750 object *sw;
1751 object *args;
1752{
1753 int a[2];
1754 if (!getpointarg(args, a))
1755 return NULL;
1756 wsetdefwinsize(a[0], a[1]);
1757 INCREF(None);
1758 return None;
1759}
1760
1761static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001762stdwin_setdefscrollbars(sw, args)
1763 object *sw;
1764 object *args;
1765{
1766 int a[2];
1767 if (!getpointarg(args, a))
1768 return NULL;
1769 wsetdefscrollbars(a[0], a[1]);
1770 INCREF(None);
1771 return None;
1772}
1773
1774static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001775stdwin_getdefwinpos(self, args)
1776 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001777 object *args;
1778{
1779 int h, v;
1780 if (!getnoarg(args))
1781 return NULL;
1782 wgetdefwinpos(&h, &v);
1783 return makepoint(h, v);
1784}
1785
1786static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001787stdwin_getdefwinsize(self, args)
1788 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001789 object *args;
1790{
1791 int width, height;
1792 if (!getnoarg(args))
1793 return NULL;
1794 wgetdefwinsize(&width, &height);
1795 return makepoint(width, height);
1796}
1797
1798static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001799stdwin_getdefscrollbars(self, args)
1800 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001801 object *args;
1802{
1803 int h, v;
1804 if (!getnoarg(args))
1805 return NULL;
1806 wgetdefscrollbars(&h, &v);
1807 return makepoint(h, v);
1808}
1809
1810static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001811stdwin_menucreate(self, args)
1812 object *self;
1813 object *args;
1814{
1815 object *title;
1816 if (!getstrarg(args, &title))
1817 return NULL;
1818 wmenusetdeflocal(0);
1819 return (object *)newmenuobject(title);
1820}
1821
1822static object *
1823stdwin_askfile(self, args)
1824 object *self;
1825 object *args;
1826{
1827 object *prompt, *dflt;
1828 int new, ret;
1829 char buf[256];
1830 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1831 return NULL;
1832 strncpy(buf, getstringvalue(dflt), sizeof buf);
1833 buf[sizeof buf - 1] = '\0';
1834 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1835 if (!ret) {
1836 err_set(KeyboardInterrupt);
1837 return NULL;
1838 }
1839 return newstringobject(buf);
1840}
1841
1842static object *
1843stdwin_askync(self, args)
1844 object *self;
1845 object *args;
1846{
1847 object *prompt;
1848 int new, ret;
1849 if (!getstrintarg(args, &prompt, &new))
1850 return NULL;
1851 ret = waskync(getstringvalue(prompt), new);
1852 if (ret < 0) {
1853 err_set(KeyboardInterrupt);
1854 return NULL;
1855 }
1856 return newintobject((long)ret);
1857}
1858
1859static object *
1860stdwin_askstr(self, args)
1861 object *self;
1862 object *args;
1863{
1864 object *prompt, *dflt;
1865 int ret;
1866 char buf[256];
1867 if (!getstrstrarg(args, &prompt, &dflt))
1868 return NULL;
1869 strncpy(buf, getstringvalue(dflt), sizeof buf);
1870 buf[sizeof buf - 1] = '\0';
1871 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1872 if (!ret) {
1873 err_set(KeyboardInterrupt);
1874 return NULL;
1875 }
1876 return newstringobject(buf);
1877}
1878
1879static object *
1880stdwin_message(self, args)
1881 object *self;
1882 object *args;
1883{
1884 object *msg;
1885 if (!getstrarg(args, &msg))
1886 return NULL;
1887 wmessage(getstringvalue(msg));
1888 INCREF(None);
1889 return None;
1890}
1891
1892static object *
1893stdwin_fleep(self, args)
1894 object *self;
1895 object *args;
1896{
1897 if (!getnoarg(args))
1898 return NULL;
1899 wfleep();
1900 INCREF(None);
1901 return None;
1902}
1903
1904static object *
1905stdwin_setcutbuffer(self, args)
1906 object *self;
1907 object *args;
1908{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001909 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001910 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001911 if (!getintstrarg(args, &i, &str))
1912 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001913 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001914 INCREF(None);
1915 return None;
1916}
1917
1918static object *
1919stdwin_getcutbuffer(self, args)
1920 object *self;
1921 object *args;
1922{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001923 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001924 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001925 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001926 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001927 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001928 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001929 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001930 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001931 len = 0;
1932 }
1933 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001934}
1935
Guido van Rossum5b10f451990-10-30 16:01:48 +00001936static object *
1937stdwin_rotatecutbuffers(self, args)
1938 object *self;
1939 object *args;
1940{
1941 int i;
1942 if (!getintarg(args, &i))
1943 return NULL;
1944 wrotatecutbuffers(i);
1945 INCREF(None);
1946 return None;
1947}
1948
1949static object *
1950stdwin_getselection(self, args)
1951 object *self;
1952 object *args;
1953{
1954 int sel;
1955 char *data;
1956 int len;
1957 if (!getintarg(args, &sel))
1958 return NULL;
1959 data = wgetselection(sel, &len);
1960 if (data == NULL) {
1961 data = "";
1962 len = 0;
1963 }
1964 return newsizedstringobject(data, len);
1965}
1966
1967static object *
1968stdwin_resetselection(self, args)
1969 object *self;
1970 object *args;
1971{
1972 int sel;
1973 if (!getintarg(args, &sel))
1974 return NULL;
1975 wresetselection(sel);
1976 INCREF(None);
1977 return None;
1978}
1979
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001980static object *
1981stdwin_fetchcolor(self, args)
1982 object *self;
1983 object *args;
1984{
1985 object *colorname;
1986 if (!getstrarg(args, &colorname))
1987 return NULL;
1988 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
1989}
1990
Guido van Rossum541c8c01991-05-05 20:13:41 +00001991static object *
1992stdwin_getscrsize(self, args)
1993 object *self;
1994 object *args;
1995{
1996 int width, height;
1997 if (!getnoarg(args))
1998 return NULL;
1999 wgetscrsize(&width, &height);
2000 return makepoint(width, height);
2001}
2002
2003static object *
2004stdwin_getscrmm(self, args)
2005 object *self;
2006 object *args;
2007{
2008 int width, height;
2009 if (!getnoarg(args))
2010 return NULL;
2011 wgetscrmm(&width, &height);
2012 return makepoint(width, height);
2013}
2014
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002015static struct methodlist stdwin_methods[] = {
2016 {"askfile", stdwin_askfile},
2017 {"askstr", stdwin_askstr},
2018 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002019 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002020 {"fleep", stdwin_fleep},
2021 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002022 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002023 {"getdefwinpos", stdwin_getdefwinpos},
2024 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002025 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002026 {"getscrmm", stdwin_getscrmm},
2027 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002028 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029 {"menucreate", stdwin_menucreate},
2030 {"message", stdwin_message},
2031 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002032 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002033 {"resetselection", stdwin_resetselection},
2034 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002035 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002036 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037 {"setdefwinpos", stdwin_setdefwinpos},
2038 {"setdefwinsize", stdwin_setdefwinsize},
2039
2040 /* Text measuring methods borrow code from drawing objects: */
2041 {"baseline", drawing_baseline},
2042 {"lineheight", drawing_lineheight},
2043 {"textbreak", drawing_textbreak},
2044 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002045
2046 /* Same for font setting methods: */
2047 {"setfont", drawing_setfont},
2048
2049 /* Same for color setting/getting methods: */
2050 {"getbgcolor", drawing_getbgcolor},
2051 {"getfgcolor", drawing_getfgcolor},
2052 {"setbgcolor", drawing_setbgcolor},
2053 {"setfgcolor", drawing_setfgcolor},
2054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055 {NULL, NULL} /* sentinel */
2056};
2057
2058void
2059initstdwin()
2060{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002061 static int inited;
2062 if (!inited) {
2063 winit();
2064 inited = 1;
2065 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002066 initmodule("stdwin", stdwin_methods);
2067}