1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
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 */
111 /* Window and menu object types declared here because of forward references */
117 object
*w_attr
; /* Attributes dictionary */
120 staticforward typeobject Windowtype
;
122 #define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
128 object
*m_attr
; /* Attributes dictionary */
131 staticforward typeobject Menutype
;
133 #define is_menuobject(mp) ((mp)->ob_type == &Menutype)
138 object
*b_attr
; /* Attributes dictionary */
141 staticforward typeobject Bitmaptype
;
143 #define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
146 /* Strongly stdwin-specific argument handlers */
154 if (!getargs(v
, "(Oi)", &mp
, &ep
->u
.m
.item
))
156 if (!is_menuobject(mp
))
158 ep
->u
.m
.id
= mp
->m_id
;
169 if (!getargs(v
, "(iOO)", &ep
->type
, &wp
, &detail
))
171 if (is_windowobject(wp
))
172 ep
->window
= ((windowobject
*)wp
) -> w_win
;
180 if (!getargs(detail
, "c", &c
))
186 return getintarg(detail
, &ep
->u
.command
);
188 if (!getrectarg(detail
, a
))
190 ep
->u
.area
.left
= a
[0];
191 ep
->u
.area
.top
= a
[1];
192 ep
->u
.area
.right
= a
[2];
193 ep
->u
.area
.bottom
= a
[3];
198 return getargs(detail
, "((ii)iii)",
199 &ep
->u
.where
.h
, &ep
->u
.where
.v
,
204 return getmenudetail(detail
, ep
);
206 return getargs(detail
, "(ii)",
207 &ep
->u
.key
.code
, &ep
->u
.key
.mask
);
214 /* Return construction tools */
220 return mkvalue("(ii)", a
, b
);
227 return mkvalue("((ii)(ii))", a
, b
, c
, d
);
231 /* Drawing objects */
238 static drawingobject
*Drawing
; /* Set to current drawing object, or NULL */
240 /* Drawing methods */
246 if (dp
->d_ref
!= NULL
) {
247 wenddrawing(dp
->d_ref
->w_win
);
260 if (dp
->d_ref
!= NULL
) {
261 wenddrawing(dp
->d_ref
->w_win
);
270 drawing_generic(dp
, args
, func
)
273 void (*func
) FPROTO((int, int, int, int));
276 if (!getrectarg(args
, a
))
278 (*func
)(a
[0], a
[1], a
[2], a
[3]);
284 drawing_line(dp
, args
)
288 return drawing_generic(dp
, args
, wdrawline
);
292 drawing_xorline(dp
, args
)
296 return drawing_generic(dp
, args
, wxorline
);
300 drawing_circle(dp
, args
)
305 if (!getpointintarg(args
, a
))
307 wdrawcircle(a
[0], a
[1], a
[2]);
313 drawing_fillcircle(dp
, args
)
318 if (!getpointintarg(args
, a
))
320 wfillcircle(a
[0], a
[1], a
[2]);
326 drawing_xorcircle(dp
, args
)
331 if (!getpointintarg(args
, a
))
333 wxorcircle(a
[0], a
[1], a
[2]);
339 drawing_elarc(dp
, args
)
344 if (!get3pointarg(args
, a
))
346 wdrawelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
352 drawing_fillelarc(dp
, args
)
357 if (!get3pointarg(args
, a
))
359 wfillelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
365 drawing_xorelarc(dp
, args
)
370 if (!get3pointarg(args
, a
))
372 wxorelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
378 drawing_box(dp
, args
)
382 return drawing_generic(dp
, args
, wdrawbox
);
386 drawing_erase(dp
, args
)
390 return drawing_generic(dp
, args
, werase
);
394 drawing_paint(dp
, args
)
398 return drawing_generic(dp
, args
, wpaint
);
402 drawing_invert(dp
, args
)
406 return drawing_generic(dp
, args
, winvert
);
410 getpointsarray(v
, psize
)
415 object
* (*getitem
) PROTO((object
*, int));
421 else if (is_listobject(v
)) {
423 getitem
= getlistitem
;
425 else if (is_tupleobject(v
)) {
427 getitem
= gettupleitem
;
435 points
= NEW(POINT
, n
);
436 if (points
== NULL
) {
441 for (i
= 0; i
< n
; i
++) {
442 object
*w
= (*getitem
)(v
, i
);
444 if (!getpointarg(w
, a
)) {
457 drawing_poly(dp
, args
)
462 POINT
*points
= getpointsarray(args
, &n
);
465 wdrawpoly(n
, points
);
472 drawing_fillpoly(dp
, args
)
477 POINT
*points
= getpointsarray(args
, &n
);
480 wfillpoly(n
, points
);
487 drawing_xorpoly(dp
, args
)
492 POINT
*points
= getpointsarray(args
, &n
);
502 drawing_cliprect(dp
, args
)
506 return drawing_generic(dp
, args
, wcliprect
);
510 drawing_noclip(dp
, args
)
522 drawing_shade(dp
, args
)
527 if (!getrectintarg(args
, a
))
529 wshade(a
[0], a
[1], a
[2], a
[3], a
[4]);
535 drawing_text(dp
, args
)
541 if (!getargs(args
, "((ii)s#)", &h
, &v
, &text
, &size
))
543 wdrawtext(h
, v
, text
, size
);
548 /* The following four are also used as stdwin functions */
551 drawing_lineheight(dp
, args
)
557 return newintobject((long)wlineheight());
561 drawing_baseline(dp
, args
)
567 return newintobject((long)wbaseline());
571 drawing_textwidth(dp
, args
)
577 if (!getargs(args
, "s#", &text
, &size
))
579 return newintobject((long)wtextwidth(text
, size
));
583 drawing_textbreak(dp
, args
)
589 if (!getargs(args
, "(s#i)", &text
, &size
, &width
))
591 return newintobject((long)wtextbreak(text
, size
, width
));
595 drawing_setfont(self
, args
)
602 if (args
== NULL
|| !is_tupleobject(args
)) {
603 if (!getargs(args
, "z", &font
))
607 int n
= gettuplesize(args
);
609 if (!getargs(args
, "(zi)", &font
, &size
))
612 else if (!getargs(args
, "(zic)", &font
, &size
, &style
)) {
614 if (!getargs(args
, "(zci)", &font
, &style
, &size
))
619 if (!wsetfont(font
)) {
620 err_setstr(StdwinError
, "font not found");
648 drawing_getbgcolor(self
, args
)
654 return newintobject((long)wgetbgcolor());
658 drawing_getfgcolor(self
, args
)
664 return newintobject((long)wgetfgcolor());
668 drawing_setbgcolor(self
, args
)
673 if (!getlongarg(args
, &color
))
675 wsetbgcolor((COLOR
)color
);
681 drawing_setfgcolor(self
, args
)
686 if (!getlongarg(args
, &color
))
688 wsetfgcolor((COLOR
)color
);
696 drawing_bitmap(self
, args
)
703 if (!getargs(args
, "((ii)O)", &h
, &v
, &bp
)) {
705 if (!getargs(args
, "((ii)OO)", &h
, &v
, &bp
, &mask
))
709 else if (!is_bitmapobject(mask
)) {
714 if (!is_bitmapobject(bp
)) {
718 if (((bitmapobject
*)bp
)->b_bitmap
== NULL
||
719 mask
!= NULL
&& ((bitmapobject
*)mask
)->b_bitmap
== NULL
) {
720 err_setstr(StdwinError
, "bitmap object already close");
724 wdrawbitmap(h
, v
, ((bitmapobject
*)bp
)->b_bitmap
, ALLBITS
);
727 ((bitmapobject
*)bp
)->b_bitmap
,
728 ((bitmapobject
*)bp
)->b_bitmap
);
733 #endif /* HAVE_BITMAPS */
735 static struct methodlist drawing_methods
[] = {
737 {"bitmap", (method
)drawing_bitmap
},
739 {"box", (method
)drawing_box
},
740 {"circle", (method
)drawing_circle
},
741 {"cliprect", (method
)drawing_cliprect
},
742 {"close", (method
)drawing_close
},
743 {"elarc", (method
)drawing_elarc
},
744 {"enddrawing", (method
)drawing_close
},
745 {"erase", (method
)drawing_erase
},
746 {"fillcircle", (method
)drawing_fillcircle
},
747 {"fillelarc", (method
)drawing_fillelarc
},
748 {"fillpoly", (method
)drawing_fillpoly
},
749 {"invert", (method
)drawing_invert
},
750 {"line", (method
)drawing_line
},
751 {"noclip", (method
)drawing_noclip
},
752 {"paint", (method
)drawing_paint
},
753 {"poly", (method
)drawing_poly
},
754 {"shade", (method
)drawing_shade
},
755 {"text", (method
)drawing_text
},
756 {"xorcircle", (method
)drawing_xorcircle
},
757 {"xorelarc", (method
)drawing_xorelarc
},
758 {"xorline", (method
)drawing_xorline
},
759 {"xorpoly", (method
)drawing_xorpoly
},
761 /* Text measuring methods: */
762 {"baseline", (method
)drawing_baseline
},
763 {"lineheight", (method
)drawing_lineheight
},
764 {"textbreak", (method
)drawing_textbreak
},
765 {"textwidth", (method
)drawing_textwidth
},
767 /* Font setting methods: */
768 {"setfont", (method
)drawing_setfont
},
771 {"getbgcolor", (method
)drawing_getbgcolor
},
772 {"getfgcolor", (method
)drawing_getfgcolor
},
773 {"setbgcolor", (method
)drawing_setbgcolor
},
774 {"setfgcolor", (method
)drawing_setfgcolor
},
776 {NULL
, NULL
} /* sentinel */
780 drawing_getattr(dp
, name
)
784 if (dp
->d_ref
== NULL
) {
785 err_setstr(StdwinError
, "drawing object already closed");
788 return findmethod(drawing_methods
, (object
*)dp
, name
);
791 typeobject Drawingtype
= {
792 OB_HEAD_INIT(&Typetype
)
794 "drawing", /*tp_name*/
795 sizeof(drawingobject
), /*tp_size*/
798 (destructor
)drawing_dealloc
, /*tp_dealloc*/
800 (getattrfunc
)drawing_getattr
, /*tp_getattr*/
807 /* Text(edit) objects */
813 object
*t_attr
; /* Attributes dictionary */
816 staticforward typeobject Texttype
;
819 newtextobject(wp
, left
, top
, right
, bottom
)
821 int left
, top
, right
, bottom
;
824 tp
= NEWOBJ(textobject
, &Texttype
);
830 tp
->t_text
= tecreate(wp
->w_win
, left
, top
, right
, bottom
);
831 if (tp
->t_text
== NULL
) {
833 return (textobject
*) err_nomem();
838 /* Text(edit) methods */
844 if (tp
->t_text
!= NULL
)
856 if (tp
->t_text
!= NULL
) {
860 if (tp
->t_attr
!= NULL
) {
864 if (tp
->t_ref
!= NULL
) {
873 text_arrow(self
, args
)
878 if (!getintarg(args
, &code
))
880 tearrow(self
->t_text
, code
);
886 text_draw(self
, args
)
890 register TEXTEDIT
*tp
= self
->t_text
;
892 int left
, top
, right
, bottom
;
893 if (!getrectarg(args
, a
))
895 if (Drawing
!= NULL
) {
896 err_setstr(StdwinError
, "already drawing");
899 /* Clip to text area and ignore if area is empty */
900 left
= tegetleft(tp
);
902 right
= tegetright(tp
);
903 bottom
= tegetbottom(tp
);
904 if (a
[0] < left
) a
[0] = left
;
905 if (a
[1] < top
) a
[1] = top
;
906 if (a
[2] > right
) a
[2] = right
;
907 if (a
[3] > bottom
) a
[3] = bottom
;
908 if (a
[0] < a
[2] && a
[1] < a
[3]) {
909 wbegindrawing(self
->t_ref
->w_win
);
910 tedrawnew(tp
, a
[0], a
[1], a
[2], a
[3]);
911 wenddrawing(self
->t_ref
->w_win
);
918 text_event(self
, args
)
922 register TEXTEDIT
*tp
= self
->t_text
;
924 if (!geteventarg(args
, &e
))
926 if (e
.type
== WE_MOUSE_DOWN
) {
927 /* Cheat at the margins */
929 wgetdocsize(e
.window
, &width
, &height
);
930 if (e
.u
.where
.h
< 0 && tegetleft(tp
) == 0)
932 else if (e
.u
.where
.h
> width
&& tegetright(tp
) == width
)
934 if (e
.u
.where
.v
< 0 && tegettop(tp
) == 0)
936 else if (e
.u
.where
.v
> height
&& tegetright(tp
) == height
)
937 e
.u
.where
.v
= height
;
939 return newintobject((long) teevent(tp
, &e
));
943 text_getfocus(self
, args
)
949 return makepoint(tegetfoc1(self
->t_text
), tegetfoc2(self
->t_text
));
953 text_getfocustext(self
, args
)
961 f1
= tegetfoc1(self
->t_text
);
962 f2
= tegetfoc2(self
->t_text
);
963 text
= tegettext(self
->t_text
);
964 return newsizedstringobject(text
+ f1
, f2
-f1
);
968 text_getrect(self
, args
)
974 return makerect(tegetleft(self
->t_text
),
975 tegettop(self
->t_text
),
976 tegetright(self
->t_text
),
977 tegetbottom(self
->t_text
));
981 text_gettext(self
, args
)
987 return newsizedstringobject(tegettext(self
->t_text
),
988 tegetlen(self
->t_text
));
992 text_move(self
, args
)
997 if (!getrectarg(args
, a
))
999 temovenew(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1005 text_replace(self
, args
)
1010 if (!getstrarg(args
, &text
))
1012 tereplace(self
->t_text
, text
);
1018 text_setactive(self
, args
)
1023 if (!getintarg(args
, &flag
))
1025 tesetactive(self
->t_text
, flag
);
1031 text_setfocus(self
, args
)
1036 if (!getpointarg(args
, a
))
1038 tesetfocus(self
->t_text
, a
[0], a
[1]);
1044 text_settext(self
, args
)
1051 if (!getargs(args
, "s#", &text
, &size
))
1053 if ((buf
= NEW(char, size
)) == NULL
) {
1056 memcpy(buf
, text
, size
);
1057 tesetbuf(self
->t_text
, buf
, size
); /* Becomes owner of buffer */
1063 text_setview(self
, args
)
1069 tenoview(self
->t_text
);
1071 if (!getrectarg(args
, a
))
1073 tesetview(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1079 static struct methodlist text_methods
[] = {
1080 {"arrow", (method
)text_arrow
},
1081 {"close", (method
)text_close
},
1082 {"draw", (method
)text_draw
},
1083 {"event", (method
)text_event
},
1084 {"getfocus", (method
)text_getfocus
},
1085 {"getfocustext",(method
)text_getfocustext
},
1086 {"getrect", (method
)text_getrect
},
1087 {"gettext", (method
)text_gettext
},
1088 {"move", (method
)text_move
},
1089 {"replace", (method
)text_replace
},
1090 {"setactive", (method
)text_setactive
},
1091 {"setfocus", (method
)text_setfocus
},
1092 {"settext", (method
)text_settext
},
1093 {"setview", (method
)text_setview
},
1094 {NULL
, NULL
} /* sentinel */
1098 text_getattr(tp
, name
)
1103 if (tp
->t_ref
== NULL
) {
1104 err_setstr(StdwinError
, "text object already closed");
1107 if (strcmp(name
, "__dict__") == 0) {
1112 else if (tp
->t_attr
!= NULL
) {
1113 v
= dictlookup(tp
->t_attr
, name
);
1119 return findmethod(text_methods
, (object
*)tp
, name
);
1123 text_setattr(tp
, name
, v
)
1128 if (tp
->t_attr
== NULL
) {
1129 tp
->t_attr
= newdictobject();
1130 if (tp
->t_attr
== NULL
)
1134 int rv
= dictremove(tp
->t_attr
, name
);
1136 err_setstr(AttributeError
,
1137 "delete non-existing text object attribute");
1141 return dictinsert(tp
->t_attr
, name
, v
);
1144 statichere typeobject Texttype
= {
1145 OB_HEAD_INIT(&Typetype
)
1147 "textedit", /*tp_name*/
1148 sizeof(textobject
), /*tp_size*/
1151 (destructor
)text_dealloc
, /*tp_dealloc*/
1153 (getattrfunc
)text_getattr
, /*tp_getattr*/
1154 (setattrfunc
)text_setattr
, /*tp_setattr*/
1162 #define IDOFFSET 10 /* Menu IDs we use start here */
1163 #define MAXNMENU 200 /* Max #menus we allow */
1164 static menuobject
*menulist
[MAXNMENU
];
1166 static menuobject
*newmenuobject
PROTO((char *));
1168 newmenuobject(title
)
1174 for (id
= 0; id
< MAXNMENU
; id
++) {
1175 if (menulist
[id
] == NULL
)
1178 if (id
>= MAXNMENU
) {
1179 err_setstr(StdwinError
, "creating too many menus");
1182 menu
= wmenucreate(id
+ IDOFFSET
, title
);
1184 return (menuobject
*) err_nomem();
1185 mp
= NEWOBJ(menuobject
, &Menutype
);
1188 mp
->m_id
= id
+ IDOFFSET
;
1204 int id
= mp
->m_id
- IDOFFSET
;
1205 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1206 menulist
[id
] = NULL
;
1208 if (mp
->m_menu
!= NULL
)
1209 wmenudelete(mp
->m_menu
);
1210 XDECREF(mp
->m_attr
);
1215 menu_close(mp
, args
)
1219 int id
= mp
->m_id
- IDOFFSET
;
1220 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1221 menulist
[id
] = NULL
;
1224 if (mp
->m_menu
!= NULL
)
1225 wmenudelete(mp
->m_menu
);
1227 XDECREF(mp
->m_attr
);
1234 menu_additem(self
, args
)
1240 if (is_tupleobject(args
)) {
1242 if (!getargs(args
, "(sc)", &text
, &c
))
1246 else if (!getstrarg(args
, &text
))
1248 wmenuadditem(self
->m_menu
, text
, shortcut
);
1254 menu_setitem(self
, args
)
1260 if (!getargs(args
, "(is)", &index
, &text
))
1262 wmenusetitem(self
->m_menu
, index
, text
);
1268 menu_enable(self
, args
)
1274 if (!getargs(args
, "(ii)", &index
, &flag
))
1276 wmenuenable(self
->m_menu
, index
, flag
);
1282 menu_check(self
, args
)
1288 if (!getargs(args
, "(ii)", &index
, &flag
))
1290 wmenucheck(self
->m_menu
, index
, flag
);
1295 static struct methodlist menu_methods
[] = {
1296 {"additem", (method
)menu_additem
},
1297 {"setitem", (method
)menu_setitem
},
1298 {"enable", (method
)menu_enable
},
1299 {"check", (method
)menu_check
},
1300 {"close", (method
)menu_close
},
1301 {NULL
, NULL
} /* sentinel */
1305 menu_getattr(mp
, name
)
1310 if (mp
->m_menu
== NULL
) {
1311 err_setstr(StdwinError
, "menu object already closed");
1314 if (strcmp(name
, "__dict__") == 0) {
1319 else if (mp
->m_attr
!= NULL
) {
1320 v
= dictlookup(mp
->m_attr
, name
);
1326 return findmethod(menu_methods
, (object
*)mp
, name
);
1330 menu_setattr(mp
, name
, v
)
1335 if (mp
->m_attr
== NULL
) {
1336 mp
->m_attr
= newdictobject();
1337 if (mp
->m_attr
== NULL
)
1341 int rv
= dictremove(mp
->m_attr
, name
);
1343 err_setstr(AttributeError
,
1344 "delete non-existing menu object attribute");
1348 return dictinsert(mp
->m_attr
, name
, v
);
1351 statichere typeobject Menutype
= {
1352 OB_HEAD_INIT(&Typetype
)
1355 sizeof(menuobject
), /*tp_size*/
1358 (destructor
)menu_dealloc
, /*tp_dealloc*/
1360 (getattrfunc
)menu_getattr
, /*tp_getattr*/
1361 (setattrfunc
)menu_setattr
, /*tp_setattr*/
1369 /* Bitmaps objects */
1371 static bitmapobject
*newbitmapobject
PROTO((int, int));
1372 static bitmapobject
*
1373 newbitmapobject(width
, height
)
1378 bitmap
= wnewbitmap(width
, height
);
1380 return (bitmapobject
*) err_nomem();
1381 bp
= NEWOBJ(bitmapobject
, &Bitmaptype
);
1383 bp
->b_bitmap
= bitmap
;
1387 wfreebitmap(bitmap
);
1391 /* Bitmap methods */
1397 if (bp
->b_bitmap
!= NULL
)
1398 wfreebitmap(bp
->b_bitmap
);
1399 XDECREF(bp
->b_attr
);
1404 bitmap_close(bp
, args
)
1408 if (bp
->b_bitmap
!= NULL
)
1409 wfreebitmap(bp
->b_bitmap
);
1410 bp
->b_bitmap
= NULL
;
1411 XDECREF(bp
->b_attr
);
1418 bitmap_setbit(self
, args
)
1423 if (!getpointintarg(args
, a
))
1425 wsetbit(self
->b_bitmap
, a
[0], a
[1], a
[2]);
1431 bitmap_getbit(self
, args
)
1436 if (!getpointarg(args
, a
))
1438 return newintobject((long) wgetbit(self
->b_bitmap
, a
[0], a
[1]));
1442 bitmap_getsize(self
, args
)
1447 if (!getnoarg(args
))
1449 wgetbitmapsize(self
->b_bitmap
, &width
, &height
);
1450 return mkvalue("(ii)", width
, height
);
1453 static struct methodlist bitmap_methods
[] = {
1454 {"close", (method
)bitmap_close
},
1455 {"getsize", (method
)bitmap_getsize
},
1456 {"getbit", (method
)bitmap_getbit
},
1457 {"setbit", (method
)bitmap_setbit
},
1458 {NULL
, NULL
} /* sentinel */
1462 bitmap_getattr(bp
, name
)
1467 if (bp
->b_bitmap
== NULL
) {
1468 err_setstr(StdwinError
, "bitmap object already closed");
1471 if (strcmp(name
, "__dict__") == 0) {
1476 else if (bp
->b_attr
!= NULL
) {
1477 v
= dictlookup(bp
->b_attr
, name
);
1483 return findmethod(bitmap_methods
, (object
*)bp
, name
);
1487 bitmap_setattr(bp
, name
, v
)
1492 if (bp
->b_attr
== NULL
) {
1493 bp
->b_attr
= newdictobject();
1494 if (bp
->b_attr
== NULL
)
1498 int rv
= dictremove(bp
->b_attr
, name
);
1500 err_setstr(AttributeError
,
1501 "delete non-existing bitmap object attribute");
1505 return dictinsert(bp
->b_attr
, name
, v
);
1508 statichere typeobject Bitmaptype
= {
1509 OB_HEAD_INIT(&Typetype
)
1511 "bitmap", /*tp_name*/
1512 sizeof(bitmapobject
), /*tp_size*/
1515 (destructor
)bitmap_dealloc
, /*tp_dealloc*/
1517 (getattrfunc
)bitmap_getattr
, /*tp_getattr*/
1518 (setattrfunc
)bitmap_setattr
, /*tp_setattr*/
1523 #endif /* HAVE_BITMAPS */
1529 static windowobject
*windowlist
[MAXNWIN
];
1531 /* Window methods */
1537 if (wp
->w_win
!= NULL
) {
1538 int tag
= wgettag(wp
->w_win
);
1539 if (tag
>= 0 && tag
< MAXNWIN
)
1540 windowlist
[tag
] = NULL
;
1542 fprintf(stderr
, "XXX help! tag %d in window_dealloc\n",
1546 DECREF(wp
->w_title
);
1547 if (wp
->w_attr
!= NULL
)
1553 window_close(wp
, args
)
1557 if (wp
->w_win
!= NULL
) {
1558 int tag
= wgettag(wp
->w_win
);
1559 if (tag
>= 0 && tag
< MAXNWIN
)
1560 windowlist
[tag
] = NULL
;
1569 window_begindrawing(wp
, args
)
1574 if (!getnoarg(args
))
1576 if (Drawing
!= NULL
) {
1577 err_setstr(StdwinError
, "already drawing");
1580 dp
= NEWOBJ(drawingobject
, &Drawingtype
);
1586 wbegindrawing(wp
->w_win
);
1587 return (object
*)dp
;
1591 window_change(wp
, args
)
1596 if (!getrectarg(args
, a
))
1598 wchange(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1604 window_gettitle(wp
, args
)
1608 if (!getnoarg(args
))
1610 INCREF(wp
->w_title
);
1615 window_getwinpos(wp
, args
)
1620 if (!getnoarg(args
))
1622 wgetwinpos(wp
->w_win
, &h
, &v
);
1623 return makepoint(h
, v
);
1627 window_getwinsize(wp
, args
)
1632 if (!getnoarg(args
))
1634 wgetwinsize(wp
->w_win
, &width
, &height
);
1635 return makepoint(width
, height
);
1639 window_setwinpos(wp
, args
)
1644 if (!getpointarg(args
, a
))
1646 wsetwinpos(wp
->w_win
, a
[0], a
[1]);
1652 window_setwinsize(wp
, args
)
1657 if (!getpointarg(args
, a
))
1659 wsetwinsize(wp
->w_win
, a
[0], a
[1]);
1665 window_getdocsize(wp
, args
)
1670 if (!getnoarg(args
))
1672 wgetdocsize(wp
->w_win
, &width
, &height
);
1673 return makepoint(width
, height
);
1677 window_getorigin(wp
, args
)
1682 if (!getnoarg(args
))
1684 wgetorigin(wp
->w_win
, &width
, &height
);
1685 return makepoint(width
, height
);
1689 window_scroll(wp
, args
)
1694 if (!getrectpointarg(args
, a
))
1696 wscroll(wp
->w_win
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
1702 window_setdocsize(wp
, args
)
1707 if (!getpointarg(args
, a
))
1709 wsetdocsize(wp
->w_win
, a
[0], a
[1]);
1715 window_setorigin(wp
, args
)
1720 if (!getpointarg(args
, a
))
1722 wsetorigin(wp
->w_win
, a
[0], a
[1]);
1728 window_settitle(wp
, args
)
1733 if (!getargs(args
, "S", &title
))
1735 DECREF(wp
->w_title
);
1737 wp
->w_title
= title
;
1738 wsettitle(wp
->w_win
, getstringvalue(title
));
1744 window_show(wp
, args
)
1749 if (!getrectarg(args
, a
))
1751 wshow(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1757 window_settimer(wp
, args
)
1762 if (!getintarg(args
, &a
))
1764 wsettimer(wp
->w_win
, a
);
1770 window_menucreate(self
, args
)
1776 if (!getstrarg(args
, &title
))
1778 wmenusetdeflocal(1);
1779 mp
= newmenuobject(title
);
1782 wmenuattach(self
->w_win
, mp
->m_menu
);
1783 return (object
*)mp
;
1787 window_textcreate(self
, args
)
1792 if (!getrectarg(args
, a
))
1795 newtextobject(self
, a
[0], a
[1], a
[2], a
[3]);
1799 window_setselection(self
, args
)
1805 if (!getargs(args
, "(is#)", &sel
, &text
, &size
))
1807 ok
= wsetselection(self
->w_win
, sel
, text
, size
);
1808 return newintobject(ok
);
1812 window_setwincursor(self
, args
)
1818 if (!getargs(args
, "z", &name
))
1823 c
= wfetchcursor(name
);
1825 err_setstr(StdwinError
, "no such cursor");
1829 wsetwincursor(self
->w_win
, c
);
1835 window_setactive(self
, args
)
1839 if (!getnoarg(args
))
1841 wsetactive(self
->w_win
);
1848 window_getxwindowid(self
, args
)
1852 long wid
= wgetxwindowid(self
->w_win
);
1853 return newintobject(wid
);
1857 static struct methodlist window_methods
[] = {
1858 {"begindrawing",(method
)window_begindrawing
},
1859 {"change", (method
)window_change
},
1860 {"close", (method
)window_close
},
1861 {"getdocsize", (method
)window_getdocsize
},
1862 {"getorigin", (method
)window_getorigin
},
1863 {"gettitle", (method
)window_gettitle
},
1864 {"getwinpos", (method
)window_getwinpos
},
1865 {"getwinsize", (method
)window_getwinsize
},
1866 {"menucreate", (method
)window_menucreate
},
1867 {"scroll", (method
)window_scroll
},
1868 {"setactive", (method
)window_setactive
},
1869 {"setdocsize", (method
)window_setdocsize
},
1870 {"setorigin", (method
)window_setorigin
},
1871 {"setselection",(method
)window_setselection
},
1872 {"settimer", (method
)window_settimer
},
1873 {"settitle", (method
)window_settitle
},
1874 {"setwincursor",(method
)window_setwincursor
},
1875 {"setwinpos", (method
)window_setwinpos
},
1876 {"setwinsize", (method
)window_setwinsize
},
1877 {"show", (method
)window_show
},
1878 {"textcreate", (method
)window_textcreate
},
1880 {"getxwindowid",(method
)window_getxwindowid
},
1882 {NULL
, NULL
} /* sentinel */
1886 window_getattr(wp
, name
)
1891 if (wp
->w_win
== NULL
) {
1892 err_setstr(StdwinError
, "window already closed");
1895 if (strcmp(name
, "__dict__") == 0) {
1900 else if (wp
->w_attr
!= NULL
) {
1901 v
= dictlookup(wp
->w_attr
, name
);
1907 return findmethod(window_methods
, (object
*)wp
, name
);
1911 window_setattr(wp
, name
, v
)
1916 if (wp
->w_attr
== NULL
) {
1917 wp
->w_attr
= newdictobject();
1918 if (wp
->w_attr
== NULL
)
1922 int rv
= dictremove(wp
->w_attr
, name
);
1924 err_setstr(AttributeError
,
1925 "delete non-existing menu object attribute");
1929 return dictinsert(wp
->w_attr
, name
, v
);
1932 statichere typeobject Windowtype
= {
1933 OB_HEAD_INIT(&Typetype
)
1935 "window", /*tp_name*/
1936 sizeof(windowobject
), /*tp_size*/
1939 (destructor
)window_dealloc
, /*tp_dealloc*/
1941 (getattrfunc
)window_getattr
, /*tp_getattr*/
1942 (setattrfunc
)window_setattr
, /*tp_setattr*/
1947 /* Stdwin methods */
1950 stdwin_done(sw
, args
)
1954 if (!getnoarg(args
))
1957 /* XXX There is no protection against continued use of
1958 XXX stdwin functions or objects after this call is made.
1959 XXX Use at own risk */
1965 stdwin_open(sw
, args
)
1972 if (!getargs(args
, "S", &title
))
1974 for (tag
= 0; tag
< MAXNWIN
; tag
++) {
1975 if (windowlist
[tag
] == NULL
)
1978 if (tag
>= MAXNWIN
) {
1979 err_setstr(StdwinError
, "creating too many windows");
1982 wp
= NEWOBJ(windowobject
, &Windowtype
);
1986 wp
->w_title
= title
;
1987 wp
->w_win
= wopen(getstringvalue(title
), (void (*)()) NULL
);
1989 if (wp
->w_win
== NULL
) {
1993 windowlist
[tag
] = wp
;
1994 wsettag(wp
->w_win
, tag
);
1995 return (object
*)wp
;
2006 int tag
= wgettag(win
);
2007 if (tag
< 0 || tag
>= MAXNWIN
|| windowlist
[tag
] == NULL
||
2008 windowlist
[tag
]->w_win
!= win
)
2011 w
= (object
*)windowlist
[tag
];
2018 stdwin_get_poll_event(poll
, args
)
2024 if (!getnoarg(args
))
2026 if (Drawing
!= NULL
) {
2027 err_setstr(StdwinError
, "cannot getevent() while drawing");
2033 if (!wpollevent(&e
)) {
2042 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CANCEL
) {
2043 /* Turn keyboard interrupts into exceptions */
2044 err_set(KeyboardInterrupt
);
2047 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CLOSE
) {
2048 /* Turn WC_CLOSE commands into WE_CLOSE events */
2051 v
= window2object(e
.window
);
2056 c
[0] = e
.u
.character
;
2057 w
= newsizedstringobject(c
, 1);
2061 w
= newintobject((long)e
.u
.command
);
2064 w
= makerect(e
.u
.area
.left
, e
.u
.area
.top
,
2065 e
.u
.area
.right
, e
.u
.area
.bottom
);
2070 w
= mkvalue("((ii)iii)",
2071 e
.u
.where
.h
, e
.u
.where
.v
,
2077 if (e
.u
.m
.id
>= IDOFFSET
&& e
.u
.m
.id
< IDOFFSET
+MAXNMENU
&&
2078 menulist
[e
.u
.m
.id
- IDOFFSET
] != NULL
)
2080 menulist
[e
.u
.m
.id
- IDOFFSET
], e
.u
.m
.item
);
2082 /* Ghost menu event.
2083 Can occur only on the Mac if another part
2084 of the aplication has installed a menu;
2085 like the THINK C console library. */
2091 w
= mkvalue("(ii)", e
.u
.key
.code
, e
.u
.key
.mask
);
2094 w
= newintobject((long)e
.u
.sel
);
2105 u
= mkvalue("(iOO)", e
.type
, v
, w
);
2112 stdwin_getevent(sw
, args
)
2116 return stdwin_get_poll_event(0, args
);
2120 stdwin_pollevent(sw
, args
)
2124 return stdwin_get_poll_event(1, args
);
2128 stdwin_setdefwinpos(sw
, args
)
2133 if (!getpointarg(args
, a
))
2135 wsetdefwinpos(a
[0], a
[1]);
2141 stdwin_setdefwinsize(sw
, args
)
2146 if (!getpointarg(args
, a
))
2148 wsetdefwinsize(a
[0], a
[1]);
2154 stdwin_setdefscrollbars(sw
, args
)
2159 if (!getpointarg(args
, a
))
2161 wsetdefscrollbars(a
[0], a
[1]);
2167 stdwin_getdefwinpos(self
, args
)
2172 if (!getnoarg(args
))
2174 wgetdefwinpos(&h
, &v
);
2175 return makepoint(h
, v
);
2179 stdwin_getdefwinsize(self
, args
)
2184 if (!getnoarg(args
))
2186 wgetdefwinsize(&width
, &height
);
2187 return makepoint(width
, height
);
2191 stdwin_getdefscrollbars(self
, args
)
2196 if (!getnoarg(args
))
2198 wgetdefscrollbars(&h
, &v
);
2199 return makepoint(h
, v
);
2203 stdwin_menucreate(self
, args
)
2208 if (!getstrarg(args
, &title
))
2210 wmenusetdeflocal(0);
2211 return (object
*)newmenuobject(title
);
2215 stdwin_askfile(self
, args
)
2219 char *prompt
, *dflt
;
2222 if (!getargs(args
, "(ssi)", &prompt
, &dflt
, &new))
2224 strncpy(buf
, dflt
, sizeof buf
);
2225 buf
[sizeof buf
- 1] = '\0';
2227 ret
= waskfile(prompt
, buf
, sizeof buf
, new);
2230 err_set(KeyboardInterrupt
);
2233 return newstringobject(buf
);
2237 stdwin_askync(self
, args
)
2243 if (!getargs(args
, "(si)", &prompt
, &new))
2246 ret
= waskync(prompt
, new);
2249 err_set(KeyboardInterrupt
);
2252 return newintobject((long)ret
);
2256 stdwin_askstr(self
, args
)
2260 char *prompt
, *dflt
;
2263 if (!getargs(args
, "(ss)", &prompt
, &dflt
))
2265 strncpy(buf
, dflt
, sizeof buf
);
2266 buf
[sizeof buf
- 1] = '\0';
2268 ret
= waskstr(prompt
, buf
, sizeof buf
);
2271 err_set(KeyboardInterrupt
);
2274 return newstringobject(buf
);
2278 stdwin_message(self
, args
)
2283 if (!getstrarg(args
, &msg
))
2293 stdwin_fleep(self
, args
)
2297 if (!getnoarg(args
))
2305 stdwin_setcutbuffer(self
, args
)
2311 if (!getargs(args
, "(is#)", &i
, &str
, &size
))
2313 wsetcutbuffer(i
, str
, size
);
2319 stdwin_getactive(self
, args
)
2323 return window2object(wgetactive());
2327 stdwin_getcutbuffer(self
, args
)
2334 if (!getintarg(args
, &i
))
2336 str
= wgetcutbuffer(i
, &len
);
2341 return newsizedstringobject(str
, len
);
2345 stdwin_rotatecutbuffers(self
, args
)
2350 if (!getintarg(args
, &i
))
2352 wrotatecutbuffers(i
);
2358 stdwin_getselection(self
, args
)
2365 if (!getintarg(args
, &sel
))
2367 data
= wgetselection(sel
, &len
);
2372 return newsizedstringobject(data
, len
);
2376 stdwin_resetselection(self
, args
)
2381 if (!getintarg(args
, &sel
))
2383 wresetselection(sel
);
2389 stdwin_fetchcolor(self
, args
)
2395 if (!getstrarg(args
, &colorname
))
2397 color
= wfetchcolor(colorname
);
2399 if (color
== BADCOLOR
) {
2400 err_setstr(StdwinError
, "color name not found");
2404 return newintobject((long)color
);
2408 stdwin_getscrsize(self
, args
)
2413 if (!getnoarg(args
))
2415 wgetscrsize(&width
, &height
);
2416 return makepoint(width
, height
);
2420 stdwin_getscrmm(self
, args
)
2425 if (!getnoarg(args
))
2427 wgetscrmm(&width
, &height
);
2428 return makepoint(width
, height
);
2433 stdwin_connectionnumber(self
, args
)
2437 if (!getnoarg(args
))
2439 return newintobject((long) wconnectionnumber());
2444 stdwin_listfontnames(self
, args
)
2452 if (!getargs(args
, "z", &pattern
))
2454 fontnames
= wlistfontnames(pattern
, &count
);
2455 list
= newlistobject(count
);
2458 for (i
= 0; i
< count
; i
++) {
2459 object
*v
= newstringobject(fontnames
[i
]);
2465 setlistitem(list
, i
, v
);
2473 stdwin_newbitmap(self
, args
)
2479 if (!getargs(args
, "(ii)", &width
, &height
))
2481 return (object
*)newbitmapobject(width
, height
);
2485 static struct methodlist stdwin_methods
[] = {
2486 {"askfile", stdwin_askfile
},
2487 {"askstr", stdwin_askstr
},
2488 {"askync", stdwin_askync
},
2489 {"done", stdwin_done
},
2490 {"fetchcolor", stdwin_fetchcolor
},
2492 {"fileno", stdwin_connectionnumber
},
2493 {"connectionnumber", stdwin_connectionnumber
},
2495 {"fleep", stdwin_fleep
},
2496 {"getactive", stdwin_getactive
},
2497 {"getcutbuffer", stdwin_getcutbuffer
},
2498 {"getdefscrollbars", stdwin_getdefscrollbars
},
2499 {"getdefwinpos", stdwin_getdefwinpos
},
2500 {"getdefwinsize", stdwin_getdefwinsize
},
2501 {"getevent", stdwin_getevent
},
2502 {"getscrmm", stdwin_getscrmm
},
2503 {"getscrsize", stdwin_getscrsize
},
2504 {"getselection", stdwin_getselection
},
2505 {"listfontnames", stdwin_listfontnames
},
2506 {"menucreate", stdwin_menucreate
},
2507 {"message", stdwin_message
},
2509 {"newbitmap", stdwin_newbitmap
},
2511 {"open", stdwin_open
},
2512 {"pollevent", stdwin_pollevent
},
2513 {"resetselection", stdwin_resetselection
},
2514 {"rotatecutbuffers", stdwin_rotatecutbuffers
},
2515 {"setcutbuffer", stdwin_setcutbuffer
},
2516 {"setdefscrollbars", stdwin_setdefscrollbars
},
2517 {"setdefwinpos", stdwin_setdefwinpos
},
2518 {"setdefwinsize", stdwin_setdefwinsize
},
2520 /* Text measuring methods borrow code from drawing objects: */
2521 {"baseline", (method
)drawing_baseline
},
2522 {"lineheight", (method
)drawing_lineheight
},
2523 {"textbreak", (method
)drawing_textbreak
},
2524 {"textwidth", (method
)drawing_textwidth
},
2526 /* Same for font setting methods: */
2527 {"setfont", (method
)drawing_setfont
},
2529 /* Same for color setting/getting methods: */
2530 {"getbgcolor", (method
)drawing_getbgcolor
},
2531 {"getfgcolor", (method
)drawing_getfgcolor
},
2532 {"setbgcolor", (method
)drawing_setbgcolor
},
2533 {"setfgcolor", (method
)drawing_setfgcolor
},
2535 {NULL
, NULL
} /* sentinel */
2540 checkstringlist(args
, ps
, pn
)
2547 if (!is_listobject(args
)) {
2548 err_setstr(TypeError
, "list of strings expected");
2551 n
= getlistsize(args
);
2552 s
= NEW(char *, n
+1);
2557 for (i
= 0; i
< n
; i
++) {
2558 object
*item
= getlistitem(args
, i
);
2559 if (!is_stringobject(item
)) {
2560 err_setstr(TypeError
, "list of strings expected");
2563 s
[i
] = getstringvalue(item
);
2565 s
[n
] = NULL
; /* In case caller wants a NULL-terminated list */
2572 putbackstringlist(list
, s
, n
)
2577 int oldsize
= getlistsize(list
);
2582 newlist
= newlistobject(n
);
2583 for (i
= 0; i
< n
&& newlist
!= NULL
; i
++) {
2584 object
*item
= newstringobject(s
[i
]);
2590 setlistitem(newlist
, i
, item
);
2592 if (newlist
== NULL
)
2594 (*list
->ob_type
->tp_as_sequence
->sq_ass_slice
)
2595 (list
, 0, oldsize
, newlist
);
2599 #endif /* macintosh */
2605 static int inited
= 0;
2610 PyMac_DoYieldEnabled
= 0;
2615 object
*sys_argv
= sysget("argv");
2616 if (sys_argv
!= NULL
) {
2617 if (!checkstringlist(sys_argv
, &argv
, &argc
))
2621 /* If argv[0] has a ".py" suffix, remove the suffix */
2622 char *p
= strrchr(argv
[0], '.');
2623 if (p
!= NULL
&& strcmp(p
, ".py") == 0) {
2624 int n
= p
- argv
[0];
2625 if (n
>= sizeof(buf
))
2627 strncpy(buf
, argv
[0], n
);
2632 winitargs(&argc
, &argv
);
2634 if (!putbackstringlist(sys_argv
, argv
, argc
))
2640 m
= initmodule("stdwin", stdwin_methods
);
2641 d
= getmoduledict(m
);
2643 /* Initialize stdwin.error exception */
2644 StdwinError
= newstringobject("stdwin.error");
2645 if (StdwinError
== NULL
|| dictinsert(d
, "error", StdwinError
) != 0)
2646 fatal("can't define stdwin.error");
2648 StdwinLock
= allocate_lock();
2649 if (StdwinLock
== NULL
)
2650 fatal("can't allocate stdwin lock");