blob: db16878c2edfd998d029ad920a70206a94da7eb8 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Stdwin module */
33
34/* Stdwin itself is a module, not a separate object type.
35 Object types defined here:
36 wp: a window
37 dp: a drawing structure (only one can exist at a time)
38 mp: a menu
39 tp: a textedit block
Guido van Rossumbf80e541993-02-08 15:49:17 +000040 bp: a bitmap
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041*/
42
43/* Rules for translating C stdwin function calls into Python stwin:
44 - All names drop their initial letter 'w'
45 - Functions with a window as first parameter are methods of window objects
46 - There is no equivalent for wclose(); just delete the window object
47 (all references to it!) (XXX maybe this is a bad idea)
48 - w.begindrawing() returns a drawing object
49 - There is no equivalent for wenddrawing(win); just delete the drawing
50 object (all references to it!) (XXX maybe this is a bad idea)
51 - Functions that may only be used inside wbegindrawing / wendddrawing
52 are methods of the drawing object; this includes the text measurement
53 functions (which however have doubles as module functions).
54 - Methods of the drawing object drop an initial 'draw' from their name
55 if they have it, e.g., wdrawline() --> d.line()
56 - The obvious type conversions: int --> intobject; string --> stringobject
57 - A text parameter followed by a length parameter is only a text (string)
58 parameter in Python
59 - A point or other pair of horizontal and vertical coordinates is always
60 a pair of integers in Python
61 - Two points forming a rectangle or endpoints of a line segment are a
62 pair of points in Python
63 - The arguments to d.elarc() are three points.
64 - The functions wgetclip() and wsetclip() are translated into
65 stdwin.getcutbuffer() and stdwin.setcutbuffer(); 'clip' is really
66 a bad word for what these functions do (clipping has a different
67 meaning in the drawing world), while cutbuffer is standard X jargon.
Guido van Rossum01769f01990-10-30 13:39:00 +000068 XXX This must change again in the light of changes to stdwin!
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 - For textedit, similar rules hold, but they are less strict.
70 XXX more?
71*/
72
Guido van Rossum3f5da241990-12-20 15:06:42 +000073#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000075#include "ceval.h"
Guido van Rossumcacd9571993-10-18 11:44:47 +000076#include "sysmodule.h"
Jack Jansendc977a91995-08-14 12:17:18 +000077#ifdef macintosh
78#include "macglue.h"
79#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000081#ifdef macintosh
Guido van Rossume9066061993-07-29 13:14:32 +000082#include ":::stdwin:H:stdwin.h"
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000083#else /* !macintosh */
Guido van Rossum3f5da241990-12-20 15:06:42 +000084#include "stdwin.h"
Guido van Rossume9066061993-07-29 13:14:32 +000085#define HAVE_BITMAPS
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000086#endif /* !macintosh */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087
Guido van Rossumb6775db1994-08-01 11:34:53 +000088#ifdef WITH_THREAD
Guido van Rossumff4949e1992-08-05 19:58:53 +000089
90#include "thread.h"
91
92static type_lock StdwinLock; /* Lock held when interpreter not locked */
93
94#define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
95#define RET_STDWIN release_lock(StdwinLock); RET_SAVE
96#define END_STDWIN release_lock(StdwinLock); END_SAVE
97
98#else
99
100#define BGN_STDWIN BGN_SAVE
101#define RET_STDWIN RET_SAVE
102#define END_STDWIN END_SAVE
103
104#endif
105
Guido van Rossum234f9421993-06-17 12:35:49 +0000106#define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
107#define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
108 a, a+1, a+2, a+3, a+4, a+5)
109#define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
110#define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
111#define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
112#define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
113 a, a+1, a+2, a+3, a+4, a+5)
114
Guido van Rossumbbf94341991-12-16 15:44:53 +0000115static object *StdwinError; /* Exception stdwin.error */
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000116
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117/* Window and menu object types declared here because of forward references */
118
119typedef struct {
120 OB_HEAD
121 object *w_title;
122 WINDOW *w_win;
123 object *w_attr; /* Attributes dictionary */
124} windowobject;
125
Guido van Rossumb6775db1994-08-01 11:34:53 +0000126staticforward typeobject Windowtype;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127
128#define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
129
130typedef struct {
131 OB_HEAD
132 MENU *m_menu;
133 int m_id;
134 object *m_attr; /* Attributes dictionary */
135} menuobject;
136
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137staticforward typeobject Menutype;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138
139#define is_menuobject(mp) ((mp)->ob_type == &Menutype)
140
Guido van Rossumbf80e541993-02-08 15:49:17 +0000141typedef struct {
142 OB_HEAD
143 BITMAP *b_bitmap;
144 object *b_attr; /* Attributes dictionary */
145} bitmapobject;
146
Guido van Rossumb6775db1994-08-01 11:34:53 +0000147staticforward typeobject Bitmaptype;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000148
149#define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
150
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151
152/* Strongly stdwin-specific argument handlers */
153
154static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155getmenudetail(v, ep)
156 object *v;
157 EVENT *ep;
158{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000159 menuobject *mp;
160 if (!getargs(v, "(Oi)", &mp, &ep->u.m.item))
161 return 0;
162 if (!is_menuobject(mp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000164 ep->u.m.id = mp->m_id;
165 return 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166}
167
168static int
169geteventarg(v, ep)
170 object *v;
171 EVENT *ep;
172{
173 object *wp, *detail;
174 int a[4];
Guido van Rossumfc58e581992-01-27 16:45:55 +0000175 if (!getargs(v, "(iOO)", &ep->type, &wp, &detail))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return 0;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000177 if (is_windowobject(wp))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 ep->window = ((windowobject *)wp) -> w_win;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000179 else if (wp == None)
180 ep->window = NULL;
181 else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 return err_badarg();
Guido van Rossumfc58e581992-01-27 16:45:55 +0000183 switch (ep->type) {
184 case WE_CHAR: {
185 char c;
186 if (!getargs(detail, "c", &c))
187 return 0;
188 ep->u.character = c;
189 return 1;
190 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 case WE_COMMAND:
192 return getintarg(detail, &ep->u.command);
193 case WE_DRAW:
194 if (!getrectarg(detail, a))
195 return 0;
196 ep->u.area.left = a[0];
197 ep->u.area.top = a[1];
198 ep->u.area.right = a[2];
199 ep->u.area.bottom = a[3];
200 return 1;
201 case WE_MOUSE_DOWN:
202 case WE_MOUSE_UP:
203 case WE_MOUSE_MOVE:
Guido van Rossumfc58e581992-01-27 16:45:55 +0000204 return getargs(detail, "((ii)iii)",
205 &ep->u.where.h, &ep->u.where.v,
206 &ep->u.where.clicks,
207 &ep->u.where.button,
208 &ep->u.where.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 case WE_MENU:
210 return getmenudetail(detail, ep);
Guido van Rossum3ee199e1992-06-30 12:48:26 +0000211 case WE_KEY:
212 return getargs(detail, "(ii)",
213 &ep->u.key.code, &ep->u.key.mask);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 default:
215 return 1;
216 }
217}
218
219
220/* Return construction tools */
221
222static object *
223makepoint(a, b)
224 int a, b;
225{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000226 return mkvalue("(ii)", a, b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227}
228
229static object *
230makerect(a, b, c, d)
231 int a, b, c, d;
232{
Guido van Rossum2ee12f41992-04-13 15:54:35 +0000233 return mkvalue("((ii)(ii))", a, b, c, d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234}
235
236
237/* Drawing objects */
238
239typedef struct {
240 OB_HEAD
241 windowobject *d_ref;
242} drawingobject;
243
244static drawingobject *Drawing; /* Set to current drawing object, or NULL */
245
246/* Drawing methods */
247
Guido van Rossum3c284741991-11-27 14:54:54 +0000248static object *
249drawing_close(dp)
250 drawingobject *dp;
251{
252 if (dp->d_ref != NULL) {
253 wenddrawing(dp->d_ref->w_win);
254 Drawing = NULL;
255 DECREF(dp->d_ref);
256 dp->d_ref = NULL;
257 }
258 INCREF(None);
259 return None;
260}
Guido van Rossum77b46041992-01-14 18:41:24 +0000261
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262static void
263drawing_dealloc(dp)
264 drawingobject *dp;
265{
Guido van Rossum3c284741991-11-27 14:54:54 +0000266 if (dp->d_ref != NULL) {
267 wenddrawing(dp->d_ref->w_win);
268 Drawing = NULL;
269 DECREF(dp->d_ref);
270 dp->d_ref = NULL;
271 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272 free((char *)dp);
273}
274
275static object *
276drawing_generic(dp, args, func)
277 drawingobject *dp;
278 object *args;
279 void (*func) FPROTO((int, int, int, int));
280{
281 int a[4];
282 if (!getrectarg(args, a))
283 return NULL;
284 (*func)(a[0], a[1], a[2], a[3]);
285 INCREF(None);
286 return None;
287}
288
289static object *
290drawing_line(dp, args)
291 drawingobject *dp;
292 object *args;
293{
Guido van Rossumbf109731991-03-06 13:14:12 +0000294 return drawing_generic(dp, args, wdrawline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295}
296
297static object *
298drawing_xorline(dp, args)
299 drawingobject *dp;
300 object *args;
301{
Guido van Rossumbf109731991-03-06 13:14:12 +0000302 return drawing_generic(dp, args, wxorline);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303}
304
305static object *
306drawing_circle(dp, args)
307 drawingobject *dp;
308 object *args;
309{
310 int a[3];
311 if (!getpointintarg(args, a))
312 return NULL;
313 wdrawcircle(a[0], a[1], a[2]);
314 INCREF(None);
315 return None;
316}
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000317
Guido van Rossum27201061991-04-16 08:43:03 +0000318static object *
319drawing_fillcircle(dp, args)
320 drawingobject *dp;
321 object *args;
322{
323 int a[3];
324 if (!getpointintarg(args, a))
325 return NULL;
326 wfillcircle(a[0], a[1], a[2]);
327 INCREF(None);
328 return None;
329}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330
331static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000332drawing_xorcircle(dp, args)
333 drawingobject *dp;
334 object *args;
335{
336 int a[3];
337 if (!getpointintarg(args, a))
338 return NULL;
339 wxorcircle(a[0], a[1], a[2]);
340 INCREF(None);
341 return None;
342}
343
344static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345drawing_elarc(dp, args)
346 drawingobject *dp;
347 object *args;
348{
349 int a[6];
350 if (!get3pointarg(args, a))
351 return NULL;
352 wdrawelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
353 INCREF(None);
354 return None;
355}
356
357static object *
Guido van Rossum27201061991-04-16 08:43:03 +0000358drawing_fillelarc(dp, args)
359 drawingobject *dp;
360 object *args;
361{
362 int a[6];
363 if (!get3pointarg(args, a))
364 return NULL;
365 wfillelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
366 INCREF(None);
367 return None;
368}
369
370static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000371drawing_xorelarc(dp, args)
372 drawingobject *dp;
373 object *args;
374{
375 int a[6];
376 if (!get3pointarg(args, a))
377 return NULL;
378 wxorelarc(a[0], a[1], a[2], a[3], a[4], a[5]);
379 INCREF(None);
380 return None;
381}
382
383static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384drawing_box(dp, args)
385 drawingobject *dp;
386 object *args;
387{
Guido van Rossumbf109731991-03-06 13:14:12 +0000388 return drawing_generic(dp, args, wdrawbox);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
391static object *
392drawing_erase(dp, args)
393 drawingobject *dp;
394 object *args;
395{
Guido van Rossumbf109731991-03-06 13:14:12 +0000396 return drawing_generic(dp, args, werase);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397}
398
399static object *
400drawing_paint(dp, args)
401 drawingobject *dp;
402 object *args;
403{
Guido van Rossumbf109731991-03-06 13:14:12 +0000404 return drawing_generic(dp, args, wpaint);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
407static object *
408drawing_invert(dp, args)
409 drawingobject *dp;
410 object *args;
411{
Guido van Rossumbf109731991-03-06 13:14:12 +0000412 return drawing_generic(dp, args, winvert);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossum27201061991-04-16 08:43:03 +0000415static POINT *
416getpointsarray(v, psize)
417 object *v;
418 int *psize;
419{
420 int n = -1;
421 object * (*getitem) PROTO((object *, int));
422 int i;
423 POINT *points;
424
425 if (v == NULL)
426 ;
427 else if (is_listobject(v)) {
428 n = getlistsize(v);
429 getitem = getlistitem;
430 }
431 else if (is_tupleobject(v)) {
432 n = gettuplesize(v);
433 getitem = gettupleitem;
434 }
435
436 if (n <= 0) {
437 (void) err_badarg();
438 return NULL;
439 }
440
441 points = NEW(POINT, n);
442 if (points == NULL) {
443 (void) err_nomem();
444 return NULL;
445 }
446
447 for (i = 0; i < n; i++) {
448 object *w = (*getitem)(v, i);
449 int a[2];
450 if (!getpointarg(w, a)) {
451 DEL(points);
452 return NULL;
453 }
454 points[i].h = a[0];
455 points[i].v = a[1];
456 }
457
458 *psize = n;
459 return points;
460}
461
462static object *
463drawing_poly(dp, args)
464 drawingobject *dp;
465 object *args;
466{
467 int n;
468 POINT *points = getpointsarray(args, &n);
469 if (points == NULL)
470 return NULL;
471 wdrawpoly(n, points);
472 DEL(points);
473 INCREF(None);
474 return None;
475}
476
477static object *
478drawing_fillpoly(dp, args)
479 drawingobject *dp;
480 object *args;
481{
482 int n;
483 POINT *points = getpointsarray(args, &n);
484 if (points == NULL)
485 return NULL;
486 wfillpoly(n, points);
487 DEL(points);
488 INCREF(None);
489 return None;
490}
491
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492static object *
Guido van Rossuma2a181a1991-05-14 12:09:25 +0000493drawing_xorpoly(dp, args)
494 drawingobject *dp;
495 object *args;
496{
497 int n;
498 POINT *points = getpointsarray(args, &n);
499 if (points == NULL)
500 return NULL;
501 wxorpoly(n, points);
502 DEL(points);
503 INCREF(None);
504 return None;
505}
506
507static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508drawing_cliprect(dp, args)
509 drawingobject *dp;
510 object *args;
511{
Guido van Rossumbf109731991-03-06 13:14:12 +0000512 return drawing_generic(dp, args, wcliprect);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
515static object *
516drawing_noclip(dp, args)
517 drawingobject *dp;
518 object *args;
519{
520 if (!getnoarg(args))
521 return NULL;
522 wnoclip();
523 INCREF(None);
524 return None;
525}
526
527static object *
528drawing_shade(dp, args)
529 drawingobject *dp;
530 object *args;
531{
532 int a[5];
533 if (!getrectintarg(args, a))
534 return NULL;
535 wshade(a[0], a[1], a[2], a[3], a[4]);
536 INCREF(None);
537 return None;
538}
539
540static object *
541drawing_text(dp, args)
542 drawingobject *dp;
543 object *args;
544{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000545 int h, v, size;
546 char *text;
547 if (!getargs(args, "((ii)s#)", &h, &v, &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000549 wdrawtext(h, v, text, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 INCREF(None);
551 return None;
552}
553
554/* The following four are also used as stdwin functions */
555
556static object *
557drawing_lineheight(dp, args)
558 drawingobject *dp;
559 object *args;
560{
561 if (!getnoarg(args))
562 return NULL;
563 return newintobject((long)wlineheight());
564}
565
566static object *
567drawing_baseline(dp, args)
568 drawingobject *dp;
569 object *args;
570{
571 if (!getnoarg(args))
572 return NULL;
573 return newintobject((long)wbaseline());
574}
575
576static object *
577drawing_textwidth(dp, args)
578 drawingobject *dp;
579 object *args;
580{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000581 char *text;
582 int size;
583 if (!getargs(args, "s#", &text, &size))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000584 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000585 return newintobject((long)wtextwidth(text, size));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586}
587
588static object *
589drawing_textbreak(dp, args)
590 drawingobject *dp;
591 object *args;
592{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000593 char *text;
594 int size, width;
595 if (!getargs(args, "(s#i)", &text, &size, &width))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000596 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000597 return newintobject((long)wtextbreak(text, size, width));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598}
599
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000600static object *
601drawing_setfont(self, args)
602 drawingobject *self;
603 object *args;
604{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000605 char *font;
606 char style = '\0';
607 int size = 0;
608 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +0000609 if (!getargs(args, "z", &font))
Guido van Rossum50429a11991-04-04 15:24:07 +0000610 return NULL;
611 }
612 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000613 int n = gettuplesize(args);
614 if (n == 2) {
615 if (!getargs(args, "(zi)", &font, &size))
616 return NULL;
617 }
618 else if (!getargs(args, "(zic)", &font, &size, &style)) {
619 err_clear();
620 if (!getargs(args, "(zci)", &font, &style, &size))
621 return NULL;
Guido van Rossum50429a11991-04-04 15:24:07 +0000622 }
623 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000624 if (font != NULL) {
625 if (!wsetfont(font)) {
626 err_setstr(StdwinError, "font not found");
627 return NULL;
628 }
629 }
Guido van Rossum50429a11991-04-04 15:24:07 +0000630 if (size != 0)
631 wsetsize(size);
Guido van Rossumfc58e581992-01-27 16:45:55 +0000632 switch (style) {
633 case 'b':
634 wsetbold();
635 break;
636 case 'i':
637 wsetitalic();
638 break;
639 case 'o':
640 wsetbolditalic();
641 break;
642 case 'u':
643 wsetunderline();
644 break;
645 case 'p':
646 wsetplain();
647 break;
648 }
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000649 INCREF(None);
650 return None;
651}
652
653static object *
654drawing_getbgcolor(self, args)
655 object *self;
656 object *args;
657{
658 if (!getnoarg(args))
659 return NULL;
660 return newintobject((long)wgetbgcolor());
661}
662
663static object *
664drawing_getfgcolor(self, args)
665 object *self;
666 object *args;
667{
668 if (!getnoarg(args))
669 return NULL;
670 return newintobject((long)wgetfgcolor());
671}
672
673static object *
674drawing_setbgcolor(self, args)
675 object *self;
676 object *args;
677{
678 long color;
679 if (!getlongarg(args, &color))
680 return NULL;
681 wsetbgcolor((COLOR)color);
682 INCREF(None);
683 return None;
684}
685
686static object *
687drawing_setfgcolor(self, args)
688 object *self;
689 object *args;
690{
691 long color;
692 if (!getlongarg(args, &color))
693 return NULL;
694 wsetfgcolor((COLOR)color);
695 INCREF(None);
696 return None;
697}
698
Guido van Rossume9066061993-07-29 13:14:32 +0000699#ifdef HAVE_BITMAPS
700
Guido van Rossumbf80e541993-02-08 15:49:17 +0000701static object *
702drawing_bitmap(self, args)
703 object *self;
704 object *args;
705{
706 int h, v;
707 object *bp;
708 object *mask = NULL;
709 if (!getargs(args, "((ii)O)", &h, &v, &bp)) {
710 err_clear();
711 if (!getargs(args, "((ii)OO)", &h, &v, &bp, &mask))
712 return NULL;
713 if (mask == None)
714 mask = NULL;
715 else if (!is_bitmapobject(mask)) {
716 err_badarg();
717 return NULL;
718 }
719 }
720 if (!is_bitmapobject(bp)) {
721 err_badarg();
722 return NULL;
723 }
724 if (((bitmapobject *)bp)->b_bitmap == NULL ||
725 mask != NULL && ((bitmapobject *)mask)->b_bitmap == NULL) {
726 err_setstr(StdwinError, "bitmap object already close");
727 return NULL;
728 }
729 if (mask == NULL)
730 wdrawbitmap(h, v, ((bitmapobject *)bp)->b_bitmap, ALLBITS);
731 else
732 wdrawbitmap(h, v,
733 ((bitmapobject *)bp)->b_bitmap,
734 ((bitmapobject *)bp)->b_bitmap);
735 INCREF(None);
736 return None;
737}
738
Guido van Rossume9066061993-07-29 13:14:32 +0000739#endif /* HAVE_BITMAPS */
740
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741static struct methodlist drawing_methods[] = {
Guido van Rossume9066061993-07-29 13:14:32 +0000742#ifdef HAVE_BITMAPS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743 {"bitmap", (method)drawing_bitmap},
Guido van Rossume9066061993-07-29 13:14:32 +0000744#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745 {"box", (method)drawing_box},
746 {"circle", (method)drawing_circle},
747 {"cliprect", (method)drawing_cliprect},
748 {"close", (method)drawing_close},
749 {"elarc", (method)drawing_elarc},
750 {"enddrawing", (method)drawing_close},
751 {"erase", (method)drawing_erase},
752 {"fillcircle", (method)drawing_fillcircle},
753 {"fillelarc", (method)drawing_fillelarc},
754 {"fillpoly", (method)drawing_fillpoly},
755 {"invert", (method)drawing_invert},
756 {"line", (method)drawing_line},
757 {"noclip", (method)drawing_noclip},
758 {"paint", (method)drawing_paint},
759 {"poly", (method)drawing_poly},
760 {"shade", (method)drawing_shade},
761 {"text", (method)drawing_text},
762 {"xorcircle", (method)drawing_xorcircle},
763 {"xorelarc", (method)drawing_xorelarc},
764 {"xorline", (method)drawing_xorline},
765 {"xorpoly", (method)drawing_xorpoly},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000766
767 /* Text measuring methods: */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000768 {"baseline", (method)drawing_baseline},
769 {"lineheight", (method)drawing_lineheight},
770 {"textbreak", (method)drawing_textbreak},
771 {"textwidth", (method)drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000772
773 /* Font setting methods: */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000774 {"setfont", (method)drawing_setfont},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000775
776 /* Color methods: */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000777 {"getbgcolor", (method)drawing_getbgcolor},
778 {"getfgcolor", (method)drawing_getfgcolor},
779 {"setbgcolor", (method)drawing_setbgcolor},
780 {"setfgcolor", (method)drawing_setfgcolor},
Guido van Rossum0c2290b1991-04-03 19:12:14 +0000781
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782 {NULL, NULL} /* sentinel */
783};
784
785static object *
Guido van Rossum77b46041992-01-14 18:41:24 +0000786drawing_getattr(dp, name)
787 drawingobject *dp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788 char *name;
789{
Guido van Rossum77b46041992-01-14 18:41:24 +0000790 if (dp->d_ref == NULL) {
791 err_setstr(StdwinError, "drawing object already closed");
792 return NULL;
793 }
794 return findmethod(drawing_methods, (object *)dp, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795}
796
Guido van Rossum541c8c01991-05-05 20:13:41 +0000797typeobject Drawingtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 OB_HEAD_INIT(&Typetype)
799 0, /*ob_size*/
800 "drawing", /*tp_name*/
801 sizeof(drawingobject), /*tp_size*/
802 0, /*tp_itemsize*/
803 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000804 (destructor)drawing_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806 (getattrfunc)drawing_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807 0, /*tp_setattr*/
808 0, /*tp_compare*/
809 0, /*tp_repr*/
810};
811
812
813/* Text(edit) objects */
814
815typedef struct {
816 OB_HEAD
817 TEXTEDIT *t_text;
818 windowobject *t_ref;
819 object *t_attr; /* Attributes dictionary */
820} textobject;
821
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822staticforward typeobject Texttype;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000823
824static textobject *
825newtextobject(wp, left, top, right, bottom)
826 windowobject *wp;
827 int left, top, right, bottom;
828{
829 textobject *tp;
830 tp = NEWOBJ(textobject, &Texttype);
831 if (tp == NULL)
832 return NULL;
833 tp->t_attr = NULL;
834 INCREF(wp);
835 tp->t_ref = wp;
836 tp->t_text = tecreate(wp->w_win, left, top, right, bottom);
837 if (tp->t_text == NULL) {
838 DECREF(tp);
839 return (textobject *) err_nomem();
840 }
841 return tp;
842}
843
844/* Text(edit) methods */
845
846static void
847text_dealloc(tp)
848 textobject *tp;
849{
850 if (tp->t_text != NULL)
851 tefree(tp->t_text);
Guido van Rossum3c284741991-11-27 14:54:54 +0000852 XDECREF(tp->t_attr);
853 XDECREF(tp->t_ref);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000854 DEL(tp);
855}
856
857static object *
Guido van Rossum3c284741991-11-27 14:54:54 +0000858text_close(tp, args)
859 textobject *tp;
860 object *args;
861{
862 if (tp->t_text != NULL) {
863 tefree(tp->t_text);
864 tp->t_text = NULL;
865 }
866 if (tp->t_attr != NULL) {
867 DECREF(tp->t_attr);
868 tp->t_attr = NULL;
869 }
870 if (tp->t_ref != NULL) {
871 DECREF(tp->t_ref);
872 tp->t_ref = NULL;
873 }
874 INCREF(None);
875 return None;
876}
877
878static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000879text_arrow(self, args)
880 textobject *self;
881 object *args;
882{
883 int code;
884 if (!getintarg(args, &code))
885 return NULL;
886 tearrow(self->t_text, code);
887 INCREF(None);
888 return None;
889}
890
891static object *
892text_draw(self, args)
893 textobject *self;
894 object *args;
895{
896 register TEXTEDIT *tp = self->t_text;
897 int a[4];
898 int left, top, right, bottom;
899 if (!getrectarg(args, a))
900 return NULL;
901 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000902 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000903 return NULL;
904 }
905 /* Clip to text area and ignore if area is empty */
906 left = tegetleft(tp);
907 top = tegettop(tp);
908 right = tegetright(tp);
909 bottom = tegetbottom(tp);
910 if (a[0] < left) a[0] = left;
911 if (a[1] < top) a[1] = top;
912 if (a[2] > right) a[2] = right;
913 if (a[3] > bottom) a[3] = bottom;
914 if (a[0] < a[2] && a[1] < a[3]) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 wbegindrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916 tedrawnew(tp, a[0], a[1], a[2], a[3]);
917 wenddrawing(self->t_ref->w_win);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 }
919 INCREF(None);
920 return None;
921}
922
923static object *
924text_event(self, args)
925 textobject *self;
926 object *args;
927{
928 register TEXTEDIT *tp = self->t_text;
929 EVENT e;
930 if (!geteventarg(args, &e))
931 return NULL;
932 if (e.type == WE_MOUSE_DOWN) {
Guido van Rossum33f17701991-02-13 23:19:39 +0000933 /* Cheat at the margins */
934 int width, height;
935 wgetdocsize(e.window, &width, &height);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000936 if (e.u.where.h < 0 && tegetleft(tp) == 0)
937 e.u.where.h = 0;
Guido van Rossum33f17701991-02-13 23:19:39 +0000938 else if (e.u.where.h > width && tegetright(tp) == width)
939 e.u.where.h = width;
940 if (e.u.where.v < 0 && tegettop(tp) == 0)
941 e.u.where.v = 0;
942 else if (e.u.where.v > height && tegetright(tp) == height)
943 e.u.where.v = height;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944 }
945 return newintobject((long) teevent(tp, &e));
946}
947
948static object *
949text_getfocus(self, args)
950 textobject *self;
951 object *args;
952{
953 if (!getnoarg(args))
954 return NULL;
955 return makepoint(tegetfoc1(self->t_text), tegetfoc2(self->t_text));
956}
957
958static object *
959text_getfocustext(self, args)
960 textobject *self;
961 object *args;
962{
963 int f1, f2;
964 char *text;
965 if (!getnoarg(args))
966 return NULL;
967 f1 = tegetfoc1(self->t_text);
968 f2 = tegetfoc2(self->t_text);
969 text = tegettext(self->t_text);
970 return newsizedstringobject(text + f1, f2-f1);
971}
972
973static object *
974text_getrect(self, args)
975 textobject *self;
976 object *args;
977{
978 if (!getnoarg(args))
979 return NULL;
980 return makerect(tegetleft(self->t_text),
981 tegettop(self->t_text),
982 tegetright(self->t_text),
983 tegetbottom(self->t_text));
984}
985
986static object *
987text_gettext(self, args)
988 textobject *self;
989 object *args;
990{
991 if (!getnoarg(args))
992 return NULL;
993 return newsizedstringobject(tegettext(self->t_text),
994 tegetlen(self->t_text));
995}
996
997static object *
998text_move(self, args)
999 textobject *self;
1000 object *args;
1001{
1002 int a[4];
1003 if (!getrectarg(args, a))
1004 return NULL;
1005 temovenew(self->t_text, a[0], a[1], a[2], a[3]);
1006 INCREF(None);
1007 return None;
1008}
1009
1010static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001011text_replace(self, args)
1012 textobject *self;
1013 object *args;
1014{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001015 char *text;
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001016 if (!getstrarg(args, &text))
1017 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001018 tereplace(self->t_text, text);
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001019 INCREF(None);
1020 return None;
1021}
1022
1023static object *
1024text_setactive(self, args)
1025 textobject *self;
1026 object *args;
1027{
1028 int flag;
1029 if (!getintarg(args, &flag))
1030 return NULL;
1031 tesetactive(self->t_text, flag);
1032 INCREF(None);
1033 return None;
1034}
1035
1036static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001037text_setfocus(self, args)
1038 textobject *self;
1039 object *args;
1040{
1041 int a[2];
1042 if (!getpointarg(args, a))
1043 return NULL;
1044 tesetfocus(self->t_text, a[0], a[1]);
1045 INCREF(None);
1046 return None;
1047}
1048
1049static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001050text_settext(self, args)
1051 textobject *self;
1052 object *args;
1053{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001054 char *text;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001055 char *buf;
1056 int size;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001057 if (!getargs(args, "s#", &text, &size))
Guido van Rossum541c8c01991-05-05 20:13:41 +00001058 return NULL;
Guido van Rossum541c8c01991-05-05 20:13:41 +00001059 if ((buf = NEW(char, size)) == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001060 return err_nomem();
Guido van Rossum541c8c01991-05-05 20:13:41 +00001061 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001062 memcpy(buf, text, size);
Guido van Rossum541c8c01991-05-05 20:13:41 +00001063 tesetbuf(self->t_text, buf, size); /* Becomes owner of buffer */
1064 INCREF(None);
1065 return None;
1066}
1067
1068static object *
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001069text_setview(self, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070 textobject *self;
1071 object *args;
1072{
Guido van Rossum4b9cf8e1991-05-28 21:57:04 +00001073 int a[4];
1074 if (args == None)
1075 tenoview(self->t_text);
1076 else {
1077 if (!getrectarg(args, a))
1078 return NULL;
1079 tesetview(self->t_text, a[0], a[1], a[2], a[3]);
1080 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081 INCREF(None);
1082 return None;
1083}
1084
1085static struct methodlist text_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001086 {"arrow", (method)text_arrow},
1087 {"close", (method)text_close},
1088 {"draw", (method)text_draw},
1089 {"event", (method)text_event},
1090 {"getfocus", (method)text_getfocus},
1091 {"getfocustext",(method)text_getfocustext},
1092 {"getrect", (method)text_getrect},
1093 {"gettext", (method)text_gettext},
1094 {"move", (method)text_move},
1095 {"replace", (method)text_replace},
1096 {"setactive", (method)text_setactive},
1097 {"setfocus", (method)text_setfocus},
1098 {"settext", (method)text_settext},
1099 {"setview", (method)text_setview},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001100 {NULL, NULL} /* sentinel */
1101};
1102
1103static object *
1104text_getattr(tp, name)
1105 textobject *tp;
1106 char *name;
1107{
Guido van Rossum85f50761991-10-20 20:22:50 +00001108 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001109 if (tp->t_ref == NULL) {
1110 err_setstr(StdwinError, "text object already closed");
1111 return NULL;
1112 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001113 if (strcmp(name, "__dict__") == 0) {
1114 v = tp->t_attr;
1115 if (v == NULL)
1116 v = None;
1117 }
1118 else if (tp->t_attr != NULL) {
1119 v = dictlookup(tp->t_attr, name);
1120 }
1121 if (v != NULL) {
1122 INCREF(v);
1123 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124 }
1125 return findmethod(text_methods, (object *)tp, name);
1126}
1127
1128static int
1129text_setattr(tp, name, v)
1130 textobject *tp;
1131 char *name;
1132 object *v;
1133{
1134 if (tp->t_attr == NULL) {
1135 tp->t_attr = newdictobject();
1136 if (tp->t_attr == NULL)
1137 return -1;
1138 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001139 if (v == NULL) {
1140 int rv = dictremove(tp->t_attr, name);
1141 if (rv < 0)
1142 err_setstr(AttributeError,
1143 "delete non-existing text object attribute");
1144 return rv;
1145 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146 else
1147 return dictinsert(tp->t_attr, name, v);
1148}
1149
Guido van Rossuma320fd31995-03-09 12:14:15 +00001150statichere typeobject Texttype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001151 OB_HEAD_INIT(&Typetype)
1152 0, /*ob_size*/
1153 "textedit", /*tp_name*/
1154 sizeof(textobject), /*tp_size*/
1155 0, /*tp_itemsize*/
1156 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001157 (destructor)text_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001159 (getattrfunc)text_getattr, /*tp_getattr*/
1160 (setattrfunc)text_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 0, /*tp_compare*/
1162 0, /*tp_repr*/
1163};
1164
1165
1166/* Menu objects */
1167
Guido van Rossum2d14e211991-02-19 12:26:49 +00001168#define IDOFFSET 10 /* Menu IDs we use start here */
Guido van Rossum27201061991-04-16 08:43:03 +00001169#define MAXNMENU 200 /* Max #menus we allow */
Guido van Rossum2d14e211991-02-19 12:26:49 +00001170static menuobject *menulist[MAXNMENU];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171
Guido van Rossumfc58e581992-01-27 16:45:55 +00001172static menuobject *newmenuobject PROTO((char *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173static menuobject *
1174newmenuobject(title)
Guido van Rossumfc58e581992-01-27 16:45:55 +00001175 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176{
1177 int id;
1178 MENU *menu;
1179 menuobject *mp;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001180 for (id = 0; id < MAXNMENU; id++) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181 if (menulist[id] == NULL)
1182 break;
1183 }
Guido van Rossum27201061991-04-16 08:43:03 +00001184 if (id >= MAXNMENU) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001185 err_setstr(StdwinError, "creating too many menus");
Guido van Rossum27201061991-04-16 08:43:03 +00001186 return NULL;
1187 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001188 menu = wmenucreate(id + IDOFFSET, title);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189 if (menu == NULL)
1190 return (menuobject *) err_nomem();
1191 mp = NEWOBJ(menuobject, &Menutype);
1192 if (mp != NULL) {
1193 mp->m_menu = menu;
Guido van Rossum2d14e211991-02-19 12:26:49 +00001194 mp->m_id = id + IDOFFSET;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195 mp->m_attr = NULL;
1196 menulist[id] = mp;
1197 }
1198 else
1199 wmenudelete(menu);
1200 return mp;
1201}
1202
1203/* Menu methods */
1204
1205static void
1206menu_dealloc(mp)
1207 menuobject *mp;
1208{
1209
Guido van Rossum2d14e211991-02-19 12:26:49 +00001210 int id = mp->m_id - IDOFFSET;
1211 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001212 menulist[id] = NULL;
1213 }
Guido van Rossum77b46041992-01-14 18:41:24 +00001214 if (mp->m_menu != NULL)
1215 wmenudelete(mp->m_menu);
1216 XDECREF(mp->m_attr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217 DEL(mp);
1218}
1219
1220static object *
Guido van Rossum77b46041992-01-14 18:41:24 +00001221menu_close(mp, args)
1222 menuobject *mp;
1223 object *args;
1224{
1225 int id = mp->m_id - IDOFFSET;
1226 if (id >= 0 && id < MAXNMENU && menulist[id] == mp) {
1227 menulist[id] = NULL;
1228 }
1229 mp->m_id = -1;
1230 if (mp->m_menu != NULL)
1231 wmenudelete(mp->m_menu);
1232 mp->m_menu = NULL;
1233 XDECREF(mp->m_attr);
1234 mp->m_attr = NULL;
1235 INCREF(None);
1236 return None;
1237}
1238
1239static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001240menu_additem(self, args)
1241 menuobject *self;
1242 object *args;
1243{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001244 char *text;
1245 int shortcut = -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246 if (is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +00001247 char c;
1248 if (!getargs(args, "(sc)", &text, &c))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001250 shortcut = c;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251 }
Guido van Rossumfc58e581992-01-27 16:45:55 +00001252 else if (!getstrarg(args, &text))
1253 return NULL;
1254 wmenuadditem(self->m_menu, text, shortcut);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001255 INCREF(None);
1256 return None;
1257}
1258
1259static object *
1260menu_setitem(self, args)
1261 menuobject *self;
1262 object *args;
1263{
1264 int index;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001265 char *text;
Guido van Rossum234f9421993-06-17 12:35:49 +00001266 if (!getargs(args, "(is)", &index, &text))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001268 wmenusetitem(self->m_menu, index, text);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269 INCREF(None);
1270 return None;
1271}
1272
1273static object *
1274menu_enable(self, args)
1275 menuobject *self;
1276 object *args;
1277{
1278 int index;
1279 int flag;
Guido van Rossum234f9421993-06-17 12:35:49 +00001280 if (!getargs(args, "(ii)", &index, &flag))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281 return NULL;
1282 wmenuenable(self->m_menu, index, flag);
1283 INCREF(None);
1284 return None;
1285}
1286
1287static object *
1288menu_check(self, args)
1289 menuobject *self;
1290 object *args;
1291{
1292 int index;
1293 int flag;
Guido van Rossum234f9421993-06-17 12:35:49 +00001294 if (!getargs(args, "(ii)", &index, &flag))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295 return NULL;
1296 wmenucheck(self->m_menu, index, flag);
1297 INCREF(None);
1298 return None;
1299}
1300
1301static struct methodlist menu_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001302 {"additem", (method)menu_additem},
1303 {"setitem", (method)menu_setitem},
1304 {"enable", (method)menu_enable},
1305 {"check", (method)menu_check},
1306 {"close", (method)menu_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307 {NULL, NULL} /* sentinel */
1308};
1309
1310static object *
1311menu_getattr(mp, name)
1312 menuobject *mp;
1313 char *name;
1314{
Guido van Rossum85f50761991-10-20 20:22:50 +00001315 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001316 if (mp->m_menu == NULL) {
1317 err_setstr(StdwinError, "menu object already closed");
1318 return NULL;
1319 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001320 if (strcmp(name, "__dict__") == 0) {
1321 v = mp->m_attr;
1322 if (v == NULL)
1323 v = None;
1324 }
1325 else if (mp->m_attr != NULL) {
1326 v = dictlookup(mp->m_attr, name);
1327 }
1328 if (v != NULL) {
1329 INCREF(v);
1330 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331 }
1332 return findmethod(menu_methods, (object *)mp, name);
1333}
1334
1335static int
1336menu_setattr(mp, name, v)
1337 menuobject *mp;
1338 char *name;
1339 object *v;
1340{
1341 if (mp->m_attr == NULL) {
1342 mp->m_attr = newdictobject();
1343 if (mp->m_attr == NULL)
1344 return -1;
1345 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001346 if (v == NULL) {
1347 int rv = dictremove(mp->m_attr, name);
1348 if (rv < 0)
1349 err_setstr(AttributeError,
1350 "delete non-existing menu object attribute");
1351 return rv;
1352 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353 else
1354 return dictinsert(mp->m_attr, name, v);
1355}
1356
Guido van Rossuma320fd31995-03-09 12:14:15 +00001357statichere typeobject Menutype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358 OB_HEAD_INIT(&Typetype)
1359 0, /*ob_size*/
1360 "menu", /*tp_name*/
1361 sizeof(menuobject), /*tp_size*/
1362 0, /*tp_itemsize*/
1363 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001364 (destructor)menu_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001366 (getattrfunc)menu_getattr, /*tp_getattr*/
1367 (setattrfunc)menu_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001368 0, /*tp_compare*/
1369 0, /*tp_repr*/
1370};
1371
1372
Guido van Rossume9066061993-07-29 13:14:32 +00001373#ifdef HAVE_BITMAPS
1374
Guido van Rossumbf80e541993-02-08 15:49:17 +00001375/* Bitmaps objects */
1376
1377static bitmapobject *newbitmapobject PROTO((int, int));
1378static bitmapobject *
1379newbitmapobject(width, height)
1380 int width, height;
1381{
1382 BITMAP *bitmap;
1383 bitmapobject *bp;
1384 bitmap = wnewbitmap(width, height);
1385 if (bitmap == NULL)
1386 return (bitmapobject *) err_nomem();
1387 bp = NEWOBJ(bitmapobject, &Bitmaptype);
1388 if (bp != NULL) {
1389 bp->b_bitmap = bitmap;
1390 bp->b_attr = NULL;
1391 }
1392 else
1393 wfreebitmap(bitmap);
1394 return bp;
1395}
1396
1397/* Bitmap methods */
1398
1399static void
1400bitmap_dealloc(bp)
1401 bitmapobject *bp;
1402{
1403 if (bp->b_bitmap != NULL)
1404 wfreebitmap(bp->b_bitmap);
1405 XDECREF(bp->b_attr);
1406 DEL(bp);
1407}
1408
1409static object *
1410bitmap_close(bp, args)
1411 bitmapobject *bp;
1412 object *args;
1413{
1414 if (bp->b_bitmap != NULL)
1415 wfreebitmap(bp->b_bitmap);
1416 bp->b_bitmap = NULL;
1417 XDECREF(bp->b_attr);
1418 bp->b_attr = NULL;
1419 INCREF(None);
1420 return None;
1421}
1422
1423static object *
1424bitmap_setbit(self, args)
1425 bitmapobject *self;
1426 object *args;
1427{
1428 int a[3];
1429 if (!getpointintarg(args, a))
1430 return NULL;
1431 wsetbit(self->b_bitmap, a[0], a[1], a[2]);
1432 INCREF(None);
1433 return None;
1434}
1435
1436static object *
1437bitmap_getbit(self, args)
1438 bitmapobject *self;
1439 object *args;
1440{
1441 int a[2];
1442 if (!getpointarg(args, a))
1443 return NULL;
1444 return newintobject((long) wgetbit(self->b_bitmap, a[0], a[1]));
1445}
1446
1447static object *
1448bitmap_getsize(self, args)
1449 bitmapobject *self;
1450 object *args;
1451{
1452 int width, height;
1453 if (!getnoarg(args))
1454 return NULL;
1455 wgetbitmapsize(self->b_bitmap, &width, &height);
1456 return mkvalue("(ii)", width, height);
1457}
1458
1459static struct methodlist bitmap_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001460 {"close", (method)bitmap_close},
1461 {"getsize", (method)bitmap_getsize},
1462 {"getbit", (method)bitmap_getbit},
1463 {"setbit", (method)bitmap_setbit},
Guido van Rossumbf80e541993-02-08 15:49:17 +00001464 {NULL, NULL} /* sentinel */
1465};
1466
1467static object *
1468bitmap_getattr(bp, name)
1469 bitmapobject *bp;
1470 char *name;
1471{
1472 object *v = NULL;
1473 if (bp->b_bitmap == NULL) {
1474 err_setstr(StdwinError, "bitmap object already closed");
1475 return NULL;
1476 }
1477 if (strcmp(name, "__dict__") == 0) {
1478 v = bp->b_attr;
1479 if (v == NULL)
1480 v = None;
1481 }
1482 else if (bp->b_attr != NULL) {
1483 v = dictlookup(bp->b_attr, name);
1484 }
1485 if (v != NULL) {
1486 INCREF(v);
1487 return v;
1488 }
1489 return findmethod(bitmap_methods, (object *)bp, name);
1490}
1491
1492static int
1493bitmap_setattr(bp, name, v)
1494 bitmapobject *bp;
1495 char *name;
1496 object *v;
1497{
1498 if (bp->b_attr == NULL) {
1499 bp->b_attr = newdictobject();
1500 if (bp->b_attr == NULL)
1501 return -1;
1502 }
1503 if (v == NULL) {
1504 int rv = dictremove(bp->b_attr, name);
1505 if (rv < 0)
1506 err_setstr(AttributeError,
1507 "delete non-existing bitmap object attribute");
1508 return rv;
1509 }
1510 else
1511 return dictinsert(bp->b_attr, name, v);
1512}
1513
Guido van Rossuma320fd31995-03-09 12:14:15 +00001514statichere typeobject Bitmaptype = {
Guido van Rossumbf80e541993-02-08 15:49:17 +00001515 OB_HEAD_INIT(&Typetype)
1516 0, /*ob_size*/
1517 "bitmap", /*tp_name*/
1518 sizeof(bitmapobject), /*tp_size*/
1519 0, /*tp_itemsize*/
1520 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 (destructor)bitmap_dealloc, /*tp_dealloc*/
Guido van Rossumbf80e541993-02-08 15:49:17 +00001522 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001523 (getattrfunc)bitmap_getattr, /*tp_getattr*/
1524 (setattrfunc)bitmap_setattr, /*tp_setattr*/
Guido van Rossumbf80e541993-02-08 15:49:17 +00001525 0, /*tp_compare*/
1526 0, /*tp_repr*/
1527};
1528
Guido van Rossume9066061993-07-29 13:14:32 +00001529#endif /* HAVE_BITMAPS */
1530
Guido van Rossumbf80e541993-02-08 15:49:17 +00001531
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001532/* Windows */
1533
1534#define MAXNWIN 50
1535static windowobject *windowlist[MAXNWIN];
1536
1537/* Window methods */
1538
1539static void
1540window_dealloc(wp)
1541 windowobject *wp;
1542{
1543 if (wp->w_win != NULL) {
1544 int tag = wgettag(wp->w_win);
1545 if (tag >= 0 && tag < MAXNWIN)
1546 windowlist[tag] = NULL;
1547 else
1548 fprintf(stderr, "XXX help! tag %d in window_dealloc\n",
1549 tag);
1550 wclose(wp->w_win);
1551 }
1552 DECREF(wp->w_title);
1553 if (wp->w_attr != NULL)
1554 DECREF(wp->w_attr);
1555 free((char *)wp);
1556}
1557
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001558static object *
Guido van Rossum3c284741991-11-27 14:54:54 +00001559window_close(wp, args)
1560 windowobject *wp;
1561 object *args;
1562{
1563 if (wp->w_win != NULL) {
1564 int tag = wgettag(wp->w_win);
1565 if (tag >= 0 && tag < MAXNWIN)
1566 windowlist[tag] = NULL;
1567 wclose(wp->w_win);
1568 wp->w_win = NULL;
1569 }
1570 INCREF(None);
1571 return None;
1572}
1573
1574static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001575window_begindrawing(wp, args)
1576 windowobject *wp;
1577 object *args;
1578{
1579 drawingobject *dp;
1580 if (!getnoarg(args))
1581 return NULL;
1582 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001583 err_setstr(StdwinError, "already drawing");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001584 return NULL;
1585 }
1586 dp = NEWOBJ(drawingobject, &Drawingtype);
1587 if (dp == NULL)
1588 return NULL;
1589 Drawing = dp;
1590 INCREF(wp);
1591 dp->d_ref = wp;
1592 wbegindrawing(wp->w_win);
1593 return (object *)dp;
1594}
1595
1596static object *
1597window_change(wp, args)
1598 windowobject *wp;
1599 object *args;
1600{
1601 int a[4];
1602 if (!getrectarg(args, a))
1603 return NULL;
1604 wchange(wp->w_win, a[0], a[1], a[2], a[3]);
1605 INCREF(None);
1606 return None;
1607}
1608
1609static object *
1610window_gettitle(wp, args)
1611 windowobject *wp;
1612 object *args;
1613{
1614 if (!getnoarg(args))
1615 return NULL;
1616 INCREF(wp->w_title);
1617 return wp->w_title;
1618}
1619
1620static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00001621window_getwinpos(wp, args)
1622 windowobject *wp;
1623 object *args;
1624{
1625 int h, v;
1626 if (!getnoarg(args))
1627 return NULL;
1628 wgetwinpos(wp->w_win, &h, &v);
1629 return makepoint(h, v);
1630}
1631
1632static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633window_getwinsize(wp, args)
1634 windowobject *wp;
1635 object *args;
1636{
1637 int width, height;
1638 if (!getnoarg(args))
1639 return NULL;
1640 wgetwinsize(wp->w_win, &width, &height);
1641 return makepoint(width, height);
1642}
1643
1644static object *
Guido van Rossumbf80e541993-02-08 15:49:17 +00001645window_setwinpos(wp, args)
1646 windowobject *wp;
1647 object *args;
1648{
1649 int a[2];
1650 if (!getpointarg(args, a))
1651 return NULL;
1652 wsetwinpos(wp->w_win, a[0], a[1]);
1653 INCREF(None);
1654 return None;
1655}
1656
1657static object *
1658window_setwinsize(wp, args)
1659 windowobject *wp;
1660 object *args;
1661{
1662 int a[2];
1663 if (!getpointarg(args, a))
1664 return NULL;
1665 wsetwinsize(wp->w_win, a[0], a[1]);
1666 INCREF(None);
1667 return None;
1668}
1669
1670static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001671window_getdocsize(wp, args)
1672 windowobject *wp;
1673 object *args;
1674{
1675 int width, height;
1676 if (!getnoarg(args))
1677 return NULL;
1678 wgetdocsize(wp->w_win, &width, &height);
1679 return makepoint(width, height);
1680}
1681
1682static object *
1683window_getorigin(wp, args)
1684 windowobject *wp;
1685 object *args;
1686{
1687 int width, height;
1688 if (!getnoarg(args))
1689 return NULL;
1690 wgetorigin(wp->w_win, &width, &height);
1691 return makepoint(width, height);
1692}
1693
1694static object *
1695window_scroll(wp, args)
1696 windowobject *wp;
1697 object *args;
1698{
1699 int a[6];
1700 if (!getrectpointarg(args, a))
1701 return NULL;
1702 wscroll(wp->w_win, a[0], a[1], a[2], a[3], a[4], a[5]);
1703 INCREF(None);
1704 return None;
1705}
1706
1707static object *
1708window_setdocsize(wp, args)
1709 windowobject *wp;
1710 object *args;
1711{
1712 int a[2];
1713 if (!getpointarg(args, a))
1714 return NULL;
1715 wsetdocsize(wp->w_win, a[0], a[1]);
1716 INCREF(None);
1717 return None;
1718}
1719
1720static object *
1721window_setorigin(wp, args)
1722 windowobject *wp;
1723 object *args;
1724{
1725 int a[2];
1726 if (!getpointarg(args, a))
1727 return NULL;
1728 wsetorigin(wp->w_win, a[0], a[1]);
1729 INCREF(None);
1730 return None;
1731}
1732
1733static object *
1734window_settitle(wp, args)
1735 windowobject *wp;
1736 object *args;
1737{
1738 object *title;
Guido van Rossum234f9421993-06-17 12:35:49 +00001739 if (!getargs(args, "S", &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001740 return NULL;
1741 DECREF(wp->w_title);
1742 INCREF(title);
1743 wp->w_title = title;
1744 wsettitle(wp->w_win, getstringvalue(title));
1745 INCREF(None);
1746 return None;
1747}
1748
1749static object *
1750window_show(wp, args)
1751 windowobject *wp;
1752 object *args;
1753{
1754 int a[4];
1755 if (!getrectarg(args, a))
1756 return NULL;
1757 wshow(wp->w_win, a[0], a[1], a[2], a[3]);
1758 INCREF(None);
1759 return None;
1760}
1761
1762static object *
1763window_settimer(wp, args)
1764 windowobject *wp;
1765 object *args;
1766{
1767 int a;
1768 if (!getintarg(args, &a))
1769 return NULL;
1770 wsettimer(wp->w_win, a);
1771 INCREF(None);
1772 return None;
1773}
1774
1775static object *
1776window_menucreate(self, args)
1777 windowobject *self;
1778 object *args;
1779{
1780 menuobject *mp;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001781 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001782 if (!getstrarg(args, &title))
1783 return NULL;
1784 wmenusetdeflocal(1);
1785 mp = newmenuobject(title);
1786 if (mp == NULL)
1787 return NULL;
1788 wmenuattach(self->w_win, mp->m_menu);
1789 return (object *)mp;
1790}
1791
1792static object *
1793window_textcreate(self, args)
1794 windowobject *self;
1795 object *args;
1796{
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001797 int a[4];
1798 if (!getrectarg(args, a))
1799 return NULL;
1800 return (object *)
1801 newtextobject(self, a[0], a[1], a[2], a[3]);
1802}
1803
Guido van Rossum5b10f451990-10-30 16:01:48 +00001804static object *
1805window_setselection(self, args)
1806 windowobject *self;
1807 object *args;
1808{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001809 int sel, size, ok;
1810 char *text;
1811 if (!getargs(args, "(is#)", &sel, &text, &size))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001812 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00001813 ok = wsetselection(self->w_win, sel, text, size);
Guido van Rossum5b10f451990-10-30 16:01:48 +00001814 return newintobject(ok);
1815}
1816
1817static object *
1818window_setwincursor(self, args)
1819 windowobject *self;
1820 object *args;
1821{
Guido van Rossumfc58e581992-01-27 16:45:55 +00001822 char *name;
Guido van Rossum5b10f451990-10-30 16:01:48 +00001823 CURSOR *c;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001824 if (!getargs(args, "z", &name))
Guido van Rossum5b10f451990-10-30 16:01:48 +00001825 return NULL;
Guido van Rossum3c8ba7a1992-02-05 11:15:00 +00001826 if (name == NULL)
1827 c = NULL;
1828 else {
1829 c = wfetchcursor(name);
1830 if (c == NULL) {
1831 err_setstr(StdwinError, "no such cursor");
1832 return NULL;
1833 }
Guido van Rossum5b10f451990-10-30 16:01:48 +00001834 }
1835 wsetwincursor(self->w_win, c);
1836 INCREF(None);
1837 return None;
1838}
1839
Guido van Rossumfc58e581992-01-27 16:45:55 +00001840static object *
1841window_setactive(self, args)
1842 windowobject *self;
1843 object *args;
1844{
1845 if (!getnoarg(args))
1846 return NULL;
1847 wsetactive(self->w_win);
1848 INCREF(None);
1849 return None;
1850}
1851
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001852#ifdef CWI_HACKS
1853static object *
1854window_getxwindowid(self, args)
1855 windowobject *self;
1856 object *args;
1857{
1858 long wid = wgetxwindowid(self->w_win);
1859 return newintobject(wid);
1860}
1861#endif
1862
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001863static struct methodlist window_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001864 {"begindrawing",(method)window_begindrawing},
1865 {"change", (method)window_change},
1866 {"close", (method)window_close},
1867 {"getdocsize", (method)window_getdocsize},
1868 {"getorigin", (method)window_getorigin},
1869 {"gettitle", (method)window_gettitle},
1870 {"getwinpos", (method)window_getwinpos},
1871 {"getwinsize", (method)window_getwinsize},
1872 {"menucreate", (method)window_menucreate},
1873 {"scroll", (method)window_scroll},
1874 {"setactive", (method)window_setactive},
1875 {"setdocsize", (method)window_setdocsize},
1876 {"setorigin", (method)window_setorigin},
1877 {"setselection",(method)window_setselection},
1878 {"settimer", (method)window_settimer},
1879 {"settitle", (method)window_settitle},
1880 {"setwincursor",(method)window_setwincursor},
1881 {"setwinpos", (method)window_setwinpos},
1882 {"setwinsize", (method)window_setwinsize},
1883 {"show", (method)window_show},
1884 {"textcreate", (method)window_textcreate},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001885#ifdef CWI_HACKS
Guido van Rossumb6775db1994-08-01 11:34:53 +00001886 {"getxwindowid",(method)window_getxwindowid},
Guido van Rossum8dcbbac1991-07-27 21:42:24 +00001887#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001888 {NULL, NULL} /* sentinel */
1889};
1890
1891static object *
1892window_getattr(wp, name)
1893 windowobject *wp;
1894 char *name;
1895{
Guido van Rossum85f50761991-10-20 20:22:50 +00001896 object *v = NULL;
Guido van Rossum77b46041992-01-14 18:41:24 +00001897 if (wp->w_win == NULL) {
1898 err_setstr(StdwinError, "window already closed");
1899 return NULL;
1900 }
Guido van Rossum85f50761991-10-20 20:22:50 +00001901 if (strcmp(name, "__dict__") == 0) {
1902 v = wp->w_attr;
1903 if (v == NULL)
1904 v = None;
1905 }
1906 else if (wp->w_attr != NULL) {
1907 v = dictlookup(wp->w_attr, name);
1908 }
1909 if (v != NULL) {
1910 INCREF(v);
1911 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001912 }
1913 return findmethod(window_methods, (object *)wp, name);
1914}
1915
1916static int
1917window_setattr(wp, name, v)
1918 windowobject *wp;
1919 char *name;
1920 object *v;
1921{
1922 if (wp->w_attr == NULL) {
1923 wp->w_attr = newdictobject();
1924 if (wp->w_attr == NULL)
1925 return -1;
1926 }
Guido van Rossum94472a01992-09-04 09:45:18 +00001927 if (v == NULL) {
1928 int rv = dictremove(wp->w_attr, name);
1929 if (rv < 0)
1930 err_setstr(AttributeError,
1931 "delete non-existing menu object attribute");
1932 return rv;
1933 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001934 else
1935 return dictinsert(wp->w_attr, name, v);
1936}
1937
Guido van Rossuma320fd31995-03-09 12:14:15 +00001938statichere typeobject Windowtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001939 OB_HEAD_INIT(&Typetype)
1940 0, /*ob_size*/
1941 "window", /*tp_name*/
1942 sizeof(windowobject), /*tp_size*/
1943 0, /*tp_itemsize*/
1944 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001945 (destructor)window_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001946 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001947 (getattrfunc)window_getattr, /*tp_getattr*/
1948 (setattrfunc)window_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001949 0, /*tp_compare*/
1950 0, /*tp_repr*/
1951};
1952
1953/* Stdwin methods */
1954
1955static object *
Guido van Rossumcacd9571993-10-18 11:44:47 +00001956stdwin_done(sw, args)
1957 object *sw;
1958 object *args;
1959{
1960 if (!getnoarg(args))
1961 return NULL;
1962 wdone();
1963 /* XXX There is no protection against continued use of
1964 XXX stdwin functions or objects after this call is made.
1965 XXX Use at own risk */
1966 INCREF(None);
1967 return None;
1968}
1969
1970static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001971stdwin_open(sw, args)
1972 object *sw;
1973 object *args;
1974{
1975 int tag;
1976 object *title;
1977 windowobject *wp;
Guido van Rossum234f9421993-06-17 12:35:49 +00001978 if (!getargs(args, "S", &title))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001979 return NULL;
1980 for (tag = 0; tag < MAXNWIN; tag++) {
1981 if (windowlist[tag] == NULL)
1982 break;
1983 }
Guido van Rossum27201061991-04-16 08:43:03 +00001984 if (tag >= MAXNWIN) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001985 err_setstr(StdwinError, "creating too many windows");
Guido van Rossum27201061991-04-16 08:43:03 +00001986 return NULL;
1987 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988 wp = NEWOBJ(windowobject, &Windowtype);
1989 if (wp == NULL)
1990 return NULL;
1991 INCREF(title);
1992 wp->w_title = title;
1993 wp->w_win = wopen(getstringvalue(title), (void (*)()) NULL);
1994 wp->w_attr = NULL;
1995 if (wp->w_win == NULL) {
1996 DECREF(wp);
1997 return NULL;
1998 }
1999 windowlist[tag] = wp;
2000 wsettag(wp->w_win, tag);
2001 return (object *)wp;
2002}
2003
2004static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002005window2object(win)
2006 WINDOW *win;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002007{
Guido van Rossum246b9d81991-06-03 10:55:14 +00002008 object *w;
2009 if (win == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002010 w = None;
2011 else {
Guido van Rossum246b9d81991-06-03 10:55:14 +00002012 int tag = wgettag(win);
2013 if (tag < 0 || tag >= MAXNWIN || windowlist[tag] == NULL ||
2014 windowlist[tag]->w_win != win)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002015 w = None;
2016 else
2017 w = (object *)windowlist[tag];
2018 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002019 INCREF(w);
Guido van Rossum246b9d81991-06-03 10:55:14 +00002020 return w;
2021}
2022
2023static object *
2024stdwin_get_poll_event(poll, args)
2025 int poll;
2026 object *args;
2027{
2028 EVENT e;
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002029 object *u, *v, *w;
Guido van Rossum246b9d81991-06-03 10:55:14 +00002030 if (!getnoarg(args))
2031 return NULL;
2032 if (Drawing != NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00002033 err_setstr(StdwinError, "cannot getevent() while drawing");
Guido van Rossum246b9d81991-06-03 10:55:14 +00002034 return NULL;
2035 }
2036 again:
Guido van Rossumff4949e1992-08-05 19:58:53 +00002037 BGN_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002038 if (poll) {
2039 if (!wpollevent(&e)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +00002040 RET_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002041 INCREF(None);
2042 return None;
2043 }
2044 }
2045 else
2046 wgetevent(&e);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002047 END_STDWIN
Guido van Rossum246b9d81991-06-03 10:55:14 +00002048 if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
2049 /* Turn keyboard interrupts into exceptions */
2050 err_set(KeyboardInterrupt);
2051 return NULL;
2052 }
2053 if (e.type == WE_COMMAND && e.u.command == WC_CLOSE) {
2054 /* Turn WC_CLOSE commands into WE_CLOSE events */
2055 e.type = WE_CLOSE;
2056 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002057 v = window2object(e.window);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058 switch (e.type) {
2059 case WE_CHAR:
2060 {
2061 char c[1];
2062 c[0] = e.u.character;
2063 w = newsizedstringobject(c, 1);
2064 }
2065 break;
2066 case WE_COMMAND:
2067 w = newintobject((long)e.u.command);
2068 break;
2069 case WE_DRAW:
2070 w = makerect(e.u.area.left, e.u.area.top,
2071 e.u.area.right, e.u.area.bottom);
2072 break;
2073 case WE_MOUSE_DOWN:
2074 case WE_MOUSE_MOVE:
2075 case WE_MOUSE_UP:
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002076 w = mkvalue("((ii)iii)",
2077 e.u.where.h, e.u.where.v,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002078 e.u.where.clicks,
2079 e.u.where.button,
2080 e.u.where.mask);
2081 break;
2082 case WE_MENU:
Guido van Rossum2d14e211991-02-19 12:26:49 +00002083 if (e.u.m.id >= IDOFFSET && e.u.m.id < IDOFFSET+MAXNMENU &&
2084 menulist[e.u.m.id - IDOFFSET] != NULL)
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002085 w = mkvalue("(Oi)",
2086 menulist[e.u.m.id - IDOFFSET], e.u.m.item);
Guido van Rossum246b9d81991-06-03 10:55:14 +00002087 else {
2088 /* Ghost menu event.
2089 Can occur only on the Mac if another part
2090 of the aplication has installed a menu;
2091 like the THINK C console library. */
2092 DECREF(v);
2093 goto again;
2094 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002095 break;
Guido van Rossum3ee199e1992-06-30 12:48:26 +00002096 case WE_KEY:
2097 w = mkvalue("(ii)", e.u.key.code, e.u.key.mask);
2098 break;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002099 case WE_LOST_SEL:
2100 w = newintobject((long)e.u.sel);
2101 break;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002102 default:
2103 w = None;
2104 INCREF(w);
2105 break;
2106 }
2107 if (w == NULL) {
2108 DECREF(v);
2109 return NULL;
2110 }
Guido van Rossum2ee12f41992-04-13 15:54:35 +00002111 u = mkvalue("(iOO)", e.type, v, w);
2112 XDECREF(v);
2113 XDECREF(w);
2114 return u;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002115}
2116
2117static object *
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002118stdwin_getevent(sw, args)
2119 object *sw;
2120 object *args;
2121{
2122 return stdwin_get_poll_event(0, args);
2123}
2124
2125static object *
2126stdwin_pollevent(sw, args)
2127 object *sw;
2128 object *args;
2129{
2130 return stdwin_get_poll_event(1, args);
2131}
2132
2133static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002134stdwin_setdefwinpos(sw, args)
2135 object *sw;
2136 object *args;
2137{
2138 int a[2];
2139 if (!getpointarg(args, a))
2140 return NULL;
2141 wsetdefwinpos(a[0], a[1]);
2142 INCREF(None);
2143 return None;
2144}
2145
2146static object *
2147stdwin_setdefwinsize(sw, args)
2148 object *sw;
2149 object *args;
2150{
2151 int a[2];
2152 if (!getpointarg(args, a))
2153 return NULL;
2154 wsetdefwinsize(a[0], a[1]);
2155 INCREF(None);
2156 return None;
2157}
2158
2159static object *
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002160stdwin_setdefscrollbars(sw, args)
2161 object *sw;
2162 object *args;
2163{
2164 int a[2];
2165 if (!getpointarg(args, a))
2166 return NULL;
2167 wsetdefscrollbars(a[0], a[1]);
2168 INCREF(None);
2169 return None;
2170}
2171
2172static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002173stdwin_getdefwinpos(self, args)
2174 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002175 object *args;
2176{
2177 int h, v;
2178 if (!getnoarg(args))
2179 return NULL;
2180 wgetdefwinpos(&h, &v);
2181 return makepoint(h, v);
2182}
2183
2184static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002185stdwin_getdefwinsize(self, args)
2186 object *self;
Guido van Rossum33f17701991-02-13 23:19:39 +00002187 object *args;
2188{
2189 int width, height;
2190 if (!getnoarg(args))
2191 return NULL;
2192 wgetdefwinsize(&width, &height);
2193 return makepoint(width, height);
2194}
2195
2196static object *
Guido van Rossum541c8c01991-05-05 20:13:41 +00002197stdwin_getdefscrollbars(self, args)
2198 object *self;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002199 object *args;
2200{
2201 int h, v;
2202 if (!getnoarg(args))
2203 return NULL;
2204 wgetdefscrollbars(&h, &v);
2205 return makepoint(h, v);
2206}
2207
2208static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002209stdwin_menucreate(self, args)
2210 object *self;
2211 object *args;
2212{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002213 char *title;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002214 if (!getstrarg(args, &title))
2215 return NULL;
2216 wmenusetdeflocal(0);
2217 return (object *)newmenuobject(title);
2218}
2219
2220static object *
2221stdwin_askfile(self, args)
2222 object *self;
2223 object *args;
2224{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002225 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002226 int new, ret;
2227 char buf[256];
Guido van Rossum234f9421993-06-17 12:35:49 +00002228 if (!getargs(args, "(ssi)", &prompt, &dflt, &new))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002229 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002230 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002231 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002232 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002233 ret = waskfile(prompt, buf, sizeof buf, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002234 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002235 if (!ret) {
2236 err_set(KeyboardInterrupt);
2237 return NULL;
2238 }
2239 return newstringobject(buf);
2240}
2241
2242static object *
2243stdwin_askync(self, args)
2244 object *self;
2245 object *args;
2246{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002247 char *prompt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002248 int new, ret;
Guido van Rossum234f9421993-06-17 12:35:49 +00002249 if (!getargs(args, "(si)", &prompt, &new))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002250 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002251 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002252 ret = waskync(prompt, new);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002253 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002254 if (ret < 0) {
2255 err_set(KeyboardInterrupt);
2256 return NULL;
2257 }
2258 return newintobject((long)ret);
2259}
2260
2261static object *
2262stdwin_askstr(self, args)
2263 object *self;
2264 object *args;
2265{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002266 char *prompt, *dflt;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002267 int ret;
2268 char buf[256];
Guido van Rossum234f9421993-06-17 12:35:49 +00002269 if (!getargs(args, "(ss)", &prompt, &dflt))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002270 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002271 strncpy(buf, dflt, sizeof buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002272 buf[sizeof buf - 1] = '\0';
Guido van Rossumff4949e1992-08-05 19:58:53 +00002273 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002274 ret = waskstr(prompt, buf, sizeof buf);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002275 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002276 if (!ret) {
2277 err_set(KeyboardInterrupt);
2278 return NULL;
2279 }
2280 return newstringobject(buf);
2281}
2282
2283static object *
2284stdwin_message(self, args)
2285 object *self;
2286 object *args;
2287{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002288 char *msg;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002289 if (!getstrarg(args, &msg))
2290 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002291 BGN_STDWIN
Guido van Rossumfc58e581992-01-27 16:45:55 +00002292 wmessage(msg);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002293 END_STDWIN
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002294 INCREF(None);
2295 return None;
2296}
2297
2298static object *
2299stdwin_fleep(self, args)
2300 object *self;
2301 object *args;
2302{
2303 if (!getnoarg(args))
2304 return NULL;
2305 wfleep();
2306 INCREF(None);
2307 return None;
2308}
2309
2310static object *
2311stdwin_setcutbuffer(self, args)
2312 object *self;
2313 object *args;
2314{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002315 int i, size;
2316 char *str;
2317 if (!getargs(args, "(is#)", &i, &str, &size))
Guido van Rossum124967c1990-11-06 15:17:35 +00002318 return NULL;
Guido van Rossumfc58e581992-01-27 16:45:55 +00002319 wsetcutbuffer(i, str, size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002320 INCREF(None);
2321 return None;
2322}
2323
2324static object *
Guido van Rossum246b9d81991-06-03 10:55:14 +00002325stdwin_getactive(self, args)
2326 object *self;
2327 object *args;
2328{
2329 return window2object(wgetactive());
2330}
2331
2332static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002333stdwin_getcutbuffer(self, args)
2334 object *self;
2335 object *args;
2336{
Guido van Rossum5b10f451990-10-30 16:01:48 +00002337 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002338 char *str;
Guido van Rossum01769f01990-10-30 13:39:00 +00002339 int len;
Guido van Rossum124967c1990-11-06 15:17:35 +00002340 if (!getintarg(args, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002341 return NULL;
Guido van Rossum5b10f451990-10-30 16:01:48 +00002342 str = wgetcutbuffer(i, &len);
Guido van Rossum01769f01990-10-30 13:39:00 +00002343 if (str == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002344 str = "";
Guido van Rossum01769f01990-10-30 13:39:00 +00002345 len = 0;
2346 }
2347 return newsizedstringobject(str, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002348}
2349
Guido van Rossum5b10f451990-10-30 16:01:48 +00002350static object *
2351stdwin_rotatecutbuffers(self, args)
2352 object *self;
2353 object *args;
2354{
2355 int i;
2356 if (!getintarg(args, &i))
2357 return NULL;
2358 wrotatecutbuffers(i);
2359 INCREF(None);
2360 return None;
2361}
2362
2363static object *
2364stdwin_getselection(self, args)
2365 object *self;
2366 object *args;
2367{
2368 int sel;
2369 char *data;
2370 int len;
2371 if (!getintarg(args, &sel))
2372 return NULL;
2373 data = wgetselection(sel, &len);
2374 if (data == NULL) {
2375 data = "";
2376 len = 0;
2377 }
2378 return newsizedstringobject(data, len);
2379}
2380
2381static object *
2382stdwin_resetselection(self, args)
2383 object *self;
2384 object *args;
2385{
2386 int sel;
2387 if (!getintarg(args, &sel))
2388 return NULL;
2389 wresetselection(sel);
2390 INCREF(None);
2391 return None;
2392}
2393
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002394static object *
2395stdwin_fetchcolor(self, args)
2396 object *self;
2397 object *args;
2398{
Guido van Rossumfc58e581992-01-27 16:45:55 +00002399 char *colorname;
Guido van Rossum34679b71993-01-26 13:33:44 +00002400 COLOR color;
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002401 if (!getstrarg(args, &colorname))
2402 return NULL;
Guido van Rossum34679b71993-01-26 13:33:44 +00002403 color = wfetchcolor(colorname);
2404#ifdef BADCOLOR
2405 if (color == BADCOLOR) {
2406 err_setstr(StdwinError, "color name not found");
2407 return NULL;
2408 }
2409#endif
2410 return newintobject((long)color);
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002411}
2412
Guido van Rossum541c8c01991-05-05 20:13:41 +00002413static object *
2414stdwin_getscrsize(self, args)
2415 object *self;
2416 object *args;
2417{
2418 int width, height;
2419 if (!getnoarg(args))
2420 return NULL;
2421 wgetscrsize(&width, &height);
2422 return makepoint(width, height);
2423}
2424
2425static object *
2426stdwin_getscrmm(self, args)
2427 object *self;
2428 object *args;
2429{
2430 int width, height;
2431 if (!getnoarg(args))
2432 return NULL;
2433 wgetscrmm(&width, &height);
2434 return makepoint(width, height);
2435}
2436
Guido van Rossumed233a51992-06-23 09:07:03 +00002437#ifdef unix
2438static object *
2439stdwin_connectionnumber(self, args)
2440 object *self;
2441 object *args;
2442{
2443 if (!getnoarg(args))
2444 return NULL;
2445 return newintobject((long) wconnectionnumber());
2446}
2447#endif
2448
Guido van Rossumbf80e541993-02-08 15:49:17 +00002449static object *
2450stdwin_listfontnames(self, args)
2451 object *self;
2452 object *args;
2453{
2454 char *pattern;
2455 char **fontnames;
2456 int count;
2457 object *list;
2458 if (!getargs(args, "z", &pattern))
2459 return NULL;
2460 fontnames = wlistfontnames(pattern, &count);
2461 list = newlistobject(count);
2462 if (list != NULL) {
2463 int i;
2464 for (i = 0; i < count; i++) {
2465 object *v = newstringobject(fontnames[i]);
2466 if (v == NULL) {
2467 DECREF(list);
2468 list = NULL;
2469 break;
2470 }
2471 setlistitem(list, i, v);
2472 }
2473 }
2474 return list;
2475}
2476
Guido van Rossume9066061993-07-29 13:14:32 +00002477#ifdef HAVE_BITMAPS
Guido van Rossumbf80e541993-02-08 15:49:17 +00002478static object *
2479stdwin_newbitmap(self, args)
2480 object *self;
2481 object *args;
2482{
2483 int width, height;
2484 bitmapobject *bp;
2485 if (!getargs(args, "(ii)", &width, &height))
2486 return NULL;
2487 return (object *)newbitmapobject(width, height);
2488}
Guido van Rossume9066061993-07-29 13:14:32 +00002489#endif
Guido van Rossumbf80e541993-02-08 15:49:17 +00002490
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002491static struct methodlist stdwin_methods[] = {
2492 {"askfile", stdwin_askfile},
2493 {"askstr", stdwin_askstr},
2494 {"askync", stdwin_askync},
Guido van Rossumcacd9571993-10-18 11:44:47 +00002495 {"done", stdwin_done},
Guido van Rossum27201061991-04-16 08:43:03 +00002496 {"fetchcolor", stdwin_fetchcolor},
Guido van Rossumed233a51992-06-23 09:07:03 +00002497#ifdef unix
2498 {"fileno", stdwin_connectionnumber},
2499 {"connectionnumber", stdwin_connectionnumber},
2500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002501 {"fleep", stdwin_fleep},
Guido van Rossum246b9d81991-06-03 10:55:14 +00002502 {"getactive", stdwin_getactive},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002503 {"getcutbuffer", stdwin_getcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002504 {"getdefscrollbars", stdwin_getdefscrollbars},
Guido van Rossum33f17701991-02-13 23:19:39 +00002505 {"getdefwinpos", stdwin_getdefwinpos},
2506 {"getdefwinsize", stdwin_getdefwinsize},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002507 {"getevent", stdwin_getevent},
Guido van Rossum541c8c01991-05-05 20:13:41 +00002508 {"getscrmm", stdwin_getscrmm},
2509 {"getscrsize", stdwin_getscrsize},
Guido van Rossum27201061991-04-16 08:43:03 +00002510 {"getselection", stdwin_getselection},
Guido van Rossumbf80e541993-02-08 15:49:17 +00002511 {"listfontnames", stdwin_listfontnames},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002512 {"menucreate", stdwin_menucreate},
2513 {"message", stdwin_message},
Guido van Rossume9066061993-07-29 13:14:32 +00002514#ifdef HAVE_BITMAPS
Guido van Rossumbf80e541993-02-08 15:49:17 +00002515 {"newbitmap", stdwin_newbitmap},
Guido van Rossume9066061993-07-29 13:14:32 +00002516#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517 {"open", stdwin_open},
Guido van Rossume8e7cf41991-01-16 14:06:18 +00002518 {"pollevent", stdwin_pollevent},
Guido van Rossum5b10f451990-10-30 16:01:48 +00002519 {"resetselection", stdwin_resetselection},
2520 {"rotatecutbuffers", stdwin_rotatecutbuffers},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002521 {"setcutbuffer", stdwin_setcutbuffer},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002522 {"setdefscrollbars", stdwin_setdefscrollbars},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002523 {"setdefwinpos", stdwin_setdefwinpos},
2524 {"setdefwinsize", stdwin_setdefwinsize},
2525
2526 /* Text measuring methods borrow code from drawing objects: */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002527 {"baseline", (method)drawing_baseline},
2528 {"lineheight", (method)drawing_lineheight},
2529 {"textbreak", (method)drawing_textbreak},
2530 {"textwidth", (method)drawing_textwidth},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002531
2532 /* Same for font setting methods: */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002533 {"setfont", (method)drawing_setfont},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002534
2535 /* Same for color setting/getting methods: */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002536 {"getbgcolor", (method)drawing_getbgcolor},
2537 {"getfgcolor", (method)drawing_getfgcolor},
2538 {"setbgcolor", (method)drawing_setbgcolor},
2539 {"setfgcolor", (method)drawing_setfgcolor},
Guido van Rossum0c2290b1991-04-03 19:12:14 +00002540
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002541 {NULL, NULL} /* sentinel */
2542};
2543
Guido van Rossumb6775db1994-08-01 11:34:53 +00002544#ifndef macintosh
Guido van Rossumcacd9571993-10-18 11:44:47 +00002545static int
2546checkstringlist(args, ps, pn)
2547 object *args;
2548 char ***ps;
2549 int *pn;
2550{
2551 int i, n;
2552 char **s;
2553 if (!is_listobject(args)) {
2554 err_setstr(TypeError, "list of strings expected");
2555 return 0;
2556 }
2557 n = getlistsize(args);
2558 s = NEW(char *, n+1);
2559 if (s == NULL) {
2560 err_nomem();
2561 return 0;
2562 }
2563 for (i = 0; i < n; i++) {
2564 object *item = getlistitem(args, i);
2565 if (!is_stringobject(item)) {
2566 err_setstr(TypeError, "list of strings expected");
2567 return 0;
2568 }
2569 s[i] = getstringvalue(item);
2570 }
2571 s[n] = NULL; /* In case caller wants a NULL-terminated list */
2572 *ps = s;
2573 *pn = n;
2574 return 1;
2575}
2576
2577static int
2578putbackstringlist(list, s, n)
2579 object *list;
2580 char **s;
2581 int n;
2582{
2583 int oldsize = getlistsize(list);
2584 object *newlist;
2585 int i;
2586 if (n == oldsize)
2587 return 1;
2588 newlist = newlistobject(n);
2589 for (i = 0; i < n && newlist != NULL; i++) {
2590 object *item = newstringobject(s[i]);
2591 if (item == NULL) {
2592 DECREF(newlist);
2593 newlist = NULL;
2594 }
2595 else
2596 setlistitem(newlist, i, item);
2597 }
2598 if (newlist == NULL)
2599 return 0;
2600 (*list->ob_type->tp_as_sequence->sq_ass_slice)
2601 (list, 0, oldsize, newlist);
2602 DECREF(newlist);
2603 return 1;
2604}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002605#endif /* macintosh */
Guido van Rossumcacd9571993-10-18 11:44:47 +00002606
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002607void
2608initstdwin()
2609{
Guido van Rossumbbf94341991-12-16 15:44:53 +00002610 object *m, *d;
2611 static int inited = 0;
2612
Guido van Rossum2d14e211991-02-19 12:26:49 +00002613 if (!inited) {
Guido van Rossumb6775db1994-08-01 11:34:53 +00002614#ifdef macintosh
2615 winit();
Jack Jansend56c1091995-01-27 14:44:16 +00002616 PyMac_DoYieldEnabled = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002617#else
Guido van Rossum39cb5ce1995-01-26 00:37:10 +00002618 char buf[1000];
Guido van Rossumcacd9571993-10-18 11:44:47 +00002619 int argc = 0;
2620 char **argv = NULL;
2621 object *sys_argv = sysget("argv");
2622 if (sys_argv != NULL) {
2623 if (!checkstringlist(sys_argv, &argv, &argc))
2624 err_clear();
2625 }
Guido van Rossumc45611d1993-11-17 22:58:56 +00002626 if (argc > 0) {
2627 /* If argv[0] has a ".py" suffix, remove the suffix */
2628 char *p = strrchr(argv[0], '.');
2629 if (p != NULL && strcmp(p, ".py") == 0) {
2630 int n = p - argv[0];
2631 if (n >= sizeof(buf))
2632 n = sizeof(buf)-1;
2633 strncpy(buf, argv[0], n);
2634 buf[n] = '\0';
2635 argv[0] = buf;
2636 }
2637 }
Guido van Rossumcacd9571993-10-18 11:44:47 +00002638 winitargs(&argc, &argv);
2639 if (argv != NULL) {
2640 if (!putbackstringlist(sys_argv, argv, argc))
2641 err_clear();
2642 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002643#endif
Guido van Rossum2d14e211991-02-19 12:26:49 +00002644 inited = 1;
2645 }
Guido van Rossumbbf94341991-12-16 15:44:53 +00002646 m = initmodule("stdwin", stdwin_methods);
2647 d = getmoduledict(m);
2648
2649 /* Initialize stdwin.error exception */
2650 StdwinError = newstringobject("stdwin.error");
2651 if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
2652 fatal("can't define stdwin.error");
Guido van Rossumb6775db1994-08-01 11:34:53 +00002653#ifdef WITH_THREAD
Guido van Rossumff4949e1992-08-05 19:58:53 +00002654 StdwinLock = allocate_lock();
2655 if (StdwinLock == NULL)
2656 fatal("can't allocate stdwin lock");
2657#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002658}