1/* 2 * Several methods of NSBezierPath cannot be handled automaticly because the 3 * size of a C-style array depends on the value of another argument. 4 */ 5 6static PyObject* 7call_NSBezierPath_elementAtIndex_associatedPoints_( 8 PyObject* method, 9 PyObject* self, PyObject* arguments) 10{ 11 PyObject* result; 12 PyObject* v; 13 struct objc_super super; 14 NSInteger idx; 15 int pointCount; 16 NSPoint points[3]; 17 NSBezierPathElement res; 18 19 if (!PyArg_ParseTuple(arguments, Py_ARG_NSInteger, &idx)) { 20 return NULL; 21 } 22 23 PyObjC_DURING 24 if (PyObjCIMP_Check(method)) { 25 res = ((NSBezierPathElement(*)(id,SEL,NSInteger,NSPoint*)) 26 PyObjCIMP_GetIMP(method))( 27 PyObjCObject_GetObject(self), 28 PyObjCIMP_GetSelector(method), 29 idx, 30 points 31 ); 32 } else { 33 PyObjC_InitSuper(&super, 34 PyObjCSelector_GetClass(method), 35 PyObjCObject_GetObject(self)); 36 37 38 res = ((NSBezierPathElement(*)(struct objc_super*, SEL, NSInteger, NSPoint*))objc_msgSendSuper)(&super, 39 PyObjCSelector_GetSelector(method), 40 idx, 41 points); 42 } 43 PyObjC_HANDLER 44 PyObjCErr_FromObjC(localException); 45 PyObjC_ENDHANDLER 46 47 if (PyErr_Occurred()) { 48 return NULL; 49 } 50 51 switch (res) { 52 case NSMoveToBezierPathElement: pointCount = 1; break; 53 case NSLineToBezierPathElement: pointCount = 1; break; 54 case NSCurveToBezierPathElement: pointCount = 3; break; 55 case NSClosePathBezierPathElement: pointCount = 0; break; 56 default: 57 PyErr_SetString(PyExc_ValueError, 58 "ObjC returned illegal value"); 59 return NULL; 60 } 61 62 result = PyTuple_New(2); 63 if (result == NULL) return NULL; 64 65 v = PyObjC_ObjCToPython(@encode(NSBezierPathElement), &res); 66 if (v == NULL) { 67 Py_DECREF(result); 68 return NULL; 69 } 70 71 PyTuple_SET_ITEM(result, 0, v); 72 73 v = PyObjC_CArrayToPython(@encode(NSPoint), points, pointCount); 74 if (v == NULL) { 75 Py_DECREF(result); 76 return NULL; 77 } 78 PyTuple_SET_ITEM(result, 1, v); 79 80 return result; 81} 82 83static PyObject* 84call_NSBezierPath_setAssociatedPoints_atIndex_( 85 PyObject* method, 86 PyObject* self, PyObject* arguments) 87{ 88 PyObject* result; 89 struct objc_super super; 90 NSInteger idx; 91 NSPoint points[3]; 92 PyObject* pointList; 93 PyObject* seq; 94 int i, len; 95 96 if (!PyArg_ParseTuple(arguments, "O" Py_ARG_NSInteger, 97 &pointList, &idx)) { 98 return NULL; 99 } 100 101 memset(points, 0, sizeof(points)); 102 103 seq = PySequence_Fast(pointList, "points is not a sequence"); 104 if (seq == NULL) { 105 return NULL; 106 } 107 108 len = PySequence_Fast_GET_SIZE(seq); 109 if (len > 3) { 110 Py_DECREF(seq); 111 PyErr_SetString(PyExc_ValueError, "Need at most 3 elements"); 112 return NULL; 113 } 114 115 for (i = 0; i < len; i++) { 116 int err = PyObjC_PythonToObjC(@encode(NSPoint), 117 PySequence_Fast_GET_ITEM(seq, i), points + i); 118 if (err == -1) { 119 return NULL; 120 } 121 } 122 123 PyObjC_DURING 124 if (PyObjCIMP_Check(method)) { 125 ((void(*)(id,SEL,NSPoint*,NSInteger)) 126 PyObjCIMP_GetIMP(method))( 127 PyObjCObject_GetObject(self), 128 PyObjCIMP_GetSelector(method), 129 points, 130 idx); 131 } else { 132 PyObjC_InitSuper(&super, 133 PyObjCSelector_GetClass(method), 134 PyObjCObject_GetObject(self)); 135 136 137 ((void(*)(struct objc_super*, SEL, NSPoint*, NSInteger))objc_msgSendSuper)(&super, 138 PyObjCSelector_GetSelector(method), 139 points, 140 idx); 141 } 142 PyObjC_HANDLER 143 PyObjCErr_FromObjC(localException); 144 result = NULL; 145 PyObjC_ENDHANDLER 146 147 if (PyErr_Occurred()) return NULL; 148 149 result = Py_None; 150 Py_INCREF(result); 151 152 return result; 153} 154 155static void 156imp_NSBezierPath_elementAtIndex_associatedPoints_( 157 void* cif __attribute__((__unused__)), 158 void* resp, 159 void** args, 160 void* callable) 161{ 162 id self = *(id*)args[0]; 163 //SEL _meth = *(SEL*)args[1]; 164 NSInteger idx = *(NSInteger*)args[2]; 165 NSPoint* points = *(NSPoint**)args[3]; 166 167 PyObject* result; 168 PyObject* seq = NULL; 169 PyObject* arglist = NULL; 170 PyObject* v; 171 int err; 172 int pointCount; 173 int i; 174 PyObject* pyself = NULL; 175 int cookie = 0; 176 177 PyGILState_STATE state = PyGILState_Ensure(); 178 179 arglist = PyTuple_New(2); 180 if (arglist == NULL) goto error; 181 182 pyself = PyObjCObject_NewTransient(self, &cookie); 183 if (pyself == NULL) goto error; 184 PyTuple_SetItem(arglist, 0, pyself); 185 Py_INCREF(pyself); 186 187 v = PyInt_FromLong(idx); 188 if (v == NULL) goto error; 189 PyTuple_SET_ITEM(arglist, 1, v); 190 191 result = PyObject_Call((PyObject*)callable, arglist, NULL); 192 Py_DECREF(arglist); arglist = NULL; 193 PyObjCObject_ReleaseTransient(pyself, cookie); pyself = NULL; 194 if (result == NULL) goto error; 195 196 seq = PySequence_Fast(result, "should return tuple of lenght 2"); 197 Py_DECREF(result); 198 if (seq == NULL) goto error; 199 200 if (PySequence_Fast_GET_SIZE(seq) != 2) { 201 PyErr_SetString(PyExc_ValueError, 202 "should return tuple of lenght 2"); 203 goto error; 204 } 205 206 v = PySequence_Fast_GET_ITEM(seq, 0); 207 208 err = PyObjC_PythonToObjC(@encode(NSBezierPathElement), v, resp); 209 if (err == -1) goto error; 210 211 v = PySequence_Fast(PySequence_Fast_GET_ITEM(seq, 1), 212 "result[1] should be a sequence"); 213 if (v == NULL) goto error; 214 215 switch (*(NSBezierPathElement*)resp) { 216 case NSMoveToBezierPathElement: pointCount = 1; break; 217 case NSLineToBezierPathElement: pointCount = 1; break; 218 case NSCurveToBezierPathElement: pointCount = 3; break; 219 case NSClosePathBezierPathElement: pointCount = 0; break; 220 default: 221 PyErr_SetString(PyExc_ValueError, 222 "Return[0] should be NS{*}PathElement"); 223 Py_DECREF(v); 224 goto error; 225 } 226 227 if (PySequence_Fast_GET_SIZE(v) != pointCount) { 228 PyErr_SetString(PyExc_ValueError, 229 "wrong number of points"); 230 Py_DECREF(v); 231 goto error; 232 } 233 234 for (i = 0; i < pointCount; i++) { 235 err = PyObjC_PythonToObjC(@encode(NSPoint), 236 PySequence_Fast_GET_ITEM(v, i), 237 points + i); 238 if (err == -1) { 239 Py_DECREF(v); 240 goto error; 241 } 242 } 243 244 Py_DECREF(v); 245 Py_DECREF(seq); 246 PyGILState_Release(state); 247 return; 248 249error: 250 *(NSBezierPathElement*)resp = 0; 251 Py_XDECREF(arglist); 252 if (pyself) { 253 PyObjCObject_ReleaseTransient(pyself, cookie); 254 } 255 Py_XDECREF(seq); 256 PyObjCErr_ToObjCWithGILState(&state); 257} 258 259 260static int setup_nsbezierpath(PyObject* m __attribute__((__unused__))) 261{ 262 Class cls = objc_lookUpClass("NSBezierPath"); 263 if (!cls) { 264 return 0; 265 } 266 267 if (PyObjC_RegisterMethodMapping(cls, 268 @selector(elementAtIndex:associatedPoints:), 269 call_NSBezierPath_elementAtIndex_associatedPoints_, 270 imp_NSBezierPath_elementAtIndex_associatedPoints_) < 0 ) { 271 272 return -1; 273 } 274 275 if (PyObjC_RegisterMethodMapping(cls, 276 @selector(setAssociatedPoints:atIndex:), 277 call_NSBezierPath_setAssociatedPoints_atIndex_, 278 PyObjCUnsupportedMethod_IMP) < 0 ) { 279 280 return -1; 281 } 282 return 0; 283} 284