17db96d56Sopenharmony_ci/*********************************************************** 27db96d56Sopenharmony_ciCopyright (C) 1994 Steen Lumholt. 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci All Rights Reserved 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci******************************************************************/ 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci/* _tkinter.c -- Interface to libtk.a and libtcl.a. */ 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci/* TCL/TK VERSION INFO: 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci Only Tcl/Tk 8.5.12 and later are supported. Older versions are not 137db96d56Sopenharmony_ci supported. Use Python 3.10 or older if you cannot upgrade your 147db96d56Sopenharmony_ci Tcl/Tk libraries. 157db96d56Sopenharmony_ci*/ 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci/* XXX Further speed-up ideas, involving Tcl 8.0 features: 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci - Register a new Tcl type, "Python callable", which can be called more 207db96d56Sopenharmony_ci efficiently and passed to Tcl_EvalObj() directly (if this is possible). 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci*/ 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 257db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 267db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 277db96d56Sopenharmony_ci#endif 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci#include "Python.h" 307db96d56Sopenharmony_ci#include <ctype.h> 317db96d56Sopenharmony_ci#ifdef MS_WINDOWS 327db96d56Sopenharmony_ci# include "pycore_fileutils.h" // _Py_stat() 337db96d56Sopenharmony_ci#endif 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci#ifdef MS_WINDOWS 367db96d56Sopenharmony_ci#include <windows.h> 377db96d56Sopenharmony_ci#endif 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci#define CHECK_SIZE(size, elemsize) \ 407db96d56Sopenharmony_ci ((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define 437db96d56Sopenharmony_ci it always; if Tcl is not threaded, the thread functions in 447db96d56Sopenharmony_ci Tcl are empty. */ 457db96d56Sopenharmony_ci#define TCL_THREADS 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci#ifdef TK_FRAMEWORK 487db96d56Sopenharmony_ci#include <Tcl/tcl.h> 497db96d56Sopenharmony_ci#include <Tk/tk.h> 507db96d56Sopenharmony_ci#else 517db96d56Sopenharmony_ci#include <tcl.h> 527db96d56Sopenharmony_ci#include <tk.h> 537db96d56Sopenharmony_ci#endif 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci#include "tkinter.h" 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci#if TK_HEX_VERSION < 0x0805020c 587db96d56Sopenharmony_ci#error "Tk older than 8.5.12 not supported" 597db96d56Sopenharmony_ci#endif 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci#include <tclTomMath.h> 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci#if defined(TCL_WITH_EXTERNAL_TOMMATH) || (TK_HEX_VERSION >= 0x08070000) 647db96d56Sopenharmony_ci#define USE_DEPRECATED_TOMMATH_API 0 657db96d56Sopenharmony_ci#else 667db96d56Sopenharmony_ci#define USE_DEPRECATED_TOMMATH_API 1 677db96d56Sopenharmony_ci#endif 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci#if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) 707db96d56Sopenharmony_ci#define HAVE_CREATEFILEHANDLER 717db96d56Sopenharmony_ci#endif 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci#ifdef HAVE_CREATEFILEHANDLER 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere 767db96d56Sopenharmony_ci with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ 777db96d56Sopenharmony_ci#ifndef TCL_UNIX_FD 787db96d56Sopenharmony_ci# ifdef TCL_WIN_SOCKET 797db96d56Sopenharmony_ci# define TCL_UNIX_FD (! TCL_WIN_SOCKET) 807db96d56Sopenharmony_ci# else 817db96d56Sopenharmony_ci# define TCL_UNIX_FD 1 827db96d56Sopenharmony_ci# endif 837db96d56Sopenharmony_ci#endif 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci/* Tcl_CreateFileHandler() changed several times; these macros deal with the 867db96d56Sopenharmony_ci messiness. In Tcl 8.0 and later, it is not available on Windows (and on 877db96d56Sopenharmony_ci Unix, only because Jack added it back); when available on Windows, it only 887db96d56Sopenharmony_ci applies to sockets. */ 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci#ifdef MS_WINDOWS 917db96d56Sopenharmony_ci#define FHANDLETYPE TCL_WIN_SOCKET 927db96d56Sopenharmony_ci#else 937db96d56Sopenharmony_ci#define FHANDLETYPE TCL_UNIX_FD 947db96d56Sopenharmony_ci#endif 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine 977db96d56Sopenharmony_ci which uses this to handle Tcl events while the user is typing commands. */ 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci#if FHANDLETYPE == TCL_UNIX_FD 1007db96d56Sopenharmony_ci#define WAIT_FOR_STDIN 1017db96d56Sopenharmony_ci#endif 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci#endif /* HAVE_CREATEFILEHANDLER */ 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci/* Use OS native encoding for converting between Python strings and 1067db96d56Sopenharmony_ci Tcl objects. 1077db96d56Sopenharmony_ci On Windows use UTF-16 (or UTF-32 for 32-bit Tcl_UniChar) with the 1087db96d56Sopenharmony_ci "surrogatepass" error handler for converting to/from Tcl Unicode objects. 1097db96d56Sopenharmony_ci On Linux use UTF-8 with the "surrogateescape" error handler for converting 1107db96d56Sopenharmony_ci to/from Tcl String objects. */ 1117db96d56Sopenharmony_ci#ifdef MS_WINDOWS 1127db96d56Sopenharmony_ci#define USE_TCL_UNICODE 1 1137db96d56Sopenharmony_ci#else 1147db96d56Sopenharmony_ci#define USE_TCL_UNICODE 0 1157db96d56Sopenharmony_ci#endif 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 1187db96d56Sopenharmony_ci#define NATIVE_BYTEORDER -1 1197db96d56Sopenharmony_ci#else 1207db96d56Sopenharmony_ci#define NATIVE_BYTEORDER 1 1217db96d56Sopenharmony_ci#endif 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci#ifdef MS_WINDOWS 1247db96d56Sopenharmony_ci#include <conio.h> 1257db96d56Sopenharmony_ci#define WAIT_FOR_STDIN 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_cistatic PyObject * 1287db96d56Sopenharmony_ci_get_tcl_lib_path() 1297db96d56Sopenharmony_ci{ 1307db96d56Sopenharmony_ci static PyObject *tcl_library_path = NULL; 1317db96d56Sopenharmony_ci static int already_checked = 0; 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci if (already_checked == 0) { 1347db96d56Sopenharmony_ci PyObject *prefix; 1357db96d56Sopenharmony_ci struct stat stat_buf; 1367db96d56Sopenharmony_ci int stat_return_value; 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1); 1397db96d56Sopenharmony_ci if (prefix == NULL) { 1407db96d56Sopenharmony_ci return NULL; 1417db96d56Sopenharmony_ci } 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci /* Check expected location for an installed Python first */ 1447db96d56Sopenharmony_ci tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION); 1457db96d56Sopenharmony_ci if (tcl_library_path == NULL) { 1467db96d56Sopenharmony_ci return NULL; 1477db96d56Sopenharmony_ci } 1487db96d56Sopenharmony_ci tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path); 1497db96d56Sopenharmony_ci if (tcl_library_path == NULL) { 1507db96d56Sopenharmony_ci return NULL; 1517db96d56Sopenharmony_ci } 1527db96d56Sopenharmony_ci stat_return_value = _Py_stat(tcl_library_path, &stat_buf); 1537db96d56Sopenharmony_ci if (stat_return_value == -2) { 1547db96d56Sopenharmony_ci return NULL; 1557db96d56Sopenharmony_ci } 1567db96d56Sopenharmony_ci if (stat_return_value == -1) { 1577db96d56Sopenharmony_ci /* install location doesn't exist, reset errno and see if 1587db96d56Sopenharmony_ci we're a repository build */ 1597db96d56Sopenharmony_ci errno = 0; 1607db96d56Sopenharmony_ci#ifdef Py_TCLTK_DIR 1617db96d56Sopenharmony_ci tcl_library_path = PyUnicode_FromString( 1627db96d56Sopenharmony_ci Py_TCLTK_DIR "\\lib\\tcl" TCL_VERSION); 1637db96d56Sopenharmony_ci if (tcl_library_path == NULL) { 1647db96d56Sopenharmony_ci return NULL; 1657db96d56Sopenharmony_ci } 1667db96d56Sopenharmony_ci stat_return_value = _Py_stat(tcl_library_path, &stat_buf); 1677db96d56Sopenharmony_ci if (stat_return_value == -2) { 1687db96d56Sopenharmony_ci return NULL; 1697db96d56Sopenharmony_ci } 1707db96d56Sopenharmony_ci if (stat_return_value == -1) { 1717db96d56Sopenharmony_ci /* tcltkDir for a repository build doesn't exist either, 1727db96d56Sopenharmony_ci reset errno and leave Tcl to its own devices */ 1737db96d56Sopenharmony_ci errno = 0; 1747db96d56Sopenharmony_ci tcl_library_path = NULL; 1757db96d56Sopenharmony_ci } 1767db96d56Sopenharmony_ci#else 1777db96d56Sopenharmony_ci tcl_library_path = NULL; 1787db96d56Sopenharmony_ci#endif 1797db96d56Sopenharmony_ci } 1807db96d56Sopenharmony_ci already_checked = 1; 1817db96d56Sopenharmony_ci } 1827db96d56Sopenharmony_ci return tcl_library_path; 1837db96d56Sopenharmony_ci} 1847db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci/* The threading situation is complicated. Tcl is not thread-safe, except 1877db96d56Sopenharmony_ci when configured with --enable-threads. 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci So we need to use a lock around all uses of Tcl. Previously, the 1907db96d56Sopenharmony_ci Python interpreter lock was used for this. However, this causes 1917db96d56Sopenharmony_ci problems when other Python threads need to run while Tcl is blocked 1927db96d56Sopenharmony_ci waiting for events. 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci To solve this problem, a separate lock for Tcl is introduced. 1957db96d56Sopenharmony_ci Holding it is incompatible with holding Python's interpreter lock. 1967db96d56Sopenharmony_ci The following four macros manipulate both locks together. 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci ENTER_TCL and LEAVE_TCL are brackets, just like 1997db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be 2007db96d56Sopenharmony_ci used whenever a call into Tcl is made that could call an event 2017db96d56Sopenharmony_ci handler, or otherwise affect the state of a Tcl interpreter. These 2027db96d56Sopenharmony_ci assume that the surrounding code has the Python interpreter lock; 2037db96d56Sopenharmony_ci inside the brackets, the Python interpreter lock has been released 2047db96d56Sopenharmony_ci and the lock for Tcl has been acquired. 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ci Sometimes, it is necessary to have both the Python lock and the Tcl 2077db96d56Sopenharmony_ci lock. (For example, when transferring data from the Tcl 2087db96d56Sopenharmony_ci interpreter result to a Python string object.) This can be done by 2097db96d56Sopenharmony_ci using different macros to close the ENTER_TCL block: ENTER_OVERLAP 2107db96d56Sopenharmony_ci reacquires the Python lock (and restores the thread state) but 2117db96d56Sopenharmony_ci doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl 2127db96d56Sopenharmony_ci lock. 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event 2157db96d56Sopenharmony_ci handlers when the handler needs to use Python. Such event handlers 2167db96d56Sopenharmony_ci are entered while the lock for Tcl is held; the event handler 2177db96d56Sopenharmony_ci presumably needs to use Python. ENTER_PYTHON releases the lock for 2187db96d56Sopenharmony_ci Tcl and acquires the Python interpreter lock, restoring the 2197db96d56Sopenharmony_ci appropriate thread state, and LEAVE_PYTHON releases the Python 2207db96d56Sopenharmony_ci interpreter lock and re-acquires the lock for Tcl. It is okay for 2217db96d56Sopenharmony_ci ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between 2227db96d56Sopenharmony_ci ENTER_PYTHON and LEAVE_PYTHON. 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci These locks expand to several statements and brackets; they should 2257db96d56Sopenharmony_ci not be used in branches of if statements and the like. 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci If Tcl is threaded, this approach won't work anymore. The Tcl 2287db96d56Sopenharmony_ci interpreter is only valid in the thread that created it, and all Tk 2297db96d56Sopenharmony_ci activity must happen in this thread, also. That means that the 2307db96d56Sopenharmony_ci mainloop must be invoked in the thread that created the 2317db96d56Sopenharmony_ci interpreter. Invoking commands from other threads is possible; 2327db96d56Sopenharmony_ci _tkinter will queue an event for the interpreter thread, which will 2337db96d56Sopenharmony_ci then execute the command and pass back the result. If the main 2347db96d56Sopenharmony_ci thread is not in the mainloop, and invoking commands causes an 2357db96d56Sopenharmony_ci exception; if the main loop is running but not processing events, 2367db96d56Sopenharmony_ci the command invocation will block. 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci In addition, for a threaded Tcl, a single global tcl_tstate won't 2397db96d56Sopenharmony_ci be sufficient anymore, since multiple Tcl interpreters may 2407db96d56Sopenharmony_ci simultaneously dispatch in different threads. So we use the Tcl TLS 2417db96d56Sopenharmony_ci API. 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci*/ 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_cistatic PyThread_type_lock tcl_lock = 0; 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_ci#ifdef TCL_THREADS 2487db96d56Sopenharmony_cistatic Tcl_ThreadDataKey state_key; 2497db96d56Sopenharmony_citypedef PyThreadState *ThreadSpecificData; 2507db96d56Sopenharmony_ci#define tcl_tstate \ 2517db96d56Sopenharmony_ci (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*))) 2527db96d56Sopenharmony_ci#else 2537db96d56Sopenharmony_cistatic PyThreadState *tcl_tstate = NULL; 2547db96d56Sopenharmony_ci#endif 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci#define ENTER_TCL \ 2577db96d56Sopenharmony_ci { PyThreadState *tstate = PyThreadState_Get(); \ 2587db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS \ 2597db96d56Sopenharmony_ci if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); \ 2607db96d56Sopenharmony_ci tcl_tstate = tstate; 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci#define LEAVE_TCL \ 2637db96d56Sopenharmony_ci tcl_tstate = NULL; \ 2647db96d56Sopenharmony_ci if(tcl_lock)PyThread_release_lock(tcl_lock); \ 2657db96d56Sopenharmony_ci Py_END_ALLOW_THREADS} 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci#define ENTER_OVERLAP \ 2687db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_ci#define LEAVE_OVERLAP_TCL \ 2717db96d56Sopenharmony_ci tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); } 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ci#define ENTER_PYTHON \ 2747db96d56Sopenharmony_ci { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \ 2757db96d56Sopenharmony_ci if(tcl_lock) \ 2767db96d56Sopenharmony_ci PyThread_release_lock(tcl_lock); \ 2777db96d56Sopenharmony_ci PyEval_RestoreThread((tstate)); } 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ci#define LEAVE_PYTHON \ 2807db96d56Sopenharmony_ci { PyThreadState *tstate = PyEval_SaveThread(); \ 2817db96d56Sopenharmony_ci if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); \ 2827db96d56Sopenharmony_ci tcl_tstate = tstate; } 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci#define CHECK_TCL_APPARTMENT \ 2857db96d56Sopenharmony_ci if (((TkappObject *)self)->threaded && \ 2867db96d56Sopenharmony_ci ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \ 2877db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, \ 2887db96d56Sopenharmony_ci "Calling Tcl from different apartment"); \ 2897db96d56Sopenharmony_ci return 0; \ 2907db96d56Sopenharmony_ci } 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci#ifndef FREECAST 2937db96d56Sopenharmony_ci#define FREECAST (char *) 2947db96d56Sopenharmony_ci#endif 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci/**** Tkapp Object Declaration ****/ 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_cistatic PyObject *Tkapp_Type; 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_citypedef struct { 3017db96d56Sopenharmony_ci PyObject_HEAD 3027db96d56Sopenharmony_ci Tcl_Interp *interp; 3037db96d56Sopenharmony_ci int wantobjects; 3047db96d56Sopenharmony_ci int threaded; /* True if tcl_platform[threaded] */ 3057db96d56Sopenharmony_ci Tcl_ThreadId thread_id; 3067db96d56Sopenharmony_ci int dispatching; 3077db96d56Sopenharmony_ci /* We cannot include tclInt.h, as this is internal. 3087db96d56Sopenharmony_ci So we cache interesting types here. */ 3097db96d56Sopenharmony_ci const Tcl_ObjType *OldBooleanType; 3107db96d56Sopenharmony_ci const Tcl_ObjType *BooleanType; 3117db96d56Sopenharmony_ci const Tcl_ObjType *ByteArrayType; 3127db96d56Sopenharmony_ci const Tcl_ObjType *DoubleType; 3137db96d56Sopenharmony_ci const Tcl_ObjType *IntType; 3147db96d56Sopenharmony_ci const Tcl_ObjType *WideIntType; 3157db96d56Sopenharmony_ci const Tcl_ObjType *BignumType; 3167db96d56Sopenharmony_ci const Tcl_ObjType *ListType; 3177db96d56Sopenharmony_ci const Tcl_ObjType *ProcBodyType; 3187db96d56Sopenharmony_ci const Tcl_ObjType *StringType; 3197db96d56Sopenharmony_ci} TkappObject; 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci#define Tkapp_Interp(v) (((TkappObject *) (v))->interp) 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ci/**** Error Handling ****/ 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_cistatic PyObject *Tkinter_TclError; 3277db96d56Sopenharmony_cistatic int quitMainLoop = 0; 3287db96d56Sopenharmony_cistatic int errorInCmd = 0; 3297db96d56Sopenharmony_cistatic PyObject *excInCmd; 3307db96d56Sopenharmony_cistatic PyObject *valInCmd; 3317db96d56Sopenharmony_cistatic PyObject *trbInCmd; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 3347db96d56Sopenharmony_cistatic int tk_load_failed = 0; 3357db96d56Sopenharmony_ci#endif 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_cistatic PyObject *Tkapp_UnicodeResult(TkappObject *); 3397db96d56Sopenharmony_ci 3407db96d56Sopenharmony_cistatic PyObject * 3417db96d56Sopenharmony_ciTkinter_Error(TkappObject *self) 3427db96d56Sopenharmony_ci{ 3437db96d56Sopenharmony_ci PyObject *res = Tkapp_UnicodeResult(self); 3447db96d56Sopenharmony_ci if (res != NULL) { 3457db96d56Sopenharmony_ci PyErr_SetObject(Tkinter_TclError, res); 3467db96d56Sopenharmony_ci Py_DECREF(res); 3477db96d56Sopenharmony_ci } 3487db96d56Sopenharmony_ci return NULL; 3497db96d56Sopenharmony_ci} 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci/**** Utils ****/ 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_cistatic int Tkinter_busywaitinterval = 20; 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_ci#ifndef MS_WINDOWS 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci/* Millisecond sleep() for Unix platforms. */ 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_cistatic void 3627db96d56Sopenharmony_ciSleep(int milli) 3637db96d56Sopenharmony_ci{ 3647db96d56Sopenharmony_ci /* XXX Too bad if you don't have select(). */ 3657db96d56Sopenharmony_ci struct timeval t; 3667db96d56Sopenharmony_ci t.tv_sec = milli/1000; 3677db96d56Sopenharmony_ci t.tv_usec = (milli%1000) * 1000; 3687db96d56Sopenharmony_ci select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); 3697db96d56Sopenharmony_ci} 3707db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_ci/* Wait up to 1s for the mainloop to come up. */ 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_cistatic int 3757db96d56Sopenharmony_ciWaitForMainloop(TkappObject* self) 3767db96d56Sopenharmony_ci{ 3777db96d56Sopenharmony_ci int i; 3787db96d56Sopenharmony_ci for (i = 0; i < 10; i++) { 3797db96d56Sopenharmony_ci if (self->dispatching) 3807db96d56Sopenharmony_ci return 1; 3817db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 3827db96d56Sopenharmony_ci Sleep(100); 3837db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 3847db96d56Sopenharmony_ci } 3857db96d56Sopenharmony_ci if (self->dispatching) 3867db96d56Sopenharmony_ci return 1; 3877db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop"); 3887db96d56Sopenharmony_ci return 0; 3897db96d56Sopenharmony_ci} 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci#define ARGSZ 64 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_ci 3967db96d56Sopenharmony_ci 3977db96d56Sopenharmony_cistatic PyObject * 3987db96d56Sopenharmony_ciunicodeFromTclStringAndSize(const char *s, Py_ssize_t size) 3997db96d56Sopenharmony_ci{ 4007db96d56Sopenharmony_ci PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); 4017db96d56Sopenharmony_ci if (r != NULL || !PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { 4027db96d56Sopenharmony_ci return r; 4037db96d56Sopenharmony_ci } 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci char *buf = NULL; 4067db96d56Sopenharmony_ci PyErr_Clear(); 4077db96d56Sopenharmony_ci /* Tcl encodes null character as \xc0\x80. 4087db96d56Sopenharmony_ci https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8 */ 4097db96d56Sopenharmony_ci if (memchr(s, '\xc0', size)) { 4107db96d56Sopenharmony_ci char *q; 4117db96d56Sopenharmony_ci const char *e = s + size; 4127db96d56Sopenharmony_ci q = buf = (char *)PyMem_Malloc(size); 4137db96d56Sopenharmony_ci if (buf == NULL) { 4147db96d56Sopenharmony_ci PyErr_NoMemory(); 4157db96d56Sopenharmony_ci return NULL; 4167db96d56Sopenharmony_ci } 4177db96d56Sopenharmony_ci while (s != e) { 4187db96d56Sopenharmony_ci if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { 4197db96d56Sopenharmony_ci *q++ = '\0'; 4207db96d56Sopenharmony_ci s += 2; 4217db96d56Sopenharmony_ci } 4227db96d56Sopenharmony_ci else 4237db96d56Sopenharmony_ci *q++ = *s++; 4247db96d56Sopenharmony_ci } 4257db96d56Sopenharmony_ci s = buf; 4267db96d56Sopenharmony_ci size = q - s; 4277db96d56Sopenharmony_ci } 4287db96d56Sopenharmony_ci r = PyUnicode_DecodeUTF8(s, size, "surrogateescape"); 4297db96d56Sopenharmony_ci if (buf != NULL) { 4307db96d56Sopenharmony_ci PyMem_Free(buf); 4317db96d56Sopenharmony_ci } 4327db96d56Sopenharmony_ci if (r == NULL || PyUnicode_KIND(r) == PyUnicode_1BYTE_KIND) { 4337db96d56Sopenharmony_ci return r; 4347db96d56Sopenharmony_ci } 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci /* In CESU-8 non-BMP characters are represented as a surrogate pair, 4377db96d56Sopenharmony_ci like in UTF-16, and then each surrogate code point is encoded in UTF-8. 4387db96d56Sopenharmony_ci https://en.wikipedia.org/wiki/CESU-8 */ 4397db96d56Sopenharmony_ci Py_ssize_t len = PyUnicode_GET_LENGTH(r); 4407db96d56Sopenharmony_ci Py_ssize_t i, j; 4417db96d56Sopenharmony_ci /* All encoded surrogate characters start with \xED. */ 4427db96d56Sopenharmony_ci i = PyUnicode_FindChar(r, 0xdcED, 0, len, 1); 4437db96d56Sopenharmony_ci if (i == -2) { 4447db96d56Sopenharmony_ci Py_DECREF(r); 4457db96d56Sopenharmony_ci return NULL; 4467db96d56Sopenharmony_ci } 4477db96d56Sopenharmony_ci if (i == -1) { 4487db96d56Sopenharmony_ci return r; 4497db96d56Sopenharmony_ci } 4507db96d56Sopenharmony_ci Py_UCS4 *u = PyUnicode_AsUCS4Copy(r); 4517db96d56Sopenharmony_ci Py_DECREF(r); 4527db96d56Sopenharmony_ci if (u == NULL) { 4537db96d56Sopenharmony_ci return NULL; 4547db96d56Sopenharmony_ci } 4557db96d56Sopenharmony_ci Py_UCS4 ch; 4567db96d56Sopenharmony_ci for (j = i; i < len; i++, u[j++] = ch) { 4577db96d56Sopenharmony_ci Py_UCS4 ch1, ch2, ch3, high, low; 4587db96d56Sopenharmony_ci /* Low surrogates U+D800 - U+DBFF are encoded as 4597db96d56Sopenharmony_ci \xED\xA0\x80 - \xED\xAF\xBF. */ 4607db96d56Sopenharmony_ci ch1 = ch = u[i]; 4617db96d56Sopenharmony_ci if (ch1 != 0xdcED) continue; 4627db96d56Sopenharmony_ci ch2 = u[i + 1]; 4637db96d56Sopenharmony_ci if (!(0xdcA0 <= ch2 && ch2 <= 0xdcAF)) continue; 4647db96d56Sopenharmony_ci ch3 = u[i + 2]; 4657db96d56Sopenharmony_ci if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue; 4667db96d56Sopenharmony_ci high = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F); 4677db96d56Sopenharmony_ci assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); 4687db96d56Sopenharmony_ci /* High surrogates U+DC00 - U+DFFF are encoded as 4697db96d56Sopenharmony_ci \xED\xB0\x80 - \xED\xBF\xBF. */ 4707db96d56Sopenharmony_ci ch1 = u[i + 3]; 4717db96d56Sopenharmony_ci if (ch1 != 0xdcED) continue; 4727db96d56Sopenharmony_ci ch2 = u[i + 4]; 4737db96d56Sopenharmony_ci if (!(0xdcB0 <= ch2 && ch2 <= 0xdcBF)) continue; 4747db96d56Sopenharmony_ci ch3 = u[i + 5]; 4757db96d56Sopenharmony_ci if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue; 4767db96d56Sopenharmony_ci low = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F); 4777db96d56Sopenharmony_ci assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); 4787db96d56Sopenharmony_ci ch = Py_UNICODE_JOIN_SURROGATES(high, low); 4797db96d56Sopenharmony_ci i += 5; 4807db96d56Sopenharmony_ci } 4817db96d56Sopenharmony_ci r = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, u, j); 4827db96d56Sopenharmony_ci PyMem_Free(u); 4837db96d56Sopenharmony_ci return r; 4847db96d56Sopenharmony_ci} 4857db96d56Sopenharmony_ci 4867db96d56Sopenharmony_cistatic PyObject * 4877db96d56Sopenharmony_ciunicodeFromTclString(const char *s) 4887db96d56Sopenharmony_ci{ 4897db96d56Sopenharmony_ci return unicodeFromTclStringAndSize(s, strlen(s)); 4907db96d56Sopenharmony_ci} 4917db96d56Sopenharmony_ci 4927db96d56Sopenharmony_cistatic PyObject * 4937db96d56Sopenharmony_ciunicodeFromTclObj(Tcl_Obj *value) 4947db96d56Sopenharmony_ci{ 4957db96d56Sopenharmony_ci int len; 4967db96d56Sopenharmony_ci#if USE_TCL_UNICODE 4977db96d56Sopenharmony_ci int byteorder = NATIVE_BYTEORDER; 4987db96d56Sopenharmony_ci const Tcl_UniChar *u = Tcl_GetUnicodeFromObj(value, &len); 4997db96d56Sopenharmony_ci if (sizeof(Tcl_UniChar) == 2) 5007db96d56Sopenharmony_ci return PyUnicode_DecodeUTF16((const char *)u, len * 2, 5017db96d56Sopenharmony_ci "surrogatepass", &byteorder); 5027db96d56Sopenharmony_ci else if (sizeof(Tcl_UniChar) == 4) 5037db96d56Sopenharmony_ci return PyUnicode_DecodeUTF32((const char *)u, len * 4, 5047db96d56Sopenharmony_ci "surrogatepass", &byteorder); 5057db96d56Sopenharmony_ci else 5067db96d56Sopenharmony_ci Py_UNREACHABLE(); 5077db96d56Sopenharmony_ci#else 5087db96d56Sopenharmony_ci const char *s = Tcl_GetStringFromObj(value, &len); 5097db96d56Sopenharmony_ci return unicodeFromTclStringAndSize(s, len); 5107db96d56Sopenharmony_ci#endif 5117db96d56Sopenharmony_ci} 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ci/*[clinic input] 5147db96d56Sopenharmony_cimodule _tkinter 5157db96d56Sopenharmony_ciclass _tkinter.tkapp "TkappObject *" "&Tkapp_Type_spec" 5167db96d56Sopenharmony_ciclass _tkinter.Tcl_Obj "PyTclObject *" "&PyTclObject_Type_spec" 5177db96d56Sopenharmony_ciclass _tkinter.tktimertoken "TkttObject *" "&Tktt_Type_spec" 5187db96d56Sopenharmony_ci[clinic start generated code]*/ 5197db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b1ebf15c162ee229]*/ 5207db96d56Sopenharmony_ci 5217db96d56Sopenharmony_ci/**** Tkapp Object ****/ 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_ci#ifndef WITH_APPINIT 5247db96d56Sopenharmony_ciint 5257db96d56Sopenharmony_ciTcl_AppInit(Tcl_Interp *interp) 5267db96d56Sopenharmony_ci{ 5277db96d56Sopenharmony_ci const char * _tkinter_skip_tk_init; 5287db96d56Sopenharmony_ci 5297db96d56Sopenharmony_ci if (Tcl_Init(interp) == TCL_ERROR) { 5307db96d56Sopenharmony_ci PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp)); 5317db96d56Sopenharmony_ci return TCL_ERROR; 5327db96d56Sopenharmony_ci } 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci _tkinter_skip_tk_init = Tcl_GetVar(interp, 5357db96d56Sopenharmony_ci "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); 5367db96d56Sopenharmony_ci if (_tkinter_skip_tk_init != NULL && 5377db96d56Sopenharmony_ci strcmp(_tkinter_skip_tk_init, "1") == 0) { 5387db96d56Sopenharmony_ci return TCL_OK; 5397db96d56Sopenharmony_ci } 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 5427db96d56Sopenharmony_ci if (tk_load_failed) { 5437db96d56Sopenharmony_ci PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG); 5447db96d56Sopenharmony_ci return TCL_ERROR; 5457db96d56Sopenharmony_ci } 5467db96d56Sopenharmony_ci#endif 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci if (Tk_Init(interp) == TCL_ERROR) { 5497db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 5507db96d56Sopenharmony_ci tk_load_failed = 1; 5517db96d56Sopenharmony_ci#endif 5527db96d56Sopenharmony_ci PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp)); 5537db96d56Sopenharmony_ci return TCL_ERROR; 5547db96d56Sopenharmony_ci } 5557db96d56Sopenharmony_ci 5567db96d56Sopenharmony_ci return TCL_OK; 5577db96d56Sopenharmony_ci} 5587db96d56Sopenharmony_ci#endif /* !WITH_APPINIT */ 5597db96d56Sopenharmony_ci 5607db96d56Sopenharmony_ci 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_ci/* Initialize the Tk application; see the `main' function in 5647db96d56Sopenharmony_ci * `tkMain.c'. 5657db96d56Sopenharmony_ci */ 5667db96d56Sopenharmony_ci 5677db96d56Sopenharmony_cistatic void EnableEventHook(void); /* Forward */ 5687db96d56Sopenharmony_cistatic void DisableEventHook(void); /* Forward */ 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_cistatic TkappObject * 5717db96d56Sopenharmony_ciTkapp_New(const char *screenName, const char *className, 5727db96d56Sopenharmony_ci int interactive, int wantobjects, int wantTk, int sync, 5737db96d56Sopenharmony_ci const char *use) 5747db96d56Sopenharmony_ci{ 5757db96d56Sopenharmony_ci TkappObject *v; 5767db96d56Sopenharmony_ci char *argv0; 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ci v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type); 5797db96d56Sopenharmony_ci if (v == NULL) 5807db96d56Sopenharmony_ci return NULL; 5817db96d56Sopenharmony_ci 5827db96d56Sopenharmony_ci v->interp = Tcl_CreateInterp(); 5837db96d56Sopenharmony_ci v->wantobjects = wantobjects; 5847db96d56Sopenharmony_ci v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded", 5857db96d56Sopenharmony_ci TCL_GLOBAL_ONLY) != NULL; 5867db96d56Sopenharmony_ci v->thread_id = Tcl_GetCurrentThread(); 5877db96d56Sopenharmony_ci v->dispatching = 0; 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ci#ifndef TCL_THREADS 5907db96d56Sopenharmony_ci if (v->threaded) { 5917db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 5927db96d56Sopenharmony_ci "Tcl is threaded but _tkinter is not"); 5937db96d56Sopenharmony_ci Py_DECREF(v); 5947db96d56Sopenharmony_ci return 0; 5957db96d56Sopenharmony_ci } 5967db96d56Sopenharmony_ci#endif 5977db96d56Sopenharmony_ci if (v->threaded && tcl_lock) { 5987db96d56Sopenharmony_ci /* If Tcl is threaded, we don't need the lock. */ 5997db96d56Sopenharmony_ci PyThread_free_lock(tcl_lock); 6007db96d56Sopenharmony_ci tcl_lock = NULL; 6017db96d56Sopenharmony_ci } 6027db96d56Sopenharmony_ci 6037db96d56Sopenharmony_ci v->OldBooleanType = Tcl_GetObjType("boolean"); 6047db96d56Sopenharmony_ci v->BooleanType = Tcl_GetObjType("booleanString"); 6057db96d56Sopenharmony_ci v->ByteArrayType = Tcl_GetObjType("bytearray"); 6067db96d56Sopenharmony_ci v->DoubleType = Tcl_GetObjType("double"); 6077db96d56Sopenharmony_ci v->IntType = Tcl_GetObjType("int"); 6087db96d56Sopenharmony_ci v->WideIntType = Tcl_GetObjType("wideInt"); 6097db96d56Sopenharmony_ci v->BignumType = Tcl_GetObjType("bignum"); 6107db96d56Sopenharmony_ci v->ListType = Tcl_GetObjType("list"); 6117db96d56Sopenharmony_ci v->ProcBodyType = Tcl_GetObjType("procbody"); 6127db96d56Sopenharmony_ci v->StringType = Tcl_GetObjType("string"); 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci /* Delete the 'exit' command, which can screw things up */ 6157db96d56Sopenharmony_ci Tcl_DeleteCommand(v->interp, "exit"); 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ci if (screenName != NULL) 6187db96d56Sopenharmony_ci Tcl_SetVar2(v->interp, "env", "DISPLAY", 6197db96d56Sopenharmony_ci screenName, TCL_GLOBAL_ONLY); 6207db96d56Sopenharmony_ci 6217db96d56Sopenharmony_ci if (interactive) 6227db96d56Sopenharmony_ci Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); 6237db96d56Sopenharmony_ci else 6247db96d56Sopenharmony_ci Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); 6257db96d56Sopenharmony_ci 6267db96d56Sopenharmony_ci /* This is used to get the application class for Tk 4.1 and up */ 6277db96d56Sopenharmony_ci argv0 = (char*)PyMem_Malloc(strlen(className) + 1); 6287db96d56Sopenharmony_ci if (!argv0) { 6297db96d56Sopenharmony_ci PyErr_NoMemory(); 6307db96d56Sopenharmony_ci Py_DECREF(v); 6317db96d56Sopenharmony_ci return NULL; 6327db96d56Sopenharmony_ci } 6337db96d56Sopenharmony_ci 6347db96d56Sopenharmony_ci strcpy(argv0, className); 6357db96d56Sopenharmony_ci if (Py_ISUPPER(argv0[0])) 6367db96d56Sopenharmony_ci argv0[0] = Py_TOLOWER(argv0[0]); 6377db96d56Sopenharmony_ci Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); 6387db96d56Sopenharmony_ci PyMem_Free(argv0); 6397db96d56Sopenharmony_ci 6407db96d56Sopenharmony_ci if (! wantTk) { 6417db96d56Sopenharmony_ci Tcl_SetVar(v->interp, 6427db96d56Sopenharmony_ci "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY); 6437db96d56Sopenharmony_ci } 6447db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 6457db96d56Sopenharmony_ci else if (tk_load_failed) { 6467db96d56Sopenharmony_ci Tcl_SetVar(v->interp, 6477db96d56Sopenharmony_ci "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); 6487db96d56Sopenharmony_ci } 6497db96d56Sopenharmony_ci#endif 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ci /* some initial arguments need to be in argv */ 6527db96d56Sopenharmony_ci if (sync || use) { 6537db96d56Sopenharmony_ci char *args; 6547db96d56Sopenharmony_ci Py_ssize_t len = 0; 6557db96d56Sopenharmony_ci 6567db96d56Sopenharmony_ci if (sync) 6577db96d56Sopenharmony_ci len += sizeof "-sync"; 6587db96d56Sopenharmony_ci if (use) 6597db96d56Sopenharmony_ci len += strlen(use) + sizeof "-use "; /* never overflows */ 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci args = (char*)PyMem_Malloc(len); 6627db96d56Sopenharmony_ci if (!args) { 6637db96d56Sopenharmony_ci PyErr_NoMemory(); 6647db96d56Sopenharmony_ci Py_DECREF(v); 6657db96d56Sopenharmony_ci return NULL; 6667db96d56Sopenharmony_ci } 6677db96d56Sopenharmony_ci 6687db96d56Sopenharmony_ci args[0] = '\0'; 6697db96d56Sopenharmony_ci if (sync) 6707db96d56Sopenharmony_ci strcat(args, "-sync"); 6717db96d56Sopenharmony_ci if (use) { 6727db96d56Sopenharmony_ci if (sync) 6737db96d56Sopenharmony_ci strcat(args, " "); 6747db96d56Sopenharmony_ci strcat(args, "-use "); 6757db96d56Sopenharmony_ci strcat(args, use); 6767db96d56Sopenharmony_ci } 6777db96d56Sopenharmony_ci 6787db96d56Sopenharmony_ci Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); 6797db96d56Sopenharmony_ci PyMem_Free(args); 6807db96d56Sopenharmony_ci } 6817db96d56Sopenharmony_ci 6827db96d56Sopenharmony_ci#ifdef MS_WINDOWS 6837db96d56Sopenharmony_ci { 6847db96d56Sopenharmony_ci PyObject *str_path; 6857db96d56Sopenharmony_ci PyObject *utf8_path; 6867db96d56Sopenharmony_ci DWORD ret; 6877db96d56Sopenharmony_ci 6887db96d56Sopenharmony_ci ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); 6897db96d56Sopenharmony_ci if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { 6907db96d56Sopenharmony_ci str_path = _get_tcl_lib_path(); 6917db96d56Sopenharmony_ci if (str_path == NULL && PyErr_Occurred()) { 6927db96d56Sopenharmony_ci return NULL; 6937db96d56Sopenharmony_ci } 6947db96d56Sopenharmony_ci if (str_path != NULL) { 6957db96d56Sopenharmony_ci utf8_path = PyUnicode_AsUTF8String(str_path); 6967db96d56Sopenharmony_ci if (utf8_path == NULL) { 6977db96d56Sopenharmony_ci return NULL; 6987db96d56Sopenharmony_ci } 6997db96d56Sopenharmony_ci Tcl_SetVar(v->interp, 7007db96d56Sopenharmony_ci "tcl_library", 7017db96d56Sopenharmony_ci PyBytes_AS_STRING(utf8_path), 7027db96d56Sopenharmony_ci TCL_GLOBAL_ONLY); 7037db96d56Sopenharmony_ci Py_DECREF(utf8_path); 7047db96d56Sopenharmony_ci } 7057db96d56Sopenharmony_ci } 7067db96d56Sopenharmony_ci } 7077db96d56Sopenharmony_ci#endif 7087db96d56Sopenharmony_ci 7097db96d56Sopenharmony_ci if (Tcl_AppInit(v->interp) != TCL_OK) { 7107db96d56Sopenharmony_ci PyObject *result = Tkinter_Error(v); 7117db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 7127db96d56Sopenharmony_ci if (wantTk) { 7137db96d56Sopenharmony_ci const char *_tkinter_tk_failed; 7147db96d56Sopenharmony_ci _tkinter_tk_failed = Tcl_GetVar(v->interp, 7157db96d56Sopenharmony_ci "_tkinter_tk_failed", TCL_GLOBAL_ONLY); 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_ci if ( _tkinter_tk_failed != NULL && 7187db96d56Sopenharmony_ci strcmp(_tkinter_tk_failed, "1") == 0) { 7197db96d56Sopenharmony_ci tk_load_failed = 1; 7207db96d56Sopenharmony_ci } 7217db96d56Sopenharmony_ci } 7227db96d56Sopenharmony_ci#endif 7237db96d56Sopenharmony_ci Py_DECREF((PyObject *)v); 7247db96d56Sopenharmony_ci return (TkappObject *)result; 7257db96d56Sopenharmony_ci } 7267db96d56Sopenharmony_ci 7277db96d56Sopenharmony_ci EnableEventHook(); 7287db96d56Sopenharmony_ci 7297db96d56Sopenharmony_ci return v; 7307db96d56Sopenharmony_ci} 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci 7337db96d56Sopenharmony_cistatic void 7347db96d56Sopenharmony_ciTkapp_ThreadSend(TkappObject *self, Tcl_Event *ev, 7357db96d56Sopenharmony_ci Tcl_Condition *cond, Tcl_Mutex *mutex) 7367db96d56Sopenharmony_ci{ 7377db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS; 7387db96d56Sopenharmony_ci Tcl_MutexLock(mutex); 7397db96d56Sopenharmony_ci Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL); 7407db96d56Sopenharmony_ci Tcl_ThreadAlert(self->thread_id); 7417db96d56Sopenharmony_ci Tcl_ConditionWait(cond, mutex, NULL); 7427db96d56Sopenharmony_ci Tcl_MutexUnlock(mutex); 7437db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 7447db96d56Sopenharmony_ci} 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ci 7477db96d56Sopenharmony_ci/** Tcl Eval **/ 7487db96d56Sopenharmony_ci 7497db96d56Sopenharmony_citypedef struct { 7507db96d56Sopenharmony_ci PyObject_HEAD 7517db96d56Sopenharmony_ci Tcl_Obj *value; 7527db96d56Sopenharmony_ci PyObject *string; /* This cannot cause cycles. */ 7537db96d56Sopenharmony_ci} PyTclObject; 7547db96d56Sopenharmony_ci 7557db96d56Sopenharmony_cistatic PyObject *PyTclObject_Type; 7567db96d56Sopenharmony_ci#define PyTclObject_Check(v) Py_IS_TYPE(v, (PyTypeObject *) PyTclObject_Type) 7577db96d56Sopenharmony_ci 7587db96d56Sopenharmony_cistatic PyObject * 7597db96d56Sopenharmony_cinewPyTclObject(Tcl_Obj *arg) 7607db96d56Sopenharmony_ci{ 7617db96d56Sopenharmony_ci PyTclObject *self; 7627db96d56Sopenharmony_ci self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type); 7637db96d56Sopenharmony_ci if (self == NULL) 7647db96d56Sopenharmony_ci return NULL; 7657db96d56Sopenharmony_ci Tcl_IncrRefCount(arg); 7667db96d56Sopenharmony_ci self->value = arg; 7677db96d56Sopenharmony_ci self->string = NULL; 7687db96d56Sopenharmony_ci return (PyObject*)self; 7697db96d56Sopenharmony_ci} 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_cistatic void 7727db96d56Sopenharmony_ciPyTclObject_dealloc(PyTclObject *self) 7737db96d56Sopenharmony_ci{ 7747db96d56Sopenharmony_ci PyObject *tp = (PyObject *) Py_TYPE(self); 7757db96d56Sopenharmony_ci Tcl_DecrRefCount(self->value); 7767db96d56Sopenharmony_ci Py_XDECREF(self->string); 7777db96d56Sopenharmony_ci PyObject_Free(self); 7787db96d56Sopenharmony_ci Py_DECREF(tp); 7797db96d56Sopenharmony_ci} 7807db96d56Sopenharmony_ci 7817db96d56Sopenharmony_ci/* Like _str, but create Unicode if necessary. */ 7827db96d56Sopenharmony_ciPyDoc_STRVAR(PyTclObject_string__doc__, 7837db96d56Sopenharmony_ci"the string representation of this object, either as str or bytes"); 7847db96d56Sopenharmony_ci 7857db96d56Sopenharmony_cistatic PyObject * 7867db96d56Sopenharmony_ciPyTclObject_string(PyTclObject *self, void *ignored) 7877db96d56Sopenharmony_ci{ 7887db96d56Sopenharmony_ci if (!self->string) { 7897db96d56Sopenharmony_ci self->string = unicodeFromTclObj(self->value); 7907db96d56Sopenharmony_ci if (!self->string) 7917db96d56Sopenharmony_ci return NULL; 7927db96d56Sopenharmony_ci } 7937db96d56Sopenharmony_ci Py_INCREF(self->string); 7947db96d56Sopenharmony_ci return self->string; 7957db96d56Sopenharmony_ci} 7967db96d56Sopenharmony_ci 7977db96d56Sopenharmony_cistatic PyObject * 7987db96d56Sopenharmony_ciPyTclObject_str(PyTclObject *self) 7997db96d56Sopenharmony_ci{ 8007db96d56Sopenharmony_ci if (self->string) { 8017db96d56Sopenharmony_ci Py_INCREF(self->string); 8027db96d56Sopenharmony_ci return self->string; 8037db96d56Sopenharmony_ci } 8047db96d56Sopenharmony_ci /* XXX Could cache result if it is non-ASCII. */ 8057db96d56Sopenharmony_ci return unicodeFromTclObj(self->value); 8067db96d56Sopenharmony_ci} 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_cistatic PyObject * 8097db96d56Sopenharmony_ciPyTclObject_repr(PyTclObject *self) 8107db96d56Sopenharmony_ci{ 8117db96d56Sopenharmony_ci PyObject *repr, *str = PyTclObject_str(self); 8127db96d56Sopenharmony_ci if (str == NULL) 8137db96d56Sopenharmony_ci return NULL; 8147db96d56Sopenharmony_ci repr = PyUnicode_FromFormat("<%s object: %R>", 8157db96d56Sopenharmony_ci self->value->typePtr->name, str); 8167db96d56Sopenharmony_ci Py_DECREF(str); 8177db96d56Sopenharmony_ci return repr; 8187db96d56Sopenharmony_ci} 8197db96d56Sopenharmony_ci 8207db96d56Sopenharmony_cistatic PyObject * 8217db96d56Sopenharmony_ciPyTclObject_richcompare(PyObject *self, PyObject *other, int op) 8227db96d56Sopenharmony_ci{ 8237db96d56Sopenharmony_ci int result; 8247db96d56Sopenharmony_ci 8257db96d56Sopenharmony_ci /* neither argument should be NULL, unless something's gone wrong */ 8267db96d56Sopenharmony_ci if (self == NULL || other == NULL) { 8277db96d56Sopenharmony_ci PyErr_BadInternalCall(); 8287db96d56Sopenharmony_ci return NULL; 8297db96d56Sopenharmony_ci } 8307db96d56Sopenharmony_ci 8317db96d56Sopenharmony_ci /* both arguments should be instances of PyTclObject */ 8327db96d56Sopenharmony_ci if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) { 8337db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 8347db96d56Sopenharmony_ci } 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci if (self == other) 8377db96d56Sopenharmony_ci /* fast path when self and other are identical */ 8387db96d56Sopenharmony_ci result = 0; 8397db96d56Sopenharmony_ci else 8407db96d56Sopenharmony_ci result = strcmp(Tcl_GetString(((PyTclObject *)self)->value), 8417db96d56Sopenharmony_ci Tcl_GetString(((PyTclObject *)other)->value)); 8427db96d56Sopenharmony_ci Py_RETURN_RICHCOMPARE(result, 0, op); 8437db96d56Sopenharmony_ci} 8447db96d56Sopenharmony_ci 8457db96d56Sopenharmony_ciPyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_cistatic PyObject* 8487db96d56Sopenharmony_ciget_typename(PyTclObject* obj, void* ignored) 8497db96d56Sopenharmony_ci{ 8507db96d56Sopenharmony_ci return unicodeFromTclString(obj->value->typePtr->name); 8517db96d56Sopenharmony_ci} 8527db96d56Sopenharmony_ci 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_cistatic PyGetSetDef PyTclObject_getsetlist[] = { 8557db96d56Sopenharmony_ci {"typename", (getter)get_typename, NULL, get_typename__doc__}, 8567db96d56Sopenharmony_ci {"string", (getter)PyTclObject_string, NULL, 8577db96d56Sopenharmony_ci PyTclObject_string__doc__}, 8587db96d56Sopenharmony_ci {0}, 8597db96d56Sopenharmony_ci}; 8607db96d56Sopenharmony_ci 8617db96d56Sopenharmony_cistatic PyType_Slot PyTclObject_Type_slots[] = { 8627db96d56Sopenharmony_ci {Py_tp_dealloc, (destructor)PyTclObject_dealloc}, 8637db96d56Sopenharmony_ci {Py_tp_repr, (reprfunc)PyTclObject_repr}, 8647db96d56Sopenharmony_ci {Py_tp_str, (reprfunc)PyTclObject_str}, 8657db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 8667db96d56Sopenharmony_ci {Py_tp_richcompare, PyTclObject_richcompare}, 8677db96d56Sopenharmony_ci {Py_tp_getset, PyTclObject_getsetlist}, 8687db96d56Sopenharmony_ci {0, 0} 8697db96d56Sopenharmony_ci}; 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_cistatic PyType_Spec PyTclObject_Type_spec = { 8727db96d56Sopenharmony_ci "_tkinter.Tcl_Obj", 8737db96d56Sopenharmony_ci sizeof(PyTclObject), 8747db96d56Sopenharmony_ci 0, 8757db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, 8767db96d56Sopenharmony_ci PyTclObject_Type_slots, 8777db96d56Sopenharmony_ci}; 8787db96d56Sopenharmony_ci 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci#if SIZE_MAX > INT_MAX 8817db96d56Sopenharmony_ci#define CHECK_STRING_LENGTH(s) do { \ 8827db96d56Sopenharmony_ci if (s != NULL && strlen(s) >= INT_MAX) { \ 8837db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "string is too long"); \ 8847db96d56Sopenharmony_ci return NULL; \ 8857db96d56Sopenharmony_ci } } while(0) 8867db96d56Sopenharmony_ci#else 8877db96d56Sopenharmony_ci#define CHECK_STRING_LENGTH(s) 8887db96d56Sopenharmony_ci#endif 8897db96d56Sopenharmony_ci 8907db96d56Sopenharmony_cistatic Tcl_Obj* 8917db96d56Sopenharmony_ciasBignumObj(PyObject *value) 8927db96d56Sopenharmony_ci{ 8937db96d56Sopenharmony_ci Tcl_Obj *result; 8947db96d56Sopenharmony_ci int neg; 8957db96d56Sopenharmony_ci PyObject *hexstr; 8967db96d56Sopenharmony_ci const char *hexchars; 8977db96d56Sopenharmony_ci mp_int bigValue; 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci neg = Py_SIZE(value) < 0; 9007db96d56Sopenharmony_ci hexstr = _PyLong_Format(value, 16); 9017db96d56Sopenharmony_ci if (hexstr == NULL) 9027db96d56Sopenharmony_ci return NULL; 9037db96d56Sopenharmony_ci hexchars = PyUnicode_AsUTF8(hexstr); 9047db96d56Sopenharmony_ci if (hexchars == NULL) { 9057db96d56Sopenharmony_ci Py_DECREF(hexstr); 9067db96d56Sopenharmony_ci return NULL; 9077db96d56Sopenharmony_ci } 9087db96d56Sopenharmony_ci hexchars += neg + 2; /* skip sign and "0x" */ 9097db96d56Sopenharmony_ci mp_init(&bigValue); 9107db96d56Sopenharmony_ci if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { 9117db96d56Sopenharmony_ci mp_clear(&bigValue); 9127db96d56Sopenharmony_ci Py_DECREF(hexstr); 9137db96d56Sopenharmony_ci PyErr_NoMemory(); 9147db96d56Sopenharmony_ci return NULL; 9157db96d56Sopenharmony_ci } 9167db96d56Sopenharmony_ci Py_DECREF(hexstr); 9177db96d56Sopenharmony_ci bigValue.sign = neg ? MP_NEG : MP_ZPOS; 9187db96d56Sopenharmony_ci result = Tcl_NewBignumObj(&bigValue); 9197db96d56Sopenharmony_ci mp_clear(&bigValue); 9207db96d56Sopenharmony_ci if (result == NULL) { 9217db96d56Sopenharmony_ci PyErr_NoMemory(); 9227db96d56Sopenharmony_ci return NULL; 9237db96d56Sopenharmony_ci } 9247db96d56Sopenharmony_ci return result; 9257db96d56Sopenharmony_ci} 9267db96d56Sopenharmony_ci 9277db96d56Sopenharmony_cistatic Tcl_Obj* 9287db96d56Sopenharmony_ciAsObj(PyObject *value) 9297db96d56Sopenharmony_ci{ 9307db96d56Sopenharmony_ci Tcl_Obj *result; 9317db96d56Sopenharmony_ci 9327db96d56Sopenharmony_ci if (PyBytes_Check(value)) { 9337db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(value) >= INT_MAX) { 9347db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); 9357db96d56Sopenharmony_ci return NULL; 9367db96d56Sopenharmony_ci } 9377db96d56Sopenharmony_ci return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value), 9387db96d56Sopenharmony_ci (int)PyBytes_GET_SIZE(value)); 9397db96d56Sopenharmony_ci } 9407db96d56Sopenharmony_ci 9417db96d56Sopenharmony_ci if (PyBool_Check(value)) 9427db96d56Sopenharmony_ci return Tcl_NewBooleanObj(PyObject_IsTrue(value)); 9437db96d56Sopenharmony_ci 9447db96d56Sopenharmony_ci if (PyLong_CheckExact(value)) { 9457db96d56Sopenharmony_ci int overflow; 9467db96d56Sopenharmony_ci long longValue; 9477db96d56Sopenharmony_ci#ifdef TCL_WIDE_INT_TYPE 9487db96d56Sopenharmony_ci Tcl_WideInt wideValue; 9497db96d56Sopenharmony_ci#endif 9507db96d56Sopenharmony_ci longValue = PyLong_AsLongAndOverflow(value, &overflow); 9517db96d56Sopenharmony_ci if (!overflow) { 9527db96d56Sopenharmony_ci return Tcl_NewLongObj(longValue); 9537db96d56Sopenharmony_ci } 9547db96d56Sopenharmony_ci /* If there is an overflow in the long conversion, 9557db96d56Sopenharmony_ci fall through to wideInt handling. */ 9567db96d56Sopenharmony_ci#ifdef TCL_WIDE_INT_TYPE 9577db96d56Sopenharmony_ci if (_PyLong_AsByteArray((PyLongObject *)value, 9587db96d56Sopenharmony_ci (unsigned char *)(void *)&wideValue, 9597db96d56Sopenharmony_ci sizeof(wideValue), 9607db96d56Sopenharmony_ci PY_LITTLE_ENDIAN, 9617db96d56Sopenharmony_ci /* signed */ 1) == 0) { 9627db96d56Sopenharmony_ci return Tcl_NewWideIntObj(wideValue); 9637db96d56Sopenharmony_ci } 9647db96d56Sopenharmony_ci PyErr_Clear(); 9657db96d56Sopenharmony_ci#endif 9667db96d56Sopenharmony_ci /* If there is an overflow in the wideInt conversion, 9677db96d56Sopenharmony_ci fall through to bignum handling. */ 9687db96d56Sopenharmony_ci return asBignumObj(value); 9697db96d56Sopenharmony_ci /* If there is no wideInt or bignum support, 9707db96d56Sopenharmony_ci fall through to default object handling. */ 9717db96d56Sopenharmony_ci } 9727db96d56Sopenharmony_ci 9737db96d56Sopenharmony_ci if (PyFloat_Check(value)) 9747db96d56Sopenharmony_ci return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); 9757db96d56Sopenharmony_ci 9767db96d56Sopenharmony_ci if (PyTuple_Check(value) || PyList_Check(value)) { 9777db96d56Sopenharmony_ci Tcl_Obj **argv; 9787db96d56Sopenharmony_ci Py_ssize_t size, i; 9797db96d56Sopenharmony_ci 9807db96d56Sopenharmony_ci size = PySequence_Fast_GET_SIZE(value); 9817db96d56Sopenharmony_ci if (size == 0) 9827db96d56Sopenharmony_ci return Tcl_NewListObj(0, NULL); 9837db96d56Sopenharmony_ci if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { 9847db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 9857db96d56Sopenharmony_ci PyTuple_Check(value) ? "tuple is too long" : 9867db96d56Sopenharmony_ci "list is too long"); 9877db96d56Sopenharmony_ci return NULL; 9887db96d56Sopenharmony_ci } 9897db96d56Sopenharmony_ci argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *)); 9907db96d56Sopenharmony_ci if (!argv) { 9917db96d56Sopenharmony_ci PyErr_NoMemory(); 9927db96d56Sopenharmony_ci return NULL; 9937db96d56Sopenharmony_ci } 9947db96d56Sopenharmony_ci for (i = 0; i < size; i++) 9957db96d56Sopenharmony_ci argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); 9967db96d56Sopenharmony_ci result = Tcl_NewListObj((int)size, argv); 9977db96d56Sopenharmony_ci PyMem_Free(argv); 9987db96d56Sopenharmony_ci return result; 9997db96d56Sopenharmony_ci } 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_ci if (PyUnicode_Check(value)) { 10027db96d56Sopenharmony_ci if (PyUnicode_READY(value) == -1) 10037db96d56Sopenharmony_ci return NULL; 10047db96d56Sopenharmony_ci 10057db96d56Sopenharmony_ci Py_ssize_t size = PyUnicode_GET_LENGTH(value); 10067db96d56Sopenharmony_ci if (size == 0) { 10077db96d56Sopenharmony_ci return Tcl_NewStringObj("", 0); 10087db96d56Sopenharmony_ci } 10097db96d56Sopenharmony_ci if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { 10107db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "string is too long"); 10117db96d56Sopenharmony_ci return NULL; 10127db96d56Sopenharmony_ci } 10137db96d56Sopenharmony_ci if (PyUnicode_IS_ASCII(value)) { 10147db96d56Sopenharmony_ci return Tcl_NewStringObj((const char *)PyUnicode_DATA(value), 10157db96d56Sopenharmony_ci (int)size); 10167db96d56Sopenharmony_ci } 10177db96d56Sopenharmony_ci 10187db96d56Sopenharmony_ci PyObject *encoded; 10197db96d56Sopenharmony_ci#if USE_TCL_UNICODE 10207db96d56Sopenharmony_ci if (sizeof(Tcl_UniChar) == 2) 10217db96d56Sopenharmony_ci encoded = _PyUnicode_EncodeUTF16(value, 10227db96d56Sopenharmony_ci "surrogatepass", NATIVE_BYTEORDER); 10237db96d56Sopenharmony_ci else if (sizeof(Tcl_UniChar) == 4) 10247db96d56Sopenharmony_ci encoded = _PyUnicode_EncodeUTF32(value, 10257db96d56Sopenharmony_ci "surrogatepass", NATIVE_BYTEORDER); 10267db96d56Sopenharmony_ci else 10277db96d56Sopenharmony_ci Py_UNREACHABLE(); 10287db96d56Sopenharmony_ci#else 10297db96d56Sopenharmony_ci encoded = _PyUnicode_AsUTF8String(value, "surrogateescape"); 10307db96d56Sopenharmony_ci#endif 10317db96d56Sopenharmony_ci if (!encoded) { 10327db96d56Sopenharmony_ci return NULL; 10337db96d56Sopenharmony_ci } 10347db96d56Sopenharmony_ci size = PyBytes_GET_SIZE(encoded); 10357db96d56Sopenharmony_ci if (size > INT_MAX) { 10367db96d56Sopenharmony_ci Py_DECREF(encoded); 10377db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "string is too long"); 10387db96d56Sopenharmony_ci return NULL; 10397db96d56Sopenharmony_ci } 10407db96d56Sopenharmony_ci#if USE_TCL_UNICODE 10417db96d56Sopenharmony_ci result = Tcl_NewUnicodeObj((const Tcl_UniChar *)PyBytes_AS_STRING(encoded), 10427db96d56Sopenharmony_ci (int)(size / sizeof(Tcl_UniChar))); 10437db96d56Sopenharmony_ci#else 10447db96d56Sopenharmony_ci result = Tcl_NewStringObj(PyBytes_AS_STRING(encoded), (int)size); 10457db96d56Sopenharmony_ci#endif 10467db96d56Sopenharmony_ci Py_DECREF(encoded); 10477db96d56Sopenharmony_ci return result; 10487db96d56Sopenharmony_ci } 10497db96d56Sopenharmony_ci 10507db96d56Sopenharmony_ci if (PyTclObject_Check(value)) { 10517db96d56Sopenharmony_ci return ((PyTclObject*)value)->value; 10527db96d56Sopenharmony_ci } 10537db96d56Sopenharmony_ci 10547db96d56Sopenharmony_ci { 10557db96d56Sopenharmony_ci PyObject *v = PyObject_Str(value); 10567db96d56Sopenharmony_ci if (!v) 10577db96d56Sopenharmony_ci return 0; 10587db96d56Sopenharmony_ci result = AsObj(v); 10597db96d56Sopenharmony_ci Py_DECREF(v); 10607db96d56Sopenharmony_ci return result; 10617db96d56Sopenharmony_ci } 10627db96d56Sopenharmony_ci} 10637db96d56Sopenharmony_ci 10647db96d56Sopenharmony_cistatic PyObject * 10657db96d56Sopenharmony_cifromBoolean(TkappObject *tkapp, Tcl_Obj *value) 10667db96d56Sopenharmony_ci{ 10677db96d56Sopenharmony_ci int boolValue; 10687db96d56Sopenharmony_ci if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) 10697db96d56Sopenharmony_ci return Tkinter_Error(tkapp); 10707db96d56Sopenharmony_ci return PyBool_FromLong(boolValue); 10717db96d56Sopenharmony_ci} 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_cistatic PyObject* 10747db96d56Sopenharmony_cifromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) 10757db96d56Sopenharmony_ci{ 10767db96d56Sopenharmony_ci Tcl_WideInt wideValue; 10777db96d56Sopenharmony_ci if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { 10787db96d56Sopenharmony_ci if (sizeof(wideValue) <= SIZEOF_LONG_LONG) 10797db96d56Sopenharmony_ci return PyLong_FromLongLong(wideValue); 10807db96d56Sopenharmony_ci return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, 10817db96d56Sopenharmony_ci sizeof(wideValue), 10827db96d56Sopenharmony_ci PY_LITTLE_ENDIAN, 10837db96d56Sopenharmony_ci /* signed */ 1); 10847db96d56Sopenharmony_ci } 10857db96d56Sopenharmony_ci return NULL; 10867db96d56Sopenharmony_ci} 10877db96d56Sopenharmony_ci 10887db96d56Sopenharmony_cistatic PyObject* 10897db96d56Sopenharmony_cifromBignumObj(TkappObject *tkapp, Tcl_Obj *value) 10907db96d56Sopenharmony_ci{ 10917db96d56Sopenharmony_ci mp_int bigValue; 10927db96d56Sopenharmony_ci mp_err err; 10937db96d56Sopenharmony_ci#if USE_DEPRECATED_TOMMATH_API 10947db96d56Sopenharmony_ci unsigned long numBytes; 10957db96d56Sopenharmony_ci#else 10967db96d56Sopenharmony_ci size_t numBytes; 10977db96d56Sopenharmony_ci#endif 10987db96d56Sopenharmony_ci unsigned char *bytes; 10997db96d56Sopenharmony_ci PyObject *res; 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_ci if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK) 11027db96d56Sopenharmony_ci return Tkinter_Error(tkapp); 11037db96d56Sopenharmony_ci#if USE_DEPRECATED_TOMMATH_API 11047db96d56Sopenharmony_ci numBytes = mp_unsigned_bin_size(&bigValue); 11057db96d56Sopenharmony_ci#else 11067db96d56Sopenharmony_ci numBytes = mp_ubin_size(&bigValue); 11077db96d56Sopenharmony_ci#endif 11087db96d56Sopenharmony_ci bytes = PyMem_Malloc(numBytes); 11097db96d56Sopenharmony_ci if (bytes == NULL) { 11107db96d56Sopenharmony_ci mp_clear(&bigValue); 11117db96d56Sopenharmony_ci return PyErr_NoMemory(); 11127db96d56Sopenharmony_ci } 11137db96d56Sopenharmony_ci#if USE_DEPRECATED_TOMMATH_API 11147db96d56Sopenharmony_ci err = mp_to_unsigned_bin_n(&bigValue, bytes, &numBytes); 11157db96d56Sopenharmony_ci#else 11167db96d56Sopenharmony_ci err = mp_to_ubin(&bigValue, bytes, numBytes, NULL); 11177db96d56Sopenharmony_ci#endif 11187db96d56Sopenharmony_ci if (err != MP_OKAY) { 11197db96d56Sopenharmony_ci mp_clear(&bigValue); 11207db96d56Sopenharmony_ci PyMem_Free(bytes); 11217db96d56Sopenharmony_ci return PyErr_NoMemory(); 11227db96d56Sopenharmony_ci } 11237db96d56Sopenharmony_ci res = _PyLong_FromByteArray(bytes, numBytes, 11247db96d56Sopenharmony_ci /* big-endian */ 0, 11257db96d56Sopenharmony_ci /* unsigned */ 0); 11267db96d56Sopenharmony_ci PyMem_Free(bytes); 11277db96d56Sopenharmony_ci if (res != NULL && bigValue.sign == MP_NEG) { 11287db96d56Sopenharmony_ci PyObject *res2 = PyNumber_Negative(res); 11297db96d56Sopenharmony_ci Py_DECREF(res); 11307db96d56Sopenharmony_ci res = res2; 11317db96d56Sopenharmony_ci } 11327db96d56Sopenharmony_ci mp_clear(&bigValue); 11337db96d56Sopenharmony_ci return res; 11347db96d56Sopenharmony_ci} 11357db96d56Sopenharmony_ci 11367db96d56Sopenharmony_cistatic PyObject* 11377db96d56Sopenharmony_ciFromObj(TkappObject *tkapp, Tcl_Obj *value) 11387db96d56Sopenharmony_ci{ 11397db96d56Sopenharmony_ci PyObject *result = NULL; 11407db96d56Sopenharmony_ci Tcl_Interp *interp = Tkapp_Interp(tkapp); 11417db96d56Sopenharmony_ci 11427db96d56Sopenharmony_ci if (value->typePtr == NULL) { 11437db96d56Sopenharmony_ci return unicodeFromTclObj(value); 11447db96d56Sopenharmony_ci } 11457db96d56Sopenharmony_ci 11467db96d56Sopenharmony_ci if (value->typePtr == tkapp->BooleanType || 11477db96d56Sopenharmony_ci value->typePtr == tkapp->OldBooleanType) { 11487db96d56Sopenharmony_ci return fromBoolean(tkapp, value); 11497db96d56Sopenharmony_ci } 11507db96d56Sopenharmony_ci 11517db96d56Sopenharmony_ci if (value->typePtr == tkapp->ByteArrayType) { 11527db96d56Sopenharmony_ci int size; 11537db96d56Sopenharmony_ci char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); 11547db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(data, size); 11557db96d56Sopenharmony_ci } 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ci if (value->typePtr == tkapp->DoubleType) { 11587db96d56Sopenharmony_ci return PyFloat_FromDouble(value->internalRep.doubleValue); 11597db96d56Sopenharmony_ci } 11607db96d56Sopenharmony_ci 11617db96d56Sopenharmony_ci if (value->typePtr == tkapp->IntType) { 11627db96d56Sopenharmony_ci long longValue; 11637db96d56Sopenharmony_ci if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) 11647db96d56Sopenharmony_ci return PyLong_FromLong(longValue); 11657db96d56Sopenharmony_ci /* If there is an error in the long conversion, 11667db96d56Sopenharmony_ci fall through to wideInt handling. */ 11677db96d56Sopenharmony_ci } 11687db96d56Sopenharmony_ci 11697db96d56Sopenharmony_ci if (value->typePtr == tkapp->IntType || 11707db96d56Sopenharmony_ci value->typePtr == tkapp->WideIntType) { 11717db96d56Sopenharmony_ci result = fromWideIntObj(tkapp, value); 11727db96d56Sopenharmony_ci if (result != NULL || PyErr_Occurred()) 11737db96d56Sopenharmony_ci return result; 11747db96d56Sopenharmony_ci Tcl_ResetResult(interp); 11757db96d56Sopenharmony_ci /* If there is an error in the wideInt conversion, 11767db96d56Sopenharmony_ci fall through to bignum handling. */ 11777db96d56Sopenharmony_ci } 11787db96d56Sopenharmony_ci 11797db96d56Sopenharmony_ci if (value->typePtr == tkapp->IntType || 11807db96d56Sopenharmony_ci value->typePtr == tkapp->WideIntType || 11817db96d56Sopenharmony_ci value->typePtr == tkapp->BignumType) { 11827db96d56Sopenharmony_ci return fromBignumObj(tkapp, value); 11837db96d56Sopenharmony_ci } 11847db96d56Sopenharmony_ci 11857db96d56Sopenharmony_ci if (value->typePtr == tkapp->ListType) { 11867db96d56Sopenharmony_ci int size; 11877db96d56Sopenharmony_ci int i, status; 11887db96d56Sopenharmony_ci PyObject *elem; 11897db96d56Sopenharmony_ci Tcl_Obj *tcl_elem; 11907db96d56Sopenharmony_ci 11917db96d56Sopenharmony_ci status = Tcl_ListObjLength(interp, value, &size); 11927db96d56Sopenharmony_ci if (status == TCL_ERROR) 11937db96d56Sopenharmony_ci return Tkinter_Error(tkapp); 11947db96d56Sopenharmony_ci result = PyTuple_New(size); 11957db96d56Sopenharmony_ci if (!result) 11967db96d56Sopenharmony_ci return NULL; 11977db96d56Sopenharmony_ci for (i = 0; i < size; i++) { 11987db96d56Sopenharmony_ci status = Tcl_ListObjIndex(interp, value, i, &tcl_elem); 11997db96d56Sopenharmony_ci if (status == TCL_ERROR) { 12007db96d56Sopenharmony_ci Py_DECREF(result); 12017db96d56Sopenharmony_ci return Tkinter_Error(tkapp); 12027db96d56Sopenharmony_ci } 12037db96d56Sopenharmony_ci elem = FromObj(tkapp, tcl_elem); 12047db96d56Sopenharmony_ci if (!elem) { 12057db96d56Sopenharmony_ci Py_DECREF(result); 12067db96d56Sopenharmony_ci return NULL; 12077db96d56Sopenharmony_ci } 12087db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 12097db96d56Sopenharmony_ci } 12107db96d56Sopenharmony_ci return result; 12117db96d56Sopenharmony_ci } 12127db96d56Sopenharmony_ci 12137db96d56Sopenharmony_ci if (value->typePtr == tkapp->ProcBodyType) { 12147db96d56Sopenharmony_ci /* fall through: return tcl object. */ 12157db96d56Sopenharmony_ci } 12167db96d56Sopenharmony_ci 12177db96d56Sopenharmony_ci if (value->typePtr == tkapp->StringType) { 12187db96d56Sopenharmony_ci return unicodeFromTclObj(value); 12197db96d56Sopenharmony_ci } 12207db96d56Sopenharmony_ci 12217db96d56Sopenharmony_ci if (tkapp->BooleanType == NULL && 12227db96d56Sopenharmony_ci strcmp(value->typePtr->name, "booleanString") == 0) { 12237db96d56Sopenharmony_ci /* booleanString type is not registered in Tcl */ 12247db96d56Sopenharmony_ci tkapp->BooleanType = value->typePtr; 12257db96d56Sopenharmony_ci return fromBoolean(tkapp, value); 12267db96d56Sopenharmony_ci } 12277db96d56Sopenharmony_ci 12287db96d56Sopenharmony_ci if (tkapp->BignumType == NULL && 12297db96d56Sopenharmony_ci strcmp(value->typePtr->name, "bignum") == 0) { 12307db96d56Sopenharmony_ci /* bignum type is not registered in Tcl */ 12317db96d56Sopenharmony_ci tkapp->BignumType = value->typePtr; 12327db96d56Sopenharmony_ci return fromBignumObj(tkapp, value); 12337db96d56Sopenharmony_ci } 12347db96d56Sopenharmony_ci 12357db96d56Sopenharmony_ci return newPyTclObject(value); 12367db96d56Sopenharmony_ci} 12377db96d56Sopenharmony_ci 12387db96d56Sopenharmony_ci/* This mutex synchronizes inter-thread command calls. */ 12397db96d56Sopenharmony_ciTCL_DECLARE_MUTEX(call_mutex) 12407db96d56Sopenharmony_ci 12417db96d56Sopenharmony_citypedef struct Tkapp_CallEvent { 12427db96d56Sopenharmony_ci Tcl_Event ev; /* Must be first */ 12437db96d56Sopenharmony_ci TkappObject *self; 12447db96d56Sopenharmony_ci PyObject *args; 12457db96d56Sopenharmony_ci int flags; 12467db96d56Sopenharmony_ci PyObject **res; 12477db96d56Sopenharmony_ci PyObject **exc_type, **exc_value, **exc_tb; 12487db96d56Sopenharmony_ci Tcl_Condition *done; 12497db96d56Sopenharmony_ci} Tkapp_CallEvent; 12507db96d56Sopenharmony_ci 12517db96d56Sopenharmony_civoid 12527db96d56Sopenharmony_ciTkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) 12537db96d56Sopenharmony_ci{ 12547db96d56Sopenharmony_ci int i; 12557db96d56Sopenharmony_ci for (i = 0; i < objc; i++) 12567db96d56Sopenharmony_ci Tcl_DecrRefCount(objv[i]); 12577db96d56Sopenharmony_ci if (objv != objStore) 12587db96d56Sopenharmony_ci PyMem_Free(objv); 12597db96d56Sopenharmony_ci} 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci/* Convert Python objects to Tcl objects. This must happen in the 12627db96d56Sopenharmony_ci interpreter thread, which may or may not be the calling thread. */ 12637db96d56Sopenharmony_ci 12647db96d56Sopenharmony_cistatic Tcl_Obj** 12657db96d56Sopenharmony_ciTkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) 12667db96d56Sopenharmony_ci{ 12677db96d56Sopenharmony_ci Tcl_Obj **objv = objStore; 12687db96d56Sopenharmony_ci Py_ssize_t objc = 0, i; 12697db96d56Sopenharmony_ci if (args == NULL) 12707db96d56Sopenharmony_ci /* do nothing */; 12717db96d56Sopenharmony_ci 12727db96d56Sopenharmony_ci else if (!(PyTuple_Check(args) || PyList_Check(args))) { 12737db96d56Sopenharmony_ci objv[0] = AsObj(args); 12747db96d56Sopenharmony_ci if (objv[0] == NULL) 12757db96d56Sopenharmony_ci goto finally; 12767db96d56Sopenharmony_ci objc = 1; 12777db96d56Sopenharmony_ci Tcl_IncrRefCount(objv[0]); 12787db96d56Sopenharmony_ci } 12797db96d56Sopenharmony_ci else { 12807db96d56Sopenharmony_ci objc = PySequence_Fast_GET_SIZE(args); 12817db96d56Sopenharmony_ci 12827db96d56Sopenharmony_ci if (objc > ARGSZ) { 12837db96d56Sopenharmony_ci if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { 12847db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 12857db96d56Sopenharmony_ci PyTuple_Check(args) ? "tuple is too long" : 12867db96d56Sopenharmony_ci "list is too long"); 12877db96d56Sopenharmony_ci return NULL; 12887db96d56Sopenharmony_ci } 12897db96d56Sopenharmony_ci objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *)); 12907db96d56Sopenharmony_ci if (objv == NULL) { 12917db96d56Sopenharmony_ci PyErr_NoMemory(); 12927db96d56Sopenharmony_ci objc = 0; 12937db96d56Sopenharmony_ci goto finally; 12947db96d56Sopenharmony_ci } 12957db96d56Sopenharmony_ci } 12967db96d56Sopenharmony_ci 12977db96d56Sopenharmony_ci for (i = 0; i < objc; i++) { 12987db96d56Sopenharmony_ci PyObject *v = PySequence_Fast_GET_ITEM(args, i); 12997db96d56Sopenharmony_ci if (v == Py_None) { 13007db96d56Sopenharmony_ci objc = i; 13017db96d56Sopenharmony_ci break; 13027db96d56Sopenharmony_ci } 13037db96d56Sopenharmony_ci objv[i] = AsObj(v); 13047db96d56Sopenharmony_ci if (!objv[i]) { 13057db96d56Sopenharmony_ci /* Reset objc, so it attempts to clear 13067db96d56Sopenharmony_ci objects only up to i. */ 13077db96d56Sopenharmony_ci objc = i; 13087db96d56Sopenharmony_ci goto finally; 13097db96d56Sopenharmony_ci } 13107db96d56Sopenharmony_ci Tcl_IncrRefCount(objv[i]); 13117db96d56Sopenharmony_ci } 13127db96d56Sopenharmony_ci } 13137db96d56Sopenharmony_ci *pobjc = (int)objc; 13147db96d56Sopenharmony_ci return objv; 13157db96d56Sopenharmony_cifinally: 13167db96d56Sopenharmony_ci Tkapp_CallDeallocArgs(objv, objStore, (int)objc); 13177db96d56Sopenharmony_ci return NULL; 13187db96d56Sopenharmony_ci} 13197db96d56Sopenharmony_ci 13207db96d56Sopenharmony_ci/* Convert the results of a command call into a Python string. */ 13217db96d56Sopenharmony_ci 13227db96d56Sopenharmony_cistatic PyObject * 13237db96d56Sopenharmony_ciTkapp_UnicodeResult(TkappObject *self) 13247db96d56Sopenharmony_ci{ 13257db96d56Sopenharmony_ci return unicodeFromTclObj(Tcl_GetObjResult(self->interp)); 13267db96d56Sopenharmony_ci} 13277db96d56Sopenharmony_ci 13287db96d56Sopenharmony_ci 13297db96d56Sopenharmony_ci/* Convert the results of a command call into a Python objects. */ 13307db96d56Sopenharmony_ci 13317db96d56Sopenharmony_cistatic PyObject * 13327db96d56Sopenharmony_ciTkapp_ObjectResult(TkappObject *self) 13337db96d56Sopenharmony_ci{ 13347db96d56Sopenharmony_ci PyObject *res = NULL; 13357db96d56Sopenharmony_ci Tcl_Obj *value = Tcl_GetObjResult(self->interp); 13367db96d56Sopenharmony_ci if (self->wantobjects) { 13377db96d56Sopenharmony_ci /* Not sure whether the IncrRef is necessary, but something 13387db96d56Sopenharmony_ci may overwrite the interpreter result while we are 13397db96d56Sopenharmony_ci converting it. */ 13407db96d56Sopenharmony_ci Tcl_IncrRefCount(value); 13417db96d56Sopenharmony_ci res = FromObj(self, value); 13427db96d56Sopenharmony_ci Tcl_DecrRefCount(value); 13437db96d56Sopenharmony_ci } else { 13447db96d56Sopenharmony_ci res = unicodeFromTclObj(value); 13457db96d56Sopenharmony_ci } 13467db96d56Sopenharmony_ci return res; 13477db96d56Sopenharmony_ci} 13487db96d56Sopenharmony_ci 13497db96d56Sopenharmony_ci 13507db96d56Sopenharmony_ci/* Tkapp_CallProc is the event procedure that is executed in the context of 13517db96d56Sopenharmony_ci the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't 13527db96d56Sopenharmony_ci hold the Python lock. */ 13537db96d56Sopenharmony_ci 13547db96d56Sopenharmony_cistatic int 13557db96d56Sopenharmony_ciTkapp_CallProc(Tkapp_CallEvent *e, int flags) 13567db96d56Sopenharmony_ci{ 13577db96d56Sopenharmony_ci Tcl_Obj *objStore[ARGSZ]; 13587db96d56Sopenharmony_ci Tcl_Obj **objv; 13597db96d56Sopenharmony_ci int objc; 13607db96d56Sopenharmony_ci int i; 13617db96d56Sopenharmony_ci ENTER_PYTHON 13627db96d56Sopenharmony_ci objv = Tkapp_CallArgs(e->args, objStore, &objc); 13637db96d56Sopenharmony_ci if (!objv) { 13647db96d56Sopenharmony_ci PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); 13657db96d56Sopenharmony_ci *(e->res) = NULL; 13667db96d56Sopenharmony_ci } 13677db96d56Sopenharmony_ci LEAVE_PYTHON 13687db96d56Sopenharmony_ci if (!objv) 13697db96d56Sopenharmony_ci goto done; 13707db96d56Sopenharmony_ci i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); 13717db96d56Sopenharmony_ci ENTER_PYTHON 13727db96d56Sopenharmony_ci if (i == TCL_ERROR) { 13737db96d56Sopenharmony_ci *(e->res) = Tkinter_Error(e->self); 13747db96d56Sopenharmony_ci } 13757db96d56Sopenharmony_ci else { 13767db96d56Sopenharmony_ci *(e->res) = Tkapp_ObjectResult(e->self); 13777db96d56Sopenharmony_ci } 13787db96d56Sopenharmony_ci if (*(e->res) == NULL) { 13797db96d56Sopenharmony_ci PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); 13807db96d56Sopenharmony_ci } 13817db96d56Sopenharmony_ci LEAVE_PYTHON 13827db96d56Sopenharmony_ci 13837db96d56Sopenharmony_ci Tkapp_CallDeallocArgs(objv, objStore, objc); 13847db96d56Sopenharmony_cidone: 13857db96d56Sopenharmony_ci /* Wake up calling thread. */ 13867db96d56Sopenharmony_ci Tcl_MutexLock(&call_mutex); 13877db96d56Sopenharmony_ci Tcl_ConditionNotify(e->done); 13887db96d56Sopenharmony_ci Tcl_MutexUnlock(&call_mutex); 13897db96d56Sopenharmony_ci return 1; 13907db96d56Sopenharmony_ci} 13917db96d56Sopenharmony_ci 13927db96d56Sopenharmony_ci 13937db96d56Sopenharmony_ci/* This is the main entry point for calling a Tcl command. 13947db96d56Sopenharmony_ci It supports three cases, with regard to threading: 13957db96d56Sopenharmony_ci 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in 13967db96d56Sopenharmony_ci the context of the calling thread. 13977db96d56Sopenharmony_ci 2. Tcl is threaded, caller of the command is in the interpreter thread: 13987db96d56Sopenharmony_ci Execute the command in the calling thread. Since the Tcl lock will 13997db96d56Sopenharmony_ci not be used, we can merge that with case 1. 14007db96d56Sopenharmony_ci 3. Tcl is threaded, caller is in a different thread: Must queue an event to 14017db96d56Sopenharmony_ci the interpreter thread. Allocation of Tcl objects needs to occur in the 14027db96d56Sopenharmony_ci interpreter thread, so we ship the PyObject* args to the target thread, 14037db96d56Sopenharmony_ci and perform processing there. */ 14047db96d56Sopenharmony_ci 14057db96d56Sopenharmony_cistatic PyObject * 14067db96d56Sopenharmony_ciTkapp_Call(PyObject *selfptr, PyObject *args) 14077db96d56Sopenharmony_ci{ 14087db96d56Sopenharmony_ci Tcl_Obj *objStore[ARGSZ]; 14097db96d56Sopenharmony_ci Tcl_Obj **objv = NULL; 14107db96d56Sopenharmony_ci int objc, i; 14117db96d56Sopenharmony_ci PyObject *res = NULL; 14127db96d56Sopenharmony_ci TkappObject *self = (TkappObject*)selfptr; 14137db96d56Sopenharmony_ci int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL; 14147db96d56Sopenharmony_ci 14157db96d56Sopenharmony_ci /* If args is a single tuple, replace with contents of tuple */ 14167db96d56Sopenharmony_ci if (PyTuple_GET_SIZE(args) == 1) { 14177db96d56Sopenharmony_ci PyObject *item = PyTuple_GET_ITEM(args, 0); 14187db96d56Sopenharmony_ci if (PyTuple_Check(item)) 14197db96d56Sopenharmony_ci args = item; 14207db96d56Sopenharmony_ci } 14217db96d56Sopenharmony_ci if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 14227db96d56Sopenharmony_ci /* We cannot call the command directly. Instead, we must 14237db96d56Sopenharmony_ci marshal the parameters to the interpreter thread. */ 14247db96d56Sopenharmony_ci Tkapp_CallEvent *ev; 14257db96d56Sopenharmony_ci Tcl_Condition cond = NULL; 14267db96d56Sopenharmony_ci PyObject *exc_type, *exc_value, *exc_tb; 14277db96d56Sopenharmony_ci if (!WaitForMainloop(self)) 14287db96d56Sopenharmony_ci return NULL; 14297db96d56Sopenharmony_ci ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent)); 14307db96d56Sopenharmony_ci if (ev == NULL) { 14317db96d56Sopenharmony_ci PyErr_NoMemory(); 14327db96d56Sopenharmony_ci return NULL; 14337db96d56Sopenharmony_ci } 14347db96d56Sopenharmony_ci ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; 14357db96d56Sopenharmony_ci ev->self = self; 14367db96d56Sopenharmony_ci ev->args = args; 14377db96d56Sopenharmony_ci ev->res = &res; 14387db96d56Sopenharmony_ci ev->exc_type = &exc_type; 14397db96d56Sopenharmony_ci ev->exc_value = &exc_value; 14407db96d56Sopenharmony_ci ev->exc_tb = &exc_tb; 14417db96d56Sopenharmony_ci ev->done = &cond; 14427db96d56Sopenharmony_ci 14437db96d56Sopenharmony_ci Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci if (res == NULL) { 14467db96d56Sopenharmony_ci if (exc_type) 14477db96d56Sopenharmony_ci PyErr_Restore(exc_type, exc_value, exc_tb); 14487db96d56Sopenharmony_ci else 14497db96d56Sopenharmony_ci PyErr_SetObject(Tkinter_TclError, exc_value); 14507db96d56Sopenharmony_ci } 14517db96d56Sopenharmony_ci Tcl_ConditionFinalize(&cond); 14527db96d56Sopenharmony_ci } 14537db96d56Sopenharmony_ci else 14547db96d56Sopenharmony_ci { 14557db96d56Sopenharmony_ci 14567db96d56Sopenharmony_ci objv = Tkapp_CallArgs(args, objStore, &objc); 14577db96d56Sopenharmony_ci if (!objv) 14587db96d56Sopenharmony_ci return NULL; 14597db96d56Sopenharmony_ci 14607db96d56Sopenharmony_ci ENTER_TCL 14617db96d56Sopenharmony_ci 14627db96d56Sopenharmony_ci i = Tcl_EvalObjv(self->interp, objc, objv, flags); 14637db96d56Sopenharmony_ci 14647db96d56Sopenharmony_ci ENTER_OVERLAP 14657db96d56Sopenharmony_ci 14667db96d56Sopenharmony_ci if (i == TCL_ERROR) 14677db96d56Sopenharmony_ci Tkinter_Error(self); 14687db96d56Sopenharmony_ci else 14697db96d56Sopenharmony_ci res = Tkapp_ObjectResult(self); 14707db96d56Sopenharmony_ci 14717db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 14727db96d56Sopenharmony_ci 14737db96d56Sopenharmony_ci Tkapp_CallDeallocArgs(objv, objStore, objc); 14747db96d56Sopenharmony_ci } 14757db96d56Sopenharmony_ci return res; 14767db96d56Sopenharmony_ci} 14777db96d56Sopenharmony_ci 14787db96d56Sopenharmony_ci 14797db96d56Sopenharmony_ci/*[clinic input] 14807db96d56Sopenharmony_ci_tkinter.tkapp.eval 14817db96d56Sopenharmony_ci 14827db96d56Sopenharmony_ci script: str 14837db96d56Sopenharmony_ci / 14847db96d56Sopenharmony_ci 14857db96d56Sopenharmony_ci[clinic start generated code]*/ 14867db96d56Sopenharmony_ci 14877db96d56Sopenharmony_cistatic PyObject * 14887db96d56Sopenharmony_ci_tkinter_tkapp_eval_impl(TkappObject *self, const char *script) 14897db96d56Sopenharmony_ci/*[clinic end generated code: output=24b79831f700dea0 input=481484123a455f22]*/ 14907db96d56Sopenharmony_ci{ 14917db96d56Sopenharmony_ci PyObject *res = NULL; 14927db96d56Sopenharmony_ci int err; 14937db96d56Sopenharmony_ci 14947db96d56Sopenharmony_ci CHECK_STRING_LENGTH(script); 14957db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 14967db96d56Sopenharmony_ci 14977db96d56Sopenharmony_ci ENTER_TCL 14987db96d56Sopenharmony_ci err = Tcl_Eval(Tkapp_Interp(self), script); 14997db96d56Sopenharmony_ci ENTER_OVERLAP 15007db96d56Sopenharmony_ci if (err == TCL_ERROR) 15017db96d56Sopenharmony_ci res = Tkinter_Error(self); 15027db96d56Sopenharmony_ci else 15037db96d56Sopenharmony_ci res = Tkapp_UnicodeResult(self); 15047db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 15057db96d56Sopenharmony_ci return res; 15067db96d56Sopenharmony_ci} 15077db96d56Sopenharmony_ci 15087db96d56Sopenharmony_ci/*[clinic input] 15097db96d56Sopenharmony_ci_tkinter.tkapp.evalfile 15107db96d56Sopenharmony_ci 15117db96d56Sopenharmony_ci fileName: str 15127db96d56Sopenharmony_ci / 15137db96d56Sopenharmony_ci 15147db96d56Sopenharmony_ci[clinic start generated code]*/ 15157db96d56Sopenharmony_ci 15167db96d56Sopenharmony_cistatic PyObject * 15177db96d56Sopenharmony_ci_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName) 15187db96d56Sopenharmony_ci/*[clinic end generated code: output=63be88dcee4f11d3 input=873ab707e5e947e1]*/ 15197db96d56Sopenharmony_ci{ 15207db96d56Sopenharmony_ci PyObject *res = NULL; 15217db96d56Sopenharmony_ci int err; 15227db96d56Sopenharmony_ci 15237db96d56Sopenharmony_ci CHECK_STRING_LENGTH(fileName); 15247db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 15257db96d56Sopenharmony_ci 15267db96d56Sopenharmony_ci ENTER_TCL 15277db96d56Sopenharmony_ci err = Tcl_EvalFile(Tkapp_Interp(self), fileName); 15287db96d56Sopenharmony_ci ENTER_OVERLAP 15297db96d56Sopenharmony_ci if (err == TCL_ERROR) 15307db96d56Sopenharmony_ci res = Tkinter_Error(self); 15317db96d56Sopenharmony_ci else 15327db96d56Sopenharmony_ci res = Tkapp_UnicodeResult(self); 15337db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 15347db96d56Sopenharmony_ci return res; 15357db96d56Sopenharmony_ci} 15367db96d56Sopenharmony_ci 15377db96d56Sopenharmony_ci/*[clinic input] 15387db96d56Sopenharmony_ci_tkinter.tkapp.record 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci script: str 15417db96d56Sopenharmony_ci / 15427db96d56Sopenharmony_ci 15437db96d56Sopenharmony_ci[clinic start generated code]*/ 15447db96d56Sopenharmony_ci 15457db96d56Sopenharmony_cistatic PyObject * 15467db96d56Sopenharmony_ci_tkinter_tkapp_record_impl(TkappObject *self, const char *script) 15477db96d56Sopenharmony_ci/*[clinic end generated code: output=0ffe08a0061730df input=c0b0db5a21412cac]*/ 15487db96d56Sopenharmony_ci{ 15497db96d56Sopenharmony_ci PyObject *res = NULL; 15507db96d56Sopenharmony_ci int err; 15517db96d56Sopenharmony_ci 15527db96d56Sopenharmony_ci CHECK_STRING_LENGTH(script); 15537db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 15547db96d56Sopenharmony_ci 15557db96d56Sopenharmony_ci ENTER_TCL 15567db96d56Sopenharmony_ci err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); 15577db96d56Sopenharmony_ci ENTER_OVERLAP 15587db96d56Sopenharmony_ci if (err == TCL_ERROR) 15597db96d56Sopenharmony_ci res = Tkinter_Error(self); 15607db96d56Sopenharmony_ci else 15617db96d56Sopenharmony_ci res = Tkapp_UnicodeResult(self); 15627db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 15637db96d56Sopenharmony_ci return res; 15647db96d56Sopenharmony_ci} 15657db96d56Sopenharmony_ci 15667db96d56Sopenharmony_ci/*[clinic input] 15677db96d56Sopenharmony_ci_tkinter.tkapp.adderrorinfo 15687db96d56Sopenharmony_ci 15697db96d56Sopenharmony_ci msg: str 15707db96d56Sopenharmony_ci / 15717db96d56Sopenharmony_ci 15727db96d56Sopenharmony_ci[clinic start generated code]*/ 15737db96d56Sopenharmony_ci 15747db96d56Sopenharmony_cistatic PyObject * 15757db96d56Sopenharmony_ci_tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg) 15767db96d56Sopenharmony_ci/*[clinic end generated code: output=52162eaca2ee53cb input=f4b37aec7c7e8c77]*/ 15777db96d56Sopenharmony_ci{ 15787db96d56Sopenharmony_ci CHECK_STRING_LENGTH(msg); 15797db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 15807db96d56Sopenharmony_ci 15817db96d56Sopenharmony_ci ENTER_TCL 15827db96d56Sopenharmony_ci Tcl_AddErrorInfo(Tkapp_Interp(self), msg); 15837db96d56Sopenharmony_ci LEAVE_TCL 15847db96d56Sopenharmony_ci 15857db96d56Sopenharmony_ci Py_RETURN_NONE; 15867db96d56Sopenharmony_ci} 15877db96d56Sopenharmony_ci 15887db96d56Sopenharmony_ci 15897db96d56Sopenharmony_ci 15907db96d56Sopenharmony_ci/** Tcl Variable **/ 15917db96d56Sopenharmony_ci 15927db96d56Sopenharmony_citypedef PyObject* (*EventFunc)(TkappObject *, PyObject *, int); 15937db96d56Sopenharmony_ci 15947db96d56Sopenharmony_ciTCL_DECLARE_MUTEX(var_mutex) 15957db96d56Sopenharmony_ci 15967db96d56Sopenharmony_citypedef struct VarEvent { 15977db96d56Sopenharmony_ci Tcl_Event ev; /* must be first */ 15987db96d56Sopenharmony_ci TkappObject *self; 15997db96d56Sopenharmony_ci PyObject *args; 16007db96d56Sopenharmony_ci int flags; 16017db96d56Sopenharmony_ci EventFunc func; 16027db96d56Sopenharmony_ci PyObject **res; 16037db96d56Sopenharmony_ci PyObject **exc_type; 16047db96d56Sopenharmony_ci PyObject **exc_val; 16057db96d56Sopenharmony_ci Tcl_Condition *cond; 16067db96d56Sopenharmony_ci} VarEvent; 16077db96d56Sopenharmony_ci 16087db96d56Sopenharmony_ci/*[python] 16097db96d56Sopenharmony_ci 16107db96d56Sopenharmony_ciclass varname_converter(CConverter): 16117db96d56Sopenharmony_ci type = 'const char *' 16127db96d56Sopenharmony_ci converter = 'varname_converter' 16137db96d56Sopenharmony_ci 16147db96d56Sopenharmony_ci[python]*/ 16157db96d56Sopenharmony_ci/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ 16167db96d56Sopenharmony_ci 16177db96d56Sopenharmony_cistatic int 16187db96d56Sopenharmony_civarname_converter(PyObject *in, void *_out) 16197db96d56Sopenharmony_ci{ 16207db96d56Sopenharmony_ci const char *s; 16217db96d56Sopenharmony_ci const char **out = (const char**)_out; 16227db96d56Sopenharmony_ci if (PyBytes_Check(in)) { 16237db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(in) > INT_MAX) { 16247db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); 16257db96d56Sopenharmony_ci return 0; 16267db96d56Sopenharmony_ci } 16277db96d56Sopenharmony_ci s = PyBytes_AS_STRING(in); 16287db96d56Sopenharmony_ci if (strlen(s) != (size_t)PyBytes_GET_SIZE(in)) { 16297db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "embedded null byte"); 16307db96d56Sopenharmony_ci return 0; 16317db96d56Sopenharmony_ci } 16327db96d56Sopenharmony_ci *out = s; 16337db96d56Sopenharmony_ci return 1; 16347db96d56Sopenharmony_ci } 16357db96d56Sopenharmony_ci if (PyUnicode_Check(in)) { 16367db96d56Sopenharmony_ci Py_ssize_t size; 16377db96d56Sopenharmony_ci s = PyUnicode_AsUTF8AndSize(in, &size); 16387db96d56Sopenharmony_ci if (s == NULL) { 16397db96d56Sopenharmony_ci return 0; 16407db96d56Sopenharmony_ci } 16417db96d56Sopenharmony_ci if (size > INT_MAX) { 16427db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "string is too long"); 16437db96d56Sopenharmony_ci return 0; 16447db96d56Sopenharmony_ci } 16457db96d56Sopenharmony_ci if (strlen(s) != (size_t)size) { 16467db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "embedded null character"); 16477db96d56Sopenharmony_ci return 0; 16487db96d56Sopenharmony_ci } 16497db96d56Sopenharmony_ci *out = s; 16507db96d56Sopenharmony_ci return 1; 16517db96d56Sopenharmony_ci } 16527db96d56Sopenharmony_ci if (PyTclObject_Check(in)) { 16537db96d56Sopenharmony_ci *out = Tcl_GetString(((PyTclObject *)in)->value); 16547db96d56Sopenharmony_ci return 1; 16557db96d56Sopenharmony_ci } 16567db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 16577db96d56Sopenharmony_ci "must be str, bytes or Tcl_Obj, not %.50s", 16587db96d56Sopenharmony_ci Py_TYPE(in)->tp_name); 16597db96d56Sopenharmony_ci return 0; 16607db96d56Sopenharmony_ci} 16617db96d56Sopenharmony_ci 16627db96d56Sopenharmony_ci 16637db96d56Sopenharmony_cistatic void 16647db96d56Sopenharmony_civar_perform(VarEvent *ev) 16657db96d56Sopenharmony_ci{ 16667db96d56Sopenharmony_ci *(ev->res) = ev->func(ev->self, ev->args, ev->flags); 16677db96d56Sopenharmony_ci if (!*(ev->res)) { 16687db96d56Sopenharmony_ci PyObject *exc, *val, *tb; 16697db96d56Sopenharmony_ci PyErr_Fetch(&exc, &val, &tb); 16707db96d56Sopenharmony_ci PyErr_NormalizeException(&exc, &val, &tb); 16717db96d56Sopenharmony_ci *(ev->exc_type) = exc; 16727db96d56Sopenharmony_ci *(ev->exc_val) = val; 16737db96d56Sopenharmony_ci Py_XDECREF(tb); 16747db96d56Sopenharmony_ci } 16757db96d56Sopenharmony_ci 16767db96d56Sopenharmony_ci} 16777db96d56Sopenharmony_ci 16787db96d56Sopenharmony_cistatic int 16797db96d56Sopenharmony_civar_proc(VarEvent* ev, int flags) 16807db96d56Sopenharmony_ci{ 16817db96d56Sopenharmony_ci ENTER_PYTHON 16827db96d56Sopenharmony_ci var_perform(ev); 16837db96d56Sopenharmony_ci Tcl_MutexLock(&var_mutex); 16847db96d56Sopenharmony_ci Tcl_ConditionNotify(ev->cond); 16857db96d56Sopenharmony_ci Tcl_MutexUnlock(&var_mutex); 16867db96d56Sopenharmony_ci LEAVE_PYTHON 16877db96d56Sopenharmony_ci return 1; 16887db96d56Sopenharmony_ci} 16897db96d56Sopenharmony_ci 16907db96d56Sopenharmony_ci 16917db96d56Sopenharmony_cistatic PyObject* 16927db96d56Sopenharmony_civar_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) 16937db96d56Sopenharmony_ci{ 16947db96d56Sopenharmony_ci TkappObject *self = (TkappObject*)selfptr; 16957db96d56Sopenharmony_ci if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 16967db96d56Sopenharmony_ci VarEvent *ev; 16977db96d56Sopenharmony_ci PyObject *res, *exc_type, *exc_val; 16987db96d56Sopenharmony_ci Tcl_Condition cond = NULL; 16997db96d56Sopenharmony_ci 17007db96d56Sopenharmony_ci /* The current thread is not the interpreter thread. Marshal 17017db96d56Sopenharmony_ci the call to the interpreter thread, then wait for 17027db96d56Sopenharmony_ci completion. */ 17037db96d56Sopenharmony_ci if (!WaitForMainloop(self)) 17047db96d56Sopenharmony_ci return NULL; 17057db96d56Sopenharmony_ci 17067db96d56Sopenharmony_ci ev = (VarEvent*)attemptckalloc(sizeof(VarEvent)); 17077db96d56Sopenharmony_ci if (ev == NULL) { 17087db96d56Sopenharmony_ci PyErr_NoMemory(); 17097db96d56Sopenharmony_ci return NULL; 17107db96d56Sopenharmony_ci } 17117db96d56Sopenharmony_ci ev->self = self; 17127db96d56Sopenharmony_ci ev->args = args; 17137db96d56Sopenharmony_ci ev->flags = flags; 17147db96d56Sopenharmony_ci ev->func = func; 17157db96d56Sopenharmony_ci ev->res = &res; 17167db96d56Sopenharmony_ci ev->exc_type = &exc_type; 17177db96d56Sopenharmony_ci ev->exc_val = &exc_val; 17187db96d56Sopenharmony_ci ev->cond = &cond; 17197db96d56Sopenharmony_ci ev->ev.proc = (Tcl_EventProc*)var_proc; 17207db96d56Sopenharmony_ci Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); 17217db96d56Sopenharmony_ci Tcl_ConditionFinalize(&cond); 17227db96d56Sopenharmony_ci if (!res) { 17237db96d56Sopenharmony_ci PyErr_SetObject(exc_type, exc_val); 17247db96d56Sopenharmony_ci Py_DECREF(exc_type); 17257db96d56Sopenharmony_ci Py_DECREF(exc_val); 17267db96d56Sopenharmony_ci return NULL; 17277db96d56Sopenharmony_ci } 17287db96d56Sopenharmony_ci return res; 17297db96d56Sopenharmony_ci } 17307db96d56Sopenharmony_ci /* Tcl is not threaded, or this is the interpreter thread. */ 17317db96d56Sopenharmony_ci return func(self, args, flags); 17327db96d56Sopenharmony_ci} 17337db96d56Sopenharmony_ci 17347db96d56Sopenharmony_cistatic PyObject * 17357db96d56Sopenharmony_ciSetVar(TkappObject *self, PyObject *args, int flags) 17367db96d56Sopenharmony_ci{ 17377db96d56Sopenharmony_ci const char *name1, *name2; 17387db96d56Sopenharmony_ci PyObject *newValue; 17397db96d56Sopenharmony_ci PyObject *res = NULL; 17407db96d56Sopenharmony_ci Tcl_Obj *newval, *ok; 17417db96d56Sopenharmony_ci 17427db96d56Sopenharmony_ci switch (PyTuple_GET_SIZE(args)) { 17437db96d56Sopenharmony_ci case 2: 17447db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "O&O:setvar", 17457db96d56Sopenharmony_ci varname_converter, &name1, &newValue)) 17467db96d56Sopenharmony_ci return NULL; 17477db96d56Sopenharmony_ci /* XXX Acquire tcl lock??? */ 17487db96d56Sopenharmony_ci newval = AsObj(newValue); 17497db96d56Sopenharmony_ci if (newval == NULL) 17507db96d56Sopenharmony_ci return NULL; 17517db96d56Sopenharmony_ci ENTER_TCL 17527db96d56Sopenharmony_ci ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, 17537db96d56Sopenharmony_ci newval, flags); 17547db96d56Sopenharmony_ci ENTER_OVERLAP 17557db96d56Sopenharmony_ci if (!ok) 17567db96d56Sopenharmony_ci Tkinter_Error(self); 17577db96d56Sopenharmony_ci else { 17587db96d56Sopenharmony_ci res = Py_None; 17597db96d56Sopenharmony_ci Py_INCREF(res); 17607db96d56Sopenharmony_ci } 17617db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 17627db96d56Sopenharmony_ci break; 17637db96d56Sopenharmony_ci case 3: 17647db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "ssO:setvar", 17657db96d56Sopenharmony_ci &name1, &name2, &newValue)) 17667db96d56Sopenharmony_ci return NULL; 17677db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name1); 17687db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name2); 17697db96d56Sopenharmony_ci /* XXX must hold tcl lock already??? */ 17707db96d56Sopenharmony_ci newval = AsObj(newValue); 17717db96d56Sopenharmony_ci ENTER_TCL 17727db96d56Sopenharmony_ci ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); 17737db96d56Sopenharmony_ci ENTER_OVERLAP 17747db96d56Sopenharmony_ci if (!ok) 17757db96d56Sopenharmony_ci Tkinter_Error(self); 17767db96d56Sopenharmony_ci else { 17777db96d56Sopenharmony_ci res = Py_None; 17787db96d56Sopenharmony_ci Py_INCREF(res); 17797db96d56Sopenharmony_ci } 17807db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 17817db96d56Sopenharmony_ci break; 17827db96d56Sopenharmony_ci default: 17837db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments"); 17847db96d56Sopenharmony_ci return NULL; 17857db96d56Sopenharmony_ci } 17867db96d56Sopenharmony_ci return res; 17877db96d56Sopenharmony_ci} 17887db96d56Sopenharmony_ci 17897db96d56Sopenharmony_cistatic PyObject * 17907db96d56Sopenharmony_ciTkapp_SetVar(PyObject *self, PyObject *args) 17917db96d56Sopenharmony_ci{ 17927db96d56Sopenharmony_ci return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG); 17937db96d56Sopenharmony_ci} 17947db96d56Sopenharmony_ci 17957db96d56Sopenharmony_cistatic PyObject * 17967db96d56Sopenharmony_ciTkapp_GlobalSetVar(PyObject *self, PyObject *args) 17977db96d56Sopenharmony_ci{ 17987db96d56Sopenharmony_ci return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 17997db96d56Sopenharmony_ci} 18007db96d56Sopenharmony_ci 18017db96d56Sopenharmony_ci 18027db96d56Sopenharmony_ci 18037db96d56Sopenharmony_cistatic PyObject * 18047db96d56Sopenharmony_ciGetVar(TkappObject *self, PyObject *args, int flags) 18057db96d56Sopenharmony_ci{ 18067db96d56Sopenharmony_ci const char *name1, *name2=NULL; 18077db96d56Sopenharmony_ci PyObject *res = NULL; 18087db96d56Sopenharmony_ci Tcl_Obj *tres; 18097db96d56Sopenharmony_ci 18107db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "O&|s:getvar", 18117db96d56Sopenharmony_ci varname_converter, &name1, &name2)) 18127db96d56Sopenharmony_ci return NULL; 18137db96d56Sopenharmony_ci 18147db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name2); 18157db96d56Sopenharmony_ci ENTER_TCL 18167db96d56Sopenharmony_ci tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); 18177db96d56Sopenharmony_ci ENTER_OVERLAP 18187db96d56Sopenharmony_ci if (tres == NULL) { 18197db96d56Sopenharmony_ci Tkinter_Error(self); 18207db96d56Sopenharmony_ci } else { 18217db96d56Sopenharmony_ci if (self->wantobjects) { 18227db96d56Sopenharmony_ci res = FromObj(self, tres); 18237db96d56Sopenharmony_ci } 18247db96d56Sopenharmony_ci else { 18257db96d56Sopenharmony_ci res = unicodeFromTclObj(tres); 18267db96d56Sopenharmony_ci } 18277db96d56Sopenharmony_ci } 18287db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 18297db96d56Sopenharmony_ci return res; 18307db96d56Sopenharmony_ci} 18317db96d56Sopenharmony_ci 18327db96d56Sopenharmony_cistatic PyObject * 18337db96d56Sopenharmony_ciTkapp_GetVar(PyObject *self, PyObject *args) 18347db96d56Sopenharmony_ci{ 18357db96d56Sopenharmony_ci return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG); 18367db96d56Sopenharmony_ci} 18377db96d56Sopenharmony_ci 18387db96d56Sopenharmony_cistatic PyObject * 18397db96d56Sopenharmony_ciTkapp_GlobalGetVar(PyObject *self, PyObject *args) 18407db96d56Sopenharmony_ci{ 18417db96d56Sopenharmony_ci return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 18427db96d56Sopenharmony_ci} 18437db96d56Sopenharmony_ci 18447db96d56Sopenharmony_ci 18457db96d56Sopenharmony_ci 18467db96d56Sopenharmony_cistatic PyObject * 18477db96d56Sopenharmony_ciUnsetVar(TkappObject *self, PyObject *args, int flags) 18487db96d56Sopenharmony_ci{ 18497db96d56Sopenharmony_ci char *name1, *name2=NULL; 18507db96d56Sopenharmony_ci int code; 18517db96d56Sopenharmony_ci PyObject *res = NULL; 18527db96d56Sopenharmony_ci 18537db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) 18547db96d56Sopenharmony_ci return NULL; 18557db96d56Sopenharmony_ci 18567db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name1); 18577db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name2); 18587db96d56Sopenharmony_ci ENTER_TCL 18597db96d56Sopenharmony_ci code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); 18607db96d56Sopenharmony_ci ENTER_OVERLAP 18617db96d56Sopenharmony_ci if (code == TCL_ERROR) 18627db96d56Sopenharmony_ci res = Tkinter_Error(self); 18637db96d56Sopenharmony_ci else { 18647db96d56Sopenharmony_ci Py_INCREF(Py_None); 18657db96d56Sopenharmony_ci res = Py_None; 18667db96d56Sopenharmony_ci } 18677db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 18687db96d56Sopenharmony_ci return res; 18697db96d56Sopenharmony_ci} 18707db96d56Sopenharmony_ci 18717db96d56Sopenharmony_cistatic PyObject * 18727db96d56Sopenharmony_ciTkapp_UnsetVar(PyObject *self, PyObject *args) 18737db96d56Sopenharmony_ci{ 18747db96d56Sopenharmony_ci return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG); 18757db96d56Sopenharmony_ci} 18767db96d56Sopenharmony_ci 18777db96d56Sopenharmony_cistatic PyObject * 18787db96d56Sopenharmony_ciTkapp_GlobalUnsetVar(PyObject *self, PyObject *args) 18797db96d56Sopenharmony_ci{ 18807db96d56Sopenharmony_ci return var_invoke(UnsetVar, self, args, 18817db96d56Sopenharmony_ci TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 18827db96d56Sopenharmony_ci} 18837db96d56Sopenharmony_ci 18847db96d56Sopenharmony_ci 18857db96d56Sopenharmony_ci 18867db96d56Sopenharmony_ci/** Tcl to Python **/ 18877db96d56Sopenharmony_ci 18887db96d56Sopenharmony_ci/*[clinic input] 18897db96d56Sopenharmony_ci_tkinter.tkapp.getint 18907db96d56Sopenharmony_ci 18917db96d56Sopenharmony_ci arg: object 18927db96d56Sopenharmony_ci / 18937db96d56Sopenharmony_ci 18947db96d56Sopenharmony_ci[clinic start generated code]*/ 18957db96d56Sopenharmony_ci 18967db96d56Sopenharmony_cistatic PyObject * 18977db96d56Sopenharmony_ci_tkinter_tkapp_getint(TkappObject *self, PyObject *arg) 18987db96d56Sopenharmony_ci/*[clinic end generated code: output=88cf293fae307cfe input=034026997c5b91f8]*/ 18997db96d56Sopenharmony_ci{ 19007db96d56Sopenharmony_ci char *s; 19017db96d56Sopenharmony_ci Tcl_Obj *value; 19027db96d56Sopenharmony_ci PyObject *result; 19037db96d56Sopenharmony_ci 19047db96d56Sopenharmony_ci if (PyLong_Check(arg)) { 19057db96d56Sopenharmony_ci Py_INCREF(arg); 19067db96d56Sopenharmony_ci return arg; 19077db96d56Sopenharmony_ci } 19087db96d56Sopenharmony_ci 19097db96d56Sopenharmony_ci if (PyTclObject_Check(arg)) { 19107db96d56Sopenharmony_ci value = ((PyTclObject*)arg)->value; 19117db96d56Sopenharmony_ci Tcl_IncrRefCount(value); 19127db96d56Sopenharmony_ci } 19137db96d56Sopenharmony_ci else { 19147db96d56Sopenharmony_ci if (!PyArg_Parse(arg, "s:getint", &s)) 19157db96d56Sopenharmony_ci return NULL; 19167db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 19177db96d56Sopenharmony_ci value = Tcl_NewStringObj(s, -1); 19187db96d56Sopenharmony_ci if (value == NULL) 19197db96d56Sopenharmony_ci return Tkinter_Error(self); 19207db96d56Sopenharmony_ci } 19217db96d56Sopenharmony_ci /* Don't use Tcl_GetInt() because it returns ambiguous result for value 19227db96d56Sopenharmony_ci in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). 19237db96d56Sopenharmony_ci 19247db96d56Sopenharmony_ci Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for 19257db96d56Sopenharmony_ci value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). 19267db96d56Sopenharmony_ci */ 19277db96d56Sopenharmony_ci result = fromBignumObj(self, value); 19287db96d56Sopenharmony_ci Tcl_DecrRefCount(value); 19297db96d56Sopenharmony_ci if (result != NULL || PyErr_Occurred()) 19307db96d56Sopenharmony_ci return result; 19317db96d56Sopenharmony_ci return Tkinter_Error(self); 19327db96d56Sopenharmony_ci} 19337db96d56Sopenharmony_ci 19347db96d56Sopenharmony_ci/*[clinic input] 19357db96d56Sopenharmony_ci_tkinter.tkapp.getdouble 19367db96d56Sopenharmony_ci 19377db96d56Sopenharmony_ci arg: object 19387db96d56Sopenharmony_ci / 19397db96d56Sopenharmony_ci 19407db96d56Sopenharmony_ci[clinic start generated code]*/ 19417db96d56Sopenharmony_ci 19427db96d56Sopenharmony_cistatic PyObject * 19437db96d56Sopenharmony_ci_tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) 19447db96d56Sopenharmony_ci/*[clinic end generated code: output=c52b138bd8b956b9 input=22015729ce9ef7f8]*/ 19457db96d56Sopenharmony_ci{ 19467db96d56Sopenharmony_ci char *s; 19477db96d56Sopenharmony_ci double v; 19487db96d56Sopenharmony_ci 19497db96d56Sopenharmony_ci if (PyFloat_Check(arg)) { 19507db96d56Sopenharmony_ci Py_INCREF(arg); 19517db96d56Sopenharmony_ci return arg; 19527db96d56Sopenharmony_ci } 19537db96d56Sopenharmony_ci 19547db96d56Sopenharmony_ci if (PyNumber_Check(arg)) { 19557db96d56Sopenharmony_ci return PyNumber_Float(arg); 19567db96d56Sopenharmony_ci } 19577db96d56Sopenharmony_ci 19587db96d56Sopenharmony_ci if (PyTclObject_Check(arg)) { 19597db96d56Sopenharmony_ci if (Tcl_GetDoubleFromObj(Tkapp_Interp(self), 19607db96d56Sopenharmony_ci ((PyTclObject*)arg)->value, 19617db96d56Sopenharmony_ci &v) == TCL_ERROR) 19627db96d56Sopenharmony_ci return Tkinter_Error(self); 19637db96d56Sopenharmony_ci return PyFloat_FromDouble(v); 19647db96d56Sopenharmony_ci } 19657db96d56Sopenharmony_ci 19667db96d56Sopenharmony_ci if (!PyArg_Parse(arg, "s:getdouble", &s)) 19677db96d56Sopenharmony_ci return NULL; 19687db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 19697db96d56Sopenharmony_ci if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) 19707db96d56Sopenharmony_ci return Tkinter_Error(self); 19717db96d56Sopenharmony_ci return PyFloat_FromDouble(v); 19727db96d56Sopenharmony_ci} 19737db96d56Sopenharmony_ci 19747db96d56Sopenharmony_ci/*[clinic input] 19757db96d56Sopenharmony_ci_tkinter.tkapp.getboolean 19767db96d56Sopenharmony_ci 19777db96d56Sopenharmony_ci arg: object 19787db96d56Sopenharmony_ci / 19797db96d56Sopenharmony_ci 19807db96d56Sopenharmony_ci[clinic start generated code]*/ 19817db96d56Sopenharmony_ci 19827db96d56Sopenharmony_cistatic PyObject * 19837db96d56Sopenharmony_ci_tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) 19847db96d56Sopenharmony_ci/*[clinic end generated code: output=726a9ae445821d91 input=7f11248ef8f8776e]*/ 19857db96d56Sopenharmony_ci{ 19867db96d56Sopenharmony_ci char *s; 19877db96d56Sopenharmony_ci int v; 19887db96d56Sopenharmony_ci 19897db96d56Sopenharmony_ci if (PyLong_Check(arg)) { /* int or bool */ 19907db96d56Sopenharmony_ci return PyBool_FromLong(Py_SIZE(arg) != 0); 19917db96d56Sopenharmony_ci } 19927db96d56Sopenharmony_ci 19937db96d56Sopenharmony_ci if (PyTclObject_Check(arg)) { 19947db96d56Sopenharmony_ci if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), 19957db96d56Sopenharmony_ci ((PyTclObject*)arg)->value, 19967db96d56Sopenharmony_ci &v) == TCL_ERROR) 19977db96d56Sopenharmony_ci return Tkinter_Error(self); 19987db96d56Sopenharmony_ci return PyBool_FromLong(v); 19997db96d56Sopenharmony_ci } 20007db96d56Sopenharmony_ci 20017db96d56Sopenharmony_ci if (!PyArg_Parse(arg, "s:getboolean", &s)) 20027db96d56Sopenharmony_ci return NULL; 20037db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 20047db96d56Sopenharmony_ci if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) 20057db96d56Sopenharmony_ci return Tkinter_Error(self); 20067db96d56Sopenharmony_ci return PyBool_FromLong(v); 20077db96d56Sopenharmony_ci} 20087db96d56Sopenharmony_ci 20097db96d56Sopenharmony_ci/*[clinic input] 20107db96d56Sopenharmony_ci_tkinter.tkapp.exprstring 20117db96d56Sopenharmony_ci 20127db96d56Sopenharmony_ci s: str 20137db96d56Sopenharmony_ci / 20147db96d56Sopenharmony_ci 20157db96d56Sopenharmony_ci[clinic start generated code]*/ 20167db96d56Sopenharmony_ci 20177db96d56Sopenharmony_cistatic PyObject * 20187db96d56Sopenharmony_ci_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s) 20197db96d56Sopenharmony_ci/*[clinic end generated code: output=beda323d3ed0abb1 input=fa78f751afb2f21b]*/ 20207db96d56Sopenharmony_ci{ 20217db96d56Sopenharmony_ci PyObject *res = NULL; 20227db96d56Sopenharmony_ci int retval; 20237db96d56Sopenharmony_ci 20247db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 20257db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 20267db96d56Sopenharmony_ci 20277db96d56Sopenharmony_ci ENTER_TCL 20287db96d56Sopenharmony_ci retval = Tcl_ExprString(Tkapp_Interp(self), s); 20297db96d56Sopenharmony_ci ENTER_OVERLAP 20307db96d56Sopenharmony_ci if (retval == TCL_ERROR) 20317db96d56Sopenharmony_ci res = Tkinter_Error(self); 20327db96d56Sopenharmony_ci else 20337db96d56Sopenharmony_ci res = Tkapp_UnicodeResult(self); 20347db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 20357db96d56Sopenharmony_ci return res; 20367db96d56Sopenharmony_ci} 20377db96d56Sopenharmony_ci 20387db96d56Sopenharmony_ci/*[clinic input] 20397db96d56Sopenharmony_ci_tkinter.tkapp.exprlong 20407db96d56Sopenharmony_ci 20417db96d56Sopenharmony_ci s: str 20427db96d56Sopenharmony_ci / 20437db96d56Sopenharmony_ci 20447db96d56Sopenharmony_ci[clinic start generated code]*/ 20457db96d56Sopenharmony_ci 20467db96d56Sopenharmony_cistatic PyObject * 20477db96d56Sopenharmony_ci_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s) 20487db96d56Sopenharmony_ci/*[clinic end generated code: output=5d6a46b63c6ebcf9 input=11bd7eee0c57b4dc]*/ 20497db96d56Sopenharmony_ci{ 20507db96d56Sopenharmony_ci PyObject *res = NULL; 20517db96d56Sopenharmony_ci int retval; 20527db96d56Sopenharmony_ci long v; 20537db96d56Sopenharmony_ci 20547db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 20557db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 20567db96d56Sopenharmony_ci 20577db96d56Sopenharmony_ci ENTER_TCL 20587db96d56Sopenharmony_ci retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); 20597db96d56Sopenharmony_ci ENTER_OVERLAP 20607db96d56Sopenharmony_ci if (retval == TCL_ERROR) 20617db96d56Sopenharmony_ci res = Tkinter_Error(self); 20627db96d56Sopenharmony_ci else 20637db96d56Sopenharmony_ci res = PyLong_FromLong(v); 20647db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 20657db96d56Sopenharmony_ci return res; 20667db96d56Sopenharmony_ci} 20677db96d56Sopenharmony_ci 20687db96d56Sopenharmony_ci/*[clinic input] 20697db96d56Sopenharmony_ci_tkinter.tkapp.exprdouble 20707db96d56Sopenharmony_ci 20717db96d56Sopenharmony_ci s: str 20727db96d56Sopenharmony_ci / 20737db96d56Sopenharmony_ci 20747db96d56Sopenharmony_ci[clinic start generated code]*/ 20757db96d56Sopenharmony_ci 20767db96d56Sopenharmony_cistatic PyObject * 20777db96d56Sopenharmony_ci_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) 20787db96d56Sopenharmony_ci/*[clinic end generated code: output=ff78df1081ea4158 input=ff02bc11798832d5]*/ 20797db96d56Sopenharmony_ci{ 20807db96d56Sopenharmony_ci PyObject *res = NULL; 20817db96d56Sopenharmony_ci double v; 20827db96d56Sopenharmony_ci int retval; 20837db96d56Sopenharmony_ci 20847db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 20857db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 20867db96d56Sopenharmony_ci ENTER_TCL 20877db96d56Sopenharmony_ci retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); 20887db96d56Sopenharmony_ci ENTER_OVERLAP 20897db96d56Sopenharmony_ci if (retval == TCL_ERROR) 20907db96d56Sopenharmony_ci res = Tkinter_Error(self); 20917db96d56Sopenharmony_ci else 20927db96d56Sopenharmony_ci res = PyFloat_FromDouble(v); 20937db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 20947db96d56Sopenharmony_ci return res; 20957db96d56Sopenharmony_ci} 20967db96d56Sopenharmony_ci 20977db96d56Sopenharmony_ci/*[clinic input] 20987db96d56Sopenharmony_ci_tkinter.tkapp.exprboolean 20997db96d56Sopenharmony_ci 21007db96d56Sopenharmony_ci s: str 21017db96d56Sopenharmony_ci / 21027db96d56Sopenharmony_ci 21037db96d56Sopenharmony_ci[clinic start generated code]*/ 21047db96d56Sopenharmony_ci 21057db96d56Sopenharmony_cistatic PyObject * 21067db96d56Sopenharmony_ci_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s) 21077db96d56Sopenharmony_ci/*[clinic end generated code: output=8b28038c22887311 input=c8c66022bdb8d5d3]*/ 21087db96d56Sopenharmony_ci{ 21097db96d56Sopenharmony_ci PyObject *res = NULL; 21107db96d56Sopenharmony_ci int retval; 21117db96d56Sopenharmony_ci int v; 21127db96d56Sopenharmony_ci 21137db96d56Sopenharmony_ci CHECK_STRING_LENGTH(s); 21147db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 21157db96d56Sopenharmony_ci ENTER_TCL 21167db96d56Sopenharmony_ci retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); 21177db96d56Sopenharmony_ci ENTER_OVERLAP 21187db96d56Sopenharmony_ci if (retval == TCL_ERROR) 21197db96d56Sopenharmony_ci res = Tkinter_Error(self); 21207db96d56Sopenharmony_ci else 21217db96d56Sopenharmony_ci res = PyLong_FromLong(v); 21227db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 21237db96d56Sopenharmony_ci return res; 21247db96d56Sopenharmony_ci} 21257db96d56Sopenharmony_ci 21267db96d56Sopenharmony_ci 21277db96d56Sopenharmony_ci 21287db96d56Sopenharmony_ci/*[clinic input] 21297db96d56Sopenharmony_ci_tkinter.tkapp.splitlist 21307db96d56Sopenharmony_ci 21317db96d56Sopenharmony_ci arg: object 21327db96d56Sopenharmony_ci / 21337db96d56Sopenharmony_ci 21347db96d56Sopenharmony_ci[clinic start generated code]*/ 21357db96d56Sopenharmony_ci 21367db96d56Sopenharmony_cistatic PyObject * 21377db96d56Sopenharmony_ci_tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) 21387db96d56Sopenharmony_ci/*[clinic end generated code: output=13b51d34386d36fb input=2b2e13351e3c0b53]*/ 21397db96d56Sopenharmony_ci{ 21407db96d56Sopenharmony_ci char *list; 21417db96d56Sopenharmony_ci int argc; 21427db96d56Sopenharmony_ci const char **argv; 21437db96d56Sopenharmony_ci PyObject *v; 21447db96d56Sopenharmony_ci int i; 21457db96d56Sopenharmony_ci 21467db96d56Sopenharmony_ci if (PyTclObject_Check(arg)) { 21477db96d56Sopenharmony_ci int objc; 21487db96d56Sopenharmony_ci Tcl_Obj **objv; 21497db96d56Sopenharmony_ci if (Tcl_ListObjGetElements(Tkapp_Interp(self), 21507db96d56Sopenharmony_ci ((PyTclObject*)arg)->value, 21517db96d56Sopenharmony_ci &objc, &objv) == TCL_ERROR) { 21527db96d56Sopenharmony_ci return Tkinter_Error(self); 21537db96d56Sopenharmony_ci } 21547db96d56Sopenharmony_ci if (!(v = PyTuple_New(objc))) 21557db96d56Sopenharmony_ci return NULL; 21567db96d56Sopenharmony_ci for (i = 0; i < objc; i++) { 21577db96d56Sopenharmony_ci PyObject *s = FromObj(self, objv[i]); 21587db96d56Sopenharmony_ci if (!s) { 21597db96d56Sopenharmony_ci Py_DECREF(v); 21607db96d56Sopenharmony_ci return NULL; 21617db96d56Sopenharmony_ci } 21627db96d56Sopenharmony_ci PyTuple_SET_ITEM(v, i, s); 21637db96d56Sopenharmony_ci } 21647db96d56Sopenharmony_ci return v; 21657db96d56Sopenharmony_ci } 21667db96d56Sopenharmony_ci if (PyTuple_Check(arg)) { 21677db96d56Sopenharmony_ci Py_INCREF(arg); 21687db96d56Sopenharmony_ci return arg; 21697db96d56Sopenharmony_ci } 21707db96d56Sopenharmony_ci if (PyList_Check(arg)) { 21717db96d56Sopenharmony_ci return PySequence_Tuple(arg); 21727db96d56Sopenharmony_ci } 21737db96d56Sopenharmony_ci 21747db96d56Sopenharmony_ci if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list)) 21757db96d56Sopenharmony_ci return NULL; 21767db96d56Sopenharmony_ci 21777db96d56Sopenharmony_ci if (strlen(list) >= INT_MAX) { 21787db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "string is too long"); 21797db96d56Sopenharmony_ci PyMem_Free(list); 21807db96d56Sopenharmony_ci return NULL; 21817db96d56Sopenharmony_ci } 21827db96d56Sopenharmony_ci if (Tcl_SplitList(Tkapp_Interp(self), list, 21837db96d56Sopenharmony_ci &argc, &argv) == TCL_ERROR) { 21847db96d56Sopenharmony_ci PyMem_Free(list); 21857db96d56Sopenharmony_ci return Tkinter_Error(self); 21867db96d56Sopenharmony_ci } 21877db96d56Sopenharmony_ci 21887db96d56Sopenharmony_ci if (!(v = PyTuple_New(argc))) 21897db96d56Sopenharmony_ci goto finally; 21907db96d56Sopenharmony_ci 21917db96d56Sopenharmony_ci for (i = 0; i < argc; i++) { 21927db96d56Sopenharmony_ci PyObject *s = unicodeFromTclString(argv[i]); 21937db96d56Sopenharmony_ci if (!s) { 21947db96d56Sopenharmony_ci Py_DECREF(v); 21957db96d56Sopenharmony_ci v = NULL; 21967db96d56Sopenharmony_ci goto finally; 21977db96d56Sopenharmony_ci } 21987db96d56Sopenharmony_ci PyTuple_SET_ITEM(v, i, s); 21997db96d56Sopenharmony_ci } 22007db96d56Sopenharmony_ci 22017db96d56Sopenharmony_ci finally: 22027db96d56Sopenharmony_ci ckfree(FREECAST argv); 22037db96d56Sopenharmony_ci PyMem_Free(list); 22047db96d56Sopenharmony_ci return v; 22057db96d56Sopenharmony_ci} 22067db96d56Sopenharmony_ci 22077db96d56Sopenharmony_ci 22087db96d56Sopenharmony_ci/** Tcl Command **/ 22097db96d56Sopenharmony_ci 22107db96d56Sopenharmony_ci/* Client data struct */ 22117db96d56Sopenharmony_citypedef struct { 22127db96d56Sopenharmony_ci PyObject *self; 22137db96d56Sopenharmony_ci PyObject *func; 22147db96d56Sopenharmony_ci} PythonCmd_ClientData; 22157db96d56Sopenharmony_ci 22167db96d56Sopenharmony_cistatic int 22177db96d56Sopenharmony_ciPythonCmd_Error(Tcl_Interp *interp) 22187db96d56Sopenharmony_ci{ 22197db96d56Sopenharmony_ci errorInCmd = 1; 22207db96d56Sopenharmony_ci PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 22217db96d56Sopenharmony_ci LEAVE_PYTHON 22227db96d56Sopenharmony_ci return TCL_ERROR; 22237db96d56Sopenharmony_ci} 22247db96d56Sopenharmony_ci 22257db96d56Sopenharmony_ci/* This is the Tcl command that acts as a wrapper for Python 22267db96d56Sopenharmony_ci * function or method. 22277db96d56Sopenharmony_ci */ 22287db96d56Sopenharmony_cistatic int 22297db96d56Sopenharmony_ciPythonCmd(ClientData clientData, Tcl_Interp *interp, 22307db96d56Sopenharmony_ci int objc, Tcl_Obj *const objv[]) 22317db96d56Sopenharmony_ci{ 22327db96d56Sopenharmony_ci PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; 22337db96d56Sopenharmony_ci PyObject *args, *res; 22347db96d56Sopenharmony_ci int i; 22357db96d56Sopenharmony_ci Tcl_Obj *obj_res; 22367db96d56Sopenharmony_ci 22377db96d56Sopenharmony_ci ENTER_PYTHON 22387db96d56Sopenharmony_ci 22397db96d56Sopenharmony_ci /* Create argument tuple (objv1, ..., objvN) */ 22407db96d56Sopenharmony_ci if (!(args = PyTuple_New(objc - 1))) 22417db96d56Sopenharmony_ci return PythonCmd_Error(interp); 22427db96d56Sopenharmony_ci 22437db96d56Sopenharmony_ci for (i = 0; i < (objc - 1); i++) { 22447db96d56Sopenharmony_ci PyObject *s = unicodeFromTclObj(objv[i + 1]); 22457db96d56Sopenharmony_ci if (!s) { 22467db96d56Sopenharmony_ci Py_DECREF(args); 22477db96d56Sopenharmony_ci return PythonCmd_Error(interp); 22487db96d56Sopenharmony_ci } 22497db96d56Sopenharmony_ci PyTuple_SET_ITEM(args, i, s); 22507db96d56Sopenharmony_ci } 22517db96d56Sopenharmony_ci 22527db96d56Sopenharmony_ci res = PyObject_Call(data->func, args, NULL); 22537db96d56Sopenharmony_ci Py_DECREF(args); 22547db96d56Sopenharmony_ci 22557db96d56Sopenharmony_ci if (res == NULL) 22567db96d56Sopenharmony_ci return PythonCmd_Error(interp); 22577db96d56Sopenharmony_ci 22587db96d56Sopenharmony_ci obj_res = AsObj(res); 22597db96d56Sopenharmony_ci if (obj_res == NULL) { 22607db96d56Sopenharmony_ci Py_DECREF(res); 22617db96d56Sopenharmony_ci return PythonCmd_Error(interp); 22627db96d56Sopenharmony_ci } 22637db96d56Sopenharmony_ci Tcl_SetObjResult(interp, obj_res); 22647db96d56Sopenharmony_ci Py_DECREF(res); 22657db96d56Sopenharmony_ci 22667db96d56Sopenharmony_ci LEAVE_PYTHON 22677db96d56Sopenharmony_ci 22687db96d56Sopenharmony_ci return TCL_OK; 22697db96d56Sopenharmony_ci} 22707db96d56Sopenharmony_ci 22717db96d56Sopenharmony_ci 22727db96d56Sopenharmony_cistatic void 22737db96d56Sopenharmony_ciPythonCmdDelete(ClientData clientData) 22747db96d56Sopenharmony_ci{ 22757db96d56Sopenharmony_ci PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; 22767db96d56Sopenharmony_ci 22777db96d56Sopenharmony_ci ENTER_PYTHON 22787db96d56Sopenharmony_ci Py_XDECREF(data->self); 22797db96d56Sopenharmony_ci Py_XDECREF(data->func); 22807db96d56Sopenharmony_ci PyMem_Free(data); 22817db96d56Sopenharmony_ci LEAVE_PYTHON 22827db96d56Sopenharmony_ci} 22837db96d56Sopenharmony_ci 22847db96d56Sopenharmony_ci 22857db96d56Sopenharmony_ci 22867db96d56Sopenharmony_ci 22877db96d56Sopenharmony_ciTCL_DECLARE_MUTEX(command_mutex) 22887db96d56Sopenharmony_ci 22897db96d56Sopenharmony_citypedef struct CommandEvent{ 22907db96d56Sopenharmony_ci Tcl_Event ev; 22917db96d56Sopenharmony_ci Tcl_Interp* interp; 22927db96d56Sopenharmony_ci const char *name; 22937db96d56Sopenharmony_ci int create; 22947db96d56Sopenharmony_ci int *status; 22957db96d56Sopenharmony_ci ClientData *data; 22967db96d56Sopenharmony_ci Tcl_Condition *done; 22977db96d56Sopenharmony_ci} CommandEvent; 22987db96d56Sopenharmony_ci 22997db96d56Sopenharmony_cistatic int 23007db96d56Sopenharmony_ciTkapp_CommandProc(CommandEvent *ev, int flags) 23017db96d56Sopenharmony_ci{ 23027db96d56Sopenharmony_ci if (ev->create) 23037db96d56Sopenharmony_ci *ev->status = Tcl_CreateObjCommand( 23047db96d56Sopenharmony_ci ev->interp, ev->name, PythonCmd, 23057db96d56Sopenharmony_ci ev->data, PythonCmdDelete) == NULL; 23067db96d56Sopenharmony_ci else 23077db96d56Sopenharmony_ci *ev->status = Tcl_DeleteCommand(ev->interp, ev->name); 23087db96d56Sopenharmony_ci Tcl_MutexLock(&command_mutex); 23097db96d56Sopenharmony_ci Tcl_ConditionNotify(ev->done); 23107db96d56Sopenharmony_ci Tcl_MutexUnlock(&command_mutex); 23117db96d56Sopenharmony_ci return 1; 23127db96d56Sopenharmony_ci} 23137db96d56Sopenharmony_ci 23147db96d56Sopenharmony_ci/*[clinic input] 23157db96d56Sopenharmony_ci_tkinter.tkapp.createcommand 23167db96d56Sopenharmony_ci 23177db96d56Sopenharmony_ci name: str 23187db96d56Sopenharmony_ci func: object 23197db96d56Sopenharmony_ci / 23207db96d56Sopenharmony_ci 23217db96d56Sopenharmony_ci[clinic start generated code]*/ 23227db96d56Sopenharmony_ci 23237db96d56Sopenharmony_cistatic PyObject * 23247db96d56Sopenharmony_ci_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, 23257db96d56Sopenharmony_ci PyObject *func) 23267db96d56Sopenharmony_ci/*[clinic end generated code: output=2a1c79a4ee2af410 input=255785cb70edc6a0]*/ 23277db96d56Sopenharmony_ci{ 23287db96d56Sopenharmony_ci PythonCmd_ClientData *data; 23297db96d56Sopenharmony_ci int err; 23307db96d56Sopenharmony_ci 23317db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name); 23327db96d56Sopenharmony_ci if (!PyCallable_Check(func)) { 23337db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "command not callable"); 23347db96d56Sopenharmony_ci return NULL; 23357db96d56Sopenharmony_ci } 23367db96d56Sopenharmony_ci 23377db96d56Sopenharmony_ci if (self->threaded && self->thread_id != Tcl_GetCurrentThread() && 23387db96d56Sopenharmony_ci !WaitForMainloop(self)) 23397db96d56Sopenharmony_ci return NULL; 23407db96d56Sopenharmony_ci 23417db96d56Sopenharmony_ci data = PyMem_NEW(PythonCmd_ClientData, 1); 23427db96d56Sopenharmony_ci if (!data) 23437db96d56Sopenharmony_ci return PyErr_NoMemory(); 23447db96d56Sopenharmony_ci Py_INCREF(self); 23457db96d56Sopenharmony_ci Py_INCREF(func); 23467db96d56Sopenharmony_ci data->self = (PyObject *) self; 23477db96d56Sopenharmony_ci data->func = func; 23487db96d56Sopenharmony_ci if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 23497db96d56Sopenharmony_ci Tcl_Condition cond = NULL; 23507db96d56Sopenharmony_ci CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); 23517db96d56Sopenharmony_ci if (ev == NULL) { 23527db96d56Sopenharmony_ci PyErr_NoMemory(); 23537db96d56Sopenharmony_ci PyMem_Free(data); 23547db96d56Sopenharmony_ci return NULL; 23557db96d56Sopenharmony_ci } 23567db96d56Sopenharmony_ci ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 23577db96d56Sopenharmony_ci ev->interp = self->interp; 23587db96d56Sopenharmony_ci ev->create = 1; 23597db96d56Sopenharmony_ci ev->name = name; 23607db96d56Sopenharmony_ci ev->data = (ClientData)data; 23617db96d56Sopenharmony_ci ev->status = &err; 23627db96d56Sopenharmony_ci ev->done = &cond; 23637db96d56Sopenharmony_ci Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); 23647db96d56Sopenharmony_ci Tcl_ConditionFinalize(&cond); 23657db96d56Sopenharmony_ci } 23667db96d56Sopenharmony_ci else 23677db96d56Sopenharmony_ci { 23687db96d56Sopenharmony_ci ENTER_TCL 23697db96d56Sopenharmony_ci err = Tcl_CreateObjCommand( 23707db96d56Sopenharmony_ci Tkapp_Interp(self), name, PythonCmd, 23717db96d56Sopenharmony_ci (ClientData)data, PythonCmdDelete) == NULL; 23727db96d56Sopenharmony_ci LEAVE_TCL 23737db96d56Sopenharmony_ci } 23747db96d56Sopenharmony_ci if (err) { 23757db96d56Sopenharmony_ci PyErr_SetString(Tkinter_TclError, "can't create Tcl command"); 23767db96d56Sopenharmony_ci PyMem_Free(data); 23777db96d56Sopenharmony_ci return NULL; 23787db96d56Sopenharmony_ci } 23797db96d56Sopenharmony_ci 23807db96d56Sopenharmony_ci Py_RETURN_NONE; 23817db96d56Sopenharmony_ci} 23827db96d56Sopenharmony_ci 23837db96d56Sopenharmony_ci 23847db96d56Sopenharmony_ci 23857db96d56Sopenharmony_ci/*[clinic input] 23867db96d56Sopenharmony_ci_tkinter.tkapp.deletecommand 23877db96d56Sopenharmony_ci 23887db96d56Sopenharmony_ci name: str 23897db96d56Sopenharmony_ci / 23907db96d56Sopenharmony_ci 23917db96d56Sopenharmony_ci[clinic start generated code]*/ 23927db96d56Sopenharmony_ci 23937db96d56Sopenharmony_cistatic PyObject * 23947db96d56Sopenharmony_ci_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name) 23957db96d56Sopenharmony_ci/*[clinic end generated code: output=a67e8cb5845e0d2d input=53e9952eae1f85f5]*/ 23967db96d56Sopenharmony_ci{ 23977db96d56Sopenharmony_ci int err; 23987db96d56Sopenharmony_ci 23997db96d56Sopenharmony_ci CHECK_STRING_LENGTH(name); 24007db96d56Sopenharmony_ci 24017db96d56Sopenharmony_ci if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 24027db96d56Sopenharmony_ci Tcl_Condition cond = NULL; 24037db96d56Sopenharmony_ci CommandEvent *ev; 24047db96d56Sopenharmony_ci ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); 24057db96d56Sopenharmony_ci if (ev == NULL) { 24067db96d56Sopenharmony_ci PyErr_NoMemory(); 24077db96d56Sopenharmony_ci return NULL; 24087db96d56Sopenharmony_ci } 24097db96d56Sopenharmony_ci ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 24107db96d56Sopenharmony_ci ev->interp = self->interp; 24117db96d56Sopenharmony_ci ev->create = 0; 24127db96d56Sopenharmony_ci ev->name = name; 24137db96d56Sopenharmony_ci ev->status = &err; 24147db96d56Sopenharmony_ci ev->done = &cond; 24157db96d56Sopenharmony_ci Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, 24167db96d56Sopenharmony_ci &command_mutex); 24177db96d56Sopenharmony_ci Tcl_ConditionFinalize(&cond); 24187db96d56Sopenharmony_ci } 24197db96d56Sopenharmony_ci else 24207db96d56Sopenharmony_ci { 24217db96d56Sopenharmony_ci ENTER_TCL 24227db96d56Sopenharmony_ci err = Tcl_DeleteCommand(self->interp, name); 24237db96d56Sopenharmony_ci LEAVE_TCL 24247db96d56Sopenharmony_ci } 24257db96d56Sopenharmony_ci if (err == -1) { 24267db96d56Sopenharmony_ci PyErr_SetString(Tkinter_TclError, "can't delete Tcl command"); 24277db96d56Sopenharmony_ci return NULL; 24287db96d56Sopenharmony_ci } 24297db96d56Sopenharmony_ci Py_RETURN_NONE; 24307db96d56Sopenharmony_ci} 24317db96d56Sopenharmony_ci 24327db96d56Sopenharmony_ci 24337db96d56Sopenharmony_ci 24347db96d56Sopenharmony_ci#ifdef HAVE_CREATEFILEHANDLER 24357db96d56Sopenharmony_ci/** File Handler **/ 24367db96d56Sopenharmony_ci 24377db96d56Sopenharmony_citypedef struct _fhcdata { 24387db96d56Sopenharmony_ci PyObject *func; 24397db96d56Sopenharmony_ci PyObject *file; 24407db96d56Sopenharmony_ci int id; 24417db96d56Sopenharmony_ci struct _fhcdata *next; 24427db96d56Sopenharmony_ci} FileHandler_ClientData; 24437db96d56Sopenharmony_ci 24447db96d56Sopenharmony_cistatic FileHandler_ClientData *HeadFHCD; 24457db96d56Sopenharmony_ci 24467db96d56Sopenharmony_cistatic FileHandler_ClientData * 24477db96d56Sopenharmony_ciNewFHCD(PyObject *func, PyObject *file, int id) 24487db96d56Sopenharmony_ci{ 24497db96d56Sopenharmony_ci FileHandler_ClientData *p; 24507db96d56Sopenharmony_ci p = PyMem_NEW(FileHandler_ClientData, 1); 24517db96d56Sopenharmony_ci if (p != NULL) { 24527db96d56Sopenharmony_ci Py_XINCREF(func); 24537db96d56Sopenharmony_ci Py_XINCREF(file); 24547db96d56Sopenharmony_ci p->func = func; 24557db96d56Sopenharmony_ci p->file = file; 24567db96d56Sopenharmony_ci p->id = id; 24577db96d56Sopenharmony_ci p->next = HeadFHCD; 24587db96d56Sopenharmony_ci HeadFHCD = p; 24597db96d56Sopenharmony_ci } 24607db96d56Sopenharmony_ci return p; 24617db96d56Sopenharmony_ci} 24627db96d56Sopenharmony_ci 24637db96d56Sopenharmony_cistatic void 24647db96d56Sopenharmony_ciDeleteFHCD(int id) 24657db96d56Sopenharmony_ci{ 24667db96d56Sopenharmony_ci FileHandler_ClientData *p, **pp; 24677db96d56Sopenharmony_ci 24687db96d56Sopenharmony_ci pp = &HeadFHCD; 24697db96d56Sopenharmony_ci while ((p = *pp) != NULL) { 24707db96d56Sopenharmony_ci if (p->id == id) { 24717db96d56Sopenharmony_ci *pp = p->next; 24727db96d56Sopenharmony_ci Py_XDECREF(p->func); 24737db96d56Sopenharmony_ci Py_XDECREF(p->file); 24747db96d56Sopenharmony_ci PyMem_Free(p); 24757db96d56Sopenharmony_ci } 24767db96d56Sopenharmony_ci else 24777db96d56Sopenharmony_ci pp = &p->next; 24787db96d56Sopenharmony_ci } 24797db96d56Sopenharmony_ci} 24807db96d56Sopenharmony_ci 24817db96d56Sopenharmony_cistatic void 24827db96d56Sopenharmony_ciFileHandler(ClientData clientData, int mask) 24837db96d56Sopenharmony_ci{ 24847db96d56Sopenharmony_ci FileHandler_ClientData *data = (FileHandler_ClientData *)clientData; 24857db96d56Sopenharmony_ci PyObject *func, *file, *res; 24867db96d56Sopenharmony_ci 24877db96d56Sopenharmony_ci ENTER_PYTHON 24887db96d56Sopenharmony_ci func = data->func; 24897db96d56Sopenharmony_ci file = data->file; 24907db96d56Sopenharmony_ci 24917db96d56Sopenharmony_ci res = PyObject_CallFunction(func, "Oi", file, mask); 24927db96d56Sopenharmony_ci if (res == NULL) { 24937db96d56Sopenharmony_ci errorInCmd = 1; 24947db96d56Sopenharmony_ci PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 24957db96d56Sopenharmony_ci } 24967db96d56Sopenharmony_ci Py_XDECREF(res); 24977db96d56Sopenharmony_ci LEAVE_PYTHON 24987db96d56Sopenharmony_ci} 24997db96d56Sopenharmony_ci 25007db96d56Sopenharmony_ci/*[clinic input] 25017db96d56Sopenharmony_ci_tkinter.tkapp.createfilehandler 25027db96d56Sopenharmony_ci 25037db96d56Sopenharmony_ci file: object 25047db96d56Sopenharmony_ci mask: int 25057db96d56Sopenharmony_ci func: object 25067db96d56Sopenharmony_ci / 25077db96d56Sopenharmony_ci 25087db96d56Sopenharmony_ci[clinic start generated code]*/ 25097db96d56Sopenharmony_ci 25107db96d56Sopenharmony_cistatic PyObject * 25117db96d56Sopenharmony_ci_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, 25127db96d56Sopenharmony_ci int mask, PyObject *func) 25137db96d56Sopenharmony_ci/*[clinic end generated code: output=f73ce82de801c353 input=84943a5286e47947]*/ 25147db96d56Sopenharmony_ci{ 25157db96d56Sopenharmony_ci FileHandler_ClientData *data; 25167db96d56Sopenharmony_ci int tfile; 25177db96d56Sopenharmony_ci 25187db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 25197db96d56Sopenharmony_ci 25207db96d56Sopenharmony_ci tfile = PyObject_AsFileDescriptor(file); 25217db96d56Sopenharmony_ci if (tfile < 0) 25227db96d56Sopenharmony_ci return NULL; 25237db96d56Sopenharmony_ci if (!PyCallable_Check(func)) { 25247db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "bad argument list"); 25257db96d56Sopenharmony_ci return NULL; 25267db96d56Sopenharmony_ci } 25277db96d56Sopenharmony_ci 25287db96d56Sopenharmony_ci data = NewFHCD(func, file, tfile); 25297db96d56Sopenharmony_ci if (data == NULL) 25307db96d56Sopenharmony_ci return NULL; 25317db96d56Sopenharmony_ci 25327db96d56Sopenharmony_ci /* Ought to check for null Tcl_File object... */ 25337db96d56Sopenharmony_ci ENTER_TCL 25347db96d56Sopenharmony_ci Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data); 25357db96d56Sopenharmony_ci LEAVE_TCL 25367db96d56Sopenharmony_ci Py_RETURN_NONE; 25377db96d56Sopenharmony_ci} 25387db96d56Sopenharmony_ci 25397db96d56Sopenharmony_ci/*[clinic input] 25407db96d56Sopenharmony_ci_tkinter.tkapp.deletefilehandler 25417db96d56Sopenharmony_ci 25427db96d56Sopenharmony_ci file: object 25437db96d56Sopenharmony_ci / 25447db96d56Sopenharmony_ci 25457db96d56Sopenharmony_ci[clinic start generated code]*/ 25467db96d56Sopenharmony_ci 25477db96d56Sopenharmony_cistatic PyObject * 25487db96d56Sopenharmony_ci_tkinter_tkapp_deletefilehandler(TkappObject *self, PyObject *file) 25497db96d56Sopenharmony_ci/*[clinic end generated code: output=b53cc96ebf9476fd input=abbec19d66312e2a]*/ 25507db96d56Sopenharmony_ci{ 25517db96d56Sopenharmony_ci int tfile; 25527db96d56Sopenharmony_ci 25537db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 25547db96d56Sopenharmony_ci 25557db96d56Sopenharmony_ci tfile = PyObject_AsFileDescriptor(file); 25567db96d56Sopenharmony_ci if (tfile < 0) 25577db96d56Sopenharmony_ci return NULL; 25587db96d56Sopenharmony_ci 25597db96d56Sopenharmony_ci DeleteFHCD(tfile); 25607db96d56Sopenharmony_ci 25617db96d56Sopenharmony_ci /* Ought to check for null Tcl_File object... */ 25627db96d56Sopenharmony_ci ENTER_TCL 25637db96d56Sopenharmony_ci Tcl_DeleteFileHandler(tfile); 25647db96d56Sopenharmony_ci LEAVE_TCL 25657db96d56Sopenharmony_ci Py_RETURN_NONE; 25667db96d56Sopenharmony_ci} 25677db96d56Sopenharmony_ci#endif /* HAVE_CREATEFILEHANDLER */ 25687db96d56Sopenharmony_ci 25697db96d56Sopenharmony_ci 25707db96d56Sopenharmony_ci/**** Tktt Object (timer token) ****/ 25717db96d56Sopenharmony_ci 25727db96d56Sopenharmony_cistatic PyObject *Tktt_Type; 25737db96d56Sopenharmony_ci 25747db96d56Sopenharmony_citypedef struct { 25757db96d56Sopenharmony_ci PyObject_HEAD 25767db96d56Sopenharmony_ci Tcl_TimerToken token; 25777db96d56Sopenharmony_ci PyObject *func; 25787db96d56Sopenharmony_ci} TkttObject; 25797db96d56Sopenharmony_ci 25807db96d56Sopenharmony_ci/*[clinic input] 25817db96d56Sopenharmony_ci_tkinter.tktimertoken.deletetimerhandler 25827db96d56Sopenharmony_ci 25837db96d56Sopenharmony_ci[clinic start generated code]*/ 25847db96d56Sopenharmony_ci 25857db96d56Sopenharmony_cistatic PyObject * 25867db96d56Sopenharmony_ci_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self) 25877db96d56Sopenharmony_ci/*[clinic end generated code: output=bd7fe17f328cfa55 input=40bd070ff85f5cf3]*/ 25887db96d56Sopenharmony_ci{ 25897db96d56Sopenharmony_ci TkttObject *v = self; 25907db96d56Sopenharmony_ci PyObject *func = v->func; 25917db96d56Sopenharmony_ci 25927db96d56Sopenharmony_ci if (v->token != NULL) { 25937db96d56Sopenharmony_ci Tcl_DeleteTimerHandler(v->token); 25947db96d56Sopenharmony_ci v->token = NULL; 25957db96d56Sopenharmony_ci } 25967db96d56Sopenharmony_ci if (func != NULL) { 25977db96d56Sopenharmony_ci v->func = NULL; 25987db96d56Sopenharmony_ci Py_DECREF(func); 25997db96d56Sopenharmony_ci Py_DECREF(v); /* See Tktt_New() */ 26007db96d56Sopenharmony_ci } 26017db96d56Sopenharmony_ci Py_RETURN_NONE; 26027db96d56Sopenharmony_ci} 26037db96d56Sopenharmony_ci 26047db96d56Sopenharmony_cistatic TkttObject * 26057db96d56Sopenharmony_ciTktt_New(PyObject *func) 26067db96d56Sopenharmony_ci{ 26077db96d56Sopenharmony_ci TkttObject *v; 26087db96d56Sopenharmony_ci 26097db96d56Sopenharmony_ci v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); 26107db96d56Sopenharmony_ci if (v == NULL) 26117db96d56Sopenharmony_ci return NULL; 26127db96d56Sopenharmony_ci 26137db96d56Sopenharmony_ci Py_INCREF(func); 26147db96d56Sopenharmony_ci v->token = NULL; 26157db96d56Sopenharmony_ci v->func = func; 26167db96d56Sopenharmony_ci 26177db96d56Sopenharmony_ci /* Extra reference, deleted when called or when handler is deleted */ 26187db96d56Sopenharmony_ci Py_INCREF(v); 26197db96d56Sopenharmony_ci return v; 26207db96d56Sopenharmony_ci} 26217db96d56Sopenharmony_ci 26227db96d56Sopenharmony_cistatic void 26237db96d56Sopenharmony_ciTktt_Dealloc(PyObject *self) 26247db96d56Sopenharmony_ci{ 26257db96d56Sopenharmony_ci TkttObject *v = (TkttObject *)self; 26267db96d56Sopenharmony_ci PyObject *func = v->func; 26277db96d56Sopenharmony_ci PyObject *tp = (PyObject *) Py_TYPE(self); 26287db96d56Sopenharmony_ci 26297db96d56Sopenharmony_ci Py_XDECREF(func); 26307db96d56Sopenharmony_ci 26317db96d56Sopenharmony_ci PyObject_Free(self); 26327db96d56Sopenharmony_ci Py_DECREF(tp); 26337db96d56Sopenharmony_ci} 26347db96d56Sopenharmony_ci 26357db96d56Sopenharmony_cistatic PyObject * 26367db96d56Sopenharmony_ciTktt_Repr(PyObject *self) 26377db96d56Sopenharmony_ci{ 26387db96d56Sopenharmony_ci TkttObject *v = (TkttObject *)self; 26397db96d56Sopenharmony_ci return PyUnicode_FromFormat("<tktimertoken at %p%s>", 26407db96d56Sopenharmony_ci v, 26417db96d56Sopenharmony_ci v->func == NULL ? ", handler deleted" : ""); 26427db96d56Sopenharmony_ci} 26437db96d56Sopenharmony_ci 26447db96d56Sopenharmony_ci/** Timer Handler **/ 26457db96d56Sopenharmony_ci 26467db96d56Sopenharmony_cistatic void 26477db96d56Sopenharmony_ciTimerHandler(ClientData clientData) 26487db96d56Sopenharmony_ci{ 26497db96d56Sopenharmony_ci TkttObject *v = (TkttObject *)clientData; 26507db96d56Sopenharmony_ci PyObject *func = v->func; 26517db96d56Sopenharmony_ci PyObject *res; 26527db96d56Sopenharmony_ci 26537db96d56Sopenharmony_ci if (func == NULL) 26547db96d56Sopenharmony_ci return; 26557db96d56Sopenharmony_ci 26567db96d56Sopenharmony_ci v->func = NULL; 26577db96d56Sopenharmony_ci 26587db96d56Sopenharmony_ci ENTER_PYTHON 26597db96d56Sopenharmony_ci 26607db96d56Sopenharmony_ci res = PyObject_CallNoArgs(func); 26617db96d56Sopenharmony_ci Py_DECREF(func); 26627db96d56Sopenharmony_ci Py_DECREF(v); /* See Tktt_New() */ 26637db96d56Sopenharmony_ci 26647db96d56Sopenharmony_ci if (res == NULL) { 26657db96d56Sopenharmony_ci errorInCmd = 1; 26667db96d56Sopenharmony_ci PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); 26677db96d56Sopenharmony_ci } 26687db96d56Sopenharmony_ci else 26697db96d56Sopenharmony_ci Py_DECREF(res); 26707db96d56Sopenharmony_ci 26717db96d56Sopenharmony_ci LEAVE_PYTHON 26727db96d56Sopenharmony_ci} 26737db96d56Sopenharmony_ci 26747db96d56Sopenharmony_ci/*[clinic input] 26757db96d56Sopenharmony_ci_tkinter.tkapp.createtimerhandler 26767db96d56Sopenharmony_ci 26777db96d56Sopenharmony_ci milliseconds: int 26787db96d56Sopenharmony_ci func: object 26797db96d56Sopenharmony_ci / 26807db96d56Sopenharmony_ci 26817db96d56Sopenharmony_ci[clinic start generated code]*/ 26827db96d56Sopenharmony_ci 26837db96d56Sopenharmony_cistatic PyObject * 26847db96d56Sopenharmony_ci_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, 26857db96d56Sopenharmony_ci PyObject *func) 26867db96d56Sopenharmony_ci/*[clinic end generated code: output=2da5959b9d031911 input=ba6729f32f0277a5]*/ 26877db96d56Sopenharmony_ci{ 26887db96d56Sopenharmony_ci TkttObject *v; 26897db96d56Sopenharmony_ci 26907db96d56Sopenharmony_ci if (!PyCallable_Check(func)) { 26917db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "bad argument list"); 26927db96d56Sopenharmony_ci return NULL; 26937db96d56Sopenharmony_ci } 26947db96d56Sopenharmony_ci 26957db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 26967db96d56Sopenharmony_ci 26977db96d56Sopenharmony_ci v = Tktt_New(func); 26987db96d56Sopenharmony_ci if (v) { 26997db96d56Sopenharmony_ci v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, 27007db96d56Sopenharmony_ci (ClientData)v); 27017db96d56Sopenharmony_ci } 27027db96d56Sopenharmony_ci 27037db96d56Sopenharmony_ci return (PyObject *) v; 27047db96d56Sopenharmony_ci} 27057db96d56Sopenharmony_ci 27067db96d56Sopenharmony_ci 27077db96d56Sopenharmony_ci/** Event Loop **/ 27087db96d56Sopenharmony_ci 27097db96d56Sopenharmony_ci/*[clinic input] 27107db96d56Sopenharmony_ci_tkinter.tkapp.mainloop 27117db96d56Sopenharmony_ci 27127db96d56Sopenharmony_ci threshold: int = 0 27137db96d56Sopenharmony_ci / 27147db96d56Sopenharmony_ci 27157db96d56Sopenharmony_ci[clinic start generated code]*/ 27167db96d56Sopenharmony_ci 27177db96d56Sopenharmony_cistatic PyObject * 27187db96d56Sopenharmony_ci_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold) 27197db96d56Sopenharmony_ci/*[clinic end generated code: output=0ba8eabbe57841b0 input=036bcdcf03d5eca0]*/ 27207db96d56Sopenharmony_ci{ 27217db96d56Sopenharmony_ci PyThreadState *tstate = PyThreadState_Get(); 27227db96d56Sopenharmony_ci 27237db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 27247db96d56Sopenharmony_ci self->dispatching = 1; 27257db96d56Sopenharmony_ci 27267db96d56Sopenharmony_ci quitMainLoop = 0; 27277db96d56Sopenharmony_ci while (Tk_GetNumMainWindows() > threshold && 27287db96d56Sopenharmony_ci !quitMainLoop && 27297db96d56Sopenharmony_ci !errorInCmd) 27307db96d56Sopenharmony_ci { 27317db96d56Sopenharmony_ci int result; 27327db96d56Sopenharmony_ci 27337db96d56Sopenharmony_ci if (self->threaded) { 27347db96d56Sopenharmony_ci /* Allow other Python threads to run. */ 27357db96d56Sopenharmony_ci ENTER_TCL 27367db96d56Sopenharmony_ci result = Tcl_DoOneEvent(0); 27377db96d56Sopenharmony_ci LEAVE_TCL 27387db96d56Sopenharmony_ci } 27397db96d56Sopenharmony_ci else { 27407db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 27417db96d56Sopenharmony_ci if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); 27427db96d56Sopenharmony_ci tcl_tstate = tstate; 27437db96d56Sopenharmony_ci result = Tcl_DoOneEvent(TCL_DONT_WAIT); 27447db96d56Sopenharmony_ci tcl_tstate = NULL; 27457db96d56Sopenharmony_ci if(tcl_lock)PyThread_release_lock(tcl_lock); 27467db96d56Sopenharmony_ci if (result == 0) 27477db96d56Sopenharmony_ci Sleep(Tkinter_busywaitinterval); 27487db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 27497db96d56Sopenharmony_ci } 27507db96d56Sopenharmony_ci 27517db96d56Sopenharmony_ci if (PyErr_CheckSignals() != 0) { 27527db96d56Sopenharmony_ci self->dispatching = 0; 27537db96d56Sopenharmony_ci return NULL; 27547db96d56Sopenharmony_ci } 27557db96d56Sopenharmony_ci if (result < 0) 27567db96d56Sopenharmony_ci break; 27577db96d56Sopenharmony_ci } 27587db96d56Sopenharmony_ci self->dispatching = 0; 27597db96d56Sopenharmony_ci quitMainLoop = 0; 27607db96d56Sopenharmony_ci 27617db96d56Sopenharmony_ci if (errorInCmd) { 27627db96d56Sopenharmony_ci errorInCmd = 0; 27637db96d56Sopenharmony_ci PyErr_Restore(excInCmd, valInCmd, trbInCmd); 27647db96d56Sopenharmony_ci excInCmd = valInCmd = trbInCmd = NULL; 27657db96d56Sopenharmony_ci return NULL; 27667db96d56Sopenharmony_ci } 27677db96d56Sopenharmony_ci Py_RETURN_NONE; 27687db96d56Sopenharmony_ci} 27697db96d56Sopenharmony_ci 27707db96d56Sopenharmony_ci/*[clinic input] 27717db96d56Sopenharmony_ci_tkinter.tkapp.dooneevent 27727db96d56Sopenharmony_ci 27737db96d56Sopenharmony_ci flags: int = 0 27747db96d56Sopenharmony_ci / 27757db96d56Sopenharmony_ci 27767db96d56Sopenharmony_ci[clinic start generated code]*/ 27777db96d56Sopenharmony_ci 27787db96d56Sopenharmony_cistatic PyObject * 27797db96d56Sopenharmony_ci_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags) 27807db96d56Sopenharmony_ci/*[clinic end generated code: output=27c6b2aa464cac29 input=6542b928e364b793]*/ 27817db96d56Sopenharmony_ci{ 27827db96d56Sopenharmony_ci int rv; 27837db96d56Sopenharmony_ci 27847db96d56Sopenharmony_ci ENTER_TCL 27857db96d56Sopenharmony_ci rv = Tcl_DoOneEvent(flags); 27867db96d56Sopenharmony_ci LEAVE_TCL 27877db96d56Sopenharmony_ci return PyLong_FromLong(rv); 27887db96d56Sopenharmony_ci} 27897db96d56Sopenharmony_ci 27907db96d56Sopenharmony_ci/*[clinic input] 27917db96d56Sopenharmony_ci_tkinter.tkapp.quit 27927db96d56Sopenharmony_ci[clinic start generated code]*/ 27937db96d56Sopenharmony_ci 27947db96d56Sopenharmony_cistatic PyObject * 27957db96d56Sopenharmony_ci_tkinter_tkapp_quit_impl(TkappObject *self) 27967db96d56Sopenharmony_ci/*[clinic end generated code: output=7f21eeff481f754f input=e03020dc38aff23c]*/ 27977db96d56Sopenharmony_ci{ 27987db96d56Sopenharmony_ci quitMainLoop = 1; 27997db96d56Sopenharmony_ci Py_RETURN_NONE; 28007db96d56Sopenharmony_ci} 28017db96d56Sopenharmony_ci 28027db96d56Sopenharmony_ci/*[clinic input] 28037db96d56Sopenharmony_ci_tkinter.tkapp.interpaddr 28047db96d56Sopenharmony_ci[clinic start generated code]*/ 28057db96d56Sopenharmony_ci 28067db96d56Sopenharmony_cistatic PyObject * 28077db96d56Sopenharmony_ci_tkinter_tkapp_interpaddr_impl(TkappObject *self) 28087db96d56Sopenharmony_ci/*[clinic end generated code: output=6caaae3273b3c95a input=2dd32cbddb55a111]*/ 28097db96d56Sopenharmony_ci{ 28107db96d56Sopenharmony_ci return PyLong_FromVoidPtr(Tkapp_Interp(self)); 28117db96d56Sopenharmony_ci} 28127db96d56Sopenharmony_ci 28137db96d56Sopenharmony_ci/*[clinic input] 28147db96d56Sopenharmony_ci_tkinter.tkapp.loadtk 28157db96d56Sopenharmony_ci[clinic start generated code]*/ 28167db96d56Sopenharmony_ci 28177db96d56Sopenharmony_cistatic PyObject * 28187db96d56Sopenharmony_ci_tkinter_tkapp_loadtk_impl(TkappObject *self) 28197db96d56Sopenharmony_ci/*[clinic end generated code: output=e9e10a954ce46d2a input=b5e82afedd6354f0]*/ 28207db96d56Sopenharmony_ci{ 28217db96d56Sopenharmony_ci Tcl_Interp *interp = Tkapp_Interp(self); 28227db96d56Sopenharmony_ci const char * _tk_exists = NULL; 28237db96d56Sopenharmony_ci int err; 28247db96d56Sopenharmony_ci 28257db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 28267db96d56Sopenharmony_ci /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the 28277db96d56Sopenharmony_ci * first call failed. 28287db96d56Sopenharmony_ci * To avoid the deadlock, we just refuse the second call through 28297db96d56Sopenharmony_ci * a static variable. 28307db96d56Sopenharmony_ci */ 28317db96d56Sopenharmony_ci if (tk_load_failed) { 28327db96d56Sopenharmony_ci PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG); 28337db96d56Sopenharmony_ci return NULL; 28347db96d56Sopenharmony_ci } 28357db96d56Sopenharmony_ci#endif 28367db96d56Sopenharmony_ci 28377db96d56Sopenharmony_ci /* We want to guard against calling Tk_Init() multiple times */ 28387db96d56Sopenharmony_ci CHECK_TCL_APPARTMENT; 28397db96d56Sopenharmony_ci ENTER_TCL 28407db96d56Sopenharmony_ci err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version"); 28417db96d56Sopenharmony_ci ENTER_OVERLAP 28427db96d56Sopenharmony_ci if (err == TCL_ERROR) { 28437db96d56Sopenharmony_ci /* This sets an exception, but we cannot return right 28447db96d56Sopenharmony_ci away because we need to exit the overlap first. */ 28457db96d56Sopenharmony_ci Tkinter_Error(self); 28467db96d56Sopenharmony_ci } else { 28477db96d56Sopenharmony_ci _tk_exists = Tcl_GetStringResult(Tkapp_Interp(self)); 28487db96d56Sopenharmony_ci } 28497db96d56Sopenharmony_ci LEAVE_OVERLAP_TCL 28507db96d56Sopenharmony_ci if (err == TCL_ERROR) { 28517db96d56Sopenharmony_ci return NULL; 28527db96d56Sopenharmony_ci } 28537db96d56Sopenharmony_ci if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { 28547db96d56Sopenharmony_ci if (Tk_Init(interp) == TCL_ERROR) { 28557db96d56Sopenharmony_ci Tkinter_Error(self); 28567db96d56Sopenharmony_ci#ifdef TKINTER_PROTECT_LOADTK 28577db96d56Sopenharmony_ci tk_load_failed = 1; 28587db96d56Sopenharmony_ci#endif 28597db96d56Sopenharmony_ci return NULL; 28607db96d56Sopenharmony_ci } 28617db96d56Sopenharmony_ci } 28627db96d56Sopenharmony_ci Py_RETURN_NONE; 28637db96d56Sopenharmony_ci} 28647db96d56Sopenharmony_ci 28657db96d56Sopenharmony_cistatic PyObject * 28667db96d56Sopenharmony_ciTkapp_WantObjects(PyObject *self, PyObject *args) 28677db96d56Sopenharmony_ci{ 28687db96d56Sopenharmony_ci 28697db96d56Sopenharmony_ci int wantobjects = -1; 28707db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) 28717db96d56Sopenharmony_ci return NULL; 28727db96d56Sopenharmony_ci if (wantobjects == -1) 28737db96d56Sopenharmony_ci return PyBool_FromLong(((TkappObject*)self)->wantobjects); 28747db96d56Sopenharmony_ci ((TkappObject*)self)->wantobjects = wantobjects; 28757db96d56Sopenharmony_ci 28767db96d56Sopenharmony_ci Py_RETURN_NONE; 28777db96d56Sopenharmony_ci} 28787db96d56Sopenharmony_ci 28797db96d56Sopenharmony_ci/*[clinic input] 28807db96d56Sopenharmony_ci_tkinter.tkapp.willdispatch 28817db96d56Sopenharmony_ci 28827db96d56Sopenharmony_ci[clinic start generated code]*/ 28837db96d56Sopenharmony_ci 28847db96d56Sopenharmony_cistatic PyObject * 28857db96d56Sopenharmony_ci_tkinter_tkapp_willdispatch_impl(TkappObject *self) 28867db96d56Sopenharmony_ci/*[clinic end generated code: output=0e3f46d244642155 input=d88f5970843d6dab]*/ 28877db96d56Sopenharmony_ci{ 28887db96d56Sopenharmony_ci self->dispatching = 1; 28897db96d56Sopenharmony_ci 28907db96d56Sopenharmony_ci Py_RETURN_NONE; 28917db96d56Sopenharmony_ci} 28927db96d56Sopenharmony_ci 28937db96d56Sopenharmony_ci 28947db96d56Sopenharmony_ci/**** Tkapp Type Methods ****/ 28957db96d56Sopenharmony_ci 28967db96d56Sopenharmony_cistatic void 28977db96d56Sopenharmony_ciTkapp_Dealloc(PyObject *self) 28987db96d56Sopenharmony_ci{ 28997db96d56Sopenharmony_ci PyObject *tp = (PyObject *) Py_TYPE(self); 29007db96d56Sopenharmony_ci /*CHECK_TCL_APPARTMENT;*/ 29017db96d56Sopenharmony_ci ENTER_TCL 29027db96d56Sopenharmony_ci Tcl_DeleteInterp(Tkapp_Interp(self)); 29037db96d56Sopenharmony_ci LEAVE_TCL 29047db96d56Sopenharmony_ci PyObject_Free(self); 29057db96d56Sopenharmony_ci Py_DECREF(tp); 29067db96d56Sopenharmony_ci DisableEventHook(); 29077db96d56Sopenharmony_ci} 29087db96d56Sopenharmony_ci 29097db96d56Sopenharmony_ci 29107db96d56Sopenharmony_ci 29117db96d56Sopenharmony_ci/**** Tkinter Module ****/ 29127db96d56Sopenharmony_ci 29137db96d56Sopenharmony_citypedef struct { 29147db96d56Sopenharmony_ci PyObject* tuple; 29157db96d56Sopenharmony_ci Py_ssize_t size; /* current size */ 29167db96d56Sopenharmony_ci Py_ssize_t maxsize; /* allocated size */ 29177db96d56Sopenharmony_ci} FlattenContext; 29187db96d56Sopenharmony_ci 29197db96d56Sopenharmony_cistatic int 29207db96d56Sopenharmony_ci_bump(FlattenContext* context, Py_ssize_t size) 29217db96d56Sopenharmony_ci{ 29227db96d56Sopenharmony_ci /* expand tuple to hold (at least) size new items. 29237db96d56Sopenharmony_ci return true if successful, false if an exception was raised */ 29247db96d56Sopenharmony_ci 29257db96d56Sopenharmony_ci Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */ 29267db96d56Sopenharmony_ci 29277db96d56Sopenharmony_ci if (maxsize < context->size + size) 29287db96d56Sopenharmony_ci maxsize = context->size + size; /* never overflows */ 29297db96d56Sopenharmony_ci 29307db96d56Sopenharmony_ci context->maxsize = maxsize; 29317db96d56Sopenharmony_ci 29327db96d56Sopenharmony_ci return _PyTuple_Resize(&context->tuple, maxsize) >= 0; 29337db96d56Sopenharmony_ci} 29347db96d56Sopenharmony_ci 29357db96d56Sopenharmony_cistatic int 29367db96d56Sopenharmony_ci_flatten1(FlattenContext* context, PyObject* item, int depth) 29377db96d56Sopenharmony_ci{ 29387db96d56Sopenharmony_ci /* add tuple or list to argument tuple (recursively) */ 29397db96d56Sopenharmony_ci 29407db96d56Sopenharmony_ci Py_ssize_t i, size; 29417db96d56Sopenharmony_ci 29427db96d56Sopenharmony_ci if (depth > 1000) { 29437db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 29447db96d56Sopenharmony_ci "nesting too deep in _flatten"); 29457db96d56Sopenharmony_ci return 0; 29467db96d56Sopenharmony_ci } else if (PyTuple_Check(item) || PyList_Check(item)) { 29477db96d56Sopenharmony_ci size = PySequence_Fast_GET_SIZE(item); 29487db96d56Sopenharmony_ci /* preallocate (assume no nesting) */ 29497db96d56Sopenharmony_ci if (context->size + size > context->maxsize && 29507db96d56Sopenharmony_ci !_bump(context, size)) 29517db96d56Sopenharmony_ci return 0; 29527db96d56Sopenharmony_ci /* copy items to output tuple */ 29537db96d56Sopenharmony_ci for (i = 0; i < size; i++) { 29547db96d56Sopenharmony_ci PyObject *o = PySequence_Fast_GET_ITEM(item, i); 29557db96d56Sopenharmony_ci if (PyList_Check(o) || PyTuple_Check(o)) { 29567db96d56Sopenharmony_ci if (!_flatten1(context, o, depth + 1)) 29577db96d56Sopenharmony_ci return 0; 29587db96d56Sopenharmony_ci } else if (o != Py_None) { 29597db96d56Sopenharmony_ci if (context->size + 1 > context->maxsize && 29607db96d56Sopenharmony_ci !_bump(context, 1)) 29617db96d56Sopenharmony_ci return 0; 29627db96d56Sopenharmony_ci Py_INCREF(o); 29637db96d56Sopenharmony_ci PyTuple_SET_ITEM(context->tuple, 29647db96d56Sopenharmony_ci context->size++, o); 29657db96d56Sopenharmony_ci } 29667db96d56Sopenharmony_ci } 29677db96d56Sopenharmony_ci } else { 29687db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "argument must be sequence"); 29697db96d56Sopenharmony_ci return 0; 29707db96d56Sopenharmony_ci } 29717db96d56Sopenharmony_ci return 1; 29727db96d56Sopenharmony_ci} 29737db96d56Sopenharmony_ci 29747db96d56Sopenharmony_ci/*[clinic input] 29757db96d56Sopenharmony_ci_tkinter._flatten 29767db96d56Sopenharmony_ci 29777db96d56Sopenharmony_ci item: object 29787db96d56Sopenharmony_ci / 29797db96d56Sopenharmony_ci 29807db96d56Sopenharmony_ci[clinic start generated code]*/ 29817db96d56Sopenharmony_ci 29827db96d56Sopenharmony_cistatic PyObject * 29837db96d56Sopenharmony_ci_tkinter__flatten(PyObject *module, PyObject *item) 29847db96d56Sopenharmony_ci/*[clinic end generated code: output=cad02a3f97f29862 input=6b9c12260aa1157f]*/ 29857db96d56Sopenharmony_ci{ 29867db96d56Sopenharmony_ci FlattenContext context; 29877db96d56Sopenharmony_ci 29887db96d56Sopenharmony_ci context.maxsize = PySequence_Size(item); 29897db96d56Sopenharmony_ci if (context.maxsize < 0) 29907db96d56Sopenharmony_ci return NULL; 29917db96d56Sopenharmony_ci if (context.maxsize == 0) 29927db96d56Sopenharmony_ci return PyTuple_New(0); 29937db96d56Sopenharmony_ci 29947db96d56Sopenharmony_ci context.tuple = PyTuple_New(context.maxsize); 29957db96d56Sopenharmony_ci if (!context.tuple) 29967db96d56Sopenharmony_ci return NULL; 29977db96d56Sopenharmony_ci 29987db96d56Sopenharmony_ci context.size = 0; 29997db96d56Sopenharmony_ci 30007db96d56Sopenharmony_ci if (!_flatten1(&context, item, 0)) { 30017db96d56Sopenharmony_ci Py_XDECREF(context.tuple); 30027db96d56Sopenharmony_ci return NULL; 30037db96d56Sopenharmony_ci } 30047db96d56Sopenharmony_ci 30057db96d56Sopenharmony_ci if (_PyTuple_Resize(&context.tuple, context.size)) 30067db96d56Sopenharmony_ci return NULL; 30077db96d56Sopenharmony_ci 30087db96d56Sopenharmony_ci return context.tuple; 30097db96d56Sopenharmony_ci} 30107db96d56Sopenharmony_ci 30117db96d56Sopenharmony_ci/*[clinic input] 30127db96d56Sopenharmony_ci_tkinter.create 30137db96d56Sopenharmony_ci 30147db96d56Sopenharmony_ci screenName: str(accept={str, NoneType}) = None 30157db96d56Sopenharmony_ci baseName: str = "" 30167db96d56Sopenharmony_ci className: str = "Tk" 30177db96d56Sopenharmony_ci interactive: bool(accept={int}) = False 30187db96d56Sopenharmony_ci wantobjects: bool(accept={int}) = False 30197db96d56Sopenharmony_ci wantTk: bool(accept={int}) = True 30207db96d56Sopenharmony_ci if false, then Tk_Init() doesn't get called 30217db96d56Sopenharmony_ci sync: bool(accept={int}) = False 30227db96d56Sopenharmony_ci if true, then pass -sync to wish 30237db96d56Sopenharmony_ci use: str(accept={str, NoneType}) = None 30247db96d56Sopenharmony_ci if not None, then pass -use to wish 30257db96d56Sopenharmony_ci / 30267db96d56Sopenharmony_ci 30277db96d56Sopenharmony_ci[clinic start generated code]*/ 30287db96d56Sopenharmony_ci 30297db96d56Sopenharmony_cistatic PyObject * 30307db96d56Sopenharmony_ci_tkinter_create_impl(PyObject *module, const char *screenName, 30317db96d56Sopenharmony_ci const char *baseName, const char *className, 30327db96d56Sopenharmony_ci int interactive, int wantobjects, int wantTk, int sync, 30337db96d56Sopenharmony_ci const char *use) 30347db96d56Sopenharmony_ci/*[clinic end generated code: output=e3315607648e6bb4 input=da9b17ee7358d862]*/ 30357db96d56Sopenharmony_ci{ 30367db96d56Sopenharmony_ci /* XXX baseName is not used anymore; 30377db96d56Sopenharmony_ci * try getting rid of it. */ 30387db96d56Sopenharmony_ci CHECK_STRING_LENGTH(screenName); 30397db96d56Sopenharmony_ci CHECK_STRING_LENGTH(baseName); 30407db96d56Sopenharmony_ci CHECK_STRING_LENGTH(className); 30417db96d56Sopenharmony_ci CHECK_STRING_LENGTH(use); 30427db96d56Sopenharmony_ci 30437db96d56Sopenharmony_ci return (PyObject *) Tkapp_New(screenName, className, 30447db96d56Sopenharmony_ci interactive, wantobjects, wantTk, 30457db96d56Sopenharmony_ci sync, use); 30467db96d56Sopenharmony_ci} 30477db96d56Sopenharmony_ci 30487db96d56Sopenharmony_ci/*[clinic input] 30497db96d56Sopenharmony_ci_tkinter.setbusywaitinterval 30507db96d56Sopenharmony_ci 30517db96d56Sopenharmony_ci new_val: int 30527db96d56Sopenharmony_ci / 30537db96d56Sopenharmony_ci 30547db96d56Sopenharmony_ciSet the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter. 30557db96d56Sopenharmony_ci 30567db96d56Sopenharmony_ciIt should be set to a divisor of the maximum time between frames in an animation. 30577db96d56Sopenharmony_ci[clinic start generated code]*/ 30587db96d56Sopenharmony_ci 30597db96d56Sopenharmony_cistatic PyObject * 30607db96d56Sopenharmony_ci_tkinter_setbusywaitinterval_impl(PyObject *module, int new_val) 30617db96d56Sopenharmony_ci/*[clinic end generated code: output=42bf7757dc2d0ab6 input=deca1d6f9e6dae47]*/ 30627db96d56Sopenharmony_ci{ 30637db96d56Sopenharmony_ci if (new_val < 0) { 30647db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 30657db96d56Sopenharmony_ci "busywaitinterval must be >= 0"); 30667db96d56Sopenharmony_ci return NULL; 30677db96d56Sopenharmony_ci } 30687db96d56Sopenharmony_ci Tkinter_busywaitinterval = new_val; 30697db96d56Sopenharmony_ci Py_RETURN_NONE; 30707db96d56Sopenharmony_ci} 30717db96d56Sopenharmony_ci 30727db96d56Sopenharmony_ci/*[clinic input] 30737db96d56Sopenharmony_ci_tkinter.getbusywaitinterval -> int 30747db96d56Sopenharmony_ci 30757db96d56Sopenharmony_ciReturn the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter. 30767db96d56Sopenharmony_ci[clinic start generated code]*/ 30777db96d56Sopenharmony_ci 30787db96d56Sopenharmony_cistatic int 30797db96d56Sopenharmony_ci_tkinter_getbusywaitinterval_impl(PyObject *module) 30807db96d56Sopenharmony_ci/*[clinic end generated code: output=23b72d552001f5c7 input=a695878d2d576a84]*/ 30817db96d56Sopenharmony_ci{ 30827db96d56Sopenharmony_ci return Tkinter_busywaitinterval; 30837db96d56Sopenharmony_ci} 30847db96d56Sopenharmony_ci 30857db96d56Sopenharmony_ci#include "clinic/_tkinter.c.h" 30867db96d56Sopenharmony_ci 30877db96d56Sopenharmony_cistatic PyMethodDef Tktt_methods[] = 30887db96d56Sopenharmony_ci{ 30897db96d56Sopenharmony_ci _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF 30907db96d56Sopenharmony_ci {NULL, NULL} 30917db96d56Sopenharmony_ci}; 30927db96d56Sopenharmony_ci 30937db96d56Sopenharmony_cistatic PyType_Slot Tktt_Type_slots[] = { 30947db96d56Sopenharmony_ci {Py_tp_dealloc, Tktt_Dealloc}, 30957db96d56Sopenharmony_ci {Py_tp_repr, Tktt_Repr}, 30967db96d56Sopenharmony_ci {Py_tp_methods, Tktt_methods}, 30977db96d56Sopenharmony_ci {0, 0} 30987db96d56Sopenharmony_ci}; 30997db96d56Sopenharmony_ci 31007db96d56Sopenharmony_cistatic PyType_Spec Tktt_Type_spec = { 31017db96d56Sopenharmony_ci "_tkinter.tktimertoken", 31027db96d56Sopenharmony_ci sizeof(TkttObject), 31037db96d56Sopenharmony_ci 0, 31047db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, 31057db96d56Sopenharmony_ci Tktt_Type_slots, 31067db96d56Sopenharmony_ci}; 31077db96d56Sopenharmony_ci 31087db96d56Sopenharmony_ci 31097db96d56Sopenharmony_ci/**** Tkapp Method List ****/ 31107db96d56Sopenharmony_ci 31117db96d56Sopenharmony_cistatic PyMethodDef Tkapp_methods[] = 31127db96d56Sopenharmony_ci{ 31137db96d56Sopenharmony_ci _TKINTER_TKAPP_WILLDISPATCH_METHODDEF 31147db96d56Sopenharmony_ci {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, 31157db96d56Sopenharmony_ci {"call", Tkapp_Call, METH_VARARGS}, 31167db96d56Sopenharmony_ci _TKINTER_TKAPP_EVAL_METHODDEF 31177db96d56Sopenharmony_ci _TKINTER_TKAPP_EVALFILE_METHODDEF 31187db96d56Sopenharmony_ci _TKINTER_TKAPP_RECORD_METHODDEF 31197db96d56Sopenharmony_ci _TKINTER_TKAPP_ADDERRORINFO_METHODDEF 31207db96d56Sopenharmony_ci {"setvar", Tkapp_SetVar, METH_VARARGS}, 31217db96d56Sopenharmony_ci {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS}, 31227db96d56Sopenharmony_ci {"getvar", Tkapp_GetVar, METH_VARARGS}, 31237db96d56Sopenharmony_ci {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS}, 31247db96d56Sopenharmony_ci {"unsetvar", Tkapp_UnsetVar, METH_VARARGS}, 31257db96d56Sopenharmony_ci {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, 31267db96d56Sopenharmony_ci _TKINTER_TKAPP_GETINT_METHODDEF 31277db96d56Sopenharmony_ci _TKINTER_TKAPP_GETDOUBLE_METHODDEF 31287db96d56Sopenharmony_ci _TKINTER_TKAPP_GETBOOLEAN_METHODDEF 31297db96d56Sopenharmony_ci _TKINTER_TKAPP_EXPRSTRING_METHODDEF 31307db96d56Sopenharmony_ci _TKINTER_TKAPP_EXPRLONG_METHODDEF 31317db96d56Sopenharmony_ci _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF 31327db96d56Sopenharmony_ci _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF 31337db96d56Sopenharmony_ci _TKINTER_TKAPP_SPLITLIST_METHODDEF 31347db96d56Sopenharmony_ci _TKINTER_TKAPP_CREATECOMMAND_METHODDEF 31357db96d56Sopenharmony_ci _TKINTER_TKAPP_DELETECOMMAND_METHODDEF 31367db96d56Sopenharmony_ci _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF 31377db96d56Sopenharmony_ci _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF 31387db96d56Sopenharmony_ci _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF 31397db96d56Sopenharmony_ci _TKINTER_TKAPP_MAINLOOP_METHODDEF 31407db96d56Sopenharmony_ci _TKINTER_TKAPP_DOONEEVENT_METHODDEF 31417db96d56Sopenharmony_ci _TKINTER_TKAPP_QUIT_METHODDEF 31427db96d56Sopenharmony_ci _TKINTER_TKAPP_INTERPADDR_METHODDEF 31437db96d56Sopenharmony_ci _TKINTER_TKAPP_LOADTK_METHODDEF 31447db96d56Sopenharmony_ci {NULL, NULL} 31457db96d56Sopenharmony_ci}; 31467db96d56Sopenharmony_ci 31477db96d56Sopenharmony_cistatic PyType_Slot Tkapp_Type_slots[] = { 31487db96d56Sopenharmony_ci {Py_tp_dealloc, Tkapp_Dealloc}, 31497db96d56Sopenharmony_ci {Py_tp_methods, Tkapp_methods}, 31507db96d56Sopenharmony_ci {0, 0} 31517db96d56Sopenharmony_ci}; 31527db96d56Sopenharmony_ci 31537db96d56Sopenharmony_ci 31547db96d56Sopenharmony_cistatic PyType_Spec Tkapp_Type_spec = { 31557db96d56Sopenharmony_ci "_tkinter.tkapp", 31567db96d56Sopenharmony_ci sizeof(TkappObject), 31577db96d56Sopenharmony_ci 0, 31587db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, 31597db96d56Sopenharmony_ci Tkapp_Type_slots, 31607db96d56Sopenharmony_ci}; 31617db96d56Sopenharmony_ci 31627db96d56Sopenharmony_cistatic PyMethodDef moduleMethods[] = 31637db96d56Sopenharmony_ci{ 31647db96d56Sopenharmony_ci _TKINTER__FLATTEN_METHODDEF 31657db96d56Sopenharmony_ci _TKINTER_CREATE_METHODDEF 31667db96d56Sopenharmony_ci _TKINTER_SETBUSYWAITINTERVAL_METHODDEF 31677db96d56Sopenharmony_ci _TKINTER_GETBUSYWAITINTERVAL_METHODDEF 31687db96d56Sopenharmony_ci {NULL, NULL} 31697db96d56Sopenharmony_ci}; 31707db96d56Sopenharmony_ci 31717db96d56Sopenharmony_ci#ifdef WAIT_FOR_STDIN 31727db96d56Sopenharmony_ci 31737db96d56Sopenharmony_cistatic int stdin_ready = 0; 31747db96d56Sopenharmony_ci 31757db96d56Sopenharmony_ci#ifndef MS_WINDOWS 31767db96d56Sopenharmony_cistatic void 31777db96d56Sopenharmony_ciMyFileProc(void *clientData, int mask) 31787db96d56Sopenharmony_ci{ 31797db96d56Sopenharmony_ci stdin_ready = 1; 31807db96d56Sopenharmony_ci} 31817db96d56Sopenharmony_ci#endif 31827db96d56Sopenharmony_ci 31837db96d56Sopenharmony_cistatic PyThreadState *event_tstate = NULL; 31847db96d56Sopenharmony_ci 31857db96d56Sopenharmony_cistatic int 31867db96d56Sopenharmony_ciEventHook(void) 31877db96d56Sopenharmony_ci{ 31887db96d56Sopenharmony_ci#ifndef MS_WINDOWS 31897db96d56Sopenharmony_ci int tfile; 31907db96d56Sopenharmony_ci#endif 31917db96d56Sopenharmony_ci PyEval_RestoreThread(event_tstate); 31927db96d56Sopenharmony_ci stdin_ready = 0; 31937db96d56Sopenharmony_ci errorInCmd = 0; 31947db96d56Sopenharmony_ci#ifndef MS_WINDOWS 31957db96d56Sopenharmony_ci tfile = fileno(stdin); 31967db96d56Sopenharmony_ci Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL); 31977db96d56Sopenharmony_ci#endif 31987db96d56Sopenharmony_ci while (!errorInCmd && !stdin_ready) { 31997db96d56Sopenharmony_ci int result; 32007db96d56Sopenharmony_ci#ifdef MS_WINDOWS 32017db96d56Sopenharmony_ci if (_kbhit()) { 32027db96d56Sopenharmony_ci stdin_ready = 1; 32037db96d56Sopenharmony_ci break; 32047db96d56Sopenharmony_ci } 32057db96d56Sopenharmony_ci#endif 32067db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 32077db96d56Sopenharmony_ci if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); 32087db96d56Sopenharmony_ci tcl_tstate = event_tstate; 32097db96d56Sopenharmony_ci 32107db96d56Sopenharmony_ci result = Tcl_DoOneEvent(TCL_DONT_WAIT); 32117db96d56Sopenharmony_ci 32127db96d56Sopenharmony_ci tcl_tstate = NULL; 32137db96d56Sopenharmony_ci if(tcl_lock)PyThread_release_lock(tcl_lock); 32147db96d56Sopenharmony_ci if (result == 0) 32157db96d56Sopenharmony_ci Sleep(Tkinter_busywaitinterval); 32167db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 32177db96d56Sopenharmony_ci 32187db96d56Sopenharmony_ci if (result < 0) 32197db96d56Sopenharmony_ci break; 32207db96d56Sopenharmony_ci } 32217db96d56Sopenharmony_ci#ifndef MS_WINDOWS 32227db96d56Sopenharmony_ci Tcl_DeleteFileHandler(tfile); 32237db96d56Sopenharmony_ci#endif 32247db96d56Sopenharmony_ci if (errorInCmd) { 32257db96d56Sopenharmony_ci errorInCmd = 0; 32267db96d56Sopenharmony_ci PyErr_Restore(excInCmd, valInCmd, trbInCmd); 32277db96d56Sopenharmony_ci excInCmd = valInCmd = trbInCmd = NULL; 32287db96d56Sopenharmony_ci PyErr_Print(); 32297db96d56Sopenharmony_ci } 32307db96d56Sopenharmony_ci PyEval_SaveThread(); 32317db96d56Sopenharmony_ci return 0; 32327db96d56Sopenharmony_ci} 32337db96d56Sopenharmony_ci 32347db96d56Sopenharmony_ci#endif 32357db96d56Sopenharmony_ci 32367db96d56Sopenharmony_cistatic void 32377db96d56Sopenharmony_ciEnableEventHook(void) 32387db96d56Sopenharmony_ci{ 32397db96d56Sopenharmony_ci#ifdef WAIT_FOR_STDIN 32407db96d56Sopenharmony_ci if (PyOS_InputHook == NULL) { 32417db96d56Sopenharmony_ci event_tstate = PyThreadState_Get(); 32427db96d56Sopenharmony_ci PyOS_InputHook = EventHook; 32437db96d56Sopenharmony_ci } 32447db96d56Sopenharmony_ci#endif 32457db96d56Sopenharmony_ci} 32467db96d56Sopenharmony_ci 32477db96d56Sopenharmony_cistatic void 32487db96d56Sopenharmony_ciDisableEventHook(void) 32497db96d56Sopenharmony_ci{ 32507db96d56Sopenharmony_ci#ifdef WAIT_FOR_STDIN 32517db96d56Sopenharmony_ci if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) { 32527db96d56Sopenharmony_ci PyOS_InputHook = NULL; 32537db96d56Sopenharmony_ci } 32547db96d56Sopenharmony_ci#endif 32557db96d56Sopenharmony_ci} 32567db96d56Sopenharmony_ci 32577db96d56Sopenharmony_ci 32587db96d56Sopenharmony_cistatic struct PyModuleDef _tkintermodule = { 32597db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 32607db96d56Sopenharmony_ci "_tkinter", 32617db96d56Sopenharmony_ci NULL, 32627db96d56Sopenharmony_ci -1, 32637db96d56Sopenharmony_ci moduleMethods, 32647db96d56Sopenharmony_ci NULL, 32657db96d56Sopenharmony_ci NULL, 32667db96d56Sopenharmony_ci NULL, 32677db96d56Sopenharmony_ci NULL 32687db96d56Sopenharmony_ci}; 32697db96d56Sopenharmony_ci 32707db96d56Sopenharmony_ciPyMODINIT_FUNC 32717db96d56Sopenharmony_ciPyInit__tkinter(void) 32727db96d56Sopenharmony_ci{ 32737db96d56Sopenharmony_ci PyObject *m, *uexe, *cexe, *o; 32747db96d56Sopenharmony_ci 32757db96d56Sopenharmony_ci tcl_lock = PyThread_allocate_lock(); 32767db96d56Sopenharmony_ci if (tcl_lock == NULL) 32777db96d56Sopenharmony_ci return NULL; 32787db96d56Sopenharmony_ci 32797db96d56Sopenharmony_ci m = PyModule_Create(&_tkintermodule); 32807db96d56Sopenharmony_ci if (m == NULL) 32817db96d56Sopenharmony_ci return NULL; 32827db96d56Sopenharmony_ci 32837db96d56Sopenharmony_ci o = PyErr_NewException("_tkinter.TclError", NULL, NULL); 32847db96d56Sopenharmony_ci if (o == NULL) { 32857db96d56Sopenharmony_ci Py_DECREF(m); 32867db96d56Sopenharmony_ci return NULL; 32877db96d56Sopenharmony_ci } 32887db96d56Sopenharmony_ci Py_INCREF(o); 32897db96d56Sopenharmony_ci if (PyModule_AddObject(m, "TclError", o)) { 32907db96d56Sopenharmony_ci Py_DECREF(o); 32917db96d56Sopenharmony_ci Py_DECREF(m); 32927db96d56Sopenharmony_ci return NULL; 32937db96d56Sopenharmony_ci } 32947db96d56Sopenharmony_ci Tkinter_TclError = o; 32957db96d56Sopenharmony_ci 32967db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) { 32977db96d56Sopenharmony_ci Py_DECREF(m); 32987db96d56Sopenharmony_ci return NULL; 32997db96d56Sopenharmony_ci } 33007db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) { 33017db96d56Sopenharmony_ci Py_DECREF(m); 33027db96d56Sopenharmony_ci return NULL; 33037db96d56Sopenharmony_ci } 33047db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) { 33057db96d56Sopenharmony_ci Py_DECREF(m); 33067db96d56Sopenharmony_ci return NULL; 33077db96d56Sopenharmony_ci } 33087db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) { 33097db96d56Sopenharmony_ci Py_DECREF(m); 33107db96d56Sopenharmony_ci return NULL; 33117db96d56Sopenharmony_ci } 33127db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) { 33137db96d56Sopenharmony_ci Py_DECREF(m); 33147db96d56Sopenharmony_ci return NULL; 33157db96d56Sopenharmony_ci } 33167db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) { 33177db96d56Sopenharmony_ci Py_DECREF(m); 33187db96d56Sopenharmony_ci return NULL; 33197db96d56Sopenharmony_ci } 33207db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) { 33217db96d56Sopenharmony_ci Py_DECREF(m); 33227db96d56Sopenharmony_ci return NULL; 33237db96d56Sopenharmony_ci } 33247db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) { 33257db96d56Sopenharmony_ci Py_DECREF(m); 33267db96d56Sopenharmony_ci return NULL; 33277db96d56Sopenharmony_ci } 33287db96d56Sopenharmony_ci if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) { 33297db96d56Sopenharmony_ci Py_DECREF(m); 33307db96d56Sopenharmony_ci return NULL; 33317db96d56Sopenharmony_ci } 33327db96d56Sopenharmony_ci if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) { 33337db96d56Sopenharmony_ci Py_DECREF(m); 33347db96d56Sopenharmony_ci return NULL; 33357db96d56Sopenharmony_ci } 33367db96d56Sopenharmony_ci if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) { 33377db96d56Sopenharmony_ci Py_DECREF(m); 33387db96d56Sopenharmony_ci return NULL; 33397db96d56Sopenharmony_ci } 33407db96d56Sopenharmony_ci 33417db96d56Sopenharmony_ci o = PyType_FromSpec(&Tkapp_Type_spec); 33427db96d56Sopenharmony_ci if (o == NULL) { 33437db96d56Sopenharmony_ci Py_DECREF(m); 33447db96d56Sopenharmony_ci return NULL; 33457db96d56Sopenharmony_ci } 33467db96d56Sopenharmony_ci if (PyModule_AddObject(m, "TkappType", o)) { 33477db96d56Sopenharmony_ci Py_DECREF(o); 33487db96d56Sopenharmony_ci Py_DECREF(m); 33497db96d56Sopenharmony_ci return NULL; 33507db96d56Sopenharmony_ci } 33517db96d56Sopenharmony_ci Tkapp_Type = o; 33527db96d56Sopenharmony_ci 33537db96d56Sopenharmony_ci o = PyType_FromSpec(&Tktt_Type_spec); 33547db96d56Sopenharmony_ci if (o == NULL) { 33557db96d56Sopenharmony_ci Py_DECREF(m); 33567db96d56Sopenharmony_ci return NULL; 33577db96d56Sopenharmony_ci } 33587db96d56Sopenharmony_ci if (PyModule_AddObject(m, "TkttType", o)) { 33597db96d56Sopenharmony_ci Py_DECREF(o); 33607db96d56Sopenharmony_ci Py_DECREF(m); 33617db96d56Sopenharmony_ci return NULL; 33627db96d56Sopenharmony_ci } 33637db96d56Sopenharmony_ci Tktt_Type = o; 33647db96d56Sopenharmony_ci 33657db96d56Sopenharmony_ci o = PyType_FromSpec(&PyTclObject_Type_spec); 33667db96d56Sopenharmony_ci if (o == NULL) { 33677db96d56Sopenharmony_ci Py_DECREF(m); 33687db96d56Sopenharmony_ci return NULL; 33697db96d56Sopenharmony_ci } 33707db96d56Sopenharmony_ci if (PyModule_AddObject(m, "Tcl_Obj", o)) { 33717db96d56Sopenharmony_ci Py_DECREF(o); 33727db96d56Sopenharmony_ci Py_DECREF(m); 33737db96d56Sopenharmony_ci return NULL; 33747db96d56Sopenharmony_ci } 33757db96d56Sopenharmony_ci PyTclObject_Type = o; 33767db96d56Sopenharmony_ci 33777db96d56Sopenharmony_ci#ifdef TK_AQUA 33787db96d56Sopenharmony_ci /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems 33797db96d56Sopenharmony_ci * start waking up. Note that Tcl_FindExecutable will do this, this 33807db96d56Sopenharmony_ci * code must be above it! The original warning from 33817db96d56Sopenharmony_ci * tkMacOSXAppInit.c is copied below. 33827db96d56Sopenharmony_ci * 33837db96d56Sopenharmony_ci * NB - You have to swap in the Tk Notifier BEFORE you start up the 33847db96d56Sopenharmony_ci * Tcl interpreter for now. It probably should work to do this 33857db96d56Sopenharmony_ci * in the other order, but for now it doesn't seem to. 33867db96d56Sopenharmony_ci * 33877db96d56Sopenharmony_ci */ 33887db96d56Sopenharmony_ci Tk_MacOSXSetupTkNotifier(); 33897db96d56Sopenharmony_ci#endif 33907db96d56Sopenharmony_ci 33917db96d56Sopenharmony_ci 33927db96d56Sopenharmony_ci /* This helps the dynamic loader; in Unicode aware Tcl versions 33937db96d56Sopenharmony_ci it also helps Tcl find its encodings. */ 33947db96d56Sopenharmony_ci uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); 33957db96d56Sopenharmony_ci if (uexe) { 33967db96d56Sopenharmony_ci cexe = PyUnicode_EncodeFSDefault(uexe); 33977db96d56Sopenharmony_ci if (cexe) { 33987db96d56Sopenharmony_ci#ifdef MS_WINDOWS 33997db96d56Sopenharmony_ci int set_var = 0; 34007db96d56Sopenharmony_ci PyObject *str_path; 34017db96d56Sopenharmony_ci wchar_t *wcs_path; 34027db96d56Sopenharmony_ci DWORD ret; 34037db96d56Sopenharmony_ci 34047db96d56Sopenharmony_ci ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); 34057db96d56Sopenharmony_ci 34067db96d56Sopenharmony_ci if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { 34077db96d56Sopenharmony_ci str_path = _get_tcl_lib_path(); 34087db96d56Sopenharmony_ci if (str_path == NULL && PyErr_Occurred()) { 34097db96d56Sopenharmony_ci Py_DECREF(m); 34107db96d56Sopenharmony_ci return NULL; 34117db96d56Sopenharmony_ci } 34127db96d56Sopenharmony_ci if (str_path != NULL) { 34137db96d56Sopenharmony_ci wcs_path = PyUnicode_AsWideCharString(str_path, NULL); 34147db96d56Sopenharmony_ci if (wcs_path == NULL) { 34157db96d56Sopenharmony_ci Py_DECREF(m); 34167db96d56Sopenharmony_ci return NULL; 34177db96d56Sopenharmony_ci } 34187db96d56Sopenharmony_ci SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); 34197db96d56Sopenharmony_ci set_var = 1; 34207db96d56Sopenharmony_ci } 34217db96d56Sopenharmony_ci } 34227db96d56Sopenharmony_ci 34237db96d56Sopenharmony_ci Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); 34247db96d56Sopenharmony_ci 34257db96d56Sopenharmony_ci if (set_var) { 34267db96d56Sopenharmony_ci SetEnvironmentVariableW(L"TCL_LIBRARY", NULL); 34277db96d56Sopenharmony_ci PyMem_Free(wcs_path); 34287db96d56Sopenharmony_ci } 34297db96d56Sopenharmony_ci#else 34307db96d56Sopenharmony_ci Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); 34317db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 34327db96d56Sopenharmony_ci } 34337db96d56Sopenharmony_ci Py_XDECREF(cexe); 34347db96d56Sopenharmony_ci Py_DECREF(uexe); 34357db96d56Sopenharmony_ci } 34367db96d56Sopenharmony_ci 34377db96d56Sopenharmony_ci if (PyErr_Occurred()) { 34387db96d56Sopenharmony_ci Py_DECREF(m); 34397db96d56Sopenharmony_ci return NULL; 34407db96d56Sopenharmony_ci } 34417db96d56Sopenharmony_ci 34427db96d56Sopenharmony_ci return m; 34437db96d56Sopenharmony_ci} 3444