blob: d7eb9ec5673da67cead9ced32935363b6bc1230e [file] [log] [blame]
Guido van Rossumb3404661995-01-22 18:36:13 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossumb3404661995-01-22 18:36:13 +00003The 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
Jack Jansenbf05d4c1996-08-19 15:11:45 +000025#ifdef __CFM68K__
26/* cfm68k InterfaceLib exports GetEventQueue, but Events.h doesn't know this
27** and defines it as GetEvQHdr (which is correct for PPC). This fix is for
28** CW9, check that the workaround is still needed for the next release.
29*/
30#define GetEvQHdr GetEventQueue
31#endif /* __CFM68K__ */
32
33#include <Events.h>
34
Jack Jansenbb6d83a2000-06-02 21:27:11 +000035#ifdef TARGET_API_MAC_CARBON
36/* Unfortunately this call is probably slower... */
37#define LMGetTicks() TickCount()
38#endif
39
Jack Jansenbf05d4c1996-08-19 15:11:45 +000040#ifdef __CFM68K__
41#undef GetEventQueue
42#endif /* __CFM68K__ */
43
Jack Jansenf93c72a1994-12-14 14:07:50 +000044#include "Python.h"
Guido van Rossumbecdbec1995-02-14 01:27:24 +000045
Jack Jansenf93c72a1994-12-14 14:07:50 +000046#include "macglue.h"
Jack Jansen74162f31995-02-15 22:58:33 +000047#include "marshal.h"
48#include "import.h"
Jack Janseneda78631997-06-12 15:29:46 +000049#include "importdl.h"
Jack Jansenf93c72a1994-12-14 14:07:50 +000050
Jack Jansen819f1771995-08-14 12:35:10 +000051#include "pythonresources.h"
52
Jack Jansenf93c72a1994-12-14 14:07:50 +000053#include <OSUtils.h> /* for Set(Current)A5 */
Jack Jansene8e8ae01995-01-26 16:36:45 +000054#include <Files.h>
Jack Jansen8cd2b721995-02-13 11:33:28 +000055#include <StandardFile.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000056#include <Resources.h>
57#include <Memory.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +000058#include <Windows.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000059#include <Traps.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000060#include <Processes.h>
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +000061#include <Fonts.h>
62#include <Menus.h>
Jack Jansen08305501995-06-18 20:03:40 +000063#include <TextUtils.h>
Jack Jansen16df2aa1995-02-27 16:17:28 +000064#ifdef __MWERKS__
65#include <SIOUX.h>
Jack Jansen9ae898b2000-07-11 21:16:03 +000066extern void SIOUXSetupMenus(void);
67extern void SIOUXDoAboutBox(void);
Jack Jansen16df2aa1995-02-27 16:17:28 +000068#endif
Jack Jansen9ae898b2000-07-11 21:16:03 +000069#ifdef USE_GUSI
70/* Functions we redefine because they're in obscure libraries */
71extern void SpinCursor(short x);
72extern void RotateCursor(short x);
73extern pascal void PLstrcpy(unsigned char *, unsigned char *);
74extern pascal int PLstrcmp(unsigned char *, unsigned char *);
75extern pascal unsigned char *PLstrrchr(unsigned char *, unsigned char);
76
77#endif
78
Jack Jansen2d1306b2000-04-07 09:10:49 +000079#ifdef USE_GUSI1
Jack Jansen911ad6b1996-03-05 16:56:24 +000080#include <TFileSpec.h> /* For Path2FSSpec */
Jack Jansenf6865f71996-09-04 15:24:59 +000081#include <GUSI.h>
Jack Jansen911ad6b1996-03-05 16:56:24 +000082#endif
Jack Jansen2d1306b2000-04-07 09:10:49 +000083#include <LowMem.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000084
Jack Jansen3469e991996-09-06 00:30:45 +000085/* The ID of the Sioux apple menu */
86#define SIOUX_APPLEID 32000
87
Jack Jansenee23d6e1995-01-27 14:43:25 +000088#include <signal.h>
Jack Jansen74162f31995-02-15 22:58:33 +000089#include <stdio.h>
Jack Jansene8e8ae01995-01-26 16:36:45 +000090
Jack Jansenee23d6e1995-01-27 14:43:25 +000091/*
Jack Jansend1f06311996-08-01 15:23:54 +000092** When less than this amount of stackspace is left we
93** raise a MemoryError.
94*/
95#ifndef MINIMUM_STACK_SIZE
96#ifdef __powerc
97#define MINIMUM_STACK_SIZE 8192
98#else
99#define MINIMUM_STACK_SIZE 4096
100#endif
101#endif
102
103/*
Jack Jansen16df2aa1995-02-27 16:17:28 +0000104** We have to be careful, since we can't handle
Jack Jansenee23d6e1995-01-27 14:43:25 +0000105** things like updates (and they'll keep coming back if we don't
Jack Jansen16df2aa1995-02-27 16:17:28 +0000106** handle them). Note that we don't know who has windows open, so
107** even handing updates off to SIOUX under MW isn't going to work.
Jack Jansenee23d6e1995-01-27 14:43:25 +0000108*/
Jack Jansen0c968871997-08-26 13:20:34 +0000109#define MAINLOOP_EVENTMASK (mDownMask|keyDownMask|osMask|activMask)
Jack Jansene8e8ae01995-01-26 16:36:45 +0000110
111#include <signal.h>
Jack Jansenf93c72a1994-12-14 14:07:50 +0000112
Guido van Rossumb3404661995-01-22 18:36:13 +0000113/* XXX We should include Errors.h here, but it has a name conflict
Jack Jansen5f653091995-01-18 13:53:49 +0000114** with the python errors.h. */
115#define fnfErr -43
116
Jack Jansene8e8ae01995-01-26 16:36:45 +0000117/* Declared in macfsmodule.c: */
Jack Jansen9ae898b2000-07-11 21:16:03 +0000118extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *);
Jack Jansend88296d2000-07-11 19:51:05 +0000119extern PyObject *newmfssobject(FSSpec *);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000120
Jack Jansenee23d6e1995-01-27 14:43:25 +0000121/* Interrupt code variables: */
122static int interrupted; /* Set to true when cmd-. seen */
Jack Jansend88296d2000-07-11 19:51:05 +0000123static RETSIGTYPE intcatcher(int);
Jack Jansenee23d6e1995-01-27 14:43:25 +0000124
Jack Jansend88296d2000-07-11 19:51:05 +0000125static int PyMac_Yield(void);
Jack Jansenf6865f71996-09-04 15:24:59 +0000126
Jack Jansene8e8ae01995-01-26 16:36:45 +0000127/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000128** These are the real scheduling parameters that control what we check
129** in the event loop, and how often we check. The values are initialized
130** from pyMac_SchedParamStruct.
131*/
132
133struct real_sched_param_struct {
134 int check_interrupt; /* if true check for command-dot */
135 int process_events; /* if nonzero enable evt processing, this mask */
136 int besocial; /* if nonzero be a little social with CPU */
137 unsigned long check_interval; /* how often to check, in ticks */
138 unsigned long bg_yield; /* yield so long when in background */
139 /* these are computed from previous and clock and such */
140 int enabled; /* check_interrupt OR process_event OR yield */
141 unsigned long next_check; /* when to check/yield next, in ticks */
142};
143
144static struct real_sched_param_struct schedparams =
145 { 1, MAINLOOP_EVENTMASK, 1, 15, 15, 1, 0};
146
Jack Jansen819f1771995-08-14 12:35:10 +0000147/*
Jack Jansenf6865f71996-09-04 15:24:59 +0000148** Workaround for sioux/gusi combo: set when we are exiting
149*/
150int PyMac_ConsoleIsDead;
151
152/*
Jack Jansencaa7c461997-06-12 10:49:13 +0000153** Sioux menu bar, saved early so we can restore it
154*/
155static Handle sioux_mbar;
156
157/*
Jack Jansen819f1771995-08-14 12:35:10 +0000158** Some stuff for our GetDirectory and PromptGetFile routines
159*/
160struct hook_args {
161 int selectcur_hit; /* Set to true when "select current" selected */
162 char *prompt; /* The prompt */
163};
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000164#ifdef TARGET_API_MAC_CARBON
165/* The StandardFile hooks don't exist in Carbon. This breaks GetDirectory,
166** but the macfsn code will replace it by a NavServices version anyway.
167*/
168#define myhook_upp NULL
169#else
Jack Jansen819f1771995-08-14 12:35:10 +0000170static DlgHookYDUPP myhook_upp;
171static int upp_inited = 0;
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000172#endif
Jack Jansen819f1771995-08-14 12:35:10 +0000173
Jack Jansen36ed5061997-06-20 16:18:15 +0000174/*
175** The python-code event handler
176*/
177static PyObject *python_event_handler;
178
Jack Jansen8f5725a1999-12-07 23:08:10 +0000179/*
180** Set to true if we're appearance-compliant
181*/
182int PyMac_AppearanceCompliant;
183
Jack Jansen2d1306b2000-04-07 09:10:49 +0000184#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000185/*
186** GUSI (1.6.0 and earlier, at the least) do not set the MacOS idea of
187** the working directory. Hence, we call this routine after each call
188** to chdir() to rectify things.
189*/
190void
191PyMac_FixGUSIcd()
192{
193 WDPBRec pb;
194 FSSpec curdirfss;
195
196 if ( Path2FSSpec(":x", &curdirfss) != noErr )
197 return;
198
199 /* Set MacOS "working directory" */
200 pb.ioNamePtr= "\p";
201 pb.ioVRefNum= curdirfss.vRefNum;
202 pb.ioWDDirID= curdirfss.parID;
Jack Jansen08c3be31997-04-08 15:27:00 +0000203 if (PBHSetVolSync(&pb) != noErr)
Jack Jansen378815c1996-03-06 16:21:34 +0000204 return;
Jack Jansen378815c1996-03-06 16:21:34 +0000205}
Jack Jansen2d1306b2000-04-07 09:10:49 +0000206#endif
Jack Jansen7ac70af1996-08-19 11:01:05 +0000207
Jack Jansen2d1306b2000-04-07 09:10:49 +0000208#ifdef USE_GUSI
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000209/*
210** SpinCursor (needed by GUSI) drags in heaps of stuff, so we
211** provide a dummy here.
212*/
Jack Jansencfadbd41996-08-19 11:36:25 +0000213void SpinCursor(short x) { /* Dummy */ }
Jack Jansenefaada71998-02-20 16:03:15 +0000214void RotateCursor(short x) { /* Dummy */ }
Jack Jansencfadbd41996-08-19 11:36:25 +0000215
Jack Jansenf6865f71996-09-04 15:24:59 +0000216/*
217** Replacement GUSI Spin function
218*/
Jack Jansen2d1306b2000-04-07 09:10:49 +0000219#ifdef USE_GUSI1
Jack Jansenf6865f71996-09-04 15:24:59 +0000220static int
221PyMac_GUSISpin(spin_msg msg, long arg)
222{
Jack Jansene3ae0df1997-06-03 15:28:29 +0000223 static Boolean inForeground = true;
224 int maxsleep = 6; /* 6 ticks is "normal" sleeptime */
Jack Jansenf6865f71996-09-04 15:24:59 +0000225
226 if (PyMac_ConsoleIsDead) return 0;
227#if 0
228 if (inForeground)
229 SpinCursor(msg == SP_AUTO_SPIN ? short(arg) : 1);
230#endif
231
232 if (interrupted) return -1;
233
Jack Jansene3ae0df1997-06-03 15:28:29 +0000234 if ( msg == SP_AUTO_SPIN )
235 maxsleep = 0;
236 if ( msg==SP_SLEEP||msg==SP_SELECT )
237 maxsleep = arg;
Jack Jansenf6865f71996-09-04 15:24:59 +0000238
Jack Jansene3ae0df1997-06-03 15:28:29 +0000239 PyMac_DoYield(maxsleep, 0); /* XXXX or is it safe to call python here? */
Jack Jansenf6865f71996-09-04 15:24:59 +0000240
241 return 0;
242}
243
244void
245PyMac_SetGUSISpin() {
246 GUSISetHook(GUSI_SpinHook, (GUSIHook)PyMac_GUSISpin);
247}
Jack Jansen2d1306b2000-04-07 09:10:49 +0000248#endif
Jack Jansenf6865f71996-09-04 15:24:59 +0000249
Jack Jansena39f1b01997-05-23 15:35:14 +0000250/* Called at exit() time thru atexit(), to stop event processing */
251void
252PyMac_StopGUSISpin() {
253 PyMac_ConsoleIsDead = 1;
254}
255
256/*
257** Replacement routines for the PLstr... functions so we don't need
258** StdCLib. Moreover, that implementation is broken under cfm68k...
259*/
Jack Jansen8bb573e1999-12-12 21:37:14 +0000260pascal void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000261PLstrcpy(unsigned char *to, unsigned char *fr)
Jack Jansena39f1b01997-05-23 15:35:14 +0000262{
263 memcpy(to, fr, fr[0]+1);
264}
265
Jack Jansen8bb573e1999-12-12 21:37:14 +0000266pascal int
Jack Jansen9ae898b2000-07-11 21:16:03 +0000267PLstrcmp(unsigned char *s1, unsigned char *s2)
Jack Jansena39f1b01997-05-23 15:35:14 +0000268{
269 int res;
270 int l = s1[0] < s2[0] ? s1[0] : s2[0];
271
272 res = memcmp(s1+1, s2+1, l);
273 if ( res != 0 )
274 return res;
275
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000276 if ( s1[0] < s2[0] )
Jack Jansena39f1b01997-05-23 15:35:14 +0000277 return -1;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000278 else if ( s1[0] > s2[0] )
Jack Jansena39f1b01997-05-23 15:35:14 +0000279 return 1;
280 else
281 return 0;
282}
283
Jack Jansen8bb573e1999-12-12 21:37:14 +0000284pascal unsigned char *
Jack Jansen9ae898b2000-07-11 21:16:03 +0000285PLstrrchr(unsigned char *str, unsigned char chr)
Jack Jansena39f1b01997-05-23 15:35:14 +0000286{
287 unsigned char *ptr = 0;
288 unsigned char *p;
289
290 for(p=str+1; p<str+str[0]; p++)
291 if ( *p == chr )
292 ptr = p;
293 return ptr;
294}
295
296#endif /* USE_GUSI */
Jack Jansen378815c1996-03-06 16:21:34 +0000297
Jack Jansen819f1771995-08-14 12:35:10 +0000298
Jack Jansen5f653091995-01-18 13:53:49 +0000299/* Convert C to Pascal string. Returns pointer to static buffer. */
300unsigned char *
301Pstring(char *str)
302{
303 static Str255 buf;
304 int len;
305
306 len = strlen(str);
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000307 if (len > 255)
308 len = 255;
Jack Jansen5f653091995-01-18 13:53:49 +0000309 buf[0] = (unsigned char)len;
310 strncpy((char *)buf+1, str, len);
311 return buf;
312}
313
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000314/* Like strerror() but for Mac OS error numbers */
315char *PyMac_StrError(int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000316{
317 static char buf[256];
318 Handle h;
319 char *str;
320
321 h = GetResource('Estr', err);
322 if ( h ) {
323 HLock(h);
324 str = (char *)*h;
325 memcpy(buf, str+1, (unsigned char)str[0]);
Guido van Rossumcc9bc8f1995-02-13 16:17:03 +0000326 buf[(unsigned char)str[0]] = '\0';
Jack Jansenf93c72a1994-12-14 14:07:50 +0000327 HUnlock(h);
328 ReleaseResource(h);
329 } else {
330 sprintf(buf, "Mac OS error code %d", err);
331 }
332 return buf;
333}
334
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000335/* Exception object shared by all Mac specific modules for Mac OS errors */
336PyObject *PyMac_OSErrException;
337
338/* Initialize and return PyMac_OSErrException */
339PyObject *
340PyMac_GetOSErrException()
341{
342 if (PyMac_OSErrException == NULL)
343 PyMac_OSErrException = PyString_FromString("Mac OS Error");
344 return PyMac_OSErrException;
345}
346
Jack Jansenf93c72a1994-12-14 14:07:50 +0000347/* Set a MAC-specific error from errno, and return NULL; return None if no error */
348PyObject *
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000349PyErr_Mac(PyObject *eobj, int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000350{
351 char *msg;
352 PyObject *v;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000353
Guido van Rossum8f691791995-01-18 23:57:26 +0000354 if (err == 0 && !PyErr_Occurred()) {
Jack Jansenf93c72a1994-12-14 14:07:50 +0000355 Py_INCREF(Py_None);
356 return Py_None;
357 }
Guido van Rossum8f691791995-01-18 23:57:26 +0000358 if (err == -1 && PyErr_Occurred())
359 return NULL;
Guido van Rossumc3d1c8e1995-02-18 15:01:31 +0000360 msg = PyMac_StrError(err);
Jack Jansenf93c72a1994-12-14 14:07:50 +0000361 v = Py_BuildValue("(is)", err, msg);
362 PyErr_SetObject(eobj, v);
363 Py_DECREF(v);
364 return NULL;
365}
366
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000367/* Call PyErr_Mac with PyMac_OSErrException */
368PyObject *
369PyMac_Error(OSErr err)
370{
371 return PyErr_Mac(PyMac_GetOSErrException(), err);
372}
373
Jack Jansen1ed95291996-07-22 15:25:10 +0000374#ifdef USE_STACKCHECK
375/* Check for stack overflow */
376int
377PyOS_CheckStack()
378{
379 long left;
380
381 left = StackSpace();
Jack Jansend1f06311996-08-01 15:23:54 +0000382 if ( left < MINIMUM_STACK_SIZE )
Jack Jansen1ed95291996-07-22 15:25:10 +0000383 return -1;
384 return 0;
385}
386#endif /* USE_STACKCHECK */
387
Jack Jansenee23d6e1995-01-27 14:43:25 +0000388/* The catcher routine (which may not be used for all compilers) */
389static RETSIGTYPE
390intcatcher(sig)
391 int sig;
392{
393 interrupted = 1;
394 signal(SIGINT, intcatcher);
395}
396
397void
398PyOS_InitInterrupts()
399{
400 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
401 signal(SIGINT, intcatcher);
402}
403
Jack Jansena8441de1997-08-08 14:57:37 +0000404void
405PyOS_FiniInterrupts()
406{
407}
408
Jack Jansenee23d6e1995-01-27 14:43:25 +0000409/*
410** This routine scans the event queue looking for cmd-.
411** This is the only way to get an interrupt under THINK (since it
412** doesn't do SIGINT handling), but is also used under MW, when
413** the full-fledged event loop is disabled. This way, we can at least
414** interrupt a runaway python program.
415*/
416static void
417scan_event_queue(flush)
418 int flush;
419{
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000420#ifdef TARGET_API_MAC_CARBON
421 /* CARBONXXXX To be implemented */
422 return;
423#else
Jack Jansenee23d6e1995-01-27 14:43:25 +0000424 register EvQElPtr q;
425
Jack Jansenefaada71998-02-20 16:03:15 +0000426 q = (EvQElPtr) LMGetEventQueue()->qHead;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000427
428 for (; q; q = (EvQElPtr)q->qLink) {
429 if (q->evtQWhat == keyDown &&
430 (char)q->evtQMessage == '.' &&
431 (q->evtQModifiers & cmdKey) != 0) {
432 if ( flush )
433 FlushEvents(keyDownMask, 0);
434 interrupted = 1;
435 break;
436 }
437 }
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000438#endif
Jack Jansenee23d6e1995-01-27 14:43:25 +0000439}
440
441int
Jack Jansen36ed5061997-06-20 16:18:15 +0000442PyErr_CheckSignals()
Jack Jansenee23d6e1995-01-27 14:43:25 +0000443{
Jack Jansene3ae0df1997-06-03 15:28:29 +0000444 if (schedparams.enabled) {
445 if ( (unsigned long)LMGetTicks() > schedparams.next_check ) {
Jack Jansen36ed5061997-06-20 16:18:15 +0000446 if ( PyMac_Yield() < 0)
447 return -1;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000448 schedparams.next_check = (unsigned long)LMGetTicks()
449 + schedparams.check_interval;
450 if (interrupted) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000451 scan_event_queue(1); /* Eat events up to cmd-. */
Jack Jansene3ae0df1997-06-03 15:28:29 +0000452 interrupted = 0;
Jack Jansen36ed5061997-06-20 16:18:15 +0000453 PyErr_SetNone(PyExc_KeyboardInterrupt);
454 return -1;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000455 }
456 }
Jack Jansenee23d6e1995-01-27 14:43:25 +0000457 }
458 return 0;
459}
460
Jack Jansen36ed5061997-06-20 16:18:15 +0000461int
462PyOS_InterruptOccurred()
463{
464 scan_event_queue(1);
465 return interrupted;
466}
Jack Jansenee23d6e1995-01-27 14:43:25 +0000467/* Check whether we are in the foreground */
Jack Jansen9ae898b2000-07-11 21:16:03 +0000468static int
469PyMac_InForeground(void)
Jack Jansenee23d6e1995-01-27 14:43:25 +0000470{
471 static ProcessSerialNumber ours;
472 static inited;
473 ProcessSerialNumber curfg;
474 Boolean eq;
475
Jack Jansene3ae0df1997-06-03 15:28:29 +0000476 if ( inited == 0 ) {
Jack Jansenee23d6e1995-01-27 14:43:25 +0000477 (void)GetCurrentProcess(&ours);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000478 inited = 1;
479 }
Jack Jansenee23d6e1995-01-27 14:43:25 +0000480 if ( GetFrontProcess(&curfg) < 0 )
481 eq = 1;
482 else if ( SameProcess(&ours, &curfg, &eq) < 0 )
483 eq = 1;
484 return (int)eq;
485
486}
487
Jack Jansen36ed5061997-06-20 16:18:15 +0000488int
489PyMac_SetEventHandler(PyObject *evh)
490{
491 if ( evh && python_event_handler ) {
492 PyErr_SetString(PyExc_RuntimeError, "Python event handler already set");
493 return 0;
494 }
495 if ( python_event_handler )
496 Py_DECREF(python_event_handler);
497 if ( evh )
498 Py_INCREF(evh);
499 python_event_handler = evh;
500 return 1;
501}
502
Jack Jansenf93c72a1994-12-14 14:07:50 +0000503/*
Jack Jansena76382a1995-02-02 14:25:56 +0000504** Handle an event, either one found in the mainloop eventhandler or
505** one passed back from the python program.
506*/
507void
Jack Jansen36ed5061997-06-20 16:18:15 +0000508PyMac_HandleEventIntern(evp)
Jack Jansena76382a1995-02-02 14:25:56 +0000509 EventRecord *evp;
510{
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000511#ifndef TARGET_API_MAC_CARBON
Jack Jansen0c968871997-08-26 13:20:34 +0000512 if ( evp->what == mouseDown ) {
513 WindowPtr wp;
514
515 if ( FindWindow(evp->where, &wp) == inSysWindow ) {
516 SystemClick(evp, wp);
517 return;
518 }
519 }
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000520#endif
Jack Jansena76382a1995-02-02 14:25:56 +0000521#ifdef __MWERKS__
Jack Jansen38e97661995-11-10 14:53:00 +0000522 {
523 int siouxdidit;
524
525 /* If SIOUX wants it we're done */
526 siouxdidit = SIOUXHandleOneEvent(evp);
527 if ( siouxdidit )
528 return;
529 }
Jack Jansena76382a1995-02-02 14:25:56 +0000530#else
Jack Jansen0c968871997-08-26 13:20:34 +0000531 /* Other compilers are just unlucky... */
Jack Jansena76382a1995-02-02 14:25:56 +0000532#endif /* !__MWERKS__ */
Jack Jansen36ed5061997-06-20 16:18:15 +0000533}
534
535/*
536** Handle an event, either through HandleEvent or by passing it to the Python
537** event handler.
538*/
539int
540PyMac_HandleEvent(evp)
541 EventRecord *evp;
542{
543 PyObject *rv;
544
545 if ( python_event_handler ) {
546 rv = PyObject_CallFunction(python_event_handler, "(O&)",
547 PyMac_BuildEventRecord, evp);
548 if ( rv )
549 Py_DECREF(rv);
550 else
551 return -1; /* Propagate exception */
552 } else {
553 PyMac_HandleEventIntern(evp);
554 }
555 return 0;
Jack Jansena76382a1995-02-02 14:25:56 +0000556}
557
558/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000559** Yield the CPU to other tasks without processing events.
Jack Jansene8e8ae01995-01-26 16:36:45 +0000560*/
Jack Jansen2d1306b2000-04-07 09:10:49 +0000561int
Jack Jansene3ae0df1997-06-03 15:28:29 +0000562PyMac_DoYield(int maxsleep, int maycallpython)
Jack Jansenf93c72a1994-12-14 14:07:50 +0000563{
564 EventRecord ev;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000565 int gotone;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000566 long latest_time_ready;
Jack Jansen36ed5061997-06-20 16:18:15 +0000567 static int in_here = 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000568
Jack Jansen36ed5061997-06-20 16:18:15 +0000569 in_here++;
Jack Jansene3ae0df1997-06-03 15:28:29 +0000570 /*
571 ** First check for interrupts, if wanted.
572 ** This sets a flag that will be picked up at an appropriate
573 ** moment in the mainloop.
574 */
575 if (schedparams.check_interrupt)
Jack Jansenee23d6e1995-01-27 14:43:25 +0000576 scan_event_queue(0);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000577
578 /* XXXX Implementing an idle routine goes here */
Jack Jansene8e8ae01995-01-26 16:36:45 +0000579
Jack Jansene3ae0df1997-06-03 15:28:29 +0000580 /*
581 ** Check which of the eventloop cases we have:
582 ** - process events
583 ** - don't process events but do yield
584 ** - do neither
585 */
Jack Jansen36ed5061997-06-20 16:18:15 +0000586 if( in_here > 1 || !schedparams.process_events ||
587 (python_event_handler && !maycallpython) ) {
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000588#ifndef TARGET_API_MAC_CARBON
Jack Jansene3ae0df1997-06-03 15:28:29 +0000589 if ( maxsleep >= 0 ) {
Jack Jansene8e8ae01995-01-26 16:36:45 +0000590 SystemTask();
Jack Jansene3ae0df1997-06-03 15:28:29 +0000591 }
Jack Jansenbb6d83a2000-06-02 21:27:11 +0000592#endif
Jack Jansene3ae0df1997-06-03 15:28:29 +0000593 } else {
594 latest_time_ready = LMGetTicks() + maxsleep;
Jack Jansen2d1306b2000-04-07 09:10:49 +0000595 do {
Jack Jansen0c968871997-08-26 13:20:34 +0000596 /* XXXX Hack by Jack.
597 ** In time.sleep() you can click to another application
598 ** once only. If you come back to Python you cannot get away
599 ** again.
600 **/
Jack Jansen36ed5061997-06-20 16:18:15 +0000601 gotone = WaitNextEvent(schedparams.process_events, &ev, maxsleep, NULL);
Jack Jansene3ae0df1997-06-03 15:28:29 +0000602 /* Get out quickly if nothing interesting is happening */
603 if ( !gotone || ev.what == nullEvent )
604 break;
Jack Jansen36ed5061997-06-20 16:18:15 +0000605 if ( PyMac_HandleEvent(&ev) < 0 ) {
606 in_here--;
607 return -1;
608 }
Jack Jansene3ae0df1997-06-03 15:28:29 +0000609 maxsleep = latest_time_ready - LMGetTicks();
Jack Jansen2d1306b2000-04-07 09:10:49 +0000610 } while ( maxsleep > 0 );
Jack Jansenf93c72a1994-12-14 14:07:50 +0000611 }
Jack Jansen36ed5061997-06-20 16:18:15 +0000612 in_here--;
613 return 0;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000614}
615
616/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000617** Process events and/or yield the CPU to other tasks if opportune
Jack Jansene8e8ae01995-01-26 16:36:45 +0000618*/
Jack Jansen36ed5061997-06-20 16:18:15 +0000619int
Jack Jansene8e8ae01995-01-26 16:36:45 +0000620PyMac_Yield() {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000621 unsigned long maxsleep;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000622
Jack Jansene3ae0df1997-06-03 15:28:29 +0000623 if( PyMac_InForeground() )
624 maxsleep = 0;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000625 else
Jack Jansene3ae0df1997-06-03 15:28:29 +0000626 maxsleep = schedparams.bg_yield;
627
Jack Jansen36ed5061997-06-20 16:18:15 +0000628 return PyMac_DoYield(maxsleep, 1);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000629}
630
631/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000632** Return current scheduler parameters
Jack Jansene8e8ae01995-01-26 16:36:45 +0000633*/
Jack Jansene3ae0df1997-06-03 15:28:29 +0000634void
635PyMac_GetSchedParams(PyMacSchedParams *sp)
Jack Jansene8e8ae01995-01-26 16:36:45 +0000636{
Jack Jansene3ae0df1997-06-03 15:28:29 +0000637 sp->check_interrupt = schedparams.check_interrupt;
638 sp->process_events = schedparams.process_events;
639 sp->besocial = schedparams.besocial;
640 sp->check_interval = schedparams.check_interval / 60.0;
641 sp->bg_yield = schedparams.bg_yield / 60.0;
Jack Jansenf93c72a1994-12-14 14:07:50 +0000642}
Jack Jansenf6865f71996-09-04 15:24:59 +0000643
Jack Jansen74162f31995-02-15 22:58:33 +0000644/*
Jack Jansene3ae0df1997-06-03 15:28:29 +0000645** Set current scheduler parameters
646*/
647void
648PyMac_SetSchedParams(PyMacSchedParams *sp)
649{
650 schedparams.check_interrupt = sp->check_interrupt;
651 schedparams.process_events = sp->process_events;
652 schedparams.besocial = sp->besocial;
653 schedparams.check_interval = (unsigned long)(sp->check_interval*60);
654 schedparams.bg_yield = (unsigned long)(sp->bg_yield*60);
655 if ( schedparams.check_interrupt || schedparams.process_events ||
656 schedparams.besocial )
657 schedparams.enabled = 1;
658 else
659 schedparams.enabled = 0;
660 schedparams.next_check = 0; /* Check immedeately */
661}
Jack Jansencaa7c461997-06-12 10:49:13 +0000662
Jack Jansene3ae0df1997-06-03 15:28:29 +0000663/*
Jack Jansen3469e991996-09-06 00:30:45 +0000664** Install our menu bar.
665*/
666void
667PyMac_InitMenuBar()
668{
Jack Jansen3469e991996-09-06 00:30:45 +0000669 MenuHandle applemenu;
670
Jack Jansencaa7c461997-06-12 10:49:13 +0000671 if ( (sioux_mbar=GetMenuBar()) == NULL ) {
672 /* Sioux menu not installed yet. Do so */
673 SIOUXSetupMenus();
674 if ( (sioux_mbar=GetMenuBar()) == NULL )
675 return;
676 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000677 if ( (applemenu=GetMenuHandle(SIOUX_APPLEID)) == NULL ) return;
Jack Jansen3469e991996-09-06 00:30:45 +0000678 SetMenuItemText(applemenu, 1, "\pAbout Python...");
679}
680
681/*
Jack Jansencaa7c461997-06-12 10:49:13 +0000682** Restore sioux menu bar
683*/
684void
685PyMac_RestoreMenuBar()
686{
Jack Janseneda78631997-06-12 15:29:46 +0000687 if ( sioux_mbar ) {
Jack Jansencaa7c461997-06-12 10:49:13 +0000688 SetMenuBar(sioux_mbar);
Jack Janseneda78631997-06-12 15:29:46 +0000689 DrawMenuBar();
Jack Jansenefaada71998-02-20 16:03:15 +0000690 } else
691 PyMac_InitMenuBar();
Jack Jansencaa7c461997-06-12 10:49:13 +0000692}
693
694
695/*
Jack Jansen3469e991996-09-06 00:30:45 +0000696** Our replacement about box
697*/
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000698
699#include "patchlevel.h"
700
Jack Jansen3469e991996-09-06 00:30:45 +0000701void
702SIOUXDoAboutBox(void)
703{
704 DialogPtr theDialog;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000705 WindowPtr theWindow;
Jack Jansen3469e991996-09-06 00:30:45 +0000706 short item;
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000707 short fontID;
Jack Jansen3469e991996-09-06 00:30:45 +0000708
709 if( (theDialog = GetNewDialog(ABOUT_ID, NULL, (WindowPtr)-1)) == NULL )
710 return;
Jack Jansend617c571996-09-22 22:14:30 +0000711 theWindow = GetDialogWindow(theDialog);
Jack Jansen7e1fb7c1998-07-31 09:36:30 +0000712 SetPortWindowPort(theWindow);
713 GetFNum("\pPython-Sans", &fontID);
714 if (fontID == 0)
715 fontID = kFontIDGeneva;
716 TextFont(fontID);
717 TextSize(9);
718 ParamText(Pstring(PATCHLEVEL), "\p", "\p", "\p");
Jack Jansend617c571996-09-22 22:14:30 +0000719 ShowWindow(theWindow);
Jack Jansen3469e991996-09-06 00:30:45 +0000720 ModalDialog(NULL, &item);
721 DisposeDialog(theDialog);
722}
723
Jack Janseneda78631997-06-12 15:29:46 +0000724#if 0
725int
726PyMac_FileExists(char *name)
727{
728 FSSpec fss;
729
730 if ( FSMakeFSSpec(0, 0, Pstring(name), &fss) == noErr )
731 return 1;
732 return 0;
733}
734#endif
735
736/*
Jack Jansen3ec804a1995-02-20 15:56:10 +0000737** Helper routine for GetDirectory
738*/
Guido van Rossum24a45e31995-02-20 23:45:53 +0000739static pascal short
Jack Jansen819f1771995-08-14 12:35:10 +0000740myhook_proc(short item, DialogPtr theDialog, struct hook_args *dataptr)
Jack Jansen3ec804a1995-02-20 15:56:10 +0000741{
Jack Jansen819f1771995-08-14 12:35:10 +0000742 if ( item == sfHookFirstCall && dataptr->prompt) {
743 Handle prompth;
744 short type;
745 Rect rect;
746
747 GetDialogItem(theDialog, PROMPT_ITEM, &type, &prompth, &rect);
748 if ( prompth )
749 SetDialogItemText(prompth, (unsigned char *)dataptr->prompt);
750 } else
Jack Jansen3ec804a1995-02-20 15:56:10 +0000751 if ( item == SELECTCUR_ITEM ) {
752 item = sfItemCancelButton;
Jack Jansen819f1771995-08-14 12:35:10 +0000753 dataptr->selectcur_hit = 1;
Jack Jansen3ec804a1995-02-20 15:56:10 +0000754 }
755 return item;
756}
Jack Jansenbb7e2132000-07-14 22:15:24 +0000757#ifndef TARGET_API_MAC_CARBON
Jack Jansen3ec804a1995-02-20 15:56:10 +0000758/*
759** Ask the user for a directory. I still can't understand
760** why Apple doesn't provide a standard solution for this...
761*/
762int
Jack Jansen819f1771995-08-14 12:35:10 +0000763PyMac_GetDirectory(dirfss, prompt)
Jack Jansen3ec804a1995-02-20 15:56:10 +0000764 FSSpec *dirfss;
Jack Jansen819f1771995-08-14 12:35:10 +0000765 char *prompt;
Jack Jansen3ec804a1995-02-20 15:56:10 +0000766{
767 static SFTypeList list = {'fldr', 0, 0, 0};
768 static Point where = {-1, -1};
Jack Jansen3ec804a1995-02-20 15:56:10 +0000769 StandardFileReply reply;
Jack Jansen819f1771995-08-14 12:35:10 +0000770 struct hook_args hook_args;
Jack Jansen3ec804a1995-02-20 15:56:10 +0000771
772 if ( !upp_inited ) {
773 myhook_upp = NewDlgHookYDProc(myhook_proc);
774 upp_inited = 1;
775 }
Jack Jansen819f1771995-08-14 12:35:10 +0000776 if ( prompt && *prompt )
777 hook_args.prompt = (char *)Pstring(prompt);
778 else
779 hook_args.prompt = NULL;
780 hook_args.selectcur_hit = 0;
Guido van Rossum24a45e31995-02-20 23:45:53 +0000781 CustomGetFile((FileFilterYDUPP)0, 1, list, &reply, GETDIR_ID, where, myhook_upp,
Jack Jansen819f1771995-08-14 12:35:10 +0000782 NULL, NULL, NULL, (void *)&hook_args);
Jack Jansen3ec804a1995-02-20 15:56:10 +0000783
784 reply.sfFile.name[0] = 0;
785 if( FSMakeFSSpec(reply.sfFile.vRefNum, reply.sfFile.parID, reply.sfFile.name, dirfss) )
786 return 0;
Jack Jansen819f1771995-08-14 12:35:10 +0000787 return hook_args.selectcur_hit;
788}
789
790/*
791** Slightly extended StandardGetFile: accepts a prompt */
792void PyMac_PromptGetFile(short numTypes, ConstSFTypeListPtr typeList,
793 StandardFileReply *reply, char *prompt)
794{
795 static Point where = {-1, -1};
796 struct hook_args hook_args;
797
798 if ( !upp_inited ) {
799 myhook_upp = NewDlgHookYDProc(myhook_proc);
800 upp_inited = 1;
801 }
802 if ( prompt && *prompt )
803 hook_args.prompt = (char *)Pstring(prompt);
804 else
805 hook_args.prompt = NULL;
806 hook_args.selectcur_hit = 0;
807 CustomGetFile((FileFilterYDUPP)0, numTypes, typeList, reply, GETFILEPROMPT_ID, where,
808 myhook_upp, NULL, NULL, NULL, (void *)&hook_args);
Jack Jansen3ec804a1995-02-20 15:56:10 +0000809}
Jack Jansenbb7e2132000-07-14 22:15:24 +0000810#endif /* TARGET_API_MAC_CARBON */
Jack Jansen5f653091995-01-18 13:53:49 +0000811
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000812/* Convert a 4-char string object argument to an OSType value */
Jack Jansen5f653091995-01-18 13:53:49 +0000813int
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000814PyMac_GetOSType(PyObject *v, OSType *pr)
Jack Jansen5f653091995-01-18 13:53:49 +0000815{
816 if (!PyString_Check(v) || PyString_Size(v) != 4) {
817 PyErr_SetString(PyExc_TypeError,
818 "OSType arg must be string of 4 chars");
819 return 0;
820 }
821 memcpy((char *)pr, PyString_AsString(v), 4);
822 return 1;
823}
824
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000825/* Convert an OSType value to a 4-char string object */
826PyObject *
827PyMac_BuildOSType(OSType t)
828{
829 return PyString_FromStringAndSize((char *)&t, 4);
830}
831
Jack Jansend1f06311996-08-01 15:23:54 +0000832/* Convert an NumVersion value to a 4-element tuple */
833PyObject *
834PyMac_BuildNumVersion(NumVersion t)
835{
836 return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
837}
838
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000839
840/* Convert a Python string object to a Str255 */
Jack Jansen5f653091995-01-18 13:53:49 +0000841int
Guido van Rossum8f691791995-01-18 23:57:26 +0000842PyMac_GetStr255(PyObject *v, Str255 pbuf)
Jack Jansen5f653091995-01-18 13:53:49 +0000843{
844 int len;
845 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
846 PyErr_SetString(PyExc_TypeError,
847 "Str255 arg must be string of at most 255 chars");
848 return 0;
849 }
850 pbuf[0] = len;
851 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
852 return 1;
853}
854
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000855/* Convert a Str255 to a Python string object */
856PyObject *
857PyMac_BuildStr255(Str255 s)
858{
Jack Jansenb734ade1999-12-17 17:15:50 +0000859 if ( s == NULL ) {
860 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
861 return NULL;
862 }
863 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
864}
865
866PyObject *
867PyMac_BuildOptStr255(Str255 s)
868{
869 if ( s == NULL ) {
870 Py_INCREF(Py_None);
871 return Py_None;
872 }
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000873 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
874}
875
876
Jack Jansen5f653091995-01-18 13:53:49 +0000877/*
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000878** Convert a Python object to an FSSpec.
879** The object may either be a full pathname or a triple
880** (vrefnum, dirid, path).
Jack Jansen5f653091995-01-18 13:53:49 +0000881** NOTE: This routine will fail on pre-sys7 machines.
882** The caller is responsible for not calling this routine
883** in those cases (which is fine, since everyone calling
884** this is probably sys7 dependent anyway).
885*/
886int
Guido van Rossum8f691791995-01-18 23:57:26 +0000887PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
Jack Jansen5f653091995-01-18 13:53:49 +0000888{
889 Str255 path;
890 short refnum;
891 long parid;
892 OSErr err;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000893 FSSpec *fs2;
Jack Jansen5f653091995-01-18 13:53:49 +0000894
Jack Jansene8e8ae01995-01-26 16:36:45 +0000895 /* first check whether it already is an FSSpec */
896 fs2 = mfs_GetFSSpecFSSpec(v);
897 if ( fs2 ) {
Jack Jansen3ec804a1995-02-20 15:56:10 +0000898 (void)FSMakeFSSpec(fs2->vRefNum, fs2->parID, fs2->name, fs);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000899 return 1;
900 }
Jack Jansen5f653091995-01-18 13:53:49 +0000901 if ( PyString_Check(v) ) {
902 /* It's a pathname */
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000903 if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
Jack Jansen5f653091995-01-18 13:53:49 +0000904 return 0;
Jack Jansen378815c1996-03-06 16:21:34 +0000905 refnum = 0; /* XXXX Should get CurWD here?? */
Jack Jansen5f653091995-01-18 13:53:49 +0000906 parid = 0;
907 } else {
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000908 if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (vrefnum,dirid,path)",
909 &refnum, &parid, PyMac_GetStr255, &path)) {
Jack Jansen5f653091995-01-18 13:53:49 +0000910 return 0;
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000911 }
Jack Jansen5f653091995-01-18 13:53:49 +0000912 }
913 err = FSMakeFSSpec(refnum, parid, path, fs);
914 if ( err && err != fnfErr ) {
Jack Jansen3d757542000-01-24 09:56:06 +0000915 PyMac_Error(err);
Jack Jansen5f653091995-01-18 13:53:49 +0000916 return 0;
917 }
918 return 1;
919}
920
Jack Jansen8bb573e1999-12-12 21:37:14 +0000921/* Convert FSSpec to PyObject */
922PyObject *PyMac_BuildFSSpec(FSSpec *v)
923{
924 return newmfssobject(v);
925}
Guido van Rossum8f691791995-01-18 23:57:26 +0000926
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000927/* Convert a Python object to a Rect.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000928 The object must be a (left, top, right, bottom) tuple.
929 (This differs from the order in the struct but is consistent with
930 the arguments to SetRect(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000931int
932PyMac_GetRect(PyObject *v, Rect *r)
Guido van Rossum8f691791995-01-18 23:57:26 +0000933{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000934 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
Guido van Rossum8f691791995-01-18 23:57:26 +0000935}
Guido van Rossumb3404661995-01-22 18:36:13 +0000936
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000937/* Convert a Rect to a Python object */
Guido van Rossumb3404661995-01-22 18:36:13 +0000938PyObject *
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000939PyMac_BuildRect(Rect *r)
Guido van Rossumb3404661995-01-22 18:36:13 +0000940{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000941 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000942}
943
944
945/* Convert a Python object to a Point.
Guido van Rossum5279ec61995-01-26 22:56:59 +0000946 The object must be a (h, v) tuple.
947 (This differs from the order in the struct but is consistent with
948 the arguments to SetPoint(), and also with STDWIN). */
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000949int
950PyMac_GetPoint(PyObject *v, Point *p)
951{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000952 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000953}
954
955/* Convert a Point to a Python object */
956PyObject *
957PyMac_BuildPoint(Point p)
958{
Guido van Rossum5279ec61995-01-26 22:56:59 +0000959 return Py_BuildValue("(hh)", p.h, p.v);
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000960}
961
962
963/* Convert a Python object to an EventRecord.
964 The object must be a (what, message, when, (v, h), modifiers) tuple. */
965int
966PyMac_GetEventRecord(PyObject *v, EventRecord *e)
967{
968 return PyArg_Parse(v, "(hll(hh)h)",
969 &e->what,
970 &e->message,
971 &e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000972 &e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000973 &e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000974 &e->modifiers);
975}
976
977/* Convert a Rect to an EventRecord object */
978PyObject *
979PyMac_BuildEventRecord(EventRecord *e)
980{
981 return Py_BuildValue("(hll(hh)h)",
982 e->what,
983 e->message,
984 e->when,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000985 e->where.h,
Guido van Rossum5279ec61995-01-26 22:56:59 +0000986 e->where.v,
Guido van Rossumcf27c2d1995-01-25 23:06:44 +0000987 e->modifiers);
Guido van Rossumb3404661995-01-22 18:36:13 +0000988}
Jack Jansenfa4d5d01995-11-15 15:19:29 +0000989
990/* Convert Python object to Fixed */
991int
992PyMac_GetFixed(PyObject *v, Fixed *f)
993{
994 double d;
995
996 if( !PyArg_Parse(v, "d", &d))
997 return 0;
998 *f = (Fixed)(d * 0x10000);
Jack Jansen31dd5c01996-05-31 13:01:39 +0000999 return 1;
Jack Jansenfa4d5d01995-11-15 15:19:29 +00001000}
1001
1002/* Convert a Point to a Python object */
1003PyObject *
1004PyMac_BuildFixed(Fixed f)
1005{
1006 double d;
1007
1008 d = f;
1009 d = d / 0x10000;
1010 return Py_BuildValue("d", d);
1011}
1012
Jack Jansend58cd631998-04-21 15:24:39 +00001013/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
1014int
1015PyMac_Getwide(PyObject *v, wide *rv)
1016{
1017 if (PyInt_Check(v)) {
1018 rv->hi = 0;
1019 rv->lo = PyInt_AsLong(v);
1020 if( rv->lo & 0x80000000 )
1021 rv->hi = -1;
1022 return 1;
1023 }
1024 return PyArg_Parse(v, "(ll)", &rv->hi, &rv->lo);
1025}
1026
1027
1028PyObject *
Jack Jansenbbf4be21998-04-23 13:20:17 +00001029PyMac_Buildwide(wide *w)
Jack Jansend58cd631998-04-21 15:24:39 +00001030{
Jack Jansenbbf4be21998-04-23 13:20:17 +00001031 if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
1032 (w->hi == -1 && (w->lo & 0x80000000) ) )
1033 return PyInt_FromLong(w->lo);
1034 return Py_BuildValue("(ll)", w->hi, w->lo);
Jack Jansend58cd631998-04-21 15:24:39 +00001035}