1 /***********************************************************
2 Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands.
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
27 /* Stdwin itself is a module, not a separate object type.
28 Object types defined here:
30 dp: a drawing structure (only one can exist at a time)
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)
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.
61 XXX This must change again in the light of changes to stdwin!
62 - For textedit, similar rules hold, but they are less strict.
66 #include "allobjects.h"
67 #include "modsupport.h"
69 #include "sysmodule.h"
72 #include ":::stdwin:H:stdwin.h"
73 #else /* !macintosh */
76 #endif /* !macintosh */
82 static type_lock StdwinLock
; /* Lock held when interpreter not locked */
84 #define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
85 #define RET_STDWIN release_lock(StdwinLock); RET_SAVE
86 #define END_STDWIN release_lock(StdwinLock); END_SAVE
90 #define BGN_STDWIN BGN_SAVE
91 #define RET_STDWIN RET_SAVE
92 #define END_STDWIN END_SAVE
96 #define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
97 #define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
98 a, a+1, a+2, a+3, a+4, a+5)
99 #define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
100 #define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
101 #define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
102 #define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
103 a, a+1, a+2, a+3, a+4, a+5)
105 static object
*StdwinError
; /* Exception stdwin.error */
107 /* Window and menu object types declared here because of forward references */
113 object
*w_attr
; /* Attributes dictionary */
116 extern typeobject Windowtype
; /* Really static, forward */
118 #define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
124 object
*m_attr
; /* Attributes dictionary */
127 extern typeobject Menutype
; /* Really static, forward */
129 #define is_menuobject(mp) ((mp)->ob_type == &Menutype)
134 object
*b_attr
; /* Attributes dictionary */
137 extern typeobject Bitmaptype
; /* Really static, forward */
139 #define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
142 /* Strongly stdwin-specific argument handlers */
150 if (!getargs(v
, "(Oi)", &mp
, &ep
->u
.m
.item
))
152 if (!is_menuobject(mp
))
154 ep
->u
.m
.id
= mp
->m_id
;
165 if (!getargs(v
, "(iOO)", &ep
->type
, &wp
, &detail
))
167 if (is_windowobject(wp
))
168 ep
->window
= ((windowobject
*)wp
) -> w_win
;
176 if (!getargs(detail
, "c", &c
))
182 return getintarg(detail
, &ep
->u
.command
);
184 if (!getrectarg(detail
, a
))
186 ep
->u
.area
.left
= a
[0];
187 ep
->u
.area
.top
= a
[1];
188 ep
->u
.area
.right
= a
[2];
189 ep
->u
.area
.bottom
= a
[3];
194 return getargs(detail
, "((ii)iii)",
195 &ep
->u
.where
.h
, &ep
->u
.where
.v
,
200 return getmenudetail(detail
, ep
);
202 return getargs(detail
, "(ii)",
203 &ep
->u
.key
.code
, &ep
->u
.key
.mask
);
210 /* Return construction tools */
216 return mkvalue("(ii)", a
, b
);
223 return mkvalue("((ii)(ii))", a
, b
, c
, d
);
227 /* Drawing objects */
234 static drawingobject
*Drawing
; /* Set to current drawing object, or NULL */
236 /* Drawing methods */
242 if (dp
->d_ref
!= NULL
) {
243 wenddrawing(dp
->d_ref
->w_win
);
256 if (dp
->d_ref
!= NULL
) {
257 wenddrawing(dp
->d_ref
->w_win
);
266 drawing_generic(dp
, args
, func
)
269 void (*func
) FPROTO((int, int, int, int));
272 if (!getrectarg(args
, a
))
274 (*func
)(a
[0], a
[1], a
[2], a
[3]);
280 drawing_line(dp
, args
)
284 return drawing_generic(dp
, args
, wdrawline
);
288 drawing_xorline(dp
, args
)
292 return drawing_generic(dp
, args
, wxorline
);
296 drawing_circle(dp
, args
)
301 if (!getpointintarg(args
, a
))
303 wdrawcircle(a
[0], a
[1], a
[2]);
309 drawing_fillcircle(dp
, args
)
314 if (!getpointintarg(args
, a
))
316 wfillcircle(a
[0], a
[1], a
[2]);
322 drawing_xorcircle(dp
, args
)
327 if (!getpointintarg(args
, a
))
329 wxorcircle(a
[0], a
[1], a
[2]);
335 drawing_elarc(dp
, args
)
340 if (!get3pointarg(args
, a
))
342 wdrawelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
348 drawing_fillelarc(dp
, args
)
353 if (!get3pointarg(args
, a
))
355 wfillelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
361 drawing_xorelarc(dp
, args
)
366 if (!get3pointarg(args
, a
))
368 wxorelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
374 drawing_box(dp
, args
)
378 return drawing_generic(dp
, args
, wdrawbox
);
382 drawing_erase(dp
, args
)
386 return drawing_generic(dp
, args
, werase
);
390 drawing_paint(dp
, args
)
394 return drawing_generic(dp
, args
, wpaint
);
398 drawing_invert(dp
, args
)
402 return drawing_generic(dp
, args
, winvert
);
406 getpointsarray(v
, psize
)
411 object
* (*getitem
) PROTO((object
*, int));
417 else if (is_listobject(v
)) {
419 getitem
= getlistitem
;
421 else if (is_tupleobject(v
)) {
423 getitem
= gettupleitem
;
431 points
= NEW(POINT
, n
);
432 if (points
== NULL
) {
437 for (i
= 0; i
< n
; i
++) {
438 object
*w
= (*getitem
)(v
, i
);
440 if (!getpointarg(w
, a
)) {
453 drawing_poly(dp
, args
)
458 POINT
*points
= getpointsarray(args
, &n
);
461 wdrawpoly(n
, points
);
468 drawing_fillpoly(dp
, args
)
473 POINT
*points
= getpointsarray(args
, &n
);
476 wfillpoly(n
, points
);
483 drawing_xorpoly(dp
, args
)
488 POINT
*points
= getpointsarray(args
, &n
);
498 drawing_cliprect(dp
, args
)
502 return drawing_generic(dp
, args
, wcliprect
);
506 drawing_noclip(dp
, args
)
518 drawing_shade(dp
, args
)
523 if (!getrectintarg(args
, a
))
525 wshade(a
[0], a
[1], a
[2], a
[3], a
[4]);
531 drawing_text(dp
, args
)
537 if (!getargs(args
, "((ii)s#)", &h
, &v
, &text
, &size
))
539 wdrawtext(h
, v
, text
, size
);
544 /* The following four are also used as stdwin functions */
547 drawing_lineheight(dp
, args
)
553 return newintobject((long)wlineheight());
557 drawing_baseline(dp
, args
)
563 return newintobject((long)wbaseline());
567 drawing_textwidth(dp
, args
)
573 if (!getargs(args
, "s#", &text
, &size
))
575 return newintobject((long)wtextwidth(text
, size
));
579 drawing_textbreak(dp
, args
)
585 if (!getargs(args
, "(s#i)", &text
, &size
, &width
))
587 return newintobject((long)wtextbreak(text
, size
, width
));
591 drawing_setfont(self
, args
)
598 if (args
== NULL
|| !is_tupleobject(args
)) {
599 if (!getargs(args
, "z", &font
))
603 int n
= gettuplesize(args
);
605 if (!getargs(args
, "(zi)", &font
, &size
))
608 else if (!getargs(args
, "(zic)", &font
, &size
, &style
)) {
610 if (!getargs(args
, "(zci)", &font
, &style
, &size
))
615 if (!wsetfont(font
)) {
616 err_setstr(StdwinError
, "font not found");
644 drawing_getbgcolor(self
, args
)
650 return newintobject((long)wgetbgcolor());
654 drawing_getfgcolor(self
, args
)
660 return newintobject((long)wgetfgcolor());
664 drawing_setbgcolor(self
, args
)
669 if (!getlongarg(args
, &color
))
671 wsetbgcolor((COLOR
)color
);
677 drawing_setfgcolor(self
, args
)
682 if (!getlongarg(args
, &color
))
684 wsetfgcolor((COLOR
)color
);
692 drawing_bitmap(self
, args
)
699 if (!getargs(args
, "((ii)O)", &h
, &v
, &bp
)) {
701 if (!getargs(args
, "((ii)OO)", &h
, &v
, &bp
, &mask
))
705 else if (!is_bitmapobject(mask
)) {
710 if (!is_bitmapobject(bp
)) {
714 if (((bitmapobject
*)bp
)->b_bitmap
== NULL
||
715 mask
!= NULL
&& ((bitmapobject
*)mask
)->b_bitmap
== NULL
) {
716 err_setstr(StdwinError
, "bitmap object already close");
720 wdrawbitmap(h
, v
, ((bitmapobject
*)bp
)->b_bitmap
, ALLBITS
);
723 ((bitmapobject
*)bp
)->b_bitmap
,
724 ((bitmapobject
*)bp
)->b_bitmap
);
729 #endif /* HAVE_BITMAPS */
731 static struct methodlist drawing_methods
[] = {
733 {"bitmap", drawing_bitmap
},
735 {"box", drawing_box
},
736 {"circle", drawing_circle
},
737 {"cliprect", drawing_cliprect
},
738 {"close", drawing_close
},
739 {"elarc", drawing_elarc
},
740 {"enddrawing", drawing_close
},
741 {"erase", drawing_erase
},
742 {"fillcircle", drawing_fillcircle
},
743 {"fillelarc", drawing_fillelarc
},
744 {"fillpoly", drawing_fillpoly
},
745 {"invert", drawing_invert
},
746 {"line", drawing_line
},
747 {"noclip", drawing_noclip
},
748 {"paint", drawing_paint
},
749 {"poly", drawing_poly
},
750 {"shade", drawing_shade
},
751 {"text", drawing_text
},
752 {"xorcircle", drawing_xorcircle
},
753 {"xorelarc", drawing_xorelarc
},
754 {"xorline", drawing_xorline
},
755 {"xorpoly", drawing_xorpoly
},
757 /* Text measuring methods: */
758 {"baseline", drawing_baseline
},
759 {"lineheight", drawing_lineheight
},
760 {"textbreak", drawing_textbreak
},
761 {"textwidth", drawing_textwidth
},
763 /* Font setting methods: */
764 {"setfont", drawing_setfont
},
767 {"getbgcolor", drawing_getbgcolor
},
768 {"getfgcolor", drawing_getfgcolor
},
769 {"setbgcolor", drawing_setbgcolor
},
770 {"setfgcolor", drawing_setfgcolor
},
772 {NULL
, NULL
} /* sentinel */
776 drawing_getattr(dp
, name
)
780 if (dp
->d_ref
== NULL
) {
781 err_setstr(StdwinError
, "drawing object already closed");
784 return findmethod(drawing_methods
, (object
*)dp
, name
);
787 typeobject Drawingtype
= {
788 OB_HEAD_INIT(&Typetype
)
790 "drawing", /*tp_name*/
791 sizeof(drawingobject
), /*tp_size*/
794 drawing_dealloc
, /*tp_dealloc*/
796 drawing_getattr
, /*tp_getattr*/
803 /* Text(edit) objects */
809 object
*t_attr
; /* Attributes dictionary */
812 extern typeobject Texttype
; /* Really static, forward */
815 newtextobject(wp
, left
, top
, right
, bottom
)
817 int left
, top
, right
, bottom
;
820 tp
= NEWOBJ(textobject
, &Texttype
);
826 tp
->t_text
= tecreate(wp
->w_win
, left
, top
, right
, bottom
);
827 if (tp
->t_text
== NULL
) {
829 return (textobject
*) err_nomem();
834 /* Text(edit) methods */
840 if (tp
->t_text
!= NULL
)
852 if (tp
->t_text
!= NULL
) {
856 if (tp
->t_attr
!= NULL
) {
860 if (tp
->t_ref
!= NULL
) {
869 text_arrow(self
, args
)
874 if (!getintarg(args
, &code
))
876 tearrow(self
->t_text
, code
);
882 text_draw(self
, args
)
886 register TEXTEDIT
*tp
= self
->t_text
;
888 int left
, top
, right
, bottom
;
889 if (!getrectarg(args
, a
))
891 if (Drawing
!= NULL
) {
892 err_setstr(StdwinError
, "already drawing");
895 /* Clip to text area and ignore if area is empty */
896 left
= tegetleft(tp
);
898 right
= tegetright(tp
);
899 bottom
= tegetbottom(tp
);
900 if (a
[0] < left
) a
[0] = left
;
901 if (a
[1] < top
) a
[1] = top
;
902 if (a
[2] > right
) a
[2] = right
;
903 if (a
[3] > bottom
) a
[3] = bottom
;
904 if (a
[0] < a
[2] && a
[1] < a
[3]) {
905 wbegindrawing(self
->t_ref
->w_win
);
906 tedrawnew(tp
, a
[0], a
[1], a
[2], a
[3]);
907 wenddrawing(self
->t_ref
->w_win
);
914 text_event(self
, args
)
918 register TEXTEDIT
*tp
= self
->t_text
;
920 if (!geteventarg(args
, &e
))
922 if (e
.type
== WE_MOUSE_DOWN
) {
923 /* Cheat at the margins */
925 wgetdocsize(e
.window
, &width
, &height
);
926 if (e
.u
.where
.h
< 0 && tegetleft(tp
) == 0)
928 else if (e
.u
.where
.h
> width
&& tegetright(tp
) == width
)
930 if (e
.u
.where
.v
< 0 && tegettop(tp
) == 0)
932 else if (e
.u
.where
.v
> height
&& tegetright(tp
) == height
)
933 e
.u
.where
.v
= height
;
935 return newintobject((long) teevent(tp
, &e
));
939 text_getfocus(self
, args
)
945 return makepoint(tegetfoc1(self
->t_text
), tegetfoc2(self
->t_text
));
949 text_getfocustext(self
, args
)
957 f1
= tegetfoc1(self
->t_text
);
958 f2
= tegetfoc2(self
->t_text
);
959 text
= tegettext(self
->t_text
);
960 return newsizedstringobject(text
+ f1
, f2
-f1
);
964 text_getrect(self
, args
)
970 return makerect(tegetleft(self
->t_text
),
971 tegettop(self
->t_text
),
972 tegetright(self
->t_text
),
973 tegetbottom(self
->t_text
));
977 text_gettext(self
, args
)
983 return newsizedstringobject(tegettext(self
->t_text
),
984 tegetlen(self
->t_text
));
988 text_move(self
, args
)
993 if (!getrectarg(args
, a
))
995 temovenew(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1001 text_replace(self
, args
)
1006 if (!getstrarg(args
, &text
))
1008 tereplace(self
->t_text
, text
);
1014 text_setactive(self
, args
)
1019 if (!getintarg(args
, &flag
))
1021 tesetactive(self
->t_text
, flag
);
1027 text_setfocus(self
, args
)
1032 if (!getpointarg(args
, a
))
1034 tesetfocus(self
->t_text
, a
[0], a
[1]);
1040 text_settext(self
, args
)
1047 if (!getargs(args
, "s#", &text
, &size
))
1049 if ((buf
= NEW(char, size
)) == NULL
) {
1052 memcpy(buf
, text
, size
);
1053 tesetbuf(self
->t_text
, buf
, size
); /* Becomes owner of buffer */
1059 text_setview(self
, args
)
1065 tenoview(self
->t_text
);
1067 if (!getrectarg(args
, a
))
1069 tesetview(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1075 static struct methodlist text_methods
[] = {
1076 {"arrow", text_arrow
},
1077 {"close", text_close
},
1078 {"draw", text_draw
},
1079 {"event", text_event
},
1080 {"getfocus", text_getfocus
},
1081 {"getfocustext",text_getfocustext
},
1082 {"getrect", text_getrect
},
1083 {"gettext", text_gettext
},
1084 {"move", text_move
},
1085 {"replace", text_replace
},
1086 {"setactive", text_setactive
},
1087 {"setfocus", text_setfocus
},
1088 {"settext", text_settext
},
1089 {"setview", text_setview
},
1090 {NULL
, NULL
} /* sentinel */
1094 text_getattr(tp
, name
)
1099 if (tp
->t_ref
== NULL
) {
1100 err_setstr(StdwinError
, "text object already closed");
1103 if (strcmp(name
, "__dict__") == 0) {
1108 else if (tp
->t_attr
!= NULL
) {
1109 v
= dictlookup(tp
->t_attr
, name
);
1115 return findmethod(text_methods
, (object
*)tp
, name
);
1119 text_setattr(tp
, name
, v
)
1124 if (tp
->t_attr
== NULL
) {
1125 tp
->t_attr
= newdictobject();
1126 if (tp
->t_attr
== NULL
)
1130 int rv
= dictremove(tp
->t_attr
, name
);
1132 err_setstr(AttributeError
,
1133 "delete non-existing text object attribute");
1137 return dictinsert(tp
->t_attr
, name
, v
);
1140 typeobject Texttype
= {
1141 OB_HEAD_INIT(&Typetype
)
1143 "textedit", /*tp_name*/
1144 sizeof(textobject
), /*tp_size*/
1147 text_dealloc
, /*tp_dealloc*/
1149 text_getattr
, /*tp_getattr*/
1150 text_setattr
, /*tp_setattr*/
1158 #define IDOFFSET 10 /* Menu IDs we use start here */
1159 #define MAXNMENU 200 /* Max #menus we allow */
1160 static menuobject
*menulist
[MAXNMENU
];
1162 static menuobject
*newmenuobject
PROTO((char *));
1164 newmenuobject(title
)
1170 for (id
= 0; id
< MAXNMENU
; id
++) {
1171 if (menulist
[id
] == NULL
)
1174 if (id
>= MAXNMENU
) {
1175 err_setstr(StdwinError
, "creating too many menus");
1178 menu
= wmenucreate(id
+ IDOFFSET
, title
);
1180 return (menuobject
*) err_nomem();
1181 mp
= NEWOBJ(menuobject
, &Menutype
);
1184 mp
->m_id
= id
+ IDOFFSET
;
1200 int id
= mp
->m_id
- IDOFFSET
;
1201 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1202 menulist
[id
] = NULL
;
1204 if (mp
->m_menu
!= NULL
)
1205 wmenudelete(mp
->m_menu
);
1206 XDECREF(mp
->m_attr
);
1211 menu_close(mp
, args
)
1215 int id
= mp
->m_id
- IDOFFSET
;
1216 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1217 menulist
[id
] = NULL
;
1220 if (mp
->m_menu
!= NULL
)
1221 wmenudelete(mp
->m_menu
);
1223 XDECREF(mp
->m_attr
);
1230 menu_additem(self
, args
)
1236 if (is_tupleobject(args
)) {
1238 if (!getargs(args
, "(sc)", &text
, &c
))
1242 else if (!getstrarg(args
, &text
))
1244 wmenuadditem(self
->m_menu
, text
, shortcut
);
1250 menu_setitem(self
, args
)
1256 if (!getargs(args
, "(is)", &index
, &text
))
1258 wmenusetitem(self
->m_menu
, index
, text
);
1264 menu_enable(self
, args
)
1270 if (!getargs(args
, "(ii)", &index
, &flag
))
1272 wmenuenable(self
->m_menu
, index
, flag
);
1278 menu_check(self
, args
)
1284 if (!getargs(args
, "(ii)", &index
, &flag
))
1286 wmenucheck(self
->m_menu
, index
, flag
);
1291 static struct methodlist menu_methods
[] = {
1292 {"additem", menu_additem
},
1293 {"setitem", menu_setitem
},
1294 {"enable", menu_enable
},
1295 {"check", menu_check
},
1296 {"close", menu_close
},
1297 {NULL
, NULL
} /* sentinel */
1301 menu_getattr(mp
, name
)
1306 if (mp
->m_menu
== NULL
) {
1307 err_setstr(StdwinError
, "menu object already closed");
1310 if (strcmp(name
, "__dict__") == 0) {
1315 else if (mp
->m_attr
!= NULL
) {
1316 v
= dictlookup(mp
->m_attr
, name
);
1322 return findmethod(menu_methods
, (object
*)mp
, name
);
1326 menu_setattr(mp
, name
, v
)
1331 if (mp
->m_attr
== NULL
) {
1332 mp
->m_attr
= newdictobject();
1333 if (mp
->m_attr
== NULL
)
1337 int rv
= dictremove(mp
->m_attr
, name
);
1339 err_setstr(AttributeError
,
1340 "delete non-existing menu object attribute");
1344 return dictinsert(mp
->m_attr
, name
, v
);
1347 typeobject Menutype
= {
1348 OB_HEAD_INIT(&Typetype
)
1351 sizeof(menuobject
), /*tp_size*/
1354 menu_dealloc
, /*tp_dealloc*/
1356 menu_getattr
, /*tp_getattr*/
1357 menu_setattr
, /*tp_setattr*/
1365 /* Bitmaps objects */
1367 static bitmapobject
*newbitmapobject
PROTO((int, int));
1368 static bitmapobject
*
1369 newbitmapobject(width
, height
)
1374 bitmap
= wnewbitmap(width
, height
);
1376 return (bitmapobject
*) err_nomem();
1377 bp
= NEWOBJ(bitmapobject
, &Bitmaptype
);
1379 bp
->b_bitmap
= bitmap
;
1383 wfreebitmap(bitmap
);
1387 /* Bitmap methods */
1393 if (bp
->b_bitmap
!= NULL
)
1394 wfreebitmap(bp
->b_bitmap
);
1395 XDECREF(bp
->b_attr
);
1400 bitmap_close(bp
, args
)
1404 if (bp
->b_bitmap
!= NULL
)
1405 wfreebitmap(bp
->b_bitmap
);
1406 bp
->b_bitmap
= NULL
;
1407 XDECREF(bp
->b_attr
);
1414 bitmap_setbit(self
, args
)
1419 if (!getpointintarg(args
, a
))
1421 wsetbit(self
->b_bitmap
, a
[0], a
[1], a
[2]);
1427 bitmap_getbit(self
, args
)
1432 if (!getpointarg(args
, a
))
1434 return newintobject((long) wgetbit(self
->b_bitmap
, a
[0], a
[1]));
1438 bitmap_getsize(self
, args
)
1443 if (!getnoarg(args
))
1445 wgetbitmapsize(self
->b_bitmap
, &width
, &height
);
1446 return mkvalue("(ii)", width
, height
);
1449 static struct methodlist bitmap_methods
[] = {
1450 {"close", bitmap_close
},
1451 {"getsize", bitmap_getsize
},
1452 {"getbit", bitmap_getbit
},
1453 {"setbit", bitmap_setbit
},
1454 {NULL
, NULL
} /* sentinel */
1458 bitmap_getattr(bp
, name
)
1463 if (bp
->b_bitmap
== NULL
) {
1464 err_setstr(StdwinError
, "bitmap object already closed");
1467 if (strcmp(name
, "__dict__") == 0) {
1472 else if (bp
->b_attr
!= NULL
) {
1473 v
= dictlookup(bp
->b_attr
, name
);
1479 return findmethod(bitmap_methods
, (object
*)bp
, name
);
1483 bitmap_setattr(bp
, name
, v
)
1488 if (bp
->b_attr
== NULL
) {
1489 bp
->b_attr
= newdictobject();
1490 if (bp
->b_attr
== NULL
)
1494 int rv
= dictremove(bp
->b_attr
, name
);
1496 err_setstr(AttributeError
,
1497 "delete non-existing bitmap object attribute");
1501 return dictinsert(bp
->b_attr
, name
, v
);
1504 typeobject Bitmaptype
= {
1505 OB_HEAD_INIT(&Typetype
)
1507 "bitmap", /*tp_name*/
1508 sizeof(bitmapobject
), /*tp_size*/
1511 bitmap_dealloc
, /*tp_dealloc*/
1513 bitmap_getattr
, /*tp_getattr*/
1514 bitmap_setattr
, /*tp_setattr*/
1519 #endif /* HAVE_BITMAPS */
1525 static windowobject
*windowlist
[MAXNWIN
];
1527 /* Window methods */
1533 if (wp
->w_win
!= NULL
) {
1534 int tag
= wgettag(wp
->w_win
);
1535 if (tag
>= 0 && tag
< MAXNWIN
)
1536 windowlist
[tag
] = NULL
;
1538 fprintf(stderr
, "XXX help! tag %d in window_dealloc\n",
1542 DECREF(wp
->w_title
);
1543 if (wp
->w_attr
!= NULL
)
1549 window_close(wp
, args
)
1553 if (wp
->w_win
!= NULL
) {
1554 int tag
= wgettag(wp
->w_win
);
1555 if (tag
>= 0 && tag
< MAXNWIN
)
1556 windowlist
[tag
] = NULL
;
1565 window_begindrawing(wp
, args
)
1570 if (!getnoarg(args
))
1572 if (Drawing
!= NULL
) {
1573 err_setstr(StdwinError
, "already drawing");
1576 dp
= NEWOBJ(drawingobject
, &Drawingtype
);
1582 wbegindrawing(wp
->w_win
);
1583 return (object
*)dp
;
1587 window_change(wp
, args
)
1592 if (!getrectarg(args
, a
))
1594 wchange(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1600 window_gettitle(wp
, args
)
1604 if (!getnoarg(args
))
1606 INCREF(wp
->w_title
);
1611 window_getwinpos(wp
, args
)
1616 if (!getnoarg(args
))
1618 wgetwinpos(wp
->w_win
, &h
, &v
);
1619 return makepoint(h
, v
);
1623 window_getwinsize(wp
, args
)
1628 if (!getnoarg(args
))
1630 wgetwinsize(wp
->w_win
, &width
, &height
);
1631 return makepoint(width
, height
);
1635 window_setwinpos(wp
, args
)
1640 if (!getpointarg(args
, a
))
1642 wsetwinpos(wp
->w_win
, a
[0], a
[1]);
1648 window_setwinsize(wp
, args
)
1653 if (!getpointarg(args
, a
))
1655 wsetwinsize(wp
->w_win
, a
[0], a
[1]);
1661 window_getdocsize(wp
, args
)
1666 if (!getnoarg(args
))
1668 wgetdocsize(wp
->w_win
, &width
, &height
);
1669 return makepoint(width
, height
);
1673 window_getorigin(wp
, args
)
1678 if (!getnoarg(args
))
1680 wgetorigin(wp
->w_win
, &width
, &height
);
1681 return makepoint(width
, height
);
1685 window_scroll(wp
, args
)
1690 if (!getrectpointarg(args
, a
))
1692 wscroll(wp
->w_win
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
1698 window_setdocsize(wp
, args
)
1703 if (!getpointarg(args
, a
))
1705 wsetdocsize(wp
->w_win
, a
[0], a
[1]);
1711 window_setorigin(wp
, args
)
1716 if (!getpointarg(args
, a
))
1718 wsetorigin(wp
->w_win
, a
[0], a
[1]);
1724 window_settitle(wp
, args
)
1729 if (!getargs(args
, "S", &title
))
1731 DECREF(wp
->w_title
);
1733 wp
->w_title
= title
;
1734 wsettitle(wp
->w_win
, getstringvalue(title
));
1740 window_show(wp
, args
)
1745 if (!getrectarg(args
, a
))
1747 wshow(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1753 window_settimer(wp
, args
)
1758 if (!getintarg(args
, &a
))
1760 wsettimer(wp
->w_win
, a
);
1766 window_menucreate(self
, args
)
1772 if (!getstrarg(args
, &title
))
1774 wmenusetdeflocal(1);
1775 mp
= newmenuobject(title
);
1778 wmenuattach(self
->w_win
, mp
->m_menu
);
1779 return (object
*)mp
;
1783 window_textcreate(self
, args
)
1789 if (!getrectarg(args
, a
))
1792 newtextobject(self
, a
[0], a
[1], a
[2], a
[3]);
1796 window_setselection(self
, args
)
1802 if (!getargs(args
, "(is#)", &sel
, &text
, &size
))
1804 ok
= wsetselection(self
->w_win
, sel
, text
, size
);
1805 return newintobject(ok
);
1809 window_setwincursor(self
, args
)
1815 if (!getargs(args
, "z", &name
))
1820 c
= wfetchcursor(name
);
1822 err_setstr(StdwinError
, "no such cursor");
1826 wsetwincursor(self
->w_win
, c
);
1832 window_setactive(self
, args
)
1836 if (!getnoarg(args
))
1838 wsetactive(self
->w_win
);
1845 window_getxwindowid(self
, args
)
1849 long wid
= wgetxwindowid(self
->w_win
);
1850 return newintobject(wid
);
1854 static struct methodlist window_methods
[] = {
1855 {"begindrawing",window_begindrawing
},
1856 {"change", window_change
},
1857 {"close", window_close
},
1858 {"getdocsize", window_getdocsize
},
1859 {"getorigin", window_getorigin
},
1860 {"gettitle", window_gettitle
},
1861 {"getwinpos", window_getwinpos
},
1862 {"getwinsize", window_getwinsize
},
1863 {"menucreate", window_menucreate
},
1864 {"scroll", window_scroll
},
1865 {"setactive", window_setactive
},
1866 {"setdocsize", window_setdocsize
},
1867 {"setorigin", window_setorigin
},
1868 {"setselection",window_setselection
},
1869 {"settimer", window_settimer
},
1870 {"settitle", window_settitle
},
1871 {"setwincursor",window_setwincursor
},
1872 {"setwinpos", window_setwinpos
},
1873 {"setwinsize", window_setwinsize
},
1874 {"show", window_show
},
1875 {"textcreate", window_textcreate
},
1877 {"getxwindowid",window_getxwindowid
},
1879 {NULL
, NULL
} /* sentinel */
1883 window_getattr(wp
, name
)
1888 if (wp
->w_win
== NULL
) {
1889 err_setstr(StdwinError
, "window already closed");
1892 if (strcmp(name
, "__dict__") == 0) {
1897 else if (wp
->w_attr
!= NULL
) {
1898 v
= dictlookup(wp
->w_attr
, name
);
1904 return findmethod(window_methods
, (object
*)wp
, name
);
1908 window_setattr(wp
, name
, v
)
1913 if (wp
->w_attr
== NULL
) {
1914 wp
->w_attr
= newdictobject();
1915 if (wp
->w_attr
== NULL
)
1919 int rv
= dictremove(wp
->w_attr
, name
);
1921 err_setstr(AttributeError
,
1922 "delete non-existing menu object attribute");
1926 return dictinsert(wp
->w_attr
, name
, v
);
1929 typeobject Windowtype
= {
1930 OB_HEAD_INIT(&Typetype
)
1932 "window", /*tp_name*/
1933 sizeof(windowobject
), /*tp_size*/
1936 window_dealloc
, /*tp_dealloc*/
1938 window_getattr
, /*tp_getattr*/
1939 window_setattr
, /*tp_setattr*/
1944 /* Stdwin methods */
1947 stdwin_done(sw
, args
)
1951 if (!getnoarg(args
))
1954 /* XXX There is no protection against continued use of
1955 XXX stdwin functions or objects after this call is made.
1956 XXX Use at own risk */
1962 stdwin_open(sw
, args
)
1969 if (!getargs(args
, "S", &title
))
1971 for (tag
= 0; tag
< MAXNWIN
; tag
++) {
1972 if (windowlist
[tag
] == NULL
)
1975 if (tag
>= MAXNWIN
) {
1976 err_setstr(StdwinError
, "creating too many windows");
1979 wp
= NEWOBJ(windowobject
, &Windowtype
);
1983 wp
->w_title
= title
;
1984 wp
->w_win
= wopen(getstringvalue(title
), (void (*)()) NULL
);
1986 if (wp
->w_win
== NULL
) {
1990 windowlist
[tag
] = wp
;
1991 wsettag(wp
->w_win
, tag
);
1992 return (object
*)wp
;
2003 int tag
= wgettag(win
);
2004 if (tag
< 0 || tag
>= MAXNWIN
|| windowlist
[tag
] == NULL
||
2005 windowlist
[tag
]->w_win
!= win
)
2008 w
= (object
*)windowlist
[tag
];
2015 stdwin_get_poll_event(poll
, args
)
2021 if (!getnoarg(args
))
2023 if (Drawing
!= NULL
) {
2024 err_setstr(StdwinError
, "cannot getevent() while drawing");
2030 if (!wpollevent(&e
)) {
2039 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CANCEL
) {
2040 /* Turn keyboard interrupts into exceptions */
2041 err_set(KeyboardInterrupt
);
2044 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CLOSE
) {
2045 /* Turn WC_CLOSE commands into WE_CLOSE events */
2048 v
= window2object(e
.window
);
2053 c
[0] = e
.u
.character
;
2054 w
= newsizedstringobject(c
, 1);
2058 w
= newintobject((long)e
.u
.command
);
2061 w
= makerect(e
.u
.area
.left
, e
.u
.area
.top
,
2062 e
.u
.area
.right
, e
.u
.area
.bottom
);
2067 w
= mkvalue("((ii)iii)",
2068 e
.u
.where
.h
, e
.u
.where
.v
,
2074 if (e
.u
.m
.id
>= IDOFFSET
&& e
.u
.m
.id
< IDOFFSET
+MAXNMENU
&&
2075 menulist
[e
.u
.m
.id
- IDOFFSET
] != NULL
)
2077 menulist
[e
.u
.m
.id
- IDOFFSET
], e
.u
.m
.item
);
2079 /* Ghost menu event.
2080 Can occur only on the Mac if another part
2081 of the aplication has installed a menu;
2082 like the THINK C console library. */
2088 w
= mkvalue("(ii)", e
.u
.key
.code
, e
.u
.key
.mask
);
2091 w
= newintobject((long)e
.u
.sel
);
2102 u
= mkvalue("(iOO)", e
.type
, v
, w
);
2109 stdwin_getevent(sw
, args
)
2113 return stdwin_get_poll_event(0, args
);
2117 stdwin_pollevent(sw
, args
)
2121 return stdwin_get_poll_event(1, args
);
2125 stdwin_setdefwinpos(sw
, args
)
2130 if (!getpointarg(args
, a
))
2132 wsetdefwinpos(a
[0], a
[1]);
2138 stdwin_setdefwinsize(sw
, args
)
2143 if (!getpointarg(args
, a
))
2145 wsetdefwinsize(a
[0], a
[1]);
2151 stdwin_setdefscrollbars(sw
, args
)
2156 if (!getpointarg(args
, a
))
2158 wsetdefscrollbars(a
[0], a
[1]);
2164 stdwin_getdefwinpos(self
, args
)
2169 if (!getnoarg(args
))
2171 wgetdefwinpos(&h
, &v
);
2172 return makepoint(h
, v
);
2176 stdwin_getdefwinsize(self
, args
)
2181 if (!getnoarg(args
))
2183 wgetdefwinsize(&width
, &height
);
2184 return makepoint(width
, height
);
2188 stdwin_getdefscrollbars(self
, args
)
2193 if (!getnoarg(args
))
2195 wgetdefscrollbars(&h
, &v
);
2196 return makepoint(h
, v
);
2200 stdwin_menucreate(self
, args
)
2205 if (!getstrarg(args
, &title
))
2207 wmenusetdeflocal(0);
2208 return (object
*)newmenuobject(title
);
2212 stdwin_askfile(self
, args
)
2216 char *prompt
, *dflt
;
2219 if (!getargs(args
, "(ssi)", &prompt
, &dflt
, &new))
2221 strncpy(buf
, dflt
, sizeof buf
);
2222 buf
[sizeof buf
- 1] = '\0';
2224 ret
= waskfile(prompt
, buf
, sizeof buf
, new);
2227 err_set(KeyboardInterrupt
);
2230 return newstringobject(buf
);
2234 stdwin_askync(self
, args
)
2240 if (!getargs(args
, "(si)", &prompt
, &new))
2243 ret
= waskync(prompt
, new);
2246 err_set(KeyboardInterrupt
);
2249 return newintobject((long)ret
);
2253 stdwin_askstr(self
, args
)
2257 char *prompt
, *dflt
;
2260 if (!getargs(args
, "(ss)", &prompt
, &dflt
))
2262 strncpy(buf
, dflt
, sizeof buf
);
2263 buf
[sizeof buf
- 1] = '\0';
2265 ret
= waskstr(prompt
, buf
, sizeof buf
);
2268 err_set(KeyboardInterrupt
);
2271 return newstringobject(buf
);
2275 stdwin_message(self
, args
)
2280 if (!getstrarg(args
, &msg
))
2290 stdwin_fleep(self
, args
)
2294 if (!getnoarg(args
))
2302 stdwin_setcutbuffer(self
, args
)
2308 if (!getargs(args
, "(is#)", &i
, &str
, &size
))
2310 wsetcutbuffer(i
, str
, size
);
2316 stdwin_getactive(self
, args
)
2320 return window2object(wgetactive());
2324 stdwin_getcutbuffer(self
, args
)
2331 if (!getintarg(args
, &i
))
2333 str
= wgetcutbuffer(i
, &len
);
2338 return newsizedstringobject(str
, len
);
2342 stdwin_rotatecutbuffers(self
, args
)
2347 if (!getintarg(args
, &i
))
2349 wrotatecutbuffers(i
);
2355 stdwin_getselection(self
, args
)
2362 if (!getintarg(args
, &sel
))
2364 data
= wgetselection(sel
, &len
);
2369 return newsizedstringobject(data
, len
);
2373 stdwin_resetselection(self
, args
)
2378 if (!getintarg(args
, &sel
))
2380 wresetselection(sel
);
2386 stdwin_fetchcolor(self
, args
)
2392 if (!getstrarg(args
, &colorname
))
2394 color
= wfetchcolor(colorname
);
2396 if (color
== BADCOLOR
) {
2397 err_setstr(StdwinError
, "color name not found");
2401 return newintobject((long)color
);
2405 stdwin_getscrsize(self
, args
)
2410 if (!getnoarg(args
))
2412 wgetscrsize(&width
, &height
);
2413 return makepoint(width
, height
);
2417 stdwin_getscrmm(self
, args
)
2422 if (!getnoarg(args
))
2424 wgetscrmm(&width
, &height
);
2425 return makepoint(width
, height
);
2430 stdwin_connectionnumber(self
, args
)
2434 if (!getnoarg(args
))
2436 return newintobject((long) wconnectionnumber());
2441 stdwin_listfontnames(self
, args
)
2449 if (!getargs(args
, "z", &pattern
))
2451 fontnames
= wlistfontnames(pattern
, &count
);
2452 list
= newlistobject(count
);
2455 for (i
= 0; i
< count
; i
++) {
2456 object
*v
= newstringobject(fontnames
[i
]);
2462 setlistitem(list
, i
, v
);
2470 stdwin_newbitmap(self
, args
)
2476 if (!getargs(args
, "(ii)", &width
, &height
))
2478 return (object
*)newbitmapobject(width
, height
);
2482 static struct methodlist stdwin_methods
[] = {
2483 {"askfile", stdwin_askfile
},
2484 {"askstr", stdwin_askstr
},
2485 {"askync", stdwin_askync
},
2486 {"done", stdwin_done
},
2487 {"fetchcolor", stdwin_fetchcolor
},
2489 {"fileno", stdwin_connectionnumber
},
2490 {"connectionnumber", stdwin_connectionnumber
},
2492 {"fleep", stdwin_fleep
},
2493 {"getactive", stdwin_getactive
},
2494 {"getcutbuffer", stdwin_getcutbuffer
},
2495 {"getdefscrollbars", stdwin_getdefscrollbars
},
2496 {"getdefwinpos", stdwin_getdefwinpos
},
2497 {"getdefwinsize", stdwin_getdefwinsize
},
2498 {"getevent", stdwin_getevent
},
2499 {"getscrmm", stdwin_getscrmm
},
2500 {"getscrsize", stdwin_getscrsize
},
2501 {"getselection", stdwin_getselection
},
2502 {"listfontnames", stdwin_listfontnames
},
2503 {"menucreate", stdwin_menucreate
},
2504 {"message", stdwin_message
},
2506 {"newbitmap", stdwin_newbitmap
},
2508 {"open", stdwin_open
},
2509 {"pollevent", stdwin_pollevent
},
2510 {"resetselection", stdwin_resetselection
},
2511 {"rotatecutbuffers", stdwin_rotatecutbuffers
},
2512 {"setcutbuffer", stdwin_setcutbuffer
},
2513 {"setdefscrollbars", stdwin_setdefscrollbars
},
2514 {"setdefwinpos", stdwin_setdefwinpos
},
2515 {"setdefwinsize", stdwin_setdefwinsize
},
2517 /* Text measuring methods borrow code from drawing objects: */
2518 {"baseline", drawing_baseline
},
2519 {"lineheight", drawing_lineheight
},
2520 {"textbreak", drawing_textbreak
},
2521 {"textwidth", drawing_textwidth
},
2523 /* Same for font setting methods: */
2524 {"setfont", drawing_setfont
},
2526 /* Same for color setting/getting methods: */
2527 {"getbgcolor", drawing_getbgcolor
},
2528 {"getfgcolor", drawing_getfgcolor
},
2529 {"setbgcolor", drawing_setbgcolor
},
2530 {"setfgcolor", drawing_setfgcolor
},
2532 {NULL
, NULL
} /* sentinel */
2536 checkstringlist(args
, ps
, pn
)
2543 if (!is_listobject(args
)) {
2544 err_setstr(TypeError
, "list of strings expected");
2547 n
= getlistsize(args
);
2548 s
= NEW(char *, n
+1);
2553 for (i
= 0; i
< n
; i
++) {
2554 object
*item
= getlistitem(args
, i
);
2555 if (!is_stringobject(item
)) {
2556 err_setstr(TypeError
, "list of strings expected");
2559 s
[i
] = getstringvalue(item
);
2561 s
[n
] = NULL
; /* In case caller wants a NULL-terminated list */
2568 putbackstringlist(list
, s
, n
)
2573 int oldsize
= getlistsize(list
);
2578 newlist
= newlistobject(n
);
2579 for (i
= 0; i
< n
&& newlist
!= NULL
; i
++) {
2580 object
*item
= newstringobject(s
[i
]);
2586 setlistitem(newlist
, i
, item
);
2588 if (newlist
== NULL
)
2590 (*list
->ob_type
->tp_as_sequence
->sq_ass_slice
)
2591 (list
, 0, oldsize
, newlist
);
2600 static int inited
= 0;
2606 object
*sys_argv
= sysget("argv");
2607 if (sys_argv
!= NULL
) {
2608 if (!checkstringlist(sys_argv
, &argv
, &argc
))
2612 /* If argv[0] has a ".py" suffix, remove the suffix */
2613 char *p
= strrchr(argv
[0], '.');
2614 if (p
!= NULL
&& strcmp(p
, ".py") == 0) {
2615 int n
= p
- argv
[0];
2616 if (n
>= sizeof(buf
))
2618 strncpy(buf
, argv
[0], n
);
2623 winitargs(&argc
, &argv
);
2625 if (!putbackstringlist(sys_argv
, argv
, argc
))
2630 m
= initmodule("stdwin", stdwin_methods
);
2631 d
= getmoduledict(m
);
2633 /* Initialize stdwin.error exception */
2634 StdwinError
= newstringobject("stdwin.error");
2635 if (StdwinError
== NULL
|| dictinsert(d
, "error", StdwinError
) != 0)
2636 fatal("can't define stdwin.error");
2638 StdwinLock
= allocate_lock();
2639 if (StdwinLock
== NULL
)
2640 fatal("can't allocate stdwin lock");