blob: b55e58b2b9b134f485f972d55798a347c7e3d804 [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{
462 TEXTATTR saveattr, winattr;
463 object *str;
464 if (!getstrarg(args, &str))
465 return NULL;
466 wsetfont(getstringvalue(str));
467 INCREF(None);
468 return None;
469}
470
471static object *
472drawing_getbgcolor(self, args)
473 object *self;
474 object *args;
475{
476 if (!getnoarg(args))
477 return NULL;
478 return newintobject((long)wgetbgcolor());
479}
480
481static object *
482drawing_getfgcolor(self, args)
483 object *self;
484 object *args;
485{
486 if (!getnoarg(args))
487 return NULL;
488 return newintobject((long)wgetfgcolor());
489}
490
491static object *
492drawing_setbgcolor(self, args)
493 object *self;
494 object *args;
495{
496 long color;
497 if (!getlongarg(args, &color))
498 return NULL;
499 wsetbgcolor((COLOR)color);
500 INCREF(None);
501 return None;
502}
503
504static object *
505drawing_setfgcolor(self, args)
506 object *self;
507 object *args;
508{
509 long color;
510 if (!getlongarg(args, &color))
511 return NULL;
512 wsetfgcolor((COLOR)color);
513 INCREF(None);
514 return None;
515}
516
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517static struct methodlist drawing_methods[] = {
518 {"box", drawing_box},
519 {"circle", drawing_circle},
520 {"cliprect", drawing_cliprect},
521 {"elarc", drawing_elarc},
522 {"erase", drawing_erase},
523 {"invert", drawing_invert},
524 {"line", drawing_line},
525 {"noclip", drawing_noclip},
526 {"paint", drawing_paint},
527 {"shade", drawing_shade},
528 {"text", drawing_text},
529 {"xorline", drawing_xorline},
530
531 /* Text measuring methods: */
532 {"baseline", drawing_baseline},
533 {"lineheight", drawing_lineheight},
534 {"textbreak", drawing_textbreak},
535 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000536
537 /* Font setting methods: */
538 {"setfont", drawing_setfont},
539
540 /* Color methods: */
541 {"getbgcolor", drawing_getbgcolor},
542 {"getfgcolor", drawing_getfgcolor},
543 {"setbgcolor", drawing_setbgcolor},
544 {"setfgcolor", drawing_setfgcolor},
545
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000546 {NULL, NULL} /* sentinel */
547};
548
549static object *
550drawing_getattr(wp, name)
551 drawingobject *wp;
552 char *name;
553{
554 return findmethod(drawing_methods, (object *)wp, name);
555}
556
557static typeobject Drawingtype = {
558 OB_HEAD_INIT(&Typetype)
559 0, /*ob_size*/
560 "drawing", /*tp_name*/
561 sizeof(drawingobject), /*tp_size*/
562 0, /*tp_itemsize*/
563 /* methods */
564 drawing_dealloc, /*tp_dealloc*/
565 0, /*tp_print*/
566 drawing_getattr, /*tp_getattr*/
567 0, /*tp_setattr*/
568 0, /*tp_compare*/
569 0, /*tp_repr*/
570};
571
572
573/* Text(edit) objects */
574
575typedef struct {
576 OB_HEAD
577 TEXTEDIT *t_text;
578 windowobject *t_ref;
579 object *t_attr; /* Attributes dictionary */
580} textobject;
581
582extern typeobject Texttype; /* Really static, forward */
583
584static textobject *
585newtextobject(wp, left, top, right, bottom)
586 windowobject *wp;
587 int left, top, right, bottom;
588{
589 textobject *tp;
590 tp = NEWOBJ(textobject, &Texttype);
591 if (tp == NULL)
592 return NULL;
593 tp->t_attr = NULL;
594 INCREF(wp);
595 tp->t_ref = wp;
596 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
597 if (tp->t_text == NULL) {
598 DECREF(tp);
599 return (textobject *) err_nomem();
600 }
601 return tp;
602}
603
604/* Text(edit) methods */
605
606static void
607text_dealloc(tp)
608 textobject *tp;
609{
610 if (tp->t_text != NULL)
611 tefree(tp->t_text);
612 if (tp->t_attr != NULL)
613 DECREF(tp->t_attr);
614 DECREF(tp->t_ref);
615 DEL(tp);
616}
617
618static object *
619text_arrow(self, args)
620 textobject *self;
621 object *args;
622{
623 int code;
624 if (!getintarg(args, &code))
625 return NULL;
626 tearrow(self->t_text, code);
627 INCREF(None);
628 return None;
629}
630
631static object *
632text_draw(self, args)
633 textobject *self;
634 object *args;
635{
636 register TEXTEDIT *tp = self->t_text;
637 int a[4];
638 int left, top, right, bottom;
639 if (!getrectarg(args, a))
640 return NULL;
641 if (Drawing != NULL) {
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000642 err_setstr(RuntimeError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return NULL;
644 }
645 /* Clip to text area and ignore if area is empty */
646 left = tegetleft(tp);
647 top = tegettop(tp);
648 right = tegetright(tp);
649 bottom = tegetbottom(tp);
650 if (a[0] < left) a[0] = left;
651 if (a[1] < top) a[1] = top;
652 if (a[2] > right) a[2] = right;
653 if (a[3] > bottom) a[3] = bottom;
654 if (a[0] < a[2] && a[1] < a[3]) {
655 /* Hide/show focus around draw call; these are undocumented,
656 but required here to get the highlighting correct.
657 The call to werase is also required for this reason.
658 Finally, this forces us to require (above) that we are NOT
659 already drawing. */
660 tehidefocus(tp);
661 wbegindrawing(self->t_ref->w_win);
662 werase(a[0], a[1], a[2], a[3]);
663 tedrawnew(tp, a[0], a[1], a[2], a[3]);
664 wenddrawing(self->t_ref->w_win);
665 teshowfocus(tp);
666 }
667 INCREF(None);
668 return None;
669}
670
671static object *
672text_event(self, args)
673 textobject *self;
674 object *args;
675{
676 register TEXTEDIT *tp = self->t_text;
677 EVENT e;
678 if (!geteventarg(args, &e))
679 return NULL;
680 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000681 /* Cheat at the margins */
682 int width, height;
683 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000684 if (e.u.where.h < 0 && tegetleft(tp) == 0)
685 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000686 else if (e.u.where.h > width && tegetright(tp) == width)
687 e.u.where.h = width;
688 if (e.u.where.v < 0 && tegettop(tp) == 0)
689 e.u.where.v = 0;
690 else if (e.u.where.v > height && tegetright(tp) == height)
691 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000692 }
693 return newintobject((long) teevent(tp, &e));
694}
695
696static object *
697text_getfocus(self, args)
698 textobject *self;
699 object *args;
700{
701 if (!getnoarg(args))
702 return NULL;
703 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
704}
705
706static object *
707text_getfocustext(self, args)
708 textobject *self;
709 object *args;
710{
711 int f1, f2;
712 char *text;
713 if (!getnoarg(args))
714 return NULL;
715 f1 = tegetfoc1(self->t_text);
716 f2 = tegetfoc2(self->t_text);
717 text = tegettext(self->t_text);
718 return newsizedstringobject(text + f1, f2-f1);
719}
720
721static object *
722text_getrect(self, args)
723 textobject *self;
724 object *args;
725{
726 if (!getnoarg(args))
727 return NULL;
728 return makerect(tegetleft(self->t_text),
729 tegettop(self->t_text),
730 tegetright(self->t_text),
731 tegetbottom(self->t_text));
732}
733
734static object *
735text_gettext(self, args)
736 textobject *self;
737 object *args;
738{
739 if (!getnoarg(args))
740 return NULL;
741 return newsizedstringobject(tegettext(self->t_text),
742 tegetlen(self->t_text));
743}
744
745static object *
746text_move(self, args)
747 textobject *self;
748 object *args;
749{
750 int a[4];
751 if (!getrectarg(args, a))
752 return NULL;
753 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
754 INCREF(None);
755 return None;
756}
757
758static object *
759text_setfocus(self, args)
760 textobject *self;
761 object *args;
762{
763 int a[2];
764 if (!getpointarg(args, a))
765 return NULL;
766 tesetfocus(self->t_text, a[0], a[1]);
767 INCREF(None);
768 return None;
769}
770
771static object *
772text_replace(self, args)
773 textobject *self;
774 object *args;
775{
776 object *text;
777 if (!getstrarg(args, &text))
778 return NULL;
779 tereplace(self->t_text, getstringvalue(text));
780 INCREF(None);
781 return None;
782}
783
784static struct methodlist text_methods[] = {
785 "arrow", text_arrow,
786 "draw", text_draw,
787 "event", text_event,
788 "getfocus", text_getfocus,
789 "getfocustext", text_getfocustext,
790 "getrect", text_getrect,
791 "gettext", text_gettext,
792 "move", text_move,
793 "replace", text_replace,
794 "setfocus", text_setfocus,
795 {NULL, NULL} /* sentinel */
796};
797
798static object *
799text_getattr(tp, name)
800 textobject *tp;
801 char *name;
802{
803 if (tp->t_attr != NULL) {
804 object *v = dictlookup(tp->t_attr, name);
805 if (v != NULL) {
806 INCREF(v);
807 return v;
808 }
809 }
810 return findmethod(text_methods, (object *)tp, name);
811}
812
813static int
814text_setattr(tp, name, v)
815 textobject *tp;
816 char *name;
817 object *v;
818{
819 if (tp->t_attr == NULL) {
820 tp->t_attr = newdictobject();
821 if (tp->t_attr == NULL)
822 return -1;
823 }
824 if (v == NULL)
825 return dictremove(tp->t_attr, name);
826 else
827 return dictinsert(tp->t_attr, name, v);
828}
829
830static typeobject Texttype = {
831 OB_HEAD_INIT(&Typetype)
832 0, /*ob_size*/
833 "textedit", /*tp_name*/
834 sizeof(textobject), /*tp_size*/
835 0, /*tp_itemsize*/
836 /* methods */
837 text_dealloc, /*tp_dealloc*/
838 0, /*tp_print*/
839 text_getattr, /*tp_getattr*/
840 text_setattr, /*tp_setattr*/
841 0, /*tp_compare*/
842 0, /*tp_repr*/
843};
844
845
846/* Menu objects */
847
Guido van Rossum2d14e211991-02-19 12:26:49 +0000848#define IDOFFSET 10 /* Menu IDs we use start here */
849#define MAXNMENU 20 /* Max #menus we allow */
850static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000851
852static menuobject *
853newmenuobject(title)
854 object *title;
855{
856 int id;
857 MENU *menu;
858 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +0000859 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000860 if (menulist[id] == NULL)
861 break;
862 }
863 if (id >= MAXNMENU)
864 return (menuobject *) err_nomem();
Guido van Rossum2d14e211991-02-19 12:26:49 +0000865 menu = wmenucreate(id + IDOFFSET, getstringvalue(title));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000866 if (menu == NULL)
867 return (menuobject *) err_nomem();
868 mp = NEWOBJ(menuobject, &Menutype);
869 if (mp != NULL) {
870 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +0000871 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000872 mp->m_attr = NULL;
873 menulist[id] = mp;
874 }
875 else
876 wmenudelete(menu);
877 return mp;
878}
879
880/* Menu methods */
881
882static void
883menu_dealloc(mp)
884 menuobject *mp;
885{
886
Guido van Rossum2d14e211991-02-19 12:26:49 +0000887 int id = mp->m_id - IDOFFSET;
888 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889 menulist[id] = NULL;
890 }
891 wmenudelete(mp->m_menu);
892 if (mp->m_attr != NULL)
893 DECREF(mp->m_attr);
894 DEL(mp);
895}
896
897static object *
898menu_additem(self, args)
899 menuobject *self;
900 object *args;
901{
902 object *text;
903 int shortcut;
904 if (is_tupleobject(args)) {
905 object *v;
906 if (!getstrstrarg(args, &text, &v))
907 return NULL;
908 if (getstringsize(v) != 1) {
909 err_badarg();
910 return NULL;
911 }
912 shortcut = *getstringvalue(v) & 0xff;
913 }
914 else {
915 if (!getstrarg(args, &text))
916 return NULL;
917 shortcut = -1;
918 }
919 wmenuadditem(self->m_menu, getstringvalue(text), shortcut);
920 INCREF(None);
921 return None;
922}
923
924static object *
925menu_setitem(self, args)
926 menuobject *self;
927 object *args;
928{
929 int index;
930 object *text;
931 if (!getintstrarg(args, &index, &text))
932 return NULL;
933 wmenusetitem(self->m_menu, index, getstringvalue(text));
934 INCREF(None);
935 return None;
936}
937
938static object *
939menu_enable(self, args)
940 menuobject *self;
941 object *args;
942{
943 int index;
944 int flag;
945 if (!getintintarg(args, &index, &flag))
946 return NULL;
947 wmenuenable(self->m_menu, index, flag);
948 INCREF(None);
949 return None;
950}
951
952static object *
953menu_check(self, args)
954 menuobject *self;
955 object *args;
956{
957 int index;
958 int flag;
959 if (!getintintarg(args, &index, &flag))
960 return NULL;
961 wmenucheck(self->m_menu, index, flag);
962 INCREF(None);
963 return None;
964}
965
966static struct methodlist menu_methods[] = {
967 "additem", menu_additem,
968 "setitem", menu_setitem,
969 "enable", menu_enable,
970 "check", menu_check,
971 {NULL, NULL} /* sentinel */
972};
973
974static object *
975menu_getattr(mp, name)
976 menuobject *mp;
977 char *name;
978{
979 if (mp->m_attr != NULL) {
980 object *v = dictlookup(mp->m_attr, name);
981 if (v != NULL) {
982 INCREF(v);
983 return v;
984 }
985 }
986 return findmethod(menu_methods, (object *)mp, name);
987}
988
989static int
990menu_setattr(mp, name, v)
991 menuobject *mp;
992 char *name;
993 object *v;
994{
995 if (mp->m_attr == NULL) {
996 mp->m_attr = newdictobject();
997 if (mp->m_attr == NULL)
998 return -1;
999 }
1000 if (v == NULL)
1001 return dictremove(mp->m_attr, name);
1002 else
1003 return dictinsert(mp->m_attr, name, v);
1004}
1005
1006static typeobject Menutype = {
1007 OB_HEAD_INIT(&Typetype)
1008 0, /*ob_size*/
1009 "menu", /*tp_name*/
1010 sizeof(menuobject), /*tp_size*/
1011 0, /*tp_itemsize*/
1012 /* methods */
1013 menu_dealloc, /*tp_dealloc*/
1014 0, /*tp_print*/
1015 menu_getattr, /*tp_getattr*/
1016 menu_setattr, /*tp_setattr*/
1017 0, /*tp_compare*/
1018 0, /*tp_repr*/
1019};
1020
1021
1022/* Windows */
1023
1024#define MAXNWIN 50
1025static windowobject *windowlist[MAXNWIN];
1026
1027/* Window methods */
1028
1029static void
1030window_dealloc(wp)
1031 windowobject *wp;
1032{
1033 if (wp->w_win != NULL) {
1034 int tag = wgettag(wp->w_win);
1035 if (tag >= 0 && tag < MAXNWIN)
1036 windowlist[tag] = NULL;
1037 else
1038 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1039 tag);
1040 wclose(wp->w_win);
1041 }
1042 DECREF(wp->w_title);
1043 if (wp->w_attr != NULL)
1044 DECREF(wp->w_attr);
1045 free((char *)wp);
1046}
1047
1048static void
1049window_print(wp, fp, flags)
1050 windowobject *wp;
1051 FILE *fp;
1052 int flags;
1053{
1054 fprintf(fp, "<window titled '%s'>", getstringvalue(wp->w_title));
1055}
1056
1057static object *
1058window_begindrawing(wp, args)
1059 windowobject *wp;
1060 object *args;
1061{
1062 drawingobject *dp;
1063 if (!getnoarg(args))
1064 return NULL;
1065 if (Drawing != NULL) {
1066 err_setstr(RuntimeError, "already drawing");
1067 return NULL;
1068 }
1069 dp = NEWOBJ(drawingobject, &Drawingtype);
1070 if (dp == NULL)
1071 return NULL;
1072 Drawing = dp;
1073 INCREF(wp);
1074 dp->d_ref = wp;
1075 wbegindrawing(wp->w_win);
1076 return (object *)dp;
1077}
1078
1079static object *
1080window_change(wp, args)
1081 windowobject *wp;
1082 object *args;
1083{
1084 int a[4];
1085 if (!getrectarg(args, a))
1086 return NULL;
1087 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1088 INCREF(None);
1089 return None;
1090}
1091
1092static object *
1093window_gettitle(wp, args)
1094 windowobject *wp;
1095 object *args;
1096{
1097 if (!getnoarg(args))
1098 return NULL;
1099 INCREF(wp->w_title);
1100 return wp->w_title;
1101}
1102
1103static object *
1104window_getwinsize(wp, args)
1105 windowobject *wp;
1106 object *args;
1107{
1108 int width, height;
1109 if (!getnoarg(args))
1110 return NULL;
1111 wgetwinsize(wp->w_win, &width, &height);
1112 return makepoint(width, height);
1113}
1114
1115static object *
1116window_getdocsize(wp, args)
1117 windowobject *wp;
1118 object *args;
1119{
1120 int width, height;
1121 if (!getnoarg(args))
1122 return NULL;
1123 wgetdocsize(wp->w_win, &width, &height);
1124 return makepoint(width, height);
1125}
1126
1127static object *
1128window_getorigin(wp, args)
1129 windowobject *wp;
1130 object *args;
1131{
1132 int width, height;
1133 if (!getnoarg(args))
1134 return NULL;
1135 wgetorigin(wp->w_win, &width, &height);
1136 return makepoint(width, height);
1137}
1138
1139static object *
1140window_scroll(wp, args)
1141 windowobject *wp;
1142 object *args;
1143{
1144 int a[6];
1145 if (!getrectpointarg(args, a))
1146 return NULL;
1147 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1148 INCREF(None);
1149 return None;
1150}
1151
1152static object *
1153window_setdocsize(wp, args)
1154 windowobject *wp;
1155 object *args;
1156{
1157 int a[2];
1158 if (!getpointarg(args, a))
1159 return NULL;
1160 wsetdocsize(wp->w_win, a[0], a[1]);
1161 INCREF(None);
1162 return None;
1163}
1164
1165static object *
1166window_setorigin(wp, args)
1167 windowobject *wp;
1168 object *args;
1169{
1170 int a[2];
1171 if (!getpointarg(args, a))
1172 return NULL;
1173 wsetorigin(wp->w_win, a[0], a[1]);
1174 INCREF(None);
1175 return None;
1176}
1177
1178static object *
1179window_settitle(wp, args)
1180 windowobject *wp;
1181 object *args;
1182{
1183 object *title;
1184 if (!getstrarg(args, &title))
1185 return NULL;
1186 DECREF(wp->w_title);
1187 INCREF(title);
1188 wp->w_title = title;
1189 wsettitle(wp->w_win, getstringvalue(title));
1190 INCREF(None);
1191 return None;
1192}
1193
1194static object *
1195window_show(wp, args)
1196 windowobject *wp;
1197 object *args;
1198{
1199 int a[4];
1200 if (!getrectarg(args, a))
1201 return NULL;
1202 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1203 INCREF(None);
1204 return None;
1205}
1206
1207static object *
1208window_settimer(wp, args)
1209 windowobject *wp;
1210 object *args;
1211{
1212 int a;
1213 if (!getintarg(args, &a))
1214 return NULL;
1215 wsettimer(wp->w_win, a);
1216 INCREF(None);
1217 return None;
1218}
1219
1220static object *
1221window_menucreate(self, args)
1222 windowobject *self;
1223 object *args;
1224{
1225 menuobject *mp;
1226 object *title;
1227 if (!getstrarg(args, &title))
1228 return NULL;
1229 wmenusetdeflocal(1);
1230 mp = newmenuobject(title);
1231 if (mp == NULL)
1232 return NULL;
1233 wmenuattach(self->w_win, mp->m_menu);
1234 return (object *)mp;
1235}
1236
1237static object *
1238window_textcreate(self, args)
1239 windowobject *self;
1240 object *args;
1241{
1242 textobject *tp;
1243 int a[4];
1244 if (!getrectarg(args, a))
1245 return NULL;
1246 return (object *)
1247 newtextobject(self, a[0], a[1], a[2], a[3]);
1248}
1249
Guido van Rossum5b10f451990-10-30 16:01:48 +00001250static object *
1251window_setselection(self, args)
1252 windowobject *self;
1253 object *args;
1254{
1255 int sel;
1256 object *str;
1257 int ok;
1258 if (!getintstrarg(args, &sel, &str))
1259 return NULL;
1260 ok = wsetselection(self->w_win, sel,
1261 getstringvalue(str), (int)getstringsize(str));
1262 return newintobject(ok);
1263}
1264
1265static object *
1266window_setwincursor(self, args)
1267 windowobject *self;
1268 object *args;
1269{
1270 object *str;
1271 CURSOR *c;
1272 if (!getstrarg(args, &str))
1273 return NULL;
1274 c = wfetchcursor(getstringvalue(str));
1275 if (c == NULL) {
1276 err_setstr(RuntimeError, "no such cursor");
1277 return NULL;
1278 }
1279 wsetwincursor(self->w_win, c);
1280 INCREF(None);
1281 return None;
1282}
1283
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001284static object *
1285window_setfont(self, args)
1286 windowobject *self;
1287 object *args;
1288{
1289 TEXTATTR saveattr, winattr;
1290 object *str;
1291 if (!getstrarg(args, &str))
1292 return NULL;
1293 wgettextattr(&saveattr);
1294 wgetwintextattr(self->w_win, &winattr);
1295 wsettextattr(&winattr);
1296 wsetfont(getstringvalue(str));
1297 wgettextattr(&winattr);
1298 wsetwintextattr(self->w_win, &winattr);
1299 wsettextattr(&saveattr);
1300 INCREF(None);
1301 return None;
1302}
1303
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304static struct methodlist window_methods[] = {
1305 {"begindrawing",window_begindrawing},
1306 {"change", window_change},
1307 {"getdocsize", window_getdocsize},
1308 {"getorigin", window_getorigin},
1309 {"gettitle", window_gettitle},
1310 {"getwinsize", window_getwinsize},
1311 {"menucreate", window_menucreate},
1312 {"scroll", window_scroll},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001313 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314 {"setdocsize", window_setdocsize},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001315 {"setfont", window_setfont},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001316 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001317 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001318 {"settimer", window_settimer},
1319 {"settitle", window_settitle},
1320 {"show", window_show},
1321 {"textcreate", window_textcreate},
1322 {NULL, NULL} /* sentinel */
1323};
1324
1325static object *
1326window_getattr(wp, name)
1327 windowobject *wp;
1328 char *name;
1329{
1330 if (wp->w_attr != NULL) {
1331 object *v = dictlookup(wp->w_attr, name);
1332 if (v != NULL) {
1333 INCREF(v);
1334 return v;
1335 }
1336 }
1337 return findmethod(window_methods, (object *)wp, name);
1338}
1339
1340static int
1341window_setattr(wp, name, v)
1342 windowobject *wp;
1343 char *name;
1344 object *v;
1345{
1346 if (wp->w_attr == NULL) {
1347 wp->w_attr = newdictobject();
1348 if (wp->w_attr == NULL)
1349 return -1;
1350 }
1351 if (v == NULL)
1352 return dictremove(wp->w_attr, name);
1353 else
1354 return dictinsert(wp->w_attr, name, v);
1355}
1356
1357static typeobject Windowtype = {
1358 OB_HEAD_INIT(&Typetype)
1359 0, /*ob_size*/
1360 "window", /*tp_name*/
1361 sizeof(windowobject), /*tp_size*/
1362 0, /*tp_itemsize*/
1363 /* methods */
1364 window_dealloc, /*tp_dealloc*/
1365 window_print, /*tp_print*/
1366 window_getattr, /*tp_getattr*/
1367 window_setattr, /*tp_setattr*/
1368 0, /*tp_compare*/
1369 0, /*tp_repr*/
1370};
1371
1372/* Stdwin methods */
1373
1374static object *
1375stdwin_open(sw, args)
1376 object *sw;
1377 object *args;
1378{
1379 int tag;
1380 object *title;
1381 windowobject *wp;
1382 if (!getstrarg(args, &title))
1383 return NULL;
1384 for (tag = 0; tag < MAXNWIN; tag++) {
1385 if (windowlist[tag] == NULL)
1386 break;
1387 }
1388 if (tag >= MAXNWIN)
1389 return err_nomem();
1390 wp = NEWOBJ(windowobject, &Windowtype);
1391 if (wp == NULL)
1392 return NULL;
1393 INCREF(title);
1394 wp->w_title = title;
1395 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1396 wp->w_attr = NULL;
1397 if (wp->w_win == NULL) {
1398 DECREF(wp);
1399 return NULL;
1400 }
1401 windowlist[tag] = wp;
1402 wsettag(wp->w_win, tag);
1403 return (object *)wp;
1404}
1405
1406static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001407stdwin_get_poll_event(poll, args)
1408 int poll;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409 object *args;
1410{
1411 EVENT e;
1412 object *v, *w;
1413 if (!getnoarg(args))
1414 return NULL;
1415 if (Drawing != NULL) {
1416 err_setstr(RuntimeError, "cannot getevent() while drawing");
1417 return NULL;
1418 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001419/* again: */
1420 if (poll) {
1421 if (!wpollevent(&e)) {
1422 INCREF(None);
1423 return None;
1424 }
1425 }
1426 else
1427 wgetevent(&e);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001428 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1429 /* Turn keyboard interrupts into exceptions */
1430 err_set(KeyboardInterrupt);
1431 return NULL;
1432 }
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001433/*
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001434 if (e.window == NULL && (e.type == WE_COMMAND || e.type == WE_CHAR))
1435 goto again;
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001436*/
Guido van Rossum124967c1990-11-06 15:17:35 +00001437 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1438 /* Turn WC_CLOSE commands into WE_CLOSE events */
1439 e.type = WE_CLOSE;
1440 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001441 v = newtupleobject(3);
1442 if (v == NULL)
1443 return NULL;
1444 if ((w = newintobject((long)e.type)) == NULL) {
1445 DECREF(v);
1446 return NULL;
1447 }
1448 settupleitem(v, 0, w);
1449 if (e.window == NULL)
1450 w = None;
1451 else {
1452 int tag = wgettag(e.window);
1453 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL)
1454 w = None;
1455 else
1456 w = (object *)windowlist[tag];
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001457#ifdef sgi
1458 /* XXX Trap for unexplained weird bug */
1459 if ((long)w == (long)0x80000001) {
1460 err_setstr(SystemError,
1461 "bad pointer in stdwin.getevent()");
1462 return NULL;
1463 }
1464#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001465 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001466 INCREF(w);
1467 settupleitem(v, 1, w);
1468 switch (e.type) {
1469 case WE_CHAR:
1470 {
1471 char c[1];
1472 c[0] = e.u.character;
1473 w = newsizedstringobject(c, 1);
1474 }
1475 break;
1476 case WE_COMMAND:
1477 w = newintobject((long)e.u.command);
1478 break;
1479 case WE_DRAW:
1480 w = makerect(e.u.area.left, e.u.area.top,
1481 e.u.area.right, e.u.area.bottom);
1482 break;
1483 case WE_MOUSE_DOWN:
1484 case WE_MOUSE_MOVE:
1485 case WE_MOUSE_UP:
1486 w = makemouse(e.u.where.h, e.u.where.v,
1487 e.u.where.clicks,
1488 e.u.where.button,
1489 e.u.where.mask);
1490 break;
1491 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001492 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1493 menulist[e.u.m.id - IDOFFSET] != NULL)
1494 w = (object *)menulist[e.u.m.id - IDOFFSET];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001495 else
1496 w = None;
1497 w = makemenu(w, e.u.m.item);
1498 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001499 case WE_LOST_SEL:
1500 w = newintobject((long)e.u.sel);
1501 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502 default:
1503 w = None;
1504 INCREF(w);
1505 break;
1506 }
1507 if (w == NULL) {
1508 DECREF(v);
1509 return NULL;
1510 }
1511 settupleitem(v, 2, w);
1512 return v;
1513}
1514
1515static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001516stdwin_getevent(sw, args)
1517 object *sw;
1518 object *args;
1519{
1520 return stdwin_get_poll_event(0, args);
1521}
1522
1523static object *
1524stdwin_pollevent(sw, args)
1525 object *sw;
1526 object *args;
1527{
1528 return stdwin_get_poll_event(1, args);
1529}
1530
1531static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001532stdwin_setdefwinpos(sw, args)
1533 object *sw;
1534 object *args;
1535{
1536 int a[2];
1537 if (!getpointarg(args, a))
1538 return NULL;
1539 wsetdefwinpos(a[0], a[1]);
1540 INCREF(None);
1541 return None;
1542}
1543
1544static object *
1545stdwin_setdefwinsize(sw, args)
1546 object *sw;
1547 object *args;
1548{
1549 int a[2];
1550 if (!getpointarg(args, a))
1551 return NULL;
1552 wsetdefwinsize(a[0], a[1]);
1553 INCREF(None);
1554 return None;
1555}
1556
1557static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001558stdwin_setdefscrollbars(sw, args)
1559 object *sw;
1560 object *args;
1561{
1562 int a[2];
1563 if (!getpointarg(args, a))
1564 return NULL;
1565 wsetdefscrollbars(a[0], a[1]);
1566 INCREF(None);
1567 return None;
1568}
1569
1570static object *
Guido van Rossum33f17701991-02-13 23:19:39 +00001571stdwin_getdefwinpos(wp, args)
1572 windowobject *wp;
1573 object *args;
1574{
1575 int h, v;
1576 if (!getnoarg(args))
1577 return NULL;
1578 wgetdefwinpos(&h, &v);
1579 return makepoint(h, v);
1580}
1581
1582static object *
1583stdwin_getdefwinsize(wp, args)
1584 windowobject *wp;
1585 object *args;
1586{
1587 int width, height;
1588 if (!getnoarg(args))
1589 return NULL;
1590 wgetdefwinsize(&width, &height);
1591 return makepoint(width, height);
1592}
1593
1594static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001595stdwin_getdefscrollbars(wp, args)
1596 windowobject *wp;
1597 object *args;
1598{
1599 int h, v;
1600 if (!getnoarg(args))
1601 return NULL;
1602 wgetdefscrollbars(&h, &v);
1603 return makepoint(h, v);
1604}
1605
1606static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001607stdwin_menucreate(self, args)
1608 object *self;
1609 object *args;
1610{
1611 object *title;
1612 if (!getstrarg(args, &title))
1613 return NULL;
1614 wmenusetdeflocal(0);
1615 return (object *)newmenuobject(title);
1616}
1617
1618static object *
1619stdwin_askfile(self, args)
1620 object *self;
1621 object *args;
1622{
1623 object *prompt, *dflt;
1624 int new, ret;
1625 char buf[256];
1626 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1627 return NULL;
1628 strncpy(buf, getstringvalue(dflt), sizeof buf);
1629 buf[sizeof buf - 1] = '\0';
1630 ret = waskfile(getstringvalue(prompt), buf, sizeof buf, new);
1631 if (!ret) {
1632 err_set(KeyboardInterrupt);
1633 return NULL;
1634 }
1635 return newstringobject(buf);
1636}
1637
1638static object *
1639stdwin_askync(self, args)
1640 object *self;
1641 object *args;
1642{
1643 object *prompt;
1644 int new, ret;
1645 if (!getstrintarg(args, &prompt, &new))
1646 return NULL;
1647 ret = waskync(getstringvalue(prompt), new);
1648 if (ret < 0) {
1649 err_set(KeyboardInterrupt);
1650 return NULL;
1651 }
1652 return newintobject((long)ret);
1653}
1654
1655static object *
1656stdwin_askstr(self, args)
1657 object *self;
1658 object *args;
1659{
1660 object *prompt, *dflt;
1661 int ret;
1662 char buf[256];
1663 if (!getstrstrarg(args, &prompt, &dflt))
1664 return NULL;
1665 strncpy(buf, getstringvalue(dflt), sizeof buf);
1666 buf[sizeof buf - 1] = '\0';
1667 ret = waskstr(getstringvalue(prompt), buf, sizeof buf);
1668 if (!ret) {
1669 err_set(KeyboardInterrupt);
1670 return NULL;
1671 }
1672 return newstringobject(buf);
1673}
1674
1675static object *
1676stdwin_message(self, args)
1677 object *self;
1678 object *args;
1679{
1680 object *msg;
1681 if (!getstrarg(args, &msg))
1682 return NULL;
1683 wmessage(getstringvalue(msg));
1684 INCREF(None);
1685 return None;
1686}
1687
1688static object *
1689stdwin_fleep(self, args)
1690 object *self;
1691 object *args;
1692{
1693 if (!getnoarg(args))
1694 return NULL;
1695 wfleep();
1696 INCREF(None);
1697 return None;
1698}
1699
1700static object *
1701stdwin_setcutbuffer(self, args)
1702 object *self;
1703 object *args;
1704{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001705 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001706 object *str;
Guido van Rossum124967c1990-11-06 15:17:35 +00001707 if (!getintstrarg(args, &i, &str))
1708 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001709 wsetcutbuffer(i, getstringvalue(str), getstringsize(str));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001710 INCREF(None);
1711 return None;
1712}
1713
1714static object *
1715stdwin_getcutbuffer(self, args)
1716 object *self;
1717 object *args;
1718{
Guido van Rossum5b10f451990-10-30 16:01:48 +00001719 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001720 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00001721 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00001722 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001724 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00001725 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001726 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00001727 len = 0;
1728 }
1729 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001730}
1731
Guido van Rossum5b10f451990-10-30 16:01:48 +00001732static object *
1733stdwin_rotatecutbuffers(self, args)
1734 object *self;
1735 object *args;
1736{
1737 int i;
1738 if (!getintarg(args, &i))
1739 return NULL;
1740 wrotatecutbuffers(i);
1741 INCREF(None);
1742 return None;
1743}
1744
1745static object *
1746stdwin_getselection(self, args)
1747 object *self;
1748 object *args;
1749{
1750 int sel;
1751 char *data;
1752 int len;
1753 if (!getintarg(args, &sel))
1754 return NULL;
1755 data = wgetselection(sel, &len);
1756 if (data == NULL) {
1757 data = "";
1758 len = 0;
1759 }
1760 return newsizedstringobject(data, len);
1761}
1762
1763static object *
1764stdwin_resetselection(self, args)
1765 object *self;
1766 object *args;
1767{
1768 int sel;
1769 if (!getintarg(args, &sel))
1770 return NULL;
1771 wresetselection(sel);
1772 INCREF(None);
1773 return None;
1774}
1775
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001776static object *
1777stdwin_fetchcolor(self, args)
1778 object *self;
1779 object *args;
1780{
1781 object *colorname;
1782 if (!getstrarg(args, &colorname))
1783 return NULL;
1784 return newintobject((long)wfetchcolor(getstringvalue(colorname)));
1785}
1786
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001787static struct methodlist stdwin_methods[] = {
1788 {"askfile", stdwin_askfile},
1789 {"askstr", stdwin_askstr},
1790 {"askync", stdwin_askync},
1791 {"fleep", stdwin_fleep},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001792 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001793 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001794 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00001795 {"getdefwinpos", stdwin_getdefwinpos},
1796 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001797 {"getevent", stdwin_getevent},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001798 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001799 {"menucreate", stdwin_menucreate},
1800 {"message", stdwin_message},
1801 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001802 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001803 {"resetselection", stdwin_resetselection},
1804 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001805 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001806 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001807 {"setdefwinpos", stdwin_setdefwinpos},
1808 {"setdefwinsize", stdwin_setdefwinsize},
1809
1810 /* Text measuring methods borrow code from drawing objects: */
1811 {"baseline", drawing_baseline},
1812 {"lineheight", drawing_lineheight},
1813 {"textbreak", drawing_textbreak},
1814 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001815
1816 /* Same for font setting methods: */
1817 {"setfont", drawing_setfont},
1818
1819 /* Same for color setting/getting methods: */
1820 {"getbgcolor", drawing_getbgcolor},
1821 {"getfgcolor", drawing_getfgcolor},
1822 {"setbgcolor", drawing_setbgcolor},
1823 {"setfgcolor", drawing_setfgcolor},
1824
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825 {NULL, NULL} /* sentinel */
1826};
1827
1828void
1829initstdwin()
1830{
Guido van Rossum2d14e211991-02-19 12:26:49 +00001831 static int inited;
1832 if (!inited) {
1833 winit();
1834 inited = 1;
1835 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836 initmodule("stdwin", stdwin_methods);
1837}