blob: fb448f2f948e908bb5b995169af47b8b1baa706d [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 Rossum27201061991-04-16 08:43:03 +0000317static object *
318drawing_fillcircle(dp, args)
319 drawingobject *dp;
320 object *args;
321{
322 int a[3];
323 if (!getpointintarg(args, a))
324 return NULL;
325 wfillcircle(a[0], a[1], a[2]);
326 INCREF(None);
327 return None;
328}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329
330static object *
331drawing_elarc(dp, args)
332 drawingobject *dp;
333 object *args;
334{
335 int a[6];
336 if (!get3pointarg(args, a))
337 return NULL;
338 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
339 INCREF(None);
340 return None;
341}
342
343static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000344drawing_fillelarc(dp, args)
345 drawingobject *dp;
346 object *args;
347{
348 int a[6];
349 if (!get3pointarg(args, a))
350 return NULL;
351 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
352 INCREF(None);
353 return None;
354}
355
356static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357drawing_box(dp, args)
358 drawingobject *dp;
359 object *args;
360{
Guido van Rossumbf109731991-03-06 13:14:12 +0000361 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362}
363
364static object *
365drawing_erase(dp, args)
366 drawingobject *dp;
367 object *args;
368{
Guido van Rossumbf109731991-03-06 13:14:12 +0000369 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370}
371
372static object *
373drawing_paint(dp, args)
374 drawingobject *dp;
375 object *args;
376{
Guido van Rossumbf109731991-03-06 13:14:12 +0000377 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378}
379
380static object *
381drawing_invert(dp, args)
382 drawingobject *dp;
383 object *args;
384{
Guido van Rossumbf109731991-03-06 13:14:12 +0000385 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386}
387
Guido van Rossum27201061991-04-16 08:43:03 +0000388static POINT *
389getpointsarray(v, psize)
390 object *v;
391 int *psize;
392{
393 int n = -1;
394 object * (*getitem) PROTO((object *, int));
395 int i;
396 POINT *points;
397
398 if (v == NULL)
399 ;
400 else if (is_listobject(v)) {
401 n = getlistsize(v);
402 getitem = getlistitem;
403 }
404 else if (is_tupleobject(v)) {
405 n = gettuplesize(v);
406 getitem = gettupleitem;
407 }
408
409 if (n <= 0) {
410 (void) err_badarg();
411 return NULL;
412 }
413
414 points = NEW(POINT, n);
415 if (points == NULL) {
416 (void) err_nomem();
417 return NULL;
418 }
419
420 for (i = 0; i < n; i++) {
421 object *w = (*getitem)(v, i);
422 int a[2];
423 if (!getpointarg(w, a)) {
424 DEL(points);
425 return NULL;
426 }
427 points[i].h = a[0];
428 points[i].v = a[1];
429 }
430
431 *psize = n;
432 return points;
433}
434
435static object *
436drawing_poly(dp, args)
437 drawingobject *dp;
438 object *args;
439{
440 int n;
441 POINT *points = getpointsarray(args, &n);
442 if (points == NULL)
443 return NULL;
444 wdrawpoly(n, points);
445 DEL(points);
446 INCREF(None);
447 return None;
448}
449
450static object *
451drawing_fillpoly(dp, args)
452 drawingobject *dp;
453 object *args;
454{
455 int n;
456 POINT *points = getpointsarray(args, &n);
457 if (points == NULL)
458 return NULL;
459 wfillpoly(n, points);
460 DEL(points);
461 INCREF(None);
462 return None;
463}
464
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000465static object *
466drawing_cliprect(dp, args)
467 drawingobject *dp;
468 object *args;
469{
Guido van Rossumbf109731991-03-06 13:14:12 +0000470 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471}
472
473static object *
474drawing_noclip(dp, args)
475 drawingobject *dp;
476 object *args;
477{
478 if (!getnoarg(args))
479 return NULL;
480 wnoclip();
481 INCREF(None);
482 return None;
483}
484
485static object *
486drawing_shade(dp, args)
487 drawingobject *dp;
488 object *args;
489{
490 int a[5];
491 if (!getrectintarg(args, a))
492 return NULL;
493 wshade(a[0], a[1], a[2], a[3], a[4]);
494 INCREF(None);
495 return None;
496}
497
498static object *
499drawing_text(dp, args)
500 drawingobject *dp;
501 object *args;
502{
503 int a[2];
504 object *s;
505 if (!getpointstrarg(args, a, &s))
506 return NULL;
507 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
508 INCREF(None);
509 return None;
510}
511
512/* The following four are also used as stdwin functions */
513
514static object *
515drawing_lineheight(dp, args)
516 drawingobject *dp;
517 object *args;
518{
519 if (!getnoarg(args))
520 return NULL;
521 return newintobject((long)wlineheight());
522}
523
524static object *
525drawing_baseline(dp, args)
526 drawingobject *dp;
527 object *args;
528{
529 if (!getnoarg(args))
530 return NULL;
531 return newintobject((long)wbaseline());
532}
533
534static object *
535drawing_textwidth(dp, args)
536 drawingobject *dp;
537 object *args;
538{
539 object *s;
540 if (!getstrarg(args, &s))
541 return NULL;
542 return newintobject(
543 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
544}
545
546static object *
547drawing_textbreak(dp, args)
548 drawingobject *dp;
549 object *args;
550{
551 object *s;
552 int a;
553 if (!getstrintarg(args, &s, &a))
554 return NULL;
555 return newintobject(
556 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
557}
558
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000559static object *
560drawing_setfont(self, args)
561 drawingobject *self;
562 object *args;
563{
Guido van Rossum50429a11991-04-04 15:24:07 +0000564 object *font, *style;
565 int size;
566 if (args == NULL) {
567 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000568 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000569 }
570 if (is_stringobject(args)) {
571 font = args;
572 style = NULL;
573 size = 0;
574 }
575 else if (is_tupleobject(args)) {
576 int n = gettuplesize(args);
577 if (n == 2) {
578 if (!getstrintarg(args, &font, &size))
579 return NULL;
580 style = NULL;
581 }
582 else if (!getstrstrintarg(args, &font, &style, &size))
583 return NULL;
584 }
585 else {
586 err_badarg();
587 return NULL;
588 }
589 if (getstringsize(font) != 0)
590 wsetfont(getstringvalue(font));
591 if (style != NULL) {
592 switch (*getstringvalue(style)) {
593 case 'b':
594 wsetbold();
595 break;
596 case 'i':
597 wsetitalic();
598 break;
599 case 'o':
600 wsetbolditalic();
601 break;
602 case 'u':
603 wsetunderline();
604 break;
605 default:
606 wsetplain();
607 break;
608 }
609 }
610 if (size != 0)
611 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000612 INCREF(None);
613 return None;
614}
615
616static object *
617drawing_getbgcolor(self, args)
618 object *self;
619 object *args;
620{
621 if (!getnoarg(args))
622 return NULL;
623 return newintobject((long)wgetbgcolor());
624}
625
626static object *
627drawing_getfgcolor(self, args)
628 object *self;
629 object *args;
630{
631 if (!getnoarg(args))
632 return NULL;
633 return newintobject((long)wgetfgcolor());
634}
635
636static object *
637drawing_setbgcolor(self, args)
638 object *self;
639 object *args;
640{
641 long color;
642 if (!getlongarg(args, &color))
643 return NULL;
644 wsetbgcolor((COLOR)color);
645 INCREF(None);
646 return None;
647}
648
649static object *
650drawing_setfgcolor(self, args)
651 object *self;
652 object *args;
653{
654 long color;
655 if (!getlongarg(args, &color))
656 return NULL;
657 wsetfgcolor((COLOR)color);
658 INCREF(None);
659 return None;
660}
661
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000662static struct methodlist drawing_methods[] = {
663 {"box", drawing_box},
664 {"circle", drawing_circle},
665 {"cliprect", drawing_cliprect},
666 {"elarc", drawing_elarc},
667 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000668 {"fillelarc", drawing_fillelarc},
669 {"fillcircle", drawing_fillcircle},
670 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000671 {"invert", drawing_invert},
672 {"line", drawing_line},
673 {"noclip", drawing_noclip},
674 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000675 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000676 {"shade", drawing_shade},
677 {"text", drawing_text},
678 {"xorline", drawing_xorline},
679
680 /* Text measuring methods: */
681 {"baseline", drawing_baseline},
682 {"lineheight", drawing_lineheight},
683 {"textbreak", drawing_textbreak},
684 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000685
686 /* Font setting methods: */
687 {"setfont", drawing_setfont},
688
689 /* Color methods: */
690 {"getbgcolor", drawing_getbgcolor},
691 {"getfgcolor", drawing_getfgcolor},
692 {"setbgcolor", drawing_setbgcolor},
693 {"setfgcolor", drawing_setfgcolor},
694
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000695 {NULL, NULL} /* sentinel */
696};
697
698static object *
699drawing_getattr(wp, name)
700 drawingobject *wp;
701 char *name;
702{
703 return findmethod(drawing_methods, (object *)wp, name);
704}
705
Guido van Rossum541c8c01991-05-05 20:13:41 +0000706typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707 OB_HEAD_INIT(&Typetype)
708 0, /*ob_size*/
709 "drawing", /*tp_name*/
710 sizeof(drawingobject), /*tp_size*/
711 0, /*tp_itemsize*/
712 /* methods */
713 drawing_dealloc, /*tp_dealloc*/
714 0, /*tp_print*/
715 drawing_getattr, /*tp_getattr*/
716 0, /*tp_setattr*/
717 0, /*tp_compare*/
718 0, /*tp_repr*/
719};
720
721
722/* Text(edit) objects */
723
724typedef struct {
725 OB_HEAD
726 TEXTEDIT *t_text;
727 windowobject *t_ref;
728 object *t_attr; /* Attributes dictionary */
729} textobject;
730
731extern typeobject Texttype; /* Really static, forward */
732
733static textobject *
734newtextobject(wp, left, top, right, bottom)
735 windowobject *wp;
736 int left, top, right, bottom;
737{
738 textobject *tp;
739 tp = NEWOBJ(textobject, &Texttype);
740 if (tp == NULL)
741 return NULL;
742 tp->t_attr = NULL;
743 INCREF(wp);
744 tp->t_ref = wp;
745 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
746 if (tp->t_text == NULL) {
747 DECREF(tp);
748 return (textobject *) err_nomem();
749 }
750 return tp;
751}
752
753/* Text(edit) methods */
754
755static void
756text_dealloc(tp)
757 textobject *tp;
758{
759 if (tp->t_text != NULL)
760 tefree(tp->t_text);
761 if (tp->t_attr != NULL)
762 DECREF(tp->t_attr);
763 DECREF(tp->t_ref);
764 DEL(tp);
765}
766
767static object *
768text_arrow(self, args)
769 textobject *self;
770 object *args;
771{
772 int code;
773 if (!getintarg(args, &code))
774 return NULL;
775 tearrow(self->t_text, code);
776 INCREF(None);
777 return None;
778}
779
780static object *
781text_draw(self, args)
782 textobject *self;
783 object *args;
784{
785 register TEXTEDIT *tp = self->t_text;
786 int a[4];
787 int left, top, right, bottom;
788 if (!getrectarg(args, a))
789 return NULL;
790 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000791 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792 return NULL;
793 }
794 /* Clip to text area and ignore if area is empty */
795 left = tegetleft(tp);
796 top = tegettop(tp);
797 right = tegetright(tp);
798 bottom = tegetbottom(tp);
799 if (a[0] < left) a[0] = left;
800 if (a[1] < top) a[1] = top;
801 if (a[2] > right) a[2] = right;
802 if (a[3] > bottom) a[3] = bottom;
803 if (a[0] < a[2] && a[1] < a[3]) {
804 /* Hide/show focus around draw call; these are undocumented,
805 but required here to get the highlighting correct.
806 The call to werase is also required for this reason.
807 Finally, this forces us to require (above) that we are NOT
808 already drawing. */
809 tehidefocus(tp);
810 wbegindrawing(self->t_ref->w_win);
811 werase(a[0], a[1], a[2], a[3]);
812 tedrawnew(tp, a[0], a[1], a[2], a[3]);
813 wenddrawing(self->t_ref->w_win);
814 teshowfocus(tp);
815 }
816 INCREF(None);
817 return None;
818}
819
820static object *
821text_event(self, args)
822 textobject *self;
823 object *args;
824{
825 register TEXTEDIT *tp = self->t_text;
826 EVENT e;
827 if (!geteventarg(args, &e))
828 return NULL;
829 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000830 /* Cheat at the margins */
831 int width, height;
832 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833 if (e.u.where.h < 0 && tegetleft(tp) == 0)
834 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000835 else if (e.u.where.h > width && tegetright(tp) == width)
836 e.u.where.h = width;
837 if (e.u.where.v < 0 && tegettop(tp) == 0)
838 e.u.where.v = 0;
839 else if (e.u.where.v > height && tegetright(tp) == height)
840 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000841 }
842 return newintobject((long) teevent(tp, &e));
843}
844
845static object *
846text_getfocus(self, args)
847 textobject *self;
848 object *args;
849{
850 if (!getnoarg(args))
851 return NULL;
852 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
853}
854
855static object *
856text_getfocustext(self, args)
857 textobject *self;
858 object *args;
859{
860 int f1, f2;
861 char *text;
862 if (!getnoarg(args))
863 return NULL;
864 f1 = tegetfoc1(self->t_text);
865 f2 = tegetfoc2(self->t_text);
866 text = tegettext(self->t_text);
867 return newsizedstringobject(text + f1, f2-f1);
868}
869
870static object *
871text_getrect(self, args)
872 textobject *self;
873 object *args;
874{
875 if (!getnoarg(args))
876 return NULL;
877 return makerect(tegetleft(self->t_text),
878 tegettop(self->t_text),
879 tegetright(self->t_text),
880 tegetbottom(self->t_text));
881}
882
883static object *
884text_gettext(self, args)
885 textobject *self;
886 object *args;
887{
888 if (!getnoarg(args))
889 return NULL;
890 return newsizedstringobject(tegettext(self->t_text),
891 tegetlen(self->t_text));
892}
893
894static object *
895text_move(self, args)
896 textobject *self;
897 object *args;
898{
899 int a[4];
900 if (!getrectarg(args, a))
901 return NULL;
902 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
903 INCREF(None);
904 return None;
905}
906
907static object *
908text_setfocus(self, args)
909 textobject *self;
910 object *args;
911{
912 int a[2];
913 if (!getpointarg(args, a))
914 return NULL;
915 tesetfocus(self->t_text, a[0], a[1]);
916 INCREF(None);
917 return None;
918}
919
920static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000921text_settext(self, args)
922 textobject *self;
923 object *args;
924{
925 object *text;
926 char *buf;
927 int size;
928 if (!getstrarg(args, &text))
929 return NULL;
930 size = getstringsize(text);
931 if ((buf = NEW(char, size)) == NULL) {
932 err_set(MemoryError);
933 return NULL;
934 }
935 memcpy(buf, getstringvalue(text), size);
936 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
937 INCREF(None);
938 return None;
939}
940
941static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000942text_replace(self, args)
943 textobject *self;
944 object *args;
945{
946 object *text;
947 if (!getstrarg(args, &text))
948 return NULL;
949 tereplace(self->t_text, getstringvalue(text));
950 INCREF(None);
951 return None;
952}
953
954static struct methodlist text_methods[] = {
955 "arrow", text_arrow,
956 "draw", text_draw,
957 "event", text_event,
958 "getfocus", text_getfocus,
959 "getfocustext", text_getfocustext,
960 "getrect", text_getrect,
961 "gettext", text_gettext,
962 "move", text_move,
963 "replace", text_replace,
964 "setfocus", text_setfocus,
Guido van Rossum541c8c01991-05-05 20:13:41 +0000965 "settext", text_settext,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966 {NULL, NULL} /* sentinel */
967};
968
969static object *
970text_getattr(tp, name)
971 textobject *tp;
972 char *name;
973{
974 if (tp->t_attr != NULL) {
975 object *v = dictlookup(tp->t_attr, name);
976 if (v != NULL) {
977 INCREF(v);
978 return v;
979 }
980 }
981 return findmethod(text_methods, (object *)tp, name);
982}
983
984static int
985text_setattr(tp, name, v)
986 textobject *tp;
987 char *name;
988 object *v;
989{
990 if (tp->t_attr == NULL) {
991 tp->t_attr = newdictobject();
992 if (tp->t_attr == NULL)
993 return -1;
994 }
995 if (v == NULL)
996 return dictremove(tp->t_attr, name);
997 else
998 return dictinsert(tp->t_attr, name, v);
999}
1000
Guido van Rossum541c8c01991-05-05 20:13:41 +00001001typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001002 OB_HEAD_INIT(&Typetype)
1003 0, /*ob_size*/
1004 "textedit", /*tp_name*/
1005 sizeof(textobject), /*tp_size*/
1006 0, /*tp_itemsize*/
1007 /* methods */
1008 text_dealloc, /*tp_dealloc*/
1009 0, /*tp_print*/
1010 text_getattr, /*tp_getattr*/
1011 text_setattr, /*tp_setattr*/
1012 0, /*tp_compare*/
1013 0, /*tp_repr*/
1014};
1015
1016
1017/* Menu objects */
1018
Guido van Rossum2d14e211991-02-19 12:26:49 +00001019#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001020#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001021static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022
1023static menuobject *
1024newmenuobject(title)
1025 object *title;
1026{
1027 int id;
1028 MENU *menu;
1029 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001030 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001031 if (menulist[id] == NULL)
1032 break;
1033 }
Guido van Rossum27201061991-04-16 08:43:03 +00001034 if (id >= MAXNMENU) {
1035 err_setstr(MemoryError, "creating too many menus");
1036 return NULL;
1037 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001038 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001039 if (menu == NULL)
1040 return (menuobject *) err_nomem();
1041 mp = NEWOBJ(menuobject, &Menutype);
1042 if (mp != NULL) {
1043 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001044 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 mp->m_attr = NULL;
1046 menulist[id] = mp;
1047 }
1048 else
1049 wmenudelete(menu);
1050 return mp;
1051}
1052
1053/* Menu methods */
1054
1055static void
1056menu_dealloc(mp)
1057 menuobject *mp;
1058{
1059
Guido van Rossum2d14e211991-02-19 12:26:49 +00001060 int id = mp->m_id - IDOFFSET;
1061 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001062 menulist[id] = NULL;
1063 }
1064 wmenudelete(mp->m_menu);
1065 if (mp->m_attr != NULL)
1066 DECREF(mp->m_attr);
1067 DEL(mp);
1068}
1069
1070static object *
1071menu_additem(self, args)
1072 menuobject *self;
1073 object *args;
1074{
1075 object *text;
1076 int shortcut;
1077 if (is_tupleobject(args)) {
1078 object *v;
1079 if (!getstrstrarg(args, &text, &v))
1080 return NULL;
1081 if (getstringsize(v) != 1) {
1082 err_badarg();
1083 return NULL;
1084 }
1085 shortcut = *getstringvalue(v) & 0xff;
1086 }
1087 else {
1088 if (!getstrarg(args, &text))
1089 return NULL;
1090 shortcut = -1;
1091 }
1092 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1093 INCREF(None);
1094 return None;
1095}
1096
1097static object *
1098menu_setitem(self, args)
1099 menuobject *self;
1100 object *args;
1101{
1102 int index;
1103 object *text;
1104 if (!getintstrarg(args, &index, &text))
1105 return NULL;
1106 wmenusetitem(self->m_menu, index, getstringvalue(text));
1107 INCREF(None);
1108 return None;
1109}
1110
1111static object *
1112menu_enable(self, args)
1113 menuobject *self;
1114 object *args;
1115{
1116 int index;
1117 int flag;
1118 if (!getintintarg(args, &index, &flag))
1119 return NULL;
1120 wmenuenable(self->m_menu, index, flag);
1121 INCREF(None);
1122 return None;
1123}
1124
1125static object *
1126menu_check(self, args)
1127 menuobject *self;
1128 object *args;
1129{
1130 int index;
1131 int flag;
1132 if (!getintintarg(args, &index, &flag))
1133 return NULL;
1134 wmenucheck(self->m_menu, index, flag);
1135 INCREF(None);
1136 return None;
1137}
1138
1139static struct methodlist menu_methods[] = {
1140 "additem", menu_additem,
1141 "setitem", menu_setitem,
1142 "enable", menu_enable,
1143 "check", menu_check,
1144 {NULL, NULL} /* sentinel */
1145};
1146
1147static object *
1148menu_getattr(mp, name)
1149 menuobject *mp;
1150 char *name;
1151{
1152 if (mp->m_attr != NULL) {
1153 object *v = dictlookup(mp->m_attr, name);
1154 if (v != NULL) {
1155 INCREF(v);
1156 return v;
1157 }
1158 }
1159 return findmethod(menu_methods, (object *)mp, name);
1160}
1161
1162static int
1163menu_setattr(mp, name, v)
1164 menuobject *mp;
1165 char *name;
1166 object *v;
1167{
1168 if (mp->m_attr == NULL) {
1169 mp->m_attr = newdictobject();
1170 if (mp->m_attr == NULL)
1171 return -1;
1172 }
1173 if (v == NULL)
1174 return dictremove(mp->m_attr, name);
1175 else
1176 return dictinsert(mp->m_attr, name, v);
1177}
1178
Guido van Rossum541c8c01991-05-05 20:13:41 +00001179typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001180 OB_HEAD_INIT(&Typetype)
1181 0, /*ob_size*/
1182 "menu", /*tp_name*/
1183 sizeof(menuobject), /*tp_size*/
1184 0, /*tp_itemsize*/
1185 /* methods */
1186 menu_dealloc, /*tp_dealloc*/
1187 0, /*tp_print*/
1188 menu_getattr, /*tp_getattr*/
1189 menu_setattr, /*tp_setattr*/
1190 0, /*tp_compare*/
1191 0, /*tp_repr*/
1192};
1193
1194
1195/* Windows */
1196
1197#define MAXNWIN 50
1198static windowobject *windowlist[MAXNWIN];
1199
1200/* Window methods */
1201
1202static void
1203window_dealloc(wp)
1204 windowobject *wp;
1205{
1206 if (wp->w_win != NULL) {
1207 int tag = wgettag(wp->w_win);
1208 if (tag >= 0 && tag < MAXNWIN)
1209 windowlist[tag] = NULL;
1210 else
1211 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1212 tag);
1213 wclose(wp->w_win);
1214 }
1215 DECREF(wp->w_title);
1216 if (wp->w_attr != NULL)
1217 DECREF(wp->w_attr);
1218 free((char *)wp);
1219}
1220
1221static void
1222window_print(wp, fp, flags)
1223 windowobject *wp;
1224 FILE *fp;
1225 int flags;
1226{
1227 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1228}
1229
1230static object *
1231window_begindrawing(wp, args)
1232 windowobject *wp;
1233 object *args;
1234{
1235 drawingobject *dp;
1236 if (!getnoarg(args))
1237 return NULL;
1238 if (Drawing != NULL) {
1239 err_setstr(RuntimeError, "already drawing");
1240 return NULL;
1241 }
1242 dp = NEWOBJ(drawingobject, &Drawingtype);
1243 if (dp == NULL)
1244 return NULL;
1245 Drawing = dp;
1246 INCREF(wp);
1247 dp->d_ref = wp;
1248 wbegindrawing(wp->w_win);
1249 return (object *)dp;
1250}
1251
1252static object *
1253window_change(wp, args)
1254 windowobject *wp;
1255 object *args;
1256{
1257 int a[4];
1258 if (!getrectarg(args, a))
1259 return NULL;
1260 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1261 INCREF(None);
1262 return None;
1263}
1264
1265static object *
1266window_gettitle(wp, args)
1267 windowobject *wp;
1268 object *args;
1269{
1270 if (!getnoarg(args))
1271 return NULL;
1272 INCREF(wp->w_title);
1273 return wp->w_title;
1274}
1275
1276static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001277window_getwinpos(wp, args)
1278 windowobject *wp;
1279 object *args;
1280{
1281 int h, v;
1282 if (!getnoarg(args))
1283 return NULL;
1284 wgetwinpos(wp->w_win, &h, &v);
1285 return makepoint(h, v);
1286}
1287
1288static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289window_getwinsize(wp, args)
1290 windowobject *wp;
1291 object *args;
1292{
1293 int width, height;
1294 if (!getnoarg(args))
1295 return NULL;
1296 wgetwinsize(wp->w_win, &width, &height);
1297 return makepoint(width, height);
1298}
1299
1300static object *
1301window_getdocsize(wp, args)
1302 windowobject *wp;
1303 object *args;
1304{
1305 int width, height;
1306 if (!getnoarg(args))
1307 return NULL;
1308 wgetdocsize(wp->w_win, &width, &height);
1309 return makepoint(width, height);
1310}
1311
1312static object *
1313window_getorigin(wp, args)
1314 windowobject *wp;
1315 object *args;
1316{
1317 int width, height;
1318 if (!getnoarg(args))
1319 return NULL;
1320 wgetorigin(wp->w_win, &width, &height);
1321 return makepoint(width, height);
1322}
1323
1324static object *
1325window_scroll(wp, args)
1326 windowobject *wp;
1327 object *args;
1328{
1329 int a[6];
1330 if (!getrectpointarg(args, a))
1331 return NULL;
1332 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1333 INCREF(None);
1334 return None;
1335}
1336
1337static object *
1338window_setdocsize(wp, args)
1339 windowobject *wp;
1340 object *args;
1341{
1342 int a[2];
1343 if (!getpointarg(args, a))
1344 return NULL;
1345 wsetdocsize(wp->w_win, a[0], a[1]);
1346 INCREF(None);
1347 return None;
1348}
1349
1350static object *
1351window_setorigin(wp, args)
1352 windowobject *wp;
1353 object *args;
1354{
1355 int a[2];
1356 if (!getpointarg(args, a))
1357 return NULL;
1358 wsetorigin(wp->w_win, a[0], a[1]);
1359 INCREF(None);
1360 return None;
1361}
1362
1363static object *
1364window_settitle(wp, args)
1365 windowobject *wp;
1366 object *args;
1367{
1368 object *title;
1369 if (!getstrarg(args, &title))
1370 return NULL;
1371 DECREF(wp->w_title);
1372 INCREF(title);
1373 wp->w_title = title;
1374 wsettitle(wp->w_win, getstringvalue(title));
1375 INCREF(None);
1376 return None;
1377}
1378
1379static object *
1380window_show(wp, args)
1381 windowobject *wp;
1382 object *args;
1383{
1384 int a[4];
1385 if (!getrectarg(args, a))
1386 return NULL;
1387 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1388 INCREF(None);
1389 return None;
1390}
1391
1392static object *
1393window_settimer(wp, args)
1394 windowobject *wp;
1395 object *args;
1396{
1397 int a;
1398 if (!getintarg(args, &a))
1399 return NULL;
1400 wsettimer(wp->w_win, a);
1401 INCREF(None);
1402 return None;
1403}
1404
1405static object *
1406window_menucreate(self, args)
1407 windowobject *self;
1408 object *args;
1409{
1410 menuobject *mp;
1411 object *title;
1412 if (!getstrarg(args, &title))
1413 return NULL;
1414 wmenusetdeflocal(1);
1415 mp = newmenuobject(title);
1416 if (mp == NULL)
1417 return NULL;
1418 wmenuattach(self->w_win, mp->m_menu);
1419 return (object *)mp;
1420}
1421
1422static object *
1423window_textcreate(self, args)
1424 windowobject *self;
1425 object *args;
1426{
1427 textobject *tp;
1428 int a[4];
1429 if (!getrectarg(args, a))
1430 return NULL;
1431 return (object *)
1432 newtextobject(self, a[0], a[1], a[2], a[3]);
1433}
1434
Guido van Rossum5b10f451990-10-30 16:01:48 +00001435static object *
1436window_setselection(self, args)
1437 windowobject *self;
1438 object *args;
1439{
1440 int sel;
1441 object *str;
1442 int ok;
1443 if (!getintstrarg(args, &sel, &str))
1444 return NULL;
1445 ok = wsetselection(self->w_win, sel,
1446 getstringvalue(str), (int)getstringsize(str));
1447 return newintobject(ok);
1448}
1449
1450static object *
1451window_setwincursor(self, args)
1452 windowobject *self;
1453 object *args;
1454{
1455 object *str;
1456 CURSOR *c;
1457 if (!getstrarg(args, &str))
1458 return NULL;
1459 c = wfetchcursor(getstringvalue(str));
1460 if (c == NULL) {
1461 err_setstr(RuntimeError, "no such cursor");
1462 return NULL;
1463 }
1464 wsetwincursor(self->w_win, c);
1465 INCREF(None);
1466 return None;
1467}
1468
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001469static struct methodlist window_methods[] = {
1470 {"begindrawing",window_begindrawing},
1471 {"change", window_change},
1472 {"getdocsize", window_getdocsize},
1473 {"getorigin", window_getorigin},
1474 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001475 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001476 {"getwinsize", window_getwinsize},
1477 {"menucreate", window_menucreate},
1478 {"scroll", window_scroll},
1479 {"setdocsize", window_setdocsize},
1480 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001481 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001482 {"settimer", window_settimer},
1483 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001484 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001485 {"show", window_show},
1486 {"textcreate", window_textcreate},
1487 {NULL, NULL} /* sentinel */
1488};
1489
1490static object *
1491window_getattr(wp, name)
1492 windowobject *wp;
1493 char *name;
1494{
1495 if (wp->w_attr != NULL) {
1496 object *v = dictlookup(wp->w_attr, name);
1497 if (v != NULL) {
1498 INCREF(v);
1499 return v;
1500 }
1501 }
1502 return findmethod(window_methods, (object *)wp, name);
1503}
1504
1505static int
1506window_setattr(wp, name, v)
1507 windowobject *wp;
1508 char *name;
1509 object *v;
1510{
1511 if (wp->w_attr == NULL) {
1512 wp->w_attr = newdictobject();
1513 if (wp->w_attr == NULL)
1514 return -1;
1515 }
1516 if (v == NULL)
1517 return dictremove(wp->w_attr, name);
1518 else
1519 return dictinsert(wp->w_attr, name, v);
1520}
1521
Guido van Rossum541c8c01991-05-05 20:13:41 +00001522typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001523 OB_HEAD_INIT(&Typetype)
1524 0, /*ob_size*/
1525 "window", /*tp_name*/
1526 sizeof(windowobject), /*tp_size*/
1527 0, /*tp_itemsize*/
1528 /* methods */
1529 window_dealloc, /*tp_dealloc*/
1530 window_print, /*tp_print*/
1531 window_getattr, /*tp_getattr*/
1532 window_setattr, /*tp_setattr*/
1533 0, /*tp_compare*/
1534 0, /*tp_repr*/
1535};
1536
1537/* Stdwin methods */
1538
1539static object *
1540stdwin_open(sw, args)
1541 object *sw;
1542 object *args;
1543{
1544 int tag;
1545 object *title;
1546 windowobject *wp;
1547 if (!getstrarg(args, &title))
1548 return NULL;
1549 for (tag = 0; tag < MAXNWIN; tag++) {
1550 if (windowlist[tag] == NULL)
1551 break;
1552 }
Guido van Rossum27201061991-04-16 08:43:03 +00001553 if (tag >= MAXNWIN) {
1554 err_setstr(MemoryError, "creating too many windows");
1555 return NULL;
1556 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001557 wp = NEWOBJ(windowobject, &Windowtype);
1558 if (wp == NULL)
1559 return NULL;
1560 INCREF(title);
1561 wp->w_title = title;
1562 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1563 wp->w_attr = NULL;
1564 if (wp->w_win == NULL) {
1565 DECREF(wp);
1566 return NULL;
1567 }
1568 windowlist[tag] = wp;
1569 wsettag(wp->w_win, tag);
1570 return (object *)wp;
1571}
1572
1573static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001574stdwin_get_poll_event(poll, args)
1575 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001576 object *args;
1577{
1578 EVENT e;
1579 object *v, *w;
1580 if (!getnoarg(args))
1581 return NULL;
1582 if (Drawing != NULL) {
1583 err_setstr(RuntimeError, "cannot getevent() while drawing");
1584 return NULL;
1585 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001586/* again: */
1587 if (poll) {
1588 if (!wpollevent(&e)) {
1589 INCREF(None);
1590 return None;
1591 }
1592 }
1593 else
1594 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001595 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1596 /* Turn keyboard interrupts into exceptions */
1597 err_set(KeyboardInterrupt);
1598 return NULL;
1599 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001600/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001601 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1602 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001603*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001604 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1605 /* Turn WC_CLOSE commands into WE_CLOSE events */
1606 e.type = WE_CLOSE;
1607 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001608 v = newtupleobject(3);
1609 if (v == NULL)
1610 return NULL;
1611 if ((w = newintobject((long)e.type)) == NULL) {
1612 DECREF(v);
1613 return NULL;
1614 }
1615 settupleitem(v, 0, w);
1616 if (e.window == NULL)
1617 w = None;
1618 else {
1619 int tag = wgettag(e.window);
1620 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1621 w = None;
1622 else
1623 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001624#ifdef sgi
1625 /* XXX Trap for unexplained weird bug */
1626 if ((long)w == (long)0x80000001) {
1627 err_setstr(SystemError,
1628 "bad pointer in stdwin.getevent()");
1629 return NULL;
1630 }
1631#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001632 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633 INCREF(w);
1634 settupleitem(v, 1, w);
1635 switch (e.type) {
1636 case WE_CHAR:
1637 {
1638 char c[1];
1639 c[0] = e.u.character;
1640 w = newsizedstringobject(c, 1);
1641 }
1642 break;
1643 case WE_COMMAND:
1644 w = newintobject((long)e.u.command);
1645 break;
1646 case WE_DRAW:
1647 w = makerect(e.u.area.left, e.u.area.top,
1648 e.u.area.right, e.u.area.bottom);
1649 break;
1650 case WE_MOUSE_DOWN:
1651 case WE_MOUSE_MOVE:
1652 case WE_MOUSE_UP:
1653 w = makemouse(e.u.where.h, e.u.where.v,
1654 e.u.where.clicks,
1655 e.u.where.button,
1656 e.u.where.mask);
1657 break;
1658 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001659 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1660 menulist[e.u.m.id - IDOFFSET] != NULL)
1661 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001662 else
1663 w = None;
1664 w = makemenu(w, e.u.m.item);
1665 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001666 case WE_LOST_SEL:
1667 w = newintobject((long)e.u.sel);
1668 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669 default:
1670 w = None;
1671 INCREF(w);
1672 break;
1673 }
1674 if (w == NULL) {
1675 DECREF(v);
1676 return NULL;
1677 }
1678 settupleitem(v, 2, w);
1679 return v;
1680}
1681
1682static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001683stdwin_getevent(sw, args)
1684 object *sw;
1685 object *args;
1686{
1687 return stdwin_get_poll_event(0, args);
1688}
1689
1690static object *
1691stdwin_pollevent(sw, args)
1692 object *sw;
1693 object *args;
1694{
1695 return stdwin_get_poll_event(1, args);
1696}
1697
1698static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001699stdwin_setdefwinpos(sw, args)
1700 object *sw;
1701 object *args;
1702{
1703 int a[2];
1704 if (!getpointarg(args, a))
1705 return NULL;
1706 wsetdefwinpos(a[0], a[1]);
1707 INCREF(None);
1708 return None;
1709}
1710
1711static object *
1712stdwin_setdefwinsize(sw, args)
1713 object *sw;
1714 object *args;
1715{
1716 int a[2];
1717 if (!getpointarg(args, a))
1718 return NULL;
1719 wsetdefwinsize(a[0], a[1]);
1720 INCREF(None);
1721 return None;
1722}
1723
1724static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001725stdwin_setdefscrollbars(sw, args)
1726 object *sw;
1727 object *args;
1728{
1729 int a[2];
1730 if (!getpointarg(args, a))
1731 return NULL;
1732 wsetdefscrollbars(a[0], a[1]);
1733 INCREF(None);
1734 return None;
1735}
1736
1737static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001738stdwin_getdefwinpos(self, args)
1739 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001740 object *args;
1741{
1742 int h, v;
1743 if (!getnoarg(args))
1744 return NULL;
1745 wgetdefwinpos(&h, &v);
1746 return makepoint(h, v);
1747}
1748
1749static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001750stdwin_getdefwinsize(self, args)
1751 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001752 object *args;
1753{
1754 int width, height;
1755 if (!getnoarg(args))
1756 return NULL;
1757 wgetdefwinsize(&width, &height);
1758 return makepoint(width, height);
1759}
1760
1761static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001762stdwin_getdefscrollbars(self, args)
1763 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001764 object *args;
1765{
1766 int h, v;
1767 if (!getnoarg(args))
1768 return NULL;
1769 wgetdefscrollbars(&h, &v);
1770 return makepoint(h, v);
1771}
1772
1773static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001774stdwin_menucreate(self, args)
1775 object *self;
1776 object *args;
1777{
1778 object *title;
1779 if (!getstrarg(args, &title))
1780 return NULL;
1781 wmenusetdeflocal(0);
1782 return (object *)newmenuobject(title);
1783}
1784
1785static object *
1786stdwin_askfile(self, args)
1787 object *self;
1788 object *args;
1789{
1790 object *prompt, *dflt;
1791 int new, ret;
1792 char buf[256];
1793 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1794 return NULL;
1795 strncpy(buf, getstringvalue(dflt), sizeof buf);
1796 buf[sizeof buf - 1] = '\0';
1797 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1798 if (!ret) {
1799 err_set(KeyboardInterrupt);
1800 return NULL;
1801 }
1802 return newstringobject(buf);
1803}
1804
1805static object *
1806stdwin_askync(self, args)
1807 object *self;
1808 object *args;
1809{
1810 object *prompt;
1811 int new, ret;
1812 if (!getstrintarg(args, &prompt, &new))
1813 return NULL;
1814 ret = waskync(getstringvalue(prompt), new);
1815 if (ret < 0) {
1816 err_set(KeyboardInterrupt);
1817 return NULL;
1818 }
1819 return newintobject((long)ret);
1820}
1821
1822static object *
1823stdwin_askstr(self, args)
1824 object *self;
1825 object *args;
1826{
1827 object *prompt, *dflt;
1828 int ret;
1829 char buf[256];
1830 if (!getstrstrarg(args, &prompt, &dflt))
1831 return NULL;
1832 strncpy(buf, getstringvalue(dflt), sizeof buf);
1833 buf[sizeof buf - 1] = '\0';
1834 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1835 if (!ret) {
1836 err_set(KeyboardInterrupt);
1837 return NULL;
1838 }
1839 return newstringobject(buf);
1840}
1841
1842static object *
1843stdwin_message(self, args)
1844 object *self;
1845 object *args;
1846{
1847 object *msg;
1848 if (!getstrarg(args, &msg))
1849 return NULL;
1850 wmessage(getstringvalue(msg));
1851 INCREF(None);
1852 return None;
1853}
1854
1855static object *
1856stdwin_fleep(self, args)
1857 object *self;
1858 object *args;
1859{
1860 if (!getnoarg(args))
1861 return NULL;
1862 wfleep();
1863 INCREF(None);
1864 return None;
1865}
1866
1867static object *
1868stdwin_setcutbuffer(self, args)
1869 object *self;
1870 object *args;
1871{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001872 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001873 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001874 if (!getintstrarg(args, &i, &str))
1875 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001876 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001877 INCREF(None);
1878 return None;
1879}
1880
1881static object *
1882stdwin_getcutbuffer(self, args)
1883 object *self;
1884 object *args;
1885{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001886 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001887 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001888 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001889 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001890 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001891 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001892 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001893 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001894 len = 0;
1895 }
1896 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001897}
1898
Guido van Rossum5b10f451990-10-30 16:01:48 +00001899static object *
1900stdwin_rotatecutbuffers(self, args)
1901 object *self;
1902 object *args;
1903{
1904 int i;
1905 if (!getintarg(args, &i))
1906 return NULL;
1907 wrotatecutbuffers(i);
1908 INCREF(None);
1909 return None;
1910}
1911
1912static object *
1913stdwin_getselection(self, args)
1914 object *self;
1915 object *args;
1916{
1917 int sel;
1918 char *data;
1919 int len;
1920 if (!getintarg(args, &sel))
1921 return NULL;
1922 data = wgetselection(sel, &len);
1923 if (data == NULL) {
1924 data = "";
1925 len = 0;
1926 }
1927 return newsizedstringobject(data, len);
1928}
1929
1930static object *
1931stdwin_resetselection(self, args)
1932 object *self;
1933 object *args;
1934{
1935 int sel;
1936 if (!getintarg(args, &sel))
1937 return NULL;
1938 wresetselection(sel);
1939 INCREF(None);
1940 return None;
1941}
1942
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001943static object *
1944stdwin_fetchcolor(self, args)
1945 object *self;
1946 object *args;
1947{
1948 object *colorname;
1949 if (!getstrarg(args, &colorname))
1950 return NULL;
1951 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
1952}
1953
Guido van Rossum541c8c01991-05-05 20:13:41 +00001954static object *
1955stdwin_getscrsize(self, args)
1956 object *self;
1957 object *args;
1958{
1959 int width, height;
1960 if (!getnoarg(args))
1961 return NULL;
1962 wgetscrsize(&width, &height);
1963 return makepoint(width, height);
1964}
1965
1966static object *
1967stdwin_getscrmm(self, args)
1968 object *self;
1969 object *args;
1970{
1971 int width, height;
1972 if (!getnoarg(args))
1973 return NULL;
1974 wgetscrmm(&width, &height);
1975 return makepoint(width, height);
1976}
1977
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001978static struct methodlist stdwin_methods[] = {
1979 {"askfile", stdwin_askfile},
1980 {"askstr", stdwin_askstr},
1981 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00001982 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001983 {"fleep", stdwin_fleep},
1984 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001985 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00001986 {"getdefwinpos", stdwin_getdefwinpos},
1987 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001989 {"getscrmm", stdwin_getscrmm},
1990 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00001991 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001992 {"menucreate", stdwin_menucreate},
1993 {"message", stdwin_message},
1994 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001995 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001996 {"resetselection", stdwin_resetselection},
1997 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001998 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001999 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002000 {"setdefwinpos", stdwin_setdefwinpos},
2001 {"setdefwinsize", stdwin_setdefwinsize},
2002
2003 /* Text measuring methods borrow code from drawing objects: */
2004 {"baseline", drawing_baseline},
2005 {"lineheight", drawing_lineheight},
2006 {"textbreak", drawing_textbreak},
2007 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002008
2009 /* Same for font setting methods: */
2010 {"setfont", drawing_setfont},
2011
2012 /* Same for color setting/getting methods: */
2013 {"getbgcolor", drawing_getbgcolor},
2014 {"getfgcolor", drawing_getfgcolor},
2015 {"setbgcolor", drawing_setbgcolor},
2016 {"setfgcolor", drawing_setfgcolor},
2017
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018 {NULL, NULL} /* sentinel */
2019};
2020
2021void
2022initstdwin()
2023{
Guido van Rossum2d14e211991-02-19 12:26:49 +00002024 static int inited;
2025 if (!inited) {
2026 winit();
2027 inited = 1;
2028 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029 initmodule("stdwin", stdwin_methods);
2030}