1 /*********************************************************** 2 Copyright (C) 1994 Steen Lumholt. 3 4 All Rights Reserved 5 6 ******************************************************************/ 7 8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */ 9 10 /* TCL/TK VERSION INFO: 11 12 Only Tcl/Tk 8.3.1 and later are supported. Older versions are not 13 supported. Use Python 2.6 or older if you cannot upgrade your 14 Tcl/Tk libraries. 15 */ 16 17 /* XXX Further speed-up ideas, involving Tcl 8.0 features: 18 19 - Register a new Tcl type, "Python callable", which can be called more 20 efficiently and passed to Tcl_EvalObj() directly (if this is possible). 21 22 */ 23 24 25 #include "Python.h" 26 #include <ctype.h> 27 28 #ifdef WITH_THREAD 29 #include "pythread.h" 30 #endif 31 32 #ifdef MS_WINDOWS 33 #include <windows.h> 34 #endif 35 36 /* Allow using this code in Python 2.[12] */ 37 #ifndef PyDoc_STRVAR 38 #define PyDoc_STRVAR(name,str) static char name[] = str 39 #endif 40 41 #ifndef PyMODINIT_FUNC 42 #define PyMODINIT_FUNC void 43 #endif 44 45 #ifndef PyBool_Check 46 #define PyBool_Check(o) 0 47 #define PyBool_FromLong PyInt_FromLong 48 #endif 49 50 #define CHECK_SIZE(size, elemsize) \ 51 ((size_t)(size) <= (size_t)INT_MAX && \ 52 (size_t)(size) <= UINT_MAX / (size_t)(elemsize)) 53 54 /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, 55 making _tkinter correct for this API means breaking earlier 56 versions. USE_COMPAT_CONST allows making _tkinter work with both 8.4 and 57 earlier versions. Once Tcl releases before 8.4 don't need to be supported 58 anymore, this should go. */ 59 #define USE_COMPAT_CONST 60 61 /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define 62 it always; if Tcl is not threaded, the thread functions in 63 Tcl are empty. */ 64 #define TCL_THREADS 65 66 #ifdef TK_FRAMEWORK 67 #include <Tcl/tcl.h> 68 #include <Tk/tk.h> 69 #else 70 #include <tcl.h> 71 #include <tk.h> 72 #endif 73 74 #include "tkinter.h" 75 76 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ 77 #ifndef CONST84_RETURN 78 #define CONST84_RETURN 79 #undef CONST 80 #define CONST 81 #endif 82 83 #if TK_HEX_VERSION < 0x08030201 84 #error "Tk older than 8.3.1 not supported" 85 #endif 86 87 /* Unicode conversion assumes that Tcl_UniChar is two bytes. 88 We cannot test this directly, so we test UTF-8 size instead, 89 expecting that TCL_UTF_MAX is changed if Tcl ever supports 90 either UTF-16 or UCS-4. 91 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for 92 Tcl_Unichar. This is also ok as long as Python uses UCS-4, 93 as well. 94 */ 95 #if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6) 96 #error "unsupported Tcl configuration" 97 #endif 98 99 #if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ 100 TK_HEX_VERSION >= 0x08060200 101 #define HAVE_LIBTOMMAMTH 102 #include <tclTomMath.h> 103 #endif 104 105 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) 106 #define HAVE_CREATEFILEHANDLER 107 #endif 108 109 #ifdef HAVE_CREATEFILEHANDLER 110 111 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere 112 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ 113 #ifndef TCL_UNIX_FD 114 # ifdef TCL_WIN_SOCKET 115 # define TCL_UNIX_FD (! TCL_WIN_SOCKET) 116 # else 117 # define TCL_UNIX_FD 1 118 # endif 119 #endif 120 121 /* Tcl_CreateFileHandler() changed several times; these macros deal with the 122 messiness. In Tcl 8.0 and later, it is not available on Windows (and on 123 Unix, only because Jack added it back); when available on Windows, it only 124 applies to sockets. */ 125 126 #ifdef MS_WINDOWS 127 #define FHANDLETYPE TCL_WIN_SOCKET 128 #else 129 #define FHANDLETYPE TCL_UNIX_FD 130 #endif 131 132 /* If Tcl can wait for a Unix file descriptor, define the EventHook() routine 133 which uses this to handle Tcl events while the user is typing commands. */ 134 135 #if FHANDLETYPE == TCL_UNIX_FD 136 #define WAIT_FOR_STDIN 137 #endif 138 139 #endif /* HAVE_CREATEFILEHANDLER */ 140 141 #ifdef MS_WINDOWS 142 #include <conio.h> 143 #define WAIT_FOR_STDIN 144 #endif 145 146 #ifdef WITH_THREAD 147 148 /* The threading situation is complicated. Tcl is not thread-safe, except 149 when configured with --enable-threads. 150 So we need to use a lock around all uses of Tcl. Previously, the Python 151 interpreter lock was used for this. However, this causes problems when 152 other Python threads need to run while Tcl is blocked waiting for events. 153 154 To solve this problem, a separate lock for Tcl is introduced. Holding it 155 is incompatible with holding Python's interpreter lock. The following four 156 macros manipulate both locks together. 157 158 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and 159 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made 160 that could call an event handler, or otherwise affect the state of a Tcl 161 interpreter. These assume that the surrounding code has the Python 162 interpreter lock; inside the brackets, the Python interpreter lock has been 163 released and the lock for Tcl has been acquired. 164 165 Sometimes, it is necessary to have both the Python lock and the Tcl lock. 166 (For example, when transferring data from the Tcl interpreter result to a 167 Python string object.) This can be done by using different macros to close 168 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores 169 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL 170 releases the Tcl lock. 171 172 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event 173 handlers when the handler needs to use Python. Such event handlers are 174 entered while the lock for Tcl is held; the event handler presumably needs 175 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires 176 the Python interpreter lock, restoring the appropriate thread state, and 177 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock 178 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside 179 the code between ENTER_PYTHON and LEAVE_PYTHON. 180 181 These locks expand to several statements and brackets; they should not be 182 used in branches of if statements and the like. 183 184 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is 185 only valid in the thread that created it, and all Tk activity must happen in this 186 thread, also. That means that the mainloop must be invoked in the thread that 187 created the interpreter. Invoking commands from other threads is possible; 188 _tkinter will queue an event for the interpreter thread, which will then 189 execute the command and pass back the result. If the main thread is not in the 190 mainloop, and invoking commands causes an exception; if the main loop is running 191 but not processing events, the command invocation will block. 192 193 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient 194 anymore, since multiple Tcl interpreters may simultaneously dispatch in different 195 threads. So we use the Tcl TLS API. 196 197 */ 198 199 static PyThread_type_lock tcl_lock = 0; 200 201 #ifdef TCL_THREADS 202 static Tcl_ThreadDataKey state_key; 203 typedef PyThreadState *ThreadSpecificData; 204 #define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*))) 205 #else 206 static PyThreadState *tcl_tstate = NULL; 207 #endif 208 209 #define ENTER_TCL \ 210 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \ 211 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; 212 213 #define LEAVE_TCL \ 214 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS} 215 216 #define ENTER_OVERLAP \ 217 Py_END_ALLOW_THREADS 218 219 #define LEAVE_OVERLAP_TCL \ 220 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); } 221 222 #define ENTER_PYTHON \ 223 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \ 224 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); } 225 226 #define LEAVE_PYTHON \ 227 { PyThreadState *tstate = PyEval_SaveThread(); \ 228 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; } 229 230 #define CHECK_TCL_APPARTMENT \ 231 if (((TkappObject *)self)->threaded && \ 232 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \ 233 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \ 234 return 0; \ 235 } 236 237 #else 238 239 #define ENTER_TCL 240 #define LEAVE_TCL 241 #define ENTER_OVERLAP 242 #define LEAVE_OVERLAP_TCL 243 #define ENTER_PYTHON 244 #define LEAVE_PYTHON 245 #define CHECK_TCL_APPARTMENT 246 247 #endif 248 249 #ifndef FREECAST 250 #define FREECAST (char *) 251 #endif 252 253 /**** Tkapp Object Declaration ****/ 254 255 static PyTypeObject Tkapp_Type; 256 257 typedef struct { 258 PyObject_HEAD 259 Tcl_Interp *interp; 260 int wantobjects; 261 int threaded; /* True if tcl_platform[threaded] */ 262 Tcl_ThreadId thread_id; 263 int dispatching; 264 /* We cannot include tclInt.h, as this is internal. 265 So we cache interesting types here. */ 266 const Tcl_ObjType *OldBooleanType; 267 const Tcl_ObjType *BooleanType; 268 const Tcl_ObjType *ByteArrayType; 269 const Tcl_ObjType *DoubleType; 270 const Tcl_ObjType *IntType; 271 const Tcl_ObjType *WideIntType; 272 const Tcl_ObjType *BignumType; 273 const Tcl_ObjType *ListType; 274 const Tcl_ObjType *ProcBodyType; 275 const Tcl_ObjType *StringType; 276 } TkappObject; 277 278 #define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type) 279 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) 280 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) 281 282 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ 283 (void *) v, Py_REFCNT(v))) 284 285 286 287 /**** Error Handling ****/ 288 289 static PyObject *Tkinter_TclError; 290 static int quitMainLoop = 0; 291 static int errorInCmd = 0; 292 static PyObject *excInCmd; 293 static PyObject *valInCmd; 294 static PyObject *trbInCmd; 295 296 #ifdef TKINTER_PROTECT_LOADTK 297 static int tk_load_failed; 298 #endif 299 300 301 static PyObject * 302 Tkinter_Error(PyObject *v) 303 { 304 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); 305 return NULL; 306 } 307 308 309 310 /**** Utils ****/ 311 312 static int Tkinter_busywaitinterval = 20; 313 314 #ifdef WITH_THREAD 315 #ifndef MS_WINDOWS 316 317 /* Millisecond sleep() for Unix platforms. */ 318 319 static void 320 Sleep(int milli) 321 { 322 /* XXX Too bad if you don't have select(). */ 323 struct timeval t; 324 t.tv_sec = milli/1000; 325 t.tv_usec = (milli%1000) * 1000; 326 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); 327 } 328 #endif /* MS_WINDOWS */ 329 330 /* Wait up to 1s for the mainloop to come up. */ 331 332 static int 333 WaitForMainloop(TkappObject* self) 334 { 335 int i; 336 for (i = 0; i < 10; i++) { 337 if (self->dispatching) 338 return 1; 339 Py_BEGIN_ALLOW_THREADS 340 Sleep(100); 341 Py_END_ALLOW_THREADS 342 } 343 if (self->dispatching) 344 return 1; 345 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop"); 346 return 0; 347 } 348 #endif /* WITH_THREAD */ 349 350 351 static char * 352 AsString(PyObject *value, PyObject *tmp) 353 { 354 if (PyString_Check(value)) 355 return PyString_AsString(value); 356 #ifdef Py_USING_UNICODE 357 else if (PyUnicode_Check(value)) { 358 PyObject *v = PyUnicode_AsUTF8String(value); 359 if (v == NULL) 360 return NULL; 361 if (PyList_Append(tmp, v) != 0) { 362 Py_DECREF(v); 363 return NULL; 364 } 365 Py_DECREF(v); 366 return PyString_AsString(v); 367 } 368 #endif 369 else { 370 PyObject *v = PyObject_Str(value); 371 if (v == NULL) 372 return NULL; 373 if (PyList_Append(tmp, v) != 0) { 374 Py_DECREF(v); 375 return NULL; 376 } 377 Py_DECREF(v); 378 return PyString_AsString(v); 379 } 380 } 381 382 383 384 #define ARGSZ 64 385 386 static char * 387 Merge(PyObject *args) 388 { 389 PyObject *tmp = NULL; 390 char *argvStore[ARGSZ]; 391 char **argv = NULL; 392 int fvStore[ARGSZ]; 393 int *fv = NULL; 394 Py_ssize_t argc = 0, fvc = 0, i; 395 char *res = NULL; 396 397 if (!(tmp = PyList_New(0))) 398 return NULL; 399 400 argv = argvStore; 401 fv = fvStore; 402 403 if (args == NULL) 404 argc = 0; 405 406 else if (!PyTuple_Check(args)) { 407 argc = 1; 408 fv[0] = 0; 409 if (!(argv[0] = AsString(args, tmp))) 410 goto finally; 411 } 412 else { 413 argc = PyTuple_Size(args); 414 415 if (argc > ARGSZ) { 416 if (!CHECK_SIZE(argc, sizeof(char *))) { 417 PyErr_SetString(PyExc_OverflowError, "tuple is too long"); 418 goto finally; 419 } 420 argv = (char **)attemptckalloc((size_t)argc * sizeof(char *)); 421 fv = (int *)attemptckalloc((size_t)argc * sizeof(int)); 422 if (argv == NULL || fv == NULL) { 423 PyErr_NoMemory(); 424 goto finally; 425 } 426 } 427 428 for (i = 0; i < argc; i++) { 429 PyObject *v = PyTuple_GetItem(args, i); 430 if (PyTuple_Check(v)) { 431 fv[i] = 1; 432 if (!(argv[i] = Merge(v))) 433 goto finally; 434 fvc++; 435 } 436 else if (v == Py_None) { 437 argc = i; 438 break; 439 } 440 else { 441 fv[i] = 0; 442 if (!(argv[i] = AsString(v, tmp))) 443 goto finally; 444 fvc++; 445 } 446 } 447 } 448 res = Tcl_Merge(argc, argv); 449 if (res == NULL) 450 PyErr_SetString(Tkinter_TclError, "merge failed"); 451 452 finally: 453 for (i = 0; i < fvc; i++) 454 if (fv[i]) { 455 ckfree(argv[i]); 456 } 457 if (argv != argvStore) 458 ckfree(FREECAST argv); 459 if (fv != fvStore) 460 ckfree(FREECAST fv); 461 462 Py_DECREF(tmp); 463 return res; 464 } 465 466 467 468 #ifdef Py_USING_UNICODE 469 static PyObject * 470 unicode_FromTclStringAndSize(const char *s, Py_ssize_t size) 471 { 472 PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); 473 if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { 474 /* Tcl encodes null character as \xc0\x80 */ 475 if (memchr(s, '\xc0', size)) { 476 char *buf, *q; 477 const char *e = s + size; 478 PyErr_Clear(); 479 q = buf = (char *)PyMem_Malloc(size); 480 if (buf == NULL) { 481 PyErr_NoMemory(); 482 return NULL; 483 } 484 while (s != e) { 485 if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { 486 *q++ = '\0'; 487 s += 2; 488 } 489 else 490 *q++ = *s++; 491 } 492 s = buf; 493 size = q - s; 494 r = PyUnicode_DecodeUTF8(s, size, NULL); 495 PyMem_Free(buf); 496 } 497 } 498 return r; 499 } 500 #endif 501 502 static PyObject * 503 fromTclStringAndSize(const char *s, Py_ssize_t size) 504 { 505 PyObject *r; 506 #ifdef Py_USING_UNICODE 507 Py_ssize_t i; 508 /* If Tcl string contains any bytes with the top bit set, 509 it's UTF-8 and we should decode it to Unicode */ 510 for (i = 0; i < size; i++) 511 if (s[i] & 0x80) 512 break; 513 if (i != size) { 514 /* It isn't an ASCII string. */ 515 r = unicode_FromTclStringAndSize(s, size); 516 if (r) 517 return r; 518 PyErr_Clear(); 519 } 520 #endif 521 r = PyString_FromStringAndSize(s, size); 522 return r; 523 } 524 525 static PyObject * 526 fromTclString(const char *s) 527 { 528 return fromTclStringAndSize(s, strlen(s)); 529 } 530 531 532 static PyObject * 533 Split(char *list) 534 { 535 int argc; 536 char **argv; 537 PyObject *v; 538 539 if (list == NULL) { 540 Py_INCREF(Py_None); 541 return Py_None; 542 } 543 544 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { 545 /* Not a list. 546 * Could be a quoted string containing funnies, e.g. {"}. 547 * Return the string itself. 548 */ 549 return PyString_FromString(list); 550 } 551 552 if (argc == 0) 553 v = PyString_FromString(""); 554 else if (argc == 1) 555 v = PyString_FromString(argv[0]); 556 else if ((v = PyTuple_New(argc)) != NULL) { 557 int i; 558 PyObject *w; 559 560 for (i = 0; i < argc; i++) { 561 if ((w = Split(argv[i])) == NULL) { 562 Py_DECREF(v); 563 v = NULL; 564 break; 565 } 566 PyTuple_SetItem(v, i, w); 567 } 568 } 569 Tcl_Free(FREECAST argv); 570 return v; 571 } 572 573 /* In some cases, Tcl will still return strings that are supposed to be 574 lists. SplitObj walks through a nested tuple, finding string objects that 575 need to be split. */ 576 577 static PyObject * 578 SplitObj(PyObject *arg) 579 { 580 if (PyTuple_Check(arg)) { 581 int i, size; 582 PyObject *elem, *newelem, *result; 583 584 size = PyTuple_Size(arg); 585 result = NULL; 586 /* Recursively invoke SplitObj for all tuple items. 587 If this does not return a new object, no action is 588 needed. */ 589 for(i = 0; i < size; i++) { 590 elem = PyTuple_GetItem(arg, i); 591 newelem = SplitObj(elem); 592 if (!newelem) { 593 Py_XDECREF(result); 594 return NULL; 595 } 596 if (!result) { 597 int k; 598 if (newelem == elem) { 599 Py_DECREF(newelem); 600 continue; 601 } 602 result = PyTuple_New(size); 603 if (!result) 604 return NULL; 605 for(k = 0; k < i; k++) { 606 elem = PyTuple_GetItem(arg, k); 607 Py_INCREF(elem); 608 PyTuple_SetItem(result, k, elem); 609 } 610 } 611 PyTuple_SetItem(result, i, newelem); 612 } 613 if (result) 614 return result; 615 /* Fall through, returning arg. */ 616 } 617 else if (PyString_Check(arg)) { 618 int argc; 619 char **argv; 620 char *list = PyString_AsString(arg); 621 622 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { 623 Py_INCREF(arg); 624 return arg; 625 } 626 Tcl_Free(FREECAST argv); 627 if (argc > 1) 628 return Split(PyString_AsString(arg)); 629 /* Fall through, returning arg. */ 630 } 631 else if (PyUnicode_Check(arg)) { 632 int argc; 633 char **argv; 634 char *list; 635 PyObject *s = PyUnicode_AsUTF8String(arg); 636 637 if (s == NULL) { 638 Py_INCREF(arg); 639 return arg; 640 } 641 list = PyString_AsString(s); 642 643 if (list == NULL || 644 Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { 645 Py_DECREF(s); 646 Py_INCREF(arg); 647 return arg; 648 } 649 Tcl_Free(FREECAST argv); 650 if (argc > 1) { 651 PyObject *v = Split(list); 652 Py_DECREF(s); 653 return v; 654 } 655 Py_DECREF(s); 656 /* Fall through, returning arg. */ 657 } 658 Py_INCREF(arg); 659 return arg; 660 } 661 662 663 /**** Tkapp Object ****/ 664 665 #ifndef WITH_APPINIT 666 int 667 Tcl_AppInit(Tcl_Interp *interp) 668 { 669 const char * _tkinter_skip_tk_init; 670 671 if (Tcl_Init(interp) == TCL_ERROR) { 672 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp)); 673 return TCL_ERROR; 674 } 675 676 _tkinter_skip_tk_init = Tcl_GetVar(interp, 677 "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); 678 if (_tkinter_skip_tk_init != NULL && 679 strcmp(_tkinter_skip_tk_init, "1") == 0) { 680 return TCL_OK; 681 } 682 683 #ifdef TKINTER_PROTECT_LOADTK 684 if (tk_load_failed) { 685 PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG); 686 return TCL_ERROR; 687 } 688 #endif 689 690 if (Tk_Init(interp) == TCL_ERROR) { 691 #ifdef TKINTER_PROTECT_LOADTK 692 tk_load_failed = 1; 693 #endif 694 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp)); 695 return TCL_ERROR; 696 } 697 698 return TCL_OK; 699 } 700 #endif /* !WITH_APPINIT */ 701 702 703 704 705 /* Initialize the Tk application; see the `main' function in 706 * `tkMain.c'. 707 */ 708 709 static void EnableEventHook(void); /* Forward */ 710 static void DisableEventHook(void); /* Forward */ 711 712 static TkappObject * 713 Tkapp_New(char *screenName, char *baseName, char *className, 714 int interactive, int wantobjects, int wantTk, int sync, char *use) 715 { 716 TkappObject *v; 717 char *argv0; 718 719 v = PyObject_New(TkappObject, &Tkapp_Type); 720 if (v == NULL) 721 return NULL; 722 723 v->interp = Tcl_CreateInterp(); 724 v->wantobjects = wantobjects; 725 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded", 726 TCL_GLOBAL_ONLY) != NULL; 727 v->thread_id = Tcl_GetCurrentThread(); 728 v->dispatching = 0; 729 730 #ifndef TCL_THREADS 731 if (v->threaded) { 732 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not"); 733 Py_DECREF(v); 734 return 0; 735 } 736 #endif 737 #ifdef WITH_THREAD 738 if (v->threaded && tcl_lock) { 739 /* If Tcl is threaded, we don't need the lock. */ 740 PyThread_free_lock(tcl_lock); 741 tcl_lock = NULL; 742 } 743 #endif 744 745 v->OldBooleanType = Tcl_GetObjType("boolean"); 746 v->BooleanType = Tcl_GetObjType("booleanString"); 747 v->ByteArrayType = Tcl_GetObjType("bytearray"); 748 v->DoubleType = Tcl_GetObjType("double"); 749 v->IntType = Tcl_GetObjType("int"); 750 v->WideIntType = Tcl_GetObjType("wideInt"); 751 v->BignumType = Tcl_GetObjType("bignum"); 752 v->ListType = Tcl_GetObjType("list"); 753 v->ProcBodyType = Tcl_GetObjType("procbody"); 754 v->StringType = Tcl_GetObjType("string"); 755 756 /* Delete the 'exit' command, which can screw things up */ 757 Tcl_DeleteCommand(v->interp, "exit"); 758 759 if (screenName != NULL) 760 Tcl_SetVar2(v->interp, "env", "DISPLAY", 761 screenName, TCL_GLOBAL_ONLY); 762 763 if (interactive) 764 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); 765 else 766 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); 767 768 /* This is used to get the application class for Tk 4.1 and up */ 769 argv0 = (char*)attemptckalloc(strlen(className) + 1); 770 if (!argv0) { 771 PyErr_NoMemory(); 772 Py_DECREF(v); 773 return NULL; 774 } 775 776 strcpy(argv0, className); 777 if (Py_ISUPPER(Py_CHARMASK(argv0[0]))) 778 argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0])); 779 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); 780 ckfree(argv0); 781 782 if (! wantTk) { 783 Tcl_SetVar(v->interp, 784 "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY); 785 } 786 #ifdef TKINTER_PROTECT_LOADTK 787 else if (tk_load_failed) { 788 Tcl_SetVar(v->interp, 789 "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); 790 } 791 #endif 792 793 /* some initial arguments need to be in argv */ 794 if (sync || use) { 795 char *args; 796 int len = 0; 797 798 if (sync) 799 len += sizeof "-sync"; 800 if (use) 801 len += strlen(use) + sizeof "-use "; 802 803 args = (char*)attemptckalloc(len); 804 if (!args) { 805 PyErr_NoMemory(); 806 Py_DECREF(v); 807 return NULL; 808 } 809 810 args[0] = '\0'; 811 if (sync) 812 strcat(args, "-sync"); 813 if (use) { 814 if (sync) 815 strcat(args, " "); 816 strcat(args, "-use "); 817 strcat(args, use); 818 } 819 820 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); 821 ckfree(args); 822 } 823 824 if (Tcl_AppInit(v->interp) != TCL_OK) { 825 PyObject *result = Tkinter_Error((PyObject *)v); 826 #ifdef TKINTER_PROTECT_LOADTK 827 if (wantTk) { 828 const char *_tkinter_tk_failed; 829 _tkinter_tk_failed = Tcl_GetVar(v->interp, 830 "_tkinter_tk_failed", TCL_GLOBAL_ONLY); 831 832 if ( _tkinter_tk_failed != NULL && 833 strcmp(_tkinter_tk_failed, "1") == 0) { 834 tk_load_failed = 1; 835 } 836 } 837 #endif 838 Py_DECREF((PyObject *)v); 839 return (TkappObject *)result; 840 } 841 842 EnableEventHook(); 843 844 return v; 845 } 846 847 848 #ifdef WITH_THREAD 849 static void 850 Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev, 851 Tcl_Condition *cond, Tcl_Mutex *mutex) 852 { 853 Py_BEGIN_ALLOW_THREADS; 854 Tcl_MutexLock(mutex); 855 Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL); 856 Tcl_ThreadAlert(self->thread_id); 857 Tcl_ConditionWait(cond, mutex, NULL); 858 Tcl_MutexUnlock(mutex); 859 Py_END_ALLOW_THREADS 860 } 861 #endif 862 863 864 /** Tcl Eval **/ 865 866 typedef struct { 867 PyObject_HEAD 868 Tcl_Obj *value; 869 PyObject *string; /* This cannot cause cycles. */ 870 } PyTclObject; 871 872 staticforward PyTypeObject PyTclObject_Type; 873 #define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type) 874 875 static PyObject * 876 newPyTclObject(Tcl_Obj *arg) 877 { 878 PyTclObject *self; 879 self = PyObject_New(PyTclObject, &PyTclObject_Type); 880 if (self == NULL) 881 return NULL; 882 Tcl_IncrRefCount(arg); 883 self->value = arg; 884 self->string = NULL; 885 return (PyObject*)self; 886 } 887 888 static void 889 PyTclObject_dealloc(PyTclObject *self) 890 { 891 Tcl_DecrRefCount(self->value); 892 Py_XDECREF(self->string); 893 PyObject_Del(self); 894 } 895 896 static PyObject * 897 PyTclObject_str(PyTclObject *self) 898 { 899 if (self->string && PyString_Check(self->string)) { 900 Py_INCREF(self->string); 901 return self->string; 902 } 903 /* XXX Could cache value if it is an ASCII string. */ 904 return PyString_FromString(Tcl_GetString(self->value)); 905 } 906 907 static char* 908 PyTclObject_TclString(PyObject *self) 909 { 910 return Tcl_GetString(((PyTclObject*)self)->value); 911 } 912 913 /* Like _str, but create Unicode if necessary. */ 914 PyDoc_STRVAR(PyTclObject_string__doc__, 915 "the string representation of this object, either as string or Unicode"); 916 917 static PyObject * 918 PyTclObject_string(PyTclObject *self, void *ignored) 919 { 920 if (!self->string) { 921 int len; 922 char *s = Tcl_GetStringFromObj(self->value, &len); 923 self->string = fromTclStringAndSize(s, len); 924 if (!self->string) 925 return NULL; 926 } 927 Py_INCREF(self->string); 928 return self->string; 929 } 930 931 #ifdef Py_USING_UNICODE 932 PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode"); 933 934 static PyObject * 935 PyTclObject_unicode(PyTclObject *self, void *ignored) 936 { 937 char *s; 938 int len; 939 if (self->string && PyUnicode_Check(self->string)) { 940 Py_INCREF(self->string); 941 return self->string; 942 } 943 /* XXX Could chache result if it is non-ASCII. */ 944 s = Tcl_GetStringFromObj(self->value, &len); 945 return unicode_FromTclStringAndSize(s, len); 946 } 947 #endif 948 949 static PyObject * 950 PyTclObject_repr(PyTclObject *self) 951 { 952 char buf[50]; 953 PyOS_snprintf(buf, 50, "<%s object at %p>", 954 self->value->typePtr->name, self->value); 955 return PyString_FromString(buf); 956 } 957 958 static int 959 PyTclObject_cmp(PyTclObject *self, PyTclObject *other) 960 { 961 int res; 962 res = strcmp(Tcl_GetString(self->value), 963 Tcl_GetString(other->value)); 964 if (res < 0) return -1; 965 if (res > 0) return 1; 966 return 0; 967 } 968 969 PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); 970 971 static PyObject* 972 get_typename(PyTclObject* obj, void* ignored) 973 { 974 return PyString_FromString(obj->value->typePtr->name); 975 } 976 977 978 static PyGetSetDef PyTclObject_getsetlist[] = { 979 {"typename", (getter)get_typename, NULL, get_typename__doc__}, 980 {"string", (getter)PyTclObject_string, NULL, 981 PyTclObject_string__doc__}, 982 {0}, 983 }; 984 985 static PyMethodDef PyTclObject_methods[] = { 986 #ifdef Py_USING_UNICODE 987 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, 988 PyTclObject_unicode__doc__}, 989 #endif 990 {0} 991 }; 992 993 statichere PyTypeObject PyTclObject_Type = { 994 PyObject_HEAD_INIT(NULL) 995 0, /*ob_size*/ 996 "_tkinter.Tcl_Obj", /*tp_name*/ 997 sizeof(PyTclObject), /*tp_basicsize*/ 998 0, /*tp_itemsize*/ 999 /* methods */ 1000 (destructor)PyTclObject_dealloc, /*tp_dealloc*/ 1001 0, /*tp_print*/ 1002 0, /*tp_getattr*/ 1003 0, /*tp_setattr*/ 1004 (cmpfunc)PyTclObject_cmp, /*tp_compare*/ 1005 (reprfunc)PyTclObject_repr, /*tp_repr*/ 1006 0, /*tp_as_number*/ 1007 0, /*tp_as_sequence*/ 1008 0, /*tp_as_mapping*/ 1009 0, /*tp_hash*/ 1010 0, /*tp_call*/ 1011 (reprfunc)PyTclObject_str, /*tp_str*/ 1012 PyObject_GenericGetAttr,/*tp_getattro*/ 1013 0, /*tp_setattro*/ 1014 0, /*tp_as_buffer*/ 1015 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1016 0, /*tp_doc*/ 1017 0, /*tp_traverse*/ 1018 0, /*tp_clear*/ 1019 0, /*tp_richcompare*/ 1020 0, /*tp_weaklistoffset*/ 1021 0, /*tp_iter*/ 1022 0, /*tp_iternext*/ 1023 PyTclObject_methods, /*tp_methods*/ 1024 0, /*tp_members*/ 1025 PyTclObject_getsetlist, /*tp_getset*/ 1026 0, /*tp_base*/ 1027 0, /*tp_dict*/ 1028 0, /*tp_descr_get*/ 1029 0, /*tp_descr_set*/ 1030 0, /*tp_dictoffset*/ 1031 0, /*tp_init*/ 1032 0, /*tp_alloc*/ 1033 0, /*tp_new*/ 1034 0, /*tp_free*/ 1035 0, /*tp_is_gc*/ 1036 }; 1037 1038 #if PY_SIZE_MAX > INT_MAX 1039 #define CHECK_STRING_LENGTH(s) do { \ 1040 if (s != NULL && strlen(s) >= INT_MAX) { \ 1041 PyErr_SetString(PyExc_OverflowError, "string is too long"); \ 1042 return NULL; \ 1043 } } while(0) 1044 #else 1045 #define CHECK_STRING_LENGTH(s) 1046 #endif 1047 1048 #ifdef HAVE_LIBTOMMAMTH 1049 static Tcl_Obj* 1050 asBignumObj(PyObject *value) 1051 { 1052 Tcl_Obj *result; 1053 int neg; 1054 PyObject *hexstr; 1055 char *hexchars; 1056 mp_int bigValue; 1057 1058 neg = Py_SIZE(value) < 0; 1059 hexstr = _PyLong_Format(value, 16, 0, 1); 1060 if (hexstr == NULL) 1061 return NULL; 1062 hexchars = PyString_AsString(hexstr); 1063 if (hexchars == NULL) { 1064 Py_DECREF(hexstr); 1065 return NULL; 1066 } 1067 hexchars += neg + 2; /* skip sign and "0x" */ 1068 mp_init(&bigValue); 1069 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { 1070 mp_clear(&bigValue); 1071 Py_DECREF(hexstr); 1072 PyErr_NoMemory(); 1073 return NULL; 1074 } 1075 Py_DECREF(hexstr); 1076 bigValue.sign = neg ? MP_NEG : MP_ZPOS; 1077 result = Tcl_NewBignumObj(&bigValue); 1078 mp_clear(&bigValue); 1079 if (result == NULL) { 1080 PyErr_NoMemory(); 1081 return NULL; 1082 } 1083 return result; 1084 } 1085 #endif 1086 1087 static Tcl_Obj* 1088 AsObj(PyObject *value) 1089 { 1090 Tcl_Obj *result; 1091 1092 if (PyString_Check(value)) 1093 return Tcl_NewStringObj(PyString_AS_STRING(value), 1094 PyString_GET_SIZE(value)); 1095 1096 if (PyBool_Check(value)) 1097 return Tcl_NewBooleanObj(PyObject_IsTrue(value)); 1098 1099 if (PyInt_Check(value)) 1100 return Tcl_NewLongObj(PyInt_AS_LONG(value)); 1101 1102 if (PyLong_CheckExact(value)) { 1103 int overflow; 1104 long longValue; 1105 #ifdef TCL_WIDE_INT_TYPE 1106 Tcl_WideInt wideValue; 1107 #endif 1108 longValue = PyLong_AsLongAndOverflow(value, &overflow); 1109 if (!overflow) { 1110 return Tcl_NewLongObj(longValue); 1111 } 1112 /* If there is an overflow in the long conversion, 1113 fall through to wideInt handling. */ 1114 #ifdef TCL_WIDE_INT_TYPE 1115 if (_PyLong_AsByteArray((PyLongObject *)value, 1116 (unsigned char *)(void *)&wideValue, 1117 sizeof(wideValue), 1118 #ifdef WORDS_BIGENDIAN 1119 0, 1120 #else 1121 1, 1122 #endif 1123 /* signed */ 1) == 0) { 1124 return Tcl_NewWideIntObj(wideValue); 1125 } 1126 PyErr_Clear(); 1127 #endif 1128 /* If there is an overflow in the wideInt conversion, 1129 fall through to bignum handling. */ 1130 #ifdef HAVE_LIBTOMMAMTH 1131 return asBignumObj(value); 1132 #endif 1133 /* If there is no wideInt or bignum support, 1134 fall through to default object handling. */ 1135 } 1136 1137 if (PyFloat_Check(value)) 1138 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); 1139 1140 if (PyTuple_Check(value)) { 1141 Tcl_Obj **argv; 1142 Py_ssize_t size, i; 1143 1144 size = PyTuple_Size(value); 1145 if (size == 0) 1146 return Tcl_NewListObj(0, NULL); 1147 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { 1148 PyErr_SetString(PyExc_OverflowError, "tuple is too long"); 1149 return NULL; 1150 } 1151 argv = (Tcl_Obj **) attemptckalloc(((size_t)size) * sizeof(Tcl_Obj *)); 1152 if(!argv) 1153 return 0; 1154 for (i = 0; i < size; i++) 1155 argv[i] = AsObj(PyTuple_GetItem(value,i)); 1156 result = Tcl_NewListObj(PyTuple_Size(value), argv); 1157 ckfree(FREECAST argv); 1158 return result; 1159 } 1160 1161 #ifdef Py_USING_UNICODE 1162 if (PyUnicode_Check(value)) { 1163 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value); 1164 Py_ssize_t size = PyUnicode_GET_SIZE(value); 1165 /* This #ifdef assumes that Tcl uses UCS-2. 1166 See TCL_UTF_MAX test above. */ 1167 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3 1168 Tcl_UniChar *outbuf = NULL; 1169 Py_ssize_t i; 1170 size_t allocsize; 1171 if (size == 0) 1172 return Tcl_NewUnicodeObj((const void *)"", 0); 1173 if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { 1174 PyErr_SetString(PyExc_OverflowError, "string is too long"); 1175 return NULL; 1176 } 1177 if (sizeof(Py_UNICODE) == sizeof(Tcl_UniChar)) 1178 return Tcl_NewUnicodeObj(inbuf, size); 1179 allocsize = ((size_t)size) * sizeof(Tcl_UniChar); 1180 if (allocsize >= size) 1181 outbuf = (Tcl_UniChar*)attemptckalloc(allocsize); 1182 /* Else overflow occurred, and we take the next exit */ 1183 if (!outbuf) { 1184 PyErr_NoMemory(); 1185 return NULL; 1186 } 1187 for (i = 0; i < size; i++) { 1188 if (inbuf[i] >= 0x10000) { 1189 /* Tcl doesn't do UTF-16, yet. */ 1190 PyErr_Format(Tkinter_TclError, 1191 "character U+%x is above the range " 1192 "(U+0000-U+FFFF) allowed by Tcl", 1193 (int)inbuf[i]); 1194 ckfree(FREECAST outbuf); 1195 return NULL; 1196 } 1197 outbuf[i] = inbuf[i]; 1198 } 1199 result = Tcl_NewUnicodeObj(outbuf, size); 1200 ckfree(FREECAST outbuf); 1201 return result; 1202 #else 1203 return Tcl_NewUnicodeObj(inbuf, size); 1204 #endif 1205 } 1206 #endif 1207 1208 if(PyTclObject_Check(value)) { 1209 Tcl_Obj *v = ((PyTclObject*)value)->value; 1210 Tcl_IncrRefCount(v); 1211 return v; 1212 } 1213 1214 { 1215 PyObject *v = PyObject_Str(value); 1216 if (!v) 1217 return 0; 1218 result = AsObj(v); 1219 Py_DECREF(v); 1220 return result; 1221 } 1222 } 1223 1224 static PyObject * 1225 fromBoolean(PyObject* tkapp, Tcl_Obj *value) 1226 { 1227 int boolValue; 1228 if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) 1229 return Tkinter_Error(tkapp); 1230 return PyBool_FromLong(boolValue); 1231 } 1232 1233 #ifdef TCL_WIDE_INT_TYPE 1234 static PyObject* 1235 fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) 1236 { 1237 Tcl_WideInt wideValue; 1238 if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { 1239 #ifdef HAVE_LONG_LONG 1240 if (sizeof(wideValue) <= SIZEOF_LONG_LONG) 1241 return PyLong_FromLongLong(wideValue); 1242 #endif 1243 return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, 1244 sizeof(wideValue), 1245 #ifdef WORDS_BIGENDIAN 1246 0, 1247 #else 1248 1, 1249 #endif 1250 /* signed */ 1); 1251 } 1252 return NULL; 1253 } 1254 #endif 1255 1256 #ifdef HAVE_LIBTOMMAMTH 1257 static PyObject* 1258 fromBignumObj(PyObject* tkapp, Tcl_Obj *value) 1259 { 1260 mp_int bigValue; 1261 unsigned long numBytes; 1262 unsigned char *bytes; 1263 PyObject *res; 1264 1265 if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK) 1266 return Tkinter_Error(tkapp); 1267 numBytes = mp_unsigned_bin_size(&bigValue); 1268 bytes = PyMem_Malloc(numBytes); 1269 if (bytes == NULL) { 1270 mp_clear(&bigValue); 1271 return PyErr_NoMemory(); 1272 } 1273 if (mp_to_unsigned_bin_n(&bigValue, bytes, 1274 &numBytes) != MP_OKAY) { 1275 mp_clear(&bigValue); 1276 PyMem_Free(bytes); 1277 return PyErr_NoMemory(); 1278 } 1279 res = _PyLong_FromByteArray(bytes, numBytes, 1280 /* big-endian */ 0, 1281 /* unsigned */ 0); 1282 PyMem_Free(bytes); 1283 if (res != NULL && bigValue.sign == MP_NEG) { 1284 PyObject *res2 = PyNumber_Negative(res); 1285 Py_DECREF(res); 1286 res = res2; 1287 } 1288 mp_clear(&bigValue); 1289 return res; 1290 } 1291 #endif 1292 1293 static PyObject* 1294 FromObj(PyObject* tkapp, Tcl_Obj *value) 1295 { 1296 PyObject *result = NULL; 1297 TkappObject *app = (TkappObject*)tkapp; 1298 Tcl_Interp *interp = Tkapp_Interp(tkapp); 1299 1300 if (value->typePtr == NULL) { 1301 result = fromTclStringAndSize(value->bytes, value->length); 1302 return result; 1303 } 1304 1305 if (value->typePtr == app->BooleanType || 1306 value->typePtr == app->OldBooleanType) { 1307 return fromBoolean(tkapp, value); 1308 } 1309 1310 if (value->typePtr == app->ByteArrayType) { 1311 int size; 1312 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); 1313 return PyString_FromStringAndSize(data, size); 1314 } 1315 1316 if (value->typePtr == app->DoubleType) { 1317 return PyFloat_FromDouble(value->internalRep.doubleValue); 1318 } 1319 1320 if (value->typePtr == app->IntType) { 1321 long longValue; 1322 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) 1323 return PyInt_FromLong(longValue); 1324 /* If there is an error in the long conversion, 1325 fall through to wideInt handling. */ 1326 } 1327 1328 #ifdef TCL_WIDE_INT_TYPE 1329 if (value->typePtr == app->IntType || 1330 value->typePtr == app->WideIntType) { 1331 result = fromWideIntObj(tkapp, value); 1332 if (result != NULL || PyErr_Occurred()) 1333 return result; 1334 Tcl_ResetResult(interp); 1335 /* If there is an error in the wideInt conversion, 1336 fall through to bignum handling. */ 1337 } 1338 #endif 1339 1340 #ifdef HAVE_LIBTOMMAMTH 1341 if (value->typePtr == app->IntType || 1342 value->typePtr == app->WideIntType || 1343 value->typePtr == app->BignumType) { 1344 return fromBignumObj(tkapp, value); 1345 } 1346 #endif 1347 1348 if (value->typePtr == app->ListType) { 1349 int size; 1350 int i, status; 1351 PyObject *elem; 1352 Tcl_Obj *tcl_elem; 1353 1354 status = Tcl_ListObjLength(interp, value, &size); 1355 if (status == TCL_ERROR) 1356 return Tkinter_Error(tkapp); 1357 result = PyTuple_New(size); 1358 if (!result) 1359 return NULL; 1360 for (i = 0; i < size; i++) { 1361 status = Tcl_ListObjIndex(interp, value, i, &tcl_elem); 1362 if (status == TCL_ERROR) { 1363 Py_DECREF(result); 1364 return Tkinter_Error(tkapp); 1365 } 1366 elem = FromObj(tkapp, tcl_elem); 1367 if (!elem) { 1368 Py_DECREF(result); 1369 return NULL; 1370 } 1371 PyTuple_SetItem(result, i, elem); 1372 } 1373 return result; 1374 } 1375 1376 if (value->typePtr == app->ProcBodyType) { 1377 /* fall through: return tcl object. */ 1378 } 1379 1380 if (value->typePtr == app->StringType) { 1381 #ifdef Py_USING_UNICODE 1382 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3 1383 PyObject *result; 1384 int size; 1385 Tcl_UniChar *input; 1386 Py_UNICODE *output; 1387 1388 size = Tcl_GetCharLength(value); 1389 result = PyUnicode_FromUnicode(NULL, size); 1390 if (!result) 1391 return NULL; 1392 input = Tcl_GetUnicode(value); 1393 output = PyUnicode_AS_UNICODE(result); 1394 while (size--) 1395 *output++ = *input++; 1396 return result; 1397 #else 1398 return PyUnicode_FromUnicode(Tcl_GetUnicode(value), 1399 Tcl_GetCharLength(value)); 1400 #endif 1401 #else 1402 int size; 1403 char *c; 1404 c = Tcl_GetStringFromObj(value, &size); 1405 return PyString_FromStringAndSize(c, size); 1406 #endif 1407 } 1408 1409 #if TK_HEX_VERSION >= 0x08050000 1410 if (app->BooleanType == NULL && 1411 strcmp(value->typePtr->name, "booleanString") == 0) { 1412 /* booleanString type is not registered in Tcl */ 1413 app->BooleanType = value->typePtr; 1414 return fromBoolean(tkapp, value); 1415 } 1416 #endif 1417 1418 #ifdef HAVE_LIBTOMMAMTH 1419 if (app->BignumType == NULL && 1420 strcmp(value->typePtr->name, "bignum") == 0) { 1421 /* bignum type is not registered in Tcl */ 1422 app->BignumType = value->typePtr; 1423 return fromBignumObj(tkapp, value); 1424 } 1425 #endif 1426 1427 return newPyTclObject(value); 1428 } 1429 1430 #ifdef WITH_THREAD 1431 /* This mutex synchronizes inter-thread command calls. */ 1432 TCL_DECLARE_MUTEX(call_mutex) 1433 1434 typedef struct Tkapp_CallEvent { 1435 Tcl_Event ev; /* Must be first */ 1436 TkappObject *self; 1437 PyObject *args; 1438 int flags; 1439 PyObject **res; 1440 PyObject **exc_type, **exc_value, **exc_tb; 1441 Tcl_Condition *done; 1442 } Tkapp_CallEvent; 1443 #endif 1444 1445 void 1446 Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) 1447 { 1448 int i; 1449 for (i = 0; i < objc; i++) 1450 Tcl_DecrRefCount(objv[i]); 1451 if (objv != objStore) 1452 ckfree(FREECAST objv); 1453 } 1454 1455 /* Convert Python objects to Tcl objects. This must happen in the 1456 interpreter thread, which may or may not be the calling thread. */ 1457 1458 static Tcl_Obj** 1459 Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) 1460 { 1461 Tcl_Obj **objv = objStore; 1462 Py_ssize_t objc = 0, i; 1463 if (args == NULL) 1464 /* do nothing */; 1465 1466 else if (!PyTuple_Check(args)) { 1467 objv[0] = AsObj(args); 1468 if (objv[0] == 0) 1469 goto finally; 1470 objc = 1; 1471 Tcl_IncrRefCount(objv[0]); 1472 } 1473 else { 1474 objc = PyTuple_Size(args); 1475 1476 if (objc > ARGSZ) { 1477 if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { 1478 PyErr_SetString(PyExc_OverflowError, "tuple is too long"); 1479 return NULL; 1480 } 1481 objv = (Tcl_Obj **)attemptckalloc(((size_t)objc) * sizeof(Tcl_Obj *)); 1482 if (objv == NULL) { 1483 PyErr_NoMemory(); 1484 objc = 0; 1485 goto finally; 1486 } 1487 } 1488 1489 for (i = 0; i < objc; i++) { 1490 PyObject *v = PyTuple_GetItem(args, i); 1491 if (v == Py_None) { 1492 objc = i; 1493 break; 1494 } 1495 objv[i] = AsObj(v); 1496 if (!objv[i]) { 1497 /* Reset objc, so it attempts to clear 1498 objects only up to i. */ 1499 objc = i; 1500 goto finally; 1501 } 1502 Tcl_IncrRefCount(objv[i]); 1503 } 1504 } 1505 *pobjc = objc; 1506 return objv; 1507 finally: 1508 Tkapp_CallDeallocArgs(objv, objStore, objc); 1509 return NULL; 1510 } 1511 1512 /* Convert the results of a command call into a Python objects. */ 1513 1514 static PyObject* 1515 Tkapp_CallResult(TkappObject *self) 1516 { 1517 PyObject *res = NULL; 1518 Tcl_Obj *value = Tcl_GetObjResult(self->interp); 1519 if(self->wantobjects) { 1520 /* Not sure whether the IncrRef is necessary, but something 1521 may overwrite the interpreter result while we are 1522 converting it. */ 1523 Tcl_IncrRefCount(value); 1524 res = FromObj((PyObject*)self, value); 1525 Tcl_DecrRefCount(value); 1526 } else { 1527 int len; 1528 const char *s = Tcl_GetStringFromObj(value, &len); 1529 res = fromTclStringAndSize(s, len); 1530 } 1531 return res; 1532 } 1533 1534 #ifdef WITH_THREAD 1535 1536 /* Tkapp_CallProc is the event procedure that is executed in the context of 1537 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't 1538 hold the Python lock. */ 1539 1540 static int 1541 Tkapp_CallProc(Tkapp_CallEvent *e, int flags) 1542 { 1543 Tcl_Obj *objStore[ARGSZ]; 1544 Tcl_Obj **objv; 1545 int objc; 1546 int i; 1547 ENTER_PYTHON 1548 objv = Tkapp_CallArgs(e->args, objStore, &objc); 1549 if (!objv) { 1550 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); 1551 *(e->res) = NULL; 1552 } 1553 LEAVE_PYTHON 1554 if (!objv) 1555 goto done; 1556 i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); 1557 ENTER_PYTHON 1558 if (i == TCL_ERROR) { 1559 *(e->res) = NULL; 1560 *(e->exc_type) = NULL; 1561 *(e->exc_tb) = NULL; 1562 *(e->exc_value) = PyObject_CallFunction( 1563 Tkinter_TclError, "s", 1564 Tcl_GetStringResult(e->self->interp)); 1565 } 1566 else { 1567 *(e->res) = Tkapp_CallResult(e->self); 1568 } 1569 LEAVE_PYTHON 1570 1571 Tkapp_CallDeallocArgs(objv, objStore, objc); 1572 done: 1573 /* Wake up calling thread. */ 1574 Tcl_MutexLock(&call_mutex); 1575 Tcl_ConditionNotify(e->done); 1576 Tcl_MutexUnlock(&call_mutex); 1577 return 1; 1578 } 1579 1580 #endif 1581 1582 /* This is the main entry point for calling a Tcl command. 1583 It supports three cases, with regard to threading: 1584 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in 1585 the context of the calling thread. 1586 2. Tcl is threaded, caller of the command is in the interpreter thread: 1587 Execute the command in the calling thread. Since the Tcl lock will 1588 not be used, we can merge that with case 1. 1589 3. Tcl is threaded, caller is in a different thread: Must queue an event to 1590 the interpreter thread. Allocation of Tcl objects needs to occur in the 1591 interpreter thread, so we ship the PyObject* args to the target thread, 1592 and perform processing there. */ 1593 1594 static PyObject * 1595 Tkapp_Call(PyObject *selfptr, PyObject *args) 1596 { 1597 Tcl_Obj *objStore[ARGSZ]; 1598 Tcl_Obj **objv = NULL; 1599 int objc, i; 1600 PyObject *res = NULL; 1601 TkappObject *self = (TkappObject*)selfptr; 1602 int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL; 1603 1604 /* If args is a single tuple, replace with contents of tuple */ 1605 if (1 == PyTuple_Size(args)){ 1606 PyObject* item = PyTuple_GetItem(args, 0); 1607 if (PyTuple_Check(item)) 1608 args = item; 1609 } 1610 #ifdef WITH_THREAD 1611 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 1612 /* We cannot call the command directly. Instead, we must 1613 marshal the parameters to the interpreter thread. */ 1614 Tkapp_CallEvent *ev; 1615 Tcl_Condition cond = NULL; 1616 PyObject *exc_type, *exc_value, *exc_tb; 1617 if (!WaitForMainloop(self)) 1618 return NULL; 1619 ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent)); 1620 if (ev == NULL) { 1621 PyErr_NoMemory(); 1622 return NULL; 1623 } 1624 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; 1625 ev->self = self; 1626 ev->args = args; 1627 ev->res = &res; 1628 ev->exc_type = &exc_type; 1629 ev->exc_value = &exc_value; 1630 ev->exc_tb = &exc_tb; 1631 ev->done = &cond; 1632 1633 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); 1634 1635 if (res == NULL) { 1636 if (exc_type) 1637 PyErr_Restore(exc_type, exc_value, exc_tb); 1638 else 1639 PyErr_SetObject(Tkinter_TclError, exc_value); 1640 } 1641 Tcl_ConditionFinalize(&cond); 1642 } 1643 else 1644 #endif 1645 { 1646 1647 objv = Tkapp_CallArgs(args, objStore, &objc); 1648 if (!objv) 1649 return NULL; 1650 1651 ENTER_TCL 1652 1653 i = Tcl_EvalObjv(self->interp, objc, objv, flags); 1654 1655 ENTER_OVERLAP 1656 1657 if (i == TCL_ERROR) 1658 Tkinter_Error(selfptr); 1659 else 1660 res = Tkapp_CallResult(self); 1661 1662 LEAVE_OVERLAP_TCL 1663 1664 Tkapp_CallDeallocArgs(objv, objStore, objc); 1665 } 1666 return res; 1667 } 1668 1669 1670 static PyObject * 1671 Tkapp_GlobalCall(PyObject *self, PyObject *args) 1672 { 1673 /* Could do the same here as for Tkapp_Call(), but this is not used 1674 much, so I can't be bothered. Unfortunately Tcl doesn't export a 1675 way for the user to do what all its Global* variants do (save and 1676 reset the scope pointer, call the local version, restore the saved 1677 scope pointer). */ 1678 1679 char *cmd; 1680 PyObject *res = NULL; 1681 1682 CHECK_TCL_APPARTMENT; 1683 1684 cmd = Merge(args); 1685 if (cmd) { 1686 int err; 1687 ENTER_TCL 1688 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd); 1689 ENTER_OVERLAP 1690 if (err == TCL_ERROR) 1691 res = Tkinter_Error(self); 1692 else 1693 res = PyString_FromString(Tkapp_Result(self)); 1694 LEAVE_OVERLAP_TCL 1695 ckfree(cmd); 1696 } 1697 1698 return res; 1699 } 1700 1701 static PyObject * 1702 Tkapp_Eval(PyObject *self, PyObject *args) 1703 { 1704 char *script; 1705 PyObject *res = NULL; 1706 int err; 1707 1708 if (!PyArg_ParseTuple(args, "s:eval", &script)) 1709 return NULL; 1710 1711 CHECK_STRING_LENGTH(script); 1712 CHECK_TCL_APPARTMENT; 1713 1714 ENTER_TCL 1715 err = Tcl_Eval(Tkapp_Interp(self), script); 1716 ENTER_OVERLAP 1717 if (err == TCL_ERROR) 1718 res = Tkinter_Error(self); 1719 else 1720 res = PyString_FromString(Tkapp_Result(self)); 1721 LEAVE_OVERLAP_TCL 1722 return res; 1723 } 1724 1725 static PyObject * 1726 Tkapp_GlobalEval(PyObject *self, PyObject *args) 1727 { 1728 char *script; 1729 PyObject *res = NULL; 1730 int err; 1731 1732 if (!PyArg_ParseTuple(args, "s:globaleval", &script)) 1733 return NULL; 1734 1735 CHECK_TCL_APPARTMENT; 1736 1737 ENTER_TCL 1738 err = Tcl_GlobalEval(Tkapp_Interp(self), script); 1739 ENTER_OVERLAP 1740 if (err == TCL_ERROR) 1741 res = Tkinter_Error(self); 1742 else 1743 res = PyString_FromString(Tkapp_Result(self)); 1744 LEAVE_OVERLAP_TCL 1745 return res; 1746 } 1747 1748 static PyObject * 1749 Tkapp_EvalFile(PyObject *self, PyObject *args) 1750 { 1751 char *fileName; 1752 PyObject *res = NULL; 1753 int err; 1754 1755 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName)) 1756 return NULL; 1757 1758 CHECK_STRING_LENGTH(fileName); 1759 CHECK_TCL_APPARTMENT; 1760 1761 ENTER_TCL 1762 err = Tcl_EvalFile(Tkapp_Interp(self), fileName); 1763 ENTER_OVERLAP 1764 if (err == TCL_ERROR) 1765 res = Tkinter_Error(self); 1766 1767 else 1768 res = PyString_FromString(Tkapp_Result(self)); 1769 LEAVE_OVERLAP_TCL 1770 return res; 1771 } 1772 1773 static PyObject * 1774 Tkapp_Record(PyObject *self, PyObject *args) 1775 { 1776 char *script; 1777 PyObject *res = NULL; 1778 int err; 1779 1780 if (!PyArg_ParseTuple(args, "s:record", &script)) 1781 return NULL; 1782 1783 CHECK_STRING_LENGTH(script); 1784 CHECK_TCL_APPARTMENT; 1785 1786 ENTER_TCL 1787 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); 1788 ENTER_OVERLAP 1789 if (err == TCL_ERROR) 1790 res = Tkinter_Error(self); 1791 else 1792 res = PyString_FromString(Tkapp_Result(self)); 1793 LEAVE_OVERLAP_TCL 1794 return res; 1795 } 1796 1797 static PyObject * 1798 Tkapp_AddErrorInfo(PyObject *self, PyObject *args) 1799 { 1800 char *msg; 1801 1802 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg)) 1803 return NULL; 1804 CHECK_STRING_LENGTH(msg); 1805 CHECK_TCL_APPARTMENT; 1806 1807 ENTER_TCL 1808 Tcl_AddErrorInfo(Tkapp_Interp(self), msg); 1809 LEAVE_TCL 1810 1811 Py_INCREF(Py_None); 1812 return Py_None; 1813 } 1814 1815 1816 1817 /** Tcl Variable **/ 1818 1819 typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags); 1820 1821 #ifdef WITH_THREAD 1822 TCL_DECLARE_MUTEX(var_mutex) 1823 1824 typedef struct VarEvent { 1825 Tcl_Event ev; /* must be first */ 1826 PyObject *self; 1827 PyObject *args; 1828 int flags; 1829 EventFunc func; 1830 PyObject **res; 1831 PyObject **exc_type; 1832 PyObject **exc_val; 1833 Tcl_Condition *cond; 1834 } VarEvent; 1835 #endif 1836 1837 static int 1838 varname_converter(PyObject *in, void *_out) 1839 { 1840 char *s; 1841 char **out = (char**)_out; 1842 if (PyString_Check(in)) { 1843 if (PyString_Size(in) > INT_MAX) { 1844 PyErr_SetString(PyExc_OverflowError, "string is too long"); 1845 return 0; 1846 } 1847 s = PyString_AsString(in); 1848 if (strlen(s) != PyString_Size(in)) { 1849 PyErr_SetString(PyExc_ValueError, "null character in string"); 1850 return 0; 1851 } 1852 *out = s; 1853 return 1; 1854 } 1855 if (PyTclObject_Check(in)) { 1856 *out = PyTclObject_TclString(in); 1857 return 1; 1858 } 1859 PyErr_Format(PyExc_TypeError, 1860 "must be str or Tcl_Obj, not %.50s", 1861 in->ob_type->tp_name); 1862 return 0; 1863 } 1864 1865 #ifdef WITH_THREAD 1866 1867 static void 1868 var_perform(VarEvent *ev) 1869 { 1870 *(ev->res) = ev->func(ev->self, ev->args, ev->flags); 1871 if (!*(ev->res)) { 1872 PyObject *exc, *val, *tb; 1873 PyErr_Fetch(&exc, &val, &tb); 1874 PyErr_NormalizeException(&exc, &val, &tb); 1875 *(ev->exc_type) = exc; 1876 *(ev->exc_val) = val; 1877 Py_XDECREF(tb); 1878 } 1879 1880 } 1881 1882 static int 1883 var_proc(VarEvent* ev, int flags) 1884 { 1885 ENTER_PYTHON 1886 var_perform(ev); 1887 Tcl_MutexLock(&var_mutex); 1888 Tcl_ConditionNotify(ev->cond); 1889 Tcl_MutexUnlock(&var_mutex); 1890 LEAVE_PYTHON 1891 return 1; 1892 } 1893 1894 #endif 1895 1896 static PyObject* 1897 var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) 1898 { 1899 #ifdef WITH_THREAD 1900 TkappObject *self = (TkappObject*)selfptr; 1901 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 1902 TkappObject *self = (TkappObject*)selfptr; 1903 VarEvent *ev; 1904 PyObject *res, *exc_type, *exc_val; 1905 Tcl_Condition cond = NULL; 1906 1907 /* The current thread is not the interpreter thread. Marshal 1908 the call to the interpreter thread, then wait for 1909 completion. */ 1910 if (!WaitForMainloop(self)) 1911 return NULL; 1912 1913 ev = (VarEvent*)attemptckalloc(sizeof(VarEvent)); 1914 if (ev == NULL) { 1915 PyErr_NoMemory(); 1916 return NULL; 1917 } 1918 ev->self = selfptr; 1919 ev->args = args; 1920 ev->flags = flags; 1921 ev->func = func; 1922 ev->res = &res; 1923 ev->exc_type = &exc_type; 1924 ev->exc_val = &exc_val; 1925 ev->cond = &cond; 1926 ev->ev.proc = (Tcl_EventProc*)var_proc; 1927 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); 1928 Tcl_ConditionFinalize(&cond); 1929 if (!res) { 1930 PyErr_SetObject(exc_type, exc_val); 1931 Py_DECREF(exc_type); 1932 Py_DECREF(exc_val); 1933 return NULL; 1934 } 1935 return res; 1936 } 1937 #endif 1938 /* Tcl is not threaded, or this is the interpreter thread. */ 1939 return func(selfptr, args, flags); 1940 } 1941 1942 static PyObject * 1943 SetVar(PyObject *self, PyObject *args, int flags) 1944 { 1945 char *name1, *name2; 1946 PyObject *newValue; 1947 PyObject *res = NULL; 1948 Tcl_Obj *newval, *ok; 1949 1950 switch (PyTuple_GET_SIZE(args)) { 1951 case 2: 1952 if (!PyArg_ParseTuple(args, "O&O:setvar", 1953 varname_converter, &name1, &newValue)) 1954 return NULL; 1955 /* XXX Acquire tcl lock??? */ 1956 newval = AsObj(newValue); 1957 if (newval == NULL) 1958 return NULL; 1959 ENTER_TCL 1960 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, 1961 newval, flags); 1962 ENTER_OVERLAP 1963 if (!ok) 1964 Tkinter_Error(self); 1965 else { 1966 res = Py_None; 1967 Py_INCREF(res); 1968 } 1969 LEAVE_OVERLAP_TCL 1970 break; 1971 case 3: 1972 if (!PyArg_ParseTuple(args, "ssO:setvar", 1973 &name1, &name2, &newValue)) 1974 return NULL; 1975 CHECK_STRING_LENGTH(name1); 1976 CHECK_STRING_LENGTH(name2); 1977 /* XXX must hold tcl lock already??? */ 1978 newval = AsObj(newValue); 1979 ENTER_TCL 1980 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); 1981 ENTER_OVERLAP 1982 if (!ok) 1983 Tkinter_Error(self); 1984 else { 1985 res = Py_None; 1986 Py_INCREF(res); 1987 } 1988 LEAVE_OVERLAP_TCL 1989 break; 1990 default: 1991 PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments"); 1992 return NULL; 1993 } 1994 return res; 1995 } 1996 1997 static PyObject * 1998 Tkapp_SetVar(PyObject *self, PyObject *args) 1999 { 2000 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG); 2001 } 2002 2003 static PyObject * 2004 Tkapp_GlobalSetVar(PyObject *self, PyObject *args) 2005 { 2006 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 2007 } 2008 2009 2010 2011 static PyObject * 2012 GetVar(PyObject *self, PyObject *args, int flags) 2013 { 2014 char *name1, *name2=NULL; 2015 PyObject *res = NULL; 2016 Tcl_Obj *tres; 2017 2018 if (!PyArg_ParseTuple(args, "O&|s:getvar", 2019 varname_converter, &name1, &name2)) 2020 return NULL; 2021 2022 CHECK_STRING_LENGTH(name2); 2023 ENTER_TCL 2024 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); 2025 ENTER_OVERLAP 2026 if (tres == NULL) { 2027 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self))); 2028 } else { 2029 if (((TkappObject*)self)->wantobjects) { 2030 res = FromObj(self, tres); 2031 } 2032 else { 2033 int len; 2034 char *s = Tcl_GetStringFromObj(tres, &len); 2035 res = PyString_FromStringAndSize(s, len); 2036 } 2037 } 2038 LEAVE_OVERLAP_TCL 2039 return res; 2040 } 2041 2042 static PyObject * 2043 Tkapp_GetVar(PyObject *self, PyObject *args) 2044 { 2045 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG); 2046 } 2047 2048 static PyObject * 2049 Tkapp_GlobalGetVar(PyObject *self, PyObject *args) 2050 { 2051 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 2052 } 2053 2054 2055 2056 static PyObject * 2057 UnsetVar(PyObject *self, PyObject *args, int flags) 2058 { 2059 char *name1, *name2=NULL; 2060 int code; 2061 PyObject *res = NULL; 2062 2063 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) 2064 return NULL; 2065 2066 CHECK_STRING_LENGTH(name1); 2067 CHECK_STRING_LENGTH(name2); 2068 ENTER_TCL 2069 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); 2070 ENTER_OVERLAP 2071 if (code == TCL_ERROR) 2072 res = Tkinter_Error(self); 2073 else { 2074 Py_INCREF(Py_None); 2075 res = Py_None; 2076 } 2077 LEAVE_OVERLAP_TCL 2078 return res; 2079 } 2080 2081 static PyObject * 2082 Tkapp_UnsetVar(PyObject *self, PyObject *args) 2083 { 2084 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG); 2085 } 2086 2087 static PyObject * 2088 Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args) 2089 { 2090 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 2091 } 2092 2093 2094 2095 /** Tcl to Python **/ 2096 2097 static PyObject * 2098 Tkapp_GetInt(PyObject *self, PyObject *args) 2099 { 2100 char *s; 2101 #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH) 2102 Tcl_Obj *value; 2103 PyObject *result; 2104 #else 2105 int intValue; 2106 #endif 2107 2108 if (PyTuple_Size(args) == 1) { 2109 PyObject* o = PyTuple_GetItem(args, 0); 2110 if (PyInt_Check(o) || PyLong_Check(o)) { 2111 Py_INCREF(o); 2112 return o; 2113 } 2114 } 2115 if (!PyArg_ParseTuple(args, "s:getint", &s)) 2116 return NULL; 2117 CHECK_STRING_LENGTH(s); 2118 #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH) 2119 value = Tcl_NewStringObj(s, -1); 2120 if (value == NULL) 2121 return Tkinter_Error(self); 2122 /* Don't use Tcl_GetInt() because it returns ambiguous result for value 2123 in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). 2124 2125 Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for 2126 value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). 2127 */ 2128 #ifdef HAVE_LIBTOMMAMTH 2129 result = fromBignumObj(self, value); 2130 #else 2131 result = fromWideIntObj(self, value); 2132 #endif 2133 Tcl_DecrRefCount(value); 2134 if (result != NULL) 2135 return PyNumber_Int(result); 2136 if (PyErr_Occurred()) 2137 return NULL; 2138 #else 2139 if (Tcl_GetInt(Tkapp_Interp(self), s, &intValue) == TCL_OK) 2140 return PyInt_FromLong(intValue); 2141 #endif 2142 return Tkinter_Error(self); 2143 } 2144 2145 static PyObject * 2146 Tkapp_GetDouble(PyObject *self, PyObject *args) 2147 { 2148 char *s; 2149 double v; 2150 2151 if (PyTuple_Size(args) == 1) { 2152 PyObject *o = PyTuple_GetItem(args, 0); 2153 if (PyFloat_Check(o)) { 2154 Py_INCREF(o); 2155 return o; 2156 } 2157 } 2158 if (!PyArg_ParseTuple(args, "s:getdouble", &s)) 2159 return NULL; 2160 CHECK_STRING_LENGTH(s); 2161 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) 2162 return Tkinter_Error(self); 2163 return Py_BuildValue("d", v); 2164 } 2165 2166 static PyObject * 2167 Tkapp_GetBoolean(PyObject *self, PyObject *arg) 2168 { 2169 char *s; 2170 int v; 2171 2172 if (PyInt_Check(arg)) /* int or bool */ 2173 return PyBool_FromLong(PyInt_AS_LONG(arg)); 2174 2175 if (PyLong_Check(arg)) 2176 return PyBool_FromLong(Py_SIZE(arg) != 0); 2177 2178 if (PyTclObject_Check(arg)) { 2179 if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), 2180 ((PyTclObject*)arg)->value, 2181 &v) == TCL_ERROR) 2182 return Tkinter_Error(self); 2183 return PyBool_FromLong(v); 2184 } 2185 2186 if (!PyArg_Parse(arg, "s:getboolean", &s)) 2187 return NULL; 2188 CHECK_STRING_LENGTH(s); 2189 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) 2190 return Tkinter_Error(self); 2191 return PyBool_FromLong(v); 2192 } 2193 2194 static PyObject * 2195 Tkapp_ExprString(PyObject *self, PyObject *args) 2196 { 2197 char *s; 2198 PyObject *res = NULL; 2199 int retval; 2200 2201 if (!PyArg_ParseTuple(args, "s:exprstring", &s)) 2202 return NULL; 2203 2204 CHECK_STRING_LENGTH(s); 2205 CHECK_TCL_APPARTMENT; 2206 2207 ENTER_TCL 2208 retval = Tcl_ExprString(Tkapp_Interp(self), s); 2209 ENTER_OVERLAP 2210 if (retval == TCL_ERROR) 2211 res = Tkinter_Error(self); 2212 else 2213 res = PyString_FromString(Tkapp_Result(self)); 2214 LEAVE_OVERLAP_TCL 2215 return res; 2216 } 2217 2218 static PyObject * 2219 Tkapp_ExprLong(PyObject *self, PyObject *args) 2220 { 2221 char *s; 2222 PyObject *res = NULL; 2223 int retval; 2224 long v; 2225 2226 if (!PyArg_ParseTuple(args, "s:exprlong", &s)) 2227 return NULL; 2228 2229 CHECK_STRING_LENGTH(s); 2230 CHECK_TCL_APPARTMENT; 2231 2232 ENTER_TCL 2233 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); 2234 ENTER_OVERLAP 2235 if (retval == TCL_ERROR) 2236 res = Tkinter_Error(self); 2237 else 2238 res = Py_BuildValue("l", v); 2239 LEAVE_OVERLAP_TCL 2240 return res; 2241 } 2242 2243 static PyObject * 2244 Tkapp_ExprDouble(PyObject *self, PyObject *args) 2245 { 2246 char *s; 2247 PyObject *res = NULL; 2248 double v; 2249 int retval; 2250 2251 if (!PyArg_ParseTuple(args, "s:exprdouble", &s)) 2252 return NULL; 2253 CHECK_STRING_LENGTH(s); 2254 CHECK_TCL_APPARTMENT; 2255 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) 2256 ENTER_TCL 2257 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); 2258 ENTER_OVERLAP 2259 PyFPE_END_PROTECT(retval) 2260 if (retval == TCL_ERROR) 2261 res = Tkinter_Error(self); 2262 else 2263 res = Py_BuildValue("d", v); 2264 LEAVE_OVERLAP_TCL 2265 return res; 2266 } 2267 2268 static PyObject * 2269 Tkapp_ExprBoolean(PyObject *self, PyObject *args) 2270 { 2271 char *s; 2272 PyObject *res = NULL; 2273 int retval; 2274 int v; 2275 2276 if (!PyArg_ParseTuple(args, "s:exprboolean", &s)) 2277 return NULL; 2278 CHECK_STRING_LENGTH(s); 2279 CHECK_TCL_APPARTMENT; 2280 ENTER_TCL 2281 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); 2282 ENTER_OVERLAP 2283 if (retval == TCL_ERROR) 2284 res = Tkinter_Error(self); 2285 else 2286 res = Py_BuildValue("i", v); 2287 LEAVE_OVERLAP_TCL 2288 return res; 2289 } 2290 2291 2292 2293 static PyObject * 2294 Tkapp_SplitList(PyObject *self, PyObject *args) 2295 { 2296 char *list; 2297 int argc; 2298 char **argv; 2299 PyObject *arg, *v; 2300 int i; 2301 2302 if (!PyArg_ParseTuple(args, "O:splitlist", &arg)) 2303 return NULL; 2304 if (PyTclObject_Check(arg)) { 2305 int objc; 2306 Tcl_Obj **objv; 2307 if (Tcl_ListObjGetElements(Tkapp_Interp(self), 2308 ((PyTclObject*)arg)->value, 2309 &objc, &objv) == TCL_ERROR) { 2310 return Tkinter_Error(self); 2311 } 2312 if (!(v = PyTuple_New(objc))) 2313 return NULL; 2314 for (i = 0; i < objc; i++) { 2315 PyObject *s = FromObj(self, objv[i]); 2316 if (!s || PyTuple_SetItem(v, i, s)) { 2317 Py_DECREF(v); 2318 return NULL; 2319 } 2320 } 2321 return v; 2322 } 2323 if (PyTuple_Check(arg)) { 2324 Py_INCREF(arg); 2325 return arg; 2326 } 2327 2328 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) 2329 return NULL; 2330 2331 CHECK_STRING_LENGTH(list); 2332 if (Tcl_SplitList(Tkapp_Interp(self), list, 2333 &argc, &argv) == TCL_ERROR) { 2334 PyMem_Free(list); 2335 return Tkinter_Error(self); 2336 } 2337 2338 if (!(v = PyTuple_New(argc))) 2339 goto finally; 2340 2341 for (i = 0; i < argc; i++) { 2342 PyObject *s = PyString_FromString(argv[i]); 2343 if (!s || PyTuple_SetItem(v, i, s)) { 2344 Py_DECREF(v); 2345 v = NULL; 2346 goto finally; 2347 } 2348 } 2349 2350 finally: 2351 ckfree(FREECAST argv); 2352 PyMem_Free(list); 2353 return v; 2354 } 2355 2356 static PyObject * 2357 Tkapp_Split(PyObject *self, PyObject *args) 2358 { 2359 PyObject *arg, *v; 2360 char *list; 2361 2362 if (!PyArg_ParseTuple(args, "O:split", &arg)) 2363 return NULL; 2364 if (PyTclObject_Check(arg)) { 2365 Tcl_Obj *value = ((PyTclObject*)arg)->value; 2366 int objc; 2367 Tcl_Obj **objv; 2368 int i; 2369 if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, 2370 &objc, &objv) == TCL_ERROR) { 2371 return FromObj(self, value); 2372 } 2373 if (objc == 0) 2374 return PyString_FromString(""); 2375 if (objc == 1) 2376 return FromObj(self, objv[0]); 2377 if (!(v = PyTuple_New(objc))) 2378 return NULL; 2379 for (i = 0; i < objc; i++) { 2380 PyObject *s = FromObj(self, objv[i]); 2381 if (!s || PyTuple_SetItem(v, i, s)) { 2382 Py_DECREF(v); 2383 return NULL; 2384 } 2385 } 2386 return v; 2387 } 2388 if (PyTuple_Check(arg)) 2389 return SplitObj(arg); 2390 2391 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) 2392 return NULL; 2393 CHECK_STRING_LENGTH(list); 2394 v = Split(list); 2395 PyMem_Free(list); 2396 return v; 2397 } 2398 2399 static PyObject * 2400 Tkapp_Merge(PyObject *self, PyObject *args) 2401 { 2402 char *s = Merge(args); 2403 PyObject *res = NULL; 2404 2405 if (s) { 2406 res = PyString_FromString(s); 2407 ckfree(s); 2408 } 2409 2410 return res; 2411 } 2412 2413 2414 2415 /** Tcl Command **/ 2416 2417 /* Client data struct */ 2418 typedef struct { 2419 PyObject *self; 2420 PyObject *func; 2421 } PythonCmd_ClientData; 2422 2423 static int 2424 PythonCmd_Error(Tcl_Interp *interp) 2425 { 2426 errorInCmd = 1; 2427 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 2428 LEAVE_PYTHON 2429 return TCL_ERROR; 2430 } 2431 2432 /* This is the Tcl command that acts as a wrapper for Python 2433 * function or method. 2434 */ 2435 static int 2436 PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) 2437 { 2438 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; 2439 PyObject *func, *arg, *res; 2440 int i, rv; 2441 Tcl_Obj *obj_res; 2442 2443 ENTER_PYTHON 2444 2445 /* TBD: no error checking here since we know, via the 2446 * Tkapp_CreateCommand() that the client data is a two-tuple 2447 */ 2448 func = data->func; 2449 2450 /* Create argument list (argv1, ..., argvN) */ 2451 if (!(arg = PyTuple_New(argc - 1))) 2452 return PythonCmd_Error(interp); 2453 2454 for (i = 0; i < (argc - 1); i++) { 2455 PyObject *s = fromTclString(argv[i + 1]); 2456 if (!s || PyTuple_SetItem(arg, i, s)) { 2457 Py_DECREF(arg); 2458 return PythonCmd_Error(interp); 2459 } 2460 } 2461 res = PyEval_CallObject(func, arg); 2462 Py_DECREF(arg); 2463 2464 if (res == NULL) 2465 return PythonCmd_Error(interp); 2466 2467 obj_res = AsObj(res); 2468 if (obj_res == NULL) { 2469 Py_DECREF(res); 2470 return PythonCmd_Error(interp); 2471 } 2472 else { 2473 Tcl_SetObjResult(interp, obj_res); 2474 rv = TCL_OK; 2475 } 2476 2477 Py_DECREF(res); 2478 2479 LEAVE_PYTHON 2480 2481 return rv; 2482 } 2483 2484 static void 2485 PythonCmdDelete(ClientData clientData) 2486 { 2487 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; 2488 2489 ENTER_PYTHON 2490 Py_XDECREF(data->self); 2491 Py_XDECREF(data->func); 2492 PyMem_DEL(data); 2493 LEAVE_PYTHON 2494 } 2495 2496 2497 2498 2499 #ifdef WITH_THREAD 2500 TCL_DECLARE_MUTEX(command_mutex) 2501 2502 typedef struct CommandEvent{ 2503 Tcl_Event ev; 2504 Tcl_Interp* interp; 2505 char *name; 2506 int create; 2507 int *status; 2508 ClientData *data; 2509 Tcl_Condition *done; 2510 } CommandEvent; 2511 2512 static int 2513 Tkapp_CommandProc(CommandEvent *ev, int flags) 2514 { 2515 if (ev->create) 2516 *ev->status = Tcl_CreateCommand( 2517 ev->interp, ev->name, PythonCmd, 2518 ev->data, PythonCmdDelete) == NULL; 2519 else 2520 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name); 2521 Tcl_MutexLock(&command_mutex); 2522 Tcl_ConditionNotify(ev->done); 2523 Tcl_MutexUnlock(&command_mutex); 2524 return 1; 2525 } 2526 #endif 2527 2528 static PyObject * 2529 Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) 2530 { 2531 TkappObject *self = (TkappObject*)selfptr; 2532 PythonCmd_ClientData *data; 2533 char *cmdName; 2534 PyObject *func; 2535 int err; 2536 2537 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func)) 2538 return NULL; 2539 CHECK_STRING_LENGTH(cmdName); 2540 if (!PyCallable_Check(func)) { 2541 PyErr_SetString(PyExc_TypeError, "command not callable"); 2542 return NULL; 2543 } 2544 2545 #ifdef WITH_THREAD 2546 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() && 2547 !WaitForMainloop(self)) 2548 return NULL; 2549 #endif 2550 2551 data = PyMem_NEW(PythonCmd_ClientData, 1); 2552 if (!data) 2553 return PyErr_NoMemory(); 2554 Py_INCREF(self); 2555 Py_INCREF(func); 2556 data->self = selfptr; 2557 data->func = func; 2558 2559 #ifdef WITH_THREAD 2560 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 2561 Tcl_Condition cond = NULL; 2562 CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); 2563 if (ev == NULL) { 2564 PyErr_NoMemory(); 2565 PyMem_DEL(data); 2566 return NULL; 2567 } 2568 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 2569 ev->interp = self->interp; 2570 ev->create = 1; 2571 ev->name = cmdName; 2572 ev->data = (ClientData)data; 2573 ev->status = &err; 2574 ev->done = &cond; 2575 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); 2576 Tcl_ConditionFinalize(&cond); 2577 } 2578 else 2579 #endif 2580 { 2581 ENTER_TCL 2582 err = Tcl_CreateCommand( 2583 Tkapp_Interp(self), cmdName, PythonCmd, 2584 (ClientData)data, PythonCmdDelete) == NULL; 2585 LEAVE_TCL 2586 } 2587 if (err) { 2588 PyErr_SetString(Tkinter_TclError, "can't create Tcl command"); 2589 PyMem_DEL(data); 2590 return NULL; 2591 } 2592 2593 Py_INCREF(Py_None); 2594 return Py_None; 2595 } 2596 2597 2598 2599 static PyObject * 2600 Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) 2601 { 2602 TkappObject *self = (TkappObject*)selfptr; 2603 char *cmdName; 2604 int err; 2605 2606 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName)) 2607 return NULL; 2608 CHECK_STRING_LENGTH(cmdName); 2609 2610 #ifdef WITH_THREAD 2611 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 2612 Tcl_Condition cond = NULL; 2613 CommandEvent *ev; 2614 ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); 2615 if (ev == NULL) { 2616 PyErr_NoMemory(); 2617 return NULL; 2618 } 2619 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 2620 ev->interp = self->interp; 2621 ev->create = 0; 2622 ev->name = cmdName; 2623 ev->status = &err; 2624 ev->done = &cond; 2625 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, 2626 &command_mutex); 2627 Tcl_ConditionFinalize(&cond); 2628 } 2629 else 2630 #endif 2631 { 2632 ENTER_TCL 2633 err = Tcl_DeleteCommand(self->interp, cmdName); 2634 LEAVE_TCL 2635 } 2636 if (err == -1) { 2637 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command"); 2638 return NULL; 2639 } 2640 Py_INCREF(Py_None); 2641 return Py_None; 2642 } 2643 2644 2645 2646 #ifdef HAVE_CREATEFILEHANDLER 2647 /** File Handler **/ 2648 2649 typedef struct _fhcdata { 2650 PyObject *func; 2651 PyObject *file; 2652 int id; 2653 struct _fhcdata *next; 2654 } FileHandler_ClientData; 2655 2656 static FileHandler_ClientData *HeadFHCD; 2657 2658 static FileHandler_ClientData * 2659 NewFHCD(PyObject *func, PyObject *file, int id) 2660 { 2661 FileHandler_ClientData *p; 2662 p = PyMem_NEW(FileHandler_ClientData, 1); 2663 if (p != NULL) { 2664 Py_XINCREF(func); 2665 Py_XINCREF(file); 2666 p->func = func; 2667 p->file = file; 2668 p->id = id; 2669 p->next = HeadFHCD; 2670 HeadFHCD = p; 2671 } 2672 return p; 2673 } 2674 2675 static void 2676 DeleteFHCD(int id) 2677 { 2678 FileHandler_ClientData *p, **pp; 2679 2680 pp = &HeadFHCD; 2681 while ((p = *pp) != NULL) { 2682 if (p->id == id) { 2683 *pp = p->next; 2684 Py_XDECREF(p->func); 2685 Py_XDECREF(p->file); 2686 PyMem_DEL(p); 2687 } 2688 else 2689 pp = &p->next; 2690 } 2691 } 2692 2693 static void 2694 FileHandler(ClientData clientData, int mask) 2695 { 2696 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData; 2697 PyObject *func, *file, *arg, *res; 2698 2699 ENTER_PYTHON 2700 func = data->func; 2701 file = data->file; 2702 2703 arg = Py_BuildValue("(Oi)", file, (long) mask); 2704 res = PyEval_CallObject(func, arg); 2705 Py_DECREF(arg); 2706 2707 if (res == NULL) { 2708 errorInCmd = 1; 2709 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 2710 } 2711 Py_XDECREF(res); 2712 LEAVE_PYTHON 2713 } 2714 2715 static PyObject * 2716 Tkapp_CreateFileHandler(PyObject *self, PyObject *args) 2717 /* args is (file, mask, func) */ 2718 { 2719 FileHandler_ClientData *data; 2720 PyObject *file, *func; 2721 int mask, tfile; 2722 2723 if (!self && Py_Py3kWarningFlag) { 2724 if (PyErr_Warn(PyExc_DeprecationWarning, 2725 "_tkinter.createfilehandler is gone in 3.x") < 0) 2726 return NULL; 2727 } 2728 2729 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", 2730 &file, &mask, &func)) 2731 return NULL; 2732 2733 #ifdef WITH_THREAD 2734 if (!self && !tcl_lock) { 2735 /* We don't have the Tcl lock since Tcl is threaded. */ 2736 PyErr_SetString(PyExc_RuntimeError, 2737 "_tkinter.createfilehandler not supported " 2738 "for threaded Tcl"); 2739 return NULL; 2740 } 2741 #endif 2742 2743 if (self) { 2744 CHECK_TCL_APPARTMENT; 2745 } 2746 2747 tfile = PyObject_AsFileDescriptor(file); 2748 if (tfile < 0) 2749 return NULL; 2750 if (!PyCallable_Check(func)) { 2751 PyErr_SetString(PyExc_TypeError, "bad argument list"); 2752 return NULL; 2753 } 2754 2755 data = NewFHCD(func, file, tfile); 2756 if (data == NULL) 2757 return NULL; 2758 2759 /* Ought to check for null Tcl_File object... */ 2760 ENTER_TCL 2761 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data); 2762 LEAVE_TCL 2763 Py_INCREF(Py_None); 2764 return Py_None; 2765 } 2766 2767 static PyObject * 2768 Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) 2769 { 2770 PyObject *file; 2771 int tfile; 2772 2773 if (!self && Py_Py3kWarningFlag) { 2774 if (PyErr_Warn(PyExc_DeprecationWarning, 2775 "_tkinter.deletefilehandler is gone in 3.x") < 0) 2776 return NULL; 2777 } 2778 2779 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) 2780 return NULL; 2781 2782 #ifdef WITH_THREAD 2783 if (!self && !tcl_lock) { 2784 /* We don't have the Tcl lock since Tcl is threaded. */ 2785 PyErr_SetString(PyExc_RuntimeError, 2786 "_tkinter.deletefilehandler not supported " 2787 "for threaded Tcl"); 2788 return NULL; 2789 } 2790 #endif 2791 2792 if (self) { 2793 CHECK_TCL_APPARTMENT; 2794 } 2795 2796 tfile = PyObject_AsFileDescriptor(file); 2797 if (tfile < 0) 2798 return NULL; 2799 2800 DeleteFHCD(tfile); 2801 2802 /* Ought to check for null Tcl_File object... */ 2803 ENTER_TCL 2804 Tcl_DeleteFileHandler(tfile); 2805 LEAVE_TCL 2806 Py_INCREF(Py_None); 2807 return Py_None; 2808 } 2809 #endif /* HAVE_CREATEFILEHANDLER */ 2810 2811 2812 /**** Tktt Object (timer token) ****/ 2813 2814 static PyTypeObject Tktt_Type; 2815 2816 typedef struct { 2817 PyObject_HEAD 2818 Tcl_TimerToken token; 2819 PyObject *func; 2820 } TkttObject; 2821 2822 static PyObject * 2823 Tktt_DeleteTimerHandler(PyObject *self, PyObject *args) 2824 { 2825 TkttObject *v = (TkttObject *)self; 2826 PyObject *func = v->func; 2827 2828 if (!PyArg_ParseTuple(args, ":deletetimerhandler")) 2829 return NULL; 2830 if (v->token != NULL) { 2831 Tcl_DeleteTimerHandler(v->token); 2832 v->token = NULL; 2833 } 2834 if (func != NULL) { 2835 v->func = NULL; 2836 Py_DECREF(func); 2837 Py_DECREF(v); /* See Tktt_New() */ 2838 } 2839 Py_INCREF(Py_None); 2840 return Py_None; 2841 } 2842 2843 static PyMethodDef Tktt_methods[] = 2844 { 2845 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS}, 2846 {NULL, NULL} 2847 }; 2848 2849 static TkttObject * 2850 Tktt_New(PyObject *func) 2851 { 2852 TkttObject *v; 2853 2854 v = PyObject_New(TkttObject, &Tktt_Type); 2855 if (v == NULL) 2856 return NULL; 2857 2858 Py_INCREF(func); 2859 v->token = NULL; 2860 v->func = func; 2861 2862 /* Extra reference, deleted when called or when handler is deleted */ 2863 Py_INCREF(v); 2864 return v; 2865 } 2866 2867 static void 2868 Tktt_Dealloc(PyObject *self) 2869 { 2870 TkttObject *v = (TkttObject *)self; 2871 PyObject *func = v->func; 2872 2873 Py_XDECREF(func); 2874 2875 PyObject_Del(self); 2876 } 2877 2878 static PyObject * 2879 Tktt_Repr(PyObject *self) 2880 { 2881 TkttObject *v = (TkttObject *)self; 2882 char buf[100]; 2883 2884 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v, 2885 v->func == NULL ? ", handler deleted" : ""); 2886 return PyString_FromString(buf); 2887 } 2888 2889 static PyObject * 2890 Tktt_GetAttr(PyObject *self, char *name) 2891 { 2892 return Py_FindMethod(Tktt_methods, self, name); 2893 } 2894 2895 static PyTypeObject Tktt_Type = 2896 { 2897 PyVarObject_HEAD_INIT(NULL, 0) 2898 "tktimertoken", /*tp_name */ 2899 sizeof(TkttObject), /*tp_basicsize */ 2900 0, /*tp_itemsize */ 2901 Tktt_Dealloc, /*tp_dealloc */ 2902 0, /*tp_print */ 2903 Tktt_GetAttr, /*tp_getattr */ 2904 0, /*tp_setattr */ 2905 0, /*tp_compare */ 2906 Tktt_Repr, /*tp_repr */ 2907 0, /*tp_as_number */ 2908 0, /*tp_as_sequence */ 2909 0, /*tp_as_mapping */ 2910 0, /*tp_hash */ 2911 }; 2912 2913 2914 2915 /** Timer Handler **/ 2916 2917 static void 2918 TimerHandler(ClientData clientData) 2919 { 2920 TkttObject *v = (TkttObject *)clientData; 2921 PyObject *func = v->func; 2922 PyObject *res; 2923 2924 if (func == NULL) 2925 return; 2926 2927 v->func = NULL; 2928 2929 ENTER_PYTHON 2930 2931 res = PyEval_CallObject(func, NULL); 2932 Py_DECREF(func); 2933 Py_DECREF(v); /* See Tktt_New() */ 2934 2935 if (res == NULL) { 2936 errorInCmd = 1; 2937 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 2938 } 2939 else 2940 Py_DECREF(res); 2941 2942 LEAVE_PYTHON 2943 } 2944 2945 static PyObject * 2946 Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) 2947 { 2948 int milliseconds; 2949 PyObject *func; 2950 TkttObject *v; 2951 2952 if (!self && Py_Py3kWarningFlag) { 2953 if (PyErr_Warn(PyExc_DeprecationWarning, 2954 "_tkinter.createtimerhandler is gone in 3.x") < 0) 2955 return NULL; 2956 } 2957 2958 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", 2959 &milliseconds, &func)) 2960 return NULL; 2961 if (!PyCallable_Check(func)) { 2962 PyErr_SetString(PyExc_TypeError, "bad argument list"); 2963 return NULL; 2964 } 2965 2966 #ifdef WITH_THREAD 2967 if (!self && !tcl_lock) { 2968 /* We don't have the Tcl lock since Tcl is threaded. */ 2969 PyErr_SetString(PyExc_RuntimeError, 2970 "_tkinter.createtimerhandler not supported " 2971 "for threaded Tcl"); 2972 return NULL; 2973 } 2974 #endif 2975 2976 if (self) { 2977 CHECK_TCL_APPARTMENT; 2978 } 2979 2980 v = Tktt_New(func); 2981 if (v) { 2982 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, 2983 (ClientData)v); 2984 } 2985 2986 return (PyObject *) v; 2987 } 2988 2989 2990 /** Event Loop **/ 2991 2992 static PyObject * 2993 Tkapp_MainLoop(PyObject *selfptr, PyObject *args) 2994 { 2995 int threshold = 0; 2996 TkappObject *self = (TkappObject*)selfptr; 2997 #ifdef WITH_THREAD 2998 PyThreadState *tstate = PyThreadState_Get(); 2999 #endif 3000 3001 if (!self && Py_Py3kWarningFlag) { 3002 if (PyErr_Warn(PyExc_DeprecationWarning, 3003 "_tkinter.mainloop is gone in 3.x") < 0) 3004 return NULL; 3005 } 3006 3007 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) 3008 return NULL; 3009 3010 #ifdef WITH_THREAD 3011 if (!self && !tcl_lock) { 3012 /* We don't have the Tcl lock since Tcl is threaded. */ 3013 PyErr_SetString(PyExc_RuntimeError, 3014 "_tkinter.mainloop not supported " 3015 "for threaded Tcl"); 3016 return NULL; 3017 } 3018 #endif 3019 3020 if (self) { 3021 CHECK_TCL_APPARTMENT; 3022 self->dispatching = 1; 3023 } 3024 3025 quitMainLoop = 0; 3026 while (Tk_GetNumMainWindows() > threshold && 3027 !quitMainLoop && 3028 !errorInCmd) 3029 { 3030 int result; 3031 3032 #ifdef WITH_THREAD 3033 if (self && self->threaded) { 3034 /* Allow other Python threads to run. */ 3035 ENTER_TCL 3036 result = Tcl_DoOneEvent(0); 3037 LEAVE_TCL 3038 } 3039 else { 3040 Py_BEGIN_ALLOW_THREADS 3041 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); 3042 tcl_tstate = tstate; 3043 result = Tcl_DoOneEvent(TCL_DONT_WAIT); 3044 tcl_tstate = NULL; 3045 if(tcl_lock)PyThread_release_lock(tcl_lock); 3046 if (result == 0) 3047 Sleep(Tkinter_busywaitinterval); 3048 Py_END_ALLOW_THREADS 3049 } 3050 #else 3051 result = Tcl_DoOneEvent(0); 3052 #endif 3053 3054 if (PyErr_CheckSignals() != 0) { 3055 if (self) 3056 self->dispatching = 0; 3057 return NULL; 3058 } 3059 if (result < 0) 3060 break; 3061 } 3062 if (self) 3063 self->dispatching = 0; 3064 quitMainLoop = 0; 3065 3066 if (errorInCmd) { 3067 errorInCmd = 0; 3068 PyErr_Restore(excInCmd, valInCmd, trbInCmd); 3069 excInCmd = valInCmd = trbInCmd = NULL; 3070 return NULL; 3071 } 3072 Py_INCREF(Py_None); 3073 return Py_None; 3074 } 3075 3076 static PyObject * 3077 Tkapp_DoOneEvent(PyObject *self, PyObject *args) 3078 { 3079 int flags = 0; 3080 int rv; 3081 3082 if (!self && Py_Py3kWarningFlag) { 3083 if (PyErr_Warn(PyExc_DeprecationWarning, 3084 "_tkinter.dooneevent is gone in 3.x") < 0) 3085 return NULL; 3086 } 3087 3088 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) 3089 return NULL; 3090 3091 ENTER_TCL 3092 rv = Tcl_DoOneEvent(flags); 3093 LEAVE_TCL 3094 return Py_BuildValue("i", rv); 3095 } 3096 3097 static PyObject * 3098 Tkapp_Quit(PyObject *self, PyObject *args) 3099 { 3100 3101 if (!self && Py_Py3kWarningFlag) { 3102 if (PyErr_Warn(PyExc_DeprecationWarning, 3103 "_tkinter.quit is gone in 3.x") < 0) 3104 return NULL; 3105 } 3106 3107 if (!PyArg_ParseTuple(args, ":quit")) 3108 return NULL; 3109 3110 quitMainLoop = 1; 3111 Py_INCREF(Py_None); 3112 return Py_None; 3113 } 3114 3115 static PyObject * 3116 Tkapp_InterpAddr(PyObject *self, PyObject *args) 3117 { 3118 3119 if (!PyArg_ParseTuple(args, ":interpaddr")) 3120 return NULL; 3121 3122 return PyLong_FromVoidPtr(Tkapp_Interp(self)); 3123 } 3124 3125 static PyObject * 3126 Tkapp_TkInit(PyObject *self, PyObject *args) 3127 { 3128 Tcl_Interp *interp = Tkapp_Interp(self); 3129 const char * _tk_exists = NULL; 3130 int err; 3131 3132 #ifdef TKINTER_PROTECT_LOADTK 3133 /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the 3134 * first call failed. 3135 * To avoid the deadlock, we just refuse the second call through 3136 * a static variable. 3137 */ 3138 if (tk_load_failed) { 3139 PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG); 3140 return NULL; 3141 } 3142 #endif 3143 3144 /* We want to guard against calling Tk_Init() multiple times */ 3145 CHECK_TCL_APPARTMENT; 3146 ENTER_TCL 3147 err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version"); 3148 ENTER_OVERLAP 3149 if (err == TCL_ERROR) { 3150 /* This sets an exception, but we cannot return right 3151 away because we need to exit the overlap first. */ 3152 Tkinter_Error(self); 3153 } else { 3154 _tk_exists = Tkapp_Result(self); 3155 } 3156 LEAVE_OVERLAP_TCL 3157 if (err == TCL_ERROR) { 3158 return NULL; 3159 } 3160 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { 3161 if (Tk_Init(interp) == TCL_ERROR) { 3162 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self))); 3163 #ifdef TKINTER_PROTECT_LOADTK 3164 tk_load_failed = 1; 3165 #endif 3166 return NULL; 3167 } 3168 } 3169 Py_INCREF(Py_None); 3170 return Py_None; 3171 } 3172 3173 static PyObject * 3174 Tkapp_WantObjects(PyObject *self, PyObject *args) 3175 { 3176 3177 int wantobjects = -1; 3178 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) 3179 return NULL; 3180 if (wantobjects == -1) 3181 return PyBool_FromLong(((TkappObject*)self)->wantobjects); 3182 ((TkappObject*)self)->wantobjects = wantobjects; 3183 3184 Py_INCREF(Py_None); 3185 return Py_None; 3186 } 3187 3188 static PyObject * 3189 Tkapp_WillDispatch(PyObject *self, PyObject *args) 3190 { 3191 3192 ((TkappObject*)self)->dispatching = 1; 3193 3194 Py_INCREF(Py_None); 3195 return Py_None; 3196 } 3197 3198 /* Convert Python string or any buffer compatible object to Tcl byte-array 3199 * object. Use it to pass binary data (e.g. image's data) to Tcl/Tk commands. 3200 */ 3201 static PyObject * 3202 Tkapp_CreateByteArray(PyObject *self, PyObject *args) 3203 { 3204 Py_buffer view; 3205 Tcl_Obj* obj; 3206 PyObject *res = NULL; 3207 3208 if (!PyArg_ParseTuple(args, "s*:_createbytearray", &view)) 3209 return NULL; 3210 3211 if (view.len >= INT_MAX) { 3212 PyErr_SetString(PyExc_OverflowError, "string is too long"); 3213 return NULL; 3214 } 3215 obj = Tcl_NewByteArrayObj(view.buf, (int)view.len); 3216 if (obj == NULL) { 3217 PyBuffer_Release(&view); 3218 return Tkinter_Error(self); 3219 } 3220 res = newPyTclObject(obj); 3221 PyBuffer_Release(&view); 3222 return res; 3223 } 3224 3225 3226 /**** Tkapp Method List ****/ 3227 3228 static PyMethodDef Tkapp_methods[] = 3229 { 3230 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS}, 3231 {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, 3232 {"call", Tkapp_Call, METH_VARARGS}, 3233 {"globalcall", Tkapp_GlobalCall, METH_VARARGS}, 3234 {"eval", Tkapp_Eval, METH_VARARGS}, 3235 {"globaleval", Tkapp_GlobalEval, METH_VARARGS}, 3236 {"evalfile", Tkapp_EvalFile, METH_VARARGS}, 3237 {"record", Tkapp_Record, METH_VARARGS}, 3238 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS}, 3239 {"setvar", Tkapp_SetVar, METH_VARARGS}, 3240 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS}, 3241 {"getvar", Tkapp_GetVar, METH_VARARGS}, 3242 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS}, 3243 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS}, 3244 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, 3245 {"getint", Tkapp_GetInt, METH_VARARGS}, 3246 {"getdouble", Tkapp_GetDouble, METH_VARARGS}, 3247 {"getboolean", Tkapp_GetBoolean, METH_O}, 3248 {"exprstring", Tkapp_ExprString, METH_VARARGS}, 3249 {"exprlong", Tkapp_ExprLong, METH_VARARGS}, 3250 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS}, 3251 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS}, 3252 {"splitlist", Tkapp_SplitList, METH_VARARGS}, 3253 {"split", Tkapp_Split, METH_VARARGS}, 3254 {"merge", Tkapp_Merge, METH_VARARGS}, 3255 {"createcommand", Tkapp_CreateCommand, METH_VARARGS}, 3256 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS}, 3257 #ifdef HAVE_CREATEFILEHANDLER 3258 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, 3259 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, 3260 #endif 3261 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, 3262 {"mainloop", Tkapp_MainLoop, METH_VARARGS}, 3263 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, 3264 {"quit", Tkapp_Quit, METH_VARARGS}, 3265 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS}, 3266 {"loadtk", Tkapp_TkInit, METH_NOARGS}, 3267 {"_createbytearray", Tkapp_CreateByteArray, METH_VARARGS}, 3268 {NULL, NULL} 3269 }; 3270 3271 3272 3273 /**** Tkapp Type Methods ****/ 3274 3275 static void 3276 Tkapp_Dealloc(PyObject *self) 3277 { 3278 /*CHECK_TCL_APPARTMENT;*/ 3279 ENTER_TCL 3280 Tcl_DeleteInterp(Tkapp_Interp(self)); 3281 LEAVE_TCL 3282 PyObject_Del(self); 3283 DisableEventHook(); 3284 } 3285 3286 static PyObject * 3287 Tkapp_GetAttr(PyObject *self, char *name) 3288 { 3289 return Py_FindMethod(Tkapp_methods, self, name); 3290 } 3291 3292 static PyTypeObject Tkapp_Type = 3293 { 3294 PyVarObject_HEAD_INIT(NULL, 0) 3295 "tkapp", /*tp_name */ 3296 sizeof(TkappObject), /*tp_basicsize */ 3297 0, /*tp_itemsize */ 3298 Tkapp_Dealloc, /*tp_dealloc */ 3299 0, /*tp_print */ 3300 Tkapp_GetAttr, /*tp_getattr */ 3301 0, /*tp_setattr */ 3302 0, /*tp_compare */ 3303 0, /*tp_repr */ 3304 0, /*tp_as_number */ 3305 0, /*tp_as_sequence */ 3306 0, /*tp_as_mapping */ 3307 0, /*tp_hash */ 3308 }; 3309 3310 3311 3312 /**** Tkinter Module ****/ 3313 3314 typedef struct { 3315 PyObject* tuple; 3316 int size; /* current size */ 3317 int maxsize; /* allocated size */ 3318 } FlattenContext; 3319 3320 static int 3321 _bump(FlattenContext* context, int size) 3322 { 3323 /* expand tuple to hold (at least) size new items. 3324 return true if successful, false if an exception was raised */ 3325 3326 int maxsize = context->maxsize * 2; 3327 3328 if (maxsize < context->size + size) 3329 maxsize = context->size + size; 3330 3331 context->maxsize = maxsize; 3332 3333 return _PyTuple_Resize(&context->tuple, maxsize) >= 0; 3334 } 3335 3336 static int 3337 _flatten1(FlattenContext* context, PyObject* item, int depth) 3338 { 3339 /* add tuple or list to argument tuple (recursively) */ 3340 3341 int i, size; 3342 3343 if (depth > 1000) { 3344 PyErr_SetString(PyExc_ValueError, 3345 "nesting too deep in _flatten"); 3346 return 0; 3347 } else if (PyList_Check(item)) { 3348 size = PyList_GET_SIZE(item); 3349 /* preallocate (assume no nesting) */ 3350 if (context->size + size > context->maxsize && 3351 !_bump(context, size)) 3352 return 0; 3353 /* copy items to output tuple */ 3354 for (i = 0; i < size; i++) { 3355 PyObject *o = PyList_GET_ITEM(item, i); 3356 if (PyList_Check(o) || PyTuple_Check(o)) { 3357 if (!_flatten1(context, o, depth + 1)) 3358 return 0; 3359 } else if (o != Py_None) { 3360 if (context->size + 1 > context->maxsize && 3361 !_bump(context, 1)) 3362 return 0; 3363 Py_INCREF(o); 3364 PyTuple_SET_ITEM(context->tuple, 3365 context->size++, o); 3366 } 3367 } 3368 } else if (PyTuple_Check(item)) { 3369 /* same, for tuples */ 3370 size = PyTuple_GET_SIZE(item); 3371 if (context->size + size > context->maxsize && 3372 !_bump(context, size)) 3373 return 0; 3374 for (i = 0; i < size; i++) { 3375 PyObject *o = PyTuple_GET_ITEM(item, i); 3376 if (PyList_Check(o) || PyTuple_Check(o)) { 3377 if (!_flatten1(context, o, depth + 1)) 3378 return 0; 3379 } else if (o != Py_None) { 3380 if (context->size + 1 > context->maxsize && 3381 !_bump(context, 1)) 3382 return 0; 3383 Py_INCREF(o); 3384 PyTuple_SET_ITEM(context->tuple, 3385 context->size++, o); 3386 } 3387 } 3388 } else { 3389 PyErr_SetString(PyExc_TypeError, "argument must be sequence"); 3390 return 0; 3391 } 3392 return 1; 3393 } 3394 3395 static PyObject * 3396 Tkinter_Flatten(PyObject* self, PyObject* args) 3397 { 3398 FlattenContext context; 3399 PyObject* item; 3400 3401 if (!PyArg_ParseTuple(args, "O:_flatten", &item)) 3402 return NULL; 3403 3404 context.maxsize = PySequence_Size(item); 3405 if (context.maxsize < 0) 3406 return NULL; 3407 if (context.maxsize == 0) 3408 return PyTuple_New(0); 3409 3410 context.tuple = PyTuple_New(context.maxsize); 3411 if (!context.tuple) 3412 return NULL; 3413 3414 context.size = 0; 3415 3416 if (!_flatten1(&context, item,0)) 3417 return NULL; 3418 3419 if (_PyTuple_Resize(&context.tuple, context.size)) 3420 return NULL; 3421 3422 return context.tuple; 3423 } 3424 3425 static PyObject * 3426 Tkinter_Create(PyObject *self, PyObject *args) 3427 { 3428 char *screenName = NULL; 3429 char *baseName = NULL; 3430 char *className = NULL; 3431 int interactive = 0; 3432 int wantobjects = 0; 3433 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */ 3434 int sync = 0; /* pass -sync to wish */ 3435 char *use = NULL; /* pass -use to wish */ 3436 3437 baseName = strrchr(Py_GetProgramName(), '/'); 3438 if (baseName != NULL) 3439 baseName++; 3440 else 3441 baseName = Py_GetProgramName(); 3442 className = "Tk"; 3443 3444 if (!PyArg_ParseTuple(args, "|zssiiiiz:create", 3445 &screenName, &baseName, &className, 3446 &interactive, &wantobjects, &wantTk, 3447 &sync, &use)) 3448 return NULL; 3449 CHECK_STRING_LENGTH(screenName); 3450 CHECK_STRING_LENGTH(baseName); 3451 CHECK_STRING_LENGTH(className); 3452 CHECK_STRING_LENGTH(use); 3453 3454 return (PyObject *) Tkapp_New(screenName, baseName, className, 3455 interactive, wantobjects, wantTk, 3456 sync, use); 3457 } 3458 3459 static PyObject * 3460 Tkinter_setbusywaitinterval(PyObject *self, PyObject *args) 3461 { 3462 int new_val; 3463 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val)) 3464 return NULL; 3465 if (new_val < 0) { 3466 PyErr_SetString(PyExc_ValueError, 3467 "busywaitinterval must be >= 0"); 3468 return NULL; 3469 } 3470 Tkinter_busywaitinterval = new_val; 3471 Py_INCREF(Py_None); 3472 return Py_None; 3473 } 3474 3475 static char setbusywaitinterval_doc[] = 3476 "setbusywaitinterval(n) -> None\n\ 3477 \n\ 3478 Set the busy-wait interval in milliseconds between successive\n\ 3479 calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\ 3480 It should be set to a divisor of the maximum time between\n\ 3481 frames in an animation."; 3482 3483 static PyObject * 3484 Tkinter_getbusywaitinterval(PyObject *self, PyObject *args) 3485 { 3486 return PyInt_FromLong(Tkinter_busywaitinterval); 3487 } 3488 3489 static char getbusywaitinterval_doc[] = 3490 "getbusywaitinterval() -> int\n\ 3491 \n\ 3492 Return the current busy-wait interval between successive\n\ 3493 calls to Tcl_DoOneEvent in a threaded Python interpreter."; 3494 3495 static PyMethodDef moduleMethods[] = 3496 { 3497 {"_flatten", Tkinter_Flatten, METH_VARARGS}, 3498 {"create", Tkinter_Create, METH_VARARGS}, 3499 #ifdef HAVE_CREATEFILEHANDLER 3500 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, 3501 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, 3502 #endif 3503 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, 3504 {"mainloop", Tkapp_MainLoop, METH_VARARGS}, 3505 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, 3506 {"quit", Tkapp_Quit, METH_VARARGS}, 3507 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS, 3508 setbusywaitinterval_doc}, 3509 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval, 3510 METH_NOARGS, getbusywaitinterval_doc}, 3511 {NULL, NULL} 3512 }; 3513 3514 #ifdef WAIT_FOR_STDIN 3515 3516 static int stdin_ready = 0; 3517 3518 #ifndef MS_WINDOWS 3519 static void 3520 MyFileProc(void *clientData, int mask) 3521 { 3522 stdin_ready = 1; 3523 } 3524 #endif 3525 3526 #ifdef WITH_THREAD 3527 static PyThreadState *event_tstate = NULL; 3528 #endif 3529 3530 static int 3531 EventHook(void) 3532 { 3533 #ifndef MS_WINDOWS 3534 int tfile; 3535 #endif 3536 #ifdef WITH_THREAD 3537 PyEval_RestoreThread(event_tstate); 3538 #endif 3539 stdin_ready = 0; 3540 errorInCmd = 0; 3541 #ifndef MS_WINDOWS 3542 tfile = fileno(stdin); 3543 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL); 3544 #endif 3545 while (!errorInCmd && !stdin_ready) { 3546 int result; 3547 #ifdef MS_WINDOWS 3548 if (_kbhit()) { 3549 stdin_ready = 1; 3550 break; 3551 } 3552 #endif 3553 #if defined(WITH_THREAD) || defined(MS_WINDOWS) 3554 Py_BEGIN_ALLOW_THREADS 3555 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); 3556 tcl_tstate = event_tstate; 3557 3558 result = Tcl_DoOneEvent(TCL_DONT_WAIT); 3559 3560 tcl_tstate = NULL; 3561 if(tcl_lock)PyThread_release_lock(tcl_lock); 3562 if (result == 0) 3563 Sleep(Tkinter_busywaitinterval); 3564 Py_END_ALLOW_THREADS 3565 #else 3566 result = Tcl_DoOneEvent(0); 3567 #endif 3568 3569 if (result < 0) 3570 break; 3571 } 3572 #ifndef MS_WINDOWS 3573 Tcl_DeleteFileHandler(tfile); 3574 #endif 3575 if (errorInCmd) { 3576 errorInCmd = 0; 3577 PyErr_Restore(excInCmd, valInCmd, trbInCmd); 3578 excInCmd = valInCmd = trbInCmd = NULL; 3579 PyErr_Print(); 3580 } 3581 #ifdef WITH_THREAD 3582 PyEval_SaveThread(); 3583 #endif 3584 return 0; 3585 } 3586 3587 #endif 3588 3589 static void 3590 EnableEventHook(void) 3591 { 3592 #ifdef WAIT_FOR_STDIN 3593 if (PyOS_InputHook == NULL) { 3594 #ifdef WITH_THREAD 3595 event_tstate = PyThreadState_Get(); 3596 #endif 3597 PyOS_InputHook = EventHook; 3598 } 3599 #endif 3600 } 3601 3602 static void 3603 DisableEventHook(void) 3604 { 3605 #ifdef WAIT_FOR_STDIN 3606 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) { 3607 PyOS_InputHook = NULL; 3608 } 3609 #endif 3610 } 3611 3612 3613 /* all errors will be checked in one fell swoop in init_tkinter() */ 3614 static void 3615 ins_long(PyObject *d, char *name, long val) 3616 { 3617 PyObject *v = PyInt_FromLong(val); 3618 if (v) { 3619 PyDict_SetItemString(d, name, v); 3620 Py_DECREF(v); 3621 } 3622 } 3623 static void 3624 ins_string(PyObject *d, char *name, char *val) 3625 { 3626 PyObject *v = PyString_FromString(val); 3627 if (v) { 3628 PyDict_SetItemString(d, name, v); 3629 Py_DECREF(v); 3630 } 3631 } 3632 3633 3634 PyMODINIT_FUNC 3635 init_tkinter(void) 3636 { 3637 PyObject *m, *d; 3638 3639 Py_TYPE(&Tkapp_Type) = &PyType_Type; 3640 3641 #ifdef WITH_THREAD 3642 tcl_lock = PyThread_allocate_lock(); 3643 #endif 3644 3645 m = Py_InitModule("_tkinter", moduleMethods); 3646 if (m == NULL) 3647 return; 3648 3649 d = PyModule_GetDict(m); 3650 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); 3651 PyDict_SetItemString(d, "TclError", Tkinter_TclError); 3652 3653 ins_long(d, "READABLE", TCL_READABLE); 3654 ins_long(d, "WRITABLE", TCL_WRITABLE); 3655 ins_long(d, "EXCEPTION", TCL_EXCEPTION); 3656 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS); 3657 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS); 3658 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS); 3659 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS); 3660 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS); 3661 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT); 3662 ins_string(d, "TK_VERSION", TK_VERSION); 3663 ins_string(d, "TCL_VERSION", TCL_VERSION); 3664 3665 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type); 3666 3667 Py_TYPE(&Tktt_Type) = &PyType_Type; 3668 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type); 3669 3670 Py_TYPE(&PyTclObject_Type) = &PyType_Type; 3671 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type); 3672 3673 #ifdef TK_AQUA 3674 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems 3675 * start waking up. Note that Tcl_FindExecutable will do this, this 3676 * code must be above it! The original warning from 3677 * tkMacOSXAppInit.c is copied below. 3678 * 3679 * NB - You have to swap in the Tk Notifier BEFORE you start up the 3680 * Tcl interpreter for now. It probably should work to do this 3681 * in the other order, but for now it doesn't seem to. 3682 * 3683 */ 3684 Tk_MacOSXSetupTkNotifier(); 3685 #endif 3686 3687 3688 /* This helps the dynamic loader; in Unicode aware Tcl versions 3689 it also helps Tcl find its encodings. */ 3690 Tcl_FindExecutable(Py_GetProgramName()); 3691 3692 if (PyErr_Occurred()) 3693 return; 3694 3695 #if 0 3696 /* This was not a good idea; through <Destroy> bindings, 3697 Tcl_Finalize() may invoke Python code but at that point the 3698 interpreter and thread state have already been destroyed! */ 3699 Py_AtExit(Tcl_Finalize); 3700 #endif 3701 3702 } 3703