Home | History | Annotate | Download | only in carbonevt
      1 # IBCarbonsupport.py
      2 
      3 from macsupport import *
      4 
      5 from CarbonEvtscan import RefObjectTypes
      6 
      7 # where should this go? macsupport.py?
      8 CFStringRef = OpaqueByValueType('CFStringRef')
      9 
     10 for typ in RefObjectTypes:
     11     execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ}
     12     exec execstr
     13 
     14 
     15 if 0:
     16     # these types will have no methods and will merely be opaque blobs
     17     # should write getattr and setattr for them?
     18 
     19     StructObjectTypes = ["EventTypeSpec",
     20                                             "HIPoint",
     21                                             "HICommand",
     22                                             "EventHotKeyID",
     23                                             ]
     24 
     25     for typ in StructObjectTypes:
     26         execstr = "%(name)s = OpaqueType('%(name)s')" % {"name": typ}
     27         exec execstr
     28 
     29 EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID")
     30 EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec")
     31 
     32 # is this the right type for the void * in GetEventParameter
     33 #void_ptr = FixedInputBufferType(1024)
     34 void_ptr = stringptr
     35 # here are some types that are really other types
     36 
     37 class MyVarInputBufferType(VarInputBufferType):
     38     def passInput(self, name):
     39         return "%s__len__, %s__in__" % (name, name)
     40 
     41 MyInBuffer = MyVarInputBufferType('char', 'long', 'l')          # (buf, len)
     42 
     43 EventTime = double
     44 EventTimeout = EventTime
     45 EventTimerInterval = EventTime
     46 EventAttributes = UInt32
     47 EventParamName = OSType
     48 EventParamType = OSType
     49 EventPriority = SInt16
     50 EventMask = UInt16
     51 
     52 EventComparatorUPP = FakeType("(EventComparatorUPP)0")
     53 EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0")
     54 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
     55 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
     56 EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0")
     57 EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0")
     58 EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0")
     59 
     60 CarbonEventsFunction = OSErrFunctionGenerator
     61 CarbonEventsMethod = OSErrMethodGenerator
     62 
     63 class EventHandlerRefMethod(OSErrMethodGenerator):
     64     def precheck(self):
     65         OutLbrace('if (_self->ob_itself == NULL)')
     66         Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");')
     67         Output('return NULL;')
     68         OutRbrace()
     69 
     70 
     71 RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
     72 GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
     73 MouseTrackingResult = UInt16
     74 
     75 
     76 includestuff = includestuff + r"""
     77 #include <Carbon/Carbon.h>
     78 
     79 extern int CFStringRef_New(CFStringRef *);
     80 
     81 extern int CFStringRef_Convert(PyObject *, CFStringRef *);
     82 extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
     83 
     84 int EventTargetRef_Convert(PyObject *, EventTargetRef *);
     85 PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
     86 PyObject *EventRef_New(EventRef itself);
     87 
     88 /********** EventTypeSpec *******/
     89 static PyObject*
     90 EventTypeSpec_New(EventTypeSpec *in)
     91 {
     92         return Py_BuildValue("ll", in->eventClass, in->eventKind);
     93 }
     94 
     95 static int
     96 EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
     97 {
     98         if (PyArg_Parse(v, "(O&l)",
     99                         PyMac_GetOSType, &(out->eventClass),
    100                         &(out->eventKind)))
    101                 return 1;
    102         return NULL;
    103 }
    104 
    105 /********** end EventTypeSpec *******/
    106 
    107 /********** HIPoint *******/
    108 
    109 #if 0  /* XXX doesn't compile */
    110 static PyObject*
    111 HIPoint_New(HIPoint *in)
    112 {
    113         return Py_BuildValue("ff", in->x, in->y);
    114 }
    115 
    116 static int
    117 HIPoint_Convert(PyObject *v, HIPoint *out)
    118 {
    119         if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
    120                 return 1;
    121         return NULL;
    122 }
    123 #endif
    124 
    125 /********** end HIPoint *******/
    126 
    127 /********** EventHotKeyID *******/
    128 
    129 static PyObject*
    130 EventHotKeyID_New(EventHotKeyID *in)
    131 {
    132         return Py_BuildValue("ll", in->signature, in->id);
    133 }
    134 
    135 static int
    136 EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
    137 {
    138         if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
    139                 return 1;
    140         return NULL;
    141 }
    142 
    143 /********** end EventHotKeyID *******/
    144 
    145 /******** myEventHandler ***********/
    146 
    147 static EventHandlerUPP myEventHandlerUPP;
    148 
    149 static pascal OSStatus
    150 myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
    151         PyObject *retValue;
    152         int status;
    153 
    154         retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&",
    155                                          EventHandlerCallRef_New, handlerRef,
    156                                          EventRef_New, event);
    157         if (retValue == NULL) {
    158                 PySys_WriteStderr("Error in event handler callback:\n");
    159                 PyErr_Print();  /* this also clears the error */
    160                 status = noErr; /* complain? how? */
    161         } else {
    162                 if (retValue == Py_None)
    163                         status = noErr;
    164                 else if (PyInt_Check(retValue)) {
    165                         status = PyInt_AsLong(retValue);
    166                 } else
    167                         status = noErr; /* wrong object type, complain? */
    168                 Py_DECREF(retValue);
    169         }
    170 
    171         return status;
    172 }
    173 
    174 /******** end myEventHandler ***********/
    175 
    176 """
    177 
    178 initstuff = initstuff + """
    179 myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
    180 """
    181 module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
    182 
    183 
    184 
    185 
    186 class EventHandlerRefObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
    187     def outputStructMembers(self):
    188         Output("%s ob_itself;", self.itselftype)
    189         Output("PyObject *ob_callback;")
    190     def outputInitStructMembers(self):
    191         Output("it->ob_itself = %sitself;", self.argref)
    192         Output("it->ob_callback = NULL;")
    193     def outputFreeIt(self, name):
    194         OutLbrace("if (self->ob_itself != NULL)")
    195         Output("RemoveEventHandler(self->ob_itself);")
    196         Output("Py_DECREF(self->ob_callback);")
    197         OutRbrace()
    198 
    199 class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
    200     pass
    201 
    202 for typ in RefObjectTypes:
    203     if typ == 'EventHandlerRef':
    204         EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef')
    205     else:
    206         execstr = typ + 'object = MyGlobalObjectDefinition(typ)'
    207         exec execstr
    208     module.addobject(eval(typ + 'object'))
    209 
    210 
    211 functions = []
    212 for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
    213     # initialize the lists for carbongen to fill
    214     execstr = typ + 'methods = []'
    215     exec execstr
    216 
    217 execfile('CarbonEventsgen.py')
    218 
    219 
    220 
    221 for f in functions: module.add(f)       # add all the functions carboneventsgen put in the list
    222 
    223 for typ in RefObjectTypes:                               ## go thru all ObjectTypes as defined in CarbonEventsscan.py
    224     methods = eval(typ + 'methods')  ## get a reference to the method list from the main namespace
    225     obj = eval(typ + 'object')                ## get a reference to the object
    226     for m in methods: obj.add(m)    ## add each method in the list to the object
    227 
    228 
    229 removeeventhandler = """
    230 OSStatus _err;
    231 if (_self->ob_itself == NULL) {
    232         PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
    233         return NULL;
    234 }
    235 if (!PyArg_ParseTuple(_args, ""))
    236         return NULL;
    237 _err = RemoveEventHandler(_self->ob_itself);
    238 if (_err != noErr) return PyMac_Error(_err);
    239 _self->ob_itself = NULL;
    240 Py_DECREF(_self->ob_callback);
    241 _self->ob_callback = NULL;
    242 Py_INCREF(Py_None);
    243 _res = Py_None;
    244 return _res;"""
    245 
    246 f = ManualGenerator("RemoveEventHandler", removeeventhandler);
    247 f.docstring = lambda: "() -> None"
    248 EventHandlerRefobject.add(f)
    249 
    250 
    251 installeventhandler = """
    252 EventTypeSpec inSpec;
    253 PyObject *callback;
    254 EventHandlerRef outRef;
    255 OSStatus _err;
    256 
    257 if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
    258         return NULL;
    259 
    260 _err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
    261 if (_err != noErr) return PyMac_Error(_err);
    262 
    263 _res = EventHandlerRef_New(outRef);
    264 if (_res != NULL) {
    265         ((EventHandlerRefObject*)_res)->ob_callback = callback;
    266         Py_INCREF(callback);
    267 }
    268 return _res;"""
    269 
    270 f = ManualGenerator("InstallEventHandler", installeventhandler);
    271 f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
    272 EventTargetRefobject.add(f)
    273 
    274 # This may not be the best, but at least it lets you get the raw data back into python as a string. You'll have to cut it up yourself and parse the result.
    275 
    276 geteventparameter = """
    277 UInt32 bufferSize;
    278 EventParamName inName;
    279 EventParamType inType;
    280 OSErr _err;
    281 void * buffer;
    282 
    283 if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
    284       return NULL;
    285 
    286 /* Figure out the size by passing a null buffer to GetEventParameter */
    287 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
    288 
    289 if (_err != noErr)
    290       return PyMac_Error(_err);
    291 buffer = PyMem_NEW(char, bufferSize);
    292 if (buffer == NULL)
    293       return PyErr_NoMemory();
    294 
    295 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
    296 
    297 if (_err != noErr) {
    298       PyMem_DEL(buffer);
    299       return PyMac_Error(_err);
    300 }
    301 _res = Py_BuildValue("s#", buffer, bufferSize);
    302 PyMem_DEL(buffer);
    303 return _res;
    304 """
    305 
    306 f = ManualGenerator("GetEventParameter", geteventparameter);
    307 f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
    308 EventRefobject.add(f)
    309 
    310 SetOutputFileName('_CarbonEvtmodule.c')
    311 module.generate()
    312 
    313 ##import os
    314 ##os.system("python setup.py build")
    315