blob: 02f7bcbd9bf2de009108346d072e09023b4f4873 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
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
Guido van Rossumbf80e541993-02-08 15:49:17 +000033 bp: a bitmap
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034*/
35
36/* Rules for translating C stdwin function calls into Python stwin:
37 - All names drop their initial letter 'w'
38 - Functions with a window as first parameter are methods of window objects
39 - There is no equivalent for wclose(); just delete the window object
40 (all references to it!) (XXX maybe this is a bad idea)
41 - w.begindrawing() returns a drawing object
42 - There is no equivalent for wenddrawing(win); just delete the drawing
43 object (all references to it!) (XXX maybe this is a bad idea)
44 - Functions that may only be used inside wbegindrawing / wendddrawing
45 are methods of the drawing object; this includes the text measurement
46 functions (which however have doubles as module functions).
47 - Methods of the drawing object drop an initial 'draw' from their name
48 if they have it, e.g., wdrawline() --> d.line()
49 - The obvious type conversions: int --> intobject; string --> stringobject
50 - A text parameter followed by a length parameter is only a text (string)
51 parameter in Python
52 - A point or other pair of horizontal and vertical coordinates is always
53 a pair of integers in Python
54 - Two points forming a rectangle or endpoints of a line segment are a
55 pair of points in Python
56 - The arguments to d.elarc() are three points.
57 - The functions wgetclip() and wsetclip() are translated into
58 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
59 a bad word for what these functions do (clipping has a different
60 meaning in the drawing world), while cutbuffer is standard X jargon.
Guido van Rossum01769f01990-10-30 13:39:00 +000061 XXX This must change again in the light of changes to stdwin!
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062 - For textedit, similar rules hold, but they are less strict.
63 XXX more?
64*/
65
Guido van Rossum3f5da241990-12-20 15:06:42 +000066#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000068#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000070#ifdef macintosh
71#include ":::src:stdwin:H:stdwin.h"
72#else /* !macintosh */
Guido van Rossum3f5da241990-12-20 15:06:42 +000073#include "stdwin.h"
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000074#endif /* !macintosh */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075
Guido van Rossumff4949e1992-08-05 19:58:53 +000076#ifdef USE_THREAD
77
78#include "thread.h"
79
80static type_lock StdwinLock; /* Lock held when interpreter not locked */
81
82#define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
83#define RET_STDWIN release_lock(StdwinLock); RET_SAVE
84#define END_STDWIN release_lock(StdwinLock); END_SAVE
85
86#else
87
88#define BGN_STDWIN BGN_SAVE
89#define RET_STDWIN RET_SAVE
90#define END_STDWIN END_SAVE
91
92#endif
93
Guido van Rossumbbf94341991-12-16 15:44:53 +000094static object *StdwinError; /* Exception stdwin.error */
Guido van Rossum87e7ea71991-12-10 14:00:03 +000095
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096/* Window and menu object types declared here because of forward references */
97
98typedef struct {
99 OB_HEAD
100 object *w_title;
101 WINDOW *w_win;
102 object *w_attr; /* Attributes dictionary */
103} windowobject;
104
105extern typeobject Windowtype; /* Really static, forward */
106
107#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
108
109typedef struct {
110 OB_HEAD
111 MENU *m_menu;
112 int m_id;
113 object *m_attr; /* Attributes dictionary */
114} menuobject;
115
116extern typeobject Menutype; /* Really static, forward */
117
118#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
119
Guido van Rossumbf80e541993-02-08 15:49:17 +0000120typedef struct {
121 OB_HEAD
122 BITMAP *b_bitmap;
123 object *b_attr; /* Attributes dictionary */
124} bitmapobject;
125
126extern typeobject Bitmaptype; /* Really static, forward */
127
128#define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
129
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130
131/* Strongly stdwin-specific argument handlers */
132
133static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134getmenudetail(v, ep)
135 object *v;
136 EVENT *ep;
137{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000138 menuobject *mp;
139 if (!getargs(v, "(Oi)", &mp, &ep->u.m.item))
140 return 0;
141 if (!is_menuobject(mp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000143 ep->u.m.id = mp->m_id;
144 return 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145}
146
147static int
148geteventarg(v, ep)
149 object *v;
150 EVENT *ep;
151{
152 object *wp, *detail;
153 int a[4];
Guido van Rossumfc58e581992-01-27 16:45:55 +0000154 if (!getargs(v, "(iOO)", &ep->type, &wp, &detail))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 return 0;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000156 if (is_windowobject(wp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 ep->window = ((windowobject *)wp) -> w_win;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000158 else if (wp == None)
159 ep->window = NULL;
160 else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000162 switch (ep->type) {
163 case WE_CHAR: {
164 char c;
165 if (!getargs(detail, "c", &c))
166 return 0;
167 ep->u.character = c;
168 return 1;
169 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170 case WE_COMMAND:
171 return getintarg(detail, &ep->u.command);
172 case WE_DRAW:
173 if (!getrectarg(detail, a))
174 return 0;
175 ep->u.area.left = a[0];
176 ep->u.area.top = a[1];
177 ep->u.area.right = a[2];
178 ep->u.area.bottom = a[3];
179 return 1;
180 case WE_MOUSE_DOWN:
181 case WE_MOUSE_UP:
182 case WE_MOUSE_MOVE:
Guido van Rossumfc58e581992-01-27 16:45:55 +0000183 return getargs(detail, "((ii)iii)",
184 &ep->u.where.h, &ep->u.where.v,
185 &ep->u.where.clicks,
186 &ep->u.where.button,
187 &ep->u.where.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 case WE_MENU:
189 return getmenudetail(detail, ep);
Guido van Rossum3ee199e1992-06-30 12:48:26 +0000190 case WE_KEY:
191 return getargs(detail, "(ii)",
192 &ep->u.key.code, &ep->u.key.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 default:
194 return 1;
195 }
196}
197
198
199/* Return construction tools */
200
201static object *
202makepoint(a, b)
203 int a, b;
204{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000205 return mkvalue("(ii)", a, b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206}
207
208static object *
209makerect(a, b, c, d)
210 int a, b, c, d;
211{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000212 return mkvalue("((ii)(ii))", a, b, c, d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213}
214
215
216/* Drawing objects */
217
218typedef struct {
219 OB_HEAD
220 windowobject *d_ref;
221} drawingobject;
222
223static drawingobject *Drawing; /* Set to current drawing object, or NULL */
224
225/* Drawing methods */
226
Guido van Rossum3c284741991-11-27 14:54:54 +0000227static object *
228drawing_close(dp)
229 drawingobject *dp;
230{
231 if (dp->d_ref != NULL) {
232 wenddrawing(dp->d_ref->w_win);
233 Drawing = NULL;
234 DECREF(dp->d_ref);
235 dp->d_ref = NULL;
236 }
237 INCREF(None);
238 return None;
239}
Guido van Rossum77b46041992-01-14 18:41:24 +0000240
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241static void
242drawing_dealloc(dp)
243 drawingobject *dp;
244{
Guido van Rossum3c284741991-11-27 14:54:54 +0000245 if (dp->d_ref != NULL) {
246 wenddrawing(dp->d_ref->w_win);
247 Drawing = NULL;
248 DECREF(dp->d_ref);
249 dp->d_ref = NULL;
250 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 free((char *)dp);
252}
253
254static object *
255drawing_generic(dp, args, func)
256 drawingobject *dp;
257 object *args;
258 void (*func) FPROTO((int, int, int, int));
259{
260 int a[4];
261 if (!getrectarg(args, a))
262 return NULL;
263 (*func)(a[0], a[1], a[2], a[3]);
264 INCREF(None);
265 return None;
266}
267
268static object *
269drawing_line(dp, args)
270 drawingobject *dp;
271 object *args;
272{
Guido van Rossumbf109731991-03-06 13:14:12 +0000273 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274}
275
276static object *
277drawing_xorline(dp, args)
278 drawingobject *dp;
279 object *args;
280{
Guido van Rossumbf109731991-03-06 13:14:12 +0000281 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282}
283
284static object *
285drawing_circle(dp, args)
286 drawingobject *dp;
287 object *args;
288{
289 int a[3];
290 if (!getpointintarg(args, a))
291 return NULL;
292 wdrawcircle(a[0], a[1], a[2]);
293 INCREF(None);
294 return None;
295}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000296
Guido van Rossum27201061991-04-16 08:43:03 +0000297static object *
298drawing_fillcircle(dp, args)
299 drawingobject *dp;
300 object *args;
301{
302 int a[3];
303 if (!getpointintarg(args, a))
304 return NULL;
305 wfillcircle(a[0], a[1], a[2]);
306 INCREF(None);
307 return None;
308}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309
310static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000311drawing_xorcircle(dp, args)
312 drawingobject *dp;
313 object *args;
314{
315 int a[3];
316 if (!getpointintarg(args, a))
317 return NULL;
318 wxorcircle(a[0], a[1], a[2]);
319 INCREF(None);
320 return None;
321}
322
323static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324drawing_elarc(dp, args)
325 drawingobject *dp;
326 object *args;
327{
328 int a[6];
329 if (!get3pointarg(args, a))
330 return NULL;
331 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
332 INCREF(None);
333 return None;
334}
335
336static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000337drawing_fillelarc(dp, args)
338 drawingobject *dp;
339 object *args;
340{
341 int a[6];
342 if (!get3pointarg(args, a))
343 return NULL;
344 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
345 INCREF(None);
346 return None;
347}
348
349static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000350drawing_xorelarc(dp, args)
351 drawingobject *dp;
352 object *args;
353{
354 int a[6];
355 if (!get3pointarg(args, a))
356 return NULL;
357 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
358 INCREF(None);
359 return None;
360}
361
362static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363drawing_box(dp, args)
364 drawingobject *dp;
365 object *args;
366{
Guido van Rossumbf109731991-03-06 13:14:12 +0000367 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000368}
369
370static object *
371drawing_erase(dp, args)
372 drawingobject *dp;
373 object *args;
374{
Guido van Rossumbf109731991-03-06 13:14:12 +0000375 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376}
377
378static object *
379drawing_paint(dp, args)
380 drawingobject *dp;
381 object *args;
382{
Guido van Rossumbf109731991-03-06 13:14:12 +0000383 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384}
385
386static object *
387drawing_invert(dp, args)
388 drawingobject *dp;
389 object *args;
390{
Guido van Rossumbf109731991-03-06 13:14:12 +0000391 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392}
393
Guido van Rossum27201061991-04-16 08:43:03 +0000394static POINT *
395getpointsarray(v, psize)
396 object *v;
397 int *psize;
398{
399 int n = -1;
400 object * (*getitem) PROTO((object *, int));
401 int i;
402 POINT *points;
403
404 if (v == NULL)
405 ;
406 else if (is_listobject(v)) {
407 n = getlistsize(v);
408 getitem = getlistitem;
409 }
410 else if (is_tupleobject(v)) {
411 n = gettuplesize(v);
412 getitem = gettupleitem;
413 }
414
415 if (n <= 0) {
416 (void) err_badarg();
417 return NULL;
418 }
419
420 points = NEW(POINT, n);
421 if (points == NULL) {
422 (void) err_nomem();
423 return NULL;
424 }
425
426 for (i = 0; i < n; i++) {
427 object *w = (*getitem)(v, i);
428 int a[2];
429 if (!getpointarg(w, a)) {
430 DEL(points);
431 return NULL;
432 }
433 points[i].h = a[0];
434 points[i].v = a[1];
435 }
436
437 *psize = n;
438 return points;
439}
440
441static object *
442drawing_poly(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 wdrawpoly(n, points);
451 DEL(points);
452 INCREF(None);
453 return None;
454}
455
456static object *
457drawing_fillpoly(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 wfillpoly(n, points);
466 DEL(points);
467 INCREF(None);
468 return None;
469}
470
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000472drawing_xorpoly(dp, args)
473 drawingobject *dp;
474 object *args;
475{
476 int n;
477 POINT *points = getpointsarray(args, &n);
478 if (points == NULL)
479 return NULL;
480 wxorpoly(n, points);
481 DEL(points);
482 INCREF(None);
483 return None;
484}
485
486static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487drawing_cliprect(dp, args)
488 drawingobject *dp;
489 object *args;
490{
Guido van Rossumbf109731991-03-06 13:14:12 +0000491 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492}
493
494static object *
495drawing_noclip(dp, args)
496 drawingobject *dp;
497 object *args;
498{
499 if (!getnoarg(args))
500 return NULL;
501 wnoclip();
502 INCREF(None);
503 return None;
504}
505
506static object *
507drawing_shade(dp, args)
508 drawingobject *dp;
509 object *args;
510{
511 int a[5];
512 if (!getrectintarg(args, a))
513 return NULL;
514 wshade(a[0], a[1], a[2], a[3], a[4]);
515 INCREF(None);
516 return None;
517}
518
519static object *
520drawing_text(dp, args)
521 drawingobject *dp;
522 object *args;
523{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000524 int h, v, size;
525 char *text;
526 if (!getargs(args, "((ii)s#)", &h, &v, &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000528 wdrawtext(h, v, text, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529 INCREF(None);
530 return None;
531}
532
533/* The following four are also used as stdwin functions */
534
535static object *
536drawing_lineheight(dp, args)
537 drawingobject *dp;
538 object *args;
539{
540 if (!getnoarg(args))
541 return NULL;
542 return newintobject((long)wlineheight());
543}
544
545static object *
546drawing_baseline(dp, args)
547 drawingobject *dp;
548 object *args;
549{
550 if (!getnoarg(args))
551 return NULL;
552 return newintobject((long)wbaseline());
553}
554
555static object *
556drawing_textwidth(dp, args)
557 drawingobject *dp;
558 object *args;
559{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000560 char *text;
561 int size;
562 if (!getargs(args, "s#", &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000563 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000564 return newintobject((long)wtextwidth(text, size));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565}
566
567static object *
568drawing_textbreak(dp, args)
569 drawingobject *dp;
570 object *args;
571{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000572 char *text;
573 int size, width;
574 if (!getargs(args, "(s#i)", &text, &size, &width))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000575 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000576 return newintobject((long)wtextbreak(text, size, width));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577}
578
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000579static object *
580drawing_setfont(self, args)
581 drawingobject *self;
582 object *args;
583{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000584 char *font;
585 char style = '\0';
586 int size = 0;
587 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +0000588 if (!getargs(args, "z", &font))
Guido van Rossum50429a11991-04-04 15:24:07 +0000589 return NULL;
590 }
591 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000592 int n = gettuplesize(args);
593 if (n == 2) {
594 if (!getargs(args, "(zi)", &font, &size))
595 return NULL;
596 }
597 else if (!getargs(args, "(zic)", &font, &size, &style)) {
598 err_clear();
599 if (!getargs(args, "(zci)", &font, &style, &size))
600 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000601 }
602 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000603 if (font != NULL) {
604 if (!wsetfont(font)) {
605 err_setstr(StdwinError, "font not found");
606 return NULL;
607 }
608 }
Guido van Rossum50429a11991-04-04 15:24:07 +0000609 if (size != 0)
610 wsetsize(size);
Guido van Rossumfc58e581992-01-27 16:45:55 +0000611 switch (style) {
612 case 'b':
613 wsetbold();
614 break;
615 case 'i':
616 wsetitalic();
617 break;
618 case 'o':
619 wsetbolditalic();
620 break;
621 case 'u':
622 wsetunderline();
623 break;
624 case 'p':
625 wsetplain();
626 break;
627 }
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000628 INCREF(None);
629 return None;
630}
631
632static object *
633drawing_getbgcolor(self, args)
634 object *self;
635 object *args;
636{
637 if (!getnoarg(args))
638 return NULL;
639 return newintobject((long)wgetbgcolor());
640}
641
642static object *
643drawing_getfgcolor(self, args)
644 object *self;
645 object *args;
646{
647 if (!getnoarg(args))
648 return NULL;
649 return newintobject((long)wgetfgcolor());
650}
651
652static object *
653drawing_setbgcolor(self, args)
654 object *self;
655 object *args;
656{
657 long color;
658 if (!getlongarg(args, &color))
659 return NULL;
660 wsetbgcolor((COLOR)color);
661 INCREF(None);
662 return None;
663}
664
665static object *
666drawing_setfgcolor(self, args)
667 object *self;
668 object *args;
669{
670 long color;
671 if (!getlongarg(args, &color))
672 return NULL;
673 wsetfgcolor((COLOR)color);
674 INCREF(None);
675 return None;
676}
677
Guido van Rossumbf80e541993-02-08 15:49:17 +0000678static object *
679drawing_bitmap(self, args)
680 object *self;
681 object *args;
682{
683 int h, v;
684 object *bp;
685 object *mask = NULL;
686 if (!getargs(args, "((ii)O)", &h, &v, &bp)) {
687 err_clear();
688 if (!getargs(args, "((ii)OO)", &h, &v, &bp, &mask))
689 return NULL;
690 if (mask == None)
691 mask = NULL;
692 else if (!is_bitmapobject(mask)) {
693 err_badarg();
694 return NULL;
695 }
696 }
697 if (!is_bitmapobject(bp)) {
698 err_badarg();
699 return NULL;
700 }
701 if (((bitmapobject *)bp)->b_bitmap == NULL ||
702 mask != NULL && ((bitmapobject *)mask)->b_bitmap == NULL) {
703 err_setstr(StdwinError, "bitmap object already close");
704 return NULL;
705 }
706 if (mask == NULL)
707 wdrawbitmap(h, v, ((bitmapobject *)bp)->b_bitmap, ALLBITS);
708 else
709 wdrawbitmap(h, v,
710 ((bitmapobject *)bp)->b_bitmap,
711 ((bitmapobject *)bp)->b_bitmap);
712 INCREF(None);
713 return None;
714}
715
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000716static struct methodlist drawing_methods[] = {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000717 {"bitmap", drawing_bitmap},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000718 {"box", drawing_box},
719 {"circle", drawing_circle},
720 {"cliprect", drawing_cliprect},
Guido van Rossum3c284741991-11-27 14:54:54 +0000721 {"close", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722 {"elarc", drawing_elarc},
Guido van Rossum3c284741991-11-27 14:54:54 +0000723 {"enddrawing", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000725 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000726 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000727 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728 {"invert", drawing_invert},
729 {"line", drawing_line},
730 {"noclip", drawing_noclip},
731 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000732 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000733 {"shade", drawing_shade},
734 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000735 {"xorcircle", drawing_xorcircle},
736 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000737 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000738 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739
740 /* Text measuring methods: */
741 {"baseline", drawing_baseline},
742 {"lineheight", drawing_lineheight},
743 {"textbreak", drawing_textbreak},
744 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000745
746 /* Font setting methods: */
747 {"setfont", drawing_setfont},
748
749 /* Color methods: */
750 {"getbgcolor", drawing_getbgcolor},
751 {"getfgcolor", drawing_getfgcolor},
752 {"setbgcolor", drawing_setbgcolor},
753 {"setfgcolor", drawing_setfgcolor},
754
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000755 {NULL, NULL} /* sentinel */
756};
757
758static object *
Guido van Rossum77b46041992-01-14 18:41:24 +0000759drawing_getattr(dp, name)
760 drawingobject *dp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761 char *name;
762{
Guido van Rossum77b46041992-01-14 18:41:24 +0000763 if (dp->d_ref == NULL) {
764 err_setstr(StdwinError, "drawing object already closed");
765 return NULL;
766 }
767 return findmethod(drawing_methods, (object *)dp, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000768}
769
Guido van Rossum541c8c01991-05-05 20:13:41 +0000770typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000771 OB_HEAD_INIT(&Typetype)
772 0, /*ob_size*/
773 "drawing", /*tp_name*/
774 sizeof(drawingobject), /*tp_size*/
775 0, /*tp_itemsize*/
776 /* methods */
777 drawing_dealloc, /*tp_dealloc*/
778 0, /*tp_print*/
779 drawing_getattr, /*tp_getattr*/
780 0, /*tp_setattr*/
781 0, /*tp_compare*/
782 0, /*tp_repr*/
783};
784
785
786/* Text(edit) objects */
787
788typedef struct {
789 OB_HEAD
790 TEXTEDIT *t_text;
791 windowobject *t_ref;
792 object *t_attr; /* Attributes dictionary */
793} textobject;
794
795extern typeobject Texttype; /* Really static, forward */
796
797static textobject *
798newtextobject(wp, left, top, right, bottom)
799 windowobject *wp;
800 int left, top, right, bottom;
801{
802 textobject *tp;
803 tp = NEWOBJ(textobject, &Texttype);
804 if (tp == NULL)
805 return NULL;
806 tp->t_attr = NULL;
807 INCREF(wp);
808 tp->t_ref = wp;
809 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
810 if (tp->t_text == NULL) {
811 DECREF(tp);
812 return (textobject *) err_nomem();
813 }
814 return tp;
815}
816
817/* Text(edit) methods */
818
819static void
820text_dealloc(tp)
821 textobject *tp;
822{
823 if (tp->t_text != NULL)
824 tefree(tp->t_text);
Guido van Rossum3c284741991-11-27 14:54:54 +0000825 XDECREF(tp->t_attr);
826 XDECREF(tp->t_ref);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000827 DEL(tp);
828}
829
830static object *
Guido van Rossum3c284741991-11-27 14:54:54 +0000831text_close(tp, args)
832 textobject *tp;
833 object *args;
834{
835 if (tp->t_text != NULL) {
836 tefree(tp->t_text);
837 tp->t_text = NULL;
838 }
839 if (tp->t_attr != NULL) {
840 DECREF(tp->t_attr);
841 tp->t_attr = NULL;
842 }
843 if (tp->t_ref != NULL) {
844 DECREF(tp->t_ref);
845 tp->t_ref = NULL;
846 }
847 INCREF(None);
848 return None;
849}
850
851static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852text_arrow(self, args)
853 textobject *self;
854 object *args;
855{
856 int code;
857 if (!getintarg(args, &code))
858 return NULL;
859 tearrow(self->t_text, code);
860 INCREF(None);
861 return None;
862}
863
864static object *
865text_draw(self, args)
866 textobject *self;
867 object *args;
868{
869 register TEXTEDIT *tp = self->t_text;
870 int a[4];
871 int left, top, right, bottom;
872 if (!getrectarg(args, a))
873 return NULL;
874 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000875 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000876 return NULL;
877 }
878 /* Clip to text area and ignore if area is empty */
879 left = tegetleft(tp);
880 top = tegettop(tp);
881 right = tegetright(tp);
882 bottom = tegetbottom(tp);
883 if (a[0] < left) a[0] = left;
884 if (a[1] < top) a[1] = top;
885 if (a[2] > right) a[2] = right;
886 if (a[3] > bottom) a[3] = bottom;
887 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889 tedrawnew(tp, a[0], a[1], a[2], a[3]);
890 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000891 }
892 INCREF(None);
893 return None;
894}
895
896static object *
897text_event(self, args)
898 textobject *self;
899 object *args;
900{
901 register TEXTEDIT *tp = self->t_text;
902 EVENT e;
903 if (!geteventarg(args, &e))
904 return NULL;
905 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000906 /* Cheat at the margins */
907 int width, height;
908 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000909 if (e.u.where.h < 0 && tegetleft(tp) == 0)
910 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000911 else if (e.u.where.h > width && tegetright(tp) == width)
912 e.u.where.h = width;
913 if (e.u.where.v < 0 && tegettop(tp) == 0)
914 e.u.where.v = 0;
915 else if (e.u.where.v > height && tegetright(tp) == height)
916 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000917 }
918 return newintobject((long) teevent(tp, &e));
919}
920
921static object *
922text_getfocus(self, args)
923 textobject *self;
924 object *args;
925{
926 if (!getnoarg(args))
927 return NULL;
928 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
929}
930
931static object *
932text_getfocustext(self, args)
933 textobject *self;
934 object *args;
935{
936 int f1, f2;
937 char *text;
938 if (!getnoarg(args))
939 return NULL;
940 f1 = tegetfoc1(self->t_text);
941 f2 = tegetfoc2(self->t_text);
942 text = tegettext(self->t_text);
943 return newsizedstringobject(text + f1, f2-f1);
944}
945
946static object *
947text_getrect(self, args)
948 textobject *self;
949 object *args;
950{
951 if (!getnoarg(args))
952 return NULL;
953 return makerect(tegetleft(self->t_text),
954 tegettop(self->t_text),
955 tegetright(self->t_text),
956 tegetbottom(self->t_text));
957}
958
959static object *
960text_gettext(self, args)
961 textobject *self;
962 object *args;
963{
964 if (!getnoarg(args))
965 return NULL;
966 return newsizedstringobject(tegettext(self->t_text),
967 tegetlen(self->t_text));
968}
969
970static object *
971text_move(self, args)
972 textobject *self;
973 object *args;
974{
975 int a[4];
976 if (!getrectarg(args, a))
977 return NULL;
978 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
979 INCREF(None);
980 return None;
981}
982
983static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000984text_replace(self, args)
985 textobject *self;
986 object *args;
987{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000988 char *text;
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000989 if (!getstrarg(args, &text))
990 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000991 tereplace(self->t_text, text);
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000992 INCREF(None);
993 return None;
994}
995
996static object *
997text_setactive(self, args)
998 textobject *self;
999 object *args;
1000{
1001 int flag;
1002 if (!getintarg(args, &flag))
1003 return NULL;
1004 tesetactive(self->t_text, flag);
1005 INCREF(None);
1006 return None;
1007}
1008
1009static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001010text_setfocus(self, args)
1011 textobject *self;
1012 object *args;
1013{
1014 int a[2];
1015 if (!getpointarg(args, a))
1016 return NULL;
1017 tesetfocus(self->t_text, a[0], a[1]);
1018 INCREF(None);
1019 return None;
1020}
1021
1022static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001023text_settext(self, args)
1024 textobject *self;
1025 object *args;
1026{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001027 char *text;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001028 char *buf;
1029 int size;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001030 if (!getargs(args, "s#", &text, &size))
Guido van Rossum541c8c01991-05-05 20:13:41 +00001031 return NULL;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001032 if ((buf = NEW(char, size)) == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001033 return err_nomem();
Guido van Rossum541c8c01991-05-05 20:13:41 +00001034 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001035 memcpy(buf, text, size);
Guido van Rossum541c8c01991-05-05 20:13:41 +00001036 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1037 INCREF(None);
1038 return None;
1039}
1040
1041static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001042text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001043 textobject *self;
1044 object *args;
1045{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001046 int a[4];
1047 if (args == None)
1048 tenoview(self->t_text);
1049 else {
1050 if (!getrectarg(args, a))
1051 return NULL;
1052 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1053 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 INCREF(None);
1055 return None;
1056}
1057
1058static struct methodlist text_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001059 {"arrow", text_arrow},
1060 {"close", text_close},
1061 {"draw", text_draw},
1062 {"event", text_event},
1063 {"getfocus", text_getfocus},
Guido van Rossum77b46041992-01-14 18:41:24 +00001064 {"getfocustext",text_getfocustext},
Guido van Rossum3c284741991-11-27 14:54:54 +00001065 {"getrect", text_getrect},
1066 {"gettext", text_gettext},
Guido van Rossum77b46041992-01-14 18:41:24 +00001067 {"move", text_move},
Guido van Rossum3c284741991-11-27 14:54:54 +00001068 {"replace", text_replace},
1069 {"setactive", text_setactive},
1070 {"setfocus", text_setfocus},
1071 {"settext", text_settext},
1072 {"setview", text_setview},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001073 {NULL, NULL} /* sentinel */
1074};
1075
1076static object *
1077text_getattr(tp, name)
1078 textobject *tp;
1079 char *name;
1080{
Guido van Rossum85f50761991-10-20 20:22:50 +00001081 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001082 if (tp->t_ref == NULL) {
1083 err_setstr(StdwinError, "text object already closed");
1084 return NULL;
1085 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001086 if (strcmp(name, "__dict__") == 0) {
1087 v = tp->t_attr;
1088 if (v == NULL)
1089 v = None;
1090 }
1091 else if (tp->t_attr != NULL) {
1092 v = dictlookup(tp->t_attr, name);
1093 }
1094 if (v != NULL) {
1095 INCREF(v);
1096 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001097 }
1098 return findmethod(text_methods, (object *)tp, name);
1099}
1100
1101static int
1102text_setattr(tp, name, v)
1103 textobject *tp;
1104 char *name;
1105 object *v;
1106{
1107 if (tp->t_attr == NULL) {
1108 tp->t_attr = newdictobject();
1109 if (tp->t_attr == NULL)
1110 return -1;
1111 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001112 if (v == NULL) {
1113 int rv = dictremove(tp->t_attr, name);
1114 if (rv < 0)
1115 err_setstr(AttributeError,
1116 "delete non-existing text object attribute");
1117 return rv;
1118 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 else
1120 return dictinsert(tp->t_attr, name, v);
1121}
1122
Guido van Rossum541c8c01991-05-05 20:13:41 +00001123typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124 OB_HEAD_INIT(&Typetype)
1125 0, /*ob_size*/
1126 "textedit", /*tp_name*/
1127 sizeof(textobject), /*tp_size*/
1128 0, /*tp_itemsize*/
1129 /* methods */
1130 text_dealloc, /*tp_dealloc*/
1131 0, /*tp_print*/
1132 text_getattr, /*tp_getattr*/
1133 text_setattr, /*tp_setattr*/
1134 0, /*tp_compare*/
1135 0, /*tp_repr*/
1136};
1137
1138
1139/* Menu objects */
1140
Guido van Rossum2d14e211991-02-19 12:26:49 +00001141#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001142#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001143static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001144
Guido van Rossumfc58e581992-01-27 16:45:55 +00001145static menuobject *newmenuobject PROTO((char *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146static menuobject *
1147newmenuobject(title)
Guido van Rossumfc58e581992-01-27 16:45:55 +00001148 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001149{
1150 int id;
1151 MENU *menu;
1152 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001153 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001154 if (menulist[id] == NULL)
1155 break;
1156 }
Guido van Rossum27201061991-04-16 08:43:03 +00001157 if (id >= MAXNMENU) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001158 err_setstr(StdwinError, "creating too many menus");
Guido van Rossum27201061991-04-16 08:43:03 +00001159 return NULL;
1160 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001161 menu = wmenucreate(id + IDOFFSET, title);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162 if (menu == NULL)
1163 return (menuobject *) err_nomem();
1164 mp = NEWOBJ(menuobject, &Menutype);
1165 if (mp != NULL) {
1166 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001167 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168 mp->m_attr = NULL;
1169 menulist[id] = mp;
1170 }
1171 else
1172 wmenudelete(menu);
1173 return mp;
1174}
1175
1176/* Menu methods */
1177
1178static void
1179menu_dealloc(mp)
1180 menuobject *mp;
1181{
1182
Guido van Rossum2d14e211991-02-19 12:26:49 +00001183 int id = mp->m_id - IDOFFSET;
1184 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 menulist[id] = NULL;
1186 }
Guido van Rossum77b46041992-01-14 18:41:24 +00001187 if (mp->m_menu != NULL)
1188 wmenudelete(mp->m_menu);
1189 XDECREF(mp->m_attr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001190 DEL(mp);
1191}
1192
1193static object *
Guido van Rossum77b46041992-01-14 18:41:24 +00001194menu_close(mp, args)
1195 menuobject *mp;
1196 object *args;
1197{
1198 int id = mp->m_id - IDOFFSET;
1199 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1200 menulist[id] = NULL;
1201 }
1202 mp->m_id = -1;
1203 if (mp->m_menu != NULL)
1204 wmenudelete(mp->m_menu);
1205 mp->m_menu = NULL;
1206 XDECREF(mp->m_attr);
1207 mp->m_attr = NULL;
1208 INCREF(None);
1209 return None;
1210}
1211
1212static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213menu_additem(self, args)
1214 menuobject *self;
1215 object *args;
1216{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001217 char *text;
1218 int shortcut = -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219 if (is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +00001220 char c;
1221 if (!getargs(args, "(sc)", &text, &c))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001223 shortcut = c;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001225 else if (!getstrarg(args, &text))
1226 return NULL;
1227 wmenuadditem(self->m_menu, text, shortcut);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228 INCREF(None);
1229 return None;
1230}
1231
1232static object *
1233menu_setitem(self, args)
1234 menuobject *self;
1235 object *args;
1236{
1237 int index;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001238 char *text;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001239 if (!getintstrarg(args, &index, &text))
1240 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001241 wmenusetitem(self->m_menu, index, text);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001242 INCREF(None);
1243 return None;
1244}
1245
1246static object *
1247menu_enable(self, args)
1248 menuobject *self;
1249 object *args;
1250{
1251 int index;
1252 int flag;
1253 if (!getintintarg(args, &index, &flag))
1254 return NULL;
1255 wmenuenable(self->m_menu, index, flag);
1256 INCREF(None);
1257 return None;
1258}
1259
1260static object *
1261menu_check(self, args)
1262 menuobject *self;
1263 object *args;
1264{
1265 int index;
1266 int flag;
1267 if (!getintintarg(args, &index, &flag))
1268 return NULL;
1269 wmenucheck(self->m_menu, index, flag);
1270 INCREF(None);
1271 return None;
1272}
1273
1274static struct methodlist menu_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001275 {"additem", menu_additem},
1276 {"setitem", menu_setitem},
1277 {"enable", menu_enable},
1278 {"check", menu_check},
Guido van Rossum77b46041992-01-14 18:41:24 +00001279 {"close", menu_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280 {NULL, NULL} /* sentinel */
1281};
1282
1283static object *
1284menu_getattr(mp, name)
1285 menuobject *mp;
1286 char *name;
1287{
Guido van Rossum85f50761991-10-20 20:22:50 +00001288 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001289 if (mp->m_menu == NULL) {
1290 err_setstr(StdwinError, "menu object already closed");
1291 return NULL;
1292 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001293 if (strcmp(name, "__dict__") == 0) {
1294 v = mp->m_attr;
1295 if (v == NULL)
1296 v = None;
1297 }
1298 else if (mp->m_attr != NULL) {
1299 v = dictlookup(mp->m_attr, name);
1300 }
1301 if (v != NULL) {
1302 INCREF(v);
1303 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304 }
1305 return findmethod(menu_methods, (object *)mp, name);
1306}
1307
1308static int
1309menu_setattr(mp, name, v)
1310 menuobject *mp;
1311 char *name;
1312 object *v;
1313{
1314 if (mp->m_attr == NULL) {
1315 mp->m_attr = newdictobject();
1316 if (mp->m_attr == NULL)
1317 return -1;
1318 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001319 if (v == NULL) {
1320 int rv = dictremove(mp->m_attr, name);
1321 if (rv < 0)
1322 err_setstr(AttributeError,
1323 "delete non-existing menu object attribute");
1324 return rv;
1325 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326 else
1327 return dictinsert(mp->m_attr, name, v);
1328}
1329
Guido van Rossum541c8c01991-05-05 20:13:41 +00001330typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331 OB_HEAD_INIT(&Typetype)
1332 0, /*ob_size*/
1333 "menu", /*tp_name*/
1334 sizeof(menuobject), /*tp_size*/
1335 0, /*tp_itemsize*/
1336 /* methods */
1337 menu_dealloc, /*tp_dealloc*/
1338 0, /*tp_print*/
1339 menu_getattr, /*tp_getattr*/
1340 menu_setattr, /*tp_setattr*/
1341 0, /*tp_compare*/
1342 0, /*tp_repr*/
1343};
1344
1345
Guido van Rossumbf80e541993-02-08 15:49:17 +00001346/* Bitmaps objects */
1347
1348static bitmapobject *newbitmapobject PROTO((int, int));
1349static bitmapobject *
1350newbitmapobject(width, height)
1351 int width, height;
1352{
1353 BITMAP *bitmap;
1354 bitmapobject *bp;
1355 bitmap = wnewbitmap(width, height);
1356 if (bitmap == NULL)
1357 return (bitmapobject *) err_nomem();
1358 bp = NEWOBJ(bitmapobject, &Bitmaptype);
1359 if (bp != NULL) {
1360 bp->b_bitmap = bitmap;
1361 bp->b_attr = NULL;
1362 }
1363 else
1364 wfreebitmap(bitmap);
1365 return bp;
1366}
1367
1368/* Bitmap methods */
1369
1370static void
1371bitmap_dealloc(bp)
1372 bitmapobject *bp;
1373{
1374 if (bp->b_bitmap != NULL)
1375 wfreebitmap(bp->b_bitmap);
1376 XDECREF(bp->b_attr);
1377 DEL(bp);
1378}
1379
1380static object *
1381bitmap_close(bp, args)
1382 bitmapobject *bp;
1383 object *args;
1384{
1385 if (bp->b_bitmap != NULL)
1386 wfreebitmap(bp->b_bitmap);
1387 bp->b_bitmap = NULL;
1388 XDECREF(bp->b_attr);
1389 bp->b_attr = NULL;
1390 INCREF(None);
1391 return None;
1392}
1393
1394static object *
1395bitmap_setbit(self, args)
1396 bitmapobject *self;
1397 object *args;
1398{
1399 int a[3];
1400 if (!getpointintarg(args, a))
1401 return NULL;
1402 wsetbit(self->b_bitmap, a[0], a[1], a[2]);
1403 INCREF(None);
1404 return None;
1405}
1406
1407static object *
1408bitmap_getbit(self, args)
1409 bitmapobject *self;
1410 object *args;
1411{
1412 int a[2];
1413 if (!getpointarg(args, a))
1414 return NULL;
1415 return newintobject((long) wgetbit(self->b_bitmap, a[0], a[1]));
1416}
1417
1418static object *
1419bitmap_getsize(self, args)
1420 bitmapobject *self;
1421 object *args;
1422{
1423 int width, height;
1424 if (!getnoarg(args))
1425 return NULL;
1426 wgetbitmapsize(self->b_bitmap, &width, &height);
1427 return mkvalue("(ii)", width, height);
1428}
1429
1430static struct methodlist bitmap_methods[] = {
1431 {"close", bitmap_close},
1432 {"getsize", bitmap_getsize},
1433 {"getbit", bitmap_getbit},
1434 {"setbit", bitmap_setbit},
1435 {NULL, NULL} /* sentinel */
1436};
1437
1438static object *
1439bitmap_getattr(bp, name)
1440 bitmapobject *bp;
1441 char *name;
1442{
1443 object *v = NULL;
1444 if (bp->b_bitmap == NULL) {
1445 err_setstr(StdwinError, "bitmap object already closed");
1446 return NULL;
1447 }
1448 if (strcmp(name, "__dict__") == 0) {
1449 v = bp->b_attr;
1450 if (v == NULL)
1451 v = None;
1452 }
1453 else if (bp->b_attr != NULL) {
1454 v = dictlookup(bp->b_attr, name);
1455 }
1456 if (v != NULL) {
1457 INCREF(v);
1458 return v;
1459 }
1460 return findmethod(bitmap_methods, (object *)bp, name);
1461}
1462
1463static int
1464bitmap_setattr(bp, name, v)
1465 bitmapobject *bp;
1466 char *name;
1467 object *v;
1468{
1469 if (bp->b_attr == NULL) {
1470 bp->b_attr = newdictobject();
1471 if (bp->b_attr == NULL)
1472 return -1;
1473 }
1474 if (v == NULL) {
1475 int rv = dictremove(bp->b_attr, name);
1476 if (rv < 0)
1477 err_setstr(AttributeError,
1478 "delete non-existing bitmap object attribute");
1479 return rv;
1480 }
1481 else
1482 return dictinsert(bp->b_attr, name, v);
1483}
1484
1485typeobject Bitmaptype = {
1486 OB_HEAD_INIT(&Typetype)
1487 0, /*ob_size*/
1488 "bitmap", /*tp_name*/
1489 sizeof(bitmapobject), /*tp_size*/
1490 0, /*tp_itemsize*/
1491 /* methods */
1492 bitmap_dealloc, /*tp_dealloc*/
1493 0, /*tp_print*/
1494 bitmap_getattr, /*tp_getattr*/
1495 bitmap_setattr, /*tp_setattr*/
1496 0, /*tp_compare*/
1497 0, /*tp_repr*/
1498};
1499
1500
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001501/* Windows */
1502
1503#define MAXNWIN 50
1504static windowobject *windowlist[MAXNWIN];
1505
1506/* Window methods */
1507
1508static void
1509window_dealloc(wp)
1510 windowobject *wp;
1511{
1512 if (wp->w_win != NULL) {
1513 int tag = wgettag(wp->w_win);
1514 if (tag >= 0 && tag < MAXNWIN)
1515 windowlist[tag] = NULL;
1516 else
1517 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1518 tag);
1519 wclose(wp->w_win);
1520 }
1521 DECREF(wp->w_title);
1522 if (wp->w_attr != NULL)
1523 DECREF(wp->w_attr);
1524 free((char *)wp);
1525}
1526
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001527static object *
Guido van Rossum3c284741991-11-27 14:54:54 +00001528window_close(wp, args)
1529 windowobject *wp;
1530 object *args;
1531{
1532 if (wp->w_win != NULL) {
1533 int tag = wgettag(wp->w_win);
1534 if (tag >= 0 && tag < MAXNWIN)
1535 windowlist[tag] = NULL;
1536 wclose(wp->w_win);
1537 wp->w_win = NULL;
1538 }
1539 INCREF(None);
1540 return None;
1541}
1542
1543static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001544window_begindrawing(wp, args)
1545 windowobject *wp;
1546 object *args;
1547{
1548 drawingobject *dp;
1549 if (!getnoarg(args))
1550 return NULL;
1551 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001552 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001553 return NULL;
1554 }
1555 dp = NEWOBJ(drawingobject, &Drawingtype);
1556 if (dp == NULL)
1557 return NULL;
1558 Drawing = dp;
1559 INCREF(wp);
1560 dp->d_ref = wp;
1561 wbegindrawing(wp->w_win);
1562 return (object *)dp;
1563}
1564
1565static object *
1566window_change(wp, args)
1567 windowobject *wp;
1568 object *args;
1569{
1570 int a[4];
1571 if (!getrectarg(args, a))
1572 return NULL;
1573 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1574 INCREF(None);
1575 return None;
1576}
1577
1578static object *
1579window_gettitle(wp, args)
1580 windowobject *wp;
1581 object *args;
1582{
1583 if (!getnoarg(args))
1584 return NULL;
1585 INCREF(wp->w_title);
1586 return wp->w_title;
1587}
1588
1589static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001590window_getwinpos(wp, args)
1591 windowobject *wp;
1592 object *args;
1593{
1594 int h, v;
1595 if (!getnoarg(args))
1596 return NULL;
1597 wgetwinpos(wp->w_win, &h, &v);
1598 return makepoint(h, v);
1599}
1600
1601static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602window_getwinsize(wp, args)
1603 windowobject *wp;
1604 object *args;
1605{
1606 int width, height;
1607 if (!getnoarg(args))
1608 return NULL;
1609 wgetwinsize(wp->w_win, &width, &height);
1610 return makepoint(width, height);
1611}
1612
1613static object *
Guido van Rossumbf80e541993-02-08 15:49:17 +00001614window_setwinpos(wp, args)
1615 windowobject *wp;
1616 object *args;
1617{
1618 int a[2];
1619 if (!getpointarg(args, a))
1620 return NULL;
1621 wsetwinpos(wp->w_win, a[0], a[1]);
1622 INCREF(None);
1623 return None;
1624}
1625
1626static object *
1627window_setwinsize(wp, args)
1628 windowobject *wp;
1629 object *args;
1630{
1631 int a[2];
1632 if (!getpointarg(args, a))
1633 return NULL;
1634 wsetwinsize(wp->w_win, a[0], a[1]);
1635 INCREF(None);
1636 return None;
1637}
1638
1639static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001640window_getdocsize(wp, args)
1641 windowobject *wp;
1642 object *args;
1643{
1644 int width, height;
1645 if (!getnoarg(args))
1646 return NULL;
1647 wgetdocsize(wp->w_win, &width, &height);
1648 return makepoint(width, height);
1649}
1650
1651static object *
1652window_getorigin(wp, args)
1653 windowobject *wp;
1654 object *args;
1655{
1656 int width, height;
1657 if (!getnoarg(args))
1658 return NULL;
1659 wgetorigin(wp->w_win, &width, &height);
1660 return makepoint(width, height);
1661}
1662
1663static object *
1664window_scroll(wp, args)
1665 windowobject *wp;
1666 object *args;
1667{
1668 int a[6];
1669 if (!getrectpointarg(args, a))
1670 return NULL;
1671 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1672 INCREF(None);
1673 return None;
1674}
1675
1676static object *
1677window_setdocsize(wp, args)
1678 windowobject *wp;
1679 object *args;
1680{
1681 int a[2];
1682 if (!getpointarg(args, a))
1683 return NULL;
1684 wsetdocsize(wp->w_win, a[0], a[1]);
1685 INCREF(None);
1686 return None;
1687}
1688
1689static object *
1690window_setorigin(wp, args)
1691 windowobject *wp;
1692 object *args;
1693{
1694 int a[2];
1695 if (!getpointarg(args, a))
1696 return NULL;
1697 wsetorigin(wp->w_win, a[0], a[1]);
1698 INCREF(None);
1699 return None;
1700}
1701
1702static object *
1703window_settitle(wp, args)
1704 windowobject *wp;
1705 object *args;
1706{
1707 object *title;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001708 if (!getStrarg(args, &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709 return NULL;
1710 DECREF(wp->w_title);
1711 INCREF(title);
1712 wp->w_title = title;
1713 wsettitle(wp->w_win, getstringvalue(title));
1714 INCREF(None);
1715 return None;
1716}
1717
1718static object *
1719window_show(wp, args)
1720 windowobject *wp;
1721 object *args;
1722{
1723 int a[4];
1724 if (!getrectarg(args, a))
1725 return NULL;
1726 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1727 INCREF(None);
1728 return None;
1729}
1730
1731static object *
1732window_settimer(wp, args)
1733 windowobject *wp;
1734 object *args;
1735{
1736 int a;
1737 if (!getintarg(args, &a))
1738 return NULL;
1739 wsettimer(wp->w_win, a);
1740 INCREF(None);
1741 return None;
1742}
1743
1744static object *
1745window_menucreate(self, args)
1746 windowobject *self;
1747 object *args;
1748{
1749 menuobject *mp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001750 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001751 if (!getstrarg(args, &title))
1752 return NULL;
1753 wmenusetdeflocal(1);
1754 mp = newmenuobject(title);
1755 if (mp == NULL)
1756 return NULL;
1757 wmenuattach(self->w_win, mp->m_menu);
1758 return (object *)mp;
1759}
1760
1761static object *
1762window_textcreate(self, args)
1763 windowobject *self;
1764 object *args;
1765{
1766 textobject *tp;
1767 int a[4];
1768 if (!getrectarg(args, a))
1769 return NULL;
1770 return (object *)
1771 newtextobject(self, a[0], a[1], a[2], a[3]);
1772}
1773
Guido van Rossum5b10f451990-10-30 16:01:48 +00001774static object *
1775window_setselection(self, args)
1776 windowobject *self;
1777 object *args;
1778{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001779 int sel, size, ok;
1780 char *text;
1781 if (!getargs(args, "(is#)", &sel, &text, &size))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001782 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001783 ok = wsetselection(self->w_win, sel, text, size);
Guido van Rossum5b10f451990-10-30 16:01:48 +00001784 return newintobject(ok);
1785}
1786
1787static object *
1788window_setwincursor(self, args)
1789 windowobject *self;
1790 object *args;
1791{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001792 char *name;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001793 CURSOR *c;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001794 if (!getargs(args, "z", &name))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001795 return NULL;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001796 if (name == NULL)
1797 c = NULL;
1798 else {
1799 c = wfetchcursor(name);
1800 if (c == NULL) {
1801 err_setstr(StdwinError, "no such cursor");
1802 return NULL;
1803 }
Guido van Rossum5b10f451990-10-30 16:01:48 +00001804 }
1805 wsetwincursor(self->w_win, c);
1806 INCREF(None);
1807 return None;
1808}
1809
Guido van Rossumfc58e581992-01-27 16:45:55 +00001810static object *
1811window_setactive(self, args)
1812 windowobject *self;
1813 object *args;
1814{
1815 if (!getnoarg(args))
1816 return NULL;
1817 wsetactive(self->w_win);
1818 INCREF(None);
1819 return None;
1820}
1821
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001822#ifdef CWI_HACKS
1823static object *
1824window_getxwindowid(self, args)
1825 windowobject *self;
1826 object *args;
1827{
1828 long wid = wgetxwindowid(self->w_win);
1829 return newintobject(wid);
1830}
1831#endif
1832
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833static struct methodlist window_methods[] = {
1834 {"begindrawing",window_begindrawing},
1835 {"change", window_change},
Guido van Rossum3c284741991-11-27 14:54:54 +00001836 {"close", window_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001837 {"getdocsize", window_getdocsize},
1838 {"getorigin", window_getorigin},
1839 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001840 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001841 {"getwinsize", window_getwinsize},
1842 {"menucreate", window_menucreate},
1843 {"scroll", window_scroll},
Guido van Rossumb7e51601992-01-26 18:13:18 +00001844 {"setactive", window_setactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845 {"setdocsize", window_setdocsize},
1846 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001847 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001848 {"settimer", window_settimer},
1849 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001850 {"setwincursor",window_setwincursor},
Guido van Rossumbf80e541993-02-08 15:49:17 +00001851 {"setwinpos", window_setwinpos},
1852 {"setwinsize", window_setwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001853 {"show", window_show},
1854 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001855#ifdef CWI_HACKS
1856 {"getxwindowid",window_getxwindowid},
1857#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001858 {NULL, NULL} /* sentinel */
1859};
1860
1861static object *
1862window_getattr(wp, name)
1863 windowobject *wp;
1864 char *name;
1865{
Guido van Rossum85f50761991-10-20 20:22:50 +00001866 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001867 if (wp->w_win == NULL) {
1868 err_setstr(StdwinError, "window already closed");
1869 return NULL;
1870 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001871 if (strcmp(name, "__dict__") == 0) {
1872 v = wp->w_attr;
1873 if (v == NULL)
1874 v = None;
1875 }
1876 else if (wp->w_attr != NULL) {
1877 v = dictlookup(wp->w_attr, name);
1878 }
1879 if (v != NULL) {
1880 INCREF(v);
1881 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001882 }
1883 return findmethod(window_methods, (object *)wp, name);
1884}
1885
1886static int
1887window_setattr(wp, name, v)
1888 windowobject *wp;
1889 char *name;
1890 object *v;
1891{
1892 if (wp->w_attr == NULL) {
1893 wp->w_attr = newdictobject();
1894 if (wp->w_attr == NULL)
1895 return -1;
1896 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001897 if (v == NULL) {
1898 int rv = dictremove(wp->w_attr, name);
1899 if (rv < 0)
1900 err_setstr(AttributeError,
1901 "delete non-existing menu object attribute");
1902 return rv;
1903 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001904 else
1905 return dictinsert(wp->w_attr, name, v);
1906}
1907
Guido van Rossum541c8c01991-05-05 20:13:41 +00001908typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001909 OB_HEAD_INIT(&Typetype)
1910 0, /*ob_size*/
1911 "window", /*tp_name*/
1912 sizeof(windowobject), /*tp_size*/
1913 0, /*tp_itemsize*/
1914 /* methods */
1915 window_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001916 0, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001917 window_getattr, /*tp_getattr*/
1918 window_setattr, /*tp_setattr*/
1919 0, /*tp_compare*/
1920 0, /*tp_repr*/
1921};
1922
1923/* Stdwin methods */
1924
1925static object *
1926stdwin_open(sw, args)
1927 object *sw;
1928 object *args;
1929{
1930 int tag;
1931 object *title;
1932 windowobject *wp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001933 if (!getStrarg(args, &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001934 return NULL;
1935 for (tag = 0; tag < MAXNWIN; tag++) {
1936 if (windowlist[tag] == NULL)
1937 break;
1938 }
Guido van Rossum27201061991-04-16 08:43:03 +00001939 if (tag >= MAXNWIN) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001940 err_setstr(StdwinError, "creating too many windows");
Guido van Rossum27201061991-04-16 08:43:03 +00001941 return NULL;
1942 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001943 wp = NEWOBJ(windowobject, &Windowtype);
1944 if (wp == NULL)
1945 return NULL;
1946 INCREF(title);
1947 wp->w_title = title;
1948 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1949 wp->w_attr = NULL;
1950 if (wp->w_win == NULL) {
1951 DECREF(wp);
1952 return NULL;
1953 }
1954 windowlist[tag] = wp;
1955 wsettag(wp->w_win, tag);
1956 return (object *)wp;
1957}
1958
1959static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001960window2object(win)
1961 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001962{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001963 object *w;
1964 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001965 w = None;
1966 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001967 int tag = wgettag(win);
1968 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1969 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001970 w = None;
1971 else
1972 w = (object *)windowlist[tag];
1973 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001975 return w;
1976}
1977
1978static object *
1979stdwin_get_poll_event(poll, args)
1980 int poll;
1981 object *args;
1982{
1983 EVENT e;
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001984 object *u, *v, *w;
Guido van Rossum246b9d81991-06-03 10:55:14 +00001985 if (!getnoarg(args))
1986 return NULL;
1987 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001988 err_setstr(StdwinError, "cannot getevent() while drawing");
Guido van Rossum246b9d81991-06-03 10:55:14 +00001989 return NULL;
1990 }
1991 again:
Guido van Rossumff4949e1992-08-05 19:58:53 +00001992 BGN_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00001993 if (poll) {
1994 if (!wpollevent(&e)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +00001995 RET_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00001996 INCREF(None);
1997 return None;
1998 }
1999 }
2000 else
2001 wgetevent(&e);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002002 END_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002003 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
2004 /* Turn keyboard interrupts into exceptions */
2005 err_set(KeyboardInterrupt);
2006 return NULL;
2007 }
2008 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
2009 /* Turn WC_CLOSE commands into WE_CLOSE events */
2010 e.type = WE_CLOSE;
2011 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002012 v = window2object(e.window);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002013 switch (e.type) {
2014 case WE_CHAR:
2015 {
2016 char c[1];
2017 c[0] = e.u.character;
2018 w = newsizedstringobject(c, 1);
2019 }
2020 break;
2021 case WE_COMMAND:
2022 w = newintobject((long)e.u.command);
2023 break;
2024 case WE_DRAW:
2025 w = makerect(e.u.area.left, e.u.area.top,
2026 e.u.area.right, e.u.area.bottom);
2027 break;
2028 case WE_MOUSE_DOWN:
2029 case WE_MOUSE_MOVE:
2030 case WE_MOUSE_UP:
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002031 w = mkvalue("((ii)iii)",
2032 e.u.where.h, e.u.where.v,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002033 e.u.where.clicks,
2034 e.u.where.button,
2035 e.u.where.mask);
2036 break;
2037 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00002038 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
2039 menulist[e.u.m.id - IDOFFSET] != NULL)
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002040 w = mkvalue("(Oi)",
2041 menulist[e.u.m.id - IDOFFSET], e.u.m.item);
Guido van Rossum246b9d81991-06-03 10:55:14 +00002042 else {
2043 /* Ghost menu event.
2044 Can occur only on the Mac if another part
2045 of the aplication has installed a menu;
2046 like the THINK C console library. */
2047 DECREF(v);
2048 goto again;
2049 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002050 break;
Guido van Rossum3ee199e1992-06-30 12:48:26 +00002051 case WE_KEY:
2052 w = mkvalue("(ii)", e.u.key.code, e.u.key.mask);
2053 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002054 case WE_LOST_SEL:
2055 w = newintobject((long)e.u.sel);
2056 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057 default:
2058 w = None;
2059 INCREF(w);
2060 break;
2061 }
2062 if (w == NULL) {
2063 DECREF(v);
2064 return NULL;
2065 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002066 u = mkvalue("(iOO)", e.type, v, w);
2067 XDECREF(v);
2068 XDECREF(w);
2069 return u;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002070}
2071
2072static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002073stdwin_getevent(sw, args)
2074 object *sw;
2075 object *args;
2076{
2077 return stdwin_get_poll_event(0, args);
2078}
2079
2080static object *
2081stdwin_pollevent(sw, args)
2082 object *sw;
2083 object *args;
2084{
2085 return stdwin_get_poll_event(1, args);
2086}
2087
2088static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002089stdwin_setdefwinpos(sw, args)
2090 object *sw;
2091 object *args;
2092{
2093 int a[2];
2094 if (!getpointarg(args, a))
2095 return NULL;
2096 wsetdefwinpos(a[0], a[1]);
2097 INCREF(None);
2098 return None;
2099}
2100
2101static object *
2102stdwin_setdefwinsize(sw, args)
2103 object *sw;
2104 object *args;
2105{
2106 int a[2];
2107 if (!getpointarg(args, a))
2108 return NULL;
2109 wsetdefwinsize(a[0], a[1]);
2110 INCREF(None);
2111 return None;
2112}
2113
2114static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002115stdwin_setdefscrollbars(sw, args)
2116 object *sw;
2117 object *args;
2118{
2119 int a[2];
2120 if (!getpointarg(args, a))
2121 return NULL;
2122 wsetdefscrollbars(a[0], a[1]);
2123 INCREF(None);
2124 return None;
2125}
2126
2127static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002128stdwin_getdefwinpos(self, args)
2129 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002130 object *args;
2131{
2132 int h, v;
2133 if (!getnoarg(args))
2134 return NULL;
2135 wgetdefwinpos(&h, &v);
2136 return makepoint(h, v);
2137}
2138
2139static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002140stdwin_getdefwinsize(self, args)
2141 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002142 object *args;
2143{
2144 int width, height;
2145 if (!getnoarg(args))
2146 return NULL;
2147 wgetdefwinsize(&width, &height);
2148 return makepoint(width, height);
2149}
2150
2151static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002152stdwin_getdefscrollbars(self, args)
2153 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002154 object *args;
2155{
2156 int h, v;
2157 if (!getnoarg(args))
2158 return NULL;
2159 wgetdefscrollbars(&h, &v);
2160 return makepoint(h, v);
2161}
2162
2163static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002164stdwin_menucreate(self, args)
2165 object *self;
2166 object *args;
2167{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002168 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002169 if (!getstrarg(args, &title))
2170 return NULL;
2171 wmenusetdeflocal(0);
2172 return (object *)newmenuobject(title);
2173}
2174
2175static object *
2176stdwin_askfile(self, args)
2177 object *self;
2178 object *args;
2179{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002180 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002181 int new, ret;
2182 char buf[256];
2183 if (!getstrstrintarg(args, &prompt, &dflt, &new))
2184 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002185 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002186 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002187 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002188 ret = waskfile(prompt, buf, sizeof buf, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002189 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002190 if (!ret) {
2191 err_set(KeyboardInterrupt);
2192 return NULL;
2193 }
2194 return newstringobject(buf);
2195}
2196
2197static object *
2198stdwin_askync(self, args)
2199 object *self;
2200 object *args;
2201{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002202 char *prompt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002203 int new, ret;
2204 if (!getstrintarg(args, &prompt, &new))
2205 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002206 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002207 ret = waskync(prompt, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002208 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002209 if (ret < 0) {
2210 err_set(KeyboardInterrupt);
2211 return NULL;
2212 }
2213 return newintobject((long)ret);
2214}
2215
2216static object *
2217stdwin_askstr(self, args)
2218 object *self;
2219 object *args;
2220{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002221 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002222 int ret;
2223 char buf[256];
2224 if (!getstrstrarg(args, &prompt, &dflt))
2225 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002226 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002227 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002228 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002229 ret = waskstr(prompt, buf, sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002230 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002231 if (!ret) {
2232 err_set(KeyboardInterrupt);
2233 return NULL;
2234 }
2235 return newstringobject(buf);
2236}
2237
2238static object *
2239stdwin_message(self, args)
2240 object *self;
2241 object *args;
2242{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002243 char *msg;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002244 if (!getstrarg(args, &msg))
2245 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002246 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002247 wmessage(msg);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002248 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002249 INCREF(None);
2250 return None;
2251}
2252
2253static object *
2254stdwin_fleep(self, args)
2255 object *self;
2256 object *args;
2257{
2258 if (!getnoarg(args))
2259 return NULL;
2260 wfleep();
2261 INCREF(None);
2262 return None;
2263}
2264
2265static object *
2266stdwin_setcutbuffer(self, args)
2267 object *self;
2268 object *args;
2269{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002270 int i, size;
2271 char *str;
2272 if (!getargs(args, "(is#)", &i, &str, &size))
Guido van Rossum124967c1990-11-06 15:17:35 +00002273 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002274 wsetcutbuffer(i, str, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275 INCREF(None);
2276 return None;
2277}
2278
2279static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002280stdwin_getactive(self, args)
2281 object *self;
2282 object *args;
2283{
2284 return window2object(wgetactive());
2285}
2286
2287static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002288stdwin_getcutbuffer(self, args)
2289 object *self;
2290 object *args;
2291{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002292 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002293 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002294 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002295 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002296 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002297 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002298 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002299 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002300 len = 0;
2301 }
2302 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002303}
2304
Guido van Rossum5b10f451990-10-30 16:01:48 +00002305static object *
2306stdwin_rotatecutbuffers(self, args)
2307 object *self;
2308 object *args;
2309{
2310 int i;
2311 if (!getintarg(args, &i))
2312 return NULL;
2313 wrotatecutbuffers(i);
2314 INCREF(None);
2315 return None;
2316}
2317
2318static object *
2319stdwin_getselection(self, args)
2320 object *self;
2321 object *args;
2322{
2323 int sel;
2324 char *data;
2325 int len;
2326 if (!getintarg(args, &sel))
2327 return NULL;
2328 data = wgetselection(sel, &len);
2329 if (data == NULL) {
2330 data = "";
2331 len = 0;
2332 }
2333 return newsizedstringobject(data, len);
2334}
2335
2336static object *
2337stdwin_resetselection(self, args)
2338 object *self;
2339 object *args;
2340{
2341 int sel;
2342 if (!getintarg(args, &sel))
2343 return NULL;
2344 wresetselection(sel);
2345 INCREF(None);
2346 return None;
2347}
2348
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002349static object *
2350stdwin_fetchcolor(self, args)
2351 object *self;
2352 object *args;
2353{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002354 char *colorname;
Guido van Rossum34679b71993-01-26 13:33:44 +00002355 COLOR color;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002356 if (!getstrarg(args, &colorname))
2357 return NULL;
Guido van Rossum34679b71993-01-26 13:33:44 +00002358 color = wfetchcolor(colorname);
2359#ifdef BADCOLOR
2360 if (color == BADCOLOR) {
2361 err_setstr(StdwinError, "color name not found");
2362 return NULL;
2363 }
2364#endif
2365 return newintobject((long)color);
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002366}
2367
Guido van Rossum541c8c01991-05-05 20:13:41 +00002368static object *
2369stdwin_getscrsize(self, args)
2370 object *self;
2371 object *args;
2372{
2373 int width, height;
2374 if (!getnoarg(args))
2375 return NULL;
2376 wgetscrsize(&width, &height);
2377 return makepoint(width, height);
2378}
2379
2380static object *
2381stdwin_getscrmm(self, args)
2382 object *self;
2383 object *args;
2384{
2385 int width, height;
2386 if (!getnoarg(args))
2387 return NULL;
2388 wgetscrmm(&width, &height);
2389 return makepoint(width, height);
2390}
2391
Guido van Rossumed233a51992-06-23 09:07:03 +00002392#ifdef unix
2393static object *
2394stdwin_connectionnumber(self, args)
2395 object *self;
2396 object *args;
2397{
2398 if (!getnoarg(args))
2399 return NULL;
2400 return newintobject((long) wconnectionnumber());
2401}
2402#endif
2403
Guido van Rossumbf80e541993-02-08 15:49:17 +00002404static object *
2405stdwin_listfontnames(self, args)
2406 object *self;
2407 object *args;
2408{
2409 char *pattern;
2410 char **fontnames;
2411 int count;
2412 object *list;
2413 if (!getargs(args, "z", &pattern))
2414 return NULL;
2415 fontnames = wlistfontnames(pattern, &count);
2416 list = newlistobject(count);
2417 if (list != NULL) {
2418 int i;
2419 for (i = 0; i < count; i++) {
2420 object *v = newstringobject(fontnames[i]);
2421 if (v == NULL) {
2422 DECREF(list);
2423 list = NULL;
2424 break;
2425 }
2426 setlistitem(list, i, v);
2427 }
2428 }
2429 return list;
2430}
2431
2432static object *
2433stdwin_newbitmap(self, args)
2434 object *self;
2435 object *args;
2436{
2437 int width, height;
2438 bitmapobject *bp;
2439 if (!getargs(args, "(ii)", &width, &height))
2440 return NULL;
2441 return (object *)newbitmapobject(width, height);
2442}
2443
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002444static struct methodlist stdwin_methods[] = {
2445 {"askfile", stdwin_askfile},
2446 {"askstr", stdwin_askstr},
2447 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002448 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossumed233a51992-06-23 09:07:03 +00002449#ifdef unix
2450 {"fileno", stdwin_connectionnumber},
2451 {"connectionnumber", stdwin_connectionnumber},
2452#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002453 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002454 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002455 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002456 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002457 {"getdefwinpos", stdwin_getdefwinpos},
2458 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002459 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002460 {"getscrmm", stdwin_getscrmm},
2461 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002462 {"getselection", stdwin_getselection},
Guido van Rossumbf80e541993-02-08 15:49:17 +00002463 {"listfontnames", stdwin_listfontnames},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002464 {"menucreate", stdwin_menucreate},
2465 {"message", stdwin_message},
Guido van Rossumbf80e541993-02-08 15:49:17 +00002466 {"newbitmap", stdwin_newbitmap},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002468 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002469 {"resetselection", stdwin_resetselection},
2470 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002471 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002472 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473 {"setdefwinpos", stdwin_setdefwinpos},
2474 {"setdefwinsize", stdwin_setdefwinsize},
2475
2476 /* Text measuring methods borrow code from drawing objects: */
2477 {"baseline", drawing_baseline},
2478 {"lineheight", drawing_lineheight},
2479 {"textbreak", drawing_textbreak},
2480 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002481
2482 /* Same for font setting methods: */
2483 {"setfont", drawing_setfont},
2484
2485 /* Same for color setting/getting methods: */
2486 {"getbgcolor", drawing_getbgcolor},
2487 {"getfgcolor", drawing_getfgcolor},
2488 {"setbgcolor", drawing_setbgcolor},
2489 {"setfgcolor", drawing_setfgcolor},
2490
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002491 {NULL, NULL} /* sentinel */
2492};
2493
2494void
2495initstdwin()
2496{
Guido van Rossumbbf94341991-12-16 15:44:53 +00002497 object *m, *d;
2498 static int inited = 0;
2499
Guido van Rossum2d14e211991-02-19 12:26:49 +00002500 if (!inited) {
2501 winit();
2502 inited = 1;
2503 }
Guido van Rossumbbf94341991-12-16 15:44:53 +00002504 m = initmodule("stdwin", stdwin_methods);
2505 d = getmoduledict(m);
2506
2507 /* Initialize stdwin.error exception */
2508 StdwinError = newstringobject("stdwin.error");
2509 if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
2510 fatal("can't define stdwin.error");
Guido van Rossumff4949e1992-08-05 19:58:53 +00002511#ifdef USE_THREAD
2512 StdwinLock = allocate_lock();
2513 if (StdwinLock == NULL)
2514 fatal("can't allocate stdwin lock");
2515#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002516}