Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Modules/_tkinter.c

    r2 r391  
    1010/* TCL/TK VERSION INFO:
    1111
    12         Only Tcl/Tk 8.2 and later are supported.  Older versions are not
    13         supported.  (Use Python 2.2 if you cannot upgrade your Tcl/Tk
    14         libraries.)
     12    Only Tcl/Tk 8.3.1 and later are supported.  Older versions are not
     13    supported. Use Python 2.6 or older if you cannot upgrade your
     14    Tcl/Tk libraries.
    1515*/
    1616
     
    4747#define PyBool_FromLong       PyInt_FromLong
    4848#endif
     49
     50#define CHECK_SIZE(size, elemsize) \
     51    ((size_t)(size) <= (size_t)INT_MAX && \
     52     (size_t)(size) <= UINT_MAX / (size_t)(elemsize))
    4953
    5054/* Starting with Tcl 8.4, many APIs offer const-correctness.  Unfortunately,
     
    6872#endif
    6973
     74#include "tkinter.h"
     75
    7076/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
    7177#ifndef CONST84_RETURN
     
    7581#endif
    7682
    77 #define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
    78 
    79 #if TKMAJORMINOR < 8002
    80 #error "Tk older than 8.2 not supported"
     83#if TK_VERSION_HEX < 0x08030102
     84#error "Tk older than 8.3.1 not supported"
    8185#endif
    8286
     
    8488   We cannot test this directly, so we test UTF-8 size instead,
    8589   expecting that TCL_UTF_MAX is changed if Tcl ever supports
    86    either UTF-16 or UCS-4. 
    87    Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for 
     90   either UTF-16 or UCS-4.
     91   Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
    8892   Tcl_Unichar. This is also ok as long as Python uses UCS-4,
    8993   as well.
     
    198202
    199203#define ENTER_TCL \
    200         { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
    201             if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
     204    { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
     205        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
    202206
    203207#define LEAVE_TCL \
     
    205209
    206210#define ENTER_OVERLAP \
    207         Py_END_ALLOW_THREADS
     211    Py_END_ALLOW_THREADS
    208212
    209213#define LEAVE_OVERLAP_TCL \
    210         tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
     214    tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
    211215
    212216#define ENTER_PYTHON \
    213         { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
    214             if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
     217    { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
     218        if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
    215219
    216220#define LEAVE_PYTHON \
    217         { PyThreadState *tstate = PyEval_SaveThread(); \
    218             if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
     221    { PyThreadState *tstate = PyEval_SaveThread(); \
     222        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
    219223
    220224#define CHECK_TCL_APPARTMENT \
    221         if (((TkappObject *)self)->threaded && \
    222             ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
    223                 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
    224                 return 0; \
    225         }
     225    if (((TkappObject *)self)->threaded && \
     226        ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
     227        PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
     228        return 0; \
     229    }
    226230
    227231#else
     
    246250
    247251typedef struct {
    248         PyObject_HEAD
    249         Tcl_Interp *interp;
    250         int wantobjects;
    251         int threaded; /* True if tcl_platform[threaded] */
    252         Tcl_ThreadId thread_id;
    253         int dispatching;
    254         /* We cannot include tclInt.h, as this is internal.
    255            So we cache interesting types here. */
    256         Tcl_ObjType *BooleanType;
    257         Tcl_ObjType *ByteArrayType;
    258         Tcl_ObjType *DoubleType;
    259         Tcl_ObjType *IntType;
    260         Tcl_ObjType *ListType;
    261         Tcl_ObjType *ProcBodyType;
    262         Tcl_ObjType *StringType;
     252    PyObject_HEAD
     253    Tcl_Interp *interp;
     254    int wantobjects;
     255    int threaded; /* True if tcl_platform[threaded] */
     256    Tcl_ThreadId thread_id;
     257    int dispatching;
     258    /* We cannot include tclInt.h, as this is internal.
     259       So we cache interesting types here. */
     260    Tcl_ObjType *BooleanType;
     261    Tcl_ObjType *ByteArrayType;
     262    Tcl_ObjType *DoubleType;
     263    Tcl_ObjType *IntType;
     264    Tcl_ObjType *ListType;
     265    Tcl_ObjType *ProcBodyType;
     266    Tcl_ObjType *StringType;
    263267} TkappObject;
    264268
     
    269273#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
    270274(void *) v, Py_REFCNT(v)))
    271 
    272275
    273276
     
    282285static PyObject *trbInCmd;
    283286
    284 
     287#ifdef TKINTER_PROTECT_LOADTK
     288static int tk_load_failed;
     289#endif
    285290
    286291
     
    288293Tkinter_Error(PyObject *v)
    289294{
    290         PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
    291         return NULL;
    292 }
    293 
     295    PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
     296    return NULL;
     297}
    294298
    295299
     
    307311Sleep(int milli)
    308312{
    309         /* XXX Too bad if you don't have select(). */
    310         struct timeval t;
    311         t.tv_sec = milli/1000;
    312         t.tv_usec = (milli%1000) * 1000;
    313         select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
     313    /* XXX Too bad if you don't have select(). */
     314    struct timeval t;
     315    t.tv_sec = milli/1000;
     316    t.tv_usec = (milli%1000) * 1000;
     317    select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
    314318}
    315319#endif /* MS_WINDOWS */
     
    320324WaitForMainloop(TkappObject* self)
    321325{
    322         int i;
    323         for (i = 0; i < 10; i++) {
    324                 if (self->dispatching)
    325                         return 1;
    326                 Py_BEGIN_ALLOW_THREADS
    327                 Sleep(100);
    328                 Py_END_ALLOW_THREADS
    329         }
    330         if (self->dispatching)
    331                 return 1;
    332         PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
    333         return 0;
     326    int i;
     327    for (i = 0; i < 10; i++) {
     328        if (self->dispatching)
     329            return 1;
     330        Py_BEGIN_ALLOW_THREADS
     331        Sleep(100);
     332        Py_END_ALLOW_THREADS
     333    }
     334    if (self->dispatching)
     335        return 1;
     336    PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
     337    return 0;
    334338}
    335339#endif /* WITH_THREAD */
    336 
    337340
    338341
     
    340343AsString(PyObject *value, PyObject *tmp)
    341344{
    342         if (PyString_Check(value))
    343                 return PyString_AsString(value);
     345    if (PyString_Check(value))
     346        return PyString_AsString(value);
    344347#ifdef Py_USING_UNICODE
    345         else if (PyUnicode_Check(value)) {
    346                 PyObject *v = PyUnicode_AsUTF8String(value);
    347                 if (v == NULL)
    348                         return NULL;
    349                 if (PyList_Append(tmp, v) != 0) {
    350                         Py_DECREF(v);
    351                         return NULL;
    352                 }
    353                 Py_DECREF(v);
    354                 return PyString_AsString(v);
    355         }
    356 #endif
    357         else {
    358                 PyObject *v = PyObject_Str(value);
    359                 if (v == NULL)
    360                         return NULL;
    361                 if (PyList_Append(tmp, v) != 0) {
    362                         Py_DECREF(v);
    363                         return NULL;
    364                 }
    365                 Py_DECREF(v);
    366                 return PyString_AsString(v);
    367         }
    368 }
    369 
     348    else if (PyUnicode_Check(value)) {
     349        PyObject *v = PyUnicode_AsUTF8String(value);
     350        if (v == NULL)
     351            return NULL;
     352        if (PyList_Append(tmp, v) != 0) {
     353            Py_DECREF(v);
     354            return NULL;
     355        }
     356        Py_DECREF(v);
     357        return PyString_AsString(v);
     358    }
     359#endif
     360    else {
     361        PyObject *v = PyObject_Str(value);
     362        if (v == NULL)
     363            return NULL;
     364        if (PyList_Append(tmp, v) != 0) {
     365            Py_DECREF(v);
     366            return NULL;
     367        }
     368        Py_DECREF(v);
     369        return PyString_AsString(v);
     370    }
     371}
    370372
    371373
     
    376378Merge(PyObject *args)
    377379{
    378         PyObject *tmp = NULL;
    379         char *argvStore[ARGSZ];
    380         char **argv = NULL;
    381         int fvStore[ARGSZ];
    382         int *fv = NULL;
    383         int argc = 0, fvc = 0, i;
    384         char *res = NULL;
    385 
    386         if (!(tmp = PyList_New(0)))
    387             return NULL;
    388 
    389         argv = argvStore;
    390         fv = fvStore;
    391 
    392         if (args == NULL)
    393                 argc = 0;
    394 
    395         else if (!PyTuple_Check(args)) {
    396                 argc = 1;
    397                 fv[0] = 0;
    398                 if (!(argv[0] = AsString(args, tmp)))
    399                         goto finally;
    400         }
    401         else {
    402                 argc = PyTuple_Size(args);
    403 
    404                 if (argc > ARGSZ) {
    405                         argv = (char **)ckalloc(argc * sizeof(char *));
    406                         fv = (int *)ckalloc(argc * sizeof(int));
    407                         if (argv == NULL || fv == NULL) {
    408                                 PyErr_NoMemory();
    409                                 goto finally;
    410                         }
    411                 }
    412 
    413                 for (i = 0; i < argc; i++) {
    414                         PyObject *v = PyTuple_GetItem(args, i);
    415                         if (PyTuple_Check(v)) {
    416                                 fv[i] = 1;
    417                                 if (!(argv[i] = Merge(v)))
    418                                         goto finally;
    419                                 fvc++;
    420                         }
    421                         else if (v == Py_None) {
    422                                 argc = i;
    423                                 break;
    424                         }
    425                         else {
    426                                 fv[i] = 0;
    427                                 if (!(argv[i] = AsString(v, tmp)))
    428                                         goto finally;
    429                                 fvc++;
    430                         }
    431                 }
    432         }
    433         res = Tcl_Merge(argc, argv);
    434         if (res == NULL)
    435                 PyErr_SetString(Tkinter_TclError, "merge failed");
     380    PyObject *tmp = NULL;
     381    char *argvStore[ARGSZ];
     382    char **argv = NULL;
     383    int fvStore[ARGSZ];
     384    int *fv = NULL;
     385    Py_ssize_t argc = 0, fvc = 0, i;
     386    char *res = NULL;
     387
     388    if (!(tmp = PyList_New(0)))
     389        return NULL;
     390
     391    argv = argvStore;
     392    fv = fvStore;
     393
     394    if (args == NULL)
     395        argc = 0;
     396
     397    else if (!PyTuple_Check(args)) {
     398        argc = 1;
     399        fv[0] = 0;
     400        if (!(argv[0] = AsString(args, tmp)))
     401            goto finally;
     402    }
     403    else {
     404        argc = PyTuple_Size(args);
     405
     406        if (argc > ARGSZ) {
     407            if (!CHECK_SIZE(argc, sizeof(char *))) {
     408                PyErr_SetString(PyExc_OverflowError, "tuple is too long");
     409                goto finally;
     410            }
     411            argv = (char **)ckalloc((size_t)argc * sizeof(char *));
     412            fv = (int *)ckalloc((size_t)argc * sizeof(int));
     413            if (argv == NULL || fv == NULL) {
     414                PyErr_NoMemory();
     415                goto finally;
     416            }
     417        }
     418
     419        for (i = 0; i < argc; i++) {
     420            PyObject *v = PyTuple_GetItem(args, i);
     421            if (PyTuple_Check(v)) {
     422                fv[i] = 1;
     423                if (!(argv[i] = Merge(v)))
     424                    goto finally;
     425                fvc++;
     426            }
     427            else if (v == Py_None) {
     428                argc = i;
     429                break;
     430            }
     431            else {
     432                fv[i] = 0;
     433                if (!(argv[i] = AsString(v, tmp)))
     434                    goto finally;
     435                fvc++;
     436            }
     437        }
     438    }
     439    res = Tcl_Merge(argc, argv);
     440    if (res == NULL)
     441        PyErr_SetString(Tkinter_TclError, "merge failed");
    436442
    437443  finally:
    438         for (i = 0; i < fvc; i++)
    439                 if (fv[i]) {
    440                         ckfree(argv[i]);
    441                 }
    442         if (argv != argvStore)
    443                 ckfree(FREECAST argv);
    444         if (fv != fvStore)
    445                 ckfree(FREECAST fv);
    446 
    447         Py_DECREF(tmp);
    448         return res;
    449 }
    450 
     444    for (i = 0; i < fvc; i++)
     445        if (fv[i]) {
     446            ckfree(argv[i]);
     447        }
     448    if (argv != argvStore)
     449        ckfree(FREECAST argv);
     450    if (fv != fvStore)
     451        ckfree(FREECAST fv);
     452
     453    Py_DECREF(tmp);
     454    return res;
     455}
    451456
    452457
     
    455460Split(char *list)
    456461{
    457         int argc;
    458         char **argv;
    459         PyObject *v;
    460 
    461         if (list == NULL) {
    462                 Py_INCREF(Py_None);
    463                 return Py_None;
    464         }
    465 
    466         if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
    467                 /* Not a list.
    468                 * Could be a quoted string containing funnies, e.g. {"}.
    469                 * Return the string itself.
    470                 */
    471                 return PyString_FromString(list);
    472         }
    473 
    474         if (argc == 0)
    475                 v = PyString_FromString("");
    476         else if (argc == 1)
    477                 v = PyString_FromString(argv[0]);
    478         else if ((v = PyTuple_New(argc)) != NULL) {
    479                 int i;
    480                 PyObject *w;
    481 
    482                 for (i = 0; i < argc; i++) {
    483                         if ((w = Split(argv[i])) == NULL) {
    484                                 Py_DECREF(v);
    485                                 v = NULL;
    486                                 break;
    487                         }
    488                         PyTuple_SetItem(v, i, w);
    489                 }
    490         }
    491         Tcl_Free(FREECAST argv);
    492         return v;
     462    int argc;
     463    char **argv;
     464    PyObject *v;
     465
     466    if (list == NULL) {
     467        Py_INCREF(Py_None);
     468        return Py_None;
     469    }
     470
     471    if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
     472        /* Not a list.
     473        * Could be a quoted string containing funnies, e.g. {"}.
     474        * Return the string itself.
     475        */
     476        return PyString_FromString(list);
     477    }
     478
     479    if (argc == 0)
     480        v = PyString_FromString("");
     481    else if (argc == 1)
     482        v = PyString_FromString(argv[0]);
     483    else if ((v = PyTuple_New(argc)) != NULL) {
     484        int i;
     485        PyObject *w;
     486
     487        for (i = 0; i < argc; i++) {
     488            if ((w = Split(argv[i])) == NULL) {
     489                Py_DECREF(v);
     490                v = NULL;
     491                break;
     492            }
     493            PyTuple_SetItem(v, i, w);
     494        }
     495    }
     496    Tcl_Free(FREECAST argv);
     497    return v;
    493498}
    494499
     
    500505SplitObj(PyObject *arg)
    501506{
    502         if (PyTuple_Check(arg)) {
    503                 int i, size;
    504                 PyObject *elem, *newelem, *result;
    505 
    506                 size = PyTuple_Size(arg);
    507                 result = NULL;
    508                 /* Recursively invoke SplitObj for all tuple items.
    509                    If this does not return a new object, no action is
    510                    needed. */
    511                 for(i = 0; i < size; i++) {
    512                         elem = PyTuple_GetItem(arg, i);
    513                         newelem = SplitObj(elem);
    514                         if (!newelem) {
    515                                 Py_XDECREF(result);
    516                                 return NULL;
    517                         }
    518                         if (!result) {
    519                                 int k;
    520                                 if (newelem == elem) {
    521                                         Py_DECREF(newelem);
    522                                         continue;
    523                                 }
    524                                 result = PyTuple_New(size);
    525                                 if (!result)
    526                                         return NULL;
    527                                 for(k = 0; k < i; k++) {
    528                                         elem = PyTuple_GetItem(arg, k);
    529                                         Py_INCREF(elem);
    530                                         PyTuple_SetItem(result, k, elem);
    531                                 }
    532                         }
    533                         PyTuple_SetItem(result, i, newelem);
    534                 }
    535                 if (result)
    536                         return result;
    537                 /* Fall through, returning arg. */
    538         }
    539         else if (PyString_Check(arg)) {
    540                 int argc;
    541                 char **argv;
    542                 char *list = PyString_AsString(arg);
    543 
    544                 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
    545                         Py_INCREF(arg);
    546                         return arg;
    547                 }
    548                 Tcl_Free(FREECAST argv);
    549                 if (argc > 1)
    550                         return Split(PyString_AsString(arg));
    551                 /* Fall through, returning arg. */
    552         }
    553         Py_INCREF(arg);
    554         return arg;
    555 }
    556 
     507    if (PyTuple_Check(arg)) {
     508        int i, size;
     509        PyObject *elem, *newelem, *result;
     510
     511        size = PyTuple_Size(arg);
     512        result = NULL;
     513        /* Recursively invoke SplitObj for all tuple items.
     514           If this does not return a new object, no action is
     515           needed. */
     516        for(i = 0; i < size; i++) {
     517            elem = PyTuple_GetItem(arg, i);
     518            newelem = SplitObj(elem);
     519            if (!newelem) {
     520                Py_XDECREF(result);
     521                return NULL;
     522            }
     523            if (!result) {
     524                int k;
     525                if (newelem == elem) {
     526                    Py_DECREF(newelem);
     527                    continue;
     528                }
     529                result = PyTuple_New(size);
     530                if (!result)
     531                    return NULL;
     532                for(k = 0; k < i; k++) {
     533                    elem = PyTuple_GetItem(arg, k);
     534                    Py_INCREF(elem);
     535                    PyTuple_SetItem(result, k, elem);
     536                }
     537            }
     538            PyTuple_SetItem(result, i, newelem);
     539        }
     540        if (result)
     541            return result;
     542        /* Fall through, returning arg. */
     543    }
     544    else if (PyString_Check(arg)) {
     545        int argc;
     546        char **argv;
     547        char *list = PyString_AsString(arg);
     548
     549        if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
     550            Py_INCREF(arg);
     551            return arg;
     552        }
     553        Tcl_Free(FREECAST argv);
     554        if (argc > 1)
     555            return Split(PyString_AsString(arg));
     556        /* Fall through, returning arg. */
     557    }
     558    else if (PyUnicode_Check(arg)) {
     559        int argc;
     560        char **argv;
     561        char *list;
     562        PyObject *s = PyUnicode_AsUTF8String(arg);
     563
     564        if (s == NULL) {
     565            Py_INCREF(arg);
     566            return arg;
     567        }
     568        list = PyString_AsString(s);
     569
     570        if (list == NULL ||
     571            Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
     572            Py_DECREF(s);
     573            Py_INCREF(arg);
     574            return arg;
     575        }
     576        Tcl_Free(FREECAST argv);
     577        if (argc > 1) {
     578            PyObject *v = Split(list);
     579            Py_DECREF(s);
     580            return v;
     581        }
     582        Py_DECREF(s);
     583        /* Fall through, returning arg. */
     584    }
     585    Py_INCREF(arg);
     586    return arg;
     587}
    557588
    558589
     
    563594Tcl_AppInit(Tcl_Interp *interp)
    564595{
    565         Tk_Window main;
    566         const char * _tkinter_skip_tk_init;
    567 
    568         if (Tcl_Init(interp) == TCL_ERROR) {
    569                 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
    570                 return TCL_ERROR;
    571         }
    572         _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
    573         if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
    574                 main = Tk_MainWindow(interp);
    575                 if (Tk_Init(interp) == TCL_ERROR) {
    576                         PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
    577                         return TCL_ERROR;
    578                 }
    579         }
    580         return TCL_OK;
     596    const char * _tkinter_skip_tk_init;
     597
     598    if (Tcl_Init(interp) == TCL_ERROR) {
     599        PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
     600        return TCL_ERROR;
     601    }
     602
     603    _tkinter_skip_tk_init = Tcl_GetVar(interp,
     604                    "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
     605    if (_tkinter_skip_tk_init != NULL &&
     606                    strcmp(_tkinter_skip_tk_init, "1") == 0) {
     607        return TCL_OK;
     608    }
     609
     610#ifdef TKINTER_PROTECT_LOADTK
     611    if (tk_load_failed) {
     612        PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
     613        return TCL_ERROR;
     614    }
     615#endif
     616
     617    if (Tk_Init(interp) == TCL_ERROR) {
     618#ifdef TKINTER_PROTECT_LOADTK
     619        tk_load_failed = 1;
     620#endif
     621        PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
     622        return TCL_ERROR;
     623    }
     624
     625    return TCL_OK;
    581626}
    582627#endif /* !WITH_APPINIT */
    583 
    584628
    585629
     
    595639static TkappObject *
    596640Tkapp_New(char *screenName, char *baseName, char *className,
    597           int interactive, int wantobjects, int wantTk, int sync, char *use)
    598 {
    599         TkappObject *v;
    600         char *argv0;
    601 
    602         v = PyObject_New(TkappObject, &Tkapp_Type);
    603         if (v == NULL)
    604                 return NULL;
    605 
    606         v->interp = Tcl_CreateInterp();
    607         v->wantobjects = wantobjects;
    608         v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
    609                                     TCL_GLOBAL_ONLY) != NULL;
    610         v->thread_id = Tcl_GetCurrentThread();
    611         v->dispatching = 0;
     641          int interactive, int wantobjects, int wantTk, int sync, char *use)
     642{
     643    TkappObject *v;
     644    char *argv0;
     645
     646    v = PyObject_New(TkappObject, &Tkapp_Type);
     647    if (v == NULL)
     648        return NULL;
     649
     650    v->interp = Tcl_CreateInterp();
     651    v->wantobjects = wantobjects;
     652    v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
     653                                TCL_GLOBAL_ONLY) != NULL;
     654    v->thread_id = Tcl_GetCurrentThread();
     655    v->dispatching = 0;
    612656
    613657#ifndef TCL_THREADS
    614         if (v->threaded) {
    615             PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
    616             Py_DECREF(v);
    617             return 0;
    618         }
     658    if (v->threaded) {
     659        PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
     660        Py_DECREF(v);
     661        return 0;
     662    }
    619663#endif
    620664#ifdef WITH_THREAD
    621         if (v->threaded && tcl_lock) {
    622             /* If Tcl is threaded, we don't need the lock. */
    623             PyThread_free_lock(tcl_lock);
    624             tcl_lock = NULL;
    625         }
    626 #endif
    627 
    628         v->BooleanType = Tcl_GetObjType("boolean");
    629         v->ByteArrayType = Tcl_GetObjType("bytearray");
    630         v->DoubleType = Tcl_GetObjType("double");
    631         v->IntType = Tcl_GetObjType("int");
    632         v->ListType = Tcl_GetObjType("list");
    633         v->ProcBodyType = Tcl_GetObjType("procbody");
    634         v->StringType = Tcl_GetObjType("string");
    635 
    636         /* Delete the 'exit' command, which can screw things up */
    637         Tcl_DeleteCommand(v->interp, "exit");
    638 
    639         if (screenName != NULL)
    640                 Tcl_SetVar2(v->interp, "env", "DISPLAY",
    641                             screenName, TCL_GLOBAL_ONLY);
    642 
    643         if (interactive)
    644                 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
    645         else
    646                 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
    647 
    648         /* This is used to get the application class for Tk 4.1 and up */
    649         argv0 = (char*)ckalloc(strlen(className) + 1);
    650         if (!argv0) {
    651                 PyErr_NoMemory();
    652                 Py_DECREF(v);
    653                 return NULL;
    654         }
    655 
    656         strcpy(argv0, className);
    657         if (isupper(Py_CHARMASK(argv0[0])))
    658                 argv0[0] = tolower(Py_CHARMASK(argv0[0]));
    659         Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
    660         ckfree(argv0);
    661 
    662         if (! wantTk) {
    663             Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
    664         }
    665 
    666         /* some initial arguments need to be in argv */
    667         if (sync || use) {
    668                 char *args;
    669                 int len = 0;
    670 
    671                 if (sync)
    672                         len += sizeof "-sync";
    673                 if (use)
    674                         len += strlen(use) + sizeof "-use ";
    675 
    676                 args = (char*)ckalloc(len);
    677                 if (!args) {
    678                         PyErr_NoMemory();
    679                         Py_DECREF(v);
    680                         return NULL;
    681                 }
    682 
    683                 args[0] = '\0';
    684                 if (sync)
    685                         strcat(args, "-sync");
    686                 if (use) {
    687                         if (sync)
    688                                 strcat(args, " ");
    689                         strcat(args, "-use ");
    690                         strcat(args, use);
    691                 }
    692 
    693                 Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
    694                 ckfree(args);
    695         }
    696 
    697         if (Tcl_AppInit(v->interp) != TCL_OK) {
    698                 PyObject *result = Tkinter_Error((PyObject *)v);
    699                 Py_DECREF((PyObject *)v);
    700                 return (TkappObject *)result;
    701         }
    702 
    703         EnableEventHook();
    704 
    705         return v;
    706 }
    707 
    708 
     665    if (v->threaded && tcl_lock) {
     666        /* If Tcl is threaded, we don't need the lock. */
     667        PyThread_free_lock(tcl_lock);
     668        tcl_lock = NULL;
     669    }
     670#endif
     671
     672    v->BooleanType = Tcl_GetObjType("boolean");
     673    v->ByteArrayType = Tcl_GetObjType("bytearray");
     674    v->DoubleType = Tcl_GetObjType("double");
     675    v->IntType = Tcl_GetObjType("int");
     676    v->ListType = Tcl_GetObjType("list");
     677    v->ProcBodyType = Tcl_GetObjType("procbody");
     678    v->StringType = Tcl_GetObjType("string");
     679
     680    /* Delete the 'exit' command, which can screw things up */
     681    Tcl_DeleteCommand(v->interp, "exit");
     682
     683    if (screenName != NULL)
     684        Tcl_SetVar2(v->interp, "env", "DISPLAY",
     685                    screenName, TCL_GLOBAL_ONLY);
     686
     687    if (interactive)
     688        Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
     689    else
     690        Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
     691
     692    /* This is used to get the application class for Tk 4.1 and up */
     693    argv0 = (char*)ckalloc(strlen(className) + 1);
     694    if (!argv0) {
     695        PyErr_NoMemory();
     696        Py_DECREF(v);
     697        return NULL;
     698    }
     699
     700    strcpy(argv0, className);
     701    if (Py_ISUPPER(Py_CHARMASK(argv0[0])))
     702        argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0]));
     703    Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
     704    ckfree(argv0);
     705
     706    if (! wantTk) {
     707        Tcl_SetVar(v->interp,
     708                        "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
     709    }
     710#ifdef TKINTER_PROTECT_LOADTK
     711    else if (tk_load_failed) {
     712        Tcl_SetVar(v->interp,
     713                        "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
     714    }
     715#endif
     716
     717    /* some initial arguments need to be in argv */
     718    if (sync || use) {
     719        char *args;
     720        int len = 0;
     721
     722        if (sync)
     723            len += sizeof "-sync";
     724        if (use)
     725            len += strlen(use) + sizeof "-use ";
     726
     727        args = (char*)ckalloc(len);
     728        if (!args) {
     729            PyErr_NoMemory();
     730            Py_DECREF(v);
     731            return NULL;
     732        }
     733
     734        args[0] = '\0';
     735        if (sync)
     736            strcat(args, "-sync");
     737        if (use) {
     738            if (sync)
     739                strcat(args, " ");
     740            strcat(args, "-use ");
     741            strcat(args, use);
     742        }
     743
     744        Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
     745        ckfree(args);
     746    }
     747
     748    if (Tcl_AppInit(v->interp) != TCL_OK) {
     749        PyObject *result = Tkinter_Error((PyObject *)v);
     750#ifdef TKINTER_PROTECT_LOADTK
     751        if (wantTk) {
     752            const char *_tkinter_tk_failed;
     753            _tkinter_tk_failed = Tcl_GetVar(v->interp,
     754                            "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
     755
     756            if ( _tkinter_tk_failed != NULL &&
     757                            strcmp(_tkinter_tk_failed, "1") == 0) {
     758                tk_load_failed = 1;
     759            }
     760        }
     761#endif
     762        Py_DECREF((PyObject *)v);
     763        return (TkappObject *)result;
     764    }
     765
     766    EnableEventHook();
     767
     768    return v;
     769}
     770
     771
     772#ifdef WITH_THREAD
    709773static void
    710774Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
    711                 Tcl_Condition *cond, Tcl_Mutex *mutex)
    712 {
    713         Py_BEGIN_ALLOW_THREADS;
    714         Tcl_MutexLock(mutex);
    715         Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
    716         Tcl_ThreadAlert(self->thread_id);
    717         Tcl_ConditionWait(cond, mutex, NULL);
    718         Tcl_MutexUnlock(mutex);
    719         Py_END_ALLOW_THREADS
    720 }
    721 
     775                Tcl_Condition *cond, Tcl_Mutex *mutex)
     776{
     777    Py_BEGIN_ALLOW_THREADS;
     778    Tcl_MutexLock(mutex);
     779    Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
     780    Tcl_ThreadAlert(self->thread_id);
     781    Tcl_ConditionWait(cond, mutex, NULL);
     782    Tcl_MutexUnlock(mutex);
     783    Py_END_ALLOW_THREADS
     784}
     785#endif
    722786
    723787
     
    725789
    726790typedef struct {
    727         PyObject_HEAD
    728         Tcl_Obj *value;
    729         PyObject *string; /* This cannot cause cycles. */
     791    PyObject_HEAD
     792    Tcl_Obj *value;
     793    PyObject *string; /* This cannot cause cycles. */
    730794} PyTclObject;
    731795
    732796staticforward PyTypeObject PyTclObject_Type;
    733 #define PyTclObject_Check(v)    ((v)->ob_type == &PyTclObject_Type)
     797#define PyTclObject_Check(v)    ((v)->ob_type == &PyTclObject_Type)
    734798
    735799static PyObject *
    736800newPyTclObject(Tcl_Obj *arg)
    737801{
    738         PyTclObject *self;
    739         self = PyObject_New(PyTclObject, &PyTclObject_Type);
    740         if (self == NULL)
    741                 return NULL;
    742         Tcl_IncrRefCount(arg);
    743         self->value = arg;
    744         self->string = NULL;
    745         return (PyObject*)self;
     802    PyTclObject *self;
     803    self = PyObject_New(PyTclObject, &PyTclObject_Type);
     804    if (self == NULL)
     805        return NULL;
     806    Tcl_IncrRefCount(arg);
     807    self->value = arg;
     808    self->string = NULL;
     809    return (PyObject*)self;
    746810}
    747811
     
    749813PyTclObject_dealloc(PyTclObject *self)
    750814{
    751         Tcl_DecrRefCount(self->value);
    752         Py_XDECREF(self->string);
    753         PyObject_Del(self);
     815    Tcl_DecrRefCount(self->value);
     816    Py_XDECREF(self->string);
     817    PyObject_Del(self);
    754818}
    755819
     
    757821PyTclObject_str(PyTclObject *self)
    758822{
    759         if (self->string && PyString_Check(self->string)) {
    760                 Py_INCREF(self->string);
    761                 return self->string;
    762         }
    763         /* XXX Could cache value if it is an ASCII string. */
    764         return PyString_FromString(Tcl_GetString(self->value));
     823    if (self->string && PyString_Check(self->string)) {
     824        Py_INCREF(self->string);
     825        return self->string;
     826    }
     827    /* XXX Could cache value if it is an ASCII string. */
     828    return PyString_FromString(Tcl_GetString(self->value));
    765829}
    766830
     
    768832PyTclObject_TclString(PyObject *self)
    769833{
    770         return Tcl_GetString(((PyTclObject*)self)->value);
     834    return Tcl_GetString(((PyTclObject*)self)->value);
    771835}
    772836
    773837/* Like _str, but create Unicode if necessary. */
    774 PyDoc_STRVAR(PyTclObject_string__doc__, 
     838PyDoc_STRVAR(PyTclObject_string__doc__,
    775839"the string representation of this object, either as string or Unicode");
    776840
     
    778842PyTclObject_string(PyTclObject *self, void *ignored)
    779843{
    780         char *s;
    781         int i, len;
    782         if (!self->string) {
    783                 s = Tcl_GetStringFromObj(self->value, &len);
    784                 for (i = 0; i < len; i++)
    785                         if (s[i] & 0x80)
    786                                 break;
     844    char *s;
     845    int i, len;
     846    if (!self->string) {
     847        s = Tcl_GetStringFromObj(self->value, &len);
     848        for (i = 0; i < len; i++)
     849            if (s[i] & 0x80)
     850                break;
    787851#ifdef Py_USING_UNICODE
    788                 if (i == len)
    789                         /* It is an ASCII string. */
    790                         self->string = PyString_FromStringAndSize(s, len);
    791                 else {
    792                         self->string = PyUnicode_DecodeUTF8(s, len, "strict");
    793                         if (!self->string) {
    794                                 PyErr_Clear();
    795                                 self->string = PyString_FromStringAndSize(s, len);
    796                         }
    797                 }
     852        if (i == len)
     853            /* It is an ASCII string. */
     854            self->string = PyString_FromStringAndSize(s, len);
     855        else {
     856            self->string = PyUnicode_DecodeUTF8(s, len, "strict");
     857            if (!self->string) {
     858                PyErr_Clear();
     859                self->string = PyString_FromStringAndSize(s, len);
     860            }
     861        }
    798862#else
    799                 self->string = PyString_FromStringAndSize(s, len);
    800 #endif
    801                 if (!self->string)
    802                         return NULL;
    803         }
    804         Py_INCREF(self->string);
    805         return self->string;
     863        self->string = PyString_FromStringAndSize(s, len);
     864#endif
     865        if (!self->string)
     866            return NULL;
     867    }
     868    Py_INCREF(self->string);
     869    return self->string;
    806870}
    807871
     
    812876PyTclObject_unicode(PyTclObject *self, void *ignored)
    813877{
    814         char *s;
    815         int len;
    816         if (self->string && PyUnicode_Check(self->string)) {
    817                 Py_INCREF(self->string);
    818                 return self->string;
    819         }
    820         /* XXX Could chache result if it is non-ASCII. */
    821         s = Tcl_GetStringFromObj(self->value, &len);
    822         return PyUnicode_DecodeUTF8(s, len, "strict");
     878    char *s;
     879    int len;
     880    if (self->string && PyUnicode_Check(self->string)) {
     881        Py_INCREF(self->string);
     882        return self->string;
     883    }
     884    /* XXX Could chache result if it is non-ASCII. */
     885    s = Tcl_GetStringFromObj(self->value, &len);
     886    return PyUnicode_DecodeUTF8(s, len, "strict");
    823887}
    824888#endif
     
    827891PyTclObject_repr(PyTclObject *self)
    828892{
    829         char buf[50];
    830         PyOS_snprintf(buf, 50, "<%s object at %p>",
    831                       self->value->typePtr->name, self->value);
    832         return PyString_FromString(buf);
     893    char buf[50];
     894    PyOS_snprintf(buf, 50, "<%s object at %p>",
     895                  self->value->typePtr->name, self->value);
     896    return PyString_FromString(buf);
    833897}
    834898
     
    836900PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
    837901{
    838         int res;
    839         res = strcmp(Tcl_GetString(self->value),
    840                      Tcl_GetString(other->value));
    841         if (res < 0) return -1;
    842         if (res > 0) return 1;
    843         return 0;
     902    int res;
     903    res = strcmp(Tcl_GetString(self->value),
     904                 Tcl_GetString(other->value));
     905    if (res < 0) return -1;
     906    if (res > 0) return 1;
     907    return 0;
    844908}
    845909
     
    849913get_typename(PyTclObject* obj, void* ignored)
    850914{
    851         return PyString_FromString(obj->value->typePtr->name);
     915    return PyString_FromString(obj->value->typePtr->name);
    852916}
    853917
    854918
    855919static PyGetSetDef PyTclObject_getsetlist[] = {
    856         {"typename", (getter)get_typename, NULL, get_typename__doc__},
    857         {"string", (getter)PyTclObject_string, NULL,
    858         PyTclObject_string__doc__},
    859         {0},
     920    {"typename", (getter)get_typename, NULL, get_typename__doc__},
     921    {"string", (getter)PyTclObject_string, NULL,
     922    PyTclObject_string__doc__},
     923    {0},
    860924};
    861925
    862926static PyMethodDef PyTclObject_methods[] = {
    863927#ifdef Py_USING_UNICODE
    864         {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
    865         PyTclObject_unicode__doc__},
    866 #endif
    867         {0}
     928    {"__unicode__",     (PyCFunction)PyTclObject_unicode, METH_NOARGS,
     929    PyTclObject_unicode__doc__},
     930#endif
     931    {0}
    868932};
    869933
    870934statichere PyTypeObject PyTclObject_Type = {
    871         PyObject_HEAD_INIT(NULL)
    872         0,                      /*ob_size*/
    873         "_tkinter.Tcl_Obj",             /*tp_name*/
    874         sizeof(PyTclObject),    /*tp_basicsize*/
    875         0,                      /*tp_itemsize*/
    876         /* methods */
    877         (destructor)PyTclObject_dealloc, /*tp_dealloc*/
    878         0,                      /*tp_print*/
    879         0,                      /*tp_getattr*/
    880         0,                      /*tp_setattr*/
    881         (cmpfunc)PyTclObject_cmp,       /*tp_compare*/
    882         (reprfunc)PyTclObject_repr,     /*tp_repr*/
    883         0,                      /*tp_as_number*/
    884         0,                      /*tp_as_sequence*/
    885         0,                      /*tp_as_mapping*/
    886         0,                      /*tp_hash*/
    887         0,                      /*tp_call*/
    888         (reprfunc)PyTclObject_str,        /*tp_str*/
    889         PyObject_GenericGetAttr,/*tp_getattro*/
    890         0,                      /*tp_setattro*/
    891         0,                      /*tp_as_buffer*/
    892         Py_TPFLAGS_DEFAULT,     /*tp_flags*/
    893         0,                      /*tp_doc*/
    894         0,                      /*tp_traverse*/
    895         0,                      /*tp_clear*/
    896         0,                      /*tp_richcompare*/
    897         0,                      /*tp_weaklistoffset*/
    898         0,                      /*tp_iter*/
    899         0,                      /*tp_iternext*/
    900         PyTclObject_methods,    /*tp_methods*/
    901         0,                      /*tp_members*/
    902         PyTclObject_getsetlist, /*tp_getset*/
    903         0,                      /*tp_base*/
    904         0,                      /*tp_dict*/
    905         0,                      /*tp_descr_get*/
    906         0,                      /*tp_descr_set*/
    907         0,                      /*tp_dictoffset*/
    908         0,                      /*tp_init*/
    909         0,                      /*tp_alloc*/
    910         0,                      /*tp_new*/
    911         0,                      /*tp_free*/
    912         0,                      /*tp_is_gc*/
     935    PyObject_HEAD_INIT(NULL)
     936    0,                          /*ob_size*/
     937    "_tkinter.Tcl_Obj",                 /*tp_name*/
     938    sizeof(PyTclObject),        /*tp_basicsize*/
     939    0,                          /*tp_itemsize*/
     940    /* methods */
     941    (destructor)PyTclObject_dealloc, /*tp_dealloc*/
     942    0,                          /*tp_print*/
     943    0,                          /*tp_getattr*/
     944    0,                          /*tp_setattr*/
     945    (cmpfunc)PyTclObject_cmp,           /*tp_compare*/
     946    (reprfunc)PyTclObject_repr,         /*tp_repr*/
     947    0,                          /*tp_as_number*/
     948    0,                          /*tp_as_sequence*/
     949    0,                          /*tp_as_mapping*/
     950    0,                          /*tp_hash*/
     951    0,                      /*tp_call*/
     952    (reprfunc)PyTclObject_str,        /*tp_str*/
     953    PyObject_GenericGetAttr,/*tp_getattro*/
     954    0,                      /*tp_setattro*/
     955    0,                      /*tp_as_buffer*/
     956    Py_TPFLAGS_DEFAULT,     /*tp_flags*/
     957    0,                      /*tp_doc*/
     958    0,                      /*tp_traverse*/
     959    0,                      /*tp_clear*/
     960    0,                      /*tp_richcompare*/
     961    0,                      /*tp_weaklistoffset*/
     962    0,                      /*tp_iter*/
     963    0,                      /*tp_iternext*/
     964    PyTclObject_methods,    /*tp_methods*/
     965    0,                          /*tp_members*/
     966    PyTclObject_getsetlist, /*tp_getset*/
     967    0,                      /*tp_base*/
     968    0,                      /*tp_dict*/
     969    0,                      /*tp_descr_get*/
     970    0,                      /*tp_descr_set*/
     971    0,                      /*tp_dictoffset*/
     972    0,                      /*tp_init*/
     973    0,                      /*tp_alloc*/
     974    0,                      /*tp_new*/
     975    0,                      /*tp_free*/
     976    0,                      /*tp_is_gc*/
    913977};
    914978
     
    916980AsObj(PyObject *value)
    917981{
    918         Tcl_Obj *result;
    919 
    920         if (PyString_Check(value))
    921                 return Tcl_NewStringObj(PyString_AS_STRING(value),
    922                                         PyString_GET_SIZE(value));
    923         else if (PyBool_Check(value))
    924                 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
    925         else if (PyInt_Check(value))
    926                 return Tcl_NewLongObj(PyInt_AS_LONG(value));
    927         else if (PyFloat_Check(value))
    928                 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
    929         else if (PyTuple_Check(value)) {
    930                 Tcl_Obj **argv = (Tcl_Obj**)
    931                         ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
    932                 int i;
    933                 if(!argv)
    934                   return 0;
    935                 for(i=0;i<PyTuple_Size(value);i++)
    936                   argv[i] = AsObj(PyTuple_GetItem(value,i));
    937                 result = Tcl_NewListObj(PyTuple_Size(value), argv);
    938                 ckfree(FREECAST argv);
    939                 return result;
    940         }
     982    Tcl_Obj *result;
     983
     984    if (PyString_Check(value))
     985        return Tcl_NewStringObj(PyString_AS_STRING(value),
     986                                PyString_GET_SIZE(value));
     987    else if (PyBool_Check(value))
     988        return Tcl_NewBooleanObj(PyObject_IsTrue(value));
     989    else if (PyInt_Check(value))
     990        return Tcl_NewLongObj(PyInt_AS_LONG(value));
     991    else if (PyFloat_Check(value))
     992        return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
     993    else if (PyTuple_Check(value)) {
     994        Tcl_Obj **argv;
     995        Py_ssize_t size, i;
     996
     997        size = PyTuple_Size(value);
     998        if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
     999            PyErr_SetString(PyExc_OverflowError, "tuple is too long");
     1000            return NULL;
     1001        }
     1002        argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *));
     1003        if(!argv)
     1004          return 0;
     1005        for (i = 0; i < size; i++)
     1006          argv[i] = AsObj(PyTuple_GetItem(value,i));
     1007        result = Tcl_NewListObj(PyTuple_Size(value), argv);
     1008        ckfree(FREECAST argv);
     1009        return result;
     1010    }
    9411011#ifdef Py_USING_UNICODE
    942         else if (PyUnicode_Check(value)) {
    943                 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
    944                 Py_ssize_t size = PyUnicode_GET_SIZE(value);
    945                 /* This #ifdef assumes that Tcl uses UCS-2.
    946                    See TCL_UTF_MAX test above. */
     1012    else if (PyUnicode_Check(value)) {
     1013        Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
     1014        Py_ssize_t size = PyUnicode_GET_SIZE(value);
     1015        /* This #ifdef assumes that Tcl uses UCS-2.
     1016           See TCL_UTF_MAX test above. */
    9471017#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
    948                 Tcl_UniChar *outbuf = NULL;
    949                 Py_ssize_t i;
    950                 size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
    951                 if (allocsize >= size)
    952                         outbuf = (Tcl_UniChar*)ckalloc(allocsize);
    953                 /* Else overflow occurred, and we take the next exit */
    954                 if (!outbuf) {
    955                         PyErr_NoMemory();
    956                         return NULL;
    957                 }
    958                 for (i = 0; i < size; i++) {
    959                         if (inbuf[i] >= 0x10000) {
    960                                 /* Tcl doesn't do UTF-16, yet. */
    961                                 PyErr_SetString(PyExc_ValueError,
    962                                                 "unsupported character");
    963                                 ckfree(FREECAST outbuf);
    964                                 return NULL;
    965                         }
    966                         outbuf[i] = inbuf[i];
    967                 }
    968                 result = Tcl_NewUnicodeObj(outbuf, size);
    969                 ckfree(FREECAST outbuf);
    970                 return result;
     1018        Tcl_UniChar *outbuf = NULL;
     1019        Py_ssize_t i;
     1020        size_t allocsize;
     1021        if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) {
     1022            PyErr_SetString(PyExc_OverflowError, "string is too long");
     1023            return NULL;
     1024        }
     1025        allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
     1026        if (allocsize >= size)
     1027            outbuf = (Tcl_UniChar*)ckalloc(allocsize);
     1028        /* Else overflow occurred, and we take the next exit */
     1029        if (!outbuf) {
     1030            PyErr_NoMemory();
     1031            return NULL;
     1032        }
     1033        for (i = 0; i < size; i++) {
     1034            if (inbuf[i] >= 0x10000) {
     1035                /* Tcl doesn't do UTF-16, yet. */
     1036                PyErr_Format(Tkinter_TclError,
     1037                             "character U+%x is above the range "
     1038                             "(U+0000-U+FFFF) allowed by Tcl",
     1039                             (int)inbuf[i]);
     1040                ckfree(FREECAST outbuf);
     1041                return NULL;
     1042            }
     1043            outbuf[i] = inbuf[i];
     1044        }
     1045        result = Tcl_NewUnicodeObj(outbuf, size);
     1046        ckfree(FREECAST outbuf);
     1047        return result;
    9711048#else
    972                 return Tcl_NewUnicodeObj(inbuf, size);
    973 #endif
    974 
    975         }
    976 #endif
    977         else if(PyTclObject_Check(value)) {
    978                 Tcl_Obj *v = ((PyTclObject*)value)->value;
    979                 Tcl_IncrRefCount(v);
    980                 return v;
    981         }
    982         else {
    983                 PyObject *v = PyObject_Str(value);
    984                 if (!v)
    985                         return 0;
    986                 result = AsObj(v);
    987                 Py_DECREF(v);
    988                 return result;
    989         }
     1049        return Tcl_NewUnicodeObj(inbuf, size);
     1050#endif
     1051
     1052    }
     1053#endif
     1054    else if(PyTclObject_Check(value)) {
     1055        Tcl_Obj *v = ((PyTclObject*)value)->value;
     1056        Tcl_IncrRefCount(v);
     1057        return v;
     1058    }
     1059    else {
     1060        PyObject *v = PyObject_Str(value);
     1061        if (!v)
     1062            return 0;
     1063        result = AsObj(v);
     1064        Py_DECREF(v);
     1065        return result;
     1066    }
    9901067}
    9911068
     
    9931070FromObj(PyObject* tkapp, Tcl_Obj *value)
    9941071{
    995         PyObject *result = NULL;
    996         TkappObject *app = (TkappObject*)tkapp;
    997 
    998         if (value->typePtr == NULL) {
    999                 /* If the result contains any bytes with the top bit set,
    1000                    it's UTF-8 and we should decode it to Unicode */
     1072    PyObject *result = NULL;
     1073    TkappObject *app = (TkappObject*)tkapp;
     1074
     1075    if (value->typePtr == NULL) {
     1076        /* If the result contains any bytes with the top bit set,
     1077           it's UTF-8 and we should decode it to Unicode */
    10011078#ifdef Py_USING_UNICODE
    1002                 int i;
    1003                 char *s = value->bytes;
    1004                 int len = value->length;
    1005                 for (i = 0; i < len; i++) {
    1006                         if (value->bytes[i] & 0x80)
    1007                                 break;
    1008                 }
    1009 
    1010                 if (i == value->length)
    1011                         result = PyString_FromStringAndSize(s, len);
    1012                 else {
    1013                         /* Convert UTF-8 to Unicode string */
    1014                         result = PyUnicode_DecodeUTF8(s, len, "strict");
    1015                         if (result == NULL) {
    1016                                 PyErr_Clear();
    1017                                 result = PyString_FromStringAndSize(s, len);
    1018                         }
    1019                 }
     1079        int i;
     1080        char *s = value->bytes;
     1081        int len = value->length;
     1082        for (i = 0; i < len; i++) {
     1083            if (value->bytes[i] & 0x80)
     1084                break;
     1085        }
     1086
     1087        if (i == value->length)
     1088            result = PyString_FromStringAndSize(s, len);
     1089        else {
     1090            /* Convert UTF-8 to Unicode string */
     1091            result = PyUnicode_DecodeUTF8(s, len, "strict");
     1092            if (result == NULL) {
     1093                PyErr_Clear();
     1094                result = PyString_FromStringAndSize(s, len);
     1095            }
     1096        }
    10201097#else
    1021                 result = PyString_FromStringAndSize(value->bytes, value->length);
    1022 #endif
    1023                 return result;
    1024         }
    1025 
    1026         if (value->typePtr == app->BooleanType) {
    1027                 result = value->internalRep.longValue ? Py_True : Py_False;
    1028                 Py_INCREF(result);
    1029                 return result;
    1030         }
    1031 
    1032         if (value->typePtr == app->ByteArrayType) {
    1033                 int size;
    1034                 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
    1035                 return PyString_FromStringAndSize(data, size);
    1036         }
    1037 
    1038         if (value->typePtr == app->DoubleType) {
    1039                 return PyFloat_FromDouble(value->internalRep.doubleValue);
    1040         }
    1041 
    1042         if (value->typePtr == app->IntType) {
    1043                 return PyInt_FromLong(value->internalRep.longValue);
    1044         }
    1045 
    1046         if (value->typePtr == app->ListType) {
    1047                 int size;
    1048                 int i, status;
    1049                 PyObject *elem;
    1050                 Tcl_Obj *tcl_elem;
    1051 
    1052                 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
    1053                 if (status == TCL_ERROR)
    1054                         return Tkinter_Error(tkapp);
    1055                 result = PyTuple_New(size);
    1056                 if (!result)
    1057                         return NULL;
    1058                 for (i = 0; i < size; i++) {
    1059                         status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
    1060                                                   value, i, &tcl_elem);
    1061                         if (status == TCL_ERROR) {
    1062                                 Py_DECREF(result);
    1063                                 return Tkinter_Error(tkapp);
    1064                         }
    1065                         elem = FromObj(tkapp, tcl_elem);
    1066                         if (!elem) {
    1067                                 Py_DECREF(result);
    1068                                 return NULL;
    1069                         }
    1070                         PyTuple_SetItem(result, i, elem);
    1071                 }
    1072                 return result;
    1073         }
    1074 
    1075         if (value->typePtr == app->ProcBodyType) {
    1076           /* fall through: return tcl object. */
    1077         }
    1078 
    1079         if (value->typePtr == app->StringType) {
     1098        result = PyString_FromStringAndSize(value->bytes, value->length);
     1099#endif
     1100        return result;
     1101    }
     1102
     1103    if (value->typePtr == app->BooleanType) {
     1104        result = value->internalRep.longValue ? Py_True : Py_False;
     1105        Py_INCREF(result);
     1106        return result;
     1107    }
     1108
     1109    if (value->typePtr == app->ByteArrayType) {
     1110        int size;
     1111        char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
     1112        return PyString_FromStringAndSize(data, size);
     1113    }
     1114
     1115    if (value->typePtr == app->DoubleType) {
     1116        return PyFloat_FromDouble(value->internalRep.doubleValue);
     1117    }
     1118
     1119    if (value->typePtr == app->IntType) {
     1120        return PyInt_FromLong(value->internalRep.longValue);
     1121    }
     1122
     1123    if (value->typePtr == app->ListType) {
     1124        int size;
     1125        int i, status;
     1126        PyObject *elem;
     1127        Tcl_Obj *tcl_elem;
     1128
     1129        status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
     1130        if (status == TCL_ERROR)
     1131            return Tkinter_Error(tkapp);
     1132        result = PyTuple_New(size);
     1133        if (!result)
     1134            return NULL;
     1135        for (i = 0; i < size; i++) {
     1136            status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
     1137                                      value, i, &tcl_elem);
     1138            if (status == TCL_ERROR) {
     1139                Py_DECREF(result);
     1140                return Tkinter_Error(tkapp);
     1141            }
     1142            elem = FromObj(tkapp, tcl_elem);
     1143            if (!elem) {
     1144                Py_DECREF(result);
     1145                return NULL;
     1146            }
     1147            PyTuple_SetItem(result, i, elem);
     1148        }
     1149        return result;
     1150    }
     1151
     1152    if (value->typePtr == app->ProcBodyType) {
     1153      /* fall through: return tcl object. */
     1154    }
     1155
     1156    if (value->typePtr == app->StringType) {
    10801157#ifdef Py_USING_UNICODE
    10811158#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
    1082                 PyObject *result;
    1083                 int size;
    1084                 Tcl_UniChar *input;
    1085                 Py_UNICODE *output;
    1086 
    1087                 size = Tcl_GetCharLength(value);
    1088                 result = PyUnicode_FromUnicode(NULL, size);
    1089                 if (!result)
    1090                         return NULL;
    1091                 input = Tcl_GetUnicode(value);
    1092                 output = PyUnicode_AS_UNICODE(result);
    1093                 while (size--)
    1094                         *output++ = *input++;
    1095                 return result;
     1159        PyObject *result;
     1160        int size;
     1161        Tcl_UniChar *input;
     1162        Py_UNICODE *output;
     1163
     1164        size = Tcl_GetCharLength(value);
     1165        result = PyUnicode_FromUnicode(NULL, size);
     1166        if (!result)
     1167            return NULL;
     1168        input = Tcl_GetUnicode(value);
     1169        output = PyUnicode_AS_UNICODE(result);
     1170        while (size--)
     1171            *output++ = *input++;
     1172        return result;
    10961173#else
    1097                 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
    1098                                              Tcl_GetCharLength(value));
     1174        return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
     1175                                     Tcl_GetCharLength(value));
    10991176#endif
    11001177#else
    1101                 int size;
    1102                 char *c;
    1103                 c = Tcl_GetStringFromObj(value, &size);
    1104                 return PyString_FromStringAndSize(c, size);
    1105 #endif
    1106         }
    1107 
    1108         return newPyTclObject(value);
    1109 }
    1110 
     1178        int size;
     1179        char *c;
     1180        c = Tcl_GetStringFromObj(value, &size);
     1181        return PyString_FromStringAndSize(c, size);
     1182#endif
     1183    }
     1184
     1185    return newPyTclObject(value);
     1186}
     1187
     1188#ifdef WITH_THREAD
    11111189/* This mutex synchronizes inter-thread command calls. */
    1112 
    11131190TCL_DECLARE_MUTEX(call_mutex)
    11141191
    11151192typedef struct Tkapp_CallEvent {
    1116         Tcl_Event ev;        /* Must be first */
    1117         TkappObject *self;
    1118         PyObject *args;
    1119         int flags;
    1120         PyObject **res;
    1121         PyObject **exc_type, **exc_value, **exc_tb;
    1122         Tcl_Condition done;
     1193    Tcl_Event ev;            /* Must be first */
     1194    TkappObject *self;
     1195    PyObject *args;
     1196    int flags;
     1197    PyObject **res;
     1198    PyObject **exc_type, **exc_value, **exc_tb;
     1199    Tcl_Condition *done;
    11231200} Tkapp_CallEvent;
     1201#endif
    11241202
    11251203void
    11261204Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
    11271205{
    1128         int i;
    1129         for (i = 0; i < objc; i++)
    1130                 Tcl_DecrRefCount(objv[i]);
    1131         if (objv != objStore)
    1132                 ckfree(FREECAST objv);
     1206    int i;
     1207    for (i = 0; i < objc; i++)
     1208        Tcl_DecrRefCount(objv[i]);
     1209    if (objv != objStore)
     1210        ckfree(FREECAST objv);
    11331211}
    11341212
     
    11391217Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
    11401218{
    1141         Tcl_Obj **objv = objStore;
    1142         int objc = 0, i;
    1143         if (args == NULL)
    1144                 /* do nothing */;
    1145 
    1146         else if (!PyTuple_Check(args)) {
    1147                 objv[0] = AsObj(args);
    1148                 if (objv[0] == 0)
    1149                         goto finally;
    1150                 objc = 1;
    1151                 Tcl_IncrRefCount(objv[0]);
    1152         }
    1153         else {
    1154                 objc = PyTuple_Size(args);
    1155 
    1156                 if (objc > ARGSZ) {
    1157                         objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
    1158                         if (objv == NULL) {
    1159                                 PyErr_NoMemory();
    1160                                 objc = 0;
    1161                                 goto finally;
    1162                         }
    1163                 }
    1164 
    1165                 for (i = 0; i < objc; i++) {
    1166                         PyObject *v = PyTuple_GetItem(args, i);
    1167                         if (v == Py_None) {
    1168                                 objc = i;
    1169                                 break;
    1170                         }
    1171                         objv[i] = AsObj(v);
    1172                         if (!objv[i]) {
    1173                                 /* Reset objc, so it attempts to clear
    1174                                    objects only up to i. */
    1175                                 objc = i;
    1176                                 goto finally;
    1177                         }
    1178                         Tcl_IncrRefCount(objv[i]);
    1179                 }
    1180         }
    1181         *pobjc = objc;
    1182         return objv;
     1219    Tcl_Obj **objv = objStore;
     1220    Py_ssize_t objc = 0, i;
     1221    if (args == NULL)
     1222        /* do nothing */;
     1223
     1224    else if (!PyTuple_Check(args)) {
     1225        objv[0] = AsObj(args);
     1226        if (objv[0] == 0)
     1227            goto finally;
     1228        objc = 1;
     1229        Tcl_IncrRefCount(objv[0]);
     1230    }
     1231    else {
     1232        objc = PyTuple_Size(args);
     1233
     1234        if (objc > ARGSZ) {
     1235            if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
     1236                PyErr_SetString(PyExc_OverflowError, "tuple is too long");
     1237                return NULL;
     1238            }
     1239            objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
     1240            if (objv == NULL) {
     1241                PyErr_NoMemory();
     1242                objc = 0;
     1243                goto finally;
     1244            }
     1245        }
     1246
     1247        for (i = 0; i < objc; i++) {
     1248            PyObject *v = PyTuple_GetItem(args, i);
     1249            if (v == Py_None) {
     1250                objc = i;
     1251                break;
     1252            }
     1253            objv[i] = AsObj(v);
     1254            if (!objv[i]) {
     1255                /* Reset objc, so it attempts to clear
     1256                   objects only up to i. */
     1257                objc = i;
     1258                goto finally;
     1259            }
     1260            Tcl_IncrRefCount(objv[i]);
     1261        }
     1262    }
     1263    *pobjc = objc;
     1264    return objv;
    11831265finally:
    1184         Tkapp_CallDeallocArgs(objv, objStore, objc);
    1185         return NULL;
     1266    Tkapp_CallDeallocArgs(objv, objStore, objc);
     1267    return NULL;
    11861268}
    11871269
     
    11911273Tkapp_CallResult(TkappObject *self)
    11921274{
    1193         PyObject *res = NULL;
    1194         if(self->wantobjects) {
    1195                 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
    1196                 /* Not sure whether the IncrRef is necessary, but something
    1197                    may overwrite the interpreter result while we are
    1198                    converting it. */
    1199                 Tcl_IncrRefCount(value);
    1200                 res = FromObj((PyObject*)self, value);
    1201                 Tcl_DecrRefCount(value);
    1202         } else {
    1203                 const char *s = Tcl_GetStringResult(self->interp);
    1204                 const char *p = s;
    1205 
    1206                 /* If the result contains any bytes with the top bit set,
    1207                    it's UTF-8 and we should decode it to Unicode */
     1275    PyObject *res = NULL;
     1276    if(self->wantobjects) {
     1277        Tcl_Obj *value = Tcl_GetObjResult(self->interp);
     1278        /* Not sure whether the IncrRef is necessary, but something
     1279           may overwrite the interpreter result while we are
     1280           converting it. */
     1281        Tcl_IncrRefCount(value);
     1282        res = FromObj((PyObject*)self, value);
     1283        Tcl_DecrRefCount(value);
     1284    } else {
     1285        const char *s = Tcl_GetStringResult(self->interp);
     1286        const char *p = s;
     1287
     1288        /* If the result contains any bytes with the top bit set,
     1289           it's UTF-8 and we should decode it to Unicode */
    12081290#ifdef Py_USING_UNICODE
    1209                 while (*p != '\0') {
    1210                         if (*p & 0x80)
    1211                                 break;
    1212                         p++;
    1213                 }
    1214 
    1215                 if (*p == '\0')
    1216                         res = PyString_FromStringAndSize(s, (int)(p-s));
    1217                 else {
    1218                         /* Convert UTF-8 to Unicode string */
    1219                         p = strchr(p, '\0');
    1220                         res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
    1221                         if (res == NULL) {
    1222                                 PyErr_Clear();
    1223                                 res = PyString_FromStringAndSize(s, (int)(p-s));
    1224                         }
    1225                 }
     1291        while (*p != '\0') {
     1292            if (*p & 0x80)
     1293                break;
     1294            p++;
     1295        }
     1296
     1297        if (*p == '\0')
     1298            res = PyString_FromStringAndSize(s, (int)(p-s));
     1299        else {
     1300            /* Convert UTF-8 to Unicode string */
     1301            p = strchr(p, '\0');
     1302            res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
     1303            if (res == NULL) {
     1304                PyErr_Clear();
     1305                res = PyString_FromStringAndSize(s, (int)(p-s));
     1306            }
     1307        }
    12261308#else
    1227                 p = strchr(p, '\0');
    1228                 res = PyString_FromStringAndSize(s, (int)(p-s));
    1229 #endif
    1230         }
    1231         return res;
    1232 }
     1309        p = strchr(p, '\0');
     1310        res = PyString_FromStringAndSize(s, (int)(p-s));
     1311#endif
     1312    }
     1313    return res;
     1314}
     1315
     1316#ifdef WITH_THREAD
    12331317
    12341318/* Tkapp_CallProc is the event procedure that is executed in the context of
     
    12391323Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
    12401324{
    1241         Tcl_Obj *objStore[ARGSZ];
    1242         Tcl_Obj **objv;
    1243         int objc;
    1244         int i;
    1245         ENTER_PYTHON
    1246         objv = Tkapp_CallArgs(e->args, objStore, &objc);
    1247         if (!objv) {
    1248                 PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
    1249                 *(e->res) = NULL;
    1250         }
    1251         LEAVE_PYTHON
    1252         if (!objv)
    1253                 goto done;
    1254         i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
    1255         ENTER_PYTHON
    1256         if (i == TCL_ERROR) {
    1257                 *(e->res) = NULL;
    1258                 *(e->exc_type) = NULL;
    1259                 *(e->exc_tb) = NULL;
    1260                 *(e->exc_value) = PyObject_CallFunction(
    1261                         Tkinter_TclError, "s",
    1262                         Tcl_GetStringResult(e->self->interp));
    1263         }
    1264         else {
    1265                 *(e->res) = Tkapp_CallResult(e->self);
    1266         }
    1267         LEAVE_PYTHON
    1268 
    1269         Tkapp_CallDeallocArgs(objv, objStore, objc);
     1325    Tcl_Obj *objStore[ARGSZ];
     1326    Tcl_Obj **objv;
     1327    int objc;
     1328    int i;
     1329    ENTER_PYTHON
     1330    objv = Tkapp_CallArgs(e->args, objStore, &objc);
     1331    if (!objv) {
     1332        PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
     1333        *(e->res) = NULL;
     1334    }
     1335    LEAVE_PYTHON
     1336    if (!objv)
     1337        goto done;
     1338    i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
     1339    ENTER_PYTHON
     1340    if (i == TCL_ERROR) {
     1341        *(e->res) = NULL;
     1342        *(e->exc_type) = NULL;
     1343        *(e->exc_tb) = NULL;
     1344        *(e->exc_value) = PyObject_CallFunction(
     1345            Tkinter_TclError, "s",
     1346            Tcl_GetStringResult(e->self->interp));
     1347    }
     1348    else {
     1349        *(e->res) = Tkapp_CallResult(e->self);
     1350    }
     1351    LEAVE_PYTHON
     1352
     1353    Tkapp_CallDeallocArgs(objv, objStore, objc);
    12701354done:
    1271         /* Wake up calling thread. */
    1272         Tcl_MutexLock(&call_mutex);
    1273         Tcl_ConditionNotify(&e->done);
    1274         Tcl_MutexUnlock(&call_mutex);
    1275         return 1;
    1276 }
     1355    /* Wake up calling thread. */
     1356    Tcl_MutexLock(&call_mutex);
     1357    Tcl_ConditionNotify(e->done);
     1358    Tcl_MutexUnlock(&call_mutex);
     1359    return 1;
     1360}
     1361
     1362#endif
    12771363
    12781364/* This is the main entry point for calling a Tcl command.
     
    12911377Tkapp_Call(PyObject *selfptr, PyObject *args)
    12921378{
    1293         Tcl_Obj *objStore[ARGSZ];
    1294         Tcl_Obj **objv = NULL;
    1295         int objc, i;
    1296         PyObject *res = NULL;
    1297         TkappObject *self = (TkappObject*)selfptr;
    1298         int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
    1299 
    1300         /* If args is a single tuple, replace with contents of tuple */
    1301         if (1 == PyTuple_Size(args)){
    1302                 PyObject* item = PyTuple_GetItem(args, 0);
    1303                 if (PyTuple_Check(item))
    1304                         args = item;
    1305         }
     1379    Tcl_Obj *objStore[ARGSZ];
     1380    Tcl_Obj **objv = NULL;
     1381    int objc, i;
     1382    PyObject *res = NULL;
     1383    TkappObject *self = (TkappObject*)selfptr;
     1384    int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
     1385
     1386    /* If args is a single tuple, replace with contents of tuple */
     1387    if (1 == PyTuple_Size(args)){
     1388        PyObject* item = PyTuple_GetItem(args, 0);
     1389        if (PyTuple_Check(item))
     1390            args = item;
     1391    }
    13061392#ifdef WITH_THREAD
    1307         if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
    1308                 /* We cannot call the command directly. Instead, we must
    1309                    marshal the parameters to the interpreter thread. */
    1310                 Tkapp_CallEvent *ev;
    1311                 PyObject *exc_type, *exc_value, *exc_tb;
    1312                 if (!WaitForMainloop(self))
    1313                         return NULL;
    1314                 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
    1315                 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
    1316                 ev->self = self;
    1317                 ev->args = args;
    1318                 ev->res = &res;
    1319                 ev->exc_type = &exc_type;
    1320                 ev->exc_value = &exc_value;
    1321                 ev->exc_tb = &exc_tb;
    1322                 ev->done = (Tcl_Condition)0;
    1323 
    1324                 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
    1325 
    1326                 if (res == NULL) {
    1327                         if (exc_type)
    1328                                 PyErr_Restore(exc_type, exc_value, exc_tb);
    1329                         else
    1330                                 PyErr_SetObject(Tkinter_TclError, exc_value);
    1331                 }
    1332         }
    1333         else
    1334 #endif
    1335         {
    1336 
    1337                 objv = Tkapp_CallArgs(args, objStore, &objc);
    1338                 if (!objv)
    1339                         return NULL;
    1340 
    1341                 ENTER_TCL
    1342 
    1343                 i = Tcl_EvalObjv(self->interp, objc, objv, flags);
    1344 
    1345                 ENTER_OVERLAP
    1346 
    1347                 if (i == TCL_ERROR)
    1348                         Tkinter_Error(selfptr);
    1349                 else
    1350                         res = Tkapp_CallResult(self);
    1351 
    1352                 LEAVE_OVERLAP_TCL
    1353 
    1354                 Tkapp_CallDeallocArgs(objv, objStore, objc);
    1355         }
    1356         return res;
     1393    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
     1394        /* We cannot call the command directly. Instead, we must
     1395           marshal the parameters to the interpreter thread. */
     1396        Tkapp_CallEvent *ev;
     1397        Tcl_Condition cond = NULL;
     1398        PyObject *exc_type, *exc_value, *exc_tb;
     1399        if (!WaitForMainloop(self))
     1400            return NULL;
     1401        ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
     1402        ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
     1403        ev->self = self;
     1404        ev->args = args;
     1405        ev->res = &res;
     1406        ev->exc_type = &exc_type;
     1407        ev->exc_value = &exc_value;
     1408        ev->exc_tb = &exc_tb;
     1409        ev->done = &cond;
     1410
     1411        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
     1412
     1413        if (res == NULL) {
     1414            if (exc_type)
     1415                PyErr_Restore(exc_type, exc_value, exc_tb);
     1416            else
     1417                PyErr_SetObject(Tkinter_TclError, exc_value);
     1418        }
     1419        Tcl_ConditionFinalize(&cond);
     1420    }
     1421    else
     1422#endif
     1423    {
     1424
     1425        objv = Tkapp_CallArgs(args, objStore, &objc);
     1426        if (!objv)
     1427            return NULL;
     1428
     1429        ENTER_TCL
     1430
     1431        i = Tcl_EvalObjv(self->interp, objc, objv, flags);
     1432
     1433        ENTER_OVERLAP
     1434
     1435        if (i == TCL_ERROR)
     1436            Tkinter_Error(selfptr);
     1437        else
     1438            res = Tkapp_CallResult(self);
     1439
     1440        LEAVE_OVERLAP_TCL
     1441
     1442        Tkapp_CallDeallocArgs(objv, objStore, objc);
     1443    }
     1444    return res;
    13571445}
    13581446
     
    13611449Tkapp_GlobalCall(PyObject *self, PyObject *args)
    13621450{
    1363         /* Could do the same here as for Tkapp_Call(), but this is not used
    1364            much, so I can't be bothered.  Unfortunately Tcl doesn't export a
    1365            way for the user to do what all its Global* variants do (save and
    1366            reset the scope pointer, call the local version, restore the saved
    1367            scope pointer). */
    1368 
    1369         char *cmd;
    1370         PyObject *res = NULL;
    1371 
    1372         CHECK_TCL_APPARTMENT;
    1373 
    1374         cmd  = Merge(args);
    1375         if (cmd) {
    1376                 int err;
    1377                 ENTER_TCL
    1378                 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
    1379                 ENTER_OVERLAP
    1380                 if (err == TCL_ERROR)
    1381                         res = Tkinter_Error(self);
    1382                 else
    1383                         res = PyString_FromString(Tkapp_Result(self));
    1384                 LEAVE_OVERLAP_TCL
    1385                 ckfree(cmd);
    1386         }
    1387 
    1388         return res;
     1451    /* Could do the same here as for Tkapp_Call(), but this is not used
     1452       much, so I can't be bothered.  Unfortunately Tcl doesn't export a
     1453       way for the user to do what all its Global* variants do (save and
     1454       reset the scope pointer, call the local version, restore the saved
     1455       scope pointer). */
     1456
     1457    char *cmd;
     1458    PyObject *res = NULL;
     1459
     1460    CHECK_TCL_APPARTMENT;
     1461
     1462    cmd  = Merge(args);
     1463    if (cmd) {
     1464        int err;
     1465        ENTER_TCL
     1466        err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
     1467        ENTER_OVERLAP
     1468        if (err == TCL_ERROR)
     1469            res = Tkinter_Error(self);
     1470        else
     1471            res = PyString_FromString(Tkapp_Result(self));
     1472        LEAVE_OVERLAP_TCL
     1473        ckfree(cmd);
     1474    }
     1475
     1476    return res;
    13891477}
    13901478
     
    13921480Tkapp_Eval(PyObject *self, PyObject *args)
    13931481{
    1394         char *script;
    1395         PyObject *res = NULL;
    1396         int err;
    1397 
    1398         if (!PyArg_ParseTuple(args, "s:eval", &script))
    1399                 return NULL;
    1400 
    1401         CHECK_TCL_APPARTMENT;
    1402 
    1403         ENTER_TCL
    1404         err = Tcl_Eval(Tkapp_Interp(self), script);
    1405         ENTER_OVERLAP
    1406         if (err == TCL_ERROR)
    1407                 res = Tkinter_Error(self);
    1408         else
    1409                 res = PyString_FromString(Tkapp_Result(self));
    1410         LEAVE_OVERLAP_TCL
    1411         return res;
     1482    char *script;
     1483    PyObject *res = NULL;
     1484    int err;
     1485
     1486    if (!PyArg_ParseTuple(args, "s:eval", &script))
     1487        return NULL;
     1488
     1489    CHECK_TCL_APPARTMENT;
     1490
     1491    ENTER_TCL
     1492    err = Tcl_Eval(Tkapp_Interp(self), script);
     1493    ENTER_OVERLAP
     1494    if (err == TCL_ERROR)
     1495        res = Tkinter_Error(self);
     1496    else
     1497        res = PyString_FromString(Tkapp_Result(self));
     1498    LEAVE_OVERLAP_TCL
     1499    return res;
    14121500}
    14131501
     
    14151503Tkapp_GlobalEval(PyObject *self, PyObject *args)
    14161504{
    1417         char *script;
    1418         PyObject *res = NULL;
    1419         int err;
    1420 
    1421         if (!PyArg_ParseTuple(args, "s:globaleval", &script))
    1422                 return NULL;
    1423 
    1424         CHECK_TCL_APPARTMENT;
    1425 
    1426         ENTER_TCL
    1427         err = Tcl_GlobalEval(Tkapp_Interp(self), script);
    1428         ENTER_OVERLAP
    1429         if (err == TCL_ERROR)
    1430                 res = Tkinter_Error(self);
    1431         else
    1432                 res = PyString_FromString(Tkapp_Result(self));
    1433         LEAVE_OVERLAP_TCL
    1434         return res;
     1505    char *script;
     1506    PyObject *res = NULL;
     1507    int err;
     1508
     1509    if (!PyArg_ParseTuple(args, "s:globaleval", &script))
     1510        return NULL;
     1511
     1512    CHECK_TCL_APPARTMENT;
     1513
     1514    ENTER_TCL
     1515    err = Tcl_GlobalEval(Tkapp_Interp(self), script);
     1516    ENTER_OVERLAP
     1517    if (err == TCL_ERROR)
     1518        res = Tkinter_Error(self);
     1519    else
     1520        res = PyString_FromString(Tkapp_Result(self));
     1521    LEAVE_OVERLAP_TCL
     1522    return res;
    14351523}
    14361524
     
    14381526Tkapp_EvalFile(PyObject *self, PyObject *args)
    14391527{
    1440         char *fileName;
    1441         PyObject *res = NULL;
    1442         int err;
    1443 
    1444         if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
    1445                 return NULL;
    1446 
    1447         CHECK_TCL_APPARTMENT;
    1448 
    1449         ENTER_TCL
    1450         err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
    1451         ENTER_OVERLAP
    1452         if (err == TCL_ERROR)
    1453                 res = Tkinter_Error(self);
    1454 
    1455         else
    1456                 res = PyString_FromString(Tkapp_Result(self));
    1457         LEAVE_OVERLAP_TCL
    1458         return res;
     1528    char *fileName;
     1529    PyObject *res = NULL;
     1530    int err;
     1531
     1532    if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
     1533        return NULL;
     1534
     1535    CHECK_TCL_APPARTMENT;
     1536
     1537    ENTER_TCL
     1538    err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
     1539    ENTER_OVERLAP
     1540    if (err == TCL_ERROR)
     1541        res = Tkinter_Error(self);
     1542
     1543    else
     1544        res = PyString_FromString(Tkapp_Result(self));
     1545    LEAVE_OVERLAP_TCL
     1546    return res;
    14591547}
    14601548
     
    14621550Tkapp_Record(PyObject *self, PyObject *args)
    14631551{
    1464         char *script;
    1465         PyObject *res = NULL;
    1466         int err;
    1467 
    1468         if (!PyArg_ParseTuple(args, "s", &script))
    1469                 return NULL;
    1470 
    1471         CHECK_TCL_APPARTMENT;
    1472 
    1473         ENTER_TCL
    1474         err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
    1475         ENTER_OVERLAP
    1476         if (err == TCL_ERROR)
    1477                 res = Tkinter_Error(self);
    1478         else
    1479                 res = PyString_FromString(Tkapp_Result(self));
    1480         LEAVE_OVERLAP_TCL
    1481         return res;
     1552    char *script;
     1553    PyObject *res = NULL;
     1554    int err;
     1555
     1556    if (!PyArg_ParseTuple(args, "s", &script))
     1557        return NULL;
     1558
     1559    CHECK_TCL_APPARTMENT;
     1560
     1561    ENTER_TCL
     1562    err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
     1563    ENTER_OVERLAP
     1564    if (err == TCL_ERROR)
     1565        res = Tkinter_Error(self);
     1566    else
     1567        res = PyString_FromString(Tkapp_Result(self));
     1568    LEAVE_OVERLAP_TCL
     1569    return res;
    14821570}
    14831571
     
    14851573Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
    14861574{
    1487         char *msg;
    1488 
    1489         if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
    1490                 return NULL;
    1491         CHECK_TCL_APPARTMENT;
    1492 
    1493         ENTER_TCL
    1494         Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
    1495         LEAVE_TCL
    1496 
    1497         Py_INCREF(Py_None);
    1498         return Py_None;
    1499 }
    1500 
     1575    char *msg;
     1576
     1577    if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
     1578        return NULL;
     1579    CHECK_TCL_APPARTMENT;
     1580
     1581    ENTER_TCL
     1582    Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
     1583    LEAVE_TCL
     1584
     1585    Py_INCREF(Py_None);
     1586    return Py_None;
     1587}
    15011588
    15021589
     
    15041591/** Tcl Variable **/
    15051592
     1593typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
     1594
     1595#ifdef WITH_THREAD
    15061596TCL_DECLARE_MUTEX(var_mutex)
    15071597
    1508 typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
    15091598typedef struct VarEvent {
    1510         Tcl_Event ev; /* must be first */
    1511         PyObject *self;
    1512         PyObject *args;
    1513         int flags;
    1514         EventFunc func;
    1515         PyObject **res;
    1516         PyObject **exc_type;
    1517         PyObject **exc_val;
    1518         Tcl_Condition cond;
     1599    Tcl_Event ev; /* must be first */
     1600    PyObject *self;
     1601    PyObject *args;
     1602    int flags;
     1603    EventFunc func;
     1604    PyObject **res;
     1605    PyObject **exc_type;
     1606    PyObject **exc_val;
     1607    Tcl_Condition *cond;
    15191608} VarEvent;
     1609#endif
    15201610
    15211611static int
    15221612varname_converter(PyObject *in, void *_out)
    15231613{
    1524         char **out = (char**)_out;
    1525         if (PyString_Check(in)) {
    1526                 *out = PyString_AsString(in);
    1527                 return 1;
    1528         }
    1529         if (PyTclObject_Check(in)) {
    1530                 *out = PyTclObject_TclString(in);
    1531                 return 1;
    1532         }
    1533         /* XXX: Should give diagnostics. */
    1534         return 0;
    1535 }       
     1614    char **out = (char**)_out;
     1615    if (PyString_Check(in)) {
     1616        *out = PyString_AsString(in);
     1617        return 1;
     1618    }
     1619    if (PyTclObject_Check(in)) {
     1620        *out = PyTclObject_TclString(in);
     1621        return 1;
     1622    }
     1623    /* XXX: Should give diagnostics. */
     1624    return 0;
     1625}
     1626
     1627#ifdef WITH_THREAD
    15361628
    15371629static void
    15381630var_perform(VarEvent *ev)
    15391631{
    1540         *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
    1541         if (!*(ev->res)) {
    1542                 PyObject *exc, *val, *tb;
    1543                 PyErr_Fetch(&exc, &val, &tb);
    1544                 PyErr_NormalizeException(&exc, &val, &tb);
    1545                 *(ev->exc_type) = exc;
    1546                 *(ev->exc_val) = val;
    1547                 Py_DECREF(tb);
    1548         }
    1549                
     1632    *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
     1633    if (!*(ev->res)) {
     1634        PyObject *exc, *val, *tb;
     1635        PyErr_Fetch(&exc, &val, &tb);
     1636        PyErr_NormalizeException(&exc, &val, &tb);
     1637        *(ev->exc_type) = exc;
     1638        *(ev->exc_val) = val;
     1639        Py_DECREF(tb);
     1640    }
     1641
    15501642}
    15511643
     
    15531645var_proc(VarEvent* ev, int flags)
    15541646{
    1555         ENTER_PYTHON
    1556         var_perform(ev);
    1557         Tcl_MutexLock(&var_mutex);
    1558         Tcl_ConditionNotify(&ev->cond);
    1559         Tcl_MutexUnlock(&var_mutex);
    1560         LEAVE_PYTHON
    1561         return 1;
    1562 }
     1647    ENTER_PYTHON
     1648    var_perform(ev);
     1649    Tcl_MutexLock(&var_mutex);
     1650    Tcl_ConditionNotify(ev->cond);
     1651    Tcl_MutexUnlock(&var_mutex);
     1652    LEAVE_PYTHON
     1653    return 1;
     1654}
     1655
     1656#endif
    15631657
    15641658static PyObject*
    15651659var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
    15661660{
    1567         TkappObject *self = (TkappObject*)selfptr;
    15681661#ifdef WITH_THREAD
    1569         if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
    1570                 TkappObject *self = (TkappObject*)selfptr;
    1571                 VarEvent *ev;
    1572                 PyObject *res, *exc_type, *exc_val;
    1573                
    1574                 /* The current thread is not the interpreter thread.  Marshal
    1575                    the call to the interpreter thread, then wait for
    1576                    completion. */
    1577                 if (!WaitForMainloop(self))
    1578                         return NULL;
    1579 
    1580                 ev = (VarEvent*)ckalloc(sizeof(VarEvent));
    1581 
    1582                 ev->self = selfptr;
    1583                 ev->args = args;
    1584                 ev->flags = flags;
    1585                 ev->func = func;
    1586                 ev->res = &res;
    1587                 ev->exc_type = &exc_type;
    1588                 ev->exc_val = &exc_val;
    1589                 ev->cond = NULL;
    1590                 ev->ev.proc = (Tcl_EventProc*)var_proc;
    1591                 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
    1592                 if (!res) {
    1593                         PyErr_SetObject(exc_type, exc_val);
    1594                         Py_DECREF(exc_type);
    1595                         Py_DECREF(exc_val);
    1596                         return NULL;
    1597                 }
    1598                 return res;
    1599         }
    1600 #endif
    1601         /* Tcl is not threaded, or this is the interpreter thread. */
    1602         return func(selfptr, args, flags);
     1662    TkappObject *self = (TkappObject*)selfptr;
     1663    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
     1664        TkappObject *self = (TkappObject*)selfptr;
     1665        VarEvent *ev;
     1666        PyObject *res, *exc_type, *exc_val;
     1667        Tcl_Condition cond = NULL;
     1668
     1669        /* The current thread is not the interpreter thread.  Marshal
     1670           the call to the interpreter thread, then wait for
     1671           completion. */
     1672        if (!WaitForMainloop(self))
     1673            return NULL;
     1674
     1675        ev = (VarEvent*)ckalloc(sizeof(VarEvent));
     1676
     1677        ev->self = selfptr;
     1678        ev->args = args;
     1679        ev->flags = flags;
     1680        ev->func = func;
     1681        ev->res = &res;
     1682        ev->exc_type = &exc_type;
     1683        ev->exc_val = &exc_val;
     1684        ev->cond = &cond;
     1685        ev->ev.proc = (Tcl_EventProc*)var_proc;
     1686        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
     1687        Tcl_ConditionFinalize(&cond);
     1688        if (!res) {
     1689            PyErr_SetObject(exc_type, exc_val);
     1690            Py_DECREF(exc_type);
     1691            Py_DECREF(exc_val);
     1692            return NULL;
     1693        }
     1694        return res;
     1695    }
     1696#endif
     1697    /* Tcl is not threaded, or this is the interpreter thread. */
     1698    return func(selfptr, args, flags);
    16031699}
    16041700
     
    16061702SetVar(PyObject *self, PyObject *args, int flags)
    16071703{
    1608         char *name1, *name2;
    1609         PyObject *newValue;
    1610         PyObject *res = NULL;
    1611         Tcl_Obj *newval, *ok;
    1612 
    1613         if (PyArg_ParseTuple(args, "O&O:setvar",
    1614                              varname_converter, &name1, &newValue)) {
    1615                 /* XXX Acquire tcl lock??? */
    1616                 newval = AsObj(newValue);
    1617                 if (newval == NULL)
    1618                         return NULL;
    1619                 ENTER_TCL
    1620                 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
    1621                                    newval, flags);
    1622                 ENTER_OVERLAP
    1623                 if (!ok)
    1624                         Tkinter_Error(self);
    1625                 else {
    1626                         res = Py_None;
    1627                         Py_INCREF(res);
    1628                 }
    1629                 LEAVE_OVERLAP_TCL
    1630         }
    1631         else {
    1632                 PyErr_Clear();
    1633                 if (PyArg_ParseTuple(args, "ssO:setvar",
    1634                                      &name1, &name2, &newValue)) {
    1635                         /* XXX must hold tcl lock already??? */
    1636                         newval = AsObj(newValue);
    1637                         ENTER_TCL
    1638                         ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
    1639                         ENTER_OVERLAP
    1640                         if (!ok)
    1641                                 Tkinter_Error(self);
    1642                         else {
    1643                                 res = Py_None;
    1644                                 Py_INCREF(res);
    1645                         }
    1646                         LEAVE_OVERLAP_TCL
    1647                 }
    1648                 else {
    1649                         return NULL;
    1650                 }
    1651         }
    1652         return res;
     1704    char *name1, *name2;
     1705    PyObject *newValue;
     1706    PyObject *res = NULL;
     1707    Tcl_Obj *newval, *ok;
     1708
     1709    if (PyArg_ParseTuple(args, "O&O:setvar",
     1710                         varname_converter, &name1, &newValue)) {
     1711        /* XXX Acquire tcl lock??? */
     1712        newval = AsObj(newValue);
     1713        if (newval == NULL)
     1714            return NULL;
     1715        ENTER_TCL
     1716        ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
     1717                           newval, flags);
     1718        ENTER_OVERLAP
     1719        if (!ok)
     1720            Tkinter_Error(self);
     1721        else {
     1722            res = Py_None;
     1723            Py_INCREF(res);
     1724        }
     1725        LEAVE_OVERLAP_TCL
     1726    }
     1727    else {
     1728        PyErr_Clear();
     1729        if (PyArg_ParseTuple(args, "ssO:setvar",
     1730                             &name1, &name2, &newValue)) {
     1731            /* XXX must hold tcl lock already??? */
     1732            newval = AsObj(newValue);
     1733            ENTER_TCL
     1734            ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
     1735            ENTER_OVERLAP
     1736            if (!ok)
     1737                Tkinter_Error(self);
     1738            else {
     1739                res = Py_None;
     1740                Py_INCREF(res);
     1741            }
     1742            LEAVE_OVERLAP_TCL
     1743        }
     1744        else {
     1745            return NULL;
     1746        }
     1747    }
     1748    return res;
    16531749}
    16541750
     
    16561752Tkapp_SetVar(PyObject *self, PyObject *args)
    16571753{
    1658         return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
     1754    return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
    16591755}
    16601756
     
    16621758Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
    16631759{
    1664         return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
    1665 }
    1666 
     1760    return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
     1761}
    16671762
    16681763
     
    16711766GetVar(PyObject *self, PyObject *args, int flags)
    16721767{
    1673         char *name1, *name2=NULL;
    1674         PyObject *res = NULL;
    1675         Tcl_Obj *tres;
    1676 
    1677         if (!PyArg_ParseTuple(args, "O&|s:getvar",
    1678                               varname_converter, &name1, &name2))
    1679                 return NULL;
    1680 
    1681         ENTER_TCL
    1682         tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
    1683         ENTER_OVERLAP
    1684         if (tres == NULL) {
    1685                 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
    1686         } else {
    1687                 if (((TkappObject*)self)->wantobjects) {
    1688                         res = FromObj(self, tres);
    1689                 }
    1690                 else {
    1691                         res = PyString_FromString(Tcl_GetString(tres));
    1692                 }
    1693         }
    1694         LEAVE_OVERLAP_TCL
    1695         return res;
     1768    char *name1, *name2=NULL;
     1769    PyObject *res = NULL;
     1770    Tcl_Obj *tres;
     1771
     1772    if (!PyArg_ParseTuple(args, "O&|s:getvar",
     1773                          varname_converter, &name1, &name2))
     1774        return NULL;
     1775
     1776    ENTER_TCL
     1777    tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
     1778    ENTER_OVERLAP
     1779    if (tres == NULL) {
     1780        PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
     1781    } else {
     1782        if (((TkappObject*)self)->wantobjects) {
     1783            res = FromObj(self, tres);
     1784        }
     1785        else {
     1786            res = PyString_FromString(Tcl_GetString(tres));
     1787        }
     1788    }
     1789    LEAVE_OVERLAP_TCL
     1790    return res;
    16961791}
    16971792
     
    16991794Tkapp_GetVar(PyObject *self, PyObject *args)
    17001795{
    1701         return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
     1796    return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
    17021797}
    17031798
     
    17051800Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
    17061801{
    1707         return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
    1708 }
    1709 
     1802    return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
     1803}
    17101804
    17111805
     
    17141808UnsetVar(PyObject *self, PyObject *args, int flags)
    17151809{
    1716         char *name1, *name2=NULL;
    1717         int code;
    1718         PyObject *res = NULL;
    1719 
    1720         if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
    1721                 return NULL;
    1722 
    1723         ENTER_TCL
    1724         code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
    1725         ENTER_OVERLAP
    1726         if (code == TCL_ERROR)
    1727                 res = Tkinter_Error(self);
    1728         else {
    1729                 Py_INCREF(Py_None);
    1730                 res = Py_None;
    1731         }
    1732         LEAVE_OVERLAP_TCL
    1733         return res;
     1810    char *name1, *name2=NULL;
     1811    int code;
     1812    PyObject *res = NULL;
     1813
     1814    if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
     1815        return NULL;
     1816
     1817    ENTER_TCL
     1818    code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
     1819    ENTER_OVERLAP
     1820    if (code == TCL_ERROR)
     1821        res = Tkinter_Error(self);
     1822    else {
     1823        Py_INCREF(Py_None);
     1824        res = Py_None;
     1825    }
     1826    LEAVE_OVERLAP_TCL
     1827    return res;
    17341828}
    17351829
     
    17371831Tkapp_UnsetVar(PyObject *self, PyObject *args)
    17381832{
    1739         return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
     1833    return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
    17401834}
    17411835
     
    17431837Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
    17441838{
    1745         return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
    1746 }
    1747 
     1839    return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
     1840}
    17481841
    17491842
     
    17541847Tkapp_GetInt(PyObject *self, PyObject *args)
    17551848{
    1756         char *s;
    1757         int v;
    1758 
    1759         if (PyTuple_Size(args) == 1) {
    1760                 PyObject* o = PyTuple_GetItem(args, 0);
    1761                 if (PyInt_Check(o)) {
    1762                         Py_INCREF(o);
    1763                         return o;
    1764                 }
    1765         }
    1766         if (!PyArg_ParseTuple(args, "s:getint", &s))
    1767                 return NULL;
    1768         if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
    1769                 return Tkinter_Error(self);
    1770         return Py_BuildValue("i", v);
     1849    char *s;
     1850    int v;
     1851
     1852    if (PyTuple_Size(args) == 1) {
     1853        PyObject* o = PyTuple_GetItem(args, 0);
     1854        if (PyInt_Check(o)) {
     1855            Py_INCREF(o);
     1856            return o;
     1857        }
     1858    }
     1859    if (!PyArg_ParseTuple(args, "s:getint", &s))
     1860        return NULL;
     1861    if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
     1862        return Tkinter_Error(self);
     1863    return Py_BuildValue("i", v);
    17711864}
    17721865
     
    17741867Tkapp_GetDouble(PyObject *self, PyObject *args)
    17751868{
    1776         char *s;
    1777         double v;
    1778 
    1779         if (PyTuple_Size(args) == 1) {
    1780                 PyObject *o = PyTuple_GetItem(args, 0);
    1781                 if (PyFloat_Check(o)) {
    1782                         Py_INCREF(o);
    1783                         return o;
    1784                 }
    1785         }
    1786         if (!PyArg_ParseTuple(args, "s:getdouble", &s))
    1787                 return NULL;
    1788         if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
    1789                 return Tkinter_Error(self);
    1790         return Py_BuildValue("d", v);
     1869    char *s;
     1870    double v;
     1871
     1872    if (PyTuple_Size(args) == 1) {
     1873        PyObject *o = PyTuple_GetItem(args, 0);
     1874        if (PyFloat_Check(o)) {
     1875            Py_INCREF(o);
     1876            return o;
     1877        }
     1878    }
     1879    if (!PyArg_ParseTuple(args, "s:getdouble", &s))
     1880        return NULL;
     1881    if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
     1882        return Tkinter_Error(self);
     1883    return Py_BuildValue("d", v);
    17911884}
    17921885
     
    17941887Tkapp_GetBoolean(PyObject *self, PyObject *args)
    17951888{
    1796         char *s;
    1797         int v;
    1798 
    1799         if (PyTuple_Size(args) == 1) {
    1800                 PyObject *o = PyTuple_GetItem(args, 0);
    1801                 if (PyInt_Check(o)) {
    1802                         Py_INCREF(o);
    1803                         return o;
    1804                 }
    1805         }
    1806         if (!PyArg_ParseTuple(args, "s:getboolean", &s))
    1807                 return NULL;
    1808         if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
    1809                 return Tkinter_Error(self);
    1810         return PyBool_FromLong(v);
     1889    char *s;
     1890    int v;
     1891
     1892    if (PyTuple_Size(args) == 1) {
     1893        PyObject *o = PyTuple_GetItem(args, 0);
     1894        if (PyInt_Check(o)) {
     1895            Py_INCREF(o);
     1896            return o;
     1897        }
     1898    }
     1899    if (!PyArg_ParseTuple(args, "s:getboolean", &s))
     1900        return NULL;
     1901    if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
     1902        return Tkinter_Error(self);
     1903    return PyBool_FromLong(v);
    18111904}
    18121905
     
    18141907Tkapp_ExprString(PyObject *self, PyObject *args)
    18151908{
    1816         char *s;
    1817         PyObject *res = NULL;
    1818         int retval;
    1819 
    1820         if (!PyArg_ParseTuple(args, "s:exprstring", &s))
    1821                 return NULL;
    1822        
    1823         CHECK_TCL_APPARTMENT;
    1824 
    1825         ENTER_TCL
    1826         retval = Tcl_ExprString(Tkapp_Interp(self), s);
    1827         ENTER_OVERLAP
    1828         if (retval == TCL_ERROR)
    1829                 res = Tkinter_Error(self);
    1830         else
    1831                 res = Py_BuildValue("s", Tkapp_Result(self));
    1832         LEAVE_OVERLAP_TCL
    1833         return res;
     1909    char *s;
     1910    PyObject *res = NULL;
     1911    int retval;
     1912
     1913    if (!PyArg_ParseTuple(args, "s:exprstring", &s))
     1914        return NULL;
     1915
     1916    CHECK_TCL_APPARTMENT;
     1917
     1918    ENTER_TCL
     1919    retval = Tcl_ExprString(Tkapp_Interp(self), s);
     1920    ENTER_OVERLAP
     1921    if (retval == TCL_ERROR)
     1922        res = Tkinter_Error(self);
     1923    else
     1924        res = Py_BuildValue("s", Tkapp_Result(self));
     1925    LEAVE_OVERLAP_TCL
     1926    return res;
    18341927}
    18351928
     
    18371930Tkapp_ExprLong(PyObject *self, PyObject *args)
    18381931{
    1839         char *s;
    1840         PyObject *res = NULL;
    1841         int retval;
    1842         long v;
    1843 
    1844         if (!PyArg_ParseTuple(args, "s:exprlong", &s))
    1845                 return NULL;
    1846 
    1847         CHECK_TCL_APPARTMENT;
    1848 
    1849         ENTER_TCL
    1850         retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
    1851         ENTER_OVERLAP
    1852         if (retval == TCL_ERROR)
    1853                 res = Tkinter_Error(self);
    1854         else
    1855                 res = Py_BuildValue("l", v);
    1856         LEAVE_OVERLAP_TCL
    1857         return res;
     1932    char *s;
     1933    PyObject *res = NULL;
     1934    int retval;
     1935    long v;
     1936
     1937    if (!PyArg_ParseTuple(args, "s:exprlong", &s))
     1938        return NULL;
     1939
     1940    CHECK_TCL_APPARTMENT;
     1941
     1942    ENTER_TCL
     1943    retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
     1944    ENTER_OVERLAP
     1945    if (retval == TCL_ERROR)
     1946        res = Tkinter_Error(self);
     1947    else
     1948        res = Py_BuildValue("l", v);
     1949    LEAVE_OVERLAP_TCL
     1950    return res;
    18581951}
    18591952
     
    18611954Tkapp_ExprDouble(PyObject *self, PyObject *args)
    18621955{
    1863         char *s;
    1864         PyObject *res = NULL;
    1865         double v;
    1866         int retval;
    1867 
    1868         if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
    1869                 return NULL;
    1870         CHECK_TCL_APPARTMENT;
    1871         PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
    1872         ENTER_TCL
    1873         retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
    1874         ENTER_OVERLAP
    1875         PyFPE_END_PROTECT(retval)
    1876         if (retval == TCL_ERROR)
    1877                 res = Tkinter_Error(self);
    1878         else
    1879                 res = Py_BuildValue("d", v);
    1880         LEAVE_OVERLAP_TCL
    1881         return res;
     1956    char *s;
     1957    PyObject *res = NULL;
     1958    double v;
     1959    int retval;
     1960
     1961    if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
     1962        return NULL;
     1963    CHECK_TCL_APPARTMENT;
     1964    PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
     1965    ENTER_TCL
     1966    retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
     1967    ENTER_OVERLAP
     1968    PyFPE_END_PROTECT(retval)
     1969    if (retval == TCL_ERROR)
     1970        res = Tkinter_Error(self);
     1971    else
     1972        res = Py_BuildValue("d", v);
     1973    LEAVE_OVERLAP_TCL
     1974    return res;
    18821975}
    18831976
     
    18851978Tkapp_ExprBoolean(PyObject *self, PyObject *args)
    18861979{
    1887         char *s;
    1888         PyObject *res = NULL;
    1889         int retval;
    1890         int v;
    1891 
    1892         if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
    1893                 return NULL;
    1894         CHECK_TCL_APPARTMENT;
    1895         ENTER_TCL
    1896         retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
    1897         ENTER_OVERLAP
    1898         if (retval == TCL_ERROR)
    1899                 res = Tkinter_Error(self);
    1900         else
    1901                 res = Py_BuildValue("i", v);
    1902         LEAVE_OVERLAP_TCL
    1903         return res;
    1904 }
    1905 
     1980    char *s;
     1981    PyObject *res = NULL;
     1982    int retval;
     1983    int v;
     1984
     1985    if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
     1986        return NULL;
     1987    CHECK_TCL_APPARTMENT;
     1988    ENTER_TCL
     1989    retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
     1990    ENTER_OVERLAP
     1991    if (retval == TCL_ERROR)
     1992        res = Tkinter_Error(self);
     1993    else
     1994        res = Py_BuildValue("i", v);
     1995    LEAVE_OVERLAP_TCL
     1996    return res;
     1997}
    19061998
    19071999
     
    19102002Tkapp_SplitList(PyObject *self, PyObject *args)
    19112003{
    1912         char *list;
    1913         int argc;
    1914         char **argv;
    1915         PyObject *v;
    1916         int i;
    1917 
    1918         if (PyTuple_Size(args) == 1) {
    1919                 v = PyTuple_GetItem(args, 0);
    1920                 if (PyTuple_Check(v)) {
    1921                         Py_INCREF(v);
    1922                         return v;
    1923                 }
    1924         }
    1925         if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
    1926                 return NULL;
    1927 
    1928         if (Tcl_SplitList(Tkapp_Interp(self), list,
    1929                           &argc, &argv) == TCL_ERROR)  {
    1930                 PyMem_Free(list);
    1931                 return Tkinter_Error(self);
    1932         }
    1933 
    1934         if (!(v = PyTuple_New(argc)))
    1935                 goto finally;
    1936 
    1937         for (i = 0; i < argc; i++) {
    1938                 PyObject *s = PyString_FromString(argv[i]);
    1939                 if (!s || PyTuple_SetItem(v, i, s)) {
    1940                         Py_DECREF(v);
    1941                         v = NULL;
    1942                         goto finally;
    1943                 }
    1944         }
     2004    char *list;
     2005    int argc;
     2006    char **argv;
     2007    PyObject *arg, *v;
     2008    int i;
     2009
     2010    if (!PyArg_ParseTuple(args, "O:splitlist", &arg))
     2011        return NULL;
     2012    if (PyTclObject_Check(arg)) {
     2013        int objc;
     2014        Tcl_Obj **objv;
     2015        if (Tcl_ListObjGetElements(Tkapp_Interp(self),
     2016                                   ((PyTclObject*)arg)->value,
     2017                                   &objc, &objv) == TCL_ERROR) {
     2018            return Tkinter_Error(self);
     2019        }
     2020        if (!(v = PyTuple_New(objc)))
     2021            return NULL;
     2022        for (i = 0; i < objc; i++) {
     2023            PyObject *s = FromObj(self, objv[i]);
     2024            if (!s || PyTuple_SetItem(v, i, s)) {
     2025                Py_DECREF(v);
     2026                return NULL;
     2027            }
     2028        }
     2029        return v;
     2030    }
     2031    if (PyTuple_Check(arg)) {
     2032        Py_INCREF(arg);
     2033        return arg;
     2034    }
     2035
     2036    if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
     2037        return NULL;
     2038
     2039    if (Tcl_SplitList(Tkapp_Interp(self), list,
     2040                      &argc, &argv) == TCL_ERROR)  {
     2041        PyMem_Free(list);
     2042        return Tkinter_Error(self);
     2043    }
     2044
     2045    if (!(v = PyTuple_New(argc)))
     2046        goto finally;
     2047
     2048    for (i = 0; i < argc; i++) {
     2049        PyObject *s = PyString_FromString(argv[i]);
     2050        if (!s || PyTuple_SetItem(v, i, s)) {
     2051            Py_DECREF(v);
     2052            v = NULL;
     2053            goto finally;
     2054        }
     2055    }
    19452056
    19462057  finally:
    1947         ckfree(FREECAST argv);
    1948         PyMem_Free(list);
    1949         return v;
     2058    ckfree(FREECAST argv);
     2059    PyMem_Free(list);
     2060    return v;
    19502061}
    19512062
     
    19532064Tkapp_Split(PyObject *self, PyObject *args)
    19542065{
    1955         PyObject *v;
    1956         char *list;
    1957 
    1958         if (PyTuple_Size(args) == 1) {
    1959                 PyObject* o = PyTuple_GetItem(args, 0);
    1960                 if (PyTuple_Check(o)) {
    1961                         o = SplitObj(o);
    1962                         return o;
    1963                 }
    1964         }
    1965         if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
    1966                 return NULL;
    1967         v = Split(list);
    1968         PyMem_Free(list);
    1969         return v;
     2066    PyObject *arg, *v;
     2067    char *list;
     2068
     2069    if (!PyArg_ParseTuple(args, "O:split", &arg))
     2070        return NULL;
     2071    if (PyTclObject_Check(arg)) {
     2072        Tcl_Obj *value = ((PyTclObject*)arg)->value;
     2073        int objc;
     2074        Tcl_Obj **objv;
     2075        int i;
     2076        if (Tcl_ListObjGetElements(Tkapp_Interp(self), value,
     2077                                   &objc, &objv) == TCL_ERROR) {
     2078            return FromObj(self, value);
     2079        }
     2080        if (objc == 0)
     2081            return PyString_FromString("");
     2082        if (objc == 1)
     2083            return FromObj(self, objv[0]);
     2084        if (!(v = PyTuple_New(objc)))
     2085            return NULL;
     2086        for (i = 0; i < objc; i++) {
     2087            PyObject *s = FromObj(self, objv[i]);
     2088            if (!s || PyTuple_SetItem(v, i, s)) {
     2089                Py_DECREF(v);
     2090                return NULL;
     2091            }
     2092        }
     2093        return v;
     2094    }
     2095    if (PyTuple_Check(arg))
     2096        return SplitObj(arg);
     2097
     2098    if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
     2099        return NULL;
     2100    v = Split(list);
     2101    PyMem_Free(list);
     2102    return v;
    19702103}
    19712104
     
    19732106Tkapp_Merge(PyObject *self, PyObject *args)
    19742107{
    1975         char *s = Merge(args);
    1976         PyObject *res = NULL;
    1977 
    1978         if (s) {
    1979                 res = PyString_FromString(s);
    1980                 ckfree(s);
    1981         }
    1982 
    1983         return res;
    1984 }
    1985 
     2108    char *s = Merge(args);
     2109    PyObject *res = NULL;
     2110
     2111    if (s) {
     2112        res = PyString_FromString(s);
     2113        ckfree(s);
     2114    }
     2115
     2116    return res;
     2117}
    19862118
    19872119
     
    19912123/* Client data struct */
    19922124typedef struct {
    1993         PyObject *self;
    1994         PyObject *func;
     2125    PyObject *self;
     2126    PyObject *func;
    19952127} PythonCmd_ClientData;
    19962128
     
    19982130PythonCmd_Error(Tcl_Interp *interp)
    19992131{
    2000         errorInCmd = 1;
    2001         PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
    2002         LEAVE_PYTHON
    2003         return TCL_ERROR;
     2132    errorInCmd = 1;
     2133    PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
     2134    LEAVE_PYTHON
     2135    return TCL_ERROR;
    20042136}
    20052137
     
    20102142PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
    20112143{
    2012         PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
    2013         PyObject *self, *func, *arg, *res;
    2014         int i, rv;
    2015         Tcl_Obj *obj_res;
    2016 
    2017         ENTER_PYTHON
    2018 
    2019         /* TBD: no error checking here since we know, via the
    2020          * Tkapp_CreateCommand() that the client data is a two-tuple
    2021          */
    2022         self = data->self;
    2023         func = data->func;
    2024 
    2025         /* Create argument list (argv1, ..., argvN) */
    2026         if (!(arg = PyTuple_New(argc - 1)))
    2027                 return PythonCmd_Error(interp);
    2028 
    2029         for (i = 0; i < (argc - 1); i++) {
    2030                 PyObject *s = PyString_FromString(argv[i + 1]);
    2031                 if (!s || PyTuple_SetItem(arg, i, s)) {
    2032                         Py_DECREF(arg);
    2033                         return PythonCmd_Error(interp);
    2034                 }
    2035         }
    2036         res = PyEval_CallObject(func, arg);
    2037         Py_DECREF(arg);
    2038 
    2039         if (res == NULL)
    2040                 return PythonCmd_Error(interp);
    2041 
    2042         obj_res = AsObj(res);
    2043         if (obj_res == NULL) {
    2044                 Py_DECREF(res);
    2045                 return PythonCmd_Error(interp);
    2046         }
    2047         else {
    2048                 Tcl_SetObjResult(interp, obj_res);
    2049                 rv = TCL_OK;
    2050         }
    2051 
    2052         Py_DECREF(res);
    2053 
    2054         LEAVE_PYTHON
    2055 
    2056         return rv;
     2144    PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
     2145    PyObject *func, *arg, *res;
     2146    int i, rv;
     2147    Tcl_Obj *obj_res;
     2148
     2149    ENTER_PYTHON
     2150
     2151    /* TBD: no error checking here since we know, via the
     2152     * Tkapp_CreateCommand() that the client data is a two-tuple
     2153     */
     2154    func = data->func;
     2155
     2156    /* Create argument list (argv1, ..., argvN) */
     2157    if (!(arg = PyTuple_New(argc - 1)))
     2158        return PythonCmd_Error(interp);
     2159
     2160    for (i = 0; i < (argc - 1); i++) {
     2161        PyObject *s = PyString_FromString(argv[i + 1]);
     2162        if (!s || PyTuple_SetItem(arg, i, s)) {
     2163            Py_DECREF(arg);
     2164            return PythonCmd_Error(interp);
     2165        }
     2166    }
     2167    res = PyEval_CallObject(func, arg);
     2168    Py_DECREF(arg);
     2169
     2170    if (res == NULL)
     2171        return PythonCmd_Error(interp);
     2172
     2173    obj_res = AsObj(res);
     2174    if (obj_res == NULL) {
     2175        Py_DECREF(res);
     2176        return PythonCmd_Error(interp);
     2177    }
     2178    else {
     2179        Tcl_SetObjResult(interp, obj_res);
     2180        rv = TCL_OK;
     2181    }
     2182
     2183    Py_DECREF(res);
     2184
     2185    LEAVE_PYTHON
     2186
     2187    return rv;
    20572188}
    20582189
     
    20602191PythonCmdDelete(ClientData clientData)
    20612192{
    2062         PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
    2063 
    2064         ENTER_PYTHON
    2065         Py_XDECREF(data->self);
    2066         Py_XDECREF(data->func);
    2067         PyMem_DEL(data);
    2068         LEAVE_PYTHON
    2069 }
    2070 
    2071 
    2072 
    2073 
    2074 
     2193    PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
     2194
     2195    ENTER_PYTHON
     2196    Py_XDECREF(data->self);
     2197    Py_XDECREF(data->func);
     2198    PyMem_DEL(data);
     2199    LEAVE_PYTHON
     2200}
     2201
     2202
     2203
     2204
     2205#ifdef WITH_THREAD
    20752206TCL_DECLARE_MUTEX(command_mutex)
    20762207
    20772208typedef struct CommandEvent{
    2078         Tcl_Event ev;
    2079         Tcl_Interp* interp;
    2080         char *name;
    2081         int create;
    2082         int *status;
    2083         ClientData *data;
    2084         Tcl_Condition done;
     2209    Tcl_Event ev;
     2210    Tcl_Interp* interp;
     2211    char *name;
     2212    int create;
     2213    int *status;
     2214    ClientData *data;
     2215    Tcl_Condition *done;
    20852216} CommandEvent;
    20862217
     
    20882219Tkapp_CommandProc(CommandEvent *ev, int flags)
    20892220{
    2090         if (ev->create)
    2091                 *ev->status = Tcl_CreateCommand(
    2092                         ev->interp, ev->name, PythonCmd,
    2093                         ev->data, PythonCmdDelete) == NULL;
    2094         else
    2095                 *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
    2096         Tcl_MutexLock(&command_mutex);
    2097         Tcl_ConditionNotify(&ev->done);
    2098         Tcl_MutexUnlock(&command_mutex);
    2099         return 1;
    2100 }
     2221    if (ev->create)
     2222        *ev->status = Tcl_CreateCommand(
     2223            ev->interp, ev->name, PythonCmd,
     2224            ev->data, PythonCmdDelete) == NULL;
     2225    else
     2226        *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
     2227    Tcl_MutexLock(&command_mutex);
     2228    Tcl_ConditionNotify(ev->done);
     2229    Tcl_MutexUnlock(&command_mutex);
     2230    return 1;
     2231}
     2232#endif
    21012233
    21022234static PyObject *
    21032235Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
    21042236{
    2105         TkappObject *self = (TkappObject*)selfptr;
    2106         PythonCmd_ClientData *data;
    2107         char *cmdName;
    2108         PyObject *func;
    2109         int err;
    2110 
    2111         if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
    2112                 return NULL;
    2113         if (!PyCallable_Check(func)) {
    2114                 PyErr_SetString(PyExc_TypeError, "command not callable");
    2115                 return NULL;
    2116         }
     2237    TkappObject *self = (TkappObject*)selfptr;
     2238    PythonCmd_ClientData *data;
     2239    char *cmdName;
     2240    PyObject *func;
     2241    int err;
     2242
     2243    if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
     2244        return NULL;
     2245    if (!PyCallable_Check(func)) {
     2246        PyErr_SetString(PyExc_TypeError, "command not callable");
     2247        return NULL;
     2248    }
    21172249
    21182250#ifdef WITH_THREAD
    2119         if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
    2120             !WaitForMainloop(self))
    2121                 return NULL;
    2122 #endif
    2123 
    2124         data = PyMem_NEW(PythonCmd_ClientData, 1);
    2125         if (!data)
    2126                 return PyErr_NoMemory();
    2127         Py_INCREF(self);
    2128         Py_INCREF(func);
    2129         data->self = selfptr;
    2130         data->func = func;
    2131        
    2132         if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
    2133                 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
    2134                 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
    2135                 ev->interp = self->interp;
    2136                 ev->create = 1;
    2137                 ev->name = cmdName;
    2138                 ev->data = (ClientData)data;
    2139                 ev->status = &err;
    2140                 ev->done = NULL;
    2141                 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
    2142         }
    2143         else {
    2144                 ENTER_TCL
    2145                 err = Tcl_CreateCommand(
    2146                         Tkapp_Interp(self), cmdName, PythonCmd,
    2147                         (ClientData)data, PythonCmdDelete) == NULL;
    2148                 LEAVE_TCL
    2149         }
    2150         if (err) {
    2151                 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
    2152                 PyMem_DEL(data);
    2153                 return NULL;
    2154         }
    2155 
    2156         Py_INCREF(Py_None);
    2157         return Py_None;
    2158 }
    2159 
     2251    if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
     2252        !WaitForMainloop(self))
     2253        return NULL;
     2254#endif
     2255
     2256    data = PyMem_NEW(PythonCmd_ClientData, 1);
     2257    if (!data)
     2258        return PyErr_NoMemory();
     2259    Py_INCREF(self);
     2260    Py_INCREF(func);
     2261    data->self = selfptr;
     2262    data->func = func;
     2263
     2264#ifdef WITH_THREAD
     2265    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
     2266        Tcl_Condition cond = NULL;
     2267        CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
     2268        ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
     2269        ev->interp = self->interp;
     2270        ev->create = 1;
     2271        ev->name = cmdName;
     2272        ev->data = (ClientData)data;
     2273        ev->status = &err;
     2274        ev->done = &cond;
     2275        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
     2276        Tcl_ConditionFinalize(&cond);
     2277    }
     2278    else
     2279#endif
     2280    {
     2281        ENTER_TCL
     2282        err = Tcl_CreateCommand(
     2283            Tkapp_Interp(self), cmdName, PythonCmd,
     2284            (ClientData)data, PythonCmdDelete) == NULL;
     2285        LEAVE_TCL
     2286    }
     2287    if (err) {
     2288        PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
     2289        PyMem_DEL(data);
     2290        return NULL;
     2291    }
     2292
     2293    Py_INCREF(Py_None);
     2294    return Py_None;
     2295}
    21602296
    21612297
     
    21642300Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
    21652301{
    2166         TkappObject *self = (TkappObject*)selfptr;
    2167         char *cmdName;
    2168         int err;
    2169 
    2170         if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
    2171                 return NULL;
    2172         if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
    2173                 CommandEvent *ev;
    2174                 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
    2175                 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
    2176                 ev->interp = self->interp;
    2177                 ev->create = 0;
    2178                 ev->name = cmdName;
    2179                 ev->status = &err;
    2180                 ev->done = NULL;
    2181                 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
    2182                                  &command_mutex);
    2183         }
    2184         else {
    2185                 ENTER_TCL
    2186                 err = Tcl_DeleteCommand(self->interp, cmdName);
    2187                 LEAVE_TCL
    2188         }
    2189         if (err == -1) {
    2190                 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
    2191                 return NULL;
    2192         }
    2193         Py_INCREF(Py_None);
    2194         return Py_None;
    2195 }
    2196 
     2302    TkappObject *self = (TkappObject*)selfptr;
     2303    char *cmdName;
     2304    int err;
     2305
     2306    if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
     2307        return NULL;
     2308
     2309#ifdef WITH_THREAD
     2310    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
     2311        Tcl_Condition cond = NULL;
     2312        CommandEvent *ev;
     2313        ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
     2314        ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
     2315        ev->interp = self->interp;
     2316        ev->create = 0;
     2317        ev->name = cmdName;
     2318        ev->status = &err;
     2319        ev->done = &cond;
     2320        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
     2321                         &command_mutex);
     2322        Tcl_ConditionFinalize(&cond);
     2323    }
     2324    else
     2325#endif
     2326    {
     2327        ENTER_TCL
     2328        err = Tcl_DeleteCommand(self->interp, cmdName);
     2329        LEAVE_TCL
     2330    }
     2331    if (err == -1) {
     2332        PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
     2333        return NULL;
     2334    }
     2335    Py_INCREF(Py_None);
     2336    return Py_None;
     2337}
    21972338
    21982339
     
    22022343
    22032344typedef struct _fhcdata {
    2204         PyObject *func;
    2205         PyObject *file;
    2206         int id;
    2207         struct _fhcdata *next;
     2345    PyObject *func;
     2346    PyObject *file;
     2347    int id;
     2348    struct _fhcdata *next;
    22082349} FileHandler_ClientData;
    22092350
     
    22132354NewFHCD(PyObject *func, PyObject *file, int id)
    22142355{
    2215         FileHandler_ClientData *p;
    2216         p = PyMem_NEW(FileHandler_ClientData, 1);
    2217         if (p != NULL) {
    2218                 Py_XINCREF(func);
    2219                 Py_XINCREF(file);
    2220                 p->func = func;
    2221                 p->file = file;
    2222                 p->id = id;
    2223                 p->next = HeadFHCD;
    2224                 HeadFHCD = p;
    2225         }
    2226         return p;
     2356    FileHandler_ClientData *p;
     2357    p = PyMem_NEW(FileHandler_ClientData, 1);
     2358    if (p != NULL) {
     2359        Py_XINCREF(func);
     2360        Py_XINCREF(file);
     2361        p->func = func;
     2362        p->file = file;
     2363        p->id = id;
     2364        p->next = HeadFHCD;
     2365        HeadFHCD = p;
     2366    }
     2367    return p;
    22272368}
    22282369
     
    22302371DeleteFHCD(int id)
    22312372{
    2232         FileHandler_ClientData *p, **pp;
    2233 
    2234         pp = &HeadFHCD;
    2235         while ((p = *pp) != NULL) {
    2236                 if (p->id == id) {
    2237                         *pp = p->next;
    2238                         Py_XDECREF(p->func);
    2239                         Py_XDECREF(p->file);
    2240                         PyMem_DEL(p);
    2241                 }
    2242                 else
    2243                         pp = &p->next;
    2244         }
     2373    FileHandler_ClientData *p, **pp;
     2374
     2375    pp = &HeadFHCD;
     2376    while ((p = *pp) != NULL) {
     2377        if (p->id == id) {
     2378            *pp = p->next;
     2379            Py_XDECREF(p->func);
     2380            Py_XDECREF(p->file);
     2381            PyMem_DEL(p);
     2382        }
     2383        else
     2384            pp = &p->next;
     2385    }
    22452386}
    22462387
     
    22482389FileHandler(ClientData clientData, int mask)
    22492390{
    2250         FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
    2251         PyObject *func, *file, *arg, *res;
    2252 
    2253         ENTER_PYTHON
    2254         func = data->func;
    2255         file = data->file;
    2256 
    2257         arg = Py_BuildValue("(Oi)", file, (long) mask);
    2258         res = PyEval_CallObject(func, arg);
    2259         Py_DECREF(arg);
    2260 
    2261         if (res == NULL) {
    2262                 errorInCmd = 1;
    2263                 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
    2264         }
    2265         Py_XDECREF(res);
    2266         LEAVE_PYTHON
     2391    FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
     2392    PyObject *func, *file, *arg, *res;
     2393
     2394    ENTER_PYTHON
     2395    func = data->func;
     2396    file = data->file;
     2397
     2398    arg = Py_BuildValue("(Oi)", file, (long) mask);
     2399    res = PyEval_CallObject(func, arg);
     2400    Py_DECREF(arg);
     2401
     2402    if (res == NULL) {
     2403        errorInCmd = 1;
     2404        PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
     2405    }
     2406    Py_XDECREF(res);
     2407    LEAVE_PYTHON
    22672408}
    22682409
     
    22712412     /* args is (file, mask, func) */
    22722413{
    2273         FileHandler_ClientData *data;
    2274         PyObject *file, *func;
    2275         int mask, tfile;
    2276 
    2277         if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
    2278                               &file, &mask, &func))
    2279                 return NULL;
     2414    FileHandler_ClientData *data;
     2415    PyObject *file, *func;
     2416    int mask, tfile;
     2417
     2418    if (!self && Py_Py3kWarningFlag) {
     2419        if (PyErr_Warn(PyExc_DeprecationWarning,
     2420                                "_tkinter.createfilehandler is gone in 3.x") < 0)
     2421            return NULL;
     2422    }
     2423
     2424    if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
     2425                          &file, &mask, &func))
     2426        return NULL;
    22802427
    22812428#ifdef WITH_THREAD
    2282         if (!self && !tcl_lock) {
    2283                 /* We don't have the Tcl lock since Tcl is threaded. */
    2284                 PyErr_SetString(PyExc_RuntimeError,
    2285                                 "_tkinter.createfilehandler not supported "
    2286                                 "for threaded Tcl");
    2287                 return NULL;
    2288         }
    2289 #endif
    2290 
    2291         if (self) {
    2292                 CHECK_TCL_APPARTMENT;
    2293         }
    2294 
    2295         tfile = PyObject_AsFileDescriptor(file);
    2296         if (tfile < 0)
    2297                 return NULL;
    2298         if (!PyCallable_Check(func)) {
    2299                 PyErr_SetString(PyExc_TypeError, "bad argument list");
    2300                 return NULL;
    2301         }
    2302 
    2303         data = NewFHCD(func, file, tfile);
    2304         if (data == NULL)
    2305                 return NULL;
    2306 
    2307         /* Ought to check for null Tcl_File object... */
    2308         ENTER_TCL
    2309         Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
    2310         LEAVE_TCL
    2311         Py_INCREF(Py_None);
    2312         return Py_None;
     2429    if (!self && !tcl_lock) {
     2430        /* We don't have the Tcl lock since Tcl is threaded. */
     2431        PyErr_SetString(PyExc_RuntimeError,
     2432                        "_tkinter.createfilehandler not supported "
     2433                        "for threaded Tcl");
     2434        return NULL;
     2435    }
     2436#endif
     2437
     2438    if (self) {
     2439        CHECK_TCL_APPARTMENT;
     2440    }
     2441
     2442    tfile = PyObject_AsFileDescriptor(file);
     2443    if (tfile < 0)
     2444        return NULL;
     2445    if (!PyCallable_Check(func)) {
     2446        PyErr_SetString(PyExc_TypeError, "bad argument list");
     2447        return NULL;
     2448    }
     2449
     2450    data = NewFHCD(func, file, tfile);
     2451    if (data == NULL)
     2452        return NULL;
     2453
     2454    /* Ought to check for null Tcl_File object... */
     2455    ENTER_TCL
     2456    Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
     2457    LEAVE_TCL
     2458    Py_INCREF(Py_None);
     2459    return Py_None;
    23132460}
    23142461
     
    23162463Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
    23172464{
    2318         PyObject *file;
    2319         int tfile;
    2320 
    2321         if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
    2322                 return NULL;
     2465    PyObject *file;
     2466    int tfile;
     2467
     2468    if (!self && Py_Py3kWarningFlag) {
     2469        if (PyErr_Warn(PyExc_DeprecationWarning,
     2470                                "_tkinter.deletefilehandler is gone in 3.x") < 0)
     2471            return NULL;
     2472    }
     2473
     2474    if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
     2475        return NULL;
    23232476
    23242477#ifdef WITH_THREAD
    2325         if (!self && !tcl_lock) {
    2326                 /* We don't have the Tcl lock since Tcl is threaded. */
    2327                 PyErr_SetString(PyExc_RuntimeError,
    2328                                 "_tkinter.deletefilehandler not supported "
    2329                                 "for threaded Tcl");
    2330                 return NULL;
    2331         }
    2332 #endif
    2333 
    2334         if (self) {
    2335                 CHECK_TCL_APPARTMENT;
    2336         }
    2337 
    2338         tfile = PyObject_AsFileDescriptor(file);
    2339         if (tfile < 0)
    2340                 return NULL;
    2341 
    2342         DeleteFHCD(tfile);
    2343 
    2344         /* Ought to check for null Tcl_File object... */
    2345         ENTER_TCL
    2346         Tcl_DeleteFileHandler(tfile);
    2347         LEAVE_TCL
    2348         Py_INCREF(Py_None);
    2349         return Py_None;
     2478    if (!self && !tcl_lock) {
     2479        /* We don't have the Tcl lock since Tcl is threaded. */
     2480        PyErr_SetString(PyExc_RuntimeError,
     2481                        "_tkinter.deletefilehandler not supported "
     2482                        "for threaded Tcl");
     2483        return NULL;
     2484    }
     2485#endif
     2486
     2487    if (self) {
     2488        CHECK_TCL_APPARTMENT;
     2489    }
     2490
     2491    tfile = PyObject_AsFileDescriptor(file);
     2492    if (tfile < 0)
     2493        return NULL;
     2494
     2495    DeleteFHCD(tfile);
     2496
     2497    /* Ought to check for null Tcl_File object... */
     2498    ENTER_TCL
     2499    Tcl_DeleteFileHandler(tfile);
     2500    LEAVE_TCL
     2501    Py_INCREF(Py_None);
     2502    return Py_None;
    23502503}
    23512504#endif /* HAVE_CREATEFILEHANDLER */
    23522505
    23532506
    2354 
    23552507/**** Tktt Object (timer token) ****/
    23562508
     
    23582510
    23592511typedef struct {
    2360         PyObject_HEAD
    2361         Tcl_TimerToken token;
    2362         PyObject *func;
     2512    PyObject_HEAD
     2513    Tcl_TimerToken token;
     2514    PyObject *func;
    23632515} TkttObject;
    23642516
     
    23662518Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
    23672519{
    2368         TkttObject *v = (TkttObject *)self;
    2369         PyObject *func = v->func;
    2370 
    2371         if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
    2372                 return NULL;
    2373         if (v->token != NULL) {
    2374                 Tcl_DeleteTimerHandler(v->token);
    2375                 v->token = NULL;
    2376         }
    2377         if (func != NULL) {
    2378                 v->func = NULL;
    2379                 Py_DECREF(func);
    2380                 Py_DECREF(v); /* See Tktt_New() */
    2381         }
    2382         Py_INCREF(Py_None);
    2383         return Py_None;
     2520    TkttObject *v = (TkttObject *)self;
     2521    PyObject *func = v->func;
     2522
     2523    if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
     2524        return NULL;
     2525    if (v->token != NULL) {
     2526        Tcl_DeleteTimerHandler(v->token);
     2527        v->token = NULL;
     2528    }
     2529    if (func != NULL) {
     2530        v->func = NULL;
     2531        Py_DECREF(func);
     2532        Py_DECREF(v); /* See Tktt_New() */
     2533    }
     2534    Py_INCREF(Py_None);
     2535    return Py_None;
    23842536}
    23852537
    23862538static PyMethodDef Tktt_methods[] =
    23872539{
    2388         {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
    2389         {NULL, NULL}
     2540    {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
     2541    {NULL, NULL}
    23902542};
    23912543
     
    23932545Tktt_New(PyObject *func)
    23942546{
    2395         TkttObject *v;
    2396  
    2397         v = PyObject_New(TkttObject, &Tktt_Type);
    2398         if (v == NULL)
    2399                 return NULL;
    2400 
    2401         Py_INCREF(func);
    2402         v->token = NULL;
    2403         v->func = func;
    2404 
    2405         /* Extra reference, deleted when called or when handler is deleted */
    2406         Py_INCREF(v);
    2407         return v;
     2547    TkttObject *v;
     2548
     2549    v = PyObject_New(TkttObject, &Tktt_Type);
     2550    if (v == NULL)
     2551        return NULL;
     2552
     2553    Py_INCREF(func);
     2554    v->token = NULL;
     2555    v->func = func;
     2556
     2557    /* Extra reference, deleted when called or when handler is deleted */
     2558    Py_INCREF(v);
     2559    return v;
    24082560}
    24092561
     
    24112563Tktt_Dealloc(PyObject *self)
    24122564{
    2413         TkttObject *v = (TkttObject *)self;
    2414         PyObject *func = v->func;
    2415 
    2416         Py_XDECREF(func);
    2417 
    2418         PyObject_Del(self);
     2565    TkttObject *v = (TkttObject *)self;
     2566    PyObject *func = v->func;
     2567
     2568    Py_XDECREF(func);
     2569
     2570    PyObject_Del(self);
    24192571}
    24202572
     
    24222574Tktt_Repr(PyObject *self)
    24232575{
    2424         TkttObject *v = (TkttObject *)self;
    2425         char buf[100];
    2426 
    2427         PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
    2428                         v->func == NULL ? ", handler deleted" : "");
    2429         return PyString_FromString(buf);
     2576    TkttObject *v = (TkttObject *)self;
     2577    char buf[100];
     2578
     2579    PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
     2580                    v->func == NULL ? ", handler deleted" : "");
     2581    return PyString_FromString(buf);
    24302582}
    24312583
     
    24332585Tktt_GetAttr(PyObject *self, char *name)
    24342586{
    2435         return Py_FindMethod(Tktt_methods, self, name);
     2587    return Py_FindMethod(Tktt_methods, self, name);
    24362588}
    24372589
    24382590static PyTypeObject Tktt_Type =
    24392591{
    2440         PyVarObject_HEAD_INIT(NULL, 0)
    2441         "tktimertoken",                      /*tp_name */
    2442         sizeof(TkttObject),                  /*tp_basicsize */
    2443         0,                                   /*tp_itemsize */
    2444         Tktt_Dealloc,                        /*tp_dealloc */
    2445         0,                                   /*tp_print */
    2446         Tktt_GetAttr,                        /*tp_getattr */
    2447         0,                                   /*tp_setattr */
    2448         0,                                   /*tp_compare */
    2449         Tktt_Repr,                           /*tp_repr */
    2450         0,                                   /*tp_as_number */
    2451         0,                                   /*tp_as_sequence */
    2452         0,                                   /*tp_as_mapping */
    2453         0,                                   /*tp_hash */
     2592    PyVarObject_HEAD_INIT(NULL, 0)
     2593    "tktimertoken",                          /*tp_name */
     2594    sizeof(TkttObject),                      /*tp_basicsize */
     2595    0,                                       /*tp_itemsize */
     2596    Tktt_Dealloc,                            /*tp_dealloc */
     2597    0,                                       /*tp_print */
     2598    Tktt_GetAttr,                            /*tp_getattr */
     2599    0,                                       /*tp_setattr */
     2600    0,                                       /*tp_compare */
     2601    Tktt_Repr,                               /*tp_repr */
     2602    0,                                       /*tp_as_number */
     2603    0,                                       /*tp_as_sequence */
     2604    0,                                       /*tp_as_mapping */
     2605    0,                                       /*tp_hash */
    24542606};
    2455 
    24562607
    24572608
     
    24622613TimerHandler(ClientData clientData)
    24632614{
    2464         TkttObject *v = (TkttObject *)clientData;
    2465         PyObject *func = v->func;
    2466         PyObject *res;
    2467 
    2468         if (func == NULL)
    2469                 return;
    2470 
    2471         v->func = NULL;
    2472 
    2473         ENTER_PYTHON
    2474 
    2475         res  = PyEval_CallObject(func, NULL);
    2476         Py_DECREF(func);
    2477         Py_DECREF(v); /* See Tktt_New() */
    2478 
    2479         if (res == NULL) {
    2480                 errorInCmd = 1;
    2481                 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
    2482         }
    2483         else
    2484                 Py_DECREF(res);
    2485 
    2486         LEAVE_PYTHON
     2615    TkttObject *v = (TkttObject *)clientData;
     2616    PyObject *func = v->func;
     2617    PyObject *res;
     2618
     2619    if (func == NULL)
     2620        return;
     2621
     2622    v->func = NULL;
     2623
     2624    ENTER_PYTHON
     2625
     2626    res  = PyEval_CallObject(func, NULL);
     2627    Py_DECREF(func);
     2628    Py_DECREF(v); /* See Tktt_New() */
     2629
     2630    if (res == NULL) {
     2631        errorInCmd = 1;
     2632        PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
     2633    }
     2634    else
     2635        Py_DECREF(res);
     2636
     2637    LEAVE_PYTHON
    24872638}
    24882639
     
    24902641Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
    24912642{
    2492         int milliseconds;
    2493         PyObject *func;
    2494         TkttObject *v;
    2495 
    2496         if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
    2497                               &milliseconds, &func))
    2498                 return NULL;
    2499         if (!PyCallable_Check(func)) {
    2500                 PyErr_SetString(PyExc_TypeError, "bad argument list");
    2501                 return NULL;
    2502         }
     2643    int milliseconds;
     2644    PyObject *func;
     2645    TkttObject *v;
     2646
     2647    if (!self && Py_Py3kWarningFlag) {
     2648        if (PyErr_Warn(PyExc_DeprecationWarning,
     2649                                "_tkinter.createtimerhandler is gone in 3.x") < 0)
     2650            return NULL;
     2651    }
     2652
     2653    if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
     2654                          &milliseconds, &func))
     2655        return NULL;
     2656    if (!PyCallable_Check(func)) {
     2657        PyErr_SetString(PyExc_TypeError, "bad argument list");
     2658        return NULL;
     2659    }
    25032660
    25042661#ifdef WITH_THREAD
    2505         if (!self && !tcl_lock) {
    2506                 /* We don't have the Tcl lock since Tcl is threaded. */
    2507                 PyErr_SetString(PyExc_RuntimeError,
    2508                                 "_tkinter.createtimerhandler not supported "
    2509                                 "for threaded Tcl");
    2510                 return NULL;
    2511         }
    2512 #endif
    2513 
    2514         if (self) {
    2515                 CHECK_TCL_APPARTMENT;
    2516         }
    2517 
    2518         v = Tktt_New(func);
    2519         if (v) {
    2520                 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
    2521                                                   (ClientData)v);
    2522         }
    2523 
    2524         return (PyObject *) v;
    2525 }
    2526 
     2662    if (!self && !tcl_lock) {
     2663        /* We don't have the Tcl lock since Tcl is threaded. */
     2664        PyErr_SetString(PyExc_RuntimeError,
     2665                        "_tkinter.createtimerhandler not supported "
     2666                        "for threaded Tcl");
     2667        return NULL;
     2668    }
     2669#endif
     2670
     2671    if (self) {
     2672        CHECK_TCL_APPARTMENT;
     2673    }
     2674
     2675    v = Tktt_New(func);
     2676    if (v) {
     2677        v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
     2678                                          (ClientData)v);
     2679    }
     2680
     2681    return (PyObject *) v;
     2682}
    25272683
    25282684
     
    25322688Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
    25332689{
    2534         int threshold = 0;
    2535         TkappObject *self = (TkappObject*)selfptr;
     2690    int threshold = 0;
     2691    TkappObject *self = (TkappObject*)selfptr;
    25362692#ifdef WITH_THREAD
    2537         PyThreadState *tstate = PyThreadState_Get();
    2538 #endif
    2539 
    2540         if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
    2541                 return NULL;
     2693    PyThreadState *tstate = PyThreadState_Get();
     2694#endif
     2695
     2696    if (!self && Py_Py3kWarningFlag) {
     2697        if (PyErr_Warn(PyExc_DeprecationWarning,
     2698                                "_tkinter.mainloop is gone in 3.x") < 0)
     2699            return NULL;
     2700    }
     2701
     2702    if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
     2703        return NULL;
    25422704
    25432705#ifdef WITH_THREAD
    2544         if (!self && !tcl_lock) {
    2545                 /* We don't have the Tcl lock since Tcl is threaded. */
    2546                 PyErr_SetString(PyExc_RuntimeError,
    2547                                 "_tkinter.mainloop not supported "
    2548                                 "for threaded Tcl");
    2549                 return NULL;
    2550         }
    2551 #endif
    2552 
    2553         if (self) {
    2554                 CHECK_TCL_APPARTMENT;
    2555                 self->dispatching = 1;
    2556         }
    2557 
    2558         quitMainLoop = 0;
    2559         while (Tk_GetNumMainWindows() > threshold &&
    2560                !quitMainLoop &&
    2561                !errorInCmd)
    2562         {
    2563                 int result;
     2706    if (!self && !tcl_lock) {
     2707        /* We don't have the Tcl lock since Tcl is threaded. */
     2708        PyErr_SetString(PyExc_RuntimeError,
     2709                        "_tkinter.mainloop not supported "
     2710                        "for threaded Tcl");
     2711        return NULL;
     2712    }
     2713#endif
     2714
     2715    if (self) {
     2716        CHECK_TCL_APPARTMENT;
     2717        self->dispatching = 1;
     2718    }
     2719
     2720    quitMainLoop = 0;
     2721    while (Tk_GetNumMainWindows() > threshold &&
     2722           !quitMainLoop &&
     2723           !errorInCmd)
     2724    {
     2725        int result;
    25642726
    25652727#ifdef WITH_THREAD
    2566                 if (self && self->threaded) {
    2567                         /* Allow other Python threads to run. */
    2568                         ENTER_TCL
    2569                         result = Tcl_DoOneEvent(0);
    2570                         LEAVE_TCL
    2571                 }
    2572                 else {
    2573                         Py_BEGIN_ALLOW_THREADS
    2574                         if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
    2575                         tcl_tstate = tstate;
    2576                         result = Tcl_DoOneEvent(TCL_DONT_WAIT);
    2577                         tcl_tstate = NULL;
    2578                         if(tcl_lock)PyThread_release_lock(tcl_lock);
    2579                         if (result == 0)
    2580                                 Sleep(Tkinter_busywaitinterval);
    2581                         Py_END_ALLOW_THREADS
    2582                 }
     2728        if (self && self->threaded) {
     2729            /* Allow other Python threads to run. */
     2730            ENTER_TCL
     2731            result = Tcl_DoOneEvent(0);
     2732            LEAVE_TCL
     2733        }
     2734        else {
     2735            Py_BEGIN_ALLOW_THREADS
     2736            if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
     2737            tcl_tstate = tstate;
     2738            result = Tcl_DoOneEvent(TCL_DONT_WAIT);
     2739            tcl_tstate = NULL;
     2740            if(tcl_lock)PyThread_release_lock(tcl_lock);
     2741            if (result == 0)
     2742                Sleep(Tkinter_busywaitinterval);
     2743            Py_END_ALLOW_THREADS
     2744        }
    25832745#else
    2584                 result = Tcl_DoOneEvent(0);
    2585 #endif
    2586 
    2587                 if (PyErr_CheckSignals() != 0) {
    2588                         if (self)
    2589                                 self->dispatching = 0;
    2590                         return NULL;
    2591                 }
    2592                 if (result < 0)
    2593                         break;
    2594         }
    2595         if (self)
    2596                 self->dispatching = 0;
    2597         quitMainLoop = 0;
    2598 
    2599         if (errorInCmd) {
    2600                 errorInCmd = 0;
    2601                 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
    2602                 excInCmd = valInCmd = trbInCmd = NULL;
    2603                 return NULL;
    2604         }
    2605         Py_INCREF(Py_None);
    2606         return Py_None;
     2746        result = Tcl_DoOneEvent(0);
     2747#endif
     2748
     2749        if (PyErr_CheckSignals() != 0) {
     2750            if (self)
     2751                self->dispatching = 0;
     2752            return NULL;
     2753        }
     2754        if (result < 0)
     2755            break;
     2756    }
     2757    if (self)
     2758        self->dispatching = 0;
     2759    quitMainLoop = 0;
     2760
     2761    if (errorInCmd) {
     2762        errorInCmd = 0;
     2763        PyErr_Restore(excInCmd, valInCmd, trbInCmd);
     2764        excInCmd = valInCmd = trbInCmd = NULL;
     2765        return NULL;
     2766    }
     2767    Py_INCREF(Py_None);
     2768    return Py_None;
    26072769}
    26082770
     
    26102772Tkapp_DoOneEvent(PyObject *self, PyObject *args)
    26112773{
    2612         int flags = 0;
    2613         int rv;
    2614 
    2615         if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
    2616                 return NULL;
    2617 
    2618         ENTER_TCL
    2619         rv = Tcl_DoOneEvent(flags);
    2620         LEAVE_TCL
    2621         return Py_BuildValue("i", rv);
     2774    int flags = 0;
     2775    int rv;
     2776
     2777    if (!self && Py_Py3kWarningFlag) {
     2778        if (PyErr_Warn(PyExc_DeprecationWarning,
     2779                                "_tkinter.dooneevent is gone in 3.x") < 0)
     2780            return NULL;
     2781    }
     2782
     2783    if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
     2784        return NULL;
     2785
     2786    ENTER_TCL
     2787    rv = Tcl_DoOneEvent(flags);
     2788    LEAVE_TCL
     2789    return Py_BuildValue("i", rv);
    26222790}
    26232791
     
    26262794{
    26272795
    2628         if (!PyArg_ParseTuple(args, ":quit"))
    2629                 return NULL;
    2630 
    2631         quitMainLoop = 1;
    2632         Py_INCREF(Py_None);
    2633         return Py_None;
     2796    if (!self && Py_Py3kWarningFlag) {
     2797        if (PyErr_Warn(PyExc_DeprecationWarning,
     2798                                "_tkinter.quit is gone in 3.x") < 0)
     2799            return NULL;
     2800    }
     2801
     2802    if (!PyArg_ParseTuple(args, ":quit"))
     2803        return NULL;
     2804
     2805    quitMainLoop = 1;
     2806    Py_INCREF(Py_None);
     2807    return Py_None;
    26342808}
    26352809
     
    26382812{
    26392813
    2640         if (!PyArg_ParseTuple(args, ":interpaddr"))
    2641                 return NULL;
    2642 
    2643         return PyInt_FromLong((long)Tkapp_Interp(self));
    2644 }
    2645 
    2646 static PyObject *
     2814    if (!PyArg_ParseTuple(args, ":interpaddr"))
     2815        return NULL;
     2816
     2817    return PyLong_FromVoidPtr(Tkapp_Interp(self));
     2818}
     2819
     2820static PyObject *
    26472821Tkapp_TkInit(PyObject *self, PyObject *args)
    26482822{
    2649         static int has_failed;
    2650         Tcl_Interp *interp = Tkapp_Interp(self);
    2651         Tk_Window main_window;
    2652         const char * _tk_exists = NULL;
    2653         int err;
    2654         main_window = Tk_MainWindow(interp);
    2655 
    2656         /* In all current versions of Tk (including 8.4.13), Tk_Init
    2657            deadlocks on the second call when the first call failed.
    2658            To avoid the deadlock, we just refuse the second call through
    2659            a static variable. */
    2660         if (has_failed) {
    2661                 PyErr_SetString(Tkinter_TclError,
    2662                                 "Calling Tk_Init again after a previous call failed might deadlock");
    2663                 return NULL;
    2664         }
    2665            
    2666         /* We want to guard against calling Tk_Init() multiple times */
    2667         CHECK_TCL_APPARTMENT;
    2668         ENTER_TCL
    2669         err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
    2670         ENTER_OVERLAP
    2671         if (err == TCL_ERROR) {
    2672                 /* This sets an exception, but we cannot return right
    2673                    away because we need to exit the overlap first. */
    2674                 Tkinter_Error(self);
    2675         } else {
    2676                 _tk_exists = Tkapp_Result(self);
    2677         }
    2678         LEAVE_OVERLAP_TCL
    2679         if (err == TCL_ERROR) {
    2680                 return NULL;
    2681         }
    2682         if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
    2683                 if (Tk_Init(interp)     == TCL_ERROR) {
    2684                         PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
    2685                         has_failed = 1;
    2686                         return NULL;
    2687                 }
    2688         }
    2689         Py_INCREF(Py_None);
    2690         return Py_None;
     2823    Tcl_Interp *interp = Tkapp_Interp(self);
     2824    const char * _tk_exists = NULL;
     2825    int err;
     2826
     2827#ifdef TKINTER_PROTECT_LOADTK
     2828    /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
     2829     * first call failed.
     2830     * To avoid the deadlock, we just refuse the second call through
     2831     * a static variable.
     2832     */
     2833    if (tk_load_failed) {
     2834        PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
     2835        return NULL;
     2836    }
     2837#endif
     2838
     2839    /* We want to guard against calling Tk_Init() multiple times */
     2840    CHECK_TCL_APPARTMENT;
     2841    ENTER_TCL
     2842    err = Tcl_Eval(Tkapp_Interp(self), "info exists     tk_version");
     2843    ENTER_OVERLAP
     2844    if (err == TCL_ERROR) {
     2845        /* This sets an exception, but we cannot return right
     2846           away because we need to exit the overlap first. */
     2847        Tkinter_Error(self);
     2848    } else {
     2849        _tk_exists = Tkapp_Result(self);
     2850    }
     2851    LEAVE_OVERLAP_TCL
     2852    if (err == TCL_ERROR) {
     2853        return NULL;
     2854    }
     2855    if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0)     {
     2856        if (Tk_Init(interp)             == TCL_ERROR) {
     2857            PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
     2858#ifdef TKINTER_PROTECT_LOADTK
     2859            tk_load_failed = 1;
     2860#endif
     2861            return NULL;
     2862        }
     2863    }
     2864    Py_INCREF(Py_None);
     2865    return Py_None;
    26912866}
    26922867
     
    26952870{
    26962871
    2697         int wantobjects = -1;
    2698         if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
    2699                 return NULL;
    2700         if (wantobjects == -1)
    2701                 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
    2702         ((TkappObject*)self)->wantobjects = wantobjects;
    2703 
    2704         Py_INCREF(Py_None);
    2705         return Py_None;
     2872    int wantobjects = -1;
     2873    if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
     2874        return NULL;
     2875    if (wantobjects == -1)
     2876        return PyBool_FromLong(((TkappObject*)self)->wantobjects);
     2877    ((TkappObject*)self)->wantobjects = wantobjects;
     2878
     2879    Py_INCREF(Py_None);
     2880    return Py_None;
    27062881}
    27072882
     
    27102885{
    27112886
    2712         ((TkappObject*)self)->dispatching = 1;
    2713 
    2714         Py_INCREF(Py_None);
    2715         return Py_None;
    2716 }
    2717 
     2887    ((TkappObject*)self)->dispatching = 1;
     2888
     2889    Py_INCREF(Py_None);
     2890    return Py_None;
     2891}
    27182892
    27192893
     
    27222896static PyMethodDef Tkapp_methods[] =
    27232897{
    2724         {"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
    2725         {"wantobjects",        Tkapp_WantObjects, METH_VARARGS},
    2726         {"call",               Tkapp_Call, METH_VARARGS},
    2727         {"globalcall",         Tkapp_GlobalCall, METH_VARARGS},
    2728         {"eval",               Tkapp_Eval, METH_VARARGS},
    2729         {"globaleval",         Tkapp_GlobalEval, METH_VARARGS},
    2730         {"evalfile",           Tkapp_EvalFile, METH_VARARGS},
    2731         {"record",             Tkapp_Record, METH_VARARGS},
    2732         {"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
    2733         {"setvar",             Tkapp_SetVar, METH_VARARGS},
    2734         {"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
    2735         {"getvar",             Tkapp_GetVar, METH_VARARGS},
    2736         {"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
    2737         {"unsetvar",           Tkapp_UnsetVar, METH_VARARGS},
    2738         {"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
    2739         {"getint",             Tkapp_GetInt, METH_VARARGS},
    2740         {"getdouble",          Tkapp_GetDouble, METH_VARARGS},
    2741         {"getboolean",         Tkapp_GetBoolean, METH_VARARGS},
    2742         {"exprstring",         Tkapp_ExprString, METH_VARARGS},
    2743         {"exprlong",           Tkapp_ExprLong, METH_VARARGS},
    2744         {"exprdouble",         Tkapp_ExprDouble, METH_VARARGS},
    2745         {"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
    2746         {"splitlist",          Tkapp_SplitList, METH_VARARGS},
    2747         {"split",              Tkapp_Split, METH_VARARGS},
    2748         {"merge",              Tkapp_Merge, METH_VARARGS},
    2749         {"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
    2750         {"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
     2898    {"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
     2899    {"wantobjects",            Tkapp_WantObjects, METH_VARARGS},
     2900    {"call",                   Tkapp_Call, METH_VARARGS},
     2901    {"globalcall",             Tkapp_GlobalCall, METH_VARARGS},
     2902    {"eval",                   Tkapp_Eval, METH_VARARGS},
     2903    {"globaleval",             Tkapp_GlobalEval, METH_VARARGS},
     2904    {"evalfile",               Tkapp_EvalFile, METH_VARARGS},
     2905    {"record",                 Tkapp_Record, METH_VARARGS},
     2906    {"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
     2907    {"setvar",                 Tkapp_SetVar, METH_VARARGS},
     2908    {"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
     2909    {"getvar",                 Tkapp_GetVar, METH_VARARGS},
     2910    {"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
     2911    {"unsetvar",               Tkapp_UnsetVar, METH_VARARGS},
     2912    {"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
     2913    {"getint",                 Tkapp_GetInt, METH_VARARGS},
     2914    {"getdouble",              Tkapp_GetDouble, METH_VARARGS},
     2915    {"getboolean",             Tkapp_GetBoolean, METH_VARARGS},
     2916    {"exprstring",             Tkapp_ExprString, METH_VARARGS},
     2917    {"exprlong",               Tkapp_ExprLong, METH_VARARGS},
     2918    {"exprdouble",             Tkapp_ExprDouble, METH_VARARGS},
     2919    {"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
     2920    {"splitlist",              Tkapp_SplitList, METH_VARARGS},
     2921    {"split",                  Tkapp_Split, METH_VARARGS},
     2922    {"merge",                  Tkapp_Merge, METH_VARARGS},
     2923    {"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
     2924    {"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
    27512925#ifdef HAVE_CREATEFILEHANDLER
    2752         {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
    2753         {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
    2754 #endif
    2755         {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
    2756         {"mainloop",           Tkapp_MainLoop, METH_VARARGS},
    2757         {"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
    2758         {"quit",               Tkapp_Quit, METH_VARARGS},
    2759         {"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
    2760         {"loadtk",             Tkapp_TkInit, METH_NOARGS},
    2761         {NULL,                 NULL}
     2926    {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
     2927    {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
     2928#endif
     2929    {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
     2930    {"mainloop",               Tkapp_MainLoop, METH_VARARGS},
     2931    {"dooneevent",             Tkapp_DoOneEvent, METH_VARARGS},
     2932    {"quit",                   Tkapp_Quit, METH_VARARGS},
     2933    {"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
     2934    {"loadtk",                 Tkapp_TkInit, METH_NOARGS},
     2935    {NULL,                     NULL}
    27622936};
    2763 
    27642937
    27652938
     
    27702943Tkapp_Dealloc(PyObject *self)
    27712944{
    2772         /*CHECK_TCL_APPARTMENT;*/
    2773         ENTER_TCL
    2774         Tcl_DeleteInterp(Tkapp_Interp(self));
    2775         LEAVE_TCL
    2776         PyObject_Del(self);
    2777         DisableEventHook();
     2945    /*CHECK_TCL_APPARTMENT;*/
     2946    ENTER_TCL
     2947    Tcl_DeleteInterp(Tkapp_Interp(self));
     2948    LEAVE_TCL
     2949    PyObject_Del(self);
     2950    DisableEventHook();
    27782951}
    27792952
     
    27812954Tkapp_GetAttr(PyObject *self, char *name)
    27822955{
    2783         return Py_FindMethod(Tkapp_methods, self, name);
     2956    return Py_FindMethod(Tkapp_methods, self, name);
    27842957}
    27852958
    27862959static PyTypeObject Tkapp_Type =
    27872960{
    2788         PyVarObject_HEAD_INIT(NULL, 0)
    2789         "tkapp",                             /*tp_name */
    2790         sizeof(TkappObject),                 /*tp_basicsize */
    2791         0,                                   /*tp_itemsize */
    2792         Tkapp_Dealloc,                       /*tp_dealloc */
    2793         0,                                   /*tp_print */
    2794         Tkapp_GetAttr,                       /*tp_getattr */
    2795         0,                                   /*tp_setattr */
    2796         0,                                   /*tp_compare */
    2797         0,                                   /*tp_repr */
    2798         0,                                   /*tp_as_number */
    2799         0,                                   /*tp_as_sequence */
    2800         0,                                   /*tp_as_mapping */
    2801         0,                                   /*tp_hash */
     2961    PyVarObject_HEAD_INIT(NULL, 0)
     2962    "tkapp",                                 /*tp_name */
     2963    sizeof(TkappObject),                     /*tp_basicsize */
     2964    0,                                       /*tp_itemsize */
     2965    Tkapp_Dealloc,                           /*tp_dealloc */
     2966    0,                                       /*tp_print */
     2967    Tkapp_GetAttr,                           /*tp_getattr */
     2968    0,                                       /*tp_setattr */
     2969    0,                                       /*tp_compare */
     2970    0,                                       /*tp_repr */
     2971    0,                                       /*tp_as_number */
     2972    0,                                       /*tp_as_sequence */
     2973    0,                                       /*tp_as_mapping */
     2974    0,                                       /*tp_hash */
    28022975};
    28032976
    28042977
    28052978
    2806 
    28072979/**** Tkinter Module ****/
    28082980
    28092981typedef struct {
    2810         PyObject* tuple;
    2811         int size; /* current size */
    2812         int maxsize; /* allocated size */
     2982    PyObject* tuple;
     2983    int size; /* current size */
     2984    int maxsize; /* allocated size */
    28132985} FlattenContext;
    28142986
     
    28162988_bump(FlattenContext* context, int size)
    28172989{
    2818         /* expand tuple to hold (at least) size new items.
    2819            return true if successful, false if an exception was raised */
    2820 
    2821         int maxsize = context->maxsize * 2;
    2822 
    2823         if (maxsize < context->size + size)
    2824                 maxsize = context->size + size;
    2825 
    2826         context->maxsize = maxsize;
    2827 
    2828         return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
     2990    /* expand tuple to hold (at least) size new items.
     2991       return true if successful, false if an exception was raised */
     2992
     2993    int maxsize = context->maxsize * 2;
     2994
     2995    if (maxsize < context->size + size)
     2996        maxsize = context->size + size;
     2997
     2998    context->maxsize = maxsize;
     2999
     3000    return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
    28293001}
    28303002
     
    28323004_flatten1(FlattenContext* context, PyObject* item, int depth)
    28333005{
    2834         /* add tuple or list to argument tuple (recursively) */
    2835 
    2836         int i, size;
    2837 
    2838         if (depth > 1000) {
    2839                 PyErr_SetString(PyExc_ValueError,
    2840                                 "nesting too deep in _flatten");
    2841                 return 0;
    2842         } else if (PyList_Check(item)) {
    2843                 size = PyList_GET_SIZE(item);
    2844                 /* preallocate (assume no nesting) */
    2845                 if (context->size + size > context->maxsize &&
    2846                     !_bump(context, size))
    2847                         return 0;
    2848                 /* copy items to output tuple */
    2849                 for (i = 0; i < size; i++) {
    2850                         PyObject *o = PyList_GET_ITEM(item, i);
    2851                         if (PyList_Check(o) || PyTuple_Check(o)) {
    2852                                 if (!_flatten1(context, o, depth + 1))
    2853                                         return 0;
    2854                         } else if (o != Py_None) {
    2855                                 if (context->size + 1 > context->maxsize &&
    2856                                     !_bump(context, 1))
    2857                                         return 0;
    2858                                 Py_INCREF(o);
    2859                                 PyTuple_SET_ITEM(context->tuple,
    2860                                                 context->size++, o);
    2861                         }
    2862                 }
    2863         } else if (PyTuple_Check(item)) {
    2864                 /* same, for tuples */
    2865                 size = PyTuple_GET_SIZE(item);
    2866                 if (context->size + size > context->maxsize &&
    2867                     !_bump(context, size))
    2868                         return 0;
    2869                 for (i = 0; i < size; i++) {
    2870                         PyObject *o = PyTuple_GET_ITEM(item, i);
    2871                         if (PyList_Check(o) || PyTuple_Check(o)) {
    2872                                 if (!_flatten1(context, o, depth + 1))
    2873                                         return 0;
    2874                         } else if (o != Py_None) {
    2875                                 if (context->size + 1 > context->maxsize &&
    2876                                     !_bump(context, 1))
    2877                                         return 0;
    2878                                 Py_INCREF(o);
    2879                                 PyTuple_SET_ITEM(context->tuple,
    2880                                                 context->size++, o);
    2881                         }
    2882                 }
    2883         } else {
    2884                 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
    2885                 return 0;
    2886         }
    2887         return 1;
     3006    /* add tuple or list to argument tuple (recursively) */
     3007
     3008    int i, size;
     3009
     3010    if (depth > 1000) {
     3011        PyErr_SetString(PyExc_ValueError,
     3012                        "nesting too deep in _flatten");
     3013        return 0;
     3014    } else if (PyList_Check(item)) {
     3015        size = PyList_GET_SIZE(item);
     3016        /* preallocate (assume no nesting) */
     3017        if (context->size + size > context->maxsize &&
     3018            !_bump(context, size))
     3019            return 0;
     3020        /* copy items to output tuple */
     3021        for (i = 0; i < size; i++) {
     3022            PyObject *o = PyList_GET_ITEM(item, i);
     3023            if (PyList_Check(o) || PyTuple_Check(o)) {
     3024                if (!_flatten1(context, o, depth + 1))
     3025                    return 0;
     3026            } else if (o != Py_None) {
     3027                if (context->size + 1 > context->maxsize &&
     3028                    !_bump(context, 1))
     3029                    return 0;
     3030                Py_INCREF(o);
     3031                PyTuple_SET_ITEM(context->tuple,
     3032                                context->size++, o);
     3033            }
     3034        }
     3035    } else if (PyTuple_Check(item)) {
     3036        /* same, for tuples */
     3037        size = PyTuple_GET_SIZE(item);
     3038        if (context->size + size > context->maxsize &&
     3039            !_bump(context, size))
     3040            return 0;
     3041        for (i = 0; i < size; i++) {
     3042            PyObject *o = PyTuple_GET_ITEM(item, i);
     3043            if (PyList_Check(o) || PyTuple_Check(o)) {
     3044                if (!_flatten1(context, o, depth + 1))
     3045                    return 0;
     3046            } else if (o != Py_None) {
     3047                if (context->size + 1 > context->maxsize &&
     3048                    !_bump(context, 1))
     3049                    return 0;
     3050                Py_INCREF(o);
     3051                PyTuple_SET_ITEM(context->tuple,
     3052                                context->size++, o);
     3053            }
     3054        }
     3055    } else {
     3056        PyErr_SetString(PyExc_TypeError, "argument must be sequence");
     3057        return 0;
     3058    }
     3059    return 1;
    28883060}
    28893061
     
    28913063Tkinter_Flatten(PyObject* self, PyObject* args)
    28923064{
    2893         FlattenContext context;
    2894         PyObject* item;
    2895 
    2896         if (!PyArg_ParseTuple(args, "O:_flatten", &item))
    2897                 return NULL;
    2898 
    2899         context.maxsize = PySequence_Size(item);
    2900         if (context.maxsize <= 0)
    2901                 return PyTuple_New(0);
    2902        
    2903         context.tuple = PyTuple_New(context.maxsize);
    2904         if (!context.tuple)
    2905                 return NULL;
    2906        
    2907         context.size = 0;
    2908 
    2909         if (!_flatten1(&context, item,0))
    2910                 return NULL;
    2911 
    2912         if (_PyTuple_Resize(&context.tuple, context.size))
    2913                 return NULL;
    2914 
    2915         return context.tuple;
     3065    FlattenContext context;
     3066    PyObject* item;
     3067
     3068    if (!PyArg_ParseTuple(args, "O:_flatten", &item))
     3069        return NULL;
     3070
     3071    context.maxsize = PySequence_Size(item);
     3072    if (context.maxsize < 0)
     3073        return NULL;
     3074    if (context.maxsize == 0)
     3075        return PyTuple_New(0);
     3076
     3077    context.tuple = PyTuple_New(context.maxsize);
     3078    if (!context.tuple)
     3079        return NULL;
     3080
     3081    context.size = 0;
     3082
     3083    if (!_flatten1(&context, item,0))
     3084        return NULL;
     3085
     3086    if (_PyTuple_Resize(&context.tuple, context.size))
     3087        return NULL;
     3088
     3089    return context.tuple;
    29163090}
    29173091
     
    29193093Tkinter_Create(PyObject *self, PyObject *args)
    29203094{
    2921         char *screenName = NULL;
    2922         char *baseName = NULL;
    2923         char *className = NULL;
    2924         int interactive = 0;
    2925         int wantobjects = 0;
    2926         int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
    2927         int sync = 0; /* pass -sync to wish */
    2928         char *use = NULL; /* pass -use to wish */
    2929 
    2930         baseName = strrchr(Py_GetProgramName(), '/');
    2931         if (baseName != NULL)
    2932                 baseName++;
    2933         else
    2934                 baseName = Py_GetProgramName();
    2935         className = "Tk";
    2936  
    2937         if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
    2938                               &screenName, &baseName, &className,
    2939                               &interactive, &wantobjects, &wantTk,
    2940                               &sync, &use))
    2941                 return NULL;
    2942 
    2943         return (PyObject *) Tkapp_New(screenName, baseName, className,
    2944                                       interactive, wantobjects, wantTk,
    2945                                       sync, use);
     3095    char *screenName = NULL;
     3096    char *baseName = NULL;
     3097    char *className = NULL;
     3098    int interactive = 0;
     3099    int wantobjects = 0;
     3100    int wantTk = 1;     /* If false, then Tk_Init() doesn't get called */
     3101    int sync = 0; /* pass -sync to wish */
     3102    char *use = NULL; /* pass -use to wish */
     3103
     3104    baseName = strrchr(Py_GetProgramName(), '/');
     3105    if (baseName != NULL)
     3106        baseName++;
     3107    else
     3108        baseName = Py_GetProgramName();
     3109    className = "Tk";
     3110
     3111    if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
     3112                          &screenName, &baseName, &className,
     3113                          &interactive, &wantobjects, &wantTk,
     3114                          &sync, &use))
     3115        return NULL;
     3116
     3117    return (PyObject *) Tkapp_New(screenName, baseName, className,
     3118                                  interactive, wantobjects,     wantTk,
     3119                                  sync, use);
    29463120}
    29473121
     
    29493123Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
    29503124{
    2951         int new_val;
    2952         if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
    2953                 return NULL;
    2954         if (new_val < 0) {
    2955                 PyErr_SetString(PyExc_ValueError,
    2956                                 "busywaitinterval must be >= 0");
    2957                 return NULL;
    2958         }
    2959         Tkinter_busywaitinterval = new_val;
    2960         Py_INCREF(Py_None);
    2961         return Py_None;
     3125    int new_val;
     3126    if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
     3127        return NULL;
     3128    if (new_val < 0) {
     3129        PyErr_SetString(PyExc_ValueError,
     3130                        "busywaitinterval must be >= 0");
     3131        return NULL;
     3132    }
     3133    Tkinter_busywaitinterval = new_val;
     3134    Py_INCREF(Py_None);
     3135    return Py_None;
    29623136}
    29633137
     
    29733147Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
    29743148{
    2975         return PyInt_FromLong(Tkinter_busywaitinterval);
     3149    return PyInt_FromLong(Tkinter_busywaitinterval);
    29763150}
    29773151
     
    29843158static PyMethodDef moduleMethods[] =
    29853159{
    2986         {"_flatten",           Tkinter_Flatten, METH_VARARGS},
    2987         {"create",             Tkinter_Create, METH_VARARGS},
     3160    {"_flatten",           Tkinter_Flatten, METH_VARARGS},
     3161    {"create",             Tkinter_Create, METH_VARARGS},
    29883162#ifdef HAVE_CREATEFILEHANDLER
    2989         {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
    2990         {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
    2991 #endif
    2992         {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
    2993         {"mainloop",           Tkapp_MainLoop, METH_VARARGS},
    2994         {"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
    2995         {"quit",               Tkapp_Quit, METH_VARARGS},
    2996         {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
    2997                                setbusywaitinterval_doc},
    2998         {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
    2999                                METH_NOARGS, getbusywaitinterval_doc},
    3000         {NULL,                 NULL}
     3163    {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
     3164    {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
     3165#endif
     3166    {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
     3167    {"mainloop",           Tkapp_MainLoop, METH_VARARGS},
     3168    {"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
     3169    {"quit",               Tkapp_Quit, METH_VARARGS},
     3170    {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
     3171                           setbusywaitinterval_doc},
     3172    {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
     3173                           METH_NOARGS, getbusywaitinterval_doc},
     3174    {NULL,                 NULL}
    30013175};
    30023176
     
    30093183MyFileProc(void *clientData, int mask)
    30103184{
    3011         stdin_ready = 1;
     3185    stdin_ready = 1;
    30123186}
    30133187#endif
     
    30213195{
    30223196#ifndef MS_WINDOWS
    3023         int tfile;
     3197    int tfile;
    30243198#endif
    30253199#ifdef WITH_THREAD
    3026         PyEval_RestoreThread(event_tstate);
    3027 #endif
    3028         stdin_ready = 0;
    3029         errorInCmd = 0;
     3200    PyEval_RestoreThread(event_tstate);
     3201#endif
     3202    stdin_ready = 0;
     3203    errorInCmd = 0;
    30303204#ifndef MS_WINDOWS
    3031         tfile = fileno(stdin);
    3032         Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
    3033 #endif
    3034         while (!errorInCmd && !stdin_ready) {
    3035                 int result;
     3205    tfile = fileno(stdin);
     3206    Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
     3207#endif
     3208    while (!errorInCmd && !stdin_ready) {
     3209        int result;
    30363210#ifdef MS_WINDOWS
    3037                 if (_kbhit()) {
    3038                         stdin_ready = 1;
    3039                         break;
    3040                 }
     3211        if (_kbhit()) {
     3212            stdin_ready = 1;
     3213            break;
     3214        }
    30413215#endif
    30423216#if defined(WITH_THREAD) || defined(MS_WINDOWS)
    3043                 Py_BEGIN_ALLOW_THREADS
    3044                 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
    3045                 tcl_tstate = event_tstate;
    3046 
    3047                 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
    3048 
    3049                 tcl_tstate = NULL;
    3050                 if(tcl_lock)PyThread_release_lock(tcl_lock);
    3051                 if (result == 0)
    3052                         Sleep(Tkinter_busywaitinterval);
    3053                 Py_END_ALLOW_THREADS
     3217        Py_BEGIN_ALLOW_THREADS
     3218        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
     3219        tcl_tstate = event_tstate;
     3220
     3221        result = Tcl_DoOneEvent(TCL_DONT_WAIT);
     3222
     3223        tcl_tstate = NULL;
     3224        if(tcl_lock)PyThread_release_lock(tcl_lock);
     3225        if (result == 0)
     3226            Sleep(Tkinter_busywaitinterval);
     3227        Py_END_ALLOW_THREADS
    30543228#else
    3055                 result = Tcl_DoOneEvent(0);
    3056 #endif
    3057 
    3058                 if (result < 0)
    3059                         break;
    3060         }
     3229        result = Tcl_DoOneEvent(0);
     3230#endif
     3231
     3232        if (result < 0)
     3233            break;
     3234    }
    30613235#ifndef MS_WINDOWS
    3062         Tcl_DeleteFileHandler(tfile);
    3063 #endif
    3064         if (errorInCmd) {
    3065                 errorInCmd = 0;
    3066                 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
    3067                 excInCmd = valInCmd = trbInCmd = NULL;
    3068                 PyErr_Print();
    3069         }
     3236    Tcl_DeleteFileHandler(tfile);
     3237#endif
     3238    if (errorInCmd) {
     3239        errorInCmd = 0;
     3240        PyErr_Restore(excInCmd, valInCmd, trbInCmd);
     3241        excInCmd = valInCmd = trbInCmd = NULL;
     3242        PyErr_Print();
     3243    }
    30703244#ifdef WITH_THREAD
    3071         PyEval_SaveThread();
    3072 #endif
    3073         return 0;
     3245    PyEval_SaveThread();
     3246#endif
     3247    return 0;
    30743248}
    30753249
     
    30803254{
    30813255#ifdef WAIT_FOR_STDIN
    3082         if (PyOS_InputHook == NULL) {
     3256    if (PyOS_InputHook == NULL) {
    30833257#ifdef WITH_THREAD
    3084                 event_tstate = PyThreadState_Get();
    3085 #endif
    3086                 PyOS_InputHook = EventHook;
    3087         }
     3258        event_tstate = PyThreadState_Get();
     3259#endif
     3260        PyOS_InputHook = EventHook;
     3261    }
    30883262#endif
    30893263}
     
    30933267{
    30943268#ifdef WAIT_FOR_STDIN
    3095         if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
    3096                 PyOS_InputHook = NULL;
    3097         }
     3269    if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
     3270        PyOS_InputHook = NULL;
     3271    }
    30983272#endif
    30993273}
     
    31043278ins_long(PyObject *d, char *name, long val)
    31053279{
    3106         PyObject *v = PyInt_FromLong(val);
    3107         if (v) {
    3108                 PyDict_SetItemString(d, name, v);
    3109                 Py_DECREF(v);
    3110         }
     3280    PyObject *v = PyInt_FromLong(val);
     3281    if (v) {
     3282        PyDict_SetItemString(d, name, v);
     3283        Py_DECREF(v);
     3284    }
    31113285}
    31123286static void
    31133287ins_string(PyObject *d, char *name, char *val)
    31143288{
    3115         PyObject *v = PyString_FromString(val);
    3116         if (v) {
    3117                 PyDict_SetItemString(d, name, v);
    3118                 Py_DECREF(v);
    3119         }
     3289    PyObject *v = PyString_FromString(val);
     3290    if (v) {
     3291        PyDict_SetItemString(d, name, v);
     3292        Py_DECREF(v);
     3293    }
    31203294}
    31213295
     
    31243298init_tkinter(void)
    31253299{
    3126         PyObject *m, *d;
    3127 
    3128         Py_TYPE(&Tkapp_Type) = &PyType_Type;
     3300    PyObject *m, *d;
     3301
     3302    Py_TYPE(&Tkapp_Type) = &PyType_Type;
    31293303
    31303304#ifdef WITH_THREAD
    3131         tcl_lock = PyThread_allocate_lock();
    3132 #endif
    3133 
    3134         m = Py_InitModule("_tkinter", moduleMethods);
    3135         if (m == NULL)
    3136                 return;
    3137 
    3138         d = PyModule_GetDict(m);
    3139         Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
    3140         PyDict_SetItemString(d, "TclError", Tkinter_TclError);
    3141 
    3142         ins_long(d, "READABLE", TCL_READABLE);
    3143         ins_long(d, "WRITABLE", TCL_WRITABLE);
    3144         ins_long(d, "EXCEPTION", TCL_EXCEPTION);
    3145         ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
    3146         ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
    3147         ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
    3148         ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
    3149         ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
    3150         ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
    3151         ins_string(d, "TK_VERSION", TK_VERSION);
    3152         ins_string(d, "TCL_VERSION", TCL_VERSION);
    3153 
    3154         PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
    3155 
    3156         Py_TYPE(&Tktt_Type) = &PyType_Type;
    3157         PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
    3158 
    3159         Py_TYPE(&PyTclObject_Type) = &PyType_Type;
    3160         PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
     3305    tcl_lock = PyThread_allocate_lock();
     3306#endif
     3307
     3308    m = Py_InitModule("_tkinter", moduleMethods);
     3309    if (m == NULL)
     3310        return;
     3311
     3312    d = PyModule_GetDict(m);
     3313    Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
     3314    PyDict_SetItemString(d, "TclError", Tkinter_TclError);
     3315
     3316    ins_long(d, "READABLE", TCL_READABLE);
     3317    ins_long(d, "WRITABLE", TCL_WRITABLE);
     3318    ins_long(d, "EXCEPTION", TCL_EXCEPTION);
     3319    ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
     3320    ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
     3321    ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
     3322    ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
     3323    ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
     3324    ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
     3325    ins_string(d, "TK_VERSION", TK_VERSION);
     3326    ins_string(d, "TCL_VERSION", TCL_VERSION);
     3327
     3328    PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
     3329
     3330    Py_TYPE(&Tktt_Type) = &PyType_Type;
     3331    PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
     3332
     3333    Py_TYPE(&PyTclObject_Type) = &PyType_Type;
     3334    PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
    31613335
    31623336#ifdef TK_AQUA
    3163         /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
    3164         * start waking up.  Note that Tcl_FindExecutable will do this, this
    3165         * code must be above it! The original warning from
    3166         * tkMacOSXAppInit.c is copied below.
    3167         *
    3168         * NB - You have to swap in the Tk Notifier BEFORE you start up the
    3169         * Tcl interpreter for now.  It probably should work to do this
    3170         * in the other order, but for now it doesn't seem to.
    3171         *
    3172         */
    3173         Tk_MacOSXSetupTkNotifier();
    3174 #endif
    3175 
    3176 
    3177         /* This helps the dynamic loader; in Unicode aware Tcl versions
    3178            it also helps Tcl find its encodings. */
    3179         Tcl_FindExecutable(Py_GetProgramName());
    3180 
    3181         if (PyErr_Occurred())
    3182                 return;
     3337    /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
     3338    * start waking up.  Note that Tcl_FindExecutable will do this, this
     3339    * code must be above it! The original warning from
     3340    * tkMacOSXAppInit.c is copied below.
     3341    *
     3342    * NB - You have to swap in the Tk Notifier BEFORE you start up the
     3343    * Tcl interpreter for now.  It probably should work to do this
     3344    * in the other order, but for now it doesn't seem to.
     3345    *
     3346    */
     3347    Tk_MacOSXSetupTkNotifier();
     3348#endif
     3349
     3350
     3351    /* This helps the dynamic loader; in Unicode aware Tcl versions
     3352       it also helps Tcl find its encodings. */
     3353    Tcl_FindExecutable(Py_GetProgramName());
     3354
     3355    if (PyErr_Occurred())
     3356        return;
    31833357
    31843358#if 0
    3185         /* This was not a good idea; through <Destroy> bindings,
    3186            Tcl_Finalize() may invoke Python code but at that point the
    3187            interpreter and thread state have already been destroyed! */
    3188         Py_AtExit(Tcl_Finalize);
    3189 #endif
    3190 
    3191 }
     3359    /* This was not a good idea; through <Destroy> bindings,
     3360       Tcl_Finalize() may invoke Python code but at that point the
     3361       interpreter and thread state have already been destroyed! */
     3362    Py_AtExit(Tcl_Finalize);
     3363#endif
     3364
     3365}
Note: See TracChangeset for help on using the changeset viewer.