blob: 0a572e457e07bd2d9cc468070b0390cc9862b3f8 [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}
317
318static object *
319drawing_elarc(dp, args)
320 drawingobject *dp;
321 object *args;
322{
323 int a[6];
324 if (!get3pointarg(args, a))
325 return NULL;
326 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
327 INCREF(None);
328 return None;
329}
330
331static object *
332drawing_box(dp, args)
333 drawingobject *dp;
334 object *args;
335{
Guido van Rossumbf109731991-03-06 13:14:12 +0000336 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337}
338
339static object *
340drawing_erase(dp, args)
341 drawingobject *dp;
342 object *args;
343{
Guido van Rossumbf109731991-03-06 13:14:12 +0000344 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345}
346
347static object *
348drawing_paint(dp, args)
349 drawingobject *dp;
350 object *args;
351{
Guido van Rossumbf109731991-03-06 13:14:12 +0000352 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353}
354
355static object *
356drawing_invert(dp, args)
357 drawingobject *dp;
358 object *args;
359{
Guido van Rossumbf109731991-03-06 13:14:12 +0000360 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361}
362
363static object *
364drawing_cliprect(dp, args)
365 drawingobject *dp;
366 object *args;
367{
Guido van Rossumbf109731991-03-06 13:14:12 +0000368 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369}
370
371static object *
372drawing_noclip(dp, args)
373 drawingobject *dp;
374 object *args;
375{
376 if (!getnoarg(args))
377 return NULL;
378 wnoclip();
379 INCREF(None);
380 return None;
381}
382
383static object *
384drawing_shade(dp, args)
385 drawingobject *dp;
386 object *args;
387{
388 int a[5];
389 if (!getrectintarg(args, a))
390 return NULL;
391 wshade(a[0], a[1], a[2], a[3], a[4]);
392 INCREF(None);
393 return None;
394}
395
396static object *
397drawing_text(dp, args)
398 drawingobject *dp;
399 object *args;
400{
401 int a[2];
402 object *s;
403 if (!getpointstrarg(args, a, &s))
404 return NULL;
405 wdrawtext(a[0], a[1], getstringvalue(s), (int)getstringsize(s));
406 INCREF(None);
407 return None;
408}
409
410/* The following four are also used as stdwin functions */
411
412static object *
413drawing_lineheight(dp, args)
414 drawingobject *dp;
415 object *args;
416{
417 if (!getnoarg(args))
418 return NULL;
419 return newintobject((long)wlineheight());
420}
421
422static object *
423drawing_baseline(dp, args)
424 drawingobject *dp;
425 object *args;
426{
427 if (!getnoarg(args))
428 return NULL;
429 return newintobject((long)wbaseline());
430}
431
432static object *
433drawing_textwidth(dp, args)
434 drawingobject *dp;
435 object *args;
436{
437 object *s;
438 if (!getstrarg(args, &s))
439 return NULL;
440 return newintobject(
441 (long)wtextwidth(getstringvalue(s), (int)getstringsize(s)));
442}
443
444static object *
445drawing_textbreak(dp, args)
446 drawingobject *dp;
447 object *args;
448{
449 object *s;
450 int a;
451 if (!getstrintarg(args, &s, &a))
452 return NULL;
453 return newintobject(
454 (long)wtextbreak(getstringvalue(s), (int)getstringsize(s), a));
455}
456
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000457static object *
458drawing_setfont(self, args)
459 drawingobject *self;
460 object *args;
461{
Guido van Rossum50429a11991-04-04 15:24:07 +0000462 object *font, *style;
463 int size;
464 if (args == NULL) {
465 err_badarg();
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000466 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000467 }
468 if (is_stringobject(args)) {
469 font = args;
470 style = NULL;
471 size = 0;
472 }
473 else if (is_tupleobject(args)) {
474 int n = gettuplesize(args);
475 if (n == 2) {
476 if (!getstrintarg(args, &font, &size))
477 return NULL;
478 style = NULL;
479 }
480 else if (!getstrstrintarg(args, &font, &style, &size))
481 return NULL;
482 }
483 else {
484 err_badarg();
485 return NULL;
486 }
487 if (getstringsize(font) != 0)
488 wsetfont(getstringvalue(font));
489 if (style != NULL) {
490 switch (*getstringvalue(style)) {
491 case 'b':
492 wsetbold();
493 break;
494 case 'i':
495 wsetitalic();
496 break;
497 case 'o':
498 wsetbolditalic();
499 break;
500 case 'u':
501 wsetunderline();
502 break;
503 default:
504 wsetplain();
505 break;
506 }
507 }
508 if (size != 0)
509 wsetsize(size);
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000510 INCREF(None);
511 return None;
512}
513
514static object *
515drawing_getbgcolor(self, args)
516 object *self;
517 object *args;
518{
519 if (!getnoarg(args))
520 return NULL;
521 return newintobject((long)wgetbgcolor());
522}
523
524static object *
525drawing_getfgcolor(self, args)
526 object *self;
527 object *args;
528{
529 if (!getnoarg(args))
530 return NULL;
531 return newintobject((long)wgetfgcolor());
532}
533
534static object *
535drawing_setbgcolor(self, args)
536 object *self;
537 object *args;
538{
539 long color;
540 if (!getlongarg(args, &color))
541 return NULL;
542 wsetbgcolor((COLOR)color);
543 INCREF(None);
544 return None;
545}
546
547static object *
548drawing_setfgcolor(self, args)
549 object *self;
550 object *args;
551{
552 long color;
553 if (!getlongarg(args, &color))
554 return NULL;
555 wsetfgcolor((COLOR)color);
556 INCREF(None);
557 return None;
558}
559
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560static struct methodlist drawing_methods[] = {
561 {"box", drawing_box},
562 {"circle", drawing_circle},
563 {"cliprect", drawing_cliprect},
564 {"elarc", drawing_elarc},
565 {"erase", drawing_erase},
566 {"invert", drawing_invert},
567 {"line", drawing_line},
568 {"noclip", drawing_noclip},
569 {"paint", drawing_paint},
570 {"shade", drawing_shade},
571 {"text", drawing_text},
572 {"xorline", drawing_xorline},
573
574 /* Text measuring methods: */
575 {"baseline", drawing_baseline},
576 {"lineheight", drawing_lineheight},
577 {"textbreak", drawing_textbreak},
578 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000579
580 /* Font setting methods: */
581 {"setfont", drawing_setfont},
582
583 /* Color methods: */
584 {"getbgcolor", drawing_getbgcolor},
585 {"getfgcolor", drawing_getfgcolor},
586 {"setbgcolor", drawing_setbgcolor},
587 {"setfgcolor", drawing_setfgcolor},
588
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589 {NULL, NULL} /* sentinel */
590};
591
592static object *
593drawing_getattr(wp, name)
594 drawingobject *wp;
595 char *name;
596{
597 return findmethod(drawing_methods, (object *)wp, name);
598}
599
600static typeobject Drawingtype = {
601 OB_HEAD_INIT(&Typetype)
602 0, /*ob_size*/
603 "drawing", /*tp_name*/
604 sizeof(drawingobject), /*tp_size*/
605 0, /*tp_itemsize*/
606 /* methods */
607 drawing_dealloc, /*tp_dealloc*/
608 0, /*tp_print*/
609 drawing_getattr, /*tp_getattr*/
610 0, /*tp_setattr*/
611 0, /*tp_compare*/
612 0, /*tp_repr*/
613};
614
615
616/* Text(edit) objects */
617
618typedef struct {
619 OB_HEAD
620 TEXTEDIT *t_text;
621 windowobject *t_ref;
622 object *t_attr; /* Attributes dictionary */
623} textobject;
624
625extern typeobject Texttype; /* Really static, forward */
626
627static textobject *
628newtextobject(wp, left, top, right, bottom)
629 windowobject *wp;
630 int left, top, right, bottom;
631{
632 textobject *tp;
633 tp = NEWOBJ(textobject, &Texttype);
634 if (tp == NULL)
635 return NULL;
636 tp->t_attr = NULL;
637 INCREF(wp);
638 tp->t_ref = wp;
639 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
640 if (tp->t_text == NULL) {
641 DECREF(tp);
642 return (textobject *) err_nomem();
643 }
644 return tp;
645}
646
647/* Text(edit) methods */
648
649static void
650text_dealloc(tp)
651 textobject *tp;
652{
653 if (tp->t_text != NULL)
654 tefree(tp->t_text);
655 if (tp->t_attr != NULL)
656 DECREF(tp->t_attr);
657 DECREF(tp->t_ref);
658 DEL(tp);
659}
660
661static object *
662text_arrow(self, args)
663 textobject *self;
664 object *args;
665{
666 int code;
667 if (!getintarg(args, &code))
668 return NULL;
669 tearrow(self->t_text, code);
670 INCREF(None);
671 return None;
672}
673
674static object *
675text_draw(self, args)
676 textobject *self;
677 object *args;
678{
679 register TEXTEDIT *tp = self->t_text;
680 int a[4];
681 int left, top, right, bottom;
682 if (!getrectarg(args, a))
683 return NULL;
684 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000685 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686 return NULL;
687 }
688 /* Clip to text area and ignore if area is empty */
689 left = tegetleft(tp);
690 top = tegettop(tp);
691 right = tegetright(tp);
692 bottom = tegetbottom(tp);
693 if (a[0] < left) a[0] = left;
694 if (a[1] < top) a[1] = top;
695 if (a[2] > right) a[2] = right;
696 if (a[3] > bottom) a[3] = bottom;
697 if (a[0] < a[2] && a[1] < a[3]) {
698 /* Hide/show focus around draw call; these are undocumented,
699 but required here to get the highlighting correct.
700 The call to werase is also required for this reason.
701 Finally, this forces us to require (above) that we are NOT
702 already drawing. */
703 tehidefocus(tp);
704 wbegindrawing(self->t_ref->w_win);
705 werase(a[0], a[1], a[2], a[3]);
706 tedrawnew(tp, a[0], a[1], a[2], a[3]);
707 wenddrawing(self->t_ref->w_win);
708 teshowfocus(tp);
709 }
710 INCREF(None);
711 return None;
712}
713
714static object *
715text_event(self, args)
716 textobject *self;
717 object *args;
718{
719 register TEXTEDIT *tp = self->t_text;
720 EVENT e;
721 if (!geteventarg(args, &e))
722 return NULL;
723 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000724 /* Cheat at the margins */
725 int width, height;
726 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727 if (e.u.where.h < 0 && tegetleft(tp) == 0)
728 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000729 else if (e.u.where.h > width && tegetright(tp) == width)
730 e.u.where.h = width;
731 if (e.u.where.v < 0 && tegettop(tp) == 0)
732 e.u.where.v = 0;
733 else if (e.u.where.v > height && tegetright(tp) == height)
734 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000735 }
736 return newintobject((long) teevent(tp, &e));
737}
738
739static object *
740text_getfocus(self, args)
741 textobject *self;
742 object *args;
743{
744 if (!getnoarg(args))
745 return NULL;
746 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
747}
748
749static object *
750text_getfocustext(self, args)
751 textobject *self;
752 object *args;
753{
754 int f1, f2;
755 char *text;
756 if (!getnoarg(args))
757 return NULL;
758 f1 = tegetfoc1(self->t_text);
759 f2 = tegetfoc2(self->t_text);
760 text = tegettext(self->t_text);
761 return newsizedstringobject(text + f1, f2-f1);
762}
763
764static object *
765text_getrect(self, args)
766 textobject *self;
767 object *args;
768{
769 if (!getnoarg(args))
770 return NULL;
771 return makerect(tegetleft(self->t_text),
772 tegettop(self->t_text),
773 tegetright(self->t_text),
774 tegetbottom(self->t_text));
775}
776
777static object *
778text_gettext(self, args)
779 textobject *self;
780 object *args;
781{
782 if (!getnoarg(args))
783 return NULL;
784 return newsizedstringobject(tegettext(self->t_text),
785 tegetlen(self->t_text));
786}
787
788static object *
789text_move(self, args)
790 textobject *self;
791 object *args;
792{
793 int a[4];
794 if (!getrectarg(args, a))
795 return NULL;
796 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
797 INCREF(None);
798 return None;
799}
800
801static object *
802text_setfocus(self, args)
803 textobject *self;
804 object *args;
805{
806 int a[2];
807 if (!getpointarg(args, a))
808 return NULL;
809 tesetfocus(self->t_text, a[0], a[1]);
810 INCREF(None);
811 return None;
812}
813
814static object *
815text_replace(self, args)
816 textobject *self;
817 object *args;
818{
819 object *text;
820 if (!getstrarg(args, &text))
821 return NULL;
822 tereplace(self->t_text, getstringvalue(text));
823 INCREF(None);
824 return None;
825}
826
827static struct methodlist text_methods[] = {
828 "arrow", text_arrow,
829 "draw", text_draw,
830 "event", text_event,
831 "getfocus", text_getfocus,
832 "getfocustext", text_getfocustext,
833 "getrect", text_getrect,
834 "gettext", text_gettext,
835 "move", text_move,
836 "replace", text_replace,
837 "setfocus", text_setfocus,
838 {NULL, NULL} /* sentinel */
839};
840
841static object *
842text_getattr(tp, name)
843 textobject *tp;
844 char *name;
845{
846 if (tp->t_attr != NULL) {
847 object *v = dictlookup(tp->t_attr, name);
848 if (v != NULL) {
849 INCREF(v);
850 return v;
851 }
852 }
853 return findmethod(text_methods, (object *)tp, name);
854}
855
856static int
857text_setattr(tp, name, v)
858 textobject *tp;
859 char *name;
860 object *v;
861{
862 if (tp->t_attr == NULL) {
863 tp->t_attr = newdictobject();
864 if (tp->t_attr == NULL)
865 return -1;
866 }
867 if (v == NULL)
868 return dictremove(tp->t_attr, name);
869 else
870 return dictinsert(tp->t_attr, name, v);
871}
872
873static typeobject Texttype = {
874 OB_HEAD_INIT(&Typetype)
875 0, /*ob_size*/
876 "textedit", /*tp_name*/
877 sizeof(textobject), /*tp_size*/
878 0, /*tp_itemsize*/
879 /* methods */
880 text_dealloc, /*tp_dealloc*/
881 0, /*tp_print*/
882 text_getattr, /*tp_getattr*/
883 text_setattr, /*tp_setattr*/
884 0, /*tp_compare*/
885 0, /*tp_repr*/
886};
887
888
889/* Menu objects */
890
Guido van Rossum2d14e211991-02-19 12:26:49 +0000891#define IDOFFSET 10 /* Menu IDs we use start here */
892#define MAXNMENU 20 /* Max #menus we allow */
893static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000894
895static menuobject *
896newmenuobject(title)
897 object *title;
898{
899 int id;
900 MENU *menu;
901 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +0000902 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000903 if (menulist[id] == NULL)
904 break;
905 }
906 if (id >= MAXNMENU)
907 return (menuobject *) err_nomem();
Guido van Rossum2d14e211991-02-19 12:26:49 +0000908 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000909 if (menu == NULL)
910 return (menuobject *) err_nomem();
911 mp = NEWOBJ(menuobject, &Menutype);
912 if (mp != NULL) {
913 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +0000914 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 mp->m_attr = NULL;
916 menulist[id] = mp;
917 }
918 else
919 wmenudelete(menu);
920 return mp;
921}
922
923/* Menu methods */
924
925static void
926menu_dealloc(mp)
927 menuobject *mp;
928{
929
Guido van Rossum2d14e211991-02-19 12:26:49 +0000930 int id = mp->m_id - IDOFFSET;
931 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932 menulist[id] = NULL;
933 }
934 wmenudelete(mp->m_menu);
935 if (mp->m_attr != NULL)
936 DECREF(mp->m_attr);
937 DEL(mp);
938}
939
940static object *
941menu_additem(self, args)
942 menuobject *self;
943 object *args;
944{
945 object *text;
946 int shortcut;
947 if (is_tupleobject(args)) {
948 object *v;
949 if (!getstrstrarg(args, &text, &v))
950 return NULL;
951 if (getstringsize(v) != 1) {
952 err_badarg();
953 return NULL;
954 }
955 shortcut = *getstringvalue(v) & 0xff;
956 }
957 else {
958 if (!getstrarg(args, &text))
959 return NULL;
960 shortcut = -1;
961 }
962 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
963 INCREF(None);
964 return None;
965}
966
967static object *
968menu_setitem(self, args)
969 menuobject *self;
970 object *args;
971{
972 int index;
973 object *text;
974 if (!getintstrarg(args, &index, &text))
975 return NULL;
976 wmenusetitem(self->m_menu, index, getstringvalue(text));
977 INCREF(None);
978 return None;
979}
980
981static object *
982menu_enable(self, args)
983 menuobject *self;
984 object *args;
985{
986 int index;
987 int flag;
988 if (!getintintarg(args, &index, &flag))
989 return NULL;
990 wmenuenable(self->m_menu, index, flag);
991 INCREF(None);
992 return None;
993}
994
995static object *
996menu_check(self, args)
997 menuobject *self;
998 object *args;
999{
1000 int index;
1001 int flag;
1002 if (!getintintarg(args, &index, &flag))
1003 return NULL;
1004 wmenucheck(self->m_menu, index, flag);
1005 INCREF(None);
1006 return None;
1007}
1008
1009static struct methodlist menu_methods[] = {
1010 "additem", menu_additem,
1011 "setitem", menu_setitem,
1012 "enable", menu_enable,
1013 "check", menu_check,
1014 {NULL, NULL} /* sentinel */
1015};
1016
1017static object *
1018menu_getattr(mp, name)
1019 menuobject *mp;
1020 char *name;
1021{
1022 if (mp->m_attr != NULL) {
1023 object *v = dictlookup(mp->m_attr, name);
1024 if (v != NULL) {
1025 INCREF(v);
1026 return v;
1027 }
1028 }
1029 return findmethod(menu_methods, (object *)mp, name);
1030}
1031
1032static int
1033menu_setattr(mp, name, v)
1034 menuobject *mp;
1035 char *name;
1036 object *v;
1037{
1038 if (mp->m_attr == NULL) {
1039 mp->m_attr = newdictobject();
1040 if (mp->m_attr == NULL)
1041 return -1;
1042 }
1043 if (v == NULL)
1044 return dictremove(mp->m_attr, name);
1045 else
1046 return dictinsert(mp->m_attr, name, v);
1047}
1048
1049static typeobject Menutype = {
1050 OB_HEAD_INIT(&Typetype)
1051 0, /*ob_size*/
1052 "menu", /*tp_name*/
1053 sizeof(menuobject), /*tp_size*/
1054 0, /*tp_itemsize*/
1055 /* methods */
1056 menu_dealloc, /*tp_dealloc*/
1057 0, /*tp_print*/
1058 menu_getattr, /*tp_getattr*/
1059 menu_setattr, /*tp_setattr*/
1060 0, /*tp_compare*/
1061 0, /*tp_repr*/
1062};
1063
1064
1065/* Windows */
1066
1067#define MAXNWIN 50
1068static windowobject *windowlist[MAXNWIN];
1069
1070/* Window methods */
1071
1072static void
1073window_dealloc(wp)
1074 windowobject *wp;
1075{
1076 if (wp->w_win != NULL) {
1077 int tag = wgettag(wp->w_win);
1078 if (tag >= 0 && tag < MAXNWIN)
1079 windowlist[tag] = NULL;
1080 else
1081 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1082 tag);
1083 wclose(wp->w_win);
1084 }
1085 DECREF(wp->w_title);
1086 if (wp->w_attr != NULL)
1087 DECREF(wp->w_attr);
1088 free((char *)wp);
1089}
1090
1091static void
1092window_print(wp, fp, flags)
1093 windowobject *wp;
1094 FILE *fp;
1095 int flags;
1096{
1097 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1098}
1099
1100static object *
1101window_begindrawing(wp, args)
1102 windowobject *wp;
1103 object *args;
1104{
1105 drawingobject *dp;
1106 if (!getnoarg(args))
1107 return NULL;
1108 if (Drawing != NULL) {
1109 err_setstr(RuntimeError, "already drawing");
1110 return NULL;
1111 }
1112 dp = NEWOBJ(drawingobject, &Drawingtype);
1113 if (dp == NULL)
1114 return NULL;
1115 Drawing = dp;
1116 INCREF(wp);
1117 dp->d_ref = wp;
1118 wbegindrawing(wp->w_win);
1119 return (object *)dp;
1120}
1121
1122static object *
1123window_change(wp, args)
1124 windowobject *wp;
1125 object *args;
1126{
1127 int a[4];
1128 if (!getrectarg(args, a))
1129 return NULL;
1130 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1131 INCREF(None);
1132 return None;
1133}
1134
1135static object *
1136window_gettitle(wp, args)
1137 windowobject *wp;
1138 object *args;
1139{
1140 if (!getnoarg(args))
1141 return NULL;
1142 INCREF(wp->w_title);
1143 return wp->w_title;
1144}
1145
1146static object *
1147window_getwinsize(wp, args)
1148 windowobject *wp;
1149 object *args;
1150{
1151 int width, height;
1152 if (!getnoarg(args))
1153 return NULL;
1154 wgetwinsize(wp->w_win, &width, &height);
1155 return makepoint(width, height);
1156}
1157
1158static object *
1159window_getdocsize(wp, args)
1160 windowobject *wp;
1161 object *args;
1162{
1163 int width, height;
1164 if (!getnoarg(args))
1165 return NULL;
1166 wgetdocsize(wp->w_win, &width, &height);
1167 return makepoint(width, height);
1168}
1169
1170static object *
1171window_getorigin(wp, args)
1172 windowobject *wp;
1173 object *args;
1174{
1175 int width, height;
1176 if (!getnoarg(args))
1177 return NULL;
1178 wgetorigin(wp->w_win, &width, &height);
1179 return makepoint(width, height);
1180}
1181
1182static object *
1183window_scroll(wp, args)
1184 windowobject *wp;
1185 object *args;
1186{
1187 int a[6];
1188 if (!getrectpointarg(args, a))
1189 return NULL;
1190 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1191 INCREF(None);
1192 return None;
1193}
1194
1195static object *
1196window_setdocsize(wp, args)
1197 windowobject *wp;
1198 object *args;
1199{
1200 int a[2];
1201 if (!getpointarg(args, a))
1202 return NULL;
1203 wsetdocsize(wp->w_win, a[0], a[1]);
1204 INCREF(None);
1205 return None;
1206}
1207
1208static object *
1209window_setorigin(wp, args)
1210 windowobject *wp;
1211 object *args;
1212{
1213 int a[2];
1214 if (!getpointarg(args, a))
1215 return NULL;
1216 wsetorigin(wp->w_win, a[0], a[1]);
1217 INCREF(None);
1218 return None;
1219}
1220
1221static object *
1222window_settitle(wp, args)
1223 windowobject *wp;
1224 object *args;
1225{
1226 object *title;
1227 if (!getstrarg(args, &title))
1228 return NULL;
1229 DECREF(wp->w_title);
1230 INCREF(title);
1231 wp->w_title = title;
1232 wsettitle(wp->w_win, getstringvalue(title));
1233 INCREF(None);
1234 return None;
1235}
1236
1237static object *
1238window_show(wp, args)
1239 windowobject *wp;
1240 object *args;
1241{
1242 int a[4];
1243 if (!getrectarg(args, a))
1244 return NULL;
1245 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1246 INCREF(None);
1247 return None;
1248}
1249
1250static object *
1251window_settimer(wp, args)
1252 windowobject *wp;
1253 object *args;
1254{
1255 int a;
1256 if (!getintarg(args, &a))
1257 return NULL;
1258 wsettimer(wp->w_win, a);
1259 INCREF(None);
1260 return None;
1261}
1262
1263static object *
1264window_menucreate(self, args)
1265 windowobject *self;
1266 object *args;
1267{
1268 menuobject *mp;
1269 object *title;
1270 if (!getstrarg(args, &title))
1271 return NULL;
1272 wmenusetdeflocal(1);
1273 mp = newmenuobject(title);
1274 if (mp == NULL)
1275 return NULL;
1276 wmenuattach(self->w_win, mp->m_menu);
1277 return (object *)mp;
1278}
1279
1280static object *
1281window_textcreate(self, args)
1282 windowobject *self;
1283 object *args;
1284{
1285 textobject *tp;
1286 int a[4];
1287 if (!getrectarg(args, a))
1288 return NULL;
1289 return (object *)
1290 newtextobject(self, a[0], a[1], a[2], a[3]);
1291}
1292
Guido van Rossum5b10f451990-10-30 16:01:48 +00001293static object *
1294window_setselection(self, args)
1295 windowobject *self;
1296 object *args;
1297{
1298 int sel;
1299 object *str;
1300 int ok;
1301 if (!getintstrarg(args, &sel, &str))
1302 return NULL;
1303 ok = wsetselection(self->w_win, sel,
1304 getstringvalue(str), (int)getstringsize(str));
1305 return newintobject(ok);
1306}
1307
1308static object *
1309window_setwincursor(self, args)
1310 windowobject *self;
1311 object *args;
1312{
1313 object *str;
1314 CURSOR *c;
1315 if (!getstrarg(args, &str))
1316 return NULL;
1317 c = wfetchcursor(getstringvalue(str));
1318 if (c == NULL) {
1319 err_setstr(RuntimeError, "no such cursor");
1320 return NULL;
1321 }
1322 wsetwincursor(self->w_win, c);
1323 INCREF(None);
1324 return None;
1325}
1326
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001327static object *
1328window_setfont(self, args)
1329 windowobject *self;
1330 object *args;
1331{
Guido van Rossumdb46c0e1991-04-04 17:26:32 +00001332 object *v;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001333 TEXTATTR saveattr, winattr;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001334 wgettextattr(&saveattr);
1335 wgetwintextattr(self->w_win, &winattr);
1336 wsettextattr(&winattr);
Guido van Rossumdb46c0e1991-04-04 17:26:32 +00001337 v = drawing_setfont((drawingobject *)NULL, args);
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001338 wgettextattr(&winattr);
1339 wsetwintextattr(self->w_win, &winattr);
1340 wsettextattr(&saveattr);
Guido van Rossumdb46c0e1991-04-04 17:26:32 +00001341 return v;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001342}
1343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344static struct methodlist window_methods[] = {
1345 {"begindrawing",window_begindrawing},
1346 {"change", window_change},
1347 {"getdocsize", window_getdocsize},
1348 {"getorigin", window_getorigin},
1349 {"gettitle", window_gettitle},
1350 {"getwinsize", window_getwinsize},
1351 {"menucreate", window_menucreate},
1352 {"scroll", window_scroll},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001353 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354 {"setdocsize", window_setdocsize},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001355 {"setfont", window_setfont},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001357 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358 {"settimer", window_settimer},
1359 {"settitle", window_settitle},
1360 {"show", window_show},
1361 {"textcreate", window_textcreate},
1362 {NULL, NULL} /* sentinel */
1363};
1364
1365static object *
1366window_getattr(wp, name)
1367 windowobject *wp;
1368 char *name;
1369{
1370 if (wp->w_attr != NULL) {
1371 object *v = dictlookup(wp->w_attr, name);
1372 if (v != NULL) {
1373 INCREF(v);
1374 return v;
1375 }
1376 }
1377 return findmethod(window_methods, (object *)wp, name);
1378}
1379
1380static int
1381window_setattr(wp, name, v)
1382 windowobject *wp;
1383 char *name;
1384 object *v;
1385{
1386 if (wp->w_attr == NULL) {
1387 wp->w_attr = newdictobject();
1388 if (wp->w_attr == NULL)
1389 return -1;
1390 }
1391 if (v == NULL)
1392 return dictremove(wp->w_attr, name);
1393 else
1394 return dictinsert(wp->w_attr, name, v);
1395}
1396
1397static typeobject Windowtype = {
1398 OB_HEAD_INIT(&Typetype)
1399 0, /*ob_size*/
1400 "window", /*tp_name*/
1401 sizeof(windowobject), /*tp_size*/
1402 0, /*tp_itemsize*/
1403 /* methods */
1404 window_dealloc, /*tp_dealloc*/
1405 window_print, /*tp_print*/
1406 window_getattr, /*tp_getattr*/
1407 window_setattr, /*tp_setattr*/
1408 0, /*tp_compare*/
1409 0, /*tp_repr*/
1410};
1411
1412/* Stdwin methods */
1413
1414static object *
1415stdwin_open(sw, args)
1416 object *sw;
1417 object *args;
1418{
1419 int tag;
1420 object *title;
1421 windowobject *wp;
1422 if (!getstrarg(args, &title))
1423 return NULL;
1424 for (tag = 0; tag < MAXNWIN; tag++) {
1425 if (windowlist[tag] == NULL)
1426 break;
1427 }
1428 if (tag >= MAXNWIN)
1429 return err_nomem();
1430 wp = NEWOBJ(windowobject, &Windowtype);
1431 if (wp == NULL)
1432 return NULL;
1433 INCREF(title);
1434 wp->w_title = title;
1435 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1436 wp->w_attr = NULL;
1437 if (wp->w_win == NULL) {
1438 DECREF(wp);
1439 return NULL;
1440 }
1441 windowlist[tag] = wp;
1442 wsettag(wp->w_win, tag);
1443 return (object *)wp;
1444}
1445
1446static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001447stdwin_get_poll_event(poll, args)
1448 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449 object *args;
1450{
1451 EVENT e;
1452 object *v, *w;
1453 if (!getnoarg(args))
1454 return NULL;
1455 if (Drawing != NULL) {
1456 err_setstr(RuntimeError, "cannot getevent() while drawing");
1457 return NULL;
1458 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001459/* again: */
1460 if (poll) {
1461 if (!wpollevent(&e)) {
1462 INCREF(None);
1463 return None;
1464 }
1465 }
1466 else
1467 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1469 /* Turn keyboard interrupts into exceptions */
1470 err_set(KeyboardInterrupt);
1471 return NULL;
1472 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001473/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001474 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1475 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001476*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001477 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1478 /* Turn WC_CLOSE commands into WE_CLOSE events */
1479 e.type = WE_CLOSE;
1480 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001481 v = newtupleobject(3);
1482 if (v == NULL)
1483 return NULL;
1484 if ((w = newintobject((long)e.type)) == NULL) {
1485 DECREF(v);
1486 return NULL;
1487 }
1488 settupleitem(v, 0, w);
1489 if (e.window == NULL)
1490 w = None;
1491 else {
1492 int tag = wgettag(e.window);
1493 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1494 w = None;
1495 else
1496 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001497#ifdef sgi
1498 /* XXX Trap for unexplained weird bug */
1499 if ((long)w == (long)0x80000001) {
1500 err_setstr(SystemError,
1501 "bad pointer in stdwin.getevent()");
1502 return NULL;
1503 }
1504#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001505 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001506 INCREF(w);
1507 settupleitem(v, 1, w);
1508 switch (e.type) {
1509 case WE_CHAR:
1510 {
1511 char c[1];
1512 c[0] = e.u.character;
1513 w = newsizedstringobject(c, 1);
1514 }
1515 break;
1516 case WE_COMMAND:
1517 w = newintobject((long)e.u.command);
1518 break;
1519 case WE_DRAW:
1520 w = makerect(e.u.area.left, e.u.area.top,
1521 e.u.area.right, e.u.area.bottom);
1522 break;
1523 case WE_MOUSE_DOWN:
1524 case WE_MOUSE_MOVE:
1525 case WE_MOUSE_UP:
1526 w = makemouse(e.u.where.h, e.u.where.v,
1527 e.u.where.clicks,
1528 e.u.where.button,
1529 e.u.where.mask);
1530 break;
1531 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001532 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1533 menulist[e.u.m.id - IDOFFSET] != NULL)
1534 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001535 else
1536 w = None;
1537 w = makemenu(w, e.u.m.item);
1538 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001539 case WE_LOST_SEL:
1540 w = newintobject((long)e.u.sel);
1541 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001542 default:
1543 w = None;
1544 INCREF(w);
1545 break;
1546 }
1547 if (w == NULL) {
1548 DECREF(v);
1549 return NULL;
1550 }
1551 settupleitem(v, 2, w);
1552 return v;
1553}
1554
1555static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001556stdwin_getevent(sw, args)
1557 object *sw;
1558 object *args;
1559{
1560 return stdwin_get_poll_event(0, args);
1561}
1562
1563static object *
1564stdwin_pollevent(sw, args)
1565 object *sw;
1566 object *args;
1567{
1568 return stdwin_get_poll_event(1, args);
1569}
1570
1571static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001572stdwin_setdefwinpos(sw, args)
1573 object *sw;
1574 object *args;
1575{
1576 int a[2];
1577 if (!getpointarg(args, a))
1578 return NULL;
1579 wsetdefwinpos(a[0], a[1]);
1580 INCREF(None);
1581 return None;
1582}
1583
1584static object *
1585stdwin_setdefwinsize(sw, args)
1586 object *sw;
1587 object *args;
1588{
1589 int a[2];
1590 if (!getpointarg(args, a))
1591 return NULL;
1592 wsetdefwinsize(a[0], a[1]);
1593 INCREF(None);
1594 return None;
1595}
1596
1597static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001598stdwin_setdefscrollbars(sw, args)
1599 object *sw;
1600 object *args;
1601{
1602 int a[2];
1603 if (!getpointarg(args, a))
1604 return NULL;
1605 wsetdefscrollbars(a[0], a[1]);
1606 INCREF(None);
1607 return None;
1608}
1609
1610static object *
Guido van Rossum33f17701991-02-13 23:19:39 +00001611stdwin_getdefwinpos(wp, args)
1612 windowobject *wp;
1613 object *args;
1614{
1615 int h, v;
1616 if (!getnoarg(args))
1617 return NULL;
1618 wgetdefwinpos(&h, &v);
1619 return makepoint(h, v);
1620}
1621
1622static object *
1623stdwin_getdefwinsize(wp, args)
1624 windowobject *wp;
1625 object *args;
1626{
1627 int width, height;
1628 if (!getnoarg(args))
1629 return NULL;
1630 wgetdefwinsize(&width, &height);
1631 return makepoint(width, height);
1632}
1633
1634static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001635stdwin_getdefscrollbars(wp, args)
1636 windowobject *wp;
1637 object *args;
1638{
1639 int h, v;
1640 if (!getnoarg(args))
1641 return NULL;
1642 wgetdefscrollbars(&h, &v);
1643 return makepoint(h, v);
1644}
1645
1646static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647stdwin_menucreate(self, args)
1648 object *self;
1649 object *args;
1650{
1651 object *title;
1652 if (!getstrarg(args, &title))
1653 return NULL;
1654 wmenusetdeflocal(0);
1655 return (object *)newmenuobject(title);
1656}
1657
1658static object *
1659stdwin_askfile(self, args)
1660 object *self;
1661 object *args;
1662{
1663 object *prompt, *dflt;
1664 int new, ret;
1665 char buf[256];
1666 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1667 return NULL;
1668 strncpy(buf, getstringvalue(dflt), sizeof buf);
1669 buf[sizeof buf - 1] = '\0';
1670 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1671 if (!ret) {
1672 err_set(KeyboardInterrupt);
1673 return NULL;
1674 }
1675 return newstringobject(buf);
1676}
1677
1678static object *
1679stdwin_askync(self, args)
1680 object *self;
1681 object *args;
1682{
1683 object *prompt;
1684 int new, ret;
1685 if (!getstrintarg(args, &prompt, &new))
1686 return NULL;
1687 ret = waskync(getstringvalue(prompt), new);
1688 if (ret < 0) {
1689 err_set(KeyboardInterrupt);
1690 return NULL;
1691 }
1692 return newintobject((long)ret);
1693}
1694
1695static object *
1696stdwin_askstr(self, args)
1697 object *self;
1698 object *args;
1699{
1700 object *prompt, *dflt;
1701 int ret;
1702 char buf[256];
1703 if (!getstrstrarg(args, &prompt, &dflt))
1704 return NULL;
1705 strncpy(buf, getstringvalue(dflt), sizeof buf);
1706 buf[sizeof buf - 1] = '\0';
1707 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1708 if (!ret) {
1709 err_set(KeyboardInterrupt);
1710 return NULL;
1711 }
1712 return newstringobject(buf);
1713}
1714
1715static object *
1716stdwin_message(self, args)
1717 object *self;
1718 object *args;
1719{
1720 object *msg;
1721 if (!getstrarg(args, &msg))
1722 return NULL;
1723 wmessage(getstringvalue(msg));
1724 INCREF(None);
1725 return None;
1726}
1727
1728static object *
1729stdwin_fleep(self, args)
1730 object *self;
1731 object *args;
1732{
1733 if (!getnoarg(args))
1734 return NULL;
1735 wfleep();
1736 INCREF(None);
1737 return None;
1738}
1739
1740static object *
1741stdwin_setcutbuffer(self, args)
1742 object *self;
1743 object *args;
1744{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001745 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001746 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001747 if (!getintstrarg(args, &i, &str))
1748 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001749 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001750 INCREF(None);
1751 return None;
1752}
1753
1754static object *
1755stdwin_getcutbuffer(self, args)
1756 object *self;
1757 object *args;
1758{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001759 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001760 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001761 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001762 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001764 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001765 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001766 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001767 len = 0;
1768 }
1769 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001770}
1771
Guido van Rossum5b10f451990-10-30 16:01:48 +00001772static object *
1773stdwin_rotatecutbuffers(self, args)
1774 object *self;
1775 object *args;
1776{
1777 int i;
1778 if (!getintarg(args, &i))
1779 return NULL;
1780 wrotatecutbuffers(i);
1781 INCREF(None);
1782 return None;
1783}
1784
1785static object *
1786stdwin_getselection(self, args)
1787 object *self;
1788 object *args;
1789{
1790 int sel;
1791 char *data;
1792 int len;
1793 if (!getintarg(args, &sel))
1794 return NULL;
1795 data = wgetselection(sel, &len);
1796 if (data == NULL) {
1797 data = "";
1798 len = 0;
1799 }
1800 return newsizedstringobject(data, len);
1801}
1802
1803static object *
1804stdwin_resetselection(self, args)
1805 object *self;
1806 object *args;
1807{
1808 int sel;
1809 if (!getintarg(args, &sel))
1810 return NULL;
1811 wresetselection(sel);
1812 INCREF(None);
1813 return None;
1814}
1815
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001816static object *
1817stdwin_fetchcolor(self, args)
1818 object *self;
1819 object *args;
1820{
1821 object *colorname;
1822 if (!getstrarg(args, &colorname))
1823 return NULL;
1824 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
1825}
1826
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001827static struct methodlist stdwin_methods[] = {
1828 {"askfile", stdwin_askfile},
1829 {"askstr", stdwin_askstr},
1830 {"askync", stdwin_askync},
1831 {"fleep", stdwin_fleep},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001832 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001834 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00001835 {"getdefwinpos", stdwin_getdefwinpos},
1836 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001837 {"getevent", stdwin_getevent},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001838 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001839 {"menucreate", stdwin_menucreate},
1840 {"message", stdwin_message},
1841 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001842 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001843 {"resetselection", stdwin_resetselection},
1844 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001846 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847 {"setdefwinpos", stdwin_setdefwinpos},
1848 {"setdefwinsize", stdwin_setdefwinsize},
1849
1850 /* Text measuring methods borrow code from drawing objects: */
1851 {"baseline", drawing_baseline},
1852 {"lineheight", drawing_lineheight},
1853 {"textbreak", drawing_textbreak},
1854 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001855
1856 /* Same for font setting methods: */
1857 {"setfont", drawing_setfont},
1858
1859 /* Same for color setting/getting methods: */
1860 {"getbgcolor", drawing_getbgcolor},
1861 {"getfgcolor", drawing_getfgcolor},
1862 {"setbgcolor", drawing_setbgcolor},
1863 {"setfgcolor", drawing_setfgcolor},
1864
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865 {NULL, NULL} /* sentinel */
1866};
1867
1868void
1869initstdwin()
1870{
Guido van Rossum2d14e211991-02-19 12:26:49 +00001871 static int inited;
1872 if (!inited) {
1873 winit();
1874 inited = 1;
1875 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001876 initmodule("stdwin", stdwin_methods);
1877}