blob: 2050b5f072834e8dff45e2057e289d3d62ec89ba [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
706static typeobject Drawingtype = {
707 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 *
921text_replace(self, args)
922 textobject *self;
923 object *args;
924{
925 object *text;
926 if (!getstrarg(args, &text))
927 return NULL;
928 tereplace(self->t_text, getstringvalue(text));
929 INCREF(None);
930 return None;
931}
932
933static struct methodlist text_methods[] = {
934 "arrow", text_arrow,
935 "draw", text_draw,
936 "event", text_event,
937 "getfocus", text_getfocus,
938 "getfocustext", text_getfocustext,
939 "getrect", text_getrect,
940 "gettext", text_gettext,
941 "move", text_move,
942 "replace", text_replace,
943 "setfocus", text_setfocus,
944 {NULL, NULL} /* sentinel */
945};
946
947static object *
948text_getattr(tp, name)
949 textobject *tp;
950 char *name;
951{
952 if (tp->t_attr != NULL) {
953 object *v = dictlookup(tp->t_attr, name);
954 if (v != NULL) {
955 INCREF(v);
956 return v;
957 }
958 }
959 return findmethod(text_methods, (object *)tp, name);
960}
961
962static int
963text_setattr(tp, name, v)
964 textobject *tp;
965 char *name;
966 object *v;
967{
968 if (tp->t_attr == NULL) {
969 tp->t_attr = newdictobject();
970 if (tp->t_attr == NULL)
971 return -1;
972 }
973 if (v == NULL)
974 return dictremove(tp->t_attr, name);
975 else
976 return dictinsert(tp->t_attr, name, v);
977}
978
979static typeobject Texttype = {
980 OB_HEAD_INIT(&Typetype)
981 0, /*ob_size*/
982 "textedit", /*tp_name*/
983 sizeof(textobject), /*tp_size*/
984 0, /*tp_itemsize*/
985 /* methods */
986 text_dealloc, /*tp_dealloc*/
987 0, /*tp_print*/
988 text_getattr, /*tp_getattr*/
989 text_setattr, /*tp_setattr*/
990 0, /*tp_compare*/
991 0, /*tp_repr*/
992};
993
994
995/* Menu objects */
996
Guido van Rossum2d14e211991-02-19 12:26:49 +0000997#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +0000998#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +0000999static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001000
1001static menuobject *
1002newmenuobject(title)
1003 object *title;
1004{
1005 int id;
1006 MENU *menu;
1007 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001008 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 if (menulist[id] == NULL)
1010 break;
1011 }
Guido van Rossum27201061991-04-16 08:43:03 +00001012 if (id >= MAXNMENU) {
1013 err_setstr(MemoryError, "creating too many menus");
1014 return NULL;
1015 }
Guido van Rossum2d14e211991-02-19 12:26:49 +00001016 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017 if (menu == NULL)
1018 return (menuobject *) err_nomem();
1019 mp = NEWOBJ(menuobject, &Menutype);
1020 if (mp != NULL) {
1021 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001022 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001023 mp->m_attr = NULL;
1024 menulist[id] = mp;
1025 }
1026 else
1027 wmenudelete(menu);
1028 return mp;
1029}
1030
1031/* Menu methods */
1032
1033static void
1034menu_dealloc(mp)
1035 menuobject *mp;
1036{
1037
Guido van Rossum2d14e211991-02-19 12:26:49 +00001038 int id = mp->m_id - IDOFFSET;
1039 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 menulist[id] = NULL;
1041 }
1042 wmenudelete(mp->m_menu);
1043 if (mp->m_attr != NULL)
1044 DECREF(mp->m_attr);
1045 DEL(mp);
1046}
1047
1048static object *
1049menu_additem(self, args)
1050 menuobject *self;
1051 object *args;
1052{
1053 object *text;
1054 int shortcut;
1055 if (is_tupleobject(args)) {
1056 object *v;
1057 if (!getstrstrarg(args, &text, &v))
1058 return NULL;
1059 if (getstringsize(v) != 1) {
1060 err_badarg();
1061 return NULL;
1062 }
1063 shortcut = *getstringvalue(v) & 0xff;
1064 }
1065 else {
1066 if (!getstrarg(args, &text))
1067 return NULL;
1068 shortcut = -1;
1069 }
1070 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
1071 INCREF(None);
1072 return None;
1073}
1074
1075static object *
1076menu_setitem(self, args)
1077 menuobject *self;
1078 object *args;
1079{
1080 int index;
1081 object *text;
1082 if (!getintstrarg(args, &index, &text))
1083 return NULL;
1084 wmenusetitem(self->m_menu, index, getstringvalue(text));
1085 INCREF(None);
1086 return None;
1087}
1088
1089static object *
1090menu_enable(self, args)
1091 menuobject *self;
1092 object *args;
1093{
1094 int index;
1095 int flag;
1096 if (!getintintarg(args, &index, &flag))
1097 return NULL;
1098 wmenuenable(self->m_menu, index, flag);
1099 INCREF(None);
1100 return None;
1101}
1102
1103static object *
1104menu_check(self, args)
1105 menuobject *self;
1106 object *args;
1107{
1108 int index;
1109 int flag;
1110 if (!getintintarg(args, &index, &flag))
1111 return NULL;
1112 wmenucheck(self->m_menu, index, flag);
1113 INCREF(None);
1114 return None;
1115}
1116
1117static struct methodlist menu_methods[] = {
1118 "additem", menu_additem,
1119 "setitem", menu_setitem,
1120 "enable", menu_enable,
1121 "check", menu_check,
1122 {NULL, NULL} /* sentinel */
1123};
1124
1125static object *
1126menu_getattr(mp, name)
1127 menuobject *mp;
1128 char *name;
1129{
1130 if (mp->m_attr != NULL) {
1131 object *v = dictlookup(mp->m_attr, name);
1132 if (v != NULL) {
1133 INCREF(v);
1134 return v;
1135 }
1136 }
1137 return findmethod(menu_methods, (object *)mp, name);
1138}
1139
1140static int
1141menu_setattr(mp, name, v)
1142 menuobject *mp;
1143 char *name;
1144 object *v;
1145{
1146 if (mp->m_attr == NULL) {
1147 mp->m_attr = newdictobject();
1148 if (mp->m_attr == NULL)
1149 return -1;
1150 }
1151 if (v == NULL)
1152 return dictremove(mp->m_attr, name);
1153 else
1154 return dictinsert(mp->m_attr, name, v);
1155}
1156
1157static typeobject Menutype = {
1158 OB_HEAD_INIT(&Typetype)
1159 0, /*ob_size*/
1160 "menu", /*tp_name*/
1161 sizeof(menuobject), /*tp_size*/
1162 0, /*tp_itemsize*/
1163 /* methods */
1164 menu_dealloc, /*tp_dealloc*/
1165 0, /*tp_print*/
1166 menu_getattr, /*tp_getattr*/
1167 menu_setattr, /*tp_setattr*/
1168 0, /*tp_compare*/
1169 0, /*tp_repr*/
1170};
1171
1172
1173/* Windows */
1174
1175#define MAXNWIN 50
1176static windowobject *windowlist[MAXNWIN];
1177
1178/* Window methods */
1179
1180static void
1181window_dealloc(wp)
1182 windowobject *wp;
1183{
1184 if (wp->w_win != NULL) {
1185 int tag = wgettag(wp->w_win);
1186 if (tag >= 0 && tag < MAXNWIN)
1187 windowlist[tag] = NULL;
1188 else
1189 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1190 tag);
1191 wclose(wp->w_win);
1192 }
1193 DECREF(wp->w_title);
1194 if (wp->w_attr != NULL)
1195 DECREF(wp->w_attr);
1196 free((char *)wp);
1197}
1198
1199static void
1200window_print(wp, fp, flags)
1201 windowobject *wp;
1202 FILE *fp;
1203 int flags;
1204{
1205 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1206}
1207
1208static object *
1209window_begindrawing(wp, args)
1210 windowobject *wp;
1211 object *args;
1212{
1213 drawingobject *dp;
1214 if (!getnoarg(args))
1215 return NULL;
1216 if (Drawing != NULL) {
1217 err_setstr(RuntimeError, "already drawing");
1218 return NULL;
1219 }
1220 dp = NEWOBJ(drawingobject, &Drawingtype);
1221 if (dp == NULL)
1222 return NULL;
1223 Drawing = dp;
1224 INCREF(wp);
1225 dp->d_ref = wp;
1226 wbegindrawing(wp->w_win);
1227 return (object *)dp;
1228}
1229
1230static object *
1231window_change(wp, args)
1232 windowobject *wp;
1233 object *args;
1234{
1235 int a[4];
1236 if (!getrectarg(args, a))
1237 return NULL;
1238 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1239 INCREF(None);
1240 return None;
1241}
1242
1243static object *
1244window_gettitle(wp, args)
1245 windowobject *wp;
1246 object *args;
1247{
1248 if (!getnoarg(args))
1249 return NULL;
1250 INCREF(wp->w_title);
1251 return wp->w_title;
1252}
1253
1254static object *
1255window_getwinsize(wp, args)
1256 windowobject *wp;
1257 object *args;
1258{
1259 int width, height;
1260 if (!getnoarg(args))
1261 return NULL;
1262 wgetwinsize(wp->w_win, &width, &height);
1263 return makepoint(width, height);
1264}
1265
1266static object *
1267window_getdocsize(wp, args)
1268 windowobject *wp;
1269 object *args;
1270{
1271 int width, height;
1272 if (!getnoarg(args))
1273 return NULL;
1274 wgetdocsize(wp->w_win, &width, &height);
1275 return makepoint(width, height);
1276}
1277
1278static object *
1279window_getorigin(wp, args)
1280 windowobject *wp;
1281 object *args;
1282{
1283 int width, height;
1284 if (!getnoarg(args))
1285 return NULL;
1286 wgetorigin(wp->w_win, &width, &height);
1287 return makepoint(width, height);
1288}
1289
1290static object *
1291window_scroll(wp, args)
1292 windowobject *wp;
1293 object *args;
1294{
1295 int a[6];
1296 if (!getrectpointarg(args, a))
1297 return NULL;
1298 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1299 INCREF(None);
1300 return None;
1301}
1302
1303static object *
1304window_setdocsize(wp, args)
1305 windowobject *wp;
1306 object *args;
1307{
1308 int a[2];
1309 if (!getpointarg(args, a))
1310 return NULL;
1311 wsetdocsize(wp->w_win, a[0], a[1]);
1312 INCREF(None);
1313 return None;
1314}
1315
1316static object *
1317window_setorigin(wp, args)
1318 windowobject *wp;
1319 object *args;
1320{
1321 int a[2];
1322 if (!getpointarg(args, a))
1323 return NULL;
1324 wsetorigin(wp->w_win, a[0], a[1]);
1325 INCREF(None);
1326 return None;
1327}
1328
1329static object *
1330window_settitle(wp, args)
1331 windowobject *wp;
1332 object *args;
1333{
1334 object *title;
1335 if (!getstrarg(args, &title))
1336 return NULL;
1337 DECREF(wp->w_title);
1338 INCREF(title);
1339 wp->w_title = title;
1340 wsettitle(wp->w_win, getstringvalue(title));
1341 INCREF(None);
1342 return None;
1343}
1344
1345static object *
1346window_show(wp, args)
1347 windowobject *wp;
1348 object *args;
1349{
1350 int a[4];
1351 if (!getrectarg(args, a))
1352 return NULL;
1353 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1354 INCREF(None);
1355 return None;
1356}
1357
1358static object *
1359window_settimer(wp, args)
1360 windowobject *wp;
1361 object *args;
1362{
1363 int a;
1364 if (!getintarg(args, &a))
1365 return NULL;
1366 wsettimer(wp->w_win, a);
1367 INCREF(None);
1368 return None;
1369}
1370
1371static object *
1372window_menucreate(self, args)
1373 windowobject *self;
1374 object *args;
1375{
1376 menuobject *mp;
1377 object *title;
1378 if (!getstrarg(args, &title))
1379 return NULL;
1380 wmenusetdeflocal(1);
1381 mp = newmenuobject(title);
1382 if (mp == NULL)
1383 return NULL;
1384 wmenuattach(self->w_win, mp->m_menu);
1385 return (object *)mp;
1386}
1387
1388static object *
1389window_textcreate(self, args)
1390 windowobject *self;
1391 object *args;
1392{
1393 textobject *tp;
1394 int a[4];
1395 if (!getrectarg(args, a))
1396 return NULL;
1397 return (object *)
1398 newtextobject(self, a[0], a[1], a[2], a[3]);
1399}
1400
Guido van Rossum5b10f451990-10-30 16:01:48 +00001401static object *
1402window_setselection(self, args)
1403 windowobject *self;
1404 object *args;
1405{
1406 int sel;
1407 object *str;
1408 int ok;
1409 if (!getintstrarg(args, &sel, &str))
1410 return NULL;
1411 ok = wsetselection(self->w_win, sel,
1412 getstringvalue(str), (int)getstringsize(str));
1413 return newintobject(ok);
1414}
1415
1416static object *
1417window_setwincursor(self, args)
1418 windowobject *self;
1419 object *args;
1420{
1421 object *str;
1422 CURSOR *c;
1423 if (!getstrarg(args, &str))
1424 return NULL;
1425 c = wfetchcursor(getstringvalue(str));
1426 if (c == NULL) {
1427 err_setstr(RuntimeError, "no such cursor");
1428 return NULL;
1429 }
1430 wsetwincursor(self->w_win, c);
1431 INCREF(None);
1432 return None;
1433}
1434
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001435static struct methodlist window_methods[] = {
1436 {"begindrawing",window_begindrawing},
1437 {"change", window_change},
1438 {"getdocsize", window_getdocsize},
1439 {"getorigin", window_getorigin},
1440 {"gettitle", window_gettitle},
1441 {"getwinsize", window_getwinsize},
1442 {"menucreate", window_menucreate},
1443 {"scroll", window_scroll},
1444 {"setdocsize", window_setdocsize},
1445 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001446 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447 {"settimer", window_settimer},
1448 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001449 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450 {"show", window_show},
1451 {"textcreate", window_textcreate},
1452 {NULL, NULL} /* sentinel */
1453};
1454
1455static object *
1456window_getattr(wp, name)
1457 windowobject *wp;
1458 char *name;
1459{
1460 if (wp->w_attr != NULL) {
1461 object *v = dictlookup(wp->w_attr, name);
1462 if (v != NULL) {
1463 INCREF(v);
1464 return v;
1465 }
1466 }
1467 return findmethod(window_methods, (object *)wp, name);
1468}
1469
1470static int
1471window_setattr(wp, name, v)
1472 windowobject *wp;
1473 char *name;
1474 object *v;
1475{
1476 if (wp->w_attr == NULL) {
1477 wp->w_attr = newdictobject();
1478 if (wp->w_attr == NULL)
1479 return -1;
1480 }
1481 if (v == NULL)
1482 return dictremove(wp->w_attr, name);
1483 else
1484 return dictinsert(wp->w_attr, name, v);
1485}
1486
1487static typeobject Windowtype = {
1488 OB_HEAD_INIT(&Typetype)
1489 0, /*ob_size*/
1490 "window", /*tp_name*/
1491 sizeof(windowobject), /*tp_size*/
1492 0, /*tp_itemsize*/
1493 /* methods */
1494 window_dealloc, /*tp_dealloc*/
1495 window_print, /*tp_print*/
1496 window_getattr, /*tp_getattr*/
1497 window_setattr, /*tp_setattr*/
1498 0, /*tp_compare*/
1499 0, /*tp_repr*/
1500};
1501
1502/* Stdwin methods */
1503
1504static object *
1505stdwin_open(sw, args)
1506 object *sw;
1507 object *args;
1508{
1509 int tag;
1510 object *title;
1511 windowobject *wp;
1512 if (!getstrarg(args, &title))
1513 return NULL;
1514 for (tag = 0; tag < MAXNWIN; tag++) {
1515 if (windowlist[tag] == NULL)
1516 break;
1517 }
Guido van Rossum27201061991-04-16 08:43:03 +00001518 if (tag >= MAXNWIN) {
1519 err_setstr(MemoryError, "creating too many windows");
1520 return NULL;
1521 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522 wp = NEWOBJ(windowobject, &Windowtype);
1523 if (wp == NULL)
1524 return NULL;
1525 INCREF(title);
1526 wp->w_title = title;
1527 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1528 wp->w_attr = NULL;
1529 if (wp->w_win == NULL) {
1530 DECREF(wp);
1531 return NULL;
1532 }
1533 windowlist[tag] = wp;
1534 wsettag(wp->w_win, tag);
1535 return (object *)wp;
1536}
1537
1538static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001539stdwin_get_poll_event(poll, args)
1540 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001541 object *args;
1542{
1543 EVENT e;
1544 object *v, *w;
1545 if (!getnoarg(args))
1546 return NULL;
1547 if (Drawing != NULL) {
1548 err_setstr(RuntimeError, "cannot getevent() while drawing");
1549 return NULL;
1550 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001551/* again: */
1552 if (poll) {
1553 if (!wpollevent(&e)) {
1554 INCREF(None);
1555 return None;
1556 }
1557 }
1558 else
1559 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001560 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1561 /* Turn keyboard interrupts into exceptions */
1562 err_set(KeyboardInterrupt);
1563 return NULL;
1564 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001565/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001566 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1567 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001568*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001569 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1570 /* Turn WC_CLOSE commands into WE_CLOSE events */
1571 e.type = WE_CLOSE;
1572 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001573 v = newtupleobject(3);
1574 if (v == NULL)
1575 return NULL;
1576 if ((w = newintobject((long)e.type)) == NULL) {
1577 DECREF(v);
1578 return NULL;
1579 }
1580 settupleitem(v, 0, w);
1581 if (e.window == NULL)
1582 w = None;
1583 else {
1584 int tag = wgettag(e.window);
1585 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1586 w = None;
1587 else
1588 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001589#ifdef sgi
1590 /* XXX Trap for unexplained weird bug */
1591 if ((long)w == (long)0x80000001) {
1592 err_setstr(SystemError,
1593 "bad pointer in stdwin.getevent()");
1594 return NULL;
1595 }
1596#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001597 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001598 INCREF(w);
1599 settupleitem(v, 1, w);
1600 switch (e.type) {
1601 case WE_CHAR:
1602 {
1603 char c[1];
1604 c[0] = e.u.character;
1605 w = newsizedstringobject(c, 1);
1606 }
1607 break;
1608 case WE_COMMAND:
1609 w = newintobject((long)e.u.command);
1610 break;
1611 case WE_DRAW:
1612 w = makerect(e.u.area.left, e.u.area.top,
1613 e.u.area.right, e.u.area.bottom);
1614 break;
1615 case WE_MOUSE_DOWN:
1616 case WE_MOUSE_MOVE:
1617 case WE_MOUSE_UP:
1618 w = makemouse(e.u.where.h, e.u.where.v,
1619 e.u.where.clicks,
1620 e.u.where.button,
1621 e.u.where.mask);
1622 break;
1623 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001624 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1625 menulist[e.u.m.id - IDOFFSET] != NULL)
1626 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001627 else
1628 w = None;
1629 w = makemenu(w, e.u.m.item);
1630 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001631 case WE_LOST_SEL:
1632 w = newintobject((long)e.u.sel);
1633 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001634 default:
1635 w = None;
1636 INCREF(w);
1637 break;
1638 }
1639 if (w == NULL) {
1640 DECREF(v);
1641 return NULL;
1642 }
1643 settupleitem(v, 2, w);
1644 return v;
1645}
1646
1647static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001648stdwin_getevent(sw, args)
1649 object *sw;
1650 object *args;
1651{
1652 return stdwin_get_poll_event(0, args);
1653}
1654
1655static object *
1656stdwin_pollevent(sw, args)
1657 object *sw;
1658 object *args;
1659{
1660 return stdwin_get_poll_event(1, args);
1661}
1662
1663static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664stdwin_setdefwinpos(sw, args)
1665 object *sw;
1666 object *args;
1667{
1668 int a[2];
1669 if (!getpointarg(args, a))
1670 return NULL;
1671 wsetdefwinpos(a[0], a[1]);
1672 INCREF(None);
1673 return None;
1674}
1675
1676static object *
1677stdwin_setdefwinsize(sw, args)
1678 object *sw;
1679 object *args;
1680{
1681 int a[2];
1682 if (!getpointarg(args, a))
1683 return NULL;
1684 wsetdefwinsize(a[0], a[1]);
1685 INCREF(None);
1686 return None;
1687}
1688
1689static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001690stdwin_setdefscrollbars(sw, args)
1691 object *sw;
1692 object *args;
1693{
1694 int a[2];
1695 if (!getpointarg(args, a))
1696 return NULL;
1697 wsetdefscrollbars(a[0], a[1]);
1698 INCREF(None);
1699 return None;
1700}
1701
1702static object *
Guido van Rossum33f17701991-02-13 23:19:39 +00001703stdwin_getdefwinpos(wp, args)
1704 windowobject *wp;
1705 object *args;
1706{
1707 int h, v;
1708 if (!getnoarg(args))
1709 return NULL;
1710 wgetdefwinpos(&h, &v);
1711 return makepoint(h, v);
1712}
1713
1714static object *
1715stdwin_getdefwinsize(wp, args)
1716 windowobject *wp;
1717 object *args;
1718{
1719 int width, height;
1720 if (!getnoarg(args))
1721 return NULL;
1722 wgetdefwinsize(&width, &height);
1723 return makepoint(width, height);
1724}
1725
1726static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001727stdwin_getdefscrollbars(wp, args)
1728 windowobject *wp;
1729 object *args;
1730{
1731 int h, v;
1732 if (!getnoarg(args))
1733 return NULL;
1734 wgetdefscrollbars(&h, &v);
1735 return makepoint(h, v);
1736}
1737
1738static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001739stdwin_menucreate(self, args)
1740 object *self;
1741 object *args;
1742{
1743 object *title;
1744 if (!getstrarg(args, &title))
1745 return NULL;
1746 wmenusetdeflocal(0);
1747 return (object *)newmenuobject(title);
1748}
1749
1750static object *
1751stdwin_askfile(self, args)
1752 object *self;
1753 object *args;
1754{
1755 object *prompt, *dflt;
1756 int new, ret;
1757 char buf[256];
1758 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1759 return NULL;
1760 strncpy(buf, getstringvalue(dflt), sizeof buf);
1761 buf[sizeof buf - 1] = '\0';
1762 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1763 if (!ret) {
1764 err_set(KeyboardInterrupt);
1765 return NULL;
1766 }
1767 return newstringobject(buf);
1768}
1769
1770static object *
1771stdwin_askync(self, args)
1772 object *self;
1773 object *args;
1774{
1775 object *prompt;
1776 int new, ret;
1777 if (!getstrintarg(args, &prompt, &new))
1778 return NULL;
1779 ret = waskync(getstringvalue(prompt), new);
1780 if (ret < 0) {
1781 err_set(KeyboardInterrupt);
1782 return NULL;
1783 }
1784 return newintobject((long)ret);
1785}
1786
1787static object *
1788stdwin_askstr(self, args)
1789 object *self;
1790 object *args;
1791{
1792 object *prompt, *dflt;
1793 int ret;
1794 char buf[256];
1795 if (!getstrstrarg(args, &prompt, &dflt))
1796 return NULL;
1797 strncpy(buf, getstringvalue(dflt), sizeof buf);
1798 buf[sizeof buf - 1] = '\0';
1799 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1800 if (!ret) {
1801 err_set(KeyboardInterrupt);
1802 return NULL;
1803 }
1804 return newstringobject(buf);
1805}
1806
1807static object *
1808stdwin_message(self, args)
1809 object *self;
1810 object *args;
1811{
1812 object *msg;
1813 if (!getstrarg(args, &msg))
1814 return NULL;
1815 wmessage(getstringvalue(msg));
1816 INCREF(None);
1817 return None;
1818}
1819
1820static object *
1821stdwin_fleep(self, args)
1822 object *self;
1823 object *args;
1824{
1825 if (!getnoarg(args))
1826 return NULL;
1827 wfleep();
1828 INCREF(None);
1829 return None;
1830}
1831
1832static object *
1833stdwin_setcutbuffer(self, args)
1834 object *self;
1835 object *args;
1836{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001837 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001838 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001839 if (!getintstrarg(args, &i, &str))
1840 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001841 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001842 INCREF(None);
1843 return None;
1844}
1845
1846static object *
1847stdwin_getcutbuffer(self, args)
1848 object *self;
1849 object *args;
1850{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001851 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001852 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001853 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001854 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001856 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001857 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001858 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001859 len = 0;
1860 }
1861 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001862}
1863
Guido van Rossum5b10f451990-10-30 16:01:48 +00001864static object *
1865stdwin_rotatecutbuffers(self, args)
1866 object *self;
1867 object *args;
1868{
1869 int i;
1870 if (!getintarg(args, &i))
1871 return NULL;
1872 wrotatecutbuffers(i);
1873 INCREF(None);
1874 return None;
1875}
1876
1877static object *
1878stdwin_getselection(self, args)
1879 object *self;
1880 object *args;
1881{
1882 int sel;
1883 char *data;
1884 int len;
1885 if (!getintarg(args, &sel))
1886 return NULL;
1887 data = wgetselection(sel, &len);
1888 if (data == NULL) {
1889 data = "";
1890 len = 0;
1891 }
1892 return newsizedstringobject(data, len);
1893}
1894
1895static object *
1896stdwin_resetselection(self, args)
1897 object *self;
1898 object *args;
1899{
1900 int sel;
1901 if (!getintarg(args, &sel))
1902 return NULL;
1903 wresetselection(sel);
1904 INCREF(None);
1905 return None;
1906}
1907
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001908static object *
1909stdwin_fetchcolor(self, args)
1910 object *self;
1911 object *args;
1912{
1913 object *colorname;
1914 if (!getstrarg(args, &colorname))
1915 return NULL;
1916 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
1917}
1918
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001919static struct methodlist stdwin_methods[] = {
1920 {"askfile", stdwin_askfile},
1921 {"askstr", stdwin_askstr},
1922 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00001923 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001924 {"fleep", stdwin_fleep},
1925 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001926 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00001927 {"getdefwinpos", stdwin_getdefwinpos},
1928 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001929 {"getevent", stdwin_getevent},
Guido van Rossum27201061991-04-16 08:43:03 +00001930 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001931 {"menucreate", stdwin_menucreate},
1932 {"message", stdwin_message},
1933 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001934 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001935 {"resetselection", stdwin_resetselection},
1936 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001937 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001938 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001939 {"setdefwinpos", stdwin_setdefwinpos},
1940 {"setdefwinsize", stdwin_setdefwinsize},
1941
1942 /* Text measuring methods borrow code from drawing objects: */
1943 {"baseline", drawing_baseline},
1944 {"lineheight", drawing_lineheight},
1945 {"textbreak", drawing_textbreak},
1946 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001947
1948 /* Same for font setting methods: */
1949 {"setfont", drawing_setfont},
1950
1951 /* Same for color setting/getting methods: */
1952 {"getbgcolor", drawing_getbgcolor},
1953 {"getfgcolor", drawing_getfgcolor},
1954 {"setbgcolor", drawing_setbgcolor},
1955 {"setfgcolor", drawing_setfgcolor},
1956
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957 {NULL, NULL} /* sentinel */
1958};
1959
1960void
1961initstdwin()
1962{
Guido van Rossum2d14e211991-02-19 12:26:49 +00001963 static int inited;
1964 if (!inited) {
1965 winit();
1966 inited = 1;
1967 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001968 initmodule("stdwin", stdwin_methods);
1969}