1/* 2 * Functions that return arrays by indirection, something that cannot be 3 * described by the metadata. 4 */ 5#include <Python.h> 6#include "pyobjc-api.h" 7 8#import <ApplicationServices/ApplicationServices.h> 9 10static PyObject* 11m_CGWaitForScreenRefreshRects(PyObject* self __attribute__((__unused__)), 12 PyObject* args) 13{ 14 CGRect* rectArray = NULL; 15 CGRectCount count = 0; 16 CGError err; 17 18 if (PyTuple_GET_SIZE(args) == 2) { 19 if (PyTuple_GET_ITEM(args, 0) != Py_None) { 20 PyErr_SetString(PyExc_ValueError, "pRectArray"); 21 return NULL; 22 } 23 if (PyTuple_GET_ITEM(args, 1) != Py_None) { 24 PyErr_SetString(PyExc_ValueError, "pCount"); 25 return NULL; 26 } 27 } 28 29 PyObjC_DURING 30 err = CGWaitForScreenRefreshRects(&rectArray, &count); 31 32 PyObjC_HANDLER 33 PyObjCErr_FromObjC(localException); 34 PyObjC_ENDHANDLER 35 36 if (PyErr_Occurred()) { 37 return NULL; 38 } 39 40 if (err == kCGErrorSuccess) { 41 /* Build the array */ 42 PyObject* arr = PyObjC_CArrayToPython( 43 @encode(CGRect), rectArray, count); 44 if (arr == NULL) { 45 return NULL; 46 } 47 48 /* Free the C-level array */ 49 CGReleaseScreenRefreshRects(rectArray); 50 51 return Py_BuildValue("lNl", err, arr, count); 52 } 53 54 return Py_BuildValue("lOO", err, Py_None, Py_None); 55} 56 57static PyObject* 58m_CGWaitForScreenUpdateRects(PyObject* self __attribute__((__unused__)), 59 PyObject* args) 60{ 61 CGRect* rectArray = NULL; 62 size_t count = 0; 63 CGScreenUpdateOperation requestedOperations; 64 CGScreenUpdateOperation currentOperation; 65 CGScreenUpdateMoveDelta delta; 66 CGError err; 67 PyObject* py_ops; 68 69 if (!PyArg_ParseTuple(args, "O", &py_ops)) { 70 PyObject* py_curop; 71 PyObject* py_rectarr; 72 PyObject* py_count; 73 PyObject* py_delta; 74 75 if (!PyArg_ParseTuple(args, "OOOOO", &py_ops, &py_curop, &py_rectarr, &py_count, &py_delta)) { 76 return NULL; 77 } 78 79 if (py_curop != Py_None) { 80 PyErr_SetString(PyExc_ValueError, "currentOperation != None"); 81 return NULL; 82 } 83 if (py_rectarr != Py_None) { 84 PyErr_SetString(PyExc_ValueError, "pRectArray != None"); 85 return NULL; 86 } 87 if (py_count != Py_None) { 88 PyErr_SetString(PyExc_ValueError, "pCount != None"); 89 return NULL; 90 } 91 if (py_delta != Py_None) { 92 PyErr_SetString(PyExc_ValueError, "pDelta != None"); 93 return NULL; 94 } 95 } 96 97 if (PyObjC_PythonToObjC(@encode(CGScreenUpdateOperation), py_ops, &requestedOperations) < 0) { 98 return NULL; 99 } 100 101 PyObjC_DURING 102 err = CGWaitForScreenUpdateRects( 103 requestedOperations, 104 ¤tOperation, 105 &rectArray, &count, 106 &delta); 107 108 PyObjC_HANDLER 109 err = -1; /* Avoid compiler warning */ 110 PyObjCErr_FromObjC(localException); 111 PyObjC_ENDHANDLER 112 113 if (PyErr_Occurred()) { 114 return NULL; 115 } 116 117 if (err == kCGErrorSuccess) { 118 /* Build the array */ 119 PyObject* arr = PyObjC_CArrayToPython( 120 @encode(CGRect), rectArray, count); 121 if (arr == NULL) { 122 return NULL; 123 } 124 PyObject* dlt = PyObjC_ObjCToPython( 125 @encode(CGScreenUpdateMoveDelta), &delta); 126 if (dlt == NULL) { 127 return NULL; 128 } 129 130 /* Free the C-level array */ 131 CGReleaseScreenRefreshRects(rectArray); 132 133 return Py_BuildValue("llNl", err, currentOperation, arr, count, dlt); 134 } 135 136 return Py_BuildValue("lOOOO", err, Py_None, Py_None, Py_None, Py_None); 137} 138 139static PyObject* 140m_CGReleaseScreenRefreshRects( 141 PyObject* self __attribute__((__unused__)), 142 PyObject* args) 143{ 144 PyObject* array; 145 146 if (!PyArg_Parse(args, "O", &array)) { 147 return NULL; 148 } 149 150 /* Do nothing, our wrappers for CGWaitForScreenRefreshRects and 151 * CGWaitForScreenUpdateRects have already released the real array. 152 */ 153 154 Py_INCREF(Py_None); 155 return Py_None; 156} 157 158 159static PyMethodDef mod_methods[] = { 160 { 161 "CGWaitForScreenRefreshRects", 162 (PyCFunction)m_CGWaitForScreenRefreshRects, 163 METH_VARARGS, 164 NULL 165 }, 166 { 167 "CGWaitForScreenUpdateRects", 168 (PyCFunction)m_CGWaitForScreenUpdateRects, 169 METH_VARARGS, 170 NULL 171 }, 172 { 173 "CGReleaseScreenRefreshRects", 174 (PyCFunction)m_CGReleaseScreenRefreshRects, 175 METH_VARARGS, 176 NULL 177 }, 178 179 180 { 0, 0, 0, 0 } 181}; 182 183PyObjC_MODULE_INIT(_doubleindirect) 184{ 185 PyObject* m = PyObjC_MODULE_CREATE(_doubleindirect); 186 187 if (PyObjC_ImportAPI(m) < 0) PyObjC_INITERROR(); 188 189 PyObjC_INITDONE(); 190} 191