1/* 2 * Wrappers for callback functions. 3 * 4 * XXX: Definitely need tests for these. 5 */ 6#include <Python.h> 7#include "pyobjc-api.h" 8 9#import <ApplicationServices/ApplicationServices.h> 10 11 12/* 13 * 14 * CGDataConsumerCreate 15 * 16 */ 17 18static size_t 19m_CGDataConsumerPutBytesCallback(void* _info, const void* buffer, size_t count) 20{ 21 size_t retval; 22 PyObject* info = (PyObject*)_info; 23 24 PyGILState_STATE state = PyGILState_Ensure(); 25 26 PyObject* result = PyObject_CallFunction( 27 PyTuple_GET_ITEM(info, 0), "Os#l", 28 PyTuple_GET_ITEM(info, 2), buffer, count, count); 29 if (result == NULL) { 30 PyObjCErr_ToObjCWithGILState(&state); 31 } 32 33 if (PyObjC_PythonToObjC(@encode(size_t), result, &retval) < 0) { 34 Py_DECREF(result); 35 PyObjCErr_ToObjCWithGILState(&state); 36 } 37 Py_DECREF(result); 38 PyGILState_Release(state); 39 return retval; 40} 41 42static void 43m_CGDataConsumerReleaseInfoCallback(void* _info) 44{ 45 PyObject* info = (PyObject*)_info; 46 47 PyGILState_STATE state = PyGILState_Ensure(); 48 49 if (PyTuple_GET_ITEM(info, 1) != Py_None) { 50 PyObject* result = PyObject_CallFunction( 51 PyTuple_GET_ITEM(info, 1), "O", 52 PyTuple_GET_ITEM(info, 2)); 53 if (result == NULL) { 54 PyObjCErr_ToObjCWithGILState(&state); 55 } 56 Py_DECREF(result); 57 } 58 59 Py_DECREF(info); 60 61 PyGILState_Release(state); 62} 63 64static CGDataConsumerCallbacks 65m_CGDataConsumerCallbacks = { 66 m_CGDataConsumerPutBytesCallback, /* putBytes */ 67 m_CGDataConsumerReleaseInfoCallback /* releaseConsumer */ 68}; 69 70PyDoc_STRVAR(doc_CGDataConsumerCreate, 71 "CGDataConsumerCreate(info, (putBytes, release)) -> object\n" 72 "\n" 73 "putBytes and release are callback functions. Release may be None"); 74static PyObject* 75m_CGDataConsumerCreate(PyObject* self __attribute__((__unused__)), 76 PyObject* args) 77{ 78 PyObject* info; 79 PyObject* putBytes; 80 PyObject* release; 81 82 if (!PyArg_ParseTuple(args, "O(OO)", &info, &putBytes, &release)) { 83 return NULL; 84 } 85 86 if (!PyCallable_Check(putBytes)) { 87 PyErr_SetString(PyExc_TypeError, "putBytes is not callable"); 88 return NULL; 89 } 90 if (release != Py_None && !PyCallable_Check(release)) { 91 PyErr_SetString(PyExc_TypeError, "release is not callable"); 92 return NULL; 93 } 94 95 PyObject* real_info = Py_BuildValue("OOO", putBytes, release, info); 96 if (real_info == NULL) { 97 return NULL; 98 } 99 100 CGDataConsumerRef result; 101 PyObjC_DURING 102 result = CGDataConsumerCreate(real_info, 103 &m_CGDataConsumerCallbacks); 104 105 PyObjC_HANDLER 106 result = NULL; 107 PyObjCErr_FromObjC(localException); 108 PyObjC_ENDHANDLER 109 110 if (result == NULL && PyErr_Occurred()) { 111 Py_DECREF(real_info); 112 return NULL; 113 } 114 115 if (result == NULL) { 116 Py_DECREF(real_info); 117 Py_INCREF(Py_None); 118 return Py_None; 119 } 120 121 PyObject* retval = PyObjC_ObjCToPython( 122 @encode(CGDataConsumerRef), &result); 123 /* CGDataConsumerCreate donated a reference, we therefore now have 124 * one too many, release a reference. 125 */ 126 CGDataConsumerRelease(result); 127 return retval; 128} 129 130/* 131 * 132 * CGDataProviderCreate* 133 * 134 */ 135 136static size_t 137m_CGDataProviderGetBytesCallback( 138 void* _info, 139 void* buffer, 140 size_t count) 141{ 142 PyObject* info = (PyObject*)_info; 143 PyObject* buf; 144 145 PyGILState_STATE state = PyGILState_Ensure(); 146 147#if PY_VERSION_HEX >= 0x02070000 148 Py_buffer view; 149 if (PyBuffer_FillInfo(&view, NULL, buffer, count, 1, PyBUF_WRITABLE) < 0) { 150 PyObjCErr_ToObjCWithGILState(&state); 151 } 152 buf = PyMemoryView_FromBuffer(&view); 153#else 154 buf = PyBuffer_FromReadWriteMemory(buffer, count); 155#endif 156 if (buf == NULL) { 157 PyObjCErr_ToObjCWithGILState(&state); 158 } 159 160 PyObject* result = PyObject_CallFunction( 161 PyTuple_GET_ITEM(info, 1), 162 "OOl", 163 PyTuple_GET_ITEM(info, 0), 164 buf, 165 count); 166 if (result == NULL) { 167 Py_DECREF(result); 168 Py_DECREF(buf); 169 PyObjCErr_ToObjCWithGILState(&state); 170 } 171 172 if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 2) { 173 PyErr_Format(PyExc_TypeError, 174 "Expecting result of type tuple of 2, got %s", 175 result->ob_type->tp_name); 176 Py_DECREF(result); 177 Py_DECREF(buf); 178 PyObjCErr_ToObjCWithGILState(&state); 179 } 180 181 size_t c_result; 182 if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GET_ITEM(result, 0), &c_result) < 0) { 183 Py_DECREF(result); 184 Py_DECREF(buf); 185 PyObjCErr_ToObjCWithGILState(&state); 186 } 187 188 if (PyTuple_GET_ITEM(result, 1) != buf) { 189 const void* b; 190 Py_ssize_t c; 191 192 if (PyObject_AsReadBuffer(PyTuple_GET_ITEM(result, 1), 193 &b, &c) < 0) { 194 Py_DECREF(result); 195 Py_DECREF(buf); 196 PyObjCErr_ToObjCWithGILState(&state); 197 } 198 199 if (c < c_result || c > count) { 200 PyErr_SetString(PyExc_ValueError, 201 "Inconsistent size"); 202 Py_DECREF(result); 203 Py_DECREF(buf); 204 PyObjCErr_ToObjCWithGILState(&state); 205 } 206 memcpy(buffer, b, c_result); 207 } else { 208 /* Assume that the user knows what he's doing and has 209 * filled the right bit of the buffer. 210 */ 211 } 212 213 Py_DECREF(buf); 214 Py_DECREF(result); 215 216 PyGILState_Release(state); 217 return c_result; 218} 219 220static void 221m_CGDataProviderRewindCallback(void* _info) 222{ 223 PyObject* info = (PyObject*)_info; 224 225 PyGILState_STATE state = PyGILState_Ensure(); 226 227 PyObject* result = PyObject_CallFunction(PyTuple_GET_ITEM(info, 3), 228 "O", PyTuple_GET_ITEM(info, 0)); 229 if (result == NULL) { 230 PyObjCErr_ToObjCWithGILState(&state); 231 } 232 Py_DECREF(result); 233 234 PyGILState_Release(state); 235} 236 237static void 238m_CGDataProviderReleaseInfoCallback(void* _info) 239{ 240 PyObject* info = (PyObject*)_info; 241 242 PyGILState_STATE state = PyGILState_Ensure(); 243 244 if (PyTuple_GET_ITEM(info, 3) != Py_None) { 245 PyObject* result = PyObject_CallFunction(PyTuple_GET_ITEM(info, 4), 246 "O", PyTuple_GET_ITEM(info, 0)); 247 if (result == NULL) { 248 PyObjCErr_ToObjCWithGILState(&state); 249 } 250 Py_DECREF(result); 251 } 252 253 /* Cleanup up the callback info */ 254 Py_DECREF(info); 255 256 PyGILState_Release(state); 257} 258 259 260 261 262#if PyObjC_BUILD_RELEASE >= 1005 263 264static off_t 265m_CGDataProviderSkipForwardCallback(void* _info, off_t count) 266{ 267 PyObject* info = (PyObject*)_info; 268 off_t retval; 269 270 PyGILState_STATE state = PyGILState_Ensure(); 271 272 PyObject* result = PyObject_CallFunction(PyTuple_GET_ITEM(info, 2), 273 "Ol", PyTuple_GET_ITEM(info, 0), count); 274 if (result == NULL) { 275 PyObjCErr_ToObjCWithGILState(&state); 276 } 277 278 if (PyObjC_PythonToObjC(@encode(off_t), result, &retval) < 0) { 279 Py_DECREF(result); 280 PyObjCErr_ToObjCWithGILState(&state); 281 } 282 Py_DECREF(result); 283 PyGILState_Release(state); 284 285 return retval; 286} 287 288 289static CGDataProviderSequentialCallbacks m_CGDataProviderSequentialCallbacks = { 290 0, /* version */ 291 m_CGDataProviderGetBytesCallback, /* getBytes */ 292 m_CGDataProviderSkipForwardCallback, /* skipForward */ 293 m_CGDataProviderRewindCallback, /* rewind */ 294 m_CGDataProviderReleaseInfoCallback /* releaseInfo */ 295 296}; 297 298PyDoc_STRVAR(doc_CGDataProviderCreateSequential, 299 "CGDataConsumerCreateSequential(info, (getBytes, skipForward, rewind, releaseProvider)) -> object\n" 300 "\n" 301 "getBytes, skipForward, rewind and release are callback functions. Release may be None"); 302static PyObject* 303m_CGDataProviderCreateSequential(PyObject* self __attribute__((__unused__)), 304 PyObject* args) 305{ 306 PyObject* info; 307 PyObject* getBytes; 308 PyObject* skipForward; 309 PyObject* rewind; 310 PyObject* release; 311 312 if (!PyArg_ParseTuple(args, "O(OOOO)", &info, &getBytes, &skipForward, &rewind, &release)) { 313 return NULL; 314 } 315 316 if (!PyCallable_Check(getBytes)) { 317 PyErr_SetString(PyExc_TypeError, "getBytes is not callable"); 318 return NULL; 319 } 320 if (!PyCallable_Check(skipForward)) { 321 PyErr_SetString(PyExc_TypeError, "skipForward is not callable"); 322 return NULL; 323 } 324 if (!PyCallable_Check(rewind)) { 325 PyErr_SetString(PyExc_TypeError, "rewind is not callable"); 326 return NULL; 327 } 328 if (release != Py_None && !PyCallable_Check(release)) { 329 PyErr_SetString(PyExc_TypeError, "release is not callable"); 330 return NULL; 331 } 332 333 PyObject* real_info = Py_BuildValue("OOOOO", info, getBytes, skipForward, rewind, release); 334 if (real_info == NULL) { 335 return NULL; 336 } 337 338 CGDataProviderRef result; 339 PyObjC_DURING 340 result = CGDataProviderCreateSequential(real_info, 341 &m_CGDataProviderSequentialCallbacks); 342 343 PyObjC_HANDLER 344 result = NULL; 345 PyObjCErr_FromObjC(localException); 346 PyObjC_ENDHANDLER 347 348 if (result == NULL && PyErr_Occurred()) { 349 Py_DECREF(real_info); 350 return NULL; 351 } 352 353 if (result == NULL) { 354 Py_DECREF(real_info); 355 Py_INCREF(Py_None); 356 return Py_None; 357 } 358 359 PyObject* retval = PyObjC_ObjCToPython( 360 @encode(CGDataProviderRef), &result); 361 /* CGDataProviderCreate donated a reference, we therefore now have 362 * one too many, release a reference. 363 */ 364 CGDataProviderRelease(result); 365 return retval; 366} 367 368#endif 369 370/* 371 * CGDataProviderCreateWithData 372 */ 373 374static void 375m_releaseData(void* _info, const void* data, size_t size) 376{ 377 PyObject* info = (PyObject*)_info; 378 int tag; 379 380 PyGILState_STATE state = PyGILState_Ensure(); 381 382#if PY_VERSION_MAJOR == 2 383 tag = PyInt_AsLong(PyTuple_GET_ITEM(info, 2)); 384#else 385 tag = PyLong_AsLong(PyTuple_GET_ITEM(info, 2)); 386#endif 387 388 if (PyTuple_GET_ITEM(info, 1) != Py_None) { 389 PyObject* result = PyObject_CallFunction( 390 PyTuple_GET_ITEM(info, 1), 391 "O", PyTuple_GET_ITEM(info, 0)); 392 if (result == NULL) { 393 PyObjC_FreeCArray(tag, (void*)data); 394 Py_DECREF(info); 395 PyObjCErr_ToObjCWithGILState(&state); 396 return; 397 } 398 Py_DECREF(result); 399 400 } 401 402 PyObjC_FreeCArray(tag, (void*)data); 403 Py_DECREF(info); 404 405 PyGILState_Release(state); 406} 407 408PyDoc_STRVAR(doc_CGDataProviderCreateWithData, 409 "CGDataProviderCreateWithData(info, data, size, release) -> object"); 410static PyObject* 411m_CGDataProviderCreateWithData(PyObject* self __attribute__((__unused__)), 412 PyObject* args) 413{ 414 PyObject* info; 415 PyObject* data; 416 long size; 417 PyObject* release; 418 419 if (!PyArg_ParseTuple(args, "OOlO", &info, &data, &size, &release)) { 420 return NULL; 421 } 422 if (release != Py_None && !PyCallable_Check(release)) { 423 PyErr_SetString(PyExc_TypeError, "release not callable"); 424 return NULL; 425 } 426 427 int tag; 428 PyObject* bufobj = NULL; 429 Py_ssize_t sz = (Py_ssize_t)size; 430 void* arr; 431 432 tag = PyObjC_PythonToCArray(NO, YES, 433 @encode(char), data, &arr, &sz, &bufobj); 434 if (tag < 0) { 435 return NULL; 436 } 437 438 PyObject* real_info; 439 if (bufobj != NULL) { 440 real_info = Py_BuildValue("OOlO", info, release, (long)tag, bufobj); 441 } else { 442 real_info = Py_BuildValue("OOl", info, release, (long)tag); 443 } 444 445 CGDataProviderRef result; 446 447 PyObjC_DURING 448 result = CGDataProviderCreateWithData( 449 real_info, arr, size, m_releaseData); 450 451 PyObjC_HANDLER 452 result = NULL; 453 PyObjCErr_FromObjC(localException); 454 PyObjC_ENDHANDLER 455 456 if (PyErr_Occurred()) { 457 PyObjC_FreeCArray(tag, arr); 458 Py_DECREF(info); 459 return NULL; 460 } 461 462 PyObject* retval = PyObjC_ObjCToPython( 463 @encode(CGDataProviderRef), &result); 464 printf("%s %d\n", __FILE__, __LINE__); 465 CFRelease(result); 466 printf("%s %d\n", __FILE__, __LINE__); 467 return retval; 468} 469 470/* 471 * CGFunctionCreate 472 */ 473 474static void 475m_CGFunctionEvaluateCallback(void* _info, const CGFloat* inData, CGFloat* outData) 476{ 477 PyObject* info = (PyObject*)_info; 478 long domdim; 479 long rangedim; 480 481 PyGILState_STATE state = PyGILState_Ensure(); 482 483#if PY_VERSION_MAJOR == 2 484 domdim = PyInt_AsLong(PyTuple_GET_ITEM(info, 2)); 485 rangedim = PyInt_AsLong(PyTuple_GET_ITEM(info, 3)); 486#else 487 domdim = PyLong_AsLong(PyTuple_GET_ITEM(info, 2)); 488 rangedim = PyLong_AsLong(PyTuple_GET_ITEM(info, 3)); 489#endif 490 491 PyObject* input; 492 if (inData) { 493 input = PyObjC_CArrayToPython(@encode(CGFloat), (void*)inData, domdim); 494 } else { 495 input = Py_None; 496 Py_INCREF(Py_None); 497 } 498 499 500 PyObject* result = PyObject_CallFunction(PyTuple_GET_ITEM(info, 1), 501 "OOO", 502 PyTuple_GET_ITEM(info, 0), 503 input, 504 Py_None); 505 Py_DECREF(input); 506 if (result == NULL) { 507 PyObjCErr_ToObjCWithGILState(&state); 508 } 509 510 if (PyObjC_DepythonifyCArray(@encode(CGFloat), rangedim, NO, result, (void*)outData) < 0) { 511 Py_DECREF(result); 512 PyObjCErr_ToObjCWithGILState(&state); 513 } 514 Py_DECREF(result); 515 516 PyGILState_Release(state); 517} 518 519static void 520m_CGFunctionReleaseInfoCallback(void* _info) 521{ 522 PyObject* info = (PyObject*)_info; 523 524 PyGILState_STATE state = PyGILState_Ensure(); 525 526 Py_DECREF(info); 527 528 PyGILState_Release(state); 529} 530 531static CGFunctionCallbacks m_CGFunctionCallbacks = { 532 0, /* version */ 533 m_CGFunctionEvaluateCallback, /* evaluate */ 534 m_CGFunctionReleaseInfoCallback /* releaseInfo */ 535}; 536 537PyDoc_STRVAR(doc_CGFunctionCreate, 538 "CGFunctionCreate(info, domainDimension, domain, rangeDimension, range, evaluate) -> functionref"); 539static PyObject* 540m_CGFunctionCreate(PyObject* self __attribute__((__unused__)), 541 PyObject* args) 542{ 543 PyObject* info; 544 PyObject* domDim; 545 PyObject* domain; 546 PyObject* rangeDim; 547 PyObject* range; 548 PyObject* evaluate; 549 size_t domainDimension; 550 size_t rangeDimension; 551 CGFloat* domainArr; 552 CGFloat* rangeArr; 553 CGFunctionRef result = NULL; 554 PyObject* domainBuf = NULL; 555 PyObject* rangeBuf = NULL; 556 int rangeTag; 557 int domainTag; 558 559 if (!PyArg_ParseTuple(args, "OOOOOO", 560 &info, &domDim, &domain, &rangeDim, 561 &range, &evaluate)) { 562 return NULL; 563 } 564 565 if (PyObjC_PythonToObjC(@encode(size_t), domDim, &domainDimension) < 0){ 566 return NULL; 567 } 568 if (PyObjC_PythonToObjC(@encode(size_t), rangeDim, &rangeDimension) < 0){ 569 return NULL; 570 } 571 if (domain == Py_None) { 572 domainArr = NULL; 573 domainTag = -1; 574 575 } else { 576 /* Parse Array */ 577 Py_ssize_t cnt = domainDimension * 2; 578 domainTag = PyObjC_PythonToCArray(NO, NO, @encode(CGFloat), 579 domain, (void**)&domainArr, &cnt, &domainBuf); 580 if (domainTag < 0) { 581 return NULL; 582 } 583 } 584 585 if (range == Py_None) { 586 rangeArr = NULL; 587 rangeTag = -1; 588 589 } else { 590 Py_ssize_t cnt = rangeDimension * 2; 591 592 /* Parse Array */ 593 rangeTag = PyObjC_PythonToCArray(NO, NO, @encode(CGFloat), 594 range, (void**)&rangeArr, &cnt, &rangeBuf); 595 if (rangeTag < 0) { 596 if (domainTag != -1) { 597 PyObjC_FreeCArray(domainTag, domainArr); 598 Py_XDECREF(domainBuf); 599 } 600 return NULL; 601 } 602 } 603 604 if (!PyCallable_Check(evaluate)) { 605 PyErr_SetString(PyExc_TypeError, "evaluate not callable"); 606 if (domainTag != -1) { 607 PyObjC_FreeCArray(domainTag, domainArr); 608 Py_XDECREF(domainBuf); 609 } 610 if (rangeTag != -1) { 611 PyObjC_FreeCArray(rangeTag, rangeArr); 612 Py_XDECREF(rangeBuf); 613 } 614 return NULL; 615 } 616 617 618 PyObject* real_info; 619 620 real_info = Py_BuildValue("OOll", 621 info, evaluate, domainDimension, rangeDimension); 622 if (real_info == NULL) { 623 return NULL; 624 } 625 626 PyObjC_DURING 627 result = CGFunctionCreate( 628 real_info, 629 domainDimension, 630 domainArr, 631 rangeDimension, 632 rangeArr, 633 &m_CGFunctionCallbacks); 634 635 PyObjC_HANDLER 636 result = NULL; 637 PyObjCErr_FromObjC(localException); 638 PyObjC_ENDHANDLER 639 640 /* cleanup domainArr, rangeArr */ 641 if (domainTag != -1) { 642 Py_XDECREF(domainBuf); 643 PyObjC_FreeCArray(domainTag, domainArr); 644 } 645 if (rangeTag != -1) { 646 Py_XDECREF(rangeBuf); 647 PyObjC_FreeCArray(rangeTag, rangeArr); 648 } 649 650 if (result == NULL) { 651 Py_DECREF(real_info); 652 if (PyErr_Occurred()) { 653 return NULL; 654 } 655 Py_INCREF(Py_None); 656 return Py_None; 657 } 658 659 PyObject* func = PyObjC_ObjCToPython(@encode(CGFunctionRef), &result); 660 CGFunctionRelease(result); /* Adjust reference count */ 661 662 return func; 663} 664 665 666/* 667 * - CGDisplayRegisterReconfigurationCallback 668 * - CGDisplayRemoveReconfigurationCallback 669 */ 670 671struct callback_struct { 672 PyObject* callback; 673 PyObject* user_info; 674 PyObject* real_info; 675}; 676struct callback_info { 677 struct callback_struct* list; 678 size_t count; 679}; 680 681struct callback_info display_reconfig_callback = { NULL, 0 }; 682 683static int 684insert_callback_info( 685 struct callback_info* info, 686 PyObject* callback, 687 PyObject* user_info, 688 PyObject* real_info) 689{ 690 size_t i; 691 692 for (i = 0; i < info->count; i++) { 693 if (info->list[i].callback == NULL) { 694 info->list[i].callback = callback; 695 info->list[i].user_info = user_info; 696 info->list[i].real_info = real_info; 697 Py_INCREF(callback); 698 Py_INCREF(user_info); 699 Py_INCREF(real_info); 700 return 0; 701 } 702 } 703 704 /* No free space found, increase the list */ 705 if (info->list == NULL) { 706 info->list = PyMem_Malloc(sizeof(*info->list)); 707 if (info->list == NULL) { 708 PyErr_NoMemory(); 709 return -1; 710 } 711 info->list[0].callback = callback; 712 info->list[0].user_info = user_info; 713 info->list[0].real_info = real_info; 714 Py_INCREF(callback); 715 Py_INCREF(user_info); 716 Py_INCREF(real_info); 717 info->count = 1; 718 } else { 719 struct callback_struct* tmp; 720 721 tmp = PyMem_Realloc(info->list, sizeof(*info->list) * (info->count+1)); 722 if (tmp == NULL) { 723 PyErr_NoMemory(); 724 return -1; 725 } 726 info->list = tmp; 727 info->list[info->count].callback = callback; 728 info->list[info->count].user_info = user_info; 729 info->list[info->count].real_info = real_info; 730 Py_INCREF(callback); 731 Py_INCREF(user_info); 732 Py_INCREF(real_info); 733 info->count++; 734 } 735 return 0; 736} 737 738static PyObject* 739find_callback_info( 740 struct callback_info* info, 741 PyObject* callback, 742 PyObject* user_info) 743{ 744 size_t i; 745 746 for (i = 0; i < info->count; i++) { 747 if (info->list[i].callback == NULL) continue; 748 749 if (!PyObject_RichCompareBool(info->list[i].callback, callback, Py_EQ)) { 750 continue; 751 } 752 if (!PyObject_RichCompareBool(info->list[i].user_info, user_info, Py_EQ)) { 753 continue; 754 } 755 756 return info->list[i].real_info; 757 } 758 PyErr_SetString(PyExc_ValueError, "Cannot find callback info"); 759 return NULL; 760} 761 762static void 763remove_callback_info( 764 struct callback_info* info, 765 PyObject* callback, 766 PyObject* user_info) 767{ 768 size_t i; 769 770 for (i = 0; i < info->count; i++) { 771 if (info->list[i].callback == NULL) continue; 772 773 if (!PyObject_RichCompareBool(info->list[i].callback, callback, Py_EQ)) { 774 continue; 775 } 776 if (!PyObject_RichCompareBool(info->list[i].user_info, user_info, Py_EQ)) { 777 continue; 778 } 779 780 Py_DECREF(info->list[i].callback); 781 Py_DECREF(info->list[i].user_info); 782 info->list[i].callback = NULL; 783 info->list[i].user_info = NULL; 784 } 785} 786 787 788static void m_CGDisplayReconfigurationCallBack( 789 CGDirectDisplayID display, 790 CGDisplayChangeSummaryFlags flags, 791 void* _userInfo) 792{ 793 PyObject* info = (PyObject*)_userInfo; 794 795 PyGILState_STATE state = PyGILState_Ensure(); 796 797 PyObject* py_display = PyObjC_ObjCToPython( 798 @encode(CGDirectDisplayID), &display); 799 if (py_display == NULL) { 800 PyObjCErr_ToObjCWithGILState(&state); 801 } 802 803 PyObject* py_flags = PyObjC_ObjCToPython( 804 @encode(CGDisplayChangeSummaryFlags), &flags); 805 if (py_flags == NULL) { 806 Py_DECREF(py_display); 807 PyObjCErr_ToObjCWithGILState(&state); 808 } 809 810 811 812 PyObject* result = PyObject_CallFunction( 813 PyTuple_GET_ITEM(info, 0), "OOO", 814 py_display, 815 py_flags, 816 PyTuple_GET_ITEM(info, 1)); 817 Py_DECREF(py_display); 818 Py_DECREF(py_flags); 819 if (result == NULL) { 820 PyObjCErr_ToObjCWithGILState(&state); 821 } 822 823 Py_DECREF(result); 824 PyGILState_Release(state); 825} 826 827static PyObject* 828m_CGDisplayRegisterReconfigurationCallback( 829 PyObject* self __attribute__((__unused__)), 830 PyObject* args) 831{ 832 PyObject* callback; 833 PyObject* userinfo; 834 CGError err; 835 836 837 if (!PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 838 return NULL; 839 } 840 if (!PyCallable_Check(callback)) { 841 PyErr_SetString(PyExc_TypeError, "callback not callable"); 842 return NULL; 843 } 844 845 PyObject* real_info = Py_BuildValue("OO", callback, userinfo); 846 847 err = -1; 848 PyObjC_DURING 849 err = CGDisplayRegisterReconfigurationCallback( 850 m_CGDisplayReconfigurationCallBack, real_info); 851 852 853 PyObjC_HANDLER 854 err = -1; 855 PyObjCErr_FromObjC(localException); 856 857 PyObjC_ENDHANDLER 858 859 if (PyErr_Occurred()) { 860 Py_DECREF(real_info); 861 return NULL; 862 } 863 864 if (insert_callback_info(&display_reconfig_callback, 865 callback, userinfo, real_info) == -1) { 866 CGDisplayRemoveReconfigurationCallback( 867 m_CGDisplayReconfigurationCallBack, 868 real_info); 869 Py_DECREF(real_info); 870 return NULL; 871 } 872 873 return PyObjC_ObjCToPython(@encode(CGError), &err); 874} 875 876static PyObject* 877m_CGDisplayRemoveReconfigurationCallback( 878 PyObject* self __attribute__((__unused__)), 879 PyObject* args) 880{ 881 PyObject* callback; 882 PyObject* userinfo; 883 884 if (!PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 885 return NULL; 886 } 887 888 PyObject* real_info = find_callback_info(&display_reconfig_callback, callback, userinfo); 889 890 if (real_info == NULL) { 891 return NULL; 892 } 893 894 CGError err = -1; 895 PyObjC_DURING 896 err = CGDisplayRemoveReconfigurationCallback( 897 m_CGDisplayReconfigurationCallBack, 898 real_info); 899 900 PyObjC_HANDLER 901 PyObjCErr_FromObjC(localException); 902 903 PyObjC_ENDHANDLER 904 905 if (PyErr_Occurred()) { 906 return NULL; 907 } 908 909 remove_callback_info(&display_reconfig_callback, callback, userinfo); 910 911 return PyObjC_ObjCToPython(@encode(CGError), &err); 912} 913 914/* 915 * CGScreenUpdateMove 916 */ 917 918struct callback_info screen_move_callback = { NULL, 0 }; 919 920static void 921m_CGScreenUpdateMoveCallback( 922 CGScreenUpdateMoveDelta delta, 923 size_t count, 924 const CGRect* rectArray, 925 void* _userInfo) 926{ 927 PyObject* info = (PyObject*)_userInfo; 928 929 PyGILState_STATE state = PyGILState_Ensure(); 930 931 PyObject* py_delta = PyObjC_ObjCToPython( 932 @encode(CGScreenUpdateMoveDelta), &delta); 933 if (py_delta == NULL) { 934 PyObjCErr_ToObjCWithGILState(&state); 935 } 936 PyObject* py_rectarray = PyObjC_CArrayToPython(@encode(CGRect), 937 (void*)rectArray, count); 938 if (py_rectarray == NULL) { 939 Py_DECREF(py_delta); 940 PyObjCErr_ToObjCWithGILState(&state); 941 } 942 943 PyObject* result = PyObject_CallFunction( 944 PyTuple_GET_ITEM(info, 0), "OlOO", 945 py_delta, 946 (long)count, 947 py_rectarray, 948 PyTuple_GET_ITEM(info, 1)); 949 Py_DECREF(py_delta); 950 Py_DECREF(py_rectarray); 951 if (result == NULL) { 952 PyObjCErr_ToObjCWithGILState(&state); 953 } 954 955 Py_DECREF(result); 956 PyGILState_Release(state); 957} 958 959static PyObject* 960m_CGScreenRegisterMoveCallback( 961 PyObject* self __attribute__((__unused__)), 962 PyObject* args) 963{ 964 PyObject* callback; 965 PyObject* userinfo; 966 967 968 if (PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 969 return NULL; 970 } 971 if (!PyCallable_Check(callback)) { 972 PyErr_SetString(PyExc_TypeError, "callback not callable"); 973 return NULL; 974 } 975 976 PyObject* real_info = Py_BuildValue("OO", callback, userinfo); 977 978 PyObjC_DURING 979 CGScreenRegisterMoveCallback( 980 m_CGScreenUpdateMoveCallback, real_info); 981 982 PyObjC_HANDLER 983 PyObjCErr_FromObjC(localException); 984 985 PyObjC_ENDHANDLER 986 987 if (PyErr_Occurred()) { 988 Py_DECREF(real_info); 989 return NULL; 990 } 991 992 if (insert_callback_info(&screen_move_callback, 993 callback, userinfo, real_info) < 0) { 994 CGScreenUnregisterMoveCallback( 995 m_CGScreenUpdateMoveCallback, 996 real_info); 997 Py_DECREF(real_info); 998 return NULL; 999 } 1000 1001 Py_INCREF(Py_None); 1002 return Py_None; 1003} 1004 1005static PyObject* 1006m_CGScreenUnregisterMoveCallback( 1007 PyObject* self __attribute__((__unused__)), 1008 PyObject* args) 1009{ 1010 PyObject* callback; 1011 PyObject* userinfo; 1012 1013 if (!PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 1014 return NULL; 1015 } 1016 1017 PyObject* real_info = find_callback_info(&screen_move_callback, callback, userinfo); 1018 1019 if (real_info == NULL) { 1020 return NULL; 1021 } 1022 1023 PyObjC_DURING 1024 CGScreenUnregisterMoveCallback( 1025 m_CGScreenUpdateMoveCallback, 1026 real_info); 1027 1028 PyObjC_HANDLER 1029 PyObjCErr_FromObjC(localException); 1030 1031 PyObjC_ENDHANDLER 1032 1033 if (PyErr_Occurred()) { 1034 return NULL; 1035 } 1036 1037 remove_callback_info(&screen_move_callback, callback, userinfo); 1038 1039 Py_INCREF(Py_None); 1040 return Py_None; 1041} 1042 1043/* 1044 * CGScreenRefresh 1045 */ 1046 1047struct callback_info screen_refresh_callback = { NULL, 0 }; 1048 1049static void m_CGScreenRefreshCallback( 1050 CGRectCount count, 1051 const CGRect* rectArray, 1052 void* _userInfo) 1053{ 1054 PyObject* info = (PyObject*)_userInfo; 1055 1056 PyGILState_STATE state = PyGILState_Ensure(); 1057 1058 PyObject* py_rectarray = PyObjC_CArrayToPython(@encode(CGRect), 1059 (void*)rectArray, count); 1060 if (py_rectarray == NULL) { 1061 PyObjCErr_ToObjCWithGILState(&state); 1062 } 1063 1064 PyObject* result = PyObject_CallFunction( 1065 PyTuple_GET_ITEM(info, 0), "lOO", 1066 (long)count, 1067 py_rectarray, 1068 PyTuple_GET_ITEM(info, 1)); 1069 Py_DECREF(py_rectarray); 1070 if (result == NULL) { 1071 PyObjCErr_ToObjCWithGILState(&state); 1072 } 1073 1074 Py_DECREF(result); 1075 PyGILState_Release(state); 1076} 1077 1078static PyObject* 1079m_CGRegisterScreenRefreshCallback( 1080 PyObject* self __attribute__((__unused__)), 1081 PyObject* args) 1082{ 1083 PyObject* callback; 1084 PyObject* userinfo; 1085 1086 1087 if (!PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 1088 return NULL; 1089 } 1090 if (!PyCallable_Check(callback)) { 1091 PyErr_SetString(PyExc_TypeError, "callback not callable"); 1092 return NULL; 1093 } 1094 1095 PyObject* real_info = Py_BuildValue("OO", callback, userinfo); 1096 1097 CGError err = -1; 1098 PyObjC_DURING 1099 err = CGRegisterScreenRefreshCallback( 1100 m_CGScreenRefreshCallback, real_info); 1101 1102 PyObjC_HANDLER 1103 PyObjCErr_FromObjC(localException); 1104 1105 PyObjC_ENDHANDLER 1106 1107 if (PyErr_Occurred()) { 1108 Py_DECREF(real_info); 1109 return NULL; 1110 } 1111 1112 if (insert_callback_info(&screen_refresh_callback, 1113 callback, userinfo, real_info) < 0) { 1114 CGUnregisterScreenRefreshCallback( 1115 m_CGScreenRefreshCallback, 1116 real_info); 1117 Py_DECREF(real_info); 1118 return NULL; 1119 } 1120 1121 return PyObjC_ObjCToPython(@encode(CGError), &err); 1122} 1123 1124static PyObject* 1125m_CGUnregisterScreenRefreshCallback( 1126 PyObject* self __attribute__((__unused__)), 1127 PyObject* args) 1128{ 1129 PyObject* callback; 1130 PyObject* userinfo; 1131 1132 if (!PyArg_ParseTuple(args, "OO", &callback, &userinfo)) { 1133 return NULL; 1134 } 1135 1136 PyObject* real_info = find_callback_info(&screen_refresh_callback, callback, userinfo); 1137 1138 if (real_info == NULL) { 1139 return NULL; 1140 } 1141 1142 PyObjC_DURING 1143 CGUnregisterScreenRefreshCallback( 1144 m_CGScreenRefreshCallback, 1145 real_info); 1146 1147 PyObjC_HANDLER 1148 PyObjCErr_FromObjC(localException); 1149 1150 PyObjC_ENDHANDLER 1151 1152 if (PyErr_Occurred()) { 1153 return NULL; 1154 } 1155 1156 remove_callback_info(&screen_refresh_callback, callback, userinfo); 1157 1158 Py_INCREF(Py_None); 1159 return Py_None; 1160} 1161 1162 1163/* 1164 * CGEventTapCreate 1165 * CGEventTapCreateForPSN 1166 * 1167 * Note that these wrappers leak some memory: the 'refcon' info passed to the 1168 * C code will never be deallocated. This is too bad, but can't be avoided with 1169 * the current CoreGraphics API. 1170 */ 1171 1172static CGEventRef 1173m_CGEventTapCallBack( 1174 CGEventTapProxy proxy, 1175 CGEventType type, 1176 CGEventRef event, 1177 void * _info) 1178{ 1179 PyObject* info = (PyObject*)_info; 1180 1181 PyGILState_STATE state = PyGILState_Ensure(); 1182 1183 PyObject* py_proxy; 1184 PyObject* py_type; 1185 PyObject* py_event; 1186 1187 py_proxy = PyObjC_ObjCToPython(@encode(CGEventTapProxy), &proxy); 1188 if (py_proxy == NULL) { 1189 PyObjCErr_ToObjCWithGILState(&state); 1190 } 1191 1192 py_type = PyObjC_ObjCToPython(@encode(CGEventType), &type); 1193 if (py_type == NULL) { 1194 Py_DECREF(py_proxy); 1195 PyObjCErr_ToObjCWithGILState(&state); 1196 } 1197 1198 py_event = PyObjC_ObjCToPython(@encode(CGEventRef), &event); 1199 if (py_event == NULL) { 1200 Py_DECREF(py_proxy); 1201 Py_DECREF(py_type); 1202 PyObjCErr_ToObjCWithGILState(&state); 1203 } 1204 1205 PyObject* result = PyObject_CallFunction( 1206 PyTuple_GET_ITEM(info, 0), 1207 "NNNO", 1208 py_proxy, py_type, py_event, PyTuple_GET_ITEM(info, 1) 1209 ); 1210 if (result == NULL) { 1211 PyObjCErr_ToObjCWithGILState(&state); 1212 } 1213 1214 if (PyObjC_PythonToObjC(@encode(CGEventRef), result, &event) < 0) { 1215 PyObjCErr_ToObjCWithGILState(&state); 1216 } 1217 1218 PyGILState_Release(state); 1219 1220 return event; 1221} 1222 1223static PyObject* 1224m_CGEventTapCreate( 1225 PyObject* self __attribute__((__unused__)), 1226 PyObject* args) 1227{ 1228 PyObject* py_tap; 1229 PyObject* py_place; 1230 PyObject* py_options; 1231 PyObject* py_eventsOfInterest; 1232 PyObject* callback; 1233 PyObject* info; 1234 CGEventTapLocation tap; 1235 CGEventTapPlacement place; 1236 CGEventTapOptions options; 1237 CGEventMask eventsOfInterest; 1238 CFMachPortRef result = NULL; 1239 1240 if (!PyArg_ParseTuple(args, "OOOOOO", 1241 &py_tap, &py_place, &py_options, &py_eventsOfInterest, 1242 &callback, &info)) { 1243 1244 return NULL; 1245 } 1246 1247 if (PyObjC_PythonToObjC(@encode(CGEventTapLocation), py_tap, &tap)<0) { 1248 return NULL; 1249 } 1250 if (PyObjC_PythonToObjC(@encode(CGEventTapPlacement), py_place, &place)<0) { 1251 return NULL; 1252 } 1253 if (PyObjC_PythonToObjC(@encode(CGEventTapOptions), py_options, &options)<0) { 1254 return NULL; 1255 } 1256 if (PyObjC_PythonToObjC(@encode(CGEventMask), py_eventsOfInterest, &eventsOfInterest)<0) { 1257 return NULL; 1258 } 1259 1260 PyObject* real_info = Py_BuildValue("OO", callback, info); 1261 if (real_info == NULL) { 1262 return NULL; 1263 } 1264 1265 PyObjC_DURING 1266 result = CGEventTapCreate( 1267 tap, 1268 place, 1269 options, 1270 eventsOfInterest, 1271 m_CGEventTapCallBack, 1272 (void*)real_info); 1273 1274 PyObjC_HANDLER 1275 PyObjCErr_FromObjC(localException); 1276 PyObjC_ENDHANDLER 1277 1278 if (PyErr_Occurred()) { 1279 return NULL; 1280 } 1281 1282 PyObject* retval = PyObjC_ObjCToPython(@encode(CFMachPortRef), &result); 1283 if (result != NULL) { 1284 CFRelease(result); /* Compensate for donated ref */ 1285 } 1286 return retval; 1287} 1288 1289static PyObject* 1290m_CGEventTapCreateForPSN( 1291 PyObject* self __attribute__((__unused__)), 1292 PyObject* args) 1293{ 1294 PyObject* py_psn; 1295 PyObject* py_place; 1296 PyObject* py_options; 1297 PyObject* py_eventsOfInterest; 1298 PyObject* callback; 1299 PyObject* info; 1300 ProcessSerialNumber psn; 1301 CGEventTapPlacement place; 1302 CGEventTapOptions options; 1303 CGEventMask eventsOfInterest; 1304 CFMachPortRef result = NULL; 1305 1306 if (!PyArg_ParseTuple(args, "OOOOOO", 1307 &py_psn, &py_place, &py_options, &py_eventsOfInterest, 1308 &callback, &info)) { 1309 1310 return NULL; 1311 } 1312 1313 if (PyObjC_PythonToObjC(@encode(ProcessSerialNumber), py_psn, &psn)<0) { 1314 return NULL; 1315 } 1316 if (PyObjC_PythonToObjC(@encode(CGEventTapPlacement), py_place, &place)<0) { 1317 return NULL; 1318 } 1319 if (PyObjC_PythonToObjC(@encode(CGEventTapOptions), py_options, &options)<0) { 1320 return NULL; 1321 } 1322 if (PyObjC_PythonToObjC(@encode(CGEventMask), py_eventsOfInterest, &eventsOfInterest)<0) { 1323 return NULL; 1324 } 1325 1326 PyObject* real_info = Py_BuildValue("OO", callback, info); 1327 if (real_info == NULL) { 1328 return NULL; 1329 } 1330 1331 PyObjC_DURING 1332 result = CGEventTapCreateForPSN( 1333 (void*)&psn, 1334 place, 1335 options, 1336 eventsOfInterest, 1337 m_CGEventTapCallBack, 1338 (void*)real_info); 1339 1340 PyObjC_HANDLER 1341 PyObjCErr_FromObjC(localException); 1342 PyObjC_ENDHANDLER 1343 1344 if (PyErr_Occurred()) { 1345 return NULL; 1346 } 1347 1348 PyObject* retval = PyObjC_ObjCToPython(@encode(CFMachPortRef), &result); 1349 if (result) { 1350 CFRelease(result); /* Compensate for donated ref */ 1351 } 1352 return retval; 1353} 1354 1355/* 1356 * CGPatternCreate 1357 */ 1358 1359static void 1360m_CGPatternDrawPatternCallback( 1361 void* _info, 1362 CGContextRef context) 1363{ 1364 PyObject* info = (PyObject*)_info; 1365 1366 PyGILState_STATE state = PyGILState_Ensure(); 1367 1368 PyObject* ctx = PyObjC_ObjCToPython(@encode(CGContextRef), &context); 1369 if (context == NULL) { 1370 PyObjCErr_ToObjCWithGILState(&state); 1371 } 1372 1373 PyObject* result = PyObject_CallFunction( 1374 PyTuple_GET_ITEM(info, 0), 1375 "ON", 1376 PyTuple_GET_ITEM(info, 1), 1377 ctx); 1378 if (result == NULL) { 1379 PyObjCErr_ToObjCWithGILState(&state); 1380 } 1381 Py_DECREF(result); 1382 PyGILState_Release(state); 1383} 1384 1385static void 1386m_CGPatternReleaseInfoCallback(void* _info) 1387{ 1388 PyObject* info = (PyObject*)_info; 1389 1390 PyGILState_STATE state = PyGILState_Ensure(); 1391 Py_DECREF(info); 1392 1393 PyGILState_Release(state); 1394} 1395 1396static CGPatternCallbacks m_CGPatternCallbacks = { 1397 0, 1398 m_CGPatternDrawPatternCallback, /* drawPattern */ 1399 m_CGPatternReleaseInfoCallback, /* releaseInfo */ 1400}; 1401 1402static PyObject* 1403m_CGPatternCreate(PyObject* self __attribute__((__unused__)), 1404 PyObject* args) 1405{ 1406 PyObject* info; 1407 PyObject* py_bounds; 1408 PyObject* py_matrix; 1409 float xStep, yStep; 1410 PyObject* py_tiling; 1411 PyObject* py_isColored; 1412 PyObject* draw; 1413 CGRect bounds; 1414 CGAffineTransform matrix; 1415 CGPatternTiling tiling; 1416 int isColored; 1417 1418 1419 if (!PyArg_ParseTuple(args, "OOOffOOO", 1420 &info, &py_bounds, &py_matrix, &xStep, &yStep, 1421 &py_tiling, &py_isColored, &draw)) { 1422 1423 return NULL; 1424 } 1425 if (!PyCallable_Check(draw)) { 1426 PyErr_SetString(PyExc_TypeError, "drawPattern is not callable"); 1427 return NULL; 1428 } 1429 if (PyObjC_PythonToObjC(@encode(CGRect), py_bounds, &bounds) < 0) { 1430 return NULL; 1431 } 1432 if (PyObjC_PythonToObjC(@encode(CGAffineTransform), py_matrix, &matrix) < 0) { 1433 return NULL; 1434 } 1435 if (PyObjC_PythonToObjC(@encode(CGPatternTiling), py_tiling, &tiling) < 0) { 1436 return NULL; 1437 } 1438 if (PyObject_IsTrue(py_isColored)) { 1439 isColored = true; 1440 } else { 1441 isColored = false; 1442 } 1443 1444 PyObject* real_info = Py_BuildValue("OO", draw, info); 1445 if (real_info == NULL) { 1446 return NULL; 1447 } 1448 1449 CGPatternRef result = NULL; 1450 1451 PyObjC_DURING 1452 result = CGPatternCreate( 1453 (void*)real_info, 1454 bounds, 1455 matrix, 1456 xStep, 1457 yStep, 1458 tiling, 1459 isColored, 1460 &m_CGPatternCallbacks); 1461 1462 PyObjC_HANDLER 1463 PyObjCErr_FromObjC(localException); 1464 PyObjC_ENDHANDLER 1465 1466 if (PyErr_Occurred()) { 1467 Py_DECREF(real_info); 1468 return NULL; 1469 } 1470 1471 PyObject* retval = PyObjC_ObjCToPython(@encode(CGPatternRef), &result); 1472 CFRelease(result); 1473 return retval; 1474} 1475 1476/* 1477 * CGPSConverterCreate 1478 */ 1479 1480static void 1481m_CGPSConverterBeginDocumentCallback(void* _info) 1482{ 1483 PyObject* info = (PyObject*)_info; 1484 1485 PyGILState_STATE state = PyGILState_Ensure(); 1486 1487 PyObject* result = PyObject_CallFunction( 1488 PyTuple_GET_ITEM(info, 1), 1489 "O", PyTuple_GET_ITEM(info, 0)); 1490 1491 if (result == NULL) { 1492 PyObjCErr_ToObjCWithGILState(&state); 1493 } 1494 Py_DECREF(result); 1495 1496 PyGILState_Release(state); 1497} 1498 1499static void 1500m_CGPSConverterBeginPageCallback(void* _info, 1501 size_t pageNumber, CFDictionaryRef pageInfo) 1502{ 1503 PyObject* info = (PyObject*)_info; 1504 1505 PyGILState_STATE state = PyGILState_Ensure(); 1506 1507 PyObject* result = PyObject_CallFunction( 1508 PyTuple_GET_ITEM(info, 3), 1509 "OlN", 1510 PyTuple_GET_ITEM(info, 0), 1511 (long)pageNumber, 1512 PyObjC_ObjCToPython(@encode(CFDictionaryRef), &pageInfo)); 1513 1514 if (result == NULL) { 1515 PyObjCErr_ToObjCWithGILState(&state); 1516 } 1517 Py_DECREF(result); 1518 1519 PyGILState_Release(state); 1520} 1521 1522static void 1523m_CGPSConverterEndDocumentCallback(void* _info, bool success) 1524{ 1525 PyObject* info = (PyObject*)_info; 1526 1527 PyGILState_STATE state = PyGILState_Ensure(); 1528 1529 1530 PyObject* result = PyObject_CallFunction( 1531 PyTuple_GET_ITEM(info, 2), 1532 "ON", PyTuple_GET_ITEM(info, 0), 1533 PyBool_FromLong(success)); 1534 1535 if (result == NULL) { 1536 PyObjCErr_ToObjCWithGILState(&state); 1537 } 1538 Py_DECREF(result); 1539 1540 PyGILState_Release(state); 1541} 1542 1543static void 1544m_CGPSConverterEndPageCallback(void* _info, size_t pageNumber, 1545 CFDictionaryRef pageInfo) 1546{ 1547 PyObject* info = (PyObject*)_info; 1548 1549 PyGILState_STATE state = PyGILState_Ensure(); 1550 1551 PyObject* result = PyObject_CallFunction( 1552 PyTuple_GET_ITEM(info, 4), 1553 "OlN", 1554 PyTuple_GET_ITEM(info, 0), 1555 (long)pageNumber, 1556 PyObjC_ObjCToPython(@encode(CFDictionaryRef), &pageInfo)); 1557 1558 if (result == NULL) { 1559 PyObjCErr_ToObjCWithGILState(&state); 1560 } 1561 Py_DECREF(result); 1562 1563 PyGILState_Release(state); 1564} 1565 1566static void 1567m_CGPSConverterMessageCallback(void* _info, CFStringRef message) 1568{ 1569 PyObject* info = (PyObject*)_info; 1570 1571 PyGILState_STATE state = PyGILState_Ensure(); 1572 1573 PyObject* result = PyObject_CallFunction( 1574 PyTuple_GET_ITEM(info, 6), 1575 "ON", 1576 PyTuple_GET_ITEM(info, 0), 1577 PyObjC_ObjCToPython(@encode(CFStringRef), &message)); 1578 1579 if (result == NULL) { 1580 PyObjCErr_ToObjCWithGILState(&state); 1581 } 1582 Py_DECREF(result); 1583 1584 PyGILState_Release(state); 1585} 1586 1587static void 1588m_CGPSConverterProgressCallback(void* _info) 1589{ 1590 PyObject* info = (PyObject*)_info; 1591 1592 PyGILState_STATE state = PyGILState_Ensure(); 1593 1594 1595 PyObject* result = PyObject_CallFunction( 1596 PyTuple_GET_ITEM(info, 5), 1597 "O", PyTuple_GET_ITEM(info, 0)); 1598 1599 if (result == NULL) { 1600 PyObjCErr_ToObjCWithGILState(&state); 1601 } 1602 Py_DECREF(result); 1603 1604 PyGILState_Release(state); 1605} 1606 1607static void 1608m_CGPSConverterReleaseInfoCallback(void* _info) 1609{ 1610 PyObject* info = (PyObject*)_info; 1611 1612 PyGILState_STATE state = PyGILState_Ensure(); 1613 1614 if (PyTuple_GET_ITEM(info, 7) != Py_None) { 1615 PyObject* result = PyObject_CallFunction( 1616 PyTuple_GET_ITEM(info, 7), 1617 "O", PyTuple_GET_ITEM(info, 0)); 1618 1619 if (result == NULL) { 1620 Py_DECREF(info); 1621 PyObjCErr_ToObjCWithGILState(&state); 1622 } 1623 Py_DECREF(result); 1624 } 1625 Py_DECREF(info); 1626 1627 PyGILState_Release(state); 1628} 1629 1630 1631static CGPSConverterCallbacks m_CGPSConverterCallbacks = { 1632 0, 1633 m_CGPSConverterBeginDocumentCallback, /* beginDocument */ 1634 m_CGPSConverterEndDocumentCallback, /* endDocument */ 1635 m_CGPSConverterBeginPageCallback, /* beginPage */ 1636 m_CGPSConverterEndPageCallback, /* endPage */ 1637 m_CGPSConverterProgressCallback, /* noteProgress */ 1638 m_CGPSConverterMessageCallback, /* noteMessage */ 1639 m_CGPSConverterReleaseInfoCallback /* releaseInfo */ 1640}; 1641 1642static PyObject* 1643m_CGPSConverterCreate( 1644 PyObject* self __attribute__((__unused__)), 1645 PyObject* args) 1646{ 1647 PyObject* info; 1648 PyObject* py_options; 1649 PyObject* beginDocument; 1650 PyObject* endDocument; 1651 PyObject* beginPage; 1652 PyObject* endPage; 1653 PyObject* noteProgress; 1654 PyObject* noteMessage; 1655 PyObject* releaseInfo; 1656 CFDictionaryRef options; 1657 CGPSConverterRef result = NULL; 1658 1659 if (!PyArg_ParseTuple(args, "O(OOOOOOO)O", 1660 &info, 1661 &beginDocument, &endDocument, 1662 &beginPage, &endPage, 1663 ¬eProgress, ¬eMessage, 1664 &releaseInfo, &py_options)) { 1665 1666 return NULL; 1667 } 1668 1669 if (!PyCallable_Check(beginDocument)) { 1670 PyErr_SetString(PyExc_TypeError, "beginDocument not callable"); 1671 return NULL; 1672 } 1673 if (!PyCallable_Check(endDocument)) { 1674 PyErr_SetString(PyExc_TypeError, "endDocument not callable"); 1675 return NULL; 1676 } 1677 if (!PyCallable_Check(beginPage)) { 1678 PyErr_SetString(PyExc_TypeError, "beginPage not callable"); 1679 return NULL; 1680 } 1681 if (!PyCallable_Check(endPage)) { 1682 PyErr_SetString(PyExc_TypeError, "endPage not callable"); 1683 return NULL; 1684 } 1685 if (!PyCallable_Check(noteProgress)) { 1686 PyErr_SetString(PyExc_TypeError, "noteProgress not callable"); 1687 return NULL; 1688 } 1689 if (!PyCallable_Check(noteMessage)) { 1690 PyErr_SetString(PyExc_TypeError, "noteMessage not callable"); 1691 return NULL; 1692 } 1693 if (PyObjC_PythonToObjC(@encode(CFDictionaryRef), py_options, &options)<0) { 1694 return NULL; 1695 } 1696 1697 PyObject* real_info = Py_BuildValue("OOOOOOOO", 1698 info, 1699 beginDocument, endDocument, 1700 beginPage, endPage, 1701 noteProgress, noteMessage, 1702 releaseInfo); 1703 1704 PyObjC_DURING 1705 result = CGPSConverterCreate(real_info, 1706 &m_CGPSConverterCallbacks, 1707 options); 1708 1709 PyObjC_HANDLER 1710 PyObjCErr_FromObjC(localException); 1711 PyObjC_ENDHANDLER 1712 1713 if (PyErr_Occurred()) { 1714 Py_DECREF(real_info); 1715 return NULL; 1716 } 1717 1718 PyObject* v = PyObjC_ObjCToPython(@encode(CGPSConverterRef), &result); 1719 CFRelease(result); 1720 return v; 1721} 1722 1723 1724static PyMethodDef mod_methods[] = { 1725 { 1726 "CGDataConsumerCreate", 1727 (PyCFunction)m_CGDataConsumerCreate, 1728 METH_VARARGS, 1729 doc_CGDataConsumerCreate 1730 }, 1731 1732#if PyObjC_BUILD_RELEASE >= 1005 1733 1734 { 1735 "CGDataProviderCreateSequential", 1736 (PyCFunction)m_CGDataProviderCreateSequential, 1737 METH_VARARGS, 1738 doc_CGDataProviderCreateSequential 1739 }, 1740 1741#endif 1742 { 1743 "CGDataProviderCreateWithData", 1744 (PyCFunction)m_CGDataProviderCreateWithData, 1745 METH_VARARGS, 1746 doc_CGDataProviderCreateWithData 1747 }, 1748 1749 { 1750 "CGFunctionCreate", 1751 (PyCFunction)m_CGFunctionCreate, 1752 METH_VARARGS, 1753 doc_CGFunctionCreate 1754 }, 1755 { 1756 "CGDisplayRegisterReconfigurationCallback", 1757 (PyCFunction)m_CGDisplayRegisterReconfigurationCallback, 1758 METH_VARARGS, 1759 NULL 1760 }, 1761 { 1762 "CGDisplayRemoveReconfigurationCallback", 1763 (PyCFunction)m_CGDisplayRemoveReconfigurationCallback, 1764 METH_VARARGS, 1765 NULL 1766 }, 1767 { 1768 "CGScreenRegisterMoveCallback", 1769 (PyCFunction)m_CGScreenRegisterMoveCallback, 1770 METH_VARARGS, 1771 NULL 1772 }, 1773 { 1774 "CGScreenUnregisterMoveCallback", 1775 (PyCFunction)m_CGScreenUnregisterMoveCallback, 1776 METH_VARARGS, 1777 NULL 1778 }, 1779 { 1780 "CGRegisterScreenRefreshCallback", 1781 (PyCFunction)m_CGRegisterScreenRefreshCallback, 1782 METH_VARARGS, 1783 NULL 1784 }, 1785 { 1786 "CGUnregisterScreenRefreshCallback", 1787 (PyCFunction)m_CGUnregisterScreenRefreshCallback, 1788 METH_VARARGS, 1789 NULL 1790 }, 1791 { 1792 "CGEventTapCreate", 1793 (PyCFunction)m_CGEventTapCreate, 1794 METH_VARARGS, 1795 NULL 1796 }, 1797 { 1798 "CGEventTapCreateForPSN", 1799 (PyCFunction)m_CGEventTapCreateForPSN, 1800 METH_VARARGS, 1801 NULL 1802 }, 1803 { 1804 "CGPatternCreate", 1805 (PyCFunction)m_CGPatternCreate, 1806 METH_VARARGS, 1807 NULL 1808 }, 1809 { 1810 "CGPSConverterCreate", 1811 (PyCFunction)m_CGPSConverterCreate, 1812 METH_VARARGS, 1813 NULL 1814 }, 1815 1816 { 0, 0, 0, } 1817}; 1818 1819PyObjC_MODULE_INIT(_callbacks) 1820{ 1821 PyObject* m = PyObjC_MODULE_CREATE(_callbacks); 1822 if (!m) PyObjC_INITERROR(); 1823 1824 PyObject* md = PyModule_GetDict(m); 1825 if (!md) PyObjC_INITERROR(); 1826 1827 if (PyObjC_ImportAPI(m) < 0) PyObjC_INITERROR(); 1828 1829#if PyObjC_BUILD_RELEASE >= 1005 1830 if (CGDataProviderCreateSequential == NULL) { 1831 if (PyDict_DelItemString(md, "CGDataProviderCreateSequential") < 0) { 1832 PyObjC_INITERROR(); 1833 } 1834 } 1835#endif 1836 1837 PyObjC_INITDONE(); 1838} 1839