From 420ed40344768adac305a6ff76baced021d6fffd Mon Sep 17 00:00:00 2001 From: Jack Jansen Date: Mon, 31 Dec 2001 14:52:03 +0000 Subject: [PATCH] Added support for the Carbon scrap manager (finally). --- Mac/Modules/scrap/_Scrapmodule.c | 364 ++++++++++++++++++++++++------ Mac/Modules/scrap/scrapscan.py | 13 +- Mac/Modules/scrap/scrapsupport.py | 14 ++ 3 files changed, 315 insertions(+), 76 deletions(-) diff --git a/Mac/Modules/scrap/_Scrapmodule.c b/Mac/Modules/scrap/_Scrapmodule.c index 3acfb81b141..cc48a811d54 100644 --- a/Mac/Modules/scrap/_Scrapmodule.c +++ b/Mac/Modules/scrap/_Scrapmodule.c @@ -1,12 +1,24 @@ -/* ========================== Module Scrap ========================== */ +/* ========================= Module _Scrap ========================== */ #include "Python.h" +#ifdef _WIN32 +#include "pywintoolbox.h" +#else #include "macglue.h" #include "pymactoolbox.h" +#endif + +/* Macro to test whether a weak-loaded CFM function exists */ +#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ + PyErr_SetString(PyExc_NotImplementedError, \ + "Not available in this shared library/OS version"); \ + return NULL; \ + }} while(0) + #ifdef WITHOUT_FRAMEWORKS #include @@ -14,7 +26,7 @@ #include #endif -#if !TARGET_API_MAC_CARBON +#if TARGET_API_MAC_OS8 /* ** Generate ScrapInfo records @@ -32,9 +44,242 @@ SCRRec_New(itself) static PyObject *Scrap_Error; -static PyObject *Scrap_LoadScrap(_self, _args) - PyObject *_self; - PyObject *_args; +#if !TARGET_API_MAC_OS8 +/* ----------------------- Object type Scrap ------------------------ */ + +PyTypeObject Scrap_Type; + +#define ScrapObj_Check(x) ((x)->ob_type == &Scrap_Type) + +typedef struct ScrapObject { + PyObject_HEAD + ScrapRef ob_itself; +} ScrapObject; + +PyObject *ScrapObj_New(ScrapRef itself) +{ + ScrapObject *it; + it = PyObject_NEW(ScrapObject, &Scrap_Type); + if (it == NULL) return NULL; + it->ob_itself = itself; + return (PyObject *)it; +} +int ScrapObj_Convert(PyObject *v, ScrapRef *p_itself) +{ + if (!ScrapObj_Check(v)) + { + PyErr_SetString(PyExc_TypeError, "Scrap required"); + return 0; + } + *p_itself = ((ScrapObject *)v)->ob_itself; + return 1; +} + +static void ScrapObj_dealloc(ScrapObject *self) +{ + /* Cleanup of self->ob_itself goes here */ + PyMem_DEL(self); +} + +static PyObject *ScrapObj_GetScrapFlavorFlags(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + ScrapFlavorType flavorType; + ScrapFlavorFlags flavorFlags; + if (!PyArg_ParseTuple(_args, "O&", + PyMac_GetOSType, &flavorType)) + return NULL; + _err = GetScrapFlavorFlags(_self->ob_itself, + flavorType, + &flavorFlags); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("l", + flavorFlags); + return _res; +} + +static PyObject *ScrapObj_GetScrapFlavorSize(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + ScrapFlavorType flavorType; + Size byteCount; + if (!PyArg_ParseTuple(_args, "O&", + PyMac_GetOSType, &flavorType)) + return NULL; + _err = GetScrapFlavorSize(_self->ob_itself, + flavorType, + &byteCount); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("l", + byteCount); + return _res; +} + +static PyObject *ScrapObj_GetScrapFlavorData(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + ScrapFlavorType flavorType; + Size byteCount; + + if (!PyArg_ParseTuple(_args, "O&", + PyMac_GetOSType, &flavorType)) + return NULL; + _err = GetScrapFlavorSize(_self->ob_itself, + flavorType, + &byteCount); + if (_err != noErr) return PyMac_Error(_err); + _res = PyString_FromStringAndSize(NULL, (int)byteCount); + if ( _res == NULL ) return NULL; + _err = GetScrapFlavorData(_self->ob_itself, + flavorType, + &byteCount, + PyString_AS_STRING(_res)); + if (_err != noErr) { + Py_XDECREF(_res); + return PyMac_Error(_err); + } + destination__error__: ; + return _res; +} + +static PyObject *ScrapObj_PutScrapFlavor(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + ScrapFlavorType flavorType; + ScrapFlavorFlags flavorFlags; + char *flavorData__in__; + int flavorData__in_len__; + if (!PyArg_ParseTuple(_args, "O&ls#", + PyMac_GetOSType, &flavorType, + &flavorFlags, + &flavorData__in__, &flavorData__in_len__)) + return NULL; + _err = PutScrapFlavor(_self->ob_itself, + flavorType, + flavorFlags, + (Size)flavorData__in_len__, + flavorData__in__); + if (_err != noErr) return PyMac_Error(_err); + Py_INCREF(Py_None); + _res = Py_None; + flavorData__error__: ; + return _res; +} + +static PyObject *ScrapObj_GetScrapFlavorCount(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + UInt32 infoCount; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _err = GetScrapFlavorCount(_self->ob_itself, + &infoCount); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("l", + infoCount); + return _res; +} + +static PyObject *ScrapObj_GetScrapFlavorInfoList(ScrapObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + PyObject *item; + OSStatus _err; + UInt32 infoCount; + ScrapFlavorInfo *infolist = NULL; + int i; + + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _err = GetScrapFlavorCount(_self->ob_itself, + &infoCount); + if (_err != noErr) return PyMac_Error(_err); + if (infoCount == 0) return Py_BuildValue("[]"); + + if ((infolist = (ScrapFlavorInfo *)malloc(infoCount*sizeof(ScrapFlavorInfo))) == NULL ) + return PyErr_NoMemory(); + + _err = GetScrapFlavorInfoList(_self->ob_itself, &infoCount, infolist); + if (_err != noErr) { + free(infolist); + return NULL; + } + if ((_res = PyList_New(infoCount)) == NULL ) { + free(infolist); + return NULL; + } + for(i=0; i (ScrapFlavorFlags flavorFlags)"}, + {"GetScrapFlavorSize", (PyCFunction)ScrapObj_GetScrapFlavorSize, 1, + "(ScrapFlavorType flavorType) -> (Size byteCount)"}, + {"GetScrapFlavorData", (PyCFunction)ScrapObj_GetScrapFlavorData, 1, + "(ScrapFlavorType flavorType) -> string"}, + {"PutScrapFlavor", (PyCFunction)ScrapObj_PutScrapFlavor, 1, + "(ScrapFlavorType flavorType, ScrapFlavorFlags flavorFlags, Buffer flavorData) -> None"}, + {"GetScrapFlavorCount", (PyCFunction)ScrapObj_GetScrapFlavorCount, 1, + "() -> (UInt32 infoCount)"}, + {"GetScrapFlavorInfoList", (PyCFunction)ScrapObj_GetScrapFlavorInfoList, 1, + "() -> ([(ScrapFlavorType, ScrapFlavorInfo), ...])"}, + {NULL, NULL, 0} +}; + +PyMethodChain ScrapObj_chain = { ScrapObj_methods, NULL }; + +static PyObject *ScrapObj_getattr(ScrapObject *self, char *name) +{ + return Py_FindMethodInChain(&ScrapObj_chain, (PyObject *)self, name); +} + +#define ScrapObj_setattr NULL + +#define ScrapObj_compare NULL + +#define ScrapObj_repr NULL + +#define ScrapObj_hash NULL + +PyTypeObject Scrap_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "_Scrap.Scrap", /*tp_name*/ + sizeof(ScrapObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) ScrapObj_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) ScrapObj_getattr, /*tp_getattr*/ + (setattrfunc) ScrapObj_setattr, /*tp_setattr*/ + (cmpfunc) ScrapObj_compare, /*tp_compare*/ + (reprfunc) ScrapObj_repr, /*tp_repr*/ + (PyNumberMethods *)0, /* tp_as_number */ + (PySequenceMethods *)0, /* tp_as_sequence */ + (PyMappingMethods *)0, /* tp_as_mapping */ + (hashfunc) ScrapObj_hash, /*tp_hash*/ +}; + +/* --------------------- End object type Scrap ---------------------- */ +#endif /* !TARGET_API_MAC_OS8 */ + +static PyObject *Scrap_LoadScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; @@ -47,9 +292,7 @@ static PyObject *Scrap_LoadScrap(_self, _args) return _res; } -static PyObject *Scrap_UnloadScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_UnloadScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; @@ -62,11 +305,9 @@ static PyObject *Scrap_UnloadScrap(_self, _args) return _res; } -#if !TARGET_API_MAC_CARBON +#if TARGET_API_MAC_OS8 -static PyObject *Scrap_InfoScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_InfoScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; ScrapStuffPtr _rv; @@ -77,13 +318,8 @@ static PyObject *Scrap_InfoScrap(_self, _args) SCRRec_New, _rv); return _res; } -#endif -#if !TARGET_API_MAC_CARBON - -static PyObject *Scrap_GetScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_GetScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; long _rv; @@ -102,37 +338,21 @@ static PyObject *Scrap_GetScrap(_self, _args) offset); return _res; } -#endif - -static PyObject *Scrap_ZeroScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_ZeroScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; if (!PyArg_ParseTuple(_args, "")) return NULL; -#if TARGET_API_MAC_CARBON - { - ScrapRef scrap; - - _err = ClearCurrentScrap(); - if (_err != noErr) return PyMac_Error(_err); - _err = GetCurrentScrap(&scrap); - } -#else _err = ZeroScrap(); -#endif if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); _res = Py_None; return _res; } -static PyObject *Scrap_PutScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_PutScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; @@ -141,37 +361,38 @@ static PyObject *Scrap_PutScrap(_self, _args) char *sourceBuffer__in__; int sourceBuffer__len__; int sourceBuffer__in_len__; -#if TARGET_API_MAC_CARBON - ScrapRef scrap; -#endif - - if (!PyArg_ParseTuple(_args, "O&s#", + if (!PyArg_ParseTuple(_args, "lO&s#", + &sourceBufferByteCount, PyMac_GetOSType, &flavorType, &sourceBuffer__in__, &sourceBuffer__in_len__)) return NULL; - sourceBufferByteCount = sourceBuffer__in_len__; - sourceBuffer__len__ = sourceBuffer__in_len__; -#if TARGET_API_MAC_CARBON - _err = GetCurrentScrap(&scrap); - if (_err != noErr) return PyMac_Error(_err); - _err = PutScrapFlavor(scrap, flavorType, 0, sourceBufferByteCount, sourceBuffer__in__); -#else _err = PutScrap(sourceBufferByteCount, flavorType, sourceBuffer__in__); -#endif if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); _res = Py_None; sourceBuffer__error__: ; return _res; } +#endif /* TARGET_API_MAC_OS8 */ -#if TARGET_API_MAC_CARBON +#if !TARGET_API_MAC_OS8 +static PyObject *Scrap_GetCurrentScrap(PyObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + OSStatus _err; + ScrapRef scrap; + if (!PyArg_ParseTuple(_args, "")) + return NULL; + _err = GetCurrentScrap(&scrap); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("O&", + ScrapObj_New, scrap); + return _res; +} -static PyObject *Scrap_ClearCurrentScrap(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_ClearCurrentScrap(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; @@ -183,13 +404,8 @@ static PyObject *Scrap_ClearCurrentScrap(_self, _args) _res = Py_None; return _res; } -#endif -#if TARGET_API_MAC_CARBON - -static PyObject *Scrap_CallInScrapPromises(_self, _args) - PyObject *_self; - PyObject *_args; +static PyObject *Scrap_CallInScrapPromises(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; @@ -209,28 +425,22 @@ static PyMethodDef Scrap_methods[] = { {"UnloadScrap", (PyCFunction)Scrap_UnloadScrap, 1, "() -> None"}, -#if !TARGET_API_MAC_CARBON +#if TARGET_API_MAC_OS8 {"InfoScrap", (PyCFunction)Scrap_InfoScrap, 1, "() -> (ScrapStuffPtr _rv)"}, -#endif - -#if !TARGET_API_MAC_CARBON {"GetScrap", (PyCFunction)Scrap_GetScrap, 1, "(Handle destination, ScrapFlavorType flavorType) -> (long _rv, SInt32 offset)"}, -#endif - {"ZeroScrap", (PyCFunction)Scrap_ZeroScrap, 1, "() -> None"}, - {"PutScrap", (PyCFunction)Scrap_PutScrap, 1, - "(ScrapFlavorType flavorType, Buffer sourceBuffer) -> None"}, - -#if TARGET_API_MAC_CARBON - {"ClearCurrentScrap", (PyCFunction)Scrap_ClearCurrentScrap, 1, - "() -> None"}, + "(SInt32 sourceBufferByteCount, ScrapFlavorType flavorType, Buffer sourceBuffer) -> None"}, #endif -#if TARGET_API_MAC_CARBON +#if !TARGET_API_MAC_OS8 + {"GetCurrentScrap", (PyCFunction)Scrap_GetCurrentScrap, 1, + "() -> (ScrapRef scrap)"}, + {"ClearCurrentScrap", (PyCFunction)Scrap_ClearCurrentScrap, 1, + "() -> None"}, {"CallInScrapPromises", (PyCFunction)Scrap_CallInScrapPromises, 1, "() -> None"}, #endif @@ -240,7 +450,7 @@ static PyMethodDef Scrap_methods[] = { -void init_Scrap() +void init_Scrap(void) { PyObject *m; PyObject *d; @@ -254,7 +464,13 @@ void init_Scrap() if (Scrap_Error == NULL || PyDict_SetItemString(d, "Error", Scrap_Error) != 0) return; +#if !TARGET_API_MAC_OS8 + Scrap_Type.ob_type = &PyType_Type; + Py_INCREF(&Scrap_Type); + if (PyDict_SetItemString(d, "ScrapType", (PyObject *)&Scrap_Type) != 0) + Py_FatalError("can't initialize ScrapType"); +#endif } -/* ======================== End module Scrap ======================== */ +/* ======================= End module _Scrap ======================== */ diff --git a/Mac/Modules/scrap/scrapscan.py b/Mac/Modules/scrap/scrapscan.py index 0d4661f9c71..6227446c80d 100644 --- a/Mac/Modules/scrap/scrapscan.py +++ b/Mac/Modules/scrap/scrapscan.py @@ -5,7 +5,10 @@ import sys import os -BGENDIR=os.path.join(sys.prefix, ':Tools:bgen:bgen') +if os.sep == ':': + BGENDIR=os.path.join(sys.prefix, ':Tools:bgen:bgen') +else: + BGENDIR="../../../Tools/bgen/bgen" sys.path.append(BGENDIR) from scantools import Scanner from bgenlocations import TOOLBOXDIR @@ -29,10 +32,16 @@ class MyScanner(Scanner): def destination(self, type, name, arglist): classname = "Function" listname = "functions" + if arglist: + t, n, m = arglist[0] + if t == 'ScrapRef' and m == "InMode": + classname = "Method" + listname = "methods" return classname, listname def makeblacklistnames(self): return [ + "GetScrapFlavorInfoList", ] def makegreylist(self): @@ -50,7 +59,7 @@ class MyScanner(Scanner): def makeblacklisttypes(self): return [ - "ScrapRef", # For now -- This is the Carbon scrap main object + 'ScrapPromiseKeeperUPP', ] def makerepairinstructions(self): diff --git a/Mac/Modules/scrap/scrapsupport.py b/Mac/Modules/scrap/scrapsupport.py index 516b22bbe80..65525be2290 100644 --- a/Mac/Modules/scrap/scrapsupport.py +++ b/Mac/Modules/scrap/scrapsupport.py @@ -11,15 +11,19 @@ import string # Declarations that change for each manager MACHEADERFILE = 'Scrap.h' # The Apple header file MODNAME = '_Scrap' # The name of the module +OBJECTNAME = 'Scrap' # The basic name of the objects used here # The following is *usually* unchanged but may still require tuning MODPREFIX = 'Scrap' # The prefix for module-wide routines +OBJECTTYPE = OBJECTNAME + 'Ref' # The C type used to represent them +OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner OUTPUTFILE = '@' + MODNAME + "module.c" # The file generated by this program from macsupport import * # Create the type objects +ScrapRef = OpaqueByValueType(OBJECTTYPE, OBJECTPREFIX) includestuff = includestuff + """ #ifdef WITHOUT_FRAMEWORKS @@ -44,21 +48,31 @@ SCRRec_New(itself) ScrapStuffPtr = OpaqueByValueType('ScrapStuffPtr', 'SCRRec') ScrapFlavorType = OSTypeType('ScrapFlavorType') +ScrapFlavorFlags = Type('ScrapFlavorFlags', 'l') +#ScrapFlavorInfo = OpaqueType('ScrapFlavorInfo', 'ScrapFlavorInfo') putscrapbuffer = FixedInputBufferType('void *') +class MyObjectDefinition(GlobalObjectDefinition): + pass + # Create the generator groups and link them module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) +object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE) +module.addobject(object) # Create the generator classes used to populate the lists Function = OSErrFunctionGenerator +Method = OSErrMethodGenerator # Create and populate the lists functions = [] +methods = [] execfile(INPUTFILE) # add the populated lists to the generator groups # (in a different wordl the scan program would generate this) for f in functions: module.add(f) +for f in methods: object.add(f) # generate output (open the output file as late as possible) SetOutputFileName(OUTPUTFILE)