/Mac/Modules/carbonevt/CarbonEvtsupport.py

http://unladen-swallow.googlecode.com/ · Python · 314 lines · 258 code · 45 blank · 11 comment · 10 complexity · fa1c6beb09bdd6d645c54a6c9d544f28 MD5 · raw file

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