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