blob: 53f130f2735e1ab74526d35eeaf64459ecf7dabc [file] [log] [blame]
Guido van Rossumb3404661995-01-22 18:36:13 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
Jack Jansenf93c72a1994-12-14 14:07:50 +000024
25#include "Python.h"
26#include "macglue.h"
27
28#include <OSUtils.h> /* for Set(Current)A5 */
Jack Jansene8e8ae01995-01-26 16:36:45 +000029#include <Files.h>
Jack Jansen8cd2b721995-02-13 11:33:28 +000030#include <Aliases.h>
31#include <StandardFile.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000032#include <Resources.h>
33#include <Memory.h>
34#include <Events.h>
35#include <Windows.h>
36#include <Desk.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000037#include <Traps.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000038#include <Processes.h>
Guido van Rossumcc0d8791995-01-30 08:57:13 +000039#ifdef THINK_C
40#include <OSEvents.h> /* For EvQElPtr */
41#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +000042
43#include <signal.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000044
Jack Jansen8cd2b721995-02-13 11:33:28 +000045#define NOPYTHON_ALERT 128
46#define YES_ITEM 1
47#define NO_ITEM 2
48#define CURWD_ITEM 3
49
Jack Jansene8e8ae01995-01-26 16:36:45 +000050#ifdef __MWERKS__
Jack Jansenee23d6e1995-01-27 14:43:25 +000051/*
52** With MW we can pass the event off to the console window, so
53** we might as well handle all events.
54*/
Jack Jansene8e8ae01995-01-26 16:36:45 +000055#include <SIOUX.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000056#define MAINLOOP_EVENTMASK everyEvent
57#else
58/*
59** For other compilers we're more careful, since we can't handle
60** things like updates (and they'll keep coming back if we don't
61** handle them)
62*/
63#define MAINLOOP_EVENTMASK (mDownMask|keyDownMask|osMask)
Jack Jansene8e8ae01995-01-26 16:36:45 +000064#endif /* __MWERKS__ */
65
66#include <signal.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000067
Guido van Rossumb3404661995-01-22 18:36:13 +000068/* XXX We should include Errors.h here, but it has a name conflict
Jack Jansen5f653091995-01-18 13:53:49 +000069** with the python errors.h. */
70#define fnfErr -43
71
Jack Jansene8e8ae01995-01-26 16:36:45 +000072/* Declared in macfsmodule.c: */
73extern FSSpec *mfs_GetFSSpecFSSpec();
74
Jack Jansenee23d6e1995-01-27 14:43:25 +000075/* Interrupt code variables: */
76static int interrupted; /* Set to true when cmd-. seen */
77static RETSIGTYPE intcatcher Py_PROTO((int));
78
Jack Jansene8e8ae01995-01-26 16:36:45 +000079/*
80** We attempt to be a good citizen by giving up the CPU periodically.
81** When in the foreground we do this less often and for shorter periods
82** than when in the background. At this time we also check for events and
Jack Jansenee23d6e1995-01-27 14:43:25 +000083** pass them off to SIOUX, if compiling with mwerks.
Jack Jansene8e8ae01995-01-26 16:36:45 +000084** The counts here are in ticks of 1/60th second.
85** XXXX The initial values here are not based on anything.
86** FG-python gives up the cpu for 1/60th 5 times per second,
87** BG-python for .2 second 10 times per second.
88*/
89static long interval_fg = 12;
90static long interval_bg = 6;
91static long yield_fg = 1;
92static long yield_bg = 12;
Jack Jansenee23d6e1995-01-27 14:43:25 +000093static long lastyield;
94static int in_foreground;
95
96int PyMac_DoYieldEnabled = 1; /* Don't do eventloop when false */
97
Jack Jansene8e8ae01995-01-26 16:36:45 +000098
Jack Jansen5f653091995-01-18 13:53:49 +000099/* Convert C to Pascal string. Returns pointer to static buffer. */
100unsigned char *
101Pstring(char *str)
102{
103 static Str255 buf;
104 int len;
105
106 len = strlen(str);
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000107 if (len > 255)
108 len = 255;
Jack Jansen5f653091995-01-18 13:53:49 +0000109 buf[0] = (unsigned char)len;
110 strncpy((char *)buf+1, str, len);
111 return buf;
112}
113
Jack Jansenf93c72a1994-12-14 14:07:50 +0000114/* Replace strerror with something that might work */
115char *macstrerror(int err)
116{
117 static char buf[256];
118 Handle h;
119 char *str;
120
121 h = GetResource('Estr', err);
122 if ( h ) {
123 HLock(h);
124 str = (char *)*h;
125 memcpy(buf, str+1, (unsigned char)str[0]);
Guido van Rossumcc9bc8f1995-02-13 16:17:03 +0000126 buf[(unsigned char)str[0]] = '\0';
Jack Jansenf93c72a1994-12-14 14:07:50 +0000127 HUnlock(h);
128 ReleaseResource(h);
129 } else {
130 sprintf(buf, "Mac OS error code %d", err);
131 }
132 return buf;
133}
134
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000135/* Exception object shared by all Mac specific modules for Mac OS errors */
136PyObject *PyMac_OSErrException;
137
138/* Initialize and return PyMac_OSErrException */
139PyObject *
140PyMac_GetOSErrException()
141{
142 if (PyMac_OSErrException == NULL)
143 PyMac_OSErrException = PyString_FromString("Mac OS Error");
144 return PyMac_OSErrException;
145}
146
Jack Jansenf93c72a1994-12-14 14:07:50 +0000147/* Set a MAC-specific error from errno, and return NULL; return None if no error */
148PyObject *
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000149PyErr_Mac(PyObject *eobj, int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000150{
151 char *msg;
152 PyObject *v;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000153
Guido van Rossum8f691791995-01-18 23:57:26 +0000154 if (err == 0 && !PyErr_Occurred()) {
Jack Jansenf93c72a1994-12-14 14:07:50 +0000155 Py_INCREF(Py_None);
156 return Py_None;
157 }
Guido van Rossum8f691791995-01-18 23:57:26 +0000158 if (err == -1 && PyErr_Occurred())
159 return NULL;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000160 msg = macstrerror(err);
161 v = Py_BuildValue("(is)", err, msg);
162 PyErr_SetObject(eobj, v);
163 Py_DECREF(v);
164 return NULL;
165}
166
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000167/* Call PyErr_Mac with PyMac_OSErrException */
168PyObject *
169PyMac_Error(OSErr err)
170{
171 return PyErr_Mac(PyMac_GetOSErrException(), err);
172}
173
Jack Jansenee23d6e1995-01-27 14:43:25 +0000174/* The catcher routine (which may not be used for all compilers) */
175static RETSIGTYPE
176intcatcher(sig)
177 int sig;
178{
179 interrupted = 1;
180 signal(SIGINT, intcatcher);
181}
182
183void
184PyOS_InitInterrupts()
185{
186 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
187 signal(SIGINT, intcatcher);
188}
189
190/*
191** This routine scans the event queue looking for cmd-.
192** This is the only way to get an interrupt under THINK (since it
193** doesn't do SIGINT handling), but is also used under MW, when
194** the full-fledged event loop is disabled. This way, we can at least
195** interrupt a runaway python program.
196*/
197static void
198scan_event_queue(flush)
199 int flush;
200{
201 register EvQElPtr q;
202
203 q = (EvQElPtr) GetEvQHdr()->qHead;
204
205 for (; q; q = (EvQElPtr)q->qLink) {
206 if (q->evtQWhat == keyDown &&
207 (char)q->evtQMessage == '.' &&
208 (q->evtQModifiers & cmdKey) != 0) {
209 if ( flush )
210 FlushEvents(keyDownMask, 0);
211 interrupted = 1;
212 break;
213 }
214 }
215}
216
217int
218PyOS_InterruptOccurred()
219{
220#ifdef THINK_C
221 scan_event_queue(1);
222#endif
223 PyMac_Yield();
224 if (interrupted) {
225 interrupted = 0;
226 return 1;
227 }
228 return 0;
229}
230
231/* intrpeek() is like intrcheck(), but it doesn't flush the events. The
232** idea is that you call intrpeek() somewhere in a busy-wait loop, and return
233** None as soon as it returns 1. The mainloop will then pick up the cmd-. soon
234** thereafter.
235*/
236static int
237intrpeek()
238{
239#ifdef THINK_C
240 scan_event_queue(0);
241#endif
242 return interrupted;
243}
244
245/* Check whether we are in the foreground */
246int
247PyMac_InForeground()
248{
249 static ProcessSerialNumber ours;
250 static inited;
251 ProcessSerialNumber curfg;
252 Boolean eq;
253
254 if ( inited == 0 )
255 (void)GetCurrentProcess(&ours);
256 inited = 1;
257 if ( GetFrontProcess(&curfg) < 0 )
258 eq = 1;
259 else if ( SameProcess(&ours, &curfg, &eq) < 0 )
260 eq = 1;
261 return (int)eq;
262
263}
264
Jack Jansenf93c72a1994-12-14 14:07:50 +0000265/*
Jack Jansene8e8ae01995-01-26 16:36:45 +0000266** Set yield timeouts
Jack Jansenf93c72a1994-12-14 14:07:50 +0000267*/
Jack Jansene8e8ae01995-01-26 16:36:45 +0000268void
269PyMac_SetYield(long fgi, long fgy, long bgi, long bgy)
270{
271 interval_fg = fgi;
272 yield_fg = fgy;
273 interval_bg = bgi;
274 yield_bg = bgy;
275}
276
277/*
Jack Jansena76382a1995-02-02 14:25:56 +0000278** Handle an event, either one found in the mainloop eventhandler or
279** one passed back from the python program.
280*/
281void
282PyMac_HandleEvent(evp)
283 EventRecord *evp;
284{
285 WindowPtr wp;
286
287#ifdef __MWERKS__
288 /* If SIOUX wants it we're done */
289 (void)SIOUXHandleOneEvent(evp);
290#else
291 /* Other compilers are just unlucky: we only weed out clicks in other applications */
292 if ( evp->what == mouseDown ) {
293 if ( FindWindow(evp->where, &wp) == inSysWindow )
294 SystemClick(evp, wp);
295 }
296#endif /* !__MWERKS__ */
297}
298
299/*
Jack Jansene8e8ae01995-01-26 16:36:45 +0000300** Yield the CPU to other tasks.
301*/
302static
303PyMac_DoYield()
Jack Jansenf93c72a1994-12-14 14:07:50 +0000304{
305 EventRecord ev;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000306 long yield;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000307 static int no_waitnextevent = -1;
308 int gotone;
309
310 if ( no_waitnextevent < 0 ) {
311 no_waitnextevent = (NGetTrapAddress(_WaitNextEvent, ToolTrap) ==
312 NGetTrapAddress(_Unimplemented, ToolTrap));
313 }
Jack Jansenf93c72a1994-12-14 14:07:50 +0000314
Jack Jansenee23d6e1995-01-27 14:43:25 +0000315 if ( !PyMac_DoYieldEnabled ) {
316#ifndef THINK_C
317 /* Under think this has been done before in intrcheck() or intrpeek() */
318 scan_event_queue(0);
319#endif
Jack Jansene8e8ae01995-01-26 16:36:45 +0000320 return;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000321 }
Jack Jansene8e8ae01995-01-26 16:36:45 +0000322
Jack Jansenee23d6e1995-01-27 14:43:25 +0000323 in_foreground = PyMac_InForeground();
324 if ( in_foreground )
Jack Jansene8e8ae01995-01-26 16:36:45 +0000325 yield = yield_fg;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000326 else
327 yield = yield_bg;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000328 while ( 1 ) {
329 if ( no_waitnextevent ) {
330 SystemTask();
Jack Jansenee23d6e1995-01-27 14:43:25 +0000331 gotone = GetNextEvent(MAINLOOP_EVENTMASK, &ev);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000332 } else {
Jack Jansenee23d6e1995-01-27 14:43:25 +0000333 gotone = WaitNextEvent(MAINLOOP_EVENTMASK, &ev, yield, NULL);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000334 }
335 /* Get out quickly if nothing interesting is happening */
336 if ( !gotone || ev.what == nullEvent )
337 break;
Jack Jansena76382a1995-02-02 14:25:56 +0000338 PyMac_HandleEvent(&ev);
Jack Jansenf93c72a1994-12-14 14:07:50 +0000339 }
Jack Jansene8e8ae01995-01-26 16:36:45 +0000340 lastyield = TickCount();
341}
342
343/*
344** Yield the CPU to other tasks if opportune
345*/
346void
347PyMac_Yield() {
348 long iv;
349
Jack Jansenee23d6e1995-01-27 14:43:25 +0000350 if ( in_foreground )
Jack Jansene8e8ae01995-01-26 16:36:45 +0000351 iv = interval_fg;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000352 else
353 iv = interval_bg;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000354 if ( TickCount() > lastyield + iv )
355 PyMac_DoYield();
356}
357
358/*
359** Idle routine for busy-wait loops.
360** Gives up CPU, handles events and returns true if an interrupt is pending
361** (but not actually handled yet).
362*/
363int
364PyMac_Idle()
365{
366 PyMac_DoYield();
367 return intrpeek();
Jack Jansenf93c72a1994-12-14 14:07:50 +0000368}
369
Jack Jansen8cd2b721995-02-13 11:33:28 +0000370/*
371** Return the name of the Python directory
372*/
373char *
374PyMac_GetPythonDir()
375{
376 int item;
377 static char name[256];
378 AliasHandle handle;
379 FSSpec dirspec;
380 int ok = 0, exists = 0;
381 Boolean modified = 0;
382 StandardFileReply sfreply;
383
384 handle = (AliasHandle)GetResource('alis', 128);
385 if ( handle ) {
386 if ( ResolveAlias(NULL, handle, &dirspec, &modified) == noErr )
387 ok = 1;
388 exists = 1;
389 }
390 if ( !ok ) {
391 item = Alert(NOPYTHON_ALERT, NULL);
392 if ( item == YES_ITEM ) {
393 StandardGetFile(NULL, 0, NULL, &sfreply);
394 if ( sfreply.sfGood ) {
395 if ( sfreply.sfIsFolder ) {
396 dirspec = sfreply.sfFile;
397 ok = 1;
398 modified = 1;
399 } else {
400 /* User selected a file. Use folder containing it */
401 if (FSMakeFSSpec(sfreply.sfFile.vRefNum,
402 sfreply.sfFile.parID, "\p", &dirspec) == 0) {
403 ok = 1;
404 modified = 1;
405 }
406 }
407 }
408 } else if ( item == CURWD_ITEM ) {
409 if ( getwd(name) ) {
410 if ( FSMakeFSSpec(0, 0, Pstring(name), &dirspec) == 0 ) {
411 ok = 1;
412 modified = 1;
413 }
414 }
415 }
416 }
417 if ( ok && modified ) {
418 if ( !exists ) {
419 if (NewAlias(NULL, &dirspec, &handle) == 0 )
420 AddResource((Handle)handle, 'alis', 128, "\p");
421 } else {
422 ChangedResource((Handle)handle);
423 }
424 UpdateResFile(CurResFile());
425 }
426 if ( ok ) {
427 ok = (nfullpath(&dirspec, name) == 0);
428 if ( ok ) strcat(name, ":");
429 }
430 if ( !ok ) {
431 /* If all fails, we return the current directory */
432 name[0] = 0;
433 (void)getwd(name);
434 }
435 return name;
436}
437
Jack Jansen5f653091995-01-18 13:53:49 +0000438
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000439/* Convert a 4-char string object argument to an OSType value */
Jack Jansen5f653091995-01-18 13:53:49 +0000440int
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000441PyMac_GetOSType(PyObject *v, OSType *pr)
Jack Jansen5f653091995-01-18 13:53:49 +0000442{
443 if (!PyString_Check(v) || PyString_Size(v) != 4) {
444 PyErr_SetString(PyExc_TypeError,
445 "OSType arg must be string of 4 chars");
446 return 0;
447 }
448 memcpy((char *)pr, PyString_AsString(v), 4);
449 return 1;
450}
451
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000452/* Convert an OSType value to a 4-char string object */
453PyObject *
454PyMac_BuildOSType(OSType t)
455{
456 return PyString_FromStringAndSize((char *)&t, 4);
457}
458
459
460/* Convert a Python string object to a Str255 */
Jack Jansen5f653091995-01-18 13:53:49 +0000461int
Guido van Rossum8f691791995-01-18 23:57:26 +0000462PyMac_GetStr255(PyObject *v, Str255 pbuf)
Jack Jansen5f653091995-01-18 13:53:49 +0000463{
464 int len;
465 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
466 PyErr_SetString(PyExc_TypeError,
467 "Str255 arg must be string of at most 255 chars");
468 return 0;
469 }
470 pbuf[0] = len;
471 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
472 return 1;
473}
474
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000475/* Convert a Str255 to a Python string object */
476PyObject *
477PyMac_BuildStr255(Str255 s)
478{
479 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
480}
481
482
Jack Jansen5f653091995-01-18 13:53:49 +0000483/*
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000484** Convert a Python object to an FSSpec.
485** The object may either be a full pathname or a triple
486** (vrefnum, dirid, path).
Jack Jansen5f653091995-01-18 13:53:49 +0000487** NOTE: This routine will fail on pre-sys7 machines.
488** The caller is responsible for not calling this routine
489** in those cases (which is fine, since everyone calling
490** this is probably sys7 dependent anyway).
491*/
492int
Guido van Rossum8f691791995-01-18 23:57:26 +0000493PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
Jack Jansen5f653091995-01-18 13:53:49 +0000494{
495 Str255 path;
496 short refnum;
497 long parid;
498 OSErr err;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000499 FSSpec *fs2;
Jack Jansen5f653091995-01-18 13:53:49 +0000500
Jack Jansene8e8ae01995-01-26 16:36:45 +0000501 /* first check whether it already is an FSSpec */
502 fs2 = mfs_GetFSSpecFSSpec(v);
503 if ( fs2 ) {
504 fs = fs2;
505 return 1;
506 }
Jack Jansen5f653091995-01-18 13:53:49 +0000507 if ( PyString_Check(v) ) {
508 /* It's a pathname */
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000509 if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
Jack Jansen5f653091995-01-18 13:53:49 +0000510 return 0;
511 refnum = 0; /* XXXX Should get CurWD here... */
512 parid = 0;
513 } else {
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000514 if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (vrefnum,dirid,path)",
515 &refnum, &parid, PyMac_GetStr255, &path)) {
Jack Jansen5f653091995-01-18 13:53:49 +0000516 return 0;
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000517 }
Jack Jansen5f653091995-01-18 13:53:49 +0000518 }
519 err = FSMakeFSSpec(refnum, parid, path, fs);
520 if ( err && err != fnfErr ) {
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000521 PyErr_Mac(PyExc_ValueError, err);
Jack Jansen5f653091995-01-18 13:53:49 +0000522 return 0;
523 }
524 return 1;
525}
526
Guido van Rossum8f691791995-01-18 23:57:26 +0000527
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000528
529/* Convert a Python object to a Rect.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000530 The object must be a (left, top, right, bottom) tuple.
531 (This differs from the order in the struct but is consistent with
532 the arguments to SetRect(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000533int
534PyMac_GetRect(PyObject *v, Rect *r)
Guido van Rossum8f691791995-01-18 23:57:26 +0000535{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000536 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
Guido van Rossum8f691791995-01-18 23:57:26 +0000537}
Guido van Rossumb3404661995-01-22 18:36:13 +0000538
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000539/* Convert a Rect to a Python object */
Guido van Rossumb3404661995-01-22 18:36:13 +0000540PyObject *
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000541PyMac_BuildRect(Rect *r)
Guido van Rossumb3404661995-01-22 18:36:13 +0000542{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000543 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000544}
545
546
547/* Convert a Python object to a Point.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000548 The object must be a (h, v) tuple.
549 (This differs from the order in the struct but is consistent with
550 the arguments to SetPoint(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000551int
552PyMac_GetPoint(PyObject *v, Point *p)
553{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000554 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000555}
556
557/* Convert a Point to a Python object */
558PyObject *
559PyMac_BuildPoint(Point p)
560{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000561 return Py_BuildValue("(hh)", p.h, p.v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000562}
563
564
565/* Convert a Python object to an EventRecord.
566 The object must be a (what, message, when, (v, h), modifiers) tuple. */
567int
568PyMac_GetEventRecord(PyObject *v, EventRecord *e)
569{
570 return PyArg_Parse(v, "(hll(hh)h)",
571 &e->what,
572 &e->message,
573 &e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000574 &e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000575 &e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000576 &e->modifiers);
577}
578
579/* Convert a Rect to an EventRecord object */
580PyObject *
581PyMac_BuildEventRecord(EventRecord *e)
582{
583 return Py_BuildValue("(hll(hh)h)",
584 e->what,
585 e->message,
586 e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000587 e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000588 e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000589 e->modifiers);
Guido van Rossumb3404661995-01-22 18:36:13 +0000590}