blob: a33366d3d339eb62d4417bdc4e6cb499556470f4 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
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#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000067#include "ceval.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
Guido van Rossumff4949e1992-08-05 19:58:53 +000071#ifdef USE_THREAD
72
73#include "thread.h"
74
75static type_lock StdwinLock; /* Lock held when interpreter not locked */
76
77#define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
78#define RET_STDWIN release_lock(StdwinLock); RET_SAVE
79#define END_STDWIN release_lock(StdwinLock); END_SAVE
80
81#else
82
83#define BGN_STDWIN BGN_SAVE
84#define RET_STDWIN RET_SAVE
85#define END_STDWIN END_SAVE
86
87#endif
88
Guido van Rossumbbf94341991-12-16 15:44:53 +000089static object *StdwinError; /* Exception stdwin.error */
Guido van Rossum87e7ea71991-12-10 14:00:03 +000090
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091/* Window and menu object types declared here because of forward references */
92
93typedef struct {
94 OB_HEAD
95 object *w_title;
96 WINDOW *w_win;
97 object *w_attr; /* Attributes dictionary */
98} windowobject;
99
100extern typeobject Windowtype; /* Really static, forward */
101
102#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
103
104typedef struct {
105 OB_HEAD
106 MENU *m_menu;
107 int m_id;
108 object *m_attr; /* Attributes dictionary */
109} menuobject;
110
111extern typeobject Menutype; /* Really static, forward */
112
113#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
114
115
116/* Strongly stdwin-specific argument handlers */
117
118static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119getmenudetail(v, ep)
120 object *v;
121 EVENT *ep;
122{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000123 menuobject *mp;
124 if (!getargs(v, "(Oi)", &mp, &ep->u.m.item))
125 return 0;
126 if (!is_menuobject(mp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000128 ep->u.m.id = mp->m_id;
129 return 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130}
131
132static int
133geteventarg(v, ep)
134 object *v;
135 EVENT *ep;
136{
137 object *wp, *detail;
138 int a[4];
Guido van Rossumfc58e581992-01-27 16:45:55 +0000139 if (!getargs(v, "(iOO)", &ep->type, &wp, &detail))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 return 0;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000141 if (is_windowobject(wp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 ep->window = ((windowobject *)wp) -> w_win;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000143 else if (wp == None)
144 ep->window = NULL;
145 else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000147 switch (ep->type) {
148 case WE_CHAR: {
149 char c;
150 if (!getargs(detail, "c", &c))
151 return 0;
152 ep->u.character = c;
153 return 1;
154 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 case WE_COMMAND:
156 return getintarg(detail, &ep->u.command);
157 case WE_DRAW:
158 if (!getrectarg(detail, a))
159 return 0;
160 ep->u.area.left = a[0];
161 ep->u.area.top = a[1];
162 ep->u.area.right = a[2];
163 ep->u.area.bottom = a[3];
164 return 1;
165 case WE_MOUSE_DOWN:
166 case WE_MOUSE_UP:
167 case WE_MOUSE_MOVE:
Guido van Rossumfc58e581992-01-27 16:45:55 +0000168 return getargs(detail, "((ii)iii)",
169 &ep->u.where.h, &ep->u.where.v,
170 &ep->u.where.clicks,
171 &ep->u.where.button,
172 &ep->u.where.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 case WE_MENU:
174 return getmenudetail(detail, ep);
Guido van Rossum3ee199e1992-06-30 12:48:26 +0000175 case WE_KEY:
176 return getargs(detail, "(ii)",
177 &ep->u.key.code, &ep->u.key.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 default:
179 return 1;
180 }
181}
182
183
184/* Return construction tools */
185
186static object *
187makepoint(a, b)
188 int a, b;
189{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000190 return mkvalue("(ii)", a, b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191}
192
193static object *
194makerect(a, b, c, d)
195 int a, b, c, d;
196{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000197 return mkvalue("((ii)(ii))", a, b, c, d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198}
199
200
201/* Drawing objects */
202
203typedef struct {
204 OB_HEAD
205 windowobject *d_ref;
206} drawingobject;
207
208static drawingobject *Drawing; /* Set to current drawing object, or NULL */
209
210/* Drawing methods */
211
Guido van Rossum3c284741991-11-27 14:54:54 +0000212static object *
213drawing_close(dp)
214 drawingobject *dp;
215{
216 if (dp->d_ref != NULL) {
217 wenddrawing(dp->d_ref->w_win);
218 Drawing = NULL;
219 DECREF(dp->d_ref);
220 dp->d_ref = NULL;
221 }
222 INCREF(None);
223 return None;
224}
Guido van Rossum77b46041992-01-14 18:41:24 +0000225
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226static void
227drawing_dealloc(dp)
228 drawingobject *dp;
229{
Guido van Rossum3c284741991-11-27 14:54:54 +0000230 if (dp->d_ref != NULL) {
231 wenddrawing(dp->d_ref->w_win);
232 Drawing = NULL;
233 DECREF(dp->d_ref);
234 dp->d_ref = NULL;
235 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 free((char *)dp);
237}
238
239static object *
240drawing_generic(dp, args, func)
241 drawingobject *dp;
242 object *args;
243 void (*func) FPROTO((int, int, int, int));
244{
245 int a[4];
246 if (!getrectarg(args, a))
247 return NULL;
248 (*func)(a[0], a[1], a[2], a[3]);
249 INCREF(None);
250 return None;
251}
252
253static object *
254drawing_line(dp, args)
255 drawingobject *dp;
256 object *args;
257{
Guido van Rossumbf109731991-03-06 13:14:12 +0000258 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259}
260
261static object *
262drawing_xorline(dp, args)
263 drawingobject *dp;
264 object *args;
265{
Guido van Rossumbf109731991-03-06 13:14:12 +0000266 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267}
268
269static object *
270drawing_circle(dp, args)
271 drawingobject *dp;
272 object *args;
273{
274 int a[3];
275 if (!getpointintarg(args, a))
276 return NULL;
277 wdrawcircle(a[0], a[1], a[2]);
278 INCREF(None);
279 return None;
280}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000281
Guido van Rossum27201061991-04-16 08:43:03 +0000282static object *
283drawing_fillcircle(dp, args)
284 drawingobject *dp;
285 object *args;
286{
287 int a[3];
288 if (!getpointintarg(args, a))
289 return NULL;
290 wfillcircle(a[0], a[1], a[2]);
291 INCREF(None);
292 return None;
293}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294
295static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000296drawing_xorcircle(dp, args)
297 drawingobject *dp;
298 object *args;
299{
300 int a[3];
301 if (!getpointintarg(args, a))
302 return NULL;
303 wxorcircle(a[0], a[1], a[2]);
304 INCREF(None);
305 return None;
306}
307
308static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309drawing_elarc(dp, args)
310 drawingobject *dp;
311 object *args;
312{
313 int a[6];
314 if (!get3pointarg(args, a))
315 return NULL;
316 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
317 INCREF(None);
318 return None;
319}
320
321static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000322drawing_fillelarc(dp, args)
323 drawingobject *dp;
324 object *args;
325{
326 int a[6];
327 if (!get3pointarg(args, a))
328 return NULL;
329 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
330 INCREF(None);
331 return None;
332}
333
334static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000335drawing_xorelarc(dp, args)
336 drawingobject *dp;
337 object *args;
338{
339 int a[6];
340 if (!get3pointarg(args, a))
341 return NULL;
342 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
343 INCREF(None);
344 return None;
345}
346
347static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348drawing_box(dp, args)
349 drawingobject *dp;
350 object *args;
351{
Guido van Rossumbf109731991-03-06 13:14:12 +0000352 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353}
354
355static object *
356drawing_erase(dp, args)
357 drawingobject *dp;
358 object *args;
359{
Guido van Rossumbf109731991-03-06 13:14:12 +0000360 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361}
362
363static object *
364drawing_paint(dp, args)
365 drawingobject *dp;
366 object *args;
367{
Guido van Rossumbf109731991-03-06 13:14:12 +0000368 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369}
370
371static object *
372drawing_invert(dp, args)
373 drawingobject *dp;
374 object *args;
375{
Guido van Rossumbf109731991-03-06 13:14:12 +0000376 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377}
378
Guido van Rossum27201061991-04-16 08:43:03 +0000379static POINT *
380getpointsarray(v, psize)
381 object *v;
382 int *psize;
383{
384 int n = -1;
385 object * (*getitem) PROTO((object *, int));
386 int i;
387 POINT *points;
388
389 if (v == NULL)
390 ;
391 else if (is_listobject(v)) {
392 n = getlistsize(v);
393 getitem = getlistitem;
394 }
395 else if (is_tupleobject(v)) {
396 n = gettuplesize(v);
397 getitem = gettupleitem;
398 }
399
400 if (n <= 0) {
401 (void) err_badarg();
402 return NULL;
403 }
404
405 points = NEW(POINT, n);
406 if (points == NULL) {
407 (void) err_nomem();
408 return NULL;
409 }
410
411 for (i = 0; i < n; i++) {
412 object *w = (*getitem)(v, i);
413 int a[2];
414 if (!getpointarg(w, a)) {
415 DEL(points);
416 return NULL;
417 }
418 points[i].h = a[0];
419 points[i].v = a[1];
420 }
421
422 *psize = n;
423 return points;
424}
425
426static object *
427drawing_poly(dp, args)
428 drawingobject *dp;
429 object *args;
430{
431 int n;
432 POINT *points = getpointsarray(args, &n);
433 if (points == NULL)
434 return NULL;
435 wdrawpoly(n, points);
436 DEL(points);
437 INCREF(None);
438 return None;
439}
440
441static object *
442drawing_fillpoly(dp, args)
443 drawingobject *dp;
444 object *args;
445{
446 int n;
447 POINT *points = getpointsarray(args, &n);
448 if (points == NULL)
449 return NULL;
450 wfillpoly(n, points);
451 DEL(points);
452 INCREF(None);
453 return None;
454}
455
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000457drawing_xorpoly(dp, args)
458 drawingobject *dp;
459 object *args;
460{
461 int n;
462 POINT *points = getpointsarray(args, &n);
463 if (points == NULL)
464 return NULL;
465 wxorpoly(n, points);
466 DEL(points);
467 INCREF(None);
468 return None;
469}
470
471static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472drawing_cliprect(dp, args)
473 drawingobject *dp;
474 object *args;
475{
Guido van Rossumbf109731991-03-06 13:14:12 +0000476 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477}
478
479static object *
480drawing_noclip(dp, args)
481 drawingobject *dp;
482 object *args;
483{
484 if (!getnoarg(args))
485 return NULL;
486 wnoclip();
487 INCREF(None);
488 return None;
489}
490
491static object *
492drawing_shade(dp, args)
493 drawingobject *dp;
494 object *args;
495{
496 int a[5];
497 if (!getrectintarg(args, a))
498 return NULL;
499 wshade(a[0], a[1], a[2], a[3], a[4]);
500 INCREF(None);
501 return None;
502}
503
504static object *
505drawing_text(dp, args)
506 drawingobject *dp;
507 object *args;
508{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000509 int h, v, size;
510 char *text;
511 if (!getargs(args, "((ii)s#)", &h, &v, &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000512 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000513 wdrawtext(h, v, text, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 INCREF(None);
515 return None;
516}
517
518/* The following four are also used as stdwin functions */
519
520static object *
521drawing_lineheight(dp, args)
522 drawingobject *dp;
523 object *args;
524{
525 if (!getnoarg(args))
526 return NULL;
527 return newintobject((long)wlineheight());
528}
529
530static object *
531drawing_baseline(dp, args)
532 drawingobject *dp;
533 object *args;
534{
535 if (!getnoarg(args))
536 return NULL;
537 return newintobject((long)wbaseline());
538}
539
540static object *
541drawing_textwidth(dp, args)
542 drawingobject *dp;
543 object *args;
544{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000545 char *text;
546 int size;
547 if (!getargs(args, "s#", &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000549 return newintobject((long)wtextwidth(text, size));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550}
551
552static object *
553drawing_textbreak(dp, args)
554 drawingobject *dp;
555 object *args;
556{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000557 char *text;
558 int size, width;
559 if (!getargs(args, "(s#i)", &text, &size, &width))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000561 return newintobject((long)wtextbreak(text, size, width));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562}
563
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000564static object *
565drawing_setfont(self, args)
566 drawingobject *self;
567 object *args;
568{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000569 char *font;
570 char style = '\0';
571 int size = 0;
572 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +0000573 if (!getargs(args, "z", &font))
Guido van Rossum50429a11991-04-04 15:24:07 +0000574 return NULL;
575 }
576 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000577 int n = gettuplesize(args);
578 if (n == 2) {
579 if (!getargs(args, "(zi)", &font, &size))
580 return NULL;
581 }
582 else if (!getargs(args, "(zic)", &font, &size, &style)) {
583 err_clear();
584 if (!getargs(args, "(zci)", &font, &style, &size))
585 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000586 }
587 }
Guido van Rossumfc58e581992-01-27 16:45:55 +0000588 if (font != NULL)
589 wsetfont(font);
Guido van Rossum50429a11991-04-04 15:24:07 +0000590 if (size != 0)
591 wsetsize(size);
Guido van Rossumfc58e581992-01-27 16:45:55 +0000592 switch (style) {
593 case 'b':
594 wsetbold();
595 break;
596 case 'i':
597 wsetitalic();
598 break;
599 case 'o':
600 wsetbolditalic();
601 break;
602 case 'u':
603 wsetunderline();
604 break;
605 case 'p':
606 wsetplain();
607 break;
608 }
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000609 INCREF(None);
610 return None;
611}
612
613static object *
614drawing_getbgcolor(self, args)
615 object *self;
616 object *args;
617{
618 if (!getnoarg(args))
619 return NULL;
620 return newintobject((long)wgetbgcolor());
621}
622
623static object *
624drawing_getfgcolor(self, args)
625 object *self;
626 object *args;
627{
628 if (!getnoarg(args))
629 return NULL;
630 return newintobject((long)wgetfgcolor());
631}
632
633static object *
634drawing_setbgcolor(self, args)
635 object *self;
636 object *args;
637{
638 long color;
639 if (!getlongarg(args, &color))
640 return NULL;
641 wsetbgcolor((COLOR)color);
642 INCREF(None);
643 return None;
644}
645
646static object *
647drawing_setfgcolor(self, args)
648 object *self;
649 object *args;
650{
651 long color;
652 if (!getlongarg(args, &color))
653 return NULL;
654 wsetfgcolor((COLOR)color);
655 INCREF(None);
656 return None;
657}
658
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000659static struct methodlist drawing_methods[] = {
660 {"box", drawing_box},
661 {"circle", drawing_circle},
662 {"cliprect", drawing_cliprect},
Guido van Rossum3c284741991-11-27 14:54:54 +0000663 {"close", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 {"elarc", drawing_elarc},
Guido van Rossum3c284741991-11-27 14:54:54 +0000665 {"enddrawing", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000667 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000668 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000669 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670 {"invert", drawing_invert},
671 {"line", drawing_line},
672 {"noclip", drawing_noclip},
673 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000674 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675 {"shade", drawing_shade},
676 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000677 {"xorcircle", drawing_xorcircle},
678 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000680 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681
682 /* Text measuring methods: */
683 {"baseline", drawing_baseline},
684 {"lineheight", drawing_lineheight},
685 {"textbreak", drawing_textbreak},
686 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000687
688 /* Font setting methods: */
689 {"setfont", drawing_setfont},
690
691 /* Color methods: */
692 {"getbgcolor", drawing_getbgcolor},
693 {"getfgcolor", drawing_getfgcolor},
694 {"setbgcolor", drawing_setbgcolor},
695 {"setfgcolor", drawing_setfgcolor},
696
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697 {NULL, NULL} /* sentinel */
698};
699
700static object *
Guido van Rossum77b46041992-01-14 18:41:24 +0000701drawing_getattr(dp, name)
702 drawingobject *dp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703 char *name;
704{
Guido van Rossum77b46041992-01-14 18:41:24 +0000705 if (dp->d_ref == NULL) {
706 err_setstr(StdwinError, "drawing object already closed");
707 return NULL;
708 }
709 return findmethod(drawing_methods, (object *)dp, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710}
711
Guido van Rossum541c8c01991-05-05 20:13:41 +0000712typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713 OB_HEAD_INIT(&Typetype)
714 0, /*ob_size*/
715 "drawing", /*tp_name*/
716 sizeof(drawingobject), /*tp_size*/
717 0, /*tp_itemsize*/
718 /* methods */
719 drawing_dealloc, /*tp_dealloc*/
720 0, /*tp_print*/
721 drawing_getattr, /*tp_getattr*/
722 0, /*tp_setattr*/
723 0, /*tp_compare*/
724 0, /*tp_repr*/
725};
726
727
728/* Text(edit) objects */
729
730typedef struct {
731 OB_HEAD
732 TEXTEDIT *t_text;
733 windowobject *t_ref;
734 object *t_attr; /* Attributes dictionary */
735} textobject;
736
737extern typeobject Texttype; /* Really static, forward */
738
739static textobject *
740newtextobject(wp, left, top, right, bottom)
741 windowobject *wp;
742 int left, top, right, bottom;
743{
744 textobject *tp;
745 tp = NEWOBJ(textobject, &Texttype);
746 if (tp == NULL)
747 return NULL;
748 tp->t_attr = NULL;
749 INCREF(wp);
750 tp->t_ref = wp;
751 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
752 if (tp->t_text == NULL) {
753 DECREF(tp);
754 return (textobject *) err_nomem();
755 }
756 return tp;
757}
758
759/* Text(edit) methods */
760
761static void
762text_dealloc(tp)
763 textobject *tp;
764{
765 if (tp->t_text != NULL)
766 tefree(tp->t_text);
Guido van Rossum3c284741991-11-27 14:54:54 +0000767 XDECREF(tp->t_attr);
768 XDECREF(tp->t_ref);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769 DEL(tp);
770}
771
772static object *
Guido van Rossum3c284741991-11-27 14:54:54 +0000773text_close(tp, args)
774 textobject *tp;
775 object *args;
776{
777 if (tp->t_text != NULL) {
778 tefree(tp->t_text);
779 tp->t_text = NULL;
780 }
781 if (tp->t_attr != NULL) {
782 DECREF(tp->t_attr);
783 tp->t_attr = NULL;
784 }
785 if (tp->t_ref != NULL) {
786 DECREF(tp->t_ref);
787 tp->t_ref = NULL;
788 }
789 INCREF(None);
790 return None;
791}
792
793static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794text_arrow(self, args)
795 textobject *self;
796 object *args;
797{
798 int code;
799 if (!getintarg(args, &code))
800 return NULL;
801 tearrow(self->t_text, code);
802 INCREF(None);
803 return None;
804}
805
806static object *
807text_draw(self, args)
808 textobject *self;
809 object *args;
810{
811 register TEXTEDIT *tp = self->t_text;
812 int a[4];
813 int left, top, right, bottom;
814 if (!getrectarg(args, a))
815 return NULL;
816 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000817 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818 return NULL;
819 }
820 /* Clip to text area and ignore if area is empty */
821 left = tegetleft(tp);
822 top = tegettop(tp);
823 right = tegetright(tp);
824 bottom = tegetbottom(tp);
825 if (a[0] < left) a[0] = left;
826 if (a[1] < top) a[1] = top;
827 if (a[2] > right) a[2] = right;
828 if (a[3] > bottom) a[3] = bottom;
829 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831 tedrawnew(tp, a[0], a[1], a[2], a[3]);
832 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833 }
834 INCREF(None);
835 return None;
836}
837
838static object *
839text_event(self, args)
840 textobject *self;
841 object *args;
842{
843 register TEXTEDIT *tp = self->t_text;
844 EVENT e;
845 if (!geteventarg(args, &e))
846 return NULL;
847 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000848 /* Cheat at the margins */
849 int width, height;
850 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000851 if (e.u.where.h < 0 && tegetleft(tp) == 0)
852 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000853 else if (e.u.where.h > width && tegetright(tp) == width)
854 e.u.where.h = width;
855 if (e.u.where.v < 0 && tegettop(tp) == 0)
856 e.u.where.v = 0;
857 else if (e.u.where.v > height && tegetright(tp) == height)
858 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000859 }
860 return newintobject((long) teevent(tp, &e));
861}
862
863static object *
864text_getfocus(self, args)
865 textobject *self;
866 object *args;
867{
868 if (!getnoarg(args))
869 return NULL;
870 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
871}
872
873static object *
874text_getfocustext(self, args)
875 textobject *self;
876 object *args;
877{
878 int f1, f2;
879 char *text;
880 if (!getnoarg(args))
881 return NULL;
882 f1 = tegetfoc1(self->t_text);
883 f2 = tegetfoc2(self->t_text);
884 text = tegettext(self->t_text);
885 return newsizedstringobject(text + f1, f2-f1);
886}
887
888static object *
889text_getrect(self, args)
890 textobject *self;
891 object *args;
892{
893 if (!getnoarg(args))
894 return NULL;
895 return makerect(tegetleft(self->t_text),
896 tegettop(self->t_text),
897 tegetright(self->t_text),
898 tegetbottom(self->t_text));
899}
900
901static object *
902text_gettext(self, args)
903 textobject *self;
904 object *args;
905{
906 if (!getnoarg(args))
907 return NULL;
908 return newsizedstringobject(tegettext(self->t_text),
909 tegetlen(self->t_text));
910}
911
912static object *
913text_move(self, args)
914 textobject *self;
915 object *args;
916{
917 int a[4];
918 if (!getrectarg(args, a))
919 return NULL;
920 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
921 INCREF(None);
922 return None;
923}
924
925static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000926text_replace(self, args)
927 textobject *self;
928 object *args;
929{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000930 char *text;
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000931 if (!getstrarg(args, &text))
932 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000933 tereplace(self->t_text, text);
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000934 INCREF(None);
935 return None;
936}
937
938static object *
939text_setactive(self, args)
940 textobject *self;
941 object *args;
942{
943 int flag;
944 if (!getintarg(args, &flag))
945 return NULL;
946 tesetactive(self->t_text, flag);
947 INCREF(None);
948 return None;
949}
950
951static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000952text_setfocus(self, args)
953 textobject *self;
954 object *args;
955{
956 int a[2];
957 if (!getpointarg(args, a))
958 return NULL;
959 tesetfocus(self->t_text, a[0], a[1]);
960 INCREF(None);
961 return None;
962}
963
964static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +0000965text_settext(self, args)
966 textobject *self;
967 object *args;
968{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000969 char *text;
Guido van Rossum541c8c01991-05-05 20:13:41 +0000970 char *buf;
971 int size;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000972 if (!getargs(args, "s#", &text, &size))
Guido van Rossum541c8c01991-05-05 20:13:41 +0000973 return NULL;
Guido van Rossum541c8c01991-05-05 20:13:41 +0000974 if ((buf = NEW(char, size)) == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000975 return err_nomem();
Guido van Rossum541c8c01991-05-05 20:13:41 +0000976 }
Guido van Rossumfc58e581992-01-27 16:45:55 +0000977 memcpy(buf, text, size);
Guido van Rossum541c8c01991-05-05 20:13:41 +0000978 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
979 INCREF(None);
980 return None;
981}
982
983static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000984text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985 textobject *self;
986 object *args;
987{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000988 int a[4];
989 if (args == None)
990 tenoview(self->t_text);
991 else {
992 if (!getrectarg(args, a))
993 return NULL;
994 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
995 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000996 INCREF(None);
997 return None;
998}
999
1000static struct methodlist text_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001001 {"arrow", text_arrow},
1002 {"close", text_close},
1003 {"draw", text_draw},
1004 {"event", text_event},
1005 {"getfocus", text_getfocus},
Guido van Rossum77b46041992-01-14 18:41:24 +00001006 {"getfocustext",text_getfocustext},
Guido van Rossum3c284741991-11-27 14:54:54 +00001007 {"getrect", text_getrect},
1008 {"gettext", text_gettext},
Guido van Rossum77b46041992-01-14 18:41:24 +00001009 {"move", text_move},
Guido van Rossum3c284741991-11-27 14:54:54 +00001010 {"replace", text_replace},
1011 {"setactive", text_setactive},
1012 {"setfocus", text_setfocus},
1013 {"settext", text_settext},
1014 {"setview", text_setview},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015 {NULL, NULL} /* sentinel */
1016};
1017
1018static object *
1019text_getattr(tp, name)
1020 textobject *tp;
1021 char *name;
1022{
Guido van Rossum85f50761991-10-20 20:22:50 +00001023 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001024 if (tp->t_ref == NULL) {
1025 err_setstr(StdwinError, "text object already closed");
1026 return NULL;
1027 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001028 if (strcmp(name, "__dict__") == 0) {
1029 v = tp->t_attr;
1030 if (v == NULL)
1031 v = None;
1032 }
1033 else if (tp->t_attr != NULL) {
1034 v = dictlookup(tp->t_attr, name);
1035 }
1036 if (v != NULL) {
1037 INCREF(v);
1038 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001039 }
1040 return findmethod(text_methods, (object *)tp, name);
1041}
1042
1043static int
1044text_setattr(tp, name, v)
1045 textobject *tp;
1046 char *name;
1047 object *v;
1048{
1049 if (tp->t_attr == NULL) {
1050 tp->t_attr = newdictobject();
1051 if (tp->t_attr == NULL)
1052 return -1;
1053 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001054 if (v == NULL) {
1055 int rv = dictremove(tp->t_attr, name);
1056 if (rv < 0)
1057 err_setstr(AttributeError,
1058 "delete non-existing text object attribute");
1059 return rv;
1060 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061 else
1062 return dictinsert(tp->t_attr, name, v);
1063}
1064
Guido van Rossum541c8c01991-05-05 20:13:41 +00001065typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001066 OB_HEAD_INIT(&Typetype)
1067 0, /*ob_size*/
1068 "textedit", /*tp_name*/
1069 sizeof(textobject), /*tp_size*/
1070 0, /*tp_itemsize*/
1071 /* methods */
1072 text_dealloc, /*tp_dealloc*/
1073 0, /*tp_print*/
1074 text_getattr, /*tp_getattr*/
1075 text_setattr, /*tp_setattr*/
1076 0, /*tp_compare*/
1077 0, /*tp_repr*/
1078};
1079
1080
1081/* Menu objects */
1082
Guido van Rossum2d14e211991-02-19 12:26:49 +00001083#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001084#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001085static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086
Guido van Rossumfc58e581992-01-27 16:45:55 +00001087static menuobject *newmenuobject PROTO((char *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001088static menuobject *
1089newmenuobject(title)
Guido van Rossumfc58e581992-01-27 16:45:55 +00001090 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001091{
1092 int id;
1093 MENU *menu;
1094 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001095 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096 if (menulist[id] == NULL)
1097 break;
1098 }
Guido van Rossum27201061991-04-16 08:43:03 +00001099 if (id >= MAXNMENU) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001100 err_setstr(StdwinError, "creating too many menus");
Guido van Rossum27201061991-04-16 08:43:03 +00001101 return NULL;
1102 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001103 menu = wmenucreate(id + IDOFFSET, title);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001104 if (menu == NULL)
1105 return (menuobject *) err_nomem();
1106 mp = NEWOBJ(menuobject, &Menutype);
1107 if (mp != NULL) {
1108 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001109 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110 mp->m_attr = NULL;
1111 menulist[id] = mp;
1112 }
1113 else
1114 wmenudelete(menu);
1115 return mp;
1116}
1117
1118/* Menu methods */
1119
1120static void
1121menu_dealloc(mp)
1122 menuobject *mp;
1123{
1124
Guido van Rossum2d14e211991-02-19 12:26:49 +00001125 int id = mp->m_id - IDOFFSET;
1126 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001127 menulist[id] = NULL;
1128 }
Guido van Rossum77b46041992-01-14 18:41:24 +00001129 if (mp->m_menu != NULL)
1130 wmenudelete(mp->m_menu);
1131 XDECREF(mp->m_attr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132 DEL(mp);
1133}
1134
1135static object *
Guido van Rossum77b46041992-01-14 18:41:24 +00001136menu_close(mp, args)
1137 menuobject *mp;
1138 object *args;
1139{
1140 int id = mp->m_id - IDOFFSET;
1141 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1142 menulist[id] = NULL;
1143 }
1144 mp->m_id = -1;
1145 if (mp->m_menu != NULL)
1146 wmenudelete(mp->m_menu);
1147 mp->m_menu = NULL;
1148 XDECREF(mp->m_attr);
1149 mp->m_attr = NULL;
1150 INCREF(None);
1151 return None;
1152}
1153
1154static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155menu_additem(self, args)
1156 menuobject *self;
1157 object *args;
1158{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001159 char *text;
1160 int shortcut = -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 if (is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +00001162 char c;
1163 if (!getargs(args, "(sc)", &text, &c))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001164 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001165 shortcut = c;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001167 else if (!getstrarg(args, &text))
1168 return NULL;
1169 wmenuadditem(self->m_menu, text, shortcut);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 INCREF(None);
1171 return None;
1172}
1173
1174static object *
1175menu_setitem(self, args)
1176 menuobject *self;
1177 object *args;
1178{
1179 int index;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001180 char *text;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181 if (!getintstrarg(args, &index, &text))
1182 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001183 wmenusetitem(self->m_menu, index, text);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 INCREF(None);
1185 return None;
1186}
1187
1188static object *
1189menu_enable(self, args)
1190 menuobject *self;
1191 object *args;
1192{
1193 int index;
1194 int flag;
1195 if (!getintintarg(args, &index, &flag))
1196 return NULL;
1197 wmenuenable(self->m_menu, index, flag);
1198 INCREF(None);
1199 return None;
1200}
1201
1202static object *
1203menu_check(self, args)
1204 menuobject *self;
1205 object *args;
1206{
1207 int index;
1208 int flag;
1209 if (!getintintarg(args, &index, &flag))
1210 return NULL;
1211 wmenucheck(self->m_menu, index, flag);
1212 INCREF(None);
1213 return None;
1214}
1215
1216static struct methodlist menu_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001217 {"additem", menu_additem},
1218 {"setitem", menu_setitem},
1219 {"enable", menu_enable},
1220 {"check", menu_check},
Guido van Rossum77b46041992-01-14 18:41:24 +00001221 {"close", menu_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222 {NULL, NULL} /* sentinel */
1223};
1224
1225static object *
1226menu_getattr(mp, name)
1227 menuobject *mp;
1228 char *name;
1229{
Guido van Rossum85f50761991-10-20 20:22:50 +00001230 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001231 if (mp->m_menu == NULL) {
1232 err_setstr(StdwinError, "menu object already closed");
1233 return NULL;
1234 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001235 if (strcmp(name, "__dict__") == 0) {
1236 v = mp->m_attr;
1237 if (v == NULL)
1238 v = None;
1239 }
1240 else if (mp->m_attr != NULL) {
1241 v = dictlookup(mp->m_attr, name);
1242 }
1243 if (v != NULL) {
1244 INCREF(v);
1245 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246 }
1247 return findmethod(menu_methods, (object *)mp, name);
1248}
1249
1250static int
1251menu_setattr(mp, name, v)
1252 menuobject *mp;
1253 char *name;
1254 object *v;
1255{
1256 if (mp->m_attr == NULL) {
1257 mp->m_attr = newdictobject();
1258 if (mp->m_attr == NULL)
1259 return -1;
1260 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001261 if (v == NULL) {
1262 int rv = dictremove(mp->m_attr, name);
1263 if (rv < 0)
1264 err_setstr(AttributeError,
1265 "delete non-existing menu object attribute");
1266 return rv;
1267 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001268 else
1269 return dictinsert(mp->m_attr, name, v);
1270}
1271
Guido van Rossum541c8c01991-05-05 20:13:41 +00001272typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273 OB_HEAD_INIT(&Typetype)
1274 0, /*ob_size*/
1275 "menu", /*tp_name*/
1276 sizeof(menuobject), /*tp_size*/
1277 0, /*tp_itemsize*/
1278 /* methods */
1279 menu_dealloc, /*tp_dealloc*/
1280 0, /*tp_print*/
1281 menu_getattr, /*tp_getattr*/
1282 menu_setattr, /*tp_setattr*/
1283 0, /*tp_compare*/
1284 0, /*tp_repr*/
1285};
1286
1287
1288/* Windows */
1289
1290#define MAXNWIN 50
1291static windowobject *windowlist[MAXNWIN];
1292
1293/* Window methods */
1294
1295static void
1296window_dealloc(wp)
1297 windowobject *wp;
1298{
1299 if (wp->w_win != NULL) {
1300 int tag = wgettag(wp->w_win);
1301 if (tag >= 0 && tag < MAXNWIN)
1302 windowlist[tag] = NULL;
1303 else
1304 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1305 tag);
1306 wclose(wp->w_win);
1307 }
1308 DECREF(wp->w_title);
1309 if (wp->w_attr != NULL)
1310 DECREF(wp->w_attr);
1311 free((char *)wp);
1312}
1313
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314static object *
Guido van Rossum3c284741991-11-27 14:54:54 +00001315window_close(wp, args)
1316 windowobject *wp;
1317 object *args;
1318{
1319 if (wp->w_win != NULL) {
1320 int tag = wgettag(wp->w_win);
1321 if (tag >= 0 && tag < MAXNWIN)
1322 windowlist[tag] = NULL;
1323 wclose(wp->w_win);
1324 wp->w_win = NULL;
1325 }
1326 INCREF(None);
1327 return None;
1328}
1329
1330static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331window_begindrawing(wp, args)
1332 windowobject *wp;
1333 object *args;
1334{
1335 drawingobject *dp;
1336 if (!getnoarg(args))
1337 return NULL;
1338 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001339 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340 return NULL;
1341 }
1342 dp = NEWOBJ(drawingobject, &Drawingtype);
1343 if (dp == NULL)
1344 return NULL;
1345 Drawing = dp;
1346 INCREF(wp);
1347 dp->d_ref = wp;
1348 wbegindrawing(wp->w_win);
1349 return (object *)dp;
1350}
1351
1352static object *
1353window_change(wp, args)
1354 windowobject *wp;
1355 object *args;
1356{
1357 int a[4];
1358 if (!getrectarg(args, a))
1359 return NULL;
1360 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1361 INCREF(None);
1362 return None;
1363}
1364
1365static object *
1366window_gettitle(wp, args)
1367 windowobject *wp;
1368 object *args;
1369{
1370 if (!getnoarg(args))
1371 return NULL;
1372 INCREF(wp->w_title);
1373 return wp->w_title;
1374}
1375
1376static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001377window_getwinpos(wp, args)
1378 windowobject *wp;
1379 object *args;
1380{
1381 int h, v;
1382 if (!getnoarg(args))
1383 return NULL;
1384 wgetwinpos(wp->w_win, &h, &v);
1385 return makepoint(h, v);
1386}
1387
1388static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001389window_getwinsize(wp, args)
1390 windowobject *wp;
1391 object *args;
1392{
1393 int width, height;
1394 if (!getnoarg(args))
1395 return NULL;
1396 wgetwinsize(wp->w_win, &width, &height);
1397 return makepoint(width, height);
1398}
1399
1400static object *
1401window_getdocsize(wp, args)
1402 windowobject *wp;
1403 object *args;
1404{
1405 int width, height;
1406 if (!getnoarg(args))
1407 return NULL;
1408 wgetdocsize(wp->w_win, &width, &height);
1409 return makepoint(width, height);
1410}
1411
1412static object *
1413window_getorigin(wp, args)
1414 windowobject *wp;
1415 object *args;
1416{
1417 int width, height;
1418 if (!getnoarg(args))
1419 return NULL;
1420 wgetorigin(wp->w_win, &width, &height);
1421 return makepoint(width, height);
1422}
1423
1424static object *
1425window_scroll(wp, args)
1426 windowobject *wp;
1427 object *args;
1428{
1429 int a[6];
1430 if (!getrectpointarg(args, a))
1431 return NULL;
1432 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1433 INCREF(None);
1434 return None;
1435}
1436
1437static object *
1438window_setdocsize(wp, args)
1439 windowobject *wp;
1440 object *args;
1441{
1442 int a[2];
1443 if (!getpointarg(args, a))
1444 return NULL;
1445 wsetdocsize(wp->w_win, a[0], a[1]);
1446 INCREF(None);
1447 return None;
1448}
1449
1450static object *
1451window_setorigin(wp, args)
1452 windowobject *wp;
1453 object *args;
1454{
1455 int a[2];
1456 if (!getpointarg(args, a))
1457 return NULL;
1458 wsetorigin(wp->w_win, a[0], a[1]);
1459 INCREF(None);
1460 return None;
1461}
1462
1463static object *
1464window_settitle(wp, args)
1465 windowobject *wp;
1466 object *args;
1467{
1468 object *title;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001469 if (!getStrarg(args, &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001470 return NULL;
1471 DECREF(wp->w_title);
1472 INCREF(title);
1473 wp->w_title = title;
1474 wsettitle(wp->w_win, getstringvalue(title));
1475 INCREF(None);
1476 return None;
1477}
1478
1479static object *
1480window_show(wp, args)
1481 windowobject *wp;
1482 object *args;
1483{
1484 int a[4];
1485 if (!getrectarg(args, a))
1486 return NULL;
1487 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1488 INCREF(None);
1489 return None;
1490}
1491
1492static object *
1493window_settimer(wp, args)
1494 windowobject *wp;
1495 object *args;
1496{
1497 int a;
1498 if (!getintarg(args, &a))
1499 return NULL;
1500 wsettimer(wp->w_win, a);
1501 INCREF(None);
1502 return None;
1503}
1504
1505static object *
1506window_menucreate(self, args)
1507 windowobject *self;
1508 object *args;
1509{
1510 menuobject *mp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001511 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001512 if (!getstrarg(args, &title))
1513 return NULL;
1514 wmenusetdeflocal(1);
1515 mp = newmenuobject(title);
1516 if (mp == NULL)
1517 return NULL;
1518 wmenuattach(self->w_win, mp->m_menu);
1519 return (object *)mp;
1520}
1521
1522static object *
1523window_textcreate(self, args)
1524 windowobject *self;
1525 object *args;
1526{
1527 textobject *tp;
1528 int a[4];
1529 if (!getrectarg(args, a))
1530 return NULL;
1531 return (object *)
1532 newtextobject(self, a[0], a[1], a[2], a[3]);
1533}
1534
Guido van Rossum5b10f451990-10-30 16:01:48 +00001535static object *
1536window_setselection(self, args)
1537 windowobject *self;
1538 object *args;
1539{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001540 int sel, size, ok;
1541 char *text;
1542 if (!getargs(args, "(is#)", &sel, &text, &size))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001543 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001544 ok = wsetselection(self->w_win, sel, text, size);
Guido van Rossum5b10f451990-10-30 16:01:48 +00001545 return newintobject(ok);
1546}
1547
1548static object *
1549window_setwincursor(self, args)
1550 windowobject *self;
1551 object *args;
1552{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001553 char *name;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001554 CURSOR *c;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001555 if (!getargs(args, "z", &name))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001556 return NULL;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001557 if (name == NULL)
1558 c = NULL;
1559 else {
1560 c = wfetchcursor(name);
1561 if (c == NULL) {
1562 err_setstr(StdwinError, "no such cursor");
1563 return NULL;
1564 }
Guido van Rossum5b10f451990-10-30 16:01:48 +00001565 }
1566 wsetwincursor(self->w_win, c);
1567 INCREF(None);
1568 return None;
1569}
1570
Guido van Rossumfc58e581992-01-27 16:45:55 +00001571static object *
1572window_setactive(self, args)
1573 windowobject *self;
1574 object *args;
1575{
1576 if (!getnoarg(args))
1577 return NULL;
1578 wsetactive(self->w_win);
1579 INCREF(None);
1580 return None;
1581}
1582
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001583#ifdef CWI_HACKS
1584static object *
1585window_getxwindowid(self, args)
1586 windowobject *self;
1587 object *args;
1588{
1589 long wid = wgetxwindowid(self->w_win);
1590 return newintobject(wid);
1591}
1592#endif
1593
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001594static struct methodlist window_methods[] = {
1595 {"begindrawing",window_begindrawing},
1596 {"change", window_change},
Guido van Rossum3c284741991-11-27 14:54:54 +00001597 {"close", window_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001598 {"getdocsize", window_getdocsize},
1599 {"getorigin", window_getorigin},
1600 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001601 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602 {"getwinsize", window_getwinsize},
1603 {"menucreate", window_menucreate},
1604 {"scroll", window_scroll},
Guido van Rossumb7e51601992-01-26 18:13:18 +00001605 {"setactive", window_setactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001606 {"setdocsize", window_setdocsize},
1607 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001608 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001609 {"settimer", window_settimer},
1610 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001611 {"setwincursor",window_setwincursor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001612 {"show", window_show},
1613 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001614#ifdef CWI_HACKS
1615 {"getxwindowid",window_getxwindowid},
1616#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617 {NULL, NULL} /* sentinel */
1618};
1619
1620static object *
1621window_getattr(wp, name)
1622 windowobject *wp;
1623 char *name;
1624{
Guido van Rossum85f50761991-10-20 20:22:50 +00001625 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001626 if (wp->w_win == NULL) {
1627 err_setstr(StdwinError, "window already closed");
1628 return NULL;
1629 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001630 if (strcmp(name, "__dict__") == 0) {
1631 v = wp->w_attr;
1632 if (v == NULL)
1633 v = None;
1634 }
1635 else if (wp->w_attr != NULL) {
1636 v = dictlookup(wp->w_attr, name);
1637 }
1638 if (v != NULL) {
1639 INCREF(v);
1640 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 }
1642 return findmethod(window_methods, (object *)wp, name);
1643}
1644
1645static int
1646window_setattr(wp, name, v)
1647 windowobject *wp;
1648 char *name;
1649 object *v;
1650{
1651 if (wp->w_attr == NULL) {
1652 wp->w_attr = newdictobject();
1653 if (wp->w_attr == NULL)
1654 return -1;
1655 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001656 if (v == NULL) {
1657 int rv = dictremove(wp->w_attr, name);
1658 if (rv < 0)
1659 err_setstr(AttributeError,
1660 "delete non-existing menu object attribute");
1661 return rv;
1662 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001663 else
1664 return dictinsert(wp->w_attr, name, v);
1665}
1666
Guido van Rossum541c8c01991-05-05 20:13:41 +00001667typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001668 OB_HEAD_INIT(&Typetype)
1669 0, /*ob_size*/
1670 "window", /*tp_name*/
1671 sizeof(windowobject), /*tp_size*/
1672 0, /*tp_itemsize*/
1673 /* methods */
1674 window_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001675 0, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001676 window_getattr, /*tp_getattr*/
1677 window_setattr, /*tp_setattr*/
1678 0, /*tp_compare*/
1679 0, /*tp_repr*/
1680};
1681
1682/* Stdwin methods */
1683
1684static object *
1685stdwin_open(sw, args)
1686 object *sw;
1687 object *args;
1688{
1689 int tag;
1690 object *title;
1691 windowobject *wp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001692 if (!getStrarg(args, &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693 return NULL;
1694 for (tag = 0; tag < MAXNWIN; tag++) {
1695 if (windowlist[tag] == NULL)
1696 break;
1697 }
Guido van Rossum27201061991-04-16 08:43:03 +00001698 if (tag >= MAXNWIN) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001699 err_setstr(StdwinError, "creating too many windows");
Guido van Rossum27201061991-04-16 08:43:03 +00001700 return NULL;
1701 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001702 wp = NEWOBJ(windowobject, &Windowtype);
1703 if (wp == NULL)
1704 return NULL;
1705 INCREF(title);
1706 wp->w_title = title;
1707 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1708 wp->w_attr = NULL;
1709 if (wp->w_win == NULL) {
1710 DECREF(wp);
1711 return NULL;
1712 }
1713 windowlist[tag] = wp;
1714 wsettag(wp->w_win, tag);
1715 return (object *)wp;
1716}
1717
1718static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001719window2object(win)
1720 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001721{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001722 object *w;
1723 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001724 w = None;
1725 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001726 int tag = wgettag(win);
1727 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1728 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001729 w = None;
1730 else
1731 w = (object *)windowlist[tag];
1732 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001733 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001734 return w;
1735}
1736
1737static object *
1738stdwin_get_poll_event(poll, args)
1739 int poll;
1740 object *args;
1741{
1742 EVENT e;
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001743 object *u, *v, *w;
Guido van Rossum246b9d81991-06-03 10:55:14 +00001744 if (!getnoarg(args))
1745 return NULL;
1746 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001747 err_setstr(StdwinError, "cannot getevent() while drawing");
Guido van Rossum246b9d81991-06-03 10:55:14 +00001748 return NULL;
1749 }
1750 again:
Guido van Rossumff4949e1992-08-05 19:58:53 +00001751 BGN_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00001752 if (poll) {
1753 if (!wpollevent(&e)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +00001754 RET_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00001755 INCREF(None);
1756 return None;
1757 }
1758 }
1759 else
1760 wgetevent(&e);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001761 END_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00001762 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
1763 /* Turn keyboard interrupts into exceptions */
1764 err_set(KeyboardInterrupt);
1765 return NULL;
1766 }
1767 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
1768 /* Turn WC_CLOSE commands into WE_CLOSE events */
1769 e.type = WE_CLOSE;
1770 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001771 v = window2object(e.window);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001772 switch (e.type) {
1773 case WE_CHAR:
1774 {
1775 char c[1];
1776 c[0] = e.u.character;
1777 w = newsizedstringobject(c, 1);
1778 }
1779 break;
1780 case WE_COMMAND:
1781 w = newintobject((long)e.u.command);
1782 break;
1783 case WE_DRAW:
1784 w = makerect(e.u.area.left, e.u.area.top,
1785 e.u.area.right, e.u.area.bottom);
1786 break;
1787 case WE_MOUSE_DOWN:
1788 case WE_MOUSE_MOVE:
1789 case WE_MOUSE_UP:
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001790 w = mkvalue("((ii)iii)",
1791 e.u.where.h, e.u.where.v,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001792 e.u.where.clicks,
1793 e.u.where.button,
1794 e.u.where.mask);
1795 break;
1796 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00001797 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
1798 menulist[e.u.m.id - IDOFFSET] != NULL)
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001799 w = mkvalue("(Oi)",
1800 menulist[e.u.m.id - IDOFFSET], e.u.m.item);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001801 else {
1802 /* Ghost menu event.
1803 Can occur only on the Mac if another part
1804 of the aplication has installed a menu;
1805 like the THINK C console library. */
1806 DECREF(v);
1807 goto again;
1808 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001809 break;
Guido van Rossum3ee199e1992-06-30 12:48:26 +00001810 case WE_KEY:
1811 w = mkvalue("(ii)", e.u.key.code, e.u.key.mask);
1812 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001813 case WE_LOST_SEL:
1814 w = newintobject((long)e.u.sel);
1815 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001816 default:
1817 w = None;
1818 INCREF(w);
1819 break;
1820 }
1821 if (w == NULL) {
1822 DECREF(v);
1823 return NULL;
1824 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001825 u = mkvalue("(iOO)", e.type, v, w);
1826 XDECREF(v);
1827 XDECREF(w);
1828 return u;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001829}
1830
1831static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00001832stdwin_getevent(sw, args)
1833 object *sw;
1834 object *args;
1835{
1836 return stdwin_get_poll_event(0, args);
1837}
1838
1839static object *
1840stdwin_pollevent(sw, args)
1841 object *sw;
1842 object *args;
1843{
1844 return stdwin_get_poll_event(1, args);
1845}
1846
1847static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001848stdwin_setdefwinpos(sw, args)
1849 object *sw;
1850 object *args;
1851{
1852 int a[2];
1853 if (!getpointarg(args, a))
1854 return NULL;
1855 wsetdefwinpos(a[0], a[1]);
1856 INCREF(None);
1857 return None;
1858}
1859
1860static object *
1861stdwin_setdefwinsize(sw, args)
1862 object *sw;
1863 object *args;
1864{
1865 int a[2];
1866 if (!getpointarg(args, a))
1867 return NULL;
1868 wsetdefwinsize(a[0], a[1]);
1869 INCREF(None);
1870 return None;
1871}
1872
1873static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001874stdwin_setdefscrollbars(sw, args)
1875 object *sw;
1876 object *args;
1877{
1878 int a[2];
1879 if (!getpointarg(args, a))
1880 return NULL;
1881 wsetdefscrollbars(a[0], a[1]);
1882 INCREF(None);
1883 return None;
1884}
1885
1886static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001887stdwin_getdefwinpos(self, args)
1888 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001889 object *args;
1890{
1891 int h, v;
1892 if (!getnoarg(args))
1893 return NULL;
1894 wgetdefwinpos(&h, &v);
1895 return makepoint(h, v);
1896}
1897
1898static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001899stdwin_getdefwinsize(self, args)
1900 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00001901 object *args;
1902{
1903 int width, height;
1904 if (!getnoarg(args))
1905 return NULL;
1906 wgetdefwinsize(&width, &height);
1907 return makepoint(width, height);
1908}
1909
1910static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001911stdwin_getdefscrollbars(self, args)
1912 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00001913 object *args;
1914{
1915 int h, v;
1916 if (!getnoarg(args))
1917 return NULL;
1918 wgetdefscrollbars(&h, &v);
1919 return makepoint(h, v);
1920}
1921
1922static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001923stdwin_menucreate(self, args)
1924 object *self;
1925 object *args;
1926{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001927 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001928 if (!getstrarg(args, &title))
1929 return NULL;
1930 wmenusetdeflocal(0);
1931 return (object *)newmenuobject(title);
1932}
1933
1934static object *
1935stdwin_askfile(self, args)
1936 object *self;
1937 object *args;
1938{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001939 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001940 int new, ret;
1941 char buf[256];
1942 if (!getstrstrintarg(args, &prompt, &dflt, &new))
1943 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001944 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001945 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00001946 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00001947 ret = waskfile(prompt, buf, sizeof buf, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001948 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001949 if (!ret) {
1950 err_set(KeyboardInterrupt);
1951 return NULL;
1952 }
1953 return newstringobject(buf);
1954}
1955
1956static object *
1957stdwin_askync(self, args)
1958 object *self;
1959 object *args;
1960{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001961 char *prompt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001962 int new, ret;
1963 if (!getstrintarg(args, &prompt, &new))
1964 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001965 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00001966 ret = waskync(prompt, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001967 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001968 if (ret < 0) {
1969 err_set(KeyboardInterrupt);
1970 return NULL;
1971 }
1972 return newintobject((long)ret);
1973}
1974
1975static object *
1976stdwin_askstr(self, args)
1977 object *self;
1978 object *args;
1979{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001980 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001981 int ret;
1982 char buf[256];
1983 if (!getstrstrarg(args, &prompt, &dflt))
1984 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001985 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00001987 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00001988 ret = waskstr(prompt, buf, sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001989 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001990 if (!ret) {
1991 err_set(KeyboardInterrupt);
1992 return NULL;
1993 }
1994 return newstringobject(buf);
1995}
1996
1997static object *
1998stdwin_message(self, args)
1999 object *self;
2000 object *args;
2001{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002002 char *msg;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002003 if (!getstrarg(args, &msg))
2004 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002005 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002006 wmessage(msg);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002007 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002008 INCREF(None);
2009 return None;
2010}
2011
2012static object *
2013stdwin_fleep(self, args)
2014 object *self;
2015 object *args;
2016{
2017 if (!getnoarg(args))
2018 return NULL;
2019 wfleep();
2020 INCREF(None);
2021 return None;
2022}
2023
2024static object *
2025stdwin_setcutbuffer(self, args)
2026 object *self;
2027 object *args;
2028{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002029 int i, size;
2030 char *str;
2031 if (!getargs(args, "(is#)", &i, &str, &size))
Guido van Rossum124967c1990-11-06 15:17:35 +00002032 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002033 wsetcutbuffer(i, str, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034 INCREF(None);
2035 return None;
2036}
2037
2038static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002039stdwin_getactive(self, args)
2040 object *self;
2041 object *args;
2042{
2043 return window2object(wgetactive());
2044}
2045
2046static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047stdwin_getcutbuffer(self, args)
2048 object *self;
2049 object *args;
2050{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002051 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002052 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002053 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002054 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002056 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002057 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002059 len = 0;
2060 }
2061 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062}
2063
Guido van Rossum5b10f451990-10-30 16:01:48 +00002064static object *
2065stdwin_rotatecutbuffers(self, args)
2066 object *self;
2067 object *args;
2068{
2069 int i;
2070 if (!getintarg(args, &i))
2071 return NULL;
2072 wrotatecutbuffers(i);
2073 INCREF(None);
2074 return None;
2075}
2076
2077static object *
2078stdwin_getselection(self, args)
2079 object *self;
2080 object *args;
2081{
2082 int sel;
2083 char *data;
2084 int len;
2085 if (!getintarg(args, &sel))
2086 return NULL;
2087 data = wgetselection(sel, &len);
2088 if (data == NULL) {
2089 data = "";
2090 len = 0;
2091 }
2092 return newsizedstringobject(data, len);
2093}
2094
2095static object *
2096stdwin_resetselection(self, args)
2097 object *self;
2098 object *args;
2099{
2100 int sel;
2101 if (!getintarg(args, &sel))
2102 return NULL;
2103 wresetselection(sel);
2104 INCREF(None);
2105 return None;
2106}
2107
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002108static object *
2109stdwin_fetchcolor(self, args)
2110 object *self;
2111 object *args;
2112{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002113 char *colorname;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002114 if (!getstrarg(args, &colorname))
2115 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002116 return newintobject((long)wfetchcolor(colorname));
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002117}
2118
Guido van Rossum541c8c01991-05-05 20:13:41 +00002119static object *
2120stdwin_getscrsize(self, args)
2121 object *self;
2122 object *args;
2123{
2124 int width, height;
2125 if (!getnoarg(args))
2126 return NULL;
2127 wgetscrsize(&width, &height);
2128 return makepoint(width, height);
2129}
2130
2131static object *
2132stdwin_getscrmm(self, args)
2133 object *self;
2134 object *args;
2135{
2136 int width, height;
2137 if (!getnoarg(args))
2138 return NULL;
2139 wgetscrmm(&width, &height);
2140 return makepoint(width, height);
2141}
2142
Guido van Rossumed233a51992-06-23 09:07:03 +00002143#ifdef unix
2144static object *
2145stdwin_connectionnumber(self, args)
2146 object *self;
2147 object *args;
2148{
2149 if (!getnoarg(args))
2150 return NULL;
2151 return newintobject((long) wconnectionnumber());
2152}
2153#endif
2154
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002155static struct methodlist stdwin_methods[] = {
2156 {"askfile", stdwin_askfile},
2157 {"askstr", stdwin_askstr},
2158 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002159 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossumed233a51992-06-23 09:07:03 +00002160#ifdef unix
2161 {"fileno", stdwin_connectionnumber},
2162 {"connectionnumber", stdwin_connectionnumber},
2163#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002164 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002165 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002166 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002167 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002168 {"getdefwinpos", stdwin_getdefwinpos},
2169 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002170 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002171 {"getscrmm", stdwin_getscrmm},
2172 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002173 {"getselection", stdwin_getselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002174 {"menucreate", stdwin_menucreate},
2175 {"message", stdwin_message},
2176 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002177 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002178 {"resetselection", stdwin_resetselection},
2179 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002180 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002181 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002182 {"setdefwinpos", stdwin_setdefwinpos},
2183 {"setdefwinsize", stdwin_setdefwinsize},
2184
2185 /* Text measuring methods borrow code from drawing objects: */
2186 {"baseline", drawing_baseline},
2187 {"lineheight", drawing_lineheight},
2188 {"textbreak", drawing_textbreak},
2189 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002190
2191 /* Same for font setting methods: */
2192 {"setfont", drawing_setfont},
2193
2194 /* Same for color setting/getting methods: */
2195 {"getbgcolor", drawing_getbgcolor},
2196 {"getfgcolor", drawing_getfgcolor},
2197 {"setbgcolor", drawing_setbgcolor},
2198 {"setfgcolor", drawing_setfgcolor},
2199
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002200 {NULL, NULL} /* sentinel */
2201};
2202
2203void
2204initstdwin()
2205{
Guido van Rossumbbf94341991-12-16 15:44:53 +00002206 object *m, *d;
2207 static int inited = 0;
2208
Guido van Rossum2d14e211991-02-19 12:26:49 +00002209 if (!inited) {
2210 winit();
2211 inited = 1;
2212 }
Guido van Rossumbbf94341991-12-16 15:44:53 +00002213 m = initmodule("stdwin", stdwin_methods);
2214 d = getmoduledict(m);
2215
2216 /* Initialize stdwin.error exception */
2217 StdwinError = newstringobject("stdwin.error");
2218 if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
2219 fatal("can't define stdwin.error");
Guido van Rossumff4949e1992-08-05 19:58:53 +00002220#ifdef USE_THREAD
2221 StdwinLock = allocate_lock();
2222 if (StdwinLock == NULL)
2223 fatal("can't allocate stdwin lock");
2224#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002225}