mirror of
https://github.com/python/cpython.git
synced 2024-11-27 23:47:29 +01:00
203 lines
5.0 KiB
C
203 lines
5.0 KiB
C
/***********************************************************
|
|
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
|
|
The Netherlands.
|
|
|
|
All Rights Reserved
|
|
|
|
Permission to use, copy, modify, and distribute this software and its
|
|
documentation for any purpose and without fee is hereby granted,
|
|
provided that the above copyright notice appear in all copies and that
|
|
both that copyright notice and this permission notice appear in
|
|
supporting documentation, and that the names of Stichting Mathematisch
|
|
Centrum or CWI not be used in advertising or publicity pertaining to
|
|
distribution of the software without specific, written prior permission.
|
|
|
|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
******************************************************************/
|
|
|
|
#include "Python.h"
|
|
#include "macglue.h"
|
|
|
|
#include <OSUtils.h> /* for Set(Current)A5 */
|
|
#include <Resources.h>
|
|
#include <Memory.h>
|
|
#include <Events.h>
|
|
#include <Windows.h>
|
|
#include <Desk.h>
|
|
|
|
/* XXX We should include Errors.h here, but it has a name conflict
|
|
** with the python errors.h. */
|
|
#define fnfErr -43
|
|
|
|
/* Convert C to Pascal string. Returns pointer to static buffer. */
|
|
unsigned char *
|
|
Pstring(char *str)
|
|
{
|
|
static Str255 buf;
|
|
int len;
|
|
|
|
len = strlen(str);
|
|
if (len > 255)
|
|
len = 255;
|
|
buf[0] = (unsigned char)len;
|
|
strncpy((char *)buf+1, str, len);
|
|
return buf;
|
|
}
|
|
|
|
/* Replace strerror with something that might work */
|
|
char *macstrerror(int err)
|
|
{
|
|
static char buf[256];
|
|
Handle h;
|
|
char *str;
|
|
|
|
h = GetResource('Estr', err);
|
|
if ( h ) {
|
|
HLock(h);
|
|
str = (char *)*h;
|
|
memcpy(buf, str+1, (unsigned char)str[0]);
|
|
HUnlock(h);
|
|
ReleaseResource(h);
|
|
} else {
|
|
sprintf(buf, "Mac OS error code %d", err);
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
/* Set a MAC-specific error from errno, and return NULL; return None if no error */
|
|
PyObject *
|
|
PyErr_Mac(PyObject *eobj, int err)
|
|
{
|
|
char *msg;
|
|
PyObject *v;
|
|
|
|
if (err == 0 && !PyErr_Occurred()) {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
if (err == -1 && PyErr_Occurred())
|
|
return NULL;
|
|
msg = macstrerror(err);
|
|
v = Py_BuildValue("(is)", err, msg);
|
|
PyErr_SetObject(eobj, v);
|
|
Py_DECREF(v);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
** Idle routine for busy-wait loops.
|
|
** This is rather tricky: if we see an event we check whether it is
|
|
** for somebody else (i.e. a click outside our windows) and, if so,
|
|
** we pass the event on (so the user can switch processes). However,
|
|
** by doing this we loose events meant for our windows. Too bad, I guess...
|
|
*/
|
|
int
|
|
PyMac_Idle()
|
|
{
|
|
EventRecord ev;
|
|
WindowPtr wp;
|
|
|
|
SystemTask();
|
|
if ( intrpeek() )
|
|
return 0;
|
|
if ( GetNextEvent(0xffff, &ev) ) {
|
|
if ( ev.what == mouseDown ) {
|
|
if ( FindWindow(ev.where, &wp) == inSysWindow )
|
|
SystemClick(&ev, wp);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* Convert a ResType argument */
|
|
int
|
|
PyMac_GetOSType(PyObject *v, ResType *pr)
|
|
{
|
|
if (!PyString_Check(v) || PyString_Size(v) != 4) {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"OSType arg must be string of 4 chars");
|
|
return 0;
|
|
}
|
|
memcpy((char *)pr, PyString_AsString(v), 4);
|
|
return 1;
|
|
}
|
|
|
|
/* Convert a Python string to a Str255 */
|
|
int
|
|
PyMac_GetStr255(PyObject *v, Str255 pbuf)
|
|
{
|
|
int len;
|
|
if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"Str255 arg must be string of at most 255 chars");
|
|
return 0;
|
|
}
|
|
pbuf[0] = len;
|
|
memcpy((char *)(pbuf+1), PyString_AsString(v), len);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
** Convert anything resembling an FSSpec argument
|
|
** NOTE: This routine will fail on pre-sys7 machines.
|
|
** The caller is responsible for not calling this routine
|
|
** in those cases (which is fine, since everyone calling
|
|
** this is probably sys7 dependent anyway).
|
|
*/
|
|
int
|
|
PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
|
|
{
|
|
Str255 path;
|
|
short refnum;
|
|
long parid;
|
|
OSErr err;
|
|
|
|
if ( PyString_Check(v) ) {
|
|
/* It's a pathname */
|
|
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
|
|
return 0;
|
|
refnum = 0; /* XXXX Should get CurWD here... */
|
|
parid = 0;
|
|
} else {
|
|
if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (vrefnum,dirid,path)",
|
|
&refnum, &parid, PyMac_GetStr255, &path)) {
|
|
return 0;
|
|
}
|
|
}
|
|
err = FSMakeFSSpec(refnum, parid, path, fs);
|
|
if ( err && err != fnfErr ) {
|
|
PyErr_Mac(PyExc_ValueError, err);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/* Return a Python object that describes an FSSpec */
|
|
PyObject *
|
|
PyMac_BuildFSSpec(FSSpec *fs)
|
|
{
|
|
return Py_BuildValue("(iis#)", fs->vRefNum, fs->parID, &fs->name[1], fs->name[0]);
|
|
}
|
|
|
|
/* Convert an OSType value to a 4-char string object */
|
|
PyObject *
|
|
PyMac_BuildOSType(OSType t)
|
|
{
|
|
return PyString_FromStringAndSize((char *)&t, 4);
|
|
}
|
|
|
|
/* Convert a Str255 to a Python string */
|
|
PyObject *
|
|
PyMac_BuildStr255(Str255 s)
|
|
{
|
|
return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
|
|
}
|