blob: 6e666a61b5622a0b7db21355415c449293067c5e [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 Rossum234f9421993-06-17 12:35:49 +000094#define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
95#define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
96 a, a+1, a+2, a+3, a+4, a+5)
97#define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
98#define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
99#define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
100#define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
101 a, a+1, a+2, a+3, a+4, a+5)
102
Guido van Rossumbbf94341991-12-16 15:44:53 +0000103static object *StdwinError; /* Exception stdwin.error */
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000104
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105/* Window and menu object types declared here because of forward references */
106
107typedef struct {
108 OB_HEAD
109 object *w_title;
110 WINDOW *w_win;
111 object *w_attr; /* Attributes dictionary */
112} windowobject;
113
114extern typeobject Windowtype; /* Really static, forward */
115
116#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
117
118typedef struct {
119 OB_HEAD
120 MENU *m_menu;
121 int m_id;
122 object *m_attr; /* Attributes dictionary */
123} menuobject;
124
125extern typeobject Menutype; /* Really static, forward */
126
127#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
128
Guido van Rossumbf80e541993-02-08 15:49:17 +0000129typedef struct {
130 OB_HEAD
131 BITMAP *b_bitmap;
132 object *b_attr; /* Attributes dictionary */
133} bitmapobject;
134
135extern typeobject Bitmaptype; /* Really static, forward */
136
137#define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
138
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139
140/* Strongly stdwin-specific argument handlers */
141
142static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143getmenudetail(v, ep)
144 object *v;
145 EVENT *ep;
146{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000147 menuobject *mp;
148 if (!getargs(v, "(Oi)", &mp, &ep->u.m.item))
149 return 0;
150 if (!is_menuobject(mp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000152 ep->u.m.id = mp->m_id;
153 return 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154}
155
156static int
157geteventarg(v, ep)
158 object *v;
159 EVENT *ep;
160{
161 object *wp, *detail;
162 int a[4];
Guido van Rossumfc58e581992-01-27 16:45:55 +0000163 if (!getargs(v, "(iOO)", &ep->type, &wp, &detail))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 return 0;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000165 if (is_windowobject(wp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 ep->window = ((windowobject *)wp) -> w_win;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000167 else if (wp == None)
168 ep->window = NULL;
169 else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000171 switch (ep->type) {
172 case WE_CHAR: {
173 char c;
174 if (!getargs(detail, "c", &c))
175 return 0;
176 ep->u.character = c;
177 return 1;
178 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179 case WE_COMMAND:
180 return getintarg(detail, &ep->u.command);
181 case WE_DRAW:
182 if (!getrectarg(detail, a))
183 return 0;
184 ep->u.area.left = a[0];
185 ep->u.area.top = a[1];
186 ep->u.area.right = a[2];
187 ep->u.area.bottom = a[3];
188 return 1;
189 case WE_MOUSE_DOWN:
190 case WE_MOUSE_UP:
191 case WE_MOUSE_MOVE:
Guido van Rossumfc58e581992-01-27 16:45:55 +0000192 return getargs(detail, "((ii)iii)",
193 &ep->u.where.h, &ep->u.where.v,
194 &ep->u.where.clicks,
195 &ep->u.where.button,
196 &ep->u.where.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 case WE_MENU:
198 return getmenudetail(detail, ep);
Guido van Rossum3ee199e1992-06-30 12:48:26 +0000199 case WE_KEY:
200 return getargs(detail, "(ii)",
201 &ep->u.key.code, &ep->u.key.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 default:
203 return 1;
204 }
205}
206
207
208/* Return construction tools */
209
210static object *
211makepoint(a, b)
212 int a, b;
213{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000214 return mkvalue("(ii)", a, b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215}
216
217static object *
218makerect(a, b, c, d)
219 int a, b, c, d;
220{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000221 return mkvalue("((ii)(ii))", a, b, c, d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222}
223
224
225/* Drawing objects */
226
227typedef struct {
228 OB_HEAD
229 windowobject *d_ref;
230} drawingobject;
231
232static drawingobject *Drawing; /* Set to current drawing object, or NULL */
233
234/* Drawing methods */
235
Guido van Rossum3c284741991-11-27 14:54:54 +0000236static object *
237drawing_close(dp)
238 drawingobject *dp;
239{
240 if (dp->d_ref != NULL) {
241 wenddrawing(dp->d_ref->w_win);
242 Drawing = NULL;
243 DECREF(dp->d_ref);
244 dp->d_ref = NULL;
245 }
246 INCREF(None);
247 return None;
248}
Guido van Rossum77b46041992-01-14 18:41:24 +0000249
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250static void
251drawing_dealloc(dp)
252 drawingobject *dp;
253{
Guido van Rossum3c284741991-11-27 14:54:54 +0000254 if (dp->d_ref != NULL) {
255 wenddrawing(dp->d_ref->w_win);
256 Drawing = NULL;
257 DECREF(dp->d_ref);
258 dp->d_ref = NULL;
259 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260 free((char *)dp);
261}
262
263static object *
264drawing_generic(dp, args, func)
265 drawingobject *dp;
266 object *args;
267 void (*func) FPROTO((int, int, int, int));
268{
269 int a[4];
270 if (!getrectarg(args, a))
271 return NULL;
272 (*func)(a[0], a[1], a[2], a[3]);
273 INCREF(None);
274 return None;
275}
276
277static object *
278drawing_line(dp, args)
279 drawingobject *dp;
280 object *args;
281{
Guido van Rossumbf109731991-03-06 13:14:12 +0000282 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283}
284
285static object *
286drawing_xorline(dp, args)
287 drawingobject *dp;
288 object *args;
289{
Guido van Rossumbf109731991-03-06 13:14:12 +0000290 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291}
292
293static object *
294drawing_circle(dp, args)
295 drawingobject *dp;
296 object *args;
297{
298 int a[3];
299 if (!getpointintarg(args, a))
300 return NULL;
301 wdrawcircle(a[0], a[1], a[2]);
302 INCREF(None);
303 return None;
304}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000305
Guido van Rossum27201061991-04-16 08:43:03 +0000306static object *
307drawing_fillcircle(dp, args)
308 drawingobject *dp;
309 object *args;
310{
311 int a[3];
312 if (!getpointintarg(args, a))
313 return NULL;
314 wfillcircle(a[0], a[1], a[2]);
315 INCREF(None);
316 return None;
317}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318
319static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000320drawing_xorcircle(dp, args)
321 drawingobject *dp;
322 object *args;
323{
324 int a[3];
325 if (!getpointintarg(args, a))
326 return NULL;
327 wxorcircle(a[0], a[1], a[2]);
328 INCREF(None);
329 return None;
330}
331
332static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333drawing_elarc(dp, args)
334 drawingobject *dp;
335 object *args;
336{
337 int a[6];
338 if (!get3pointarg(args, a))
339 return NULL;
340 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
341 INCREF(None);
342 return None;
343}
344
345static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000346drawing_fillelarc(dp, args)
347 drawingobject *dp;
348 object *args;
349{
350 int a[6];
351 if (!get3pointarg(args, a))
352 return NULL;
353 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
354 INCREF(None);
355 return None;
356}
357
358static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000359drawing_xorelarc(dp, args)
360 drawingobject *dp;
361 object *args;
362{
363 int a[6];
364 if (!get3pointarg(args, a))
365 return NULL;
366 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
367 INCREF(None);
368 return None;
369}
370
371static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372drawing_box(dp, args)
373 drawingobject *dp;
374 object *args;
375{
Guido van Rossumbf109731991-03-06 13:14:12 +0000376 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377}
378
379static object *
380drawing_erase(dp, args)
381 drawingobject *dp;
382 object *args;
383{
Guido van Rossumbf109731991-03-06 13:14:12 +0000384 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385}
386
387static object *
388drawing_paint(dp, args)
389 drawingobject *dp;
390 object *args;
391{
Guido van Rossumbf109731991-03-06 13:14:12 +0000392 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393}
394
395static object *
396drawing_invert(dp, args)
397 drawingobject *dp;
398 object *args;
399{
Guido van Rossumbf109731991-03-06 13:14:12 +0000400 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401}
402
Guido van Rossum27201061991-04-16 08:43:03 +0000403static POINT *
404getpointsarray(v, psize)
405 object *v;
406 int *psize;
407{
408 int n = -1;
409 object * (*getitem) PROTO((object *, int));
410 int i;
411 POINT *points;
412
413 if (v == NULL)
414 ;
415 else if (is_listobject(v)) {
416 n = getlistsize(v);
417 getitem = getlistitem;
418 }
419 else if (is_tupleobject(v)) {
420 n = gettuplesize(v);
421 getitem = gettupleitem;
422 }
423
424 if (n <= 0) {
425 (void) err_badarg();
426 return NULL;
427 }
428
429 points = NEW(POINT, n);
430 if (points == NULL) {
431 (void) err_nomem();
432 return NULL;
433 }
434
435 for (i = 0; i < n; i++) {
436 object *w = (*getitem)(v, i);
437 int a[2];
438 if (!getpointarg(w, a)) {
439 DEL(points);
440 return NULL;
441 }
442 points[i].h = a[0];
443 points[i].v = a[1];
444 }
445
446 *psize = n;
447 return points;
448}
449
450static object *
451drawing_poly(dp, args)
452 drawingobject *dp;
453 object *args;
454{
455 int n;
456 POINT *points = getpointsarray(args, &n);
457 if (points == NULL)
458 return NULL;
459 wdrawpoly(n, points);
460 DEL(points);
461 INCREF(None);
462 return None;
463}
464
465static object *
466drawing_fillpoly(dp, args)
467 drawingobject *dp;
468 object *args;
469{
470 int n;
471 POINT *points = getpointsarray(args, &n);
472 if (points == NULL)
473 return NULL;
474 wfillpoly(n, points);
475 DEL(points);
476 INCREF(None);
477 return None;
478}
479
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000481drawing_xorpoly(dp, args)
482 drawingobject *dp;
483 object *args;
484{
485 int n;
486 POINT *points = getpointsarray(args, &n);
487 if (points == NULL)
488 return NULL;
489 wxorpoly(n, points);
490 DEL(points);
491 INCREF(None);
492 return None;
493}
494
495static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496drawing_cliprect(dp, args)
497 drawingobject *dp;
498 object *args;
499{
Guido van Rossumbf109731991-03-06 13:14:12 +0000500 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501}
502
503static object *
504drawing_noclip(dp, args)
505 drawingobject *dp;
506 object *args;
507{
508 if (!getnoarg(args))
509 return NULL;
510 wnoclip();
511 INCREF(None);
512 return None;
513}
514
515static object *
516drawing_shade(dp, args)
517 drawingobject *dp;
518 object *args;
519{
520 int a[5];
521 if (!getrectintarg(args, a))
522 return NULL;
523 wshade(a[0], a[1], a[2], a[3], a[4]);
524 INCREF(None);
525 return None;
526}
527
528static object *
529drawing_text(dp, args)
530 drawingobject *dp;
531 object *args;
532{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000533 int h, v, size;
534 char *text;
535 if (!getargs(args, "((ii)s#)", &h, &v, &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000537 wdrawtext(h, v, text, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 INCREF(None);
539 return None;
540}
541
542/* The following four are also used as stdwin functions */
543
544static object *
545drawing_lineheight(dp, args)
546 drawingobject *dp;
547 object *args;
548{
549 if (!getnoarg(args))
550 return NULL;
551 return newintobject((long)wlineheight());
552}
553
554static object *
555drawing_baseline(dp, args)
556 drawingobject *dp;
557 object *args;
558{
559 if (!getnoarg(args))
560 return NULL;
561 return newintobject((long)wbaseline());
562}
563
564static object *
565drawing_textwidth(dp, args)
566 drawingobject *dp;
567 object *args;
568{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000569 char *text;
570 int size;
571 if (!getargs(args, "s#", &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000572 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000573 return newintobject((long)wtextwidth(text, size));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574}
575
576static object *
577drawing_textbreak(dp, args)
578 drawingobject *dp;
579 object *args;
580{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000581 char *text;
582 int size, width;
583 if (!getargs(args, "(s#i)", &text, &size, &width))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000584 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000585 return newintobject((long)wtextbreak(text, size, width));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586}
587
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000588static object *
589drawing_setfont(self, args)
590 drawingobject *self;
591 object *args;
592{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000593 char *font;
594 char style = '\0';
595 int size = 0;
596 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +0000597 if (!getargs(args, "z", &font))
Guido van Rossum50429a11991-04-04 15:24:07 +0000598 return NULL;
599 }
600 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000601 int n = gettuplesize(args);
602 if (n == 2) {
603 if (!getargs(args, "(zi)", &font, &size))
604 return NULL;
605 }
606 else if (!getargs(args, "(zic)", &font, &size, &style)) {
607 err_clear();
608 if (!getargs(args, "(zci)", &font, &style, &size))
609 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000610 }
611 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000612 if (font != NULL) {
613 if (!wsetfont(font)) {
614 err_setstr(StdwinError, "font not found");
615 return NULL;
616 }
617 }
Guido van Rossum50429a11991-04-04 15:24:07 +0000618 if (size != 0)
619 wsetsize(size);
Guido van Rossumfc58e581992-01-27 16:45:55 +0000620 switch (style) {
621 case 'b':
622 wsetbold();
623 break;
624 case 'i':
625 wsetitalic();
626 break;
627 case 'o':
628 wsetbolditalic();
629 break;
630 case 'u':
631 wsetunderline();
632 break;
633 case 'p':
634 wsetplain();
635 break;
636 }
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000637 INCREF(None);
638 return None;
639}
640
641static object *
642drawing_getbgcolor(self, args)
643 object *self;
644 object *args;
645{
646 if (!getnoarg(args))
647 return NULL;
648 return newintobject((long)wgetbgcolor());
649}
650
651static object *
652drawing_getfgcolor(self, args)
653 object *self;
654 object *args;
655{
656 if (!getnoarg(args))
657 return NULL;
658 return newintobject((long)wgetfgcolor());
659}
660
661static object *
662drawing_setbgcolor(self, args)
663 object *self;
664 object *args;
665{
666 long color;
667 if (!getlongarg(args, &color))
668 return NULL;
669 wsetbgcolor((COLOR)color);
670 INCREF(None);
671 return None;
672}
673
674static object *
675drawing_setfgcolor(self, args)
676 object *self;
677 object *args;
678{
679 long color;
680 if (!getlongarg(args, &color))
681 return NULL;
682 wsetfgcolor((COLOR)color);
683 INCREF(None);
684 return None;
685}
686
Guido van Rossumbf80e541993-02-08 15:49:17 +0000687static object *
688drawing_bitmap(self, args)
689 object *self;
690 object *args;
691{
692 int h, v;
693 object *bp;
694 object *mask = NULL;
695 if (!getargs(args, "((ii)O)", &h, &v, &bp)) {
696 err_clear();
697 if (!getargs(args, "((ii)OO)", &h, &v, &bp, &mask))
698 return NULL;
699 if (mask == None)
700 mask = NULL;
701 else if (!is_bitmapobject(mask)) {
702 err_badarg();
703 return NULL;
704 }
705 }
706 if (!is_bitmapobject(bp)) {
707 err_badarg();
708 return NULL;
709 }
710 if (((bitmapobject *)bp)->b_bitmap == NULL ||
711 mask != NULL && ((bitmapobject *)mask)->b_bitmap == NULL) {
712 err_setstr(StdwinError, "bitmap object already close");
713 return NULL;
714 }
715 if (mask == NULL)
716 wdrawbitmap(h, v, ((bitmapobject *)bp)->b_bitmap, ALLBITS);
717 else
718 wdrawbitmap(h, v,
719 ((bitmapobject *)bp)->b_bitmap,
720 ((bitmapobject *)bp)->b_bitmap);
721 INCREF(None);
722 return None;
723}
724
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725static struct methodlist drawing_methods[] = {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000726 {"bitmap", drawing_bitmap},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727 {"box", drawing_box},
728 {"circle", drawing_circle},
729 {"cliprect", drawing_cliprect},
Guido van Rossum3c284741991-11-27 14:54:54 +0000730 {"close", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000731 {"elarc", drawing_elarc},
Guido van Rossum3c284741991-11-27 14:54:54 +0000732 {"enddrawing", drawing_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000733 {"erase", drawing_erase},
Guido van Rossum27201061991-04-16 08:43:03 +0000734 {"fillcircle", drawing_fillcircle},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000735 {"fillelarc", drawing_fillelarc},
Guido van Rossum27201061991-04-16 08:43:03 +0000736 {"fillpoly", drawing_fillpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000737 {"invert", drawing_invert},
738 {"line", drawing_line},
739 {"noclip", drawing_noclip},
740 {"paint", drawing_paint},
Guido van Rossum27201061991-04-16 08:43:03 +0000741 {"poly", drawing_poly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742 {"shade", drawing_shade},
743 {"text", drawing_text},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000744 {"xorcircle", drawing_xorcircle},
745 {"xorelarc", drawing_xorelarc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000746 {"xorline", drawing_xorline},
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000747 {"xorpoly", drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000748
749 /* Text measuring methods: */
750 {"baseline", drawing_baseline},
751 {"lineheight", drawing_lineheight},
752 {"textbreak", drawing_textbreak},
753 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000754
755 /* Font setting methods: */
756 {"setfont", drawing_setfont},
757
758 /* Color methods: */
759 {"getbgcolor", drawing_getbgcolor},
760 {"getfgcolor", drawing_getfgcolor},
761 {"setbgcolor", drawing_setbgcolor},
762 {"setfgcolor", drawing_setfgcolor},
763
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000764 {NULL, NULL} /* sentinel */
765};
766
767static object *
Guido van Rossum77b46041992-01-14 18:41:24 +0000768drawing_getattr(dp, name)
769 drawingobject *dp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 char *name;
771{
Guido van Rossum77b46041992-01-14 18:41:24 +0000772 if (dp->d_ref == NULL) {
773 err_setstr(StdwinError, "drawing object already closed");
774 return NULL;
775 }
776 return findmethod(drawing_methods, (object *)dp, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000777}
778
Guido van Rossum541c8c01991-05-05 20:13:41 +0000779typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780 OB_HEAD_INIT(&Typetype)
781 0, /*ob_size*/
782 "drawing", /*tp_name*/
783 sizeof(drawingobject), /*tp_size*/
784 0, /*tp_itemsize*/
785 /* methods */
786 drawing_dealloc, /*tp_dealloc*/
787 0, /*tp_print*/
788 drawing_getattr, /*tp_getattr*/
789 0, /*tp_setattr*/
790 0, /*tp_compare*/
791 0, /*tp_repr*/
792};
793
794
795/* Text(edit) objects */
796
797typedef struct {
798 OB_HEAD
799 TEXTEDIT *t_text;
800 windowobject *t_ref;
801 object *t_attr; /* Attributes dictionary */
802} textobject;
803
804extern typeobject Texttype; /* Really static, forward */
805
806static textobject *
807newtextobject(wp, left, top, right, bottom)
808 windowobject *wp;
809 int left, top, right, bottom;
810{
811 textobject *tp;
812 tp = NEWOBJ(textobject, &Texttype);
813 if (tp == NULL)
814 return NULL;
815 tp->t_attr = NULL;
816 INCREF(wp);
817 tp->t_ref = wp;
818 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
819 if (tp->t_text == NULL) {
820 DECREF(tp);
821 return (textobject *) err_nomem();
822 }
823 return tp;
824}
825
826/* Text(edit) methods */
827
828static void
829text_dealloc(tp)
830 textobject *tp;
831{
832 if (tp->t_text != NULL)
833 tefree(tp->t_text);
Guido van Rossum3c284741991-11-27 14:54:54 +0000834 XDECREF(tp->t_attr);
835 XDECREF(tp->t_ref);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836 DEL(tp);
837}
838
839static object *
Guido van Rossum3c284741991-11-27 14:54:54 +0000840text_close(tp, args)
841 textobject *tp;
842 object *args;
843{
844 if (tp->t_text != NULL) {
845 tefree(tp->t_text);
846 tp->t_text = NULL;
847 }
848 if (tp->t_attr != NULL) {
849 DECREF(tp->t_attr);
850 tp->t_attr = NULL;
851 }
852 if (tp->t_ref != NULL) {
853 DECREF(tp->t_ref);
854 tp->t_ref = NULL;
855 }
856 INCREF(None);
857 return None;
858}
859
860static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861text_arrow(self, args)
862 textobject *self;
863 object *args;
864{
865 int code;
866 if (!getintarg(args, &code))
867 return NULL;
868 tearrow(self->t_text, code);
869 INCREF(None);
870 return None;
871}
872
873static object *
874text_draw(self, args)
875 textobject *self;
876 object *args;
877{
878 register TEXTEDIT *tp = self->t_text;
879 int a[4];
880 int left, top, right, bottom;
881 if (!getrectarg(args, a))
882 return NULL;
883 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000884 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000885 return NULL;
886 }
887 /* Clip to text area and ignore if area is empty */
888 left = tegetleft(tp);
889 top = tegettop(tp);
890 right = tegetright(tp);
891 bottom = tegetbottom(tp);
892 if (a[0] < left) a[0] = left;
893 if (a[1] < top) a[1] = top;
894 if (a[2] > right) a[2] = right;
895 if (a[3] > bottom) a[3] = bottom;
896 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000897 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000898 tedrawnew(tp, a[0], a[1], a[2], a[3]);
899 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000900 }
901 INCREF(None);
902 return None;
903}
904
905static object *
906text_event(self, args)
907 textobject *self;
908 object *args;
909{
910 register TEXTEDIT *tp = self->t_text;
911 EVENT e;
912 if (!geteventarg(args, &e))
913 return NULL;
914 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000915 /* Cheat at the margins */
916 int width, height;
917 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 if (e.u.where.h < 0 && tegetleft(tp) == 0)
919 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000920 else if (e.u.where.h > width && tegetright(tp) == width)
921 e.u.where.h = width;
922 if (e.u.where.v < 0 && tegettop(tp) == 0)
923 e.u.where.v = 0;
924 else if (e.u.where.v > height && tegetright(tp) == height)
925 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926 }
927 return newintobject((long) teevent(tp, &e));
928}
929
930static object *
931text_getfocus(self, args)
932 textobject *self;
933 object *args;
934{
935 if (!getnoarg(args))
936 return NULL;
937 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
938}
939
940static object *
941text_getfocustext(self, args)
942 textobject *self;
943 object *args;
944{
945 int f1, f2;
946 char *text;
947 if (!getnoarg(args))
948 return NULL;
949 f1 = tegetfoc1(self->t_text);
950 f2 = tegetfoc2(self->t_text);
951 text = tegettext(self->t_text);
952 return newsizedstringobject(text + f1, f2-f1);
953}
954
955static object *
956text_getrect(self, args)
957 textobject *self;
958 object *args;
959{
960 if (!getnoarg(args))
961 return NULL;
962 return makerect(tegetleft(self->t_text),
963 tegettop(self->t_text),
964 tegetright(self->t_text),
965 tegetbottom(self->t_text));
966}
967
968static object *
969text_gettext(self, args)
970 textobject *self;
971 object *args;
972{
973 if (!getnoarg(args))
974 return NULL;
975 return newsizedstringobject(tegettext(self->t_text),
976 tegetlen(self->t_text));
977}
978
979static object *
980text_move(self, args)
981 textobject *self;
982 object *args;
983{
984 int a[4];
985 if (!getrectarg(args, a))
986 return NULL;
987 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
988 INCREF(None);
989 return None;
990}
991
992static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000993text_replace(self, args)
994 textobject *self;
995 object *args;
996{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000997 char *text;
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +0000998 if (!getstrarg(args, &text))
999 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001000 tereplace(self->t_text, text);
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001001 INCREF(None);
1002 return None;
1003}
1004
1005static object *
1006text_setactive(self, args)
1007 textobject *self;
1008 object *args;
1009{
1010 int flag;
1011 if (!getintarg(args, &flag))
1012 return NULL;
1013 tesetactive(self->t_text, flag);
1014 INCREF(None);
1015 return None;
1016}
1017
1018static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019text_setfocus(self, args)
1020 textobject *self;
1021 object *args;
1022{
1023 int a[2];
1024 if (!getpointarg(args, a))
1025 return NULL;
1026 tesetfocus(self->t_text, a[0], a[1]);
1027 INCREF(None);
1028 return None;
1029}
1030
1031static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001032text_settext(self, args)
1033 textobject *self;
1034 object *args;
1035{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001036 char *text;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001037 char *buf;
1038 int size;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001039 if (!getargs(args, "s#", &text, &size))
Guido van Rossum541c8c01991-05-05 20:13:41 +00001040 return NULL;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001041 if ((buf = NEW(char, size)) == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001042 return err_nomem();
Guido van Rossum541c8c01991-05-05 20:13:41 +00001043 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001044 memcpy(buf, text, size);
Guido van Rossum541c8c01991-05-05 20:13:41 +00001045 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1046 INCREF(None);
1047 return None;
1048}
1049
1050static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001051text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052 textobject *self;
1053 object *args;
1054{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001055 int a[4];
1056 if (args == None)
1057 tenoview(self->t_text);
1058 else {
1059 if (!getrectarg(args, a))
1060 return NULL;
1061 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1062 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001063 INCREF(None);
1064 return None;
1065}
1066
1067static struct methodlist text_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001068 {"arrow", text_arrow},
1069 {"close", text_close},
1070 {"draw", text_draw},
1071 {"event", text_event},
1072 {"getfocus", text_getfocus},
Guido van Rossum77b46041992-01-14 18:41:24 +00001073 {"getfocustext",text_getfocustext},
Guido van Rossum3c284741991-11-27 14:54:54 +00001074 {"getrect", text_getrect},
1075 {"gettext", text_gettext},
Guido van Rossum77b46041992-01-14 18:41:24 +00001076 {"move", text_move},
Guido van Rossum3c284741991-11-27 14:54:54 +00001077 {"replace", text_replace},
1078 {"setactive", text_setactive},
1079 {"setfocus", text_setfocus},
1080 {"settext", text_settext},
1081 {"setview", text_setview},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001082 {NULL, NULL} /* sentinel */
1083};
1084
1085static object *
1086text_getattr(tp, name)
1087 textobject *tp;
1088 char *name;
1089{
Guido van Rossum85f50761991-10-20 20:22:50 +00001090 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001091 if (tp->t_ref == NULL) {
1092 err_setstr(StdwinError, "text object already closed");
1093 return NULL;
1094 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001095 if (strcmp(name, "__dict__") == 0) {
1096 v = tp->t_attr;
1097 if (v == NULL)
1098 v = None;
1099 }
1100 else if (tp->t_attr != NULL) {
1101 v = dictlookup(tp->t_attr, name);
1102 }
1103 if (v != NULL) {
1104 INCREF(v);
1105 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001106 }
1107 return findmethod(text_methods, (object *)tp, name);
1108}
1109
1110static int
1111text_setattr(tp, name, v)
1112 textobject *tp;
1113 char *name;
1114 object *v;
1115{
1116 if (tp->t_attr == NULL) {
1117 tp->t_attr = newdictobject();
1118 if (tp->t_attr == NULL)
1119 return -1;
1120 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001121 if (v == NULL) {
1122 int rv = dictremove(tp->t_attr, name);
1123 if (rv < 0)
1124 err_setstr(AttributeError,
1125 "delete non-existing text object attribute");
1126 return rv;
1127 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001128 else
1129 return dictinsert(tp->t_attr, name, v);
1130}
1131
Guido van Rossum541c8c01991-05-05 20:13:41 +00001132typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001133 OB_HEAD_INIT(&Typetype)
1134 0, /*ob_size*/
1135 "textedit", /*tp_name*/
1136 sizeof(textobject), /*tp_size*/
1137 0, /*tp_itemsize*/
1138 /* methods */
1139 text_dealloc, /*tp_dealloc*/
1140 0, /*tp_print*/
1141 text_getattr, /*tp_getattr*/
1142 text_setattr, /*tp_setattr*/
1143 0, /*tp_compare*/
1144 0, /*tp_repr*/
1145};
1146
1147
1148/* Menu objects */
1149
Guido van Rossum2d14e211991-02-19 12:26:49 +00001150#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001151#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001152static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153
Guido van Rossumfc58e581992-01-27 16:45:55 +00001154static menuobject *newmenuobject PROTO((char *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155static menuobject *
1156newmenuobject(title)
Guido van Rossumfc58e581992-01-27 16:45:55 +00001157 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158{
1159 int id;
1160 MENU *menu;
1161 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001162 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163 if (menulist[id] == NULL)
1164 break;
1165 }
Guido van Rossum27201061991-04-16 08:43:03 +00001166 if (id >= MAXNMENU) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001167 err_setstr(StdwinError, "creating too many menus");
Guido van Rossum27201061991-04-16 08:43:03 +00001168 return NULL;
1169 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001170 menu = wmenucreate(id + IDOFFSET, title);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 if (menu == NULL)
1172 return (menuobject *) err_nomem();
1173 mp = NEWOBJ(menuobject, &Menutype);
1174 if (mp != NULL) {
1175 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001176 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177 mp->m_attr = NULL;
1178 menulist[id] = mp;
1179 }
1180 else
1181 wmenudelete(menu);
1182 return mp;
1183}
1184
1185/* Menu methods */
1186
1187static void
1188menu_dealloc(mp)
1189 menuobject *mp;
1190{
1191
Guido van Rossum2d14e211991-02-19 12:26:49 +00001192 int id = mp->m_id - IDOFFSET;
1193 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 menulist[id] = NULL;
1195 }
Guido van Rossum77b46041992-01-14 18:41:24 +00001196 if (mp->m_menu != NULL)
1197 wmenudelete(mp->m_menu);
1198 XDECREF(mp->m_attr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199 DEL(mp);
1200}
1201
1202static object *
Guido van Rossum77b46041992-01-14 18:41:24 +00001203menu_close(mp, args)
1204 menuobject *mp;
1205 object *args;
1206{
1207 int id = mp->m_id - IDOFFSET;
1208 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1209 menulist[id] = NULL;
1210 }
1211 mp->m_id = -1;
1212 if (mp->m_menu != NULL)
1213 wmenudelete(mp->m_menu);
1214 mp->m_menu = NULL;
1215 XDECREF(mp->m_attr);
1216 mp->m_attr = NULL;
1217 INCREF(None);
1218 return None;
1219}
1220
1221static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222menu_additem(self, args)
1223 menuobject *self;
1224 object *args;
1225{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001226 char *text;
1227 int shortcut = -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228 if (is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +00001229 char c;
1230 if (!getargs(args, "(sc)", &text, &c))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001232 shortcut = c;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001233 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001234 else if (!getstrarg(args, &text))
1235 return NULL;
1236 wmenuadditem(self->m_menu, text, shortcut);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237 INCREF(None);
1238 return None;
1239}
1240
1241static object *
1242menu_setitem(self, args)
1243 menuobject *self;
1244 object *args;
1245{
1246 int index;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001247 char *text;
Guido van Rossum234f9421993-06-17 12:35:49 +00001248 if (!getargs(args, "(is)", &index, &text))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001250 wmenusetitem(self->m_menu, index, text);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251 INCREF(None);
1252 return None;
1253}
1254
1255static object *
1256menu_enable(self, args)
1257 menuobject *self;
1258 object *args;
1259{
1260 int index;
1261 int flag;
Guido van Rossum234f9421993-06-17 12:35:49 +00001262 if (!getargs(args, "(ii)", &index, &flag))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001263 return NULL;
1264 wmenuenable(self->m_menu, index, flag);
1265 INCREF(None);
1266 return None;
1267}
1268
1269static object *
1270menu_check(self, args)
1271 menuobject *self;
1272 object *args;
1273{
1274 int index;
1275 int flag;
Guido van Rossum234f9421993-06-17 12:35:49 +00001276 if (!getargs(args, "(ii)", &index, &flag))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001277 return NULL;
1278 wmenucheck(self->m_menu, index, flag);
1279 INCREF(None);
1280 return None;
1281}
1282
1283static struct methodlist menu_methods[] = {
Guido van Rossum3c284741991-11-27 14:54:54 +00001284 {"additem", menu_additem},
1285 {"setitem", menu_setitem},
1286 {"enable", menu_enable},
1287 {"check", menu_check},
Guido van Rossum77b46041992-01-14 18:41:24 +00001288 {"close", menu_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289 {NULL, NULL} /* sentinel */
1290};
1291
1292static object *
1293menu_getattr(mp, name)
1294 menuobject *mp;
1295 char *name;
1296{
Guido van Rossum85f50761991-10-20 20:22:50 +00001297 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001298 if (mp->m_menu == NULL) {
1299 err_setstr(StdwinError, "menu object already closed");
1300 return NULL;
1301 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001302 if (strcmp(name, "__dict__") == 0) {
1303 v = mp->m_attr;
1304 if (v == NULL)
1305 v = None;
1306 }
1307 else if (mp->m_attr != NULL) {
1308 v = dictlookup(mp->m_attr, name);
1309 }
1310 if (v != NULL) {
1311 INCREF(v);
1312 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313 }
1314 return findmethod(menu_methods, (object *)mp, name);
1315}
1316
1317static int
1318menu_setattr(mp, name, v)
1319 menuobject *mp;
1320 char *name;
1321 object *v;
1322{
1323 if (mp->m_attr == NULL) {
1324 mp->m_attr = newdictobject();
1325 if (mp->m_attr == NULL)
1326 return -1;
1327 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001328 if (v == NULL) {
1329 int rv = dictremove(mp->m_attr, name);
1330 if (rv < 0)
1331 err_setstr(AttributeError,
1332 "delete non-existing menu object attribute");
1333 return rv;
1334 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335 else
1336 return dictinsert(mp->m_attr, name, v);
1337}
1338
Guido van Rossum541c8c01991-05-05 20:13:41 +00001339typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340 OB_HEAD_INIT(&Typetype)
1341 0, /*ob_size*/
1342 "menu", /*tp_name*/
1343 sizeof(menuobject), /*tp_size*/
1344 0, /*tp_itemsize*/
1345 /* methods */
1346 menu_dealloc, /*tp_dealloc*/
1347 0, /*tp_print*/
1348 menu_getattr, /*tp_getattr*/
1349 menu_setattr, /*tp_setattr*/
1350 0, /*tp_compare*/
1351 0, /*tp_repr*/
1352};
1353
1354
Guido van Rossumbf80e541993-02-08 15:49:17 +00001355/* Bitmaps objects */
1356
1357static bitmapobject *newbitmapobject PROTO((int, int));
1358static bitmapobject *
1359newbitmapobject(width, height)
1360 int width, height;
1361{
1362 BITMAP *bitmap;
1363 bitmapobject *bp;
1364 bitmap = wnewbitmap(width, height);
1365 if (bitmap == NULL)
1366 return (bitmapobject *) err_nomem();
1367 bp = NEWOBJ(bitmapobject, &Bitmaptype);
1368 if (bp != NULL) {
1369 bp->b_bitmap = bitmap;
1370 bp->b_attr = NULL;
1371 }
1372 else
1373 wfreebitmap(bitmap);
1374 return bp;
1375}
1376
1377/* Bitmap methods */
1378
1379static void
1380bitmap_dealloc(bp)
1381 bitmapobject *bp;
1382{
1383 if (bp->b_bitmap != NULL)
1384 wfreebitmap(bp->b_bitmap);
1385 XDECREF(bp->b_attr);
1386 DEL(bp);
1387}
1388
1389static object *
1390bitmap_close(bp, args)
1391 bitmapobject *bp;
1392 object *args;
1393{
1394 if (bp->b_bitmap != NULL)
1395 wfreebitmap(bp->b_bitmap);
1396 bp->b_bitmap = NULL;
1397 XDECREF(bp->b_attr);
1398 bp->b_attr = NULL;
1399 INCREF(None);
1400 return None;
1401}
1402
1403static object *
1404bitmap_setbit(self, args)
1405 bitmapobject *self;
1406 object *args;
1407{
1408 int a[3];
1409 if (!getpointintarg(args, a))
1410 return NULL;
1411 wsetbit(self->b_bitmap, a[0], a[1], a[2]);
1412 INCREF(None);
1413 return None;
1414}
1415
1416static object *
1417bitmap_getbit(self, args)
1418 bitmapobject *self;
1419 object *args;
1420{
1421 int a[2];
1422 if (!getpointarg(args, a))
1423 return NULL;
1424 return newintobject((long) wgetbit(self->b_bitmap, a[0], a[1]));
1425}
1426
1427static object *
1428bitmap_getsize(self, args)
1429 bitmapobject *self;
1430 object *args;
1431{
1432 int width, height;
1433 if (!getnoarg(args))
1434 return NULL;
1435 wgetbitmapsize(self->b_bitmap, &width, &height);
1436 return mkvalue("(ii)", width, height);
1437}
1438
1439static struct methodlist bitmap_methods[] = {
1440 {"close", bitmap_close},
1441 {"getsize", bitmap_getsize},
1442 {"getbit", bitmap_getbit},
1443 {"setbit", bitmap_setbit},
1444 {NULL, NULL} /* sentinel */
1445};
1446
1447static object *
1448bitmap_getattr(bp, name)
1449 bitmapobject *bp;
1450 char *name;
1451{
1452 object *v = NULL;
1453 if (bp->b_bitmap == NULL) {
1454 err_setstr(StdwinError, "bitmap object already closed");
1455 return NULL;
1456 }
1457 if (strcmp(name, "__dict__") == 0) {
1458 v = bp->b_attr;
1459 if (v == NULL)
1460 v = None;
1461 }
1462 else if (bp->b_attr != NULL) {
1463 v = dictlookup(bp->b_attr, name);
1464 }
1465 if (v != NULL) {
1466 INCREF(v);
1467 return v;
1468 }
1469 return findmethod(bitmap_methods, (object *)bp, name);
1470}
1471
1472static int
1473bitmap_setattr(bp, name, v)
1474 bitmapobject *bp;
1475 char *name;
1476 object *v;
1477{
1478 if (bp->b_attr == NULL) {
1479 bp->b_attr = newdictobject();
1480 if (bp->b_attr == NULL)
1481 return -1;
1482 }
1483 if (v == NULL) {
1484 int rv = dictremove(bp->b_attr, name);
1485 if (rv < 0)
1486 err_setstr(AttributeError,
1487 "delete non-existing bitmap object attribute");
1488 return rv;
1489 }
1490 else
1491 return dictinsert(bp->b_attr, name, v);
1492}
1493
1494typeobject Bitmaptype = {
1495 OB_HEAD_INIT(&Typetype)
1496 0, /*ob_size*/
1497 "bitmap", /*tp_name*/
1498 sizeof(bitmapobject), /*tp_size*/
1499 0, /*tp_itemsize*/
1500 /* methods */
1501 bitmap_dealloc, /*tp_dealloc*/
1502 0, /*tp_print*/
1503 bitmap_getattr, /*tp_getattr*/
1504 bitmap_setattr, /*tp_setattr*/
1505 0, /*tp_compare*/
1506 0, /*tp_repr*/
1507};
1508
1509
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001510/* Windows */
1511
1512#define MAXNWIN 50
1513static windowobject *windowlist[MAXNWIN];
1514
1515/* Window methods */
1516
1517static void
1518window_dealloc(wp)
1519 windowobject *wp;
1520{
1521 if (wp->w_win != NULL) {
1522 int tag = wgettag(wp->w_win);
1523 if (tag >= 0 && tag < MAXNWIN)
1524 windowlist[tag] = NULL;
1525 else
1526 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1527 tag);
1528 wclose(wp->w_win);
1529 }
1530 DECREF(wp->w_title);
1531 if (wp->w_attr != NULL)
1532 DECREF(wp->w_attr);
1533 free((char *)wp);
1534}
1535
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001536static object *
Guido van Rossum3c284741991-11-27 14:54:54 +00001537window_close(wp, args)
1538 windowobject *wp;
1539 object *args;
1540{
1541 if (wp->w_win != NULL) {
1542 int tag = wgettag(wp->w_win);
1543 if (tag >= 0 && tag < MAXNWIN)
1544 windowlist[tag] = NULL;
1545 wclose(wp->w_win);
1546 wp->w_win = NULL;
1547 }
1548 INCREF(None);
1549 return None;
1550}
1551
1552static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001553window_begindrawing(wp, args)
1554 windowobject *wp;
1555 object *args;
1556{
1557 drawingobject *dp;
1558 if (!getnoarg(args))
1559 return NULL;
1560 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001561 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001562 return NULL;
1563 }
1564 dp = NEWOBJ(drawingobject, &Drawingtype);
1565 if (dp == NULL)
1566 return NULL;
1567 Drawing = dp;
1568 INCREF(wp);
1569 dp->d_ref = wp;
1570 wbegindrawing(wp->w_win);
1571 return (object *)dp;
1572}
1573
1574static object *
1575window_change(wp, args)
1576 windowobject *wp;
1577 object *args;
1578{
1579 int a[4];
1580 if (!getrectarg(args, a))
1581 return NULL;
1582 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1583 INCREF(None);
1584 return None;
1585}
1586
1587static object *
1588window_gettitle(wp, args)
1589 windowobject *wp;
1590 object *args;
1591{
1592 if (!getnoarg(args))
1593 return NULL;
1594 INCREF(wp->w_title);
1595 return wp->w_title;
1596}
1597
1598static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001599window_getwinpos(wp, args)
1600 windowobject *wp;
1601 object *args;
1602{
1603 int h, v;
1604 if (!getnoarg(args))
1605 return NULL;
1606 wgetwinpos(wp->w_win, &h, &v);
1607 return makepoint(h, v);
1608}
1609
1610static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001611window_getwinsize(wp, args)
1612 windowobject *wp;
1613 object *args;
1614{
1615 int width, height;
1616 if (!getnoarg(args))
1617 return NULL;
1618 wgetwinsize(wp->w_win, &width, &height);
1619 return makepoint(width, height);
1620}
1621
1622static object *
Guido van Rossumbf80e541993-02-08 15:49:17 +00001623window_setwinpos(wp, args)
1624 windowobject *wp;
1625 object *args;
1626{
1627 int a[2];
1628 if (!getpointarg(args, a))
1629 return NULL;
1630 wsetwinpos(wp->w_win, a[0], a[1]);
1631 INCREF(None);
1632 return None;
1633}
1634
1635static object *
1636window_setwinsize(wp, args)
1637 windowobject *wp;
1638 object *args;
1639{
1640 int a[2];
1641 if (!getpointarg(args, a))
1642 return NULL;
1643 wsetwinsize(wp->w_win, a[0], a[1]);
1644 INCREF(None);
1645 return None;
1646}
1647
1648static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649window_getdocsize(wp, args)
1650 windowobject *wp;
1651 object *args;
1652{
1653 int width, height;
1654 if (!getnoarg(args))
1655 return NULL;
1656 wgetdocsize(wp->w_win, &width, &height);
1657 return makepoint(width, height);
1658}
1659
1660static object *
1661window_getorigin(wp, args)
1662 windowobject *wp;
1663 object *args;
1664{
1665 int width, height;
1666 if (!getnoarg(args))
1667 return NULL;
1668 wgetorigin(wp->w_win, &width, &height);
1669 return makepoint(width, height);
1670}
1671
1672static object *
1673window_scroll(wp, args)
1674 windowobject *wp;
1675 object *args;
1676{
1677 int a[6];
1678 if (!getrectpointarg(args, a))
1679 return NULL;
1680 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1681 INCREF(None);
1682 return None;
1683}
1684
1685static object *
1686window_setdocsize(wp, args)
1687 windowobject *wp;
1688 object *args;
1689{
1690 int a[2];
1691 if (!getpointarg(args, a))
1692 return NULL;
1693 wsetdocsize(wp->w_win, a[0], a[1]);
1694 INCREF(None);
1695 return None;
1696}
1697
1698static object *
1699window_setorigin(wp, args)
1700 windowobject *wp;
1701 object *args;
1702{
1703 int a[2];
1704 if (!getpointarg(args, a))
1705 return NULL;
1706 wsetorigin(wp->w_win, a[0], a[1]);
1707 INCREF(None);
1708 return None;
1709}
1710
1711static object *
1712window_settitle(wp, args)
1713 windowobject *wp;
1714 object *args;
1715{
1716 object *title;
Guido van Rossum234f9421993-06-17 12:35:49 +00001717 if (!getargs(args, "S", &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001718 return NULL;
1719 DECREF(wp->w_title);
1720 INCREF(title);
1721 wp->w_title = title;
1722 wsettitle(wp->w_win, getstringvalue(title));
1723 INCREF(None);
1724 return None;
1725}
1726
1727static object *
1728window_show(wp, args)
1729 windowobject *wp;
1730 object *args;
1731{
1732 int a[4];
1733 if (!getrectarg(args, a))
1734 return NULL;
1735 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1736 INCREF(None);
1737 return None;
1738}
1739
1740static object *
1741window_settimer(wp, args)
1742 windowobject *wp;
1743 object *args;
1744{
1745 int a;
1746 if (!getintarg(args, &a))
1747 return NULL;
1748 wsettimer(wp->w_win, a);
1749 INCREF(None);
1750 return None;
1751}
1752
1753static object *
1754window_menucreate(self, args)
1755 windowobject *self;
1756 object *args;
1757{
1758 menuobject *mp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001759 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001760 if (!getstrarg(args, &title))
1761 return NULL;
1762 wmenusetdeflocal(1);
1763 mp = newmenuobject(title);
1764 if (mp == NULL)
1765 return NULL;
1766 wmenuattach(self->w_win, mp->m_menu);
1767 return (object *)mp;
1768}
1769
1770static object *
1771window_textcreate(self, args)
1772 windowobject *self;
1773 object *args;
1774{
1775 textobject *tp;
1776 int a[4];
1777 if (!getrectarg(args, a))
1778 return NULL;
1779 return (object *)
1780 newtextobject(self, a[0], a[1], a[2], a[3]);
1781}
1782
Guido van Rossum5b10f451990-10-30 16:01:48 +00001783static object *
1784window_setselection(self, args)
1785 windowobject *self;
1786 object *args;
1787{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001788 int sel, size, ok;
1789 char *text;
1790 if (!getargs(args, "(is#)", &sel, &text, &size))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001791 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001792 ok = wsetselection(self->w_win, sel, text, size);
Guido van Rossum5b10f451990-10-30 16:01:48 +00001793 return newintobject(ok);
1794}
1795
1796static object *
1797window_setwincursor(self, args)
1798 windowobject *self;
1799 object *args;
1800{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001801 char *name;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001802 CURSOR *c;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001803 if (!getargs(args, "z", &name))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001804 return NULL;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001805 if (name == NULL)
1806 c = NULL;
1807 else {
1808 c = wfetchcursor(name);
1809 if (c == NULL) {
1810 err_setstr(StdwinError, "no such cursor");
1811 return NULL;
1812 }
Guido van Rossum5b10f451990-10-30 16:01:48 +00001813 }
1814 wsetwincursor(self->w_win, c);
1815 INCREF(None);
1816 return None;
1817}
1818
Guido van Rossumfc58e581992-01-27 16:45:55 +00001819static object *
1820window_setactive(self, args)
1821 windowobject *self;
1822 object *args;
1823{
1824 if (!getnoarg(args))
1825 return NULL;
1826 wsetactive(self->w_win);
1827 INCREF(None);
1828 return None;
1829}
1830
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001831#ifdef CWI_HACKS
1832static object *
1833window_getxwindowid(self, args)
1834 windowobject *self;
1835 object *args;
1836{
1837 long wid = wgetxwindowid(self->w_win);
1838 return newintobject(wid);
1839}
1840#endif
1841
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001842static struct methodlist window_methods[] = {
1843 {"begindrawing",window_begindrawing},
1844 {"change", window_change},
Guido van Rossum3c284741991-11-27 14:54:54 +00001845 {"close", window_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001846 {"getdocsize", window_getdocsize},
1847 {"getorigin", window_getorigin},
1848 {"gettitle", window_gettitle},
Guido van Rossum541c8c01991-05-05 20:13:41 +00001849 {"getwinpos", window_getwinpos},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001850 {"getwinsize", window_getwinsize},
1851 {"menucreate", window_menucreate},
1852 {"scroll", window_scroll},
Guido van Rossumb7e51601992-01-26 18:13:18 +00001853 {"setactive", window_setactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001854 {"setdocsize", window_setdocsize},
1855 {"setorigin", window_setorigin},
Guido van Rossum5b10f451990-10-30 16:01:48 +00001856 {"setselection",window_setselection},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857 {"settimer", window_settimer},
1858 {"settitle", window_settitle},
Guido van Rossum27201061991-04-16 08:43:03 +00001859 {"setwincursor",window_setwincursor},
Guido van Rossumbf80e541993-02-08 15:49:17 +00001860 {"setwinpos", window_setwinpos},
1861 {"setwinsize", window_setwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001862 {"show", window_show},
1863 {"textcreate", window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001864#ifdef CWI_HACKS
1865 {"getxwindowid",window_getxwindowid},
1866#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001867 {NULL, NULL} /* sentinel */
1868};
1869
1870static object *
1871window_getattr(wp, name)
1872 windowobject *wp;
1873 char *name;
1874{
Guido van Rossum85f50761991-10-20 20:22:50 +00001875 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001876 if (wp->w_win == NULL) {
1877 err_setstr(StdwinError, "window already closed");
1878 return NULL;
1879 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001880 if (strcmp(name, "__dict__") == 0) {
1881 v = wp->w_attr;
1882 if (v == NULL)
1883 v = None;
1884 }
1885 else if (wp->w_attr != NULL) {
1886 v = dictlookup(wp->w_attr, name);
1887 }
1888 if (v != NULL) {
1889 INCREF(v);
1890 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001891 }
1892 return findmethod(window_methods, (object *)wp, name);
1893}
1894
1895static int
1896window_setattr(wp, name, v)
1897 windowobject *wp;
1898 char *name;
1899 object *v;
1900{
1901 if (wp->w_attr == NULL) {
1902 wp->w_attr = newdictobject();
1903 if (wp->w_attr == NULL)
1904 return -1;
1905 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001906 if (v == NULL) {
1907 int rv = dictremove(wp->w_attr, name);
1908 if (rv < 0)
1909 err_setstr(AttributeError,
1910 "delete non-existing menu object attribute");
1911 return rv;
1912 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001913 else
1914 return dictinsert(wp->w_attr, name, v);
1915}
1916
Guido van Rossum541c8c01991-05-05 20:13:41 +00001917typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918 OB_HEAD_INIT(&Typetype)
1919 0, /*ob_size*/
1920 "window", /*tp_name*/
1921 sizeof(windowobject), /*tp_size*/
1922 0, /*tp_itemsize*/
1923 /* methods */
1924 window_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001925 0, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001926 window_getattr, /*tp_getattr*/
1927 window_setattr, /*tp_setattr*/
1928 0, /*tp_compare*/
1929 0, /*tp_repr*/
1930};
1931
1932/* Stdwin methods */
1933
1934static object *
1935stdwin_open(sw, args)
1936 object *sw;
1937 object *args;
1938{
1939 int tag;
1940 object *title;
1941 windowobject *wp;
Guido van Rossum234f9421993-06-17 12:35:49 +00001942 if (!getargs(args, "S", &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001943 return NULL;
1944 for (tag = 0; tag < MAXNWIN; tag++) {
1945 if (windowlist[tag] == NULL)
1946 break;
1947 }
Guido van Rossum27201061991-04-16 08:43:03 +00001948 if (tag >= MAXNWIN) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001949 err_setstr(StdwinError, "creating too many windows");
Guido van Rossum27201061991-04-16 08:43:03 +00001950 return NULL;
1951 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001952 wp = NEWOBJ(windowobject, &Windowtype);
1953 if (wp == NULL)
1954 return NULL;
1955 INCREF(title);
1956 wp->w_title = title;
1957 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1958 wp->w_attr = NULL;
1959 if (wp->w_win == NULL) {
1960 DECREF(wp);
1961 return NULL;
1962 }
1963 windowlist[tag] = wp;
1964 wsettag(wp->w_win, tag);
1965 return (object *)wp;
1966}
1967
1968static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00001969window2object(win)
1970 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001971{
Guido van Rossum246b9d81991-06-03 10:55:14 +00001972 object *w;
1973 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974 w = None;
1975 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00001976 int tag = wgettag(win);
1977 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
1978 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001979 w = None;
1980 else
1981 w = (object *)windowlist[tag];
1982 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001983 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00001984 return w;
1985}
1986
1987static object *
1988stdwin_get_poll_event(poll, args)
1989 int poll;
1990 object *args;
1991{
1992 EVENT e;
Guido van Rossum2ee12f41992-04-13 15:54:35 +00001993 object *u, *v, *w;
Guido van Rossum246b9d81991-06-03 10:55:14 +00001994 if (!getnoarg(args))
1995 return NULL;
1996 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001997 err_setstr(StdwinError, "cannot getevent() while drawing");
Guido van Rossum246b9d81991-06-03 10:55:14 +00001998 return NULL;
1999 }
2000 again:
Guido van Rossumff4949e1992-08-05 19:58:53 +00002001 BGN_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002002 if (poll) {
2003 if (!wpollevent(&e)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +00002004 RET_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002005 INCREF(None);
2006 return None;
2007 }
2008 }
2009 else
2010 wgetevent(&e);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002011 END_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002012 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
2013 /* Turn keyboard interrupts into exceptions */
2014 err_set(KeyboardInterrupt);
2015 return NULL;
2016 }
2017 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
2018 /* Turn WC_CLOSE commands into WE_CLOSE events */
2019 e.type = WE_CLOSE;
2020 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002021 v = window2object(e.window);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002022 switch (e.type) {
2023 case WE_CHAR:
2024 {
2025 char c[1];
2026 c[0] = e.u.character;
2027 w = newsizedstringobject(c, 1);
2028 }
2029 break;
2030 case WE_COMMAND:
2031 w = newintobject((long)e.u.command);
2032 break;
2033 case WE_DRAW:
2034 w = makerect(e.u.area.left, e.u.area.top,
2035 e.u.area.right, e.u.area.bottom);
2036 break;
2037 case WE_MOUSE_DOWN:
2038 case WE_MOUSE_MOVE:
2039 case WE_MOUSE_UP:
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002040 w = mkvalue("((ii)iii)",
2041 e.u.where.h, e.u.where.v,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042 e.u.where.clicks,
2043 e.u.where.button,
2044 e.u.where.mask);
2045 break;
2046 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00002047 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
2048 menulist[e.u.m.id - IDOFFSET] != NULL)
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002049 w = mkvalue("(Oi)",
2050 menulist[e.u.m.id - IDOFFSET], e.u.m.item);
Guido van Rossum246b9d81991-06-03 10:55:14 +00002051 else {
2052 /* Ghost menu event.
2053 Can occur only on the Mac if another part
2054 of the aplication has installed a menu;
2055 like the THINK C console library. */
2056 DECREF(v);
2057 goto again;
2058 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059 break;
Guido van Rossum3ee199e1992-06-30 12:48:26 +00002060 case WE_KEY:
2061 w = mkvalue("(ii)", e.u.key.code, e.u.key.mask);
2062 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002063 case WE_LOST_SEL:
2064 w = newintobject((long)e.u.sel);
2065 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002066 default:
2067 w = None;
2068 INCREF(w);
2069 break;
2070 }
2071 if (w == NULL) {
2072 DECREF(v);
2073 return NULL;
2074 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002075 u = mkvalue("(iOO)", e.type, v, w);
2076 XDECREF(v);
2077 XDECREF(w);
2078 return u;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079}
2080
2081static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002082stdwin_getevent(sw, args)
2083 object *sw;
2084 object *args;
2085{
2086 return stdwin_get_poll_event(0, args);
2087}
2088
2089static object *
2090stdwin_pollevent(sw, args)
2091 object *sw;
2092 object *args;
2093{
2094 return stdwin_get_poll_event(1, args);
2095}
2096
2097static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002098stdwin_setdefwinpos(sw, args)
2099 object *sw;
2100 object *args;
2101{
2102 int a[2];
2103 if (!getpointarg(args, a))
2104 return NULL;
2105 wsetdefwinpos(a[0], a[1]);
2106 INCREF(None);
2107 return None;
2108}
2109
2110static object *
2111stdwin_setdefwinsize(sw, args)
2112 object *sw;
2113 object *args;
2114{
2115 int a[2];
2116 if (!getpointarg(args, a))
2117 return NULL;
2118 wsetdefwinsize(a[0], a[1]);
2119 INCREF(None);
2120 return None;
2121}
2122
2123static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002124stdwin_setdefscrollbars(sw, args)
2125 object *sw;
2126 object *args;
2127{
2128 int a[2];
2129 if (!getpointarg(args, a))
2130 return NULL;
2131 wsetdefscrollbars(a[0], a[1]);
2132 INCREF(None);
2133 return None;
2134}
2135
2136static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002137stdwin_getdefwinpos(self, args)
2138 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002139 object *args;
2140{
2141 int h, v;
2142 if (!getnoarg(args))
2143 return NULL;
2144 wgetdefwinpos(&h, &v);
2145 return makepoint(h, v);
2146}
2147
2148static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002149stdwin_getdefwinsize(self, args)
2150 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002151 object *args;
2152{
2153 int width, height;
2154 if (!getnoarg(args))
2155 return NULL;
2156 wgetdefwinsize(&width, &height);
2157 return makepoint(width, height);
2158}
2159
2160static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002161stdwin_getdefscrollbars(self, args)
2162 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002163 object *args;
2164{
2165 int h, v;
2166 if (!getnoarg(args))
2167 return NULL;
2168 wgetdefscrollbars(&h, &v);
2169 return makepoint(h, v);
2170}
2171
2172static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002173stdwin_menucreate(self, args)
2174 object *self;
2175 object *args;
2176{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002177 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002178 if (!getstrarg(args, &title))
2179 return NULL;
2180 wmenusetdeflocal(0);
2181 return (object *)newmenuobject(title);
2182}
2183
2184static object *
2185stdwin_askfile(self, args)
2186 object *self;
2187 object *args;
2188{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002189 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002190 int new, ret;
2191 char buf[256];
Guido van Rossum234f9421993-06-17 12:35:49 +00002192 if (!getargs(args, "(ssi)", &prompt, &dflt, &new))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002193 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002194 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002195 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002196 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002197 ret = waskfile(prompt, buf, sizeof buf, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002198 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002199 if (!ret) {
2200 err_set(KeyboardInterrupt);
2201 return NULL;
2202 }
2203 return newstringobject(buf);
2204}
2205
2206static object *
2207stdwin_askync(self, args)
2208 object *self;
2209 object *args;
2210{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002211 char *prompt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002212 int new, ret;
Guido van Rossum234f9421993-06-17 12:35:49 +00002213 if (!getargs(args, "(si)", &prompt, &new))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002214 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002215 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002216 ret = waskync(prompt, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002217 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002218 if (ret < 0) {
2219 err_set(KeyboardInterrupt);
2220 return NULL;
2221 }
2222 return newintobject((long)ret);
2223}
2224
2225static object *
2226stdwin_askstr(self, args)
2227 object *self;
2228 object *args;
2229{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002230 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002231 int ret;
2232 char buf[256];
Guido van Rossum234f9421993-06-17 12:35:49 +00002233 if (!getargs(args, "(ss)", &prompt, &dflt))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002234 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002235 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002236 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002237 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002238 ret = waskstr(prompt, buf, sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002239 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002240 if (!ret) {
2241 err_set(KeyboardInterrupt);
2242 return NULL;
2243 }
2244 return newstringobject(buf);
2245}
2246
2247static object *
2248stdwin_message(self, args)
2249 object *self;
2250 object *args;
2251{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002252 char *msg;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002253 if (!getstrarg(args, &msg))
2254 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002255 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002256 wmessage(msg);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002257 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002258 INCREF(None);
2259 return None;
2260}
2261
2262static object *
2263stdwin_fleep(self, args)
2264 object *self;
2265 object *args;
2266{
2267 if (!getnoarg(args))
2268 return NULL;
2269 wfleep();
2270 INCREF(None);
2271 return None;
2272}
2273
2274static object *
2275stdwin_setcutbuffer(self, args)
2276 object *self;
2277 object *args;
2278{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002279 int i, size;
2280 char *str;
2281 if (!getargs(args, "(is#)", &i, &str, &size))
Guido van Rossum124967c1990-11-06 15:17:35 +00002282 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002283 wsetcutbuffer(i, str, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002284 INCREF(None);
2285 return None;
2286}
2287
2288static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002289stdwin_getactive(self, args)
2290 object *self;
2291 object *args;
2292{
2293 return window2object(wgetactive());
2294}
2295
2296static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002297stdwin_getcutbuffer(self, args)
2298 object *self;
2299 object *args;
2300{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002301 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002303 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002304 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002305 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002306 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002307 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002308 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002309 len = 0;
2310 }
2311 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002312}
2313
Guido van Rossum5b10f451990-10-30 16:01:48 +00002314static object *
2315stdwin_rotatecutbuffers(self, args)
2316 object *self;
2317 object *args;
2318{
2319 int i;
2320 if (!getintarg(args, &i))
2321 return NULL;
2322 wrotatecutbuffers(i);
2323 INCREF(None);
2324 return None;
2325}
2326
2327static object *
2328stdwin_getselection(self, args)
2329 object *self;
2330 object *args;
2331{
2332 int sel;
2333 char *data;
2334 int len;
2335 if (!getintarg(args, &sel))
2336 return NULL;
2337 data = wgetselection(sel, &len);
2338 if (data == NULL) {
2339 data = "";
2340 len = 0;
2341 }
2342 return newsizedstringobject(data, len);
2343}
2344
2345static object *
2346stdwin_resetselection(self, args)
2347 object *self;
2348 object *args;
2349{
2350 int sel;
2351 if (!getintarg(args, &sel))
2352 return NULL;
2353 wresetselection(sel);
2354 INCREF(None);
2355 return None;
2356}
2357
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002358static object *
2359stdwin_fetchcolor(self, args)
2360 object *self;
2361 object *args;
2362{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002363 char *colorname;
Guido van Rossum34679b71993-01-26 13:33:44 +00002364 COLOR color;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002365 if (!getstrarg(args, &colorname))
2366 return NULL;
Guido van Rossum34679b71993-01-26 13:33:44 +00002367 color = wfetchcolor(colorname);
2368#ifdef BADCOLOR
2369 if (color == BADCOLOR) {
2370 err_setstr(StdwinError, "color name not found");
2371 return NULL;
2372 }
2373#endif
2374 return newintobject((long)color);
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002375}
2376
Guido van Rossum541c8c01991-05-05 20:13:41 +00002377static object *
2378stdwin_getscrsize(self, args)
2379 object *self;
2380 object *args;
2381{
2382 int width, height;
2383 if (!getnoarg(args))
2384 return NULL;
2385 wgetscrsize(&width, &height);
2386 return makepoint(width, height);
2387}
2388
2389static object *
2390stdwin_getscrmm(self, args)
2391 object *self;
2392 object *args;
2393{
2394 int width, height;
2395 if (!getnoarg(args))
2396 return NULL;
2397 wgetscrmm(&width, &height);
2398 return makepoint(width, height);
2399}
2400
Guido van Rossumed233a51992-06-23 09:07:03 +00002401#ifdef unix
2402static object *
2403stdwin_connectionnumber(self, args)
2404 object *self;
2405 object *args;
2406{
2407 if (!getnoarg(args))
2408 return NULL;
2409 return newintobject((long) wconnectionnumber());
2410}
2411#endif
2412
Guido van Rossumbf80e541993-02-08 15:49:17 +00002413static object *
2414stdwin_listfontnames(self, args)
2415 object *self;
2416 object *args;
2417{
2418 char *pattern;
2419 char **fontnames;
2420 int count;
2421 object *list;
2422 if (!getargs(args, "z", &pattern))
2423 return NULL;
2424 fontnames = wlistfontnames(pattern, &count);
2425 list = newlistobject(count);
2426 if (list != NULL) {
2427 int i;
2428 for (i = 0; i < count; i++) {
2429 object *v = newstringobject(fontnames[i]);
2430 if (v == NULL) {
2431 DECREF(list);
2432 list = NULL;
2433 break;
2434 }
2435 setlistitem(list, i, v);
2436 }
2437 }
2438 return list;
2439}
2440
2441static object *
2442stdwin_newbitmap(self, args)
2443 object *self;
2444 object *args;
2445{
2446 int width, height;
2447 bitmapobject *bp;
2448 if (!getargs(args, "(ii)", &width, &height))
2449 return NULL;
2450 return (object *)newbitmapobject(width, height);
2451}
2452
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002453static struct methodlist stdwin_methods[] = {
2454 {"askfile", stdwin_askfile},
2455 {"askstr", stdwin_askstr},
2456 {"askync", stdwin_askync},
Guido van Rossum27201061991-04-16 08:43:03 +00002457 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossumed233a51992-06-23 09:07:03 +00002458#ifdef unix
2459 {"fileno", stdwin_connectionnumber},
2460 {"connectionnumber", stdwin_connectionnumber},
2461#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002462 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002463 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002464 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002465 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002466 {"getdefwinpos", stdwin_getdefwinpos},
2467 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002468 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002469 {"getscrmm", stdwin_getscrmm},
2470 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002471 {"getselection", stdwin_getselection},
Guido van Rossumbf80e541993-02-08 15:49:17 +00002472 {"listfontnames", stdwin_listfontnames},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473 {"menucreate", stdwin_menucreate},
2474 {"message", stdwin_message},
Guido van Rossumbf80e541993-02-08 15:49:17 +00002475 {"newbitmap", stdwin_newbitmap},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002476 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002477 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002478 {"resetselection", stdwin_resetselection},
2479 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002480 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002481 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002482 {"setdefwinpos", stdwin_setdefwinpos},
2483 {"setdefwinsize", stdwin_setdefwinsize},
2484
2485 /* Text measuring methods borrow code from drawing objects: */
2486 {"baseline", drawing_baseline},
2487 {"lineheight", drawing_lineheight},
2488 {"textbreak", drawing_textbreak},
2489 {"textwidth", drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002490
2491 /* Same for font setting methods: */
2492 {"setfont", drawing_setfont},
2493
2494 /* Same for color setting/getting methods: */
2495 {"getbgcolor", drawing_getbgcolor},
2496 {"getfgcolor", drawing_getfgcolor},
2497 {"setbgcolor", drawing_setbgcolor},
2498 {"setfgcolor", drawing_setfgcolor},
2499
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002500 {NULL, NULL} /* sentinel */
2501};
2502
2503void
2504initstdwin()
2505{
Guido van Rossumbbf94341991-12-16 15:44:53 +00002506 object *m, *d;
2507 static int inited = 0;
2508
Guido van Rossum2d14e211991-02-19 12:26:49 +00002509 if (!inited) {
2510 winit();
2511 inited = 1;
2512 }
Guido van Rossumbbf94341991-12-16 15:44:53 +00002513 m = initmodule("stdwin", stdwin_methods);
2514 d = getmoduledict(m);
2515
2516 /* Initialize stdwin.error exception */
2517 StdwinError = newstringobject("stdwin.error");
2518 if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
2519 fatal("can't define stdwin.error");
Guido van Rossumff4949e1992-08-05 19:58:53 +00002520#ifdef USE_THREAD
2521 StdwinLock = allocate_lock();
2522 if (StdwinLock == NULL)
2523 fatal("can't allocate stdwin lock");
2524#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002525}