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"
75 #include ":::stdwin:H:stdwin.h"
76 #else /* !macintosh */
79 #endif /* !macintosh */
85 static type_lock StdwinLock
; /* Lock held when interpreter not locked */
87 #define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
88 #define RET_STDWIN release_lock(StdwinLock); RET_SAVE
89 #define END_STDWIN release_lock(StdwinLock); END_SAVE
93 #define BGN_STDWIN BGN_SAVE
94 #define RET_STDWIN RET_SAVE
95 #define END_STDWIN END_SAVE
99 #define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
100 #define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
101 a, a+1, a+2, a+3, a+4, a+5)
102 #define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
103 #define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
104 #define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
105 #define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
106 a, a+1, a+2, a+3, a+4, a+5)
108 static object
*StdwinError
; /* Exception stdwin.error */
110 /* Window and menu object types declared here because of forward references */
116 object
*w_attr
; /* Attributes dictionary */
119 staticforward typeobject Windowtype
;
121 #define is_windowobject(wp) ((wp)->ob_type == &Windowtype)
127 object
*m_attr
; /* Attributes dictionary */
130 staticforward typeobject Menutype
;
132 #define is_menuobject(mp) ((mp)->ob_type == &Menutype)
137 object
*b_attr
; /* Attributes dictionary */
140 staticforward typeobject Bitmaptype
;
142 #define is_bitmapobject(mp) ((mp)->ob_type == &Bitmaptype)
145 /* Strongly stdwin-specific argument handlers */
153 if (!getargs(v
, "(Oi)", &mp
, &ep
->u
.m
.item
))
155 if (!is_menuobject(mp
))
157 ep
->u
.m
.id
= mp
->m_id
;
168 if (!getargs(v
, "(iOO)", &ep
->type
, &wp
, &detail
))
170 if (is_windowobject(wp
))
171 ep
->window
= ((windowobject
*)wp
) -> w_win
;
179 if (!getargs(detail
, "c", &c
))
185 return getintarg(detail
, &ep
->u
.command
);
187 if (!getrectarg(detail
, a
))
189 ep
->u
.area
.left
= a
[0];
190 ep
->u
.area
.top
= a
[1];
191 ep
->u
.area
.right
= a
[2];
192 ep
->u
.area
.bottom
= a
[3];
197 return getargs(detail
, "((ii)iii)",
198 &ep
->u
.where
.h
, &ep
->u
.where
.v
,
203 return getmenudetail(detail
, ep
);
205 return getargs(detail
, "(ii)",
206 &ep
->u
.key
.code
, &ep
->u
.key
.mask
);
213 /* Return construction tools */
219 return mkvalue("(ii)", a
, b
);
226 return mkvalue("((ii)(ii))", a
, b
, c
, d
);
230 /* Drawing objects */
237 static drawingobject
*Drawing
; /* Set to current drawing object, or NULL */
239 /* Drawing methods */
245 if (dp
->d_ref
!= NULL
) {
246 wenddrawing(dp
->d_ref
->w_win
);
259 if (dp
->d_ref
!= NULL
) {
260 wenddrawing(dp
->d_ref
->w_win
);
269 drawing_generic(dp
, args
, func
)
272 void (*func
) FPROTO((int, int, int, int));
275 if (!getrectarg(args
, a
))
277 (*func
)(a
[0], a
[1], a
[2], a
[3]);
283 drawing_line(dp
, args
)
287 return drawing_generic(dp
, args
, wdrawline
);
291 drawing_xorline(dp
, args
)
295 return drawing_generic(dp
, args
, wxorline
);
299 drawing_circle(dp
, args
)
304 if (!getpointintarg(args
, a
))
306 wdrawcircle(a
[0], a
[1], a
[2]);
312 drawing_fillcircle(dp
, args
)
317 if (!getpointintarg(args
, a
))
319 wfillcircle(a
[0], a
[1], a
[2]);
325 drawing_xorcircle(dp
, args
)
330 if (!getpointintarg(args
, a
))
332 wxorcircle(a
[0], a
[1], a
[2]);
338 drawing_elarc(dp
, args
)
343 if (!get3pointarg(args
, a
))
345 wdrawelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
351 drawing_fillelarc(dp
, args
)
356 if (!get3pointarg(args
, a
))
358 wfillelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
364 drawing_xorelarc(dp
, args
)
369 if (!get3pointarg(args
, a
))
371 wxorelarc(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
377 drawing_box(dp
, args
)
381 return drawing_generic(dp
, args
, wdrawbox
);
385 drawing_erase(dp
, args
)
389 return drawing_generic(dp
, args
, werase
);
393 drawing_paint(dp
, args
)
397 return drawing_generic(dp
, args
, wpaint
);
401 drawing_invert(dp
, args
)
405 return drawing_generic(dp
, args
, winvert
);
409 getpointsarray(v
, psize
)
414 object
* (*getitem
) PROTO((object
*, int));
420 else if (is_listobject(v
)) {
422 getitem
= getlistitem
;
424 else if (is_tupleobject(v
)) {
426 getitem
= gettupleitem
;
434 points
= NEW(POINT
, n
);
435 if (points
== NULL
) {
440 for (i
= 0; i
< n
; i
++) {
441 object
*w
= (*getitem
)(v
, i
);
443 if (!getpointarg(w
, a
)) {
456 drawing_poly(dp
, args
)
461 POINT
*points
= getpointsarray(args
, &n
);
464 wdrawpoly(n
, points
);
471 drawing_fillpoly(dp
, args
)
476 POINT
*points
= getpointsarray(args
, &n
);
479 wfillpoly(n
, points
);
486 drawing_xorpoly(dp
, args
)
491 POINT
*points
= getpointsarray(args
, &n
);
501 drawing_cliprect(dp
, args
)
505 return drawing_generic(dp
, args
, wcliprect
);
509 drawing_noclip(dp
, args
)
521 drawing_shade(dp
, args
)
526 if (!getrectintarg(args
, a
))
528 wshade(a
[0], a
[1], a
[2], a
[3], a
[4]);
534 drawing_text(dp
, args
)
540 if (!getargs(args
, "((ii)s#)", &h
, &v
, &text
, &size
))
542 wdrawtext(h
, v
, text
, size
);
547 /* The following four are also used as stdwin functions */
550 drawing_lineheight(dp
, args
)
556 return newintobject((long)wlineheight());
560 drawing_baseline(dp
, args
)
566 return newintobject((long)wbaseline());
570 drawing_textwidth(dp
, args
)
576 if (!getargs(args
, "s#", &text
, &size
))
578 return newintobject((long)wtextwidth(text
, size
));
582 drawing_textbreak(dp
, args
)
588 if (!getargs(args
, "(s#i)", &text
, &size
, &width
))
590 return newintobject((long)wtextbreak(text
, size
, width
));
594 drawing_setfont(self
, args
)
601 if (args
== NULL
|| !is_tupleobject(args
)) {
602 if (!getargs(args
, "z", &font
))
606 int n
= gettuplesize(args
);
608 if (!getargs(args
, "(zi)", &font
, &size
))
611 else if (!getargs(args
, "(zic)", &font
, &size
, &style
)) {
613 if (!getargs(args
, "(zci)", &font
, &style
, &size
))
618 if (!wsetfont(font
)) {
619 err_setstr(StdwinError
, "font not found");
647 drawing_getbgcolor(self
, args
)
653 return newintobject((long)wgetbgcolor());
657 drawing_getfgcolor(self
, args
)
663 return newintobject((long)wgetfgcolor());
667 drawing_setbgcolor(self
, args
)
672 if (!getlongarg(args
, &color
))
674 wsetbgcolor((COLOR
)color
);
680 drawing_setfgcolor(self
, args
)
685 if (!getlongarg(args
, &color
))
687 wsetfgcolor((COLOR
)color
);
695 drawing_bitmap(self
, args
)
702 if (!getargs(args
, "((ii)O)", &h
, &v
, &bp
)) {
704 if (!getargs(args
, "((ii)OO)", &h
, &v
, &bp
, &mask
))
708 else if (!is_bitmapobject(mask
)) {
713 if (!is_bitmapobject(bp
)) {
717 if (((bitmapobject
*)bp
)->b_bitmap
== NULL
||
718 mask
!= NULL
&& ((bitmapobject
*)mask
)->b_bitmap
== NULL
) {
719 err_setstr(StdwinError
, "bitmap object already close");
723 wdrawbitmap(h
, v
, ((bitmapobject
*)bp
)->b_bitmap
, ALLBITS
);
726 ((bitmapobject
*)bp
)->b_bitmap
,
727 ((bitmapobject
*)bp
)->b_bitmap
);
732 #endif /* HAVE_BITMAPS */
734 static struct methodlist drawing_methods
[] = {
736 {"bitmap", (method
)drawing_bitmap
},
738 {"box", (method
)drawing_box
},
739 {"circle", (method
)drawing_circle
},
740 {"cliprect", (method
)drawing_cliprect
},
741 {"close", (method
)drawing_close
},
742 {"elarc", (method
)drawing_elarc
},
743 {"enddrawing", (method
)drawing_close
},
744 {"erase", (method
)drawing_erase
},
745 {"fillcircle", (method
)drawing_fillcircle
},
746 {"fillelarc", (method
)drawing_fillelarc
},
747 {"fillpoly", (method
)drawing_fillpoly
},
748 {"invert", (method
)drawing_invert
},
749 {"line", (method
)drawing_line
},
750 {"noclip", (method
)drawing_noclip
},
751 {"paint", (method
)drawing_paint
},
752 {"poly", (method
)drawing_poly
},
753 {"shade", (method
)drawing_shade
},
754 {"text", (method
)drawing_text
},
755 {"xorcircle", (method
)drawing_xorcircle
},
756 {"xorelarc", (method
)drawing_xorelarc
},
757 {"xorline", (method
)drawing_xorline
},
758 {"xorpoly", (method
)drawing_xorpoly
},
760 /* Text measuring methods: */
761 {"baseline", (method
)drawing_baseline
},
762 {"lineheight", (method
)drawing_lineheight
},
763 {"textbreak", (method
)drawing_textbreak
},
764 {"textwidth", (method
)drawing_textwidth
},
766 /* Font setting methods: */
767 {"setfont", (method
)drawing_setfont
},
770 {"getbgcolor", (method
)drawing_getbgcolor
},
771 {"getfgcolor", (method
)drawing_getfgcolor
},
772 {"setbgcolor", (method
)drawing_setbgcolor
},
773 {"setfgcolor", (method
)drawing_setfgcolor
},
775 {NULL
, NULL
} /* sentinel */
779 drawing_getattr(dp
, name
)
783 if (dp
->d_ref
== NULL
) {
784 err_setstr(StdwinError
, "drawing object already closed");
787 return findmethod(drawing_methods
, (object
*)dp
, name
);
790 typeobject Drawingtype
= {
791 OB_HEAD_INIT(&Typetype
)
793 "drawing", /*tp_name*/
794 sizeof(drawingobject
), /*tp_size*/
797 (destructor
)drawing_dealloc
, /*tp_dealloc*/
799 (getattrfunc
)drawing_getattr
, /*tp_getattr*/
806 /* Text(edit) objects */
812 object
*t_attr
; /* Attributes dictionary */
815 staticforward typeobject Texttype
;
818 newtextobject(wp
, left
, top
, right
, bottom
)
820 int left
, top
, right
, bottom
;
823 tp
= NEWOBJ(textobject
, &Texttype
);
829 tp
->t_text
= tecreate(wp
->w_win
, left
, top
, right
, bottom
);
830 if (tp
->t_text
== NULL
) {
832 return (textobject
*) err_nomem();
837 /* Text(edit) methods */
843 if (tp
->t_text
!= NULL
)
855 if (tp
->t_text
!= NULL
) {
859 if (tp
->t_attr
!= NULL
) {
863 if (tp
->t_ref
!= NULL
) {
872 text_arrow(self
, args
)
877 if (!getintarg(args
, &code
))
879 tearrow(self
->t_text
, code
);
885 text_draw(self
, args
)
889 register TEXTEDIT
*tp
= self
->t_text
;
891 int left
, top
, right
, bottom
;
892 if (!getrectarg(args
, a
))
894 if (Drawing
!= NULL
) {
895 err_setstr(StdwinError
, "already drawing");
898 /* Clip to text area and ignore if area is empty */
899 left
= tegetleft(tp
);
901 right
= tegetright(tp
);
902 bottom
= tegetbottom(tp
);
903 if (a
[0] < left
) a
[0] = left
;
904 if (a
[1] < top
) a
[1] = top
;
905 if (a
[2] > right
) a
[2] = right
;
906 if (a
[3] > bottom
) a
[3] = bottom
;
907 if (a
[0] < a
[2] && a
[1] < a
[3]) {
908 wbegindrawing(self
->t_ref
->w_win
);
909 tedrawnew(tp
, a
[0], a
[1], a
[2], a
[3]);
910 wenddrawing(self
->t_ref
->w_win
);
917 text_event(self
, args
)
921 register TEXTEDIT
*tp
= self
->t_text
;
923 if (!geteventarg(args
, &e
))
925 if (e
.type
== WE_MOUSE_DOWN
) {
926 /* Cheat at the margins */
928 wgetdocsize(e
.window
, &width
, &height
);
929 if (e
.u
.where
.h
< 0 && tegetleft(tp
) == 0)
931 else if (e
.u
.where
.h
> width
&& tegetright(tp
) == width
)
933 if (e
.u
.where
.v
< 0 && tegettop(tp
) == 0)
935 else if (e
.u
.where
.v
> height
&& tegetright(tp
) == height
)
936 e
.u
.where
.v
= height
;
938 return newintobject((long) teevent(tp
, &e
));
942 text_getfocus(self
, args
)
948 return makepoint(tegetfoc1(self
->t_text
), tegetfoc2(self
->t_text
));
952 text_getfocustext(self
, args
)
960 f1
= tegetfoc1(self
->t_text
);
961 f2
= tegetfoc2(self
->t_text
);
962 text
= tegettext(self
->t_text
);
963 return newsizedstringobject(text
+ f1
, f2
-f1
);
967 text_getrect(self
, args
)
973 return makerect(tegetleft(self
->t_text
),
974 tegettop(self
->t_text
),
975 tegetright(self
->t_text
),
976 tegetbottom(self
->t_text
));
980 text_gettext(self
, args
)
986 return newsizedstringobject(tegettext(self
->t_text
),
987 tegetlen(self
->t_text
));
991 text_move(self
, args
)
996 if (!getrectarg(args
, a
))
998 temovenew(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1004 text_replace(self
, args
)
1009 if (!getstrarg(args
, &text
))
1011 tereplace(self
->t_text
, text
);
1017 text_setactive(self
, args
)
1022 if (!getintarg(args
, &flag
))
1024 tesetactive(self
->t_text
, flag
);
1030 text_setfocus(self
, args
)
1035 if (!getpointarg(args
, a
))
1037 tesetfocus(self
->t_text
, a
[0], a
[1]);
1043 text_settext(self
, args
)
1050 if (!getargs(args
, "s#", &text
, &size
))
1052 if ((buf
= NEW(char, size
)) == NULL
) {
1055 memcpy(buf
, text
, size
);
1056 tesetbuf(self
->t_text
, buf
, size
); /* Becomes owner of buffer */
1062 text_setview(self
, args
)
1068 tenoview(self
->t_text
);
1070 if (!getrectarg(args
, a
))
1072 tesetview(self
->t_text
, a
[0], a
[1], a
[2], a
[3]);
1078 static struct methodlist text_methods
[] = {
1079 {"arrow", (method
)text_arrow
},
1080 {"close", (method
)text_close
},
1081 {"draw", (method
)text_draw
},
1082 {"event", (method
)text_event
},
1083 {"getfocus", (method
)text_getfocus
},
1084 {"getfocustext",(method
)text_getfocustext
},
1085 {"getrect", (method
)text_getrect
},
1086 {"gettext", (method
)text_gettext
},
1087 {"move", (method
)text_move
},
1088 {"replace", (method
)text_replace
},
1089 {"setactive", (method
)text_setactive
},
1090 {"setfocus", (method
)text_setfocus
},
1091 {"settext", (method
)text_settext
},
1092 {"setview", (method
)text_setview
},
1093 {NULL
, NULL
} /* sentinel */
1097 text_getattr(tp
, name
)
1102 if (tp
->t_ref
== NULL
) {
1103 err_setstr(StdwinError
, "text object already closed");
1106 if (strcmp(name
, "__dict__") == 0) {
1111 else if (tp
->t_attr
!= NULL
) {
1112 v
= dictlookup(tp
->t_attr
, name
);
1118 return findmethod(text_methods
, (object
*)tp
, name
);
1122 text_setattr(tp
, name
, v
)
1127 if (tp
->t_attr
== NULL
) {
1128 tp
->t_attr
= newdictobject();
1129 if (tp
->t_attr
== NULL
)
1133 int rv
= dictremove(tp
->t_attr
, name
);
1135 err_setstr(AttributeError
,
1136 "delete non-existing text object attribute");
1140 return dictinsert(tp
->t_attr
, name
, v
);
1143 statichere typeobject Texttype
= {
1144 OB_HEAD_INIT(&Typetype
)
1146 "textedit", /*tp_name*/
1147 sizeof(textobject
), /*tp_size*/
1150 (destructor
)text_dealloc
, /*tp_dealloc*/
1152 (getattrfunc
)text_getattr
, /*tp_getattr*/
1153 (setattrfunc
)text_setattr
, /*tp_setattr*/
1161 #define IDOFFSET 10 /* Menu IDs we use start here */
1162 #define MAXNMENU 200 /* Max #menus we allow */
1163 static menuobject
*menulist
[MAXNMENU
];
1165 static menuobject
*newmenuobject
PROTO((char *));
1167 newmenuobject(title
)
1173 for (id
= 0; id
< MAXNMENU
; id
++) {
1174 if (menulist
[id
] == NULL
)
1177 if (id
>= MAXNMENU
) {
1178 err_setstr(StdwinError
, "creating too many menus");
1181 menu
= wmenucreate(id
+ IDOFFSET
, title
);
1183 return (menuobject
*) err_nomem();
1184 mp
= NEWOBJ(menuobject
, &Menutype
);
1187 mp
->m_id
= id
+ IDOFFSET
;
1203 int id
= mp
->m_id
- IDOFFSET
;
1204 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1205 menulist
[id
] = NULL
;
1207 if (mp
->m_menu
!= NULL
)
1208 wmenudelete(mp
->m_menu
);
1209 XDECREF(mp
->m_attr
);
1214 menu_close(mp
, args
)
1218 int id
= mp
->m_id
- IDOFFSET
;
1219 if (id
>= 0 && id
< MAXNMENU
&& menulist
[id
] == mp
) {
1220 menulist
[id
] = NULL
;
1223 if (mp
->m_menu
!= NULL
)
1224 wmenudelete(mp
->m_menu
);
1226 XDECREF(mp
->m_attr
);
1233 menu_additem(self
, args
)
1239 if (is_tupleobject(args
)) {
1241 if (!getargs(args
, "(sc)", &text
, &c
))
1245 else if (!getstrarg(args
, &text
))
1247 wmenuadditem(self
->m_menu
, text
, shortcut
);
1253 menu_setitem(self
, args
)
1259 if (!getargs(args
, "(is)", &index
, &text
))
1261 wmenusetitem(self
->m_menu
, index
, text
);
1267 menu_enable(self
, args
)
1273 if (!getargs(args
, "(ii)", &index
, &flag
))
1275 wmenuenable(self
->m_menu
, index
, flag
);
1281 menu_check(self
, args
)
1287 if (!getargs(args
, "(ii)", &index
, &flag
))
1289 wmenucheck(self
->m_menu
, index
, flag
);
1294 static struct methodlist menu_methods
[] = {
1295 {"additem", (method
)menu_additem
},
1296 {"setitem", (method
)menu_setitem
},
1297 {"enable", (method
)menu_enable
},
1298 {"check", (method
)menu_check
},
1299 {"close", (method
)menu_close
},
1300 {NULL
, NULL
} /* sentinel */
1304 menu_getattr(mp
, name
)
1309 if (mp
->m_menu
== NULL
) {
1310 err_setstr(StdwinError
, "menu object already closed");
1313 if (strcmp(name
, "__dict__") == 0) {
1318 else if (mp
->m_attr
!= NULL
) {
1319 v
= dictlookup(mp
->m_attr
, name
);
1325 return findmethod(menu_methods
, (object
*)mp
, name
);
1329 menu_setattr(mp
, name
, v
)
1334 if (mp
->m_attr
== NULL
) {
1335 mp
->m_attr
= newdictobject();
1336 if (mp
->m_attr
== NULL
)
1340 int rv
= dictremove(mp
->m_attr
, name
);
1342 err_setstr(AttributeError
,
1343 "delete non-existing menu object attribute");
1347 return dictinsert(mp
->m_attr
, name
, v
);
1350 statichere typeobject Menutype
= {
1351 OB_HEAD_INIT(&Typetype
)
1354 sizeof(menuobject
), /*tp_size*/
1357 (destructor
)menu_dealloc
, /*tp_dealloc*/
1359 (getattrfunc
)menu_getattr
, /*tp_getattr*/
1360 (setattrfunc
)menu_setattr
, /*tp_setattr*/
1368 /* Bitmaps objects */
1370 static bitmapobject
*newbitmapobject
PROTO((int, int));
1371 static bitmapobject
*
1372 newbitmapobject(width
, height
)
1377 bitmap
= wnewbitmap(width
, height
);
1379 return (bitmapobject
*) err_nomem();
1380 bp
= NEWOBJ(bitmapobject
, &Bitmaptype
);
1382 bp
->b_bitmap
= bitmap
;
1386 wfreebitmap(bitmap
);
1390 /* Bitmap methods */
1396 if (bp
->b_bitmap
!= NULL
)
1397 wfreebitmap(bp
->b_bitmap
);
1398 XDECREF(bp
->b_attr
);
1403 bitmap_close(bp
, args
)
1407 if (bp
->b_bitmap
!= NULL
)
1408 wfreebitmap(bp
->b_bitmap
);
1409 bp
->b_bitmap
= NULL
;
1410 XDECREF(bp
->b_attr
);
1417 bitmap_setbit(self
, args
)
1422 if (!getpointintarg(args
, a
))
1424 wsetbit(self
->b_bitmap
, a
[0], a
[1], a
[2]);
1430 bitmap_getbit(self
, args
)
1435 if (!getpointarg(args
, a
))
1437 return newintobject((long) wgetbit(self
->b_bitmap
, a
[0], a
[1]));
1441 bitmap_getsize(self
, args
)
1446 if (!getnoarg(args
))
1448 wgetbitmapsize(self
->b_bitmap
, &width
, &height
);
1449 return mkvalue("(ii)", width
, height
);
1452 static struct methodlist bitmap_methods
[] = {
1453 {"close", (method
)bitmap_close
},
1454 {"getsize", (method
)bitmap_getsize
},
1455 {"getbit", (method
)bitmap_getbit
},
1456 {"setbit", (method
)bitmap_setbit
},
1457 {NULL
, NULL
} /* sentinel */
1461 bitmap_getattr(bp
, name
)
1466 if (bp
->b_bitmap
== NULL
) {
1467 err_setstr(StdwinError
, "bitmap object already closed");
1470 if (strcmp(name
, "__dict__") == 0) {
1475 else if (bp
->b_attr
!= NULL
) {
1476 v
= dictlookup(bp
->b_attr
, name
);
1482 return findmethod(bitmap_methods
, (object
*)bp
, name
);
1486 bitmap_setattr(bp
, name
, v
)
1491 if (bp
->b_attr
== NULL
) {
1492 bp
->b_attr
= newdictobject();
1493 if (bp
->b_attr
== NULL
)
1497 int rv
= dictremove(bp
->b_attr
, name
);
1499 err_setstr(AttributeError
,
1500 "delete non-existing bitmap object attribute");
1504 return dictinsert(bp
->b_attr
, name
, v
);
1507 statichere typeobject Bitmaptype
= {
1508 OB_HEAD_INIT(&Typetype
)
1510 "bitmap", /*tp_name*/
1511 sizeof(bitmapobject
), /*tp_size*/
1514 (destructor
)bitmap_dealloc
, /*tp_dealloc*/
1516 (getattrfunc
)bitmap_getattr
, /*tp_getattr*/
1517 (setattrfunc
)bitmap_setattr
, /*tp_setattr*/
1522 #endif /* HAVE_BITMAPS */
1528 static windowobject
*windowlist
[MAXNWIN
];
1530 /* Window methods */
1536 if (wp
->w_win
!= NULL
) {
1537 int tag
= wgettag(wp
->w_win
);
1538 if (tag
>= 0 && tag
< MAXNWIN
)
1539 windowlist
[tag
] = NULL
;
1541 fprintf(stderr
, "XXX help! tag %d in window_dealloc\n",
1545 DECREF(wp
->w_title
);
1546 if (wp
->w_attr
!= NULL
)
1552 window_close(wp
, args
)
1556 if (wp
->w_win
!= NULL
) {
1557 int tag
= wgettag(wp
->w_win
);
1558 if (tag
>= 0 && tag
< MAXNWIN
)
1559 windowlist
[tag
] = NULL
;
1568 window_begindrawing(wp
, args
)
1573 if (!getnoarg(args
))
1575 if (Drawing
!= NULL
) {
1576 err_setstr(StdwinError
, "already drawing");
1579 dp
= NEWOBJ(drawingobject
, &Drawingtype
);
1585 wbegindrawing(wp
->w_win
);
1586 return (object
*)dp
;
1590 window_change(wp
, args
)
1595 if (!getrectarg(args
, a
))
1597 wchange(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1603 window_gettitle(wp
, args
)
1607 if (!getnoarg(args
))
1609 INCREF(wp
->w_title
);
1614 window_getwinpos(wp
, args
)
1619 if (!getnoarg(args
))
1621 wgetwinpos(wp
->w_win
, &h
, &v
);
1622 return makepoint(h
, v
);
1626 window_getwinsize(wp
, args
)
1631 if (!getnoarg(args
))
1633 wgetwinsize(wp
->w_win
, &width
, &height
);
1634 return makepoint(width
, height
);
1638 window_setwinpos(wp
, args
)
1643 if (!getpointarg(args
, a
))
1645 wsetwinpos(wp
->w_win
, a
[0], a
[1]);
1651 window_setwinsize(wp
, args
)
1656 if (!getpointarg(args
, a
))
1658 wsetwinsize(wp
->w_win
, a
[0], a
[1]);
1664 window_getdocsize(wp
, args
)
1669 if (!getnoarg(args
))
1671 wgetdocsize(wp
->w_win
, &width
, &height
);
1672 return makepoint(width
, height
);
1676 window_getorigin(wp
, args
)
1681 if (!getnoarg(args
))
1683 wgetorigin(wp
->w_win
, &width
, &height
);
1684 return makepoint(width
, height
);
1688 window_scroll(wp
, args
)
1693 if (!getrectpointarg(args
, a
))
1695 wscroll(wp
->w_win
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
1701 window_setdocsize(wp
, args
)
1706 if (!getpointarg(args
, a
))
1708 wsetdocsize(wp
->w_win
, a
[0], a
[1]);
1714 window_setorigin(wp
, args
)
1719 if (!getpointarg(args
, a
))
1721 wsetorigin(wp
->w_win
, a
[0], a
[1]);
1727 window_settitle(wp
, args
)
1732 if (!getargs(args
, "S", &title
))
1734 DECREF(wp
->w_title
);
1736 wp
->w_title
= title
;
1737 wsettitle(wp
->w_win
, getstringvalue(title
));
1743 window_show(wp
, args
)
1748 if (!getrectarg(args
, a
))
1750 wshow(wp
->w_win
, a
[0], a
[1], a
[2], a
[3]);
1756 window_settimer(wp
, args
)
1761 if (!getintarg(args
, &a
))
1763 wsettimer(wp
->w_win
, a
);
1769 window_menucreate(self
, args
)
1775 if (!getstrarg(args
, &title
))
1777 wmenusetdeflocal(1);
1778 mp
= newmenuobject(title
);
1781 wmenuattach(self
->w_win
, mp
->m_menu
);
1782 return (object
*)mp
;
1786 window_textcreate(self
, args
)
1791 if (!getrectarg(args
, a
))
1794 newtextobject(self
, a
[0], a
[1], a
[2], a
[3]);
1798 window_setselection(self
, args
)
1804 if (!getargs(args
, "(is#)", &sel
, &text
, &size
))
1806 ok
= wsetselection(self
->w_win
, sel
, text
, size
);
1807 return newintobject(ok
);
1811 window_setwincursor(self
, args
)
1817 if (!getargs(args
, "z", &name
))
1822 c
= wfetchcursor(name
);
1824 err_setstr(StdwinError
, "no such cursor");
1828 wsetwincursor(self
->w_win
, c
);
1834 window_setactive(self
, args
)
1838 if (!getnoarg(args
))
1840 wsetactive(self
->w_win
);
1847 window_getxwindowid(self
, args
)
1851 long wid
= wgetxwindowid(self
->w_win
);
1852 return newintobject(wid
);
1856 static struct methodlist window_methods
[] = {
1857 {"begindrawing",(method
)window_begindrawing
},
1858 {"change", (method
)window_change
},
1859 {"close", (method
)window_close
},
1860 {"getdocsize", (method
)window_getdocsize
},
1861 {"getorigin", (method
)window_getorigin
},
1862 {"gettitle", (method
)window_gettitle
},
1863 {"getwinpos", (method
)window_getwinpos
},
1864 {"getwinsize", (method
)window_getwinsize
},
1865 {"menucreate", (method
)window_menucreate
},
1866 {"scroll", (method
)window_scroll
},
1867 {"setactive", (method
)window_setactive
},
1868 {"setdocsize", (method
)window_setdocsize
},
1869 {"setorigin", (method
)window_setorigin
},
1870 {"setselection",(method
)window_setselection
},
1871 {"settimer", (method
)window_settimer
},
1872 {"settitle", (method
)window_settitle
},
1873 {"setwincursor",(method
)window_setwincursor
},
1874 {"setwinpos", (method
)window_setwinpos
},
1875 {"setwinsize", (method
)window_setwinsize
},
1876 {"show", (method
)window_show
},
1877 {"textcreate", (method
)window_textcreate
},
1879 {"getxwindowid",(method
)window_getxwindowid
},
1881 {NULL
, NULL
} /* sentinel */
1885 window_getattr(wp
, name
)
1890 if (wp
->w_win
== NULL
) {
1891 err_setstr(StdwinError
, "window already closed");
1894 if (strcmp(name
, "__dict__") == 0) {
1899 else if (wp
->w_attr
!= NULL
) {
1900 v
= dictlookup(wp
->w_attr
, name
);
1906 return findmethod(window_methods
, (object
*)wp
, name
);
1910 window_setattr(wp
, name
, v
)
1915 if (wp
->w_attr
== NULL
) {
1916 wp
->w_attr
= newdictobject();
1917 if (wp
->w_attr
== NULL
)
1921 int rv
= dictremove(wp
->w_attr
, name
);
1923 err_setstr(AttributeError
,
1924 "delete non-existing menu object attribute");
1928 return dictinsert(wp
->w_attr
, name
, v
);
1931 statichere typeobject Windowtype
= {
1932 OB_HEAD_INIT(&Typetype
)
1934 "window", /*tp_name*/
1935 sizeof(windowobject
), /*tp_size*/
1938 (destructor
)window_dealloc
, /*tp_dealloc*/
1940 (getattrfunc
)window_getattr
, /*tp_getattr*/
1941 (setattrfunc
)window_setattr
, /*tp_setattr*/
1946 /* Stdwin methods */
1949 stdwin_done(sw
, args
)
1953 if (!getnoarg(args
))
1956 /* XXX There is no protection against continued use of
1957 XXX stdwin functions or objects after this call is made.
1958 XXX Use at own risk */
1964 stdwin_open(sw
, args
)
1971 if (!getargs(args
, "S", &title
))
1973 for (tag
= 0; tag
< MAXNWIN
; tag
++) {
1974 if (windowlist
[tag
] == NULL
)
1977 if (tag
>= MAXNWIN
) {
1978 err_setstr(StdwinError
, "creating too many windows");
1981 wp
= NEWOBJ(windowobject
, &Windowtype
);
1985 wp
->w_title
= title
;
1986 wp
->w_win
= wopen(getstringvalue(title
), (void (*)()) NULL
);
1988 if (wp
->w_win
== NULL
) {
1992 windowlist
[tag
] = wp
;
1993 wsettag(wp
->w_win
, tag
);
1994 return (object
*)wp
;
2005 int tag
= wgettag(win
);
2006 if (tag
< 0 || tag
>= MAXNWIN
|| windowlist
[tag
] == NULL
||
2007 windowlist
[tag
]->w_win
!= win
)
2010 w
= (object
*)windowlist
[tag
];
2017 stdwin_get_poll_event(poll
, args
)
2023 if (!getnoarg(args
))
2025 if (Drawing
!= NULL
) {
2026 err_setstr(StdwinError
, "cannot getevent() while drawing");
2032 if (!wpollevent(&e
)) {
2041 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CANCEL
) {
2042 /* Turn keyboard interrupts into exceptions */
2043 err_set(KeyboardInterrupt
);
2046 if (e
.type
== WE_COMMAND
&& e
.u
.command
== WC_CLOSE
) {
2047 /* Turn WC_CLOSE commands into WE_CLOSE events */
2050 v
= window2object(e
.window
);
2055 c
[0] = e
.u
.character
;
2056 w
= newsizedstringobject(c
, 1);
2060 w
= newintobject((long)e
.u
.command
);
2063 w
= makerect(e
.u
.area
.left
, e
.u
.area
.top
,
2064 e
.u
.area
.right
, e
.u
.area
.bottom
);
2069 w
= mkvalue("((ii)iii)",
2070 e
.u
.where
.h
, e
.u
.where
.v
,
2076 if (e
.u
.m
.id
>= IDOFFSET
&& e
.u
.m
.id
< IDOFFSET
+MAXNMENU
&&
2077 menulist
[e
.u
.m
.id
- IDOFFSET
] != NULL
)
2079 menulist
[e
.u
.m
.id
- IDOFFSET
], e
.u
.m
.item
);
2081 /* Ghost menu event.
2082 Can occur only on the Mac if another part
2083 of the aplication has installed a menu;
2084 like the THINK C console library. */
2090 w
= mkvalue("(ii)", e
.u
.key
.code
, e
.u
.key
.mask
);
2093 w
= newintobject((long)e
.u
.sel
);
2104 u
= mkvalue("(iOO)", e
.type
, v
, w
);
2111 stdwin_getevent(sw
, args
)
2115 return stdwin_get_poll_event(0, args
);
2119 stdwin_pollevent(sw
, args
)
2123 return stdwin_get_poll_event(1, args
);
2127 stdwin_setdefwinpos(sw
, args
)
2132 if (!getpointarg(args
, a
))
2134 wsetdefwinpos(a
[0], a
[1]);
2140 stdwin_setdefwinsize(sw
, args
)
2145 if (!getpointarg(args
, a
))
2147 wsetdefwinsize(a
[0], a
[1]);
2153 stdwin_setdefscrollbars(sw
, args
)
2158 if (!getpointarg(args
, a
))
2160 wsetdefscrollbars(a
[0], a
[1]);
2166 stdwin_getdefwinpos(self
, args
)
2171 if (!getnoarg(args
))
2173 wgetdefwinpos(&h
, &v
);
2174 return makepoint(h
, v
);
2178 stdwin_getdefwinsize(self
, args
)
2183 if (!getnoarg(args
))
2185 wgetdefwinsize(&width
, &height
);
2186 return makepoint(width
, height
);
2190 stdwin_getdefscrollbars(self
, args
)
2195 if (!getnoarg(args
))
2197 wgetdefscrollbars(&h
, &v
);
2198 return makepoint(h
, v
);
2202 stdwin_menucreate(self
, args
)
2207 if (!getstrarg(args
, &title
))
2209 wmenusetdeflocal(0);
2210 return (object
*)newmenuobject(title
);
2214 stdwin_askfile(self
, args
)
2218 char *prompt
, *dflt
;
2221 if (!getargs(args
, "(ssi)", &prompt
, &dflt
, &new))
2223 strncpy(buf
, dflt
, sizeof buf
);
2224 buf
[sizeof buf
- 1] = '\0';
2226 ret
= waskfile(prompt
, buf
, sizeof buf
, new);
2229 err_set(KeyboardInterrupt
);
2232 return newstringobject(buf
);
2236 stdwin_askync(self
, args
)
2242 if (!getargs(args
, "(si)", &prompt
, &new))
2245 ret
= waskync(prompt
, new);
2248 err_set(KeyboardInterrupt
);
2251 return newintobject((long)ret
);
2255 stdwin_askstr(self
, args
)
2259 char *prompt
, *dflt
;
2262 if (!getargs(args
, "(ss)", &prompt
, &dflt
))
2264 strncpy(buf
, dflt
, sizeof buf
);
2265 buf
[sizeof buf
- 1] = '\0';
2267 ret
= waskstr(prompt
, buf
, sizeof buf
);
2270 err_set(KeyboardInterrupt
);
2273 return newstringobject(buf
);
2277 stdwin_message(self
, args
)
2282 if (!getstrarg(args
, &msg
))
2292 stdwin_fleep(self
, args
)
2296 if (!getnoarg(args
))
2304 stdwin_setcutbuffer(self
, args
)
2310 if (!getargs(args
, "(is#)", &i
, &str
, &size
))
2312 wsetcutbuffer(i
, str
, size
);
2318 stdwin_getactive(self
, args
)
2322 return window2object(wgetactive());
2326 stdwin_getcutbuffer(self
, args
)
2333 if (!getintarg(args
, &i
))
2335 str
= wgetcutbuffer(i
, &len
);
2340 return newsizedstringobject(str
, len
);
2344 stdwin_rotatecutbuffers(self
, args
)
2349 if (!getintarg(args
, &i
))
2351 wrotatecutbuffers(i
);
2357 stdwin_getselection(self
, args
)
2364 if (!getintarg(args
, &sel
))
2366 data
= wgetselection(sel
, &len
);
2371 return newsizedstringobject(data
, len
);
2375 stdwin_resetselection(self
, args
)
2380 if (!getintarg(args
, &sel
))
2382 wresetselection(sel
);
2388 stdwin_fetchcolor(self
, args
)
2394 if (!getstrarg(args
, &colorname
))
2396 color
= wfetchcolor(colorname
);
2398 if (color
== BADCOLOR
) {
2399 err_setstr(StdwinError
, "color name not found");
2403 return newintobject((long)color
);
2407 stdwin_getscrsize(self
, args
)
2412 if (!getnoarg(args
))
2414 wgetscrsize(&width
, &height
);
2415 return makepoint(width
, height
);
2419 stdwin_getscrmm(self
, args
)
2424 if (!getnoarg(args
))
2426 wgetscrmm(&width
, &height
);
2427 return makepoint(width
, height
);
2432 stdwin_connectionnumber(self
, args
)
2436 if (!getnoarg(args
))
2438 return newintobject((long) wconnectionnumber());
2443 stdwin_listfontnames(self
, args
)
2451 if (!getargs(args
, "z", &pattern
))
2453 fontnames
= wlistfontnames(pattern
, &count
);
2454 list
= newlistobject(count
);
2457 for (i
= 0; i
< count
; i
++) {
2458 object
*v
= newstringobject(fontnames
[i
]);
2464 setlistitem(list
, i
, v
);
2472 stdwin_newbitmap(self
, args
)
2478 if (!getargs(args
, "(ii)", &width
, &height
))
2480 return (object
*)newbitmapobject(width
, height
);
2484 static struct methodlist stdwin_methods
[] = {
2485 {"askfile", stdwin_askfile
},
2486 {"askstr", stdwin_askstr
},
2487 {"askync", stdwin_askync
},
2488 {"done", stdwin_done
},
2489 {"fetchcolor", stdwin_fetchcolor
},
2491 {"fileno", stdwin_connectionnumber
},
2492 {"connectionnumber", stdwin_connectionnumber
},
2494 {"fleep", stdwin_fleep
},
2495 {"getactive", stdwin_getactive
},
2496 {"getcutbuffer", stdwin_getcutbuffer
},
2497 {"getdefscrollbars", stdwin_getdefscrollbars
},
2498 {"getdefwinpos", stdwin_getdefwinpos
},
2499 {"getdefwinsize", stdwin_getdefwinsize
},
2500 {"getevent", stdwin_getevent
},
2501 {"getscrmm", stdwin_getscrmm
},
2502 {"getscrsize", stdwin_getscrsize
},
2503 {"getselection", stdwin_getselection
},
2504 {"listfontnames", stdwin_listfontnames
},
2505 {"menucreate", stdwin_menucreate
},
2506 {"message", stdwin_message
},
2508 {"newbitmap", stdwin_newbitmap
},
2510 {"open", stdwin_open
},
2511 {"pollevent", stdwin_pollevent
},
2512 {"resetselection", stdwin_resetselection
},
2513 {"rotatecutbuffers", stdwin_rotatecutbuffers
},
2514 {"setcutbuffer", stdwin_setcutbuffer
},
2515 {"setdefscrollbars", stdwin_setdefscrollbars
},
2516 {"setdefwinpos", stdwin_setdefwinpos
},
2517 {"setdefwinsize", stdwin_setdefwinsize
},
2519 /* Text measuring methods borrow code from drawing objects: */
2520 {"baseline", (method
)drawing_baseline
},
2521 {"lineheight", (method
)drawing_lineheight
},
2522 {"textbreak", (method
)drawing_textbreak
},
2523 {"textwidth", (method
)drawing_textwidth
},
2525 /* Same for font setting methods: */
2526 {"setfont", (method
)drawing_setfont
},
2528 /* Same for color setting/getting methods: */
2529 {"getbgcolor", (method
)drawing_getbgcolor
},
2530 {"getfgcolor", (method
)drawing_getfgcolor
},
2531 {"setbgcolor", (method
)drawing_setbgcolor
},
2532 {"setfgcolor", (method
)drawing_setfgcolor
},
2534 {NULL
, NULL
} /* sentinel */
2539 checkstringlist(args
, ps
, pn
)
2546 if (!is_listobject(args
)) {
2547 err_setstr(TypeError
, "list of strings expected");
2550 n
= getlistsize(args
);
2551 s
= NEW(char *, n
+1);
2556 for (i
= 0; i
< n
; i
++) {
2557 object
*item
= getlistitem(args
, i
);
2558 if (!is_stringobject(item
)) {
2559 err_setstr(TypeError
, "list of strings expected");
2562 s
[i
] = getstringvalue(item
);
2564 s
[n
] = NULL
; /* In case caller wants a NULL-terminated list */
2571 putbackstringlist(list
, s
, n
)
2576 int oldsize
= getlistsize(list
);
2581 newlist
= newlistobject(n
);
2582 for (i
= 0; i
< n
&& newlist
!= NULL
; i
++) {
2583 object
*item
= newstringobject(s
[i
]);
2589 setlistitem(newlist
, i
, item
);
2591 if (newlist
== NULL
)
2593 (*list
->ob_type
->tp_as_sequence
->sq_ass_slice
)
2594 (list
, 0, oldsize
, newlist
);
2598 #endif /* macintosh */
2604 static int inited
= 0;
2609 PyMac_DoYieldEnabled
= 0;
2614 object
*sys_argv
= sysget("argv");
2615 if (sys_argv
!= NULL
) {
2616 if (!checkstringlist(sys_argv
, &argv
, &argc
))
2620 /* If argv[0] has a ".py" suffix, remove the suffix */
2621 char *p
= strrchr(argv
[0], '.');
2622 if (p
!= NULL
&& strcmp(p
, ".py") == 0) {
2623 int n
= p
- argv
[0];
2624 if (n
>= sizeof(buf
))
2626 strncpy(buf
, argv
[0], n
);
2631 winitargs(&argc
, &argv
);
2633 if (!putbackstringlist(sys_argv
, argv
, argc
))
2639 m
= initmodule("stdwin", stdwin_methods
);
2640 d
= getmoduledict(m
);
2642 /* Initialize stdwin.error exception */
2643 StdwinError
= newstringobject("stdwin.error");
2644 if (StdwinError
== NULL
|| dictinsert(d
, "error", StdwinError
) != 0)
2645 fatal("can't define stdwin.error");
2647 StdwinLock
= allocate_lock();
2648 if (StdwinLock
== NULL
)
2649 fatal("can't allocate stdwin lock");