~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Modules/_tkinter.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
/* TCL/TK VERSION INFO:
11
11
 
12
 
        Only Tcl/Tk 8.3.1 and later are supported.  Older versions are not
13
 
        supported. Use Python 2.6 or older if you cannot upgrade your
14
 
        Tcl/Tk libraries.
 
12
    Only Tcl/Tk 8.3.1 and later are supported.  Older versions are not
 
13
    supported. Use Python 2.6 or older if you cannot upgrade your
 
14
    Tcl/Tk libraries.
15
15
*/
16
16
 
17
17
/* XXX Further speed-up ideas, involving Tcl 8.0 features:
197
197
#endif
198
198
 
199
199
#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;
 
200
    { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
 
201
        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
202
202
 
203
203
#define LEAVE_TCL \
204
204
    tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
205
205
 
206
206
#define ENTER_OVERLAP \
207
 
        Py_END_ALLOW_THREADS
 
207
    Py_END_ALLOW_THREADS
208
208
 
209
209
#define LEAVE_OVERLAP_TCL \
210
 
        tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
 
210
    tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
211
211
 
212
212
#define ENTER_PYTHON \
213
 
        { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
214
 
            if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
 
213
    { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
 
214
        if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
215
215
 
216
216
#define LEAVE_PYTHON \
217
 
        { PyThreadState *tstate = PyEval_SaveThread(); \
218
 
            if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
 
217
    { PyThreadState *tstate = PyEval_SaveThread(); \
 
218
        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219
219
 
220
220
#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
 
        }
 
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
    }
226
226
 
227
227
#else
228
228
 
245
245
static PyTypeObject Tkapp_Type;
246
246
 
247
247
typedef 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;
 
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;
263
263
} TkappObject;
264
264
 
265
265
#define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
270
270
(void *) v, Py_REFCNT(v)))
271
271
 
272
272
 
273
 
 
 
273
 
274
274
/**** Error Handling ****/
275
275
 
276
276
static PyObject *Tkinter_TclError;
284
284
static int tk_load_failed = 0;
285
285
#endif
286
286
 
287
 
 
 
287
 
288
288
static PyObject *
289
289
Tkinter_Error(PyObject *v)
290
290
{
291
 
        PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
292
 
        return NULL;
 
291
    PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
 
292
    return NULL;
293
293
}
294
294
 
295
295
 
296
 
 
 
296
 
297
297
/**** Utils ****/
298
298
 
299
299
static int Tkinter_busywaitinterval = 20;
306
306
static void
307
307
Sleep(int milli)
308
308
{
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);
 
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);
314
314
}
315
315
#endif /* MS_WINDOWS */
316
316
 
319
319
static int
320
320
WaitForMainloop(TkappObject* self)
321
321
{
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;
 
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;
334
334
}
335
335
#endif /* WITH_THREAD */
336
336
 
337
 
 
 
337
 
338
338
static char *
339
339
AsString(PyObject *value, PyObject *tmp)
340
340
{
341
 
        if (PyBytes_Check(value))
342
 
                return PyBytes_AsString(value);
343
 
        else if (PyUnicode_Check(value)) {
344
 
                PyObject *v = PyUnicode_AsUTF8String(value);
345
 
                if (v == NULL)
346
 
                        return NULL;
347
 
                if (PyList_Append(tmp, v) != 0) {
348
 
                        Py_DECREF(v);
349
 
                        return NULL;
350
 
                }
351
 
                Py_DECREF(v);
352
 
                return PyBytes_AsString(v);
353
 
        }
354
 
        else {
355
 
                PyObject *v = PyObject_Str(value);
356
 
                if (v == NULL)
357
 
                        return NULL;
358
 
                if (PyList_Append(tmp, v) != 0) {
359
 
                        Py_DECREF(v);
360
 
                        return NULL;
361
 
                }
362
 
                Py_DECREF(v);
363
 
                return PyBytes_AsString(v);
364
 
        }
 
341
    if (PyBytes_Check(value))
 
342
        return PyBytes_AsString(value);
 
343
    else if (PyUnicode_Check(value)) {
 
344
        PyObject *v = PyUnicode_AsUTF8String(value);
 
345
        if (v == NULL)
 
346
            return NULL;
 
347
        if (PyList_Append(tmp, v) != 0) {
 
348
            Py_DECREF(v);
 
349
            return NULL;
 
350
        }
 
351
        Py_DECREF(v);
 
352
        return PyBytes_AsString(v);
 
353
    }
 
354
    else {
 
355
        PyObject *v = PyObject_Str(value);
 
356
        if (v == NULL)
 
357
            return NULL;
 
358
        if (PyList_Append(tmp, v) != 0) {
 
359
            Py_DECREF(v);
 
360
            return NULL;
 
361
        }
 
362
        Py_DECREF(v);
 
363
        return PyBytes_AsString(v);
 
364
    }
365
365
}
366
366
 
367
367
 
368
 
 
 
368
 
369
369
#define ARGSZ 64
370
370
 
371
371
static char *
372
372
Merge(PyObject *args)
373
373
{
374
 
        PyObject *tmp = NULL;
375
 
        char *argvStore[ARGSZ];
376
 
        char **argv = NULL;
377
 
        int fvStore[ARGSZ];
378
 
        int *fv = NULL;
379
 
        int argc = 0, fvc = 0, i;
380
 
        char *res = NULL;
381
 
 
382
 
        if (!(tmp = PyList_New(0)))
383
 
            return NULL;
384
 
 
385
 
        argv = argvStore;
386
 
        fv = fvStore;
387
 
 
388
 
        if (args == NULL)
389
 
                argc = 0;
390
 
 
391
 
        else if (!PyTuple_Check(args)) {
392
 
                argc = 1;
393
 
                fv[0] = 0;
394
 
                if (!(argv[0] = AsString(args, tmp)))
395
 
                        goto finally;
396
 
        }
397
 
        else {
398
 
                argc = PyTuple_Size(args);
399
 
 
400
 
                if (argc > ARGSZ) {
401
 
                        argv = (char **)ckalloc(argc * sizeof(char *));
402
 
                        fv = (int *)ckalloc(argc * sizeof(int));
403
 
                        if (argv == NULL || fv == NULL) {
404
 
                                PyErr_NoMemory();
405
 
                                goto finally;
406
 
                        }
407
 
                }
408
 
 
409
 
                for (i = 0; i < argc; i++) {
410
 
                        PyObject *v = PyTuple_GetItem(args, i);
411
 
                        if (PyTuple_Check(v)) {
412
 
                                fv[i] = 1;
413
 
                                if (!(argv[i] = Merge(v)))
414
 
                                        goto finally;
415
 
                                fvc++;
416
 
                        }
417
 
                        else if (v == Py_None) {
418
 
                                argc = i;
419
 
                                break;
420
 
                        }
421
 
                        else {
422
 
                                fv[i] = 0;
423
 
                                if (!(argv[i] = AsString(v, tmp)))
424
 
                                        goto finally;
425
 
                                fvc++;
426
 
                        }
427
 
                }
428
 
        }
429
 
        res = Tcl_Merge(argc, argv);
430
 
        if (res == NULL)
431
 
                PyErr_SetString(Tkinter_TclError, "merge failed");
 
374
    PyObject *tmp = NULL;
 
375
    char *argvStore[ARGSZ];
 
376
    char **argv = NULL;
 
377
    int fvStore[ARGSZ];
 
378
    int *fv = NULL;
 
379
    int argc = 0, fvc = 0, i;
 
380
    char *res = NULL;
 
381
 
 
382
    if (!(tmp = PyList_New(0)))
 
383
        return NULL;
 
384
 
 
385
    argv = argvStore;
 
386
    fv = fvStore;
 
387
 
 
388
    if (args == NULL)
 
389
        argc = 0;
 
390
 
 
391
    else if (!PyTuple_Check(args)) {
 
392
        argc = 1;
 
393
        fv[0] = 0;
 
394
        if (!(argv[0] = AsString(args, tmp)))
 
395
            goto finally;
 
396
    }
 
397
    else {
 
398
        argc = PyTuple_Size(args);
 
399
 
 
400
        if (argc > ARGSZ) {
 
401
            argv = (char **)ckalloc(argc * sizeof(char *));
 
402
            fv = (int *)ckalloc(argc * sizeof(int));
 
403
            if (argv == NULL || fv == NULL) {
 
404
                PyErr_NoMemory();
 
405
                goto finally;
 
406
            }
 
407
        }
 
408
 
 
409
        for (i = 0; i < argc; i++) {
 
410
            PyObject *v = PyTuple_GetItem(args, i);
 
411
            if (PyTuple_Check(v)) {
 
412
                fv[i] = 1;
 
413
                if (!(argv[i] = Merge(v)))
 
414
                    goto finally;
 
415
                fvc++;
 
416
            }
 
417
            else if (v == Py_None) {
 
418
                argc = i;
 
419
                break;
 
420
            }
 
421
            else {
 
422
                fv[i] = 0;
 
423
                if (!(argv[i] = AsString(v, tmp)))
 
424
                    goto finally;
 
425
                fvc++;
 
426
            }
 
427
        }
 
428
    }
 
429
    res = Tcl_Merge(argc, argv);
 
430
    if (res == NULL)
 
431
        PyErr_SetString(Tkinter_TclError, "merge failed");
432
432
 
433
433
  finally:
434
 
        for (i = 0; i < fvc; i++)
435
 
                if (fv[i]) {
436
 
                        ckfree(argv[i]);
437
 
                }
438
 
        if (argv != argvStore)
439
 
                ckfree(FREECAST argv);
440
 
        if (fv != fvStore)
441
 
                ckfree(FREECAST fv);
 
434
    for (i = 0; i < fvc; i++)
 
435
        if (fv[i]) {
 
436
            ckfree(argv[i]);
 
437
        }
 
438
    if (argv != argvStore)
 
439
        ckfree(FREECAST argv);
 
440
    if (fv != fvStore)
 
441
        ckfree(FREECAST fv);
442
442
 
443
 
        Py_DECREF(tmp);
444
 
        return res;
 
443
    Py_DECREF(tmp);
 
444
    return res;
445
445
}
446
446
 
447
447
 
448
 
 
 
448
 
449
449
static PyObject *
450
450
Split(char *list)
451
451
{
452
 
        int argc;
453
 
        char **argv;
454
 
        PyObject *v;
455
 
 
456
 
        if (list == NULL) {
457
 
                Py_INCREF(Py_None);
458
 
                return Py_None;
459
 
        }
460
 
 
461
 
        if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
462
 
                /* Not a list.
463
 
                 * Could be a quoted string containing funnies, e.g. {"}.
464
 
                 * Return the string itself.
465
 
                 */
466
 
                return PyUnicode_FromString(list);
467
 
        }
468
 
 
469
 
        if (argc == 0)
470
 
                v = PyUnicode_FromString("");
471
 
        else if (argc == 1)
472
 
                v = PyUnicode_FromString(argv[0]);
473
 
        else if ((v = PyTuple_New(argc)) != NULL) {
474
 
                int i;
475
 
                PyObject *w;
476
 
 
477
 
                for (i = 0; i < argc; i++) {
478
 
                        if ((w = Split(argv[i])) == NULL) {
479
 
                                Py_DECREF(v);
480
 
                                v = NULL;
481
 
                                break;
482
 
                        }
483
 
                        PyTuple_SetItem(v, i, w);
484
 
                }
485
 
        }
486
 
        Tcl_Free(FREECAST argv);
487
 
        return v;
 
452
    int argc;
 
453
    char **argv;
 
454
    PyObject *v;
 
455
 
 
456
    if (list == NULL) {
 
457
        Py_INCREF(Py_None);
 
458
        return Py_None;
 
459
    }
 
460
 
 
461
    if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
 
462
        /* Not a list.
 
463
         * Could be a quoted string containing funnies, e.g. {"}.
 
464
         * Return the string itself.
 
465
         */
 
466
        return PyUnicode_FromString(list);
 
467
    }
 
468
 
 
469
    if (argc == 0)
 
470
        v = PyUnicode_FromString("");
 
471
    else if (argc == 1)
 
472
        v = PyUnicode_FromString(argv[0]);
 
473
    else if ((v = PyTuple_New(argc)) != NULL) {
 
474
        int i;
 
475
        PyObject *w;
 
476
 
 
477
        for (i = 0; i < argc; i++) {
 
478
            if ((w = Split(argv[i])) == NULL) {
 
479
                Py_DECREF(v);
 
480
                v = NULL;
 
481
                break;
 
482
            }
 
483
            PyTuple_SetItem(v, i, w);
 
484
        }
 
485
    }
 
486
    Tcl_Free(FREECAST argv);
 
487
    return v;
488
488
}
489
489
 
490
490
/* In some cases, Tcl will still return strings that are supposed to be
494
494
static PyObject *
495
495
SplitObj(PyObject *arg)
496
496
{
497
 
        if (PyTuple_Check(arg)) {
498
 
                int i, size;
499
 
                PyObject *elem, *newelem, *result;
500
 
 
501
 
                size = PyTuple_Size(arg);
502
 
                result = NULL;
503
 
                /* Recursively invoke SplitObj for all tuple items.
504
 
                   If this does not return a new object, no action is
505
 
                   needed. */
506
 
                for(i = 0; i < size; i++) {
507
 
                        elem = PyTuple_GetItem(arg, i);
508
 
                        newelem = SplitObj(elem);
509
 
                        if (!newelem) {
510
 
                                Py_XDECREF(result);
511
 
                                return NULL;
512
 
                        }
513
 
                        if (!result) {
514
 
                                int k;
515
 
                                if (newelem == elem) {
516
 
                                        Py_DECREF(newelem);
517
 
                                        continue;
518
 
                                }
519
 
                                result = PyTuple_New(size);
520
 
                                if (!result)
521
 
                                        return NULL;
522
 
                                for(k = 0; k < i; k++) {
523
 
                                        elem = PyTuple_GetItem(arg, k);
524
 
                                        Py_INCREF(elem);
525
 
                                        PyTuple_SetItem(result, k, elem);
526
 
                                }
527
 
                        }
528
 
                        PyTuple_SetItem(result, i, newelem);
529
 
                }
530
 
                if (result)
531
 
                        return result;
532
 
                /* Fall through, returning arg. */
533
 
        }
534
 
        else if (PyBytes_Check(arg)) {
535
 
                int argc;
536
 
                char **argv;
537
 
                char *list = PyBytes_AsString(arg);
538
 
 
539
 
                if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
540
 
                        Py_INCREF(arg);
541
 
                        return arg;
542
 
                }
543
 
                Tcl_Free(FREECAST argv);
544
 
                if (argc > 1)
545
 
                        return Split(PyBytes_AsString(arg));
546
 
                /* Fall through, returning arg. */
547
 
        }
548
 
        Py_INCREF(arg);
549
 
        return arg;
 
497
    if (PyTuple_Check(arg)) {
 
498
        int i, size;
 
499
        PyObject *elem, *newelem, *result;
 
500
 
 
501
        size = PyTuple_Size(arg);
 
502
        result = NULL;
 
503
        /* Recursively invoke SplitObj for all tuple items.
 
504
           If this does not return a new object, no action is
 
505
           needed. */
 
506
        for(i = 0; i < size; i++) {
 
507
            elem = PyTuple_GetItem(arg, i);
 
508
            newelem = SplitObj(elem);
 
509
            if (!newelem) {
 
510
                Py_XDECREF(result);
 
511
                return NULL;
 
512
            }
 
513
            if (!result) {
 
514
                int k;
 
515
                if (newelem == elem) {
 
516
                    Py_DECREF(newelem);
 
517
                    continue;
 
518
                }
 
519
                result = PyTuple_New(size);
 
520
                if (!result)
 
521
                    return NULL;
 
522
                for(k = 0; k < i; k++) {
 
523
                    elem = PyTuple_GetItem(arg, k);
 
524
                    Py_INCREF(elem);
 
525
                    PyTuple_SetItem(result, k, elem);
 
526
                }
 
527
            }
 
528
            PyTuple_SetItem(result, i, newelem);
 
529
        }
 
530
        if (result)
 
531
            return result;
 
532
        /* Fall through, returning arg. */
 
533
    }
 
534
    else if (PyBytes_Check(arg)) {
 
535
        int argc;
 
536
        char **argv;
 
537
        char *list = PyBytes_AsString(arg);
 
538
 
 
539
        if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
 
540
            Py_INCREF(arg);
 
541
            return arg;
 
542
        }
 
543
        Tcl_Free(FREECAST argv);
 
544
        if (argc > 1)
 
545
            return Split(PyBytes_AsString(arg));
 
546
        /* Fall through, returning arg. */
 
547
    }
 
548
    Py_INCREF(arg);
 
549
    return arg;
550
550
}
551
551
 
552
 
 
 
552
 
553
553
/**** Tkapp Object ****/
554
554
 
555
555
#ifndef WITH_APPINIT
556
556
int
557
557
Tcl_AppInit(Tcl_Interp *interp)
558
558
{
559
 
        const char * _tkinter_skip_tk_init;
560
 
 
561
 
        if (Tcl_Init(interp) == TCL_ERROR) {
562
 
                PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
563
 
                return TCL_ERROR;
564
 
        }
565
 
 
566
 
        _tkinter_skip_tk_init = Tcl_GetVar(interp,
567
 
                        "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
568
 
        if (_tkinter_skip_tk_init != NULL &&
569
 
                        strcmp(_tkinter_skip_tk_init, "1") == 0) {
570
 
                return TCL_OK;
571
 
        }
572
 
 
573
 
#ifdef TKINTER_PROTECT_LOADTK
574
 
        if (tk_load_failed) {
575
 
                PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
576
 
                return TCL_ERROR;
577
 
        }
578
 
#endif
579
 
 
580
 
        if (Tk_Init(interp) == TCL_ERROR) {
581
 
#ifdef TKINTER_PROTECT_LOADTK
582
 
                tk_load_failed = 1;
583
 
#endif
584
 
                PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
585
 
                return TCL_ERROR;
586
 
        }
587
 
 
588
 
        return TCL_OK;
 
559
    const char * _tkinter_skip_tk_init;
 
560
 
 
561
    if (Tcl_Init(interp) == TCL_ERROR) {
 
562
        PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
 
563
        return TCL_ERROR;
 
564
    }
 
565
 
 
566
    _tkinter_skip_tk_init = Tcl_GetVar(interp,
 
567
                    "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
 
568
    if (_tkinter_skip_tk_init != NULL &&
 
569
                    strcmp(_tkinter_skip_tk_init, "1") == 0) {
 
570
        return TCL_OK;
 
571
    }
 
572
 
 
573
#ifdef TKINTER_PROTECT_LOADTK
 
574
    if (tk_load_failed) {
 
575
        PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG);
 
576
        return TCL_ERROR;
 
577
    }
 
578
#endif
 
579
 
 
580
    if (Tk_Init(interp) == TCL_ERROR) {
 
581
#ifdef TKINTER_PROTECT_LOADTK
 
582
        tk_load_failed = 1;
 
583
#endif
 
584
        PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
 
585
        return TCL_ERROR;
 
586
    }
 
587
 
 
588
    return TCL_OK;
589
589
}
590
590
#endif /* !WITH_APPINIT */
591
591
 
592
592
 
593
 
 
 
593
 
594
594
 
595
595
/* Initialize the Tk application; see the `main' function in
596
596
 * `tkMain.c'.
601
601
 
602
602
static TkappObject *
603
603
Tkapp_New(char *screenName, char *className,
604
 
          int interactive, int wantobjects, int wantTk, int sync, char *use)
 
604
          int interactive, int wantobjects, int wantTk, int sync, char *use)
605
605
{
606
 
        TkappObject *v;
607
 
        char *argv0;
608
 
 
609
 
        v = PyObject_New(TkappObject, &Tkapp_Type);
610
 
        if (v == NULL)
611
 
                return NULL;
612
 
 
613
 
        v->interp = Tcl_CreateInterp();
614
 
        v->wantobjects = wantobjects;
615
 
        v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
616
 
                                    TCL_GLOBAL_ONLY) != NULL;
617
 
        v->thread_id = Tcl_GetCurrentThread();
618
 
        v->dispatching = 0;
 
606
    TkappObject *v;
 
607
    char *argv0;
 
608
 
 
609
    v = PyObject_New(TkappObject, &Tkapp_Type);
 
610
    if (v == NULL)
 
611
        return NULL;
 
612
 
 
613
    v->interp = Tcl_CreateInterp();
 
614
    v->wantobjects = wantobjects;
 
615
    v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
 
616
                                TCL_GLOBAL_ONLY) != NULL;
 
617
    v->thread_id = Tcl_GetCurrentThread();
 
618
    v->dispatching = 0;
619
619
 
620
620
#ifndef TCL_THREADS
621
 
        if (v->threaded) {
622
 
            PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
623
 
            Py_DECREF(v);
624
 
            return 0;
625
 
        }
 
621
    if (v->threaded) {
 
622
        PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
 
623
        Py_DECREF(v);
 
624
        return 0;
 
625
    }
626
626
#endif
627
627
#ifdef WITH_THREAD
628
 
        if (v->threaded && tcl_lock) {
629
 
            /* If Tcl is threaded, we don't need the lock. */
630
 
            PyThread_free_lock(tcl_lock);
631
 
            tcl_lock = NULL;
632
 
        }
633
 
#endif
634
 
 
635
 
        v->BooleanType = Tcl_GetObjType("boolean");
636
 
        v->ByteArrayType = Tcl_GetObjType("bytearray");
637
 
        v->DoubleType = Tcl_GetObjType("double");
638
 
        v->IntType = Tcl_GetObjType("int");
639
 
        v->ListType = Tcl_GetObjType("list");
640
 
        v->ProcBodyType = Tcl_GetObjType("procbody");
641
 
        v->StringType = Tcl_GetObjType("string");
642
 
 
643
 
        /* Delete the 'exit' command, which can screw things up */
644
 
        Tcl_DeleteCommand(v->interp, "exit");
645
 
 
646
 
        if (screenName != NULL)
647
 
                Tcl_SetVar2(v->interp, "env", "DISPLAY",
648
 
                            screenName, TCL_GLOBAL_ONLY);
649
 
 
650
 
        if (interactive)
651
 
                Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
652
 
        else
653
 
                Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
654
 
 
655
 
        /* This is used to get the application class for Tk 4.1 and up */
656
 
        argv0 = (char*)ckalloc(strlen(className) + 1);
657
 
        if (!argv0) {
658
 
                PyErr_NoMemory();
659
 
                Py_DECREF(v);
660
 
                return NULL;
661
 
        }
662
 
 
663
 
        strcpy(argv0, className);
664
 
        if (isupper(Py_CHARMASK(argv0[0])))
665
 
                argv0[0] = tolower(Py_CHARMASK(argv0[0]));
666
 
        Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
667
 
        ckfree(argv0);
668
 
 
669
 
        if (! wantTk) {
670
 
                Tcl_SetVar(v->interp,
671
 
                                "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
672
 
        }
673
 
#ifdef TKINTER_PROTECT_LOADTK
674
 
        else if (tk_load_failed) {
675
 
                Tcl_SetVar(v->interp,
676
 
                                "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
677
 
        }
678
 
#endif
679
 
 
680
 
        /* some initial arguments need to be in argv */
681
 
        if (sync || use) {
682
 
                char *args;
683
 
                int len = 0;
684
 
 
685
 
                if (sync)
686
 
                        len += sizeof "-sync";
687
 
                if (use)
688
 
                        len += strlen(use) + sizeof "-use ";
689
 
 
690
 
                args = (char*)ckalloc(len);
691
 
                if (!args) {
692
 
                        PyErr_NoMemory();
693
 
                        Py_DECREF(v);
694
 
                        return NULL;
695
 
                }
696
 
 
697
 
                args[0] = '\0';
698
 
                if (sync)
699
 
                        strcat(args, "-sync");
700
 
                if (use) {
701
 
                        if (sync)
702
 
                                strcat(args, " ");
703
 
                        strcat(args, "-use ");
704
 
                        strcat(args, use);
705
 
                }
706
 
 
707
 
                Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
708
 
                ckfree(args);
709
 
        }
710
 
 
711
 
        if (Tcl_AppInit(v->interp) != TCL_OK) {
712
 
                PyObject *result = Tkinter_Error((PyObject *)v);
713
 
#ifdef TKINTER_PROTECT_LOADTK
714
 
                if (wantTk) {
715
 
                        const char *_tkinter_tk_failed;
716
 
                        _tkinter_tk_failed = Tcl_GetVar(v->interp,
717
 
                                        "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
718
 
 
719
 
                        if ( _tkinter_tk_failed != NULL &&
720
 
                                        strcmp(_tkinter_tk_failed, "1") == 0) {
721
 
                                tk_load_failed = 1;
722
 
                        }
723
 
                }
724
 
#endif
725
 
                Py_DECREF((PyObject *)v);
726
 
                return (TkappObject *)result;
727
 
        }
728
 
 
729
 
        EnableEventHook();
730
 
 
731
 
        return v;
 
628
    if (v->threaded && tcl_lock) {
 
629
        /* If Tcl is threaded, we don't need the lock. */
 
630
        PyThread_free_lock(tcl_lock);
 
631
        tcl_lock = NULL;
 
632
    }
 
633
#endif
 
634
 
 
635
    v->BooleanType = Tcl_GetObjType("boolean");
 
636
    v->ByteArrayType = Tcl_GetObjType("bytearray");
 
637
    v->DoubleType = Tcl_GetObjType("double");
 
638
    v->IntType = Tcl_GetObjType("int");
 
639
    v->ListType = Tcl_GetObjType("list");
 
640
    v->ProcBodyType = Tcl_GetObjType("procbody");
 
641
    v->StringType = Tcl_GetObjType("string");
 
642
 
 
643
    /* Delete the 'exit' command, which can screw things up */
 
644
    Tcl_DeleteCommand(v->interp, "exit");
 
645
 
 
646
    if (screenName != NULL)
 
647
        Tcl_SetVar2(v->interp, "env", "DISPLAY",
 
648
                    screenName, TCL_GLOBAL_ONLY);
 
649
 
 
650
    if (interactive)
 
651
        Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
 
652
    else
 
653
        Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
 
654
 
 
655
    /* This is used to get the application class for Tk 4.1 and up */
 
656
    argv0 = (char*)ckalloc(strlen(className) + 1);
 
657
    if (!argv0) {
 
658
        PyErr_NoMemory();
 
659
        Py_DECREF(v);
 
660
        return NULL;
 
661
    }
 
662
 
 
663
    strcpy(argv0, className);
 
664
    if (isupper(Py_CHARMASK(argv0[0])))
 
665
        argv0[0] = tolower(Py_CHARMASK(argv0[0]));
 
666
    Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
 
667
    ckfree(argv0);
 
668
 
 
669
    if (! wantTk) {
 
670
        Tcl_SetVar(v->interp,
 
671
                        "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
 
672
    }
 
673
#ifdef TKINTER_PROTECT_LOADTK
 
674
    else if (tk_load_failed) {
 
675
        Tcl_SetVar(v->interp,
 
676
                        "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY);
 
677
    }
 
678
#endif
 
679
 
 
680
    /* some initial arguments need to be in argv */
 
681
    if (sync || use) {
 
682
        char *args;
 
683
        int len = 0;
 
684
 
 
685
        if (sync)
 
686
            len += sizeof "-sync";
 
687
        if (use)
 
688
            len += strlen(use) + sizeof "-use ";
 
689
 
 
690
        args = (char*)ckalloc(len);
 
691
        if (!args) {
 
692
            PyErr_NoMemory();
 
693
            Py_DECREF(v);
 
694
            return NULL;
 
695
        }
 
696
 
 
697
        args[0] = '\0';
 
698
        if (sync)
 
699
            strcat(args, "-sync");
 
700
        if (use) {
 
701
            if (sync)
 
702
                strcat(args, " ");
 
703
            strcat(args, "-use ");
 
704
            strcat(args, use);
 
705
        }
 
706
 
 
707
        Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
 
708
        ckfree(args);
 
709
    }
 
710
 
 
711
    if (Tcl_AppInit(v->interp) != TCL_OK) {
 
712
        PyObject *result = Tkinter_Error((PyObject *)v);
 
713
#ifdef TKINTER_PROTECT_LOADTK
 
714
        if (wantTk) {
 
715
            const char *_tkinter_tk_failed;
 
716
            _tkinter_tk_failed = Tcl_GetVar(v->interp,
 
717
                            "_tkinter_tk_failed", TCL_GLOBAL_ONLY);
 
718
 
 
719
            if ( _tkinter_tk_failed != NULL &&
 
720
                            strcmp(_tkinter_tk_failed, "1") == 0) {
 
721
                tk_load_failed = 1;
 
722
            }
 
723
        }
 
724
#endif
 
725
        Py_DECREF((PyObject *)v);
 
726
        return (TkappObject *)result;
 
727
    }
 
728
 
 
729
    EnableEventHook();
 
730
 
 
731
    return v;
732
732
}
733
733
 
734
734
 
735
735
#ifdef WITH_THREAD
736
736
static void
737
737
Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
738
 
                 Tcl_Condition *cond, Tcl_Mutex *mutex)
 
738
                 Tcl_Condition *cond, Tcl_Mutex *mutex)
739
739
{
740
 
        Py_BEGIN_ALLOW_THREADS;
741
 
        Tcl_MutexLock(mutex);
742
 
        Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
743
 
        Tcl_ThreadAlert(self->thread_id);
744
 
        Tcl_ConditionWait(cond, mutex, NULL);
745
 
        Tcl_MutexUnlock(mutex);
746
 
        Py_END_ALLOW_THREADS
 
740
    Py_BEGIN_ALLOW_THREADS;
 
741
    Tcl_MutexLock(mutex);
 
742
    Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
 
743
    Tcl_ThreadAlert(self->thread_id);
 
744
    Tcl_ConditionWait(cond, mutex, NULL);
 
745
    Tcl_MutexUnlock(mutex);
 
746
    Py_END_ALLOW_THREADS
747
747
}
748
748
#endif
749
749
 
750
 
 
 
750
 
751
751
/** Tcl Eval **/
752
752
 
753
753
typedef struct {
754
 
        PyObject_HEAD
755
 
        Tcl_Obj *value;
756
 
        PyObject *string; /* This cannot cause cycles. */
 
754
    PyObject_HEAD
 
755
    Tcl_Obj *value;
 
756
    PyObject *string; /* This cannot cause cycles. */
757
757
} PyTclObject;
758
758
 
759
759
static PyTypeObject PyTclObject_Type;
760
 
#define PyTclObject_Check(v)    ((v)->ob_type == &PyTclObject_Type)
 
760
#define PyTclObject_Check(v)    ((v)->ob_type == &PyTclObject_Type)
761
761
 
762
762
static PyObject *
763
763
newPyTclObject(Tcl_Obj *arg)
764
764
{
765
 
        PyTclObject *self;
766
 
        self = PyObject_New(PyTclObject, &PyTclObject_Type);
767
 
        if (self == NULL)
768
 
                return NULL;
769
 
        Tcl_IncrRefCount(arg);
770
 
        self->value = arg;
771
 
        self->string = NULL;
772
 
        return (PyObject*)self;
 
765
    PyTclObject *self;
 
766
    self = PyObject_New(PyTclObject, &PyTclObject_Type);
 
767
    if (self == NULL)
 
768
        return NULL;
 
769
    Tcl_IncrRefCount(arg);
 
770
    self->value = arg;
 
771
    self->string = NULL;
 
772
    return (PyObject*)self;
773
773
}
774
774
 
775
775
static void
776
776
PyTclObject_dealloc(PyTclObject *self)
777
777
{
778
 
        Tcl_DecrRefCount(self->value);
779
 
        Py_XDECREF(self->string);
780
 
        PyObject_Del(self);
 
778
    Tcl_DecrRefCount(self->value);
 
779
    Py_XDECREF(self->string);
 
780
    PyObject_Del(self);
781
781
}
782
782
 
783
783
static char*
784
784
PyTclObject_TclString(PyObject *self)
785
785
{
786
 
        return Tcl_GetString(((PyTclObject*)self)->value);
 
786
    return Tcl_GetString(((PyTclObject*)self)->value);
787
787
}
788
788
 
789
789
/* Like _str, but create Unicode if necessary. */
793
793
static PyObject *
794
794
PyTclObject_string(PyTclObject *self, void *ignored)
795
795
{
796
 
        char *s;
797
 
        int len;
798
 
        if (!self->string) {
799
 
                s = Tcl_GetStringFromObj(self->value, &len);
800
 
                self->string = PyUnicode_FromStringAndSize(s, len);
801
 
                if (!self->string)
802
 
                        return NULL;
803
 
        }
804
 
        Py_INCREF(self->string);
805
 
        return self->string;
 
796
    char *s;
 
797
    int len;
 
798
    if (!self->string) {
 
799
        s = Tcl_GetStringFromObj(self->value, &len);
 
800
        self->string = PyUnicode_FromStringAndSize(s, len);
 
801
        if (!self->string)
 
802
            return NULL;
 
803
    }
 
804
    Py_INCREF(self->string);
 
805
    return self->string;
806
806
}
807
807
 
808
808
static PyObject *
809
809
PyTclObject_str(PyTclObject *self, void *ignored)
810
810
{
811
 
        char *s;
812
 
        int len;
813
 
        if (self->string && PyUnicode_Check(self->string)) {
814
 
                Py_INCREF(self->string);
815
 
                return self->string;
816
 
        }
817
 
        /* XXX Could chache result if it is non-ASCII. */
818
 
        s = Tcl_GetStringFromObj(self->value, &len);
819
 
        return PyUnicode_DecodeUTF8(s, len, "strict");
 
811
    char *s;
 
812
    int len;
 
813
    if (self->string && PyUnicode_Check(self->string)) {
 
814
        Py_INCREF(self->string);
 
815
        return self->string;
 
816
    }
 
817
    /* XXX Could chache result if it is non-ASCII. */
 
818
    s = Tcl_GetStringFromObj(self->value, &len);
 
819
    return PyUnicode_DecodeUTF8(s, len, "strict");
820
820
}
821
821
 
822
822
static PyObject *
823
823
PyTclObject_repr(PyTclObject *self)
824
824
{
825
 
        return PyUnicode_FromFormat("<%s object at %p>",
826
 
                                    self->value->typePtr->name, self->value);
 
825
    return PyUnicode_FromFormat("<%s object at %p>",
 
826
                                self->value->typePtr->name, self->value);
827
827
}
828
828
 
829
829
#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
831
831
static PyObject *
832
832
PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
833
833
{
834
 
        int result;
835
 
        PyObject *v;
836
 
 
837
 
        /* neither argument should be NULL, unless something's gone wrong */
838
 
        if (self == NULL || other == NULL) {
839
 
                PyErr_BadInternalCall();
840
 
                return NULL;
841
 
        }
842
 
 
843
 
        /* both arguments should be instances of PyTclObject */
844
 
        if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
845
 
                v = Py_NotImplemented;
846
 
                goto finished;
847
 
        }
848
 
 
849
 
        if (self == other)
850
 
                /* fast path when self and other are identical */
851
 
                result = 0;
852
 
        else
853
 
                result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
854
 
                                Tcl_GetString(((PyTclObject *)other)->value));
855
 
        /* Convert return value to a Boolean */
856
 
        switch (op) {
857
 
        case Py_EQ:
858
 
                v = TEST_COND(result == 0);
859
 
                break;
860
 
        case Py_NE:
861
 
                v = TEST_COND(result != 0);
862
 
                break;
863
 
        case Py_LE:
864
 
                v = TEST_COND(result <= 0);
865
 
                break;
866
 
        case Py_GE:
867
 
                v = TEST_COND(result >= 0);
868
 
                break;
869
 
        case Py_LT:
870
 
                v = TEST_COND(result < 0);
871
 
                break;
872
 
        case Py_GT:
873
 
                v = TEST_COND(result > 0);
874
 
                break;
875
 
        default:
876
 
                PyErr_BadArgument();
877
 
                return NULL;
878
 
        }
 
834
    int result;
 
835
    PyObject *v;
 
836
 
 
837
    /* neither argument should be NULL, unless something's gone wrong */
 
838
    if (self == NULL || other == NULL) {
 
839
        PyErr_BadInternalCall();
 
840
        return NULL;
 
841
    }
 
842
 
 
843
    /* both arguments should be instances of PyTclObject */
 
844
    if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
 
845
        v = Py_NotImplemented;
 
846
        goto finished;
 
847
    }
 
848
 
 
849
    if (self == other)
 
850
        /* fast path when self and other are identical */
 
851
        result = 0;
 
852
    else
 
853
        result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
 
854
                        Tcl_GetString(((PyTclObject *)other)->value));
 
855
    /* Convert return value to a Boolean */
 
856
    switch (op) {
 
857
    case Py_EQ:
 
858
        v = TEST_COND(result == 0);
 
859
        break;
 
860
    case Py_NE:
 
861
        v = TEST_COND(result != 0);
 
862
        break;
 
863
    case Py_LE:
 
864
        v = TEST_COND(result <= 0);
 
865
        break;
 
866
    case Py_GE:
 
867
        v = TEST_COND(result >= 0);
 
868
        break;
 
869
    case Py_LT:
 
870
        v = TEST_COND(result < 0);
 
871
        break;
 
872
    case Py_GT:
 
873
        v = TEST_COND(result > 0);
 
874
        break;
 
875
    default:
 
876
        PyErr_BadArgument();
 
877
        return NULL;
 
878
    }
879
879
  finished:
880
 
        Py_INCREF(v);
881
 
        return v;
 
880
    Py_INCREF(v);
 
881
    return v;
882
882
}
883
883
 
884
884
PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
886
886
static PyObject*
887
887
get_typename(PyTclObject* obj, void* ignored)
888
888
{
889
 
        return PyUnicode_FromString(obj->value->typePtr->name);
 
889
    return PyUnicode_FromString(obj->value->typePtr->name);
890
890
}
891
891
 
892
892
 
893
893
static PyGetSetDef PyTclObject_getsetlist[] = {
894
 
        {"typename", (getter)get_typename, NULL, get_typename__doc__},
895
 
        {"string", (getter)PyTclObject_string, NULL,
896
 
         PyTclObject_string__doc__},
897
 
        {0},
 
894
    {"typename", (getter)get_typename, NULL, get_typename__doc__},
 
895
    {"string", (getter)PyTclObject_string, NULL,
 
896
     PyTclObject_string__doc__},
 
897
    {0},
898
898
};
899
899
 
900
900
static PyTypeObject PyTclObject_Type = {
901
 
        PyVarObject_HEAD_INIT(NULL, 0)
902
 
        "_tkinter.Tcl_Obj",             /*tp_name*/
903
 
        sizeof(PyTclObject),            /*tp_basicsize*/
904
 
        0,                              /*tp_itemsize*/
905
 
        /* methods */
906
 
        (destructor)PyTclObject_dealloc,/*tp_dealloc*/
907
 
        0,                              /*tp_print*/
908
 
        0,                              /*tp_getattr*/
909
 
        0,                              /*tp_setattr*/
910
 
        0,                              /*tp_reserved*/
911
 
        (reprfunc)PyTclObject_repr,     /*tp_repr*/
912
 
        0,                              /*tp_as_number*/
913
 
        0,                              /*tp_as_sequence*/
914
 
        0,                              /*tp_as_mapping*/
915
 
        0,                              /*tp_hash*/
916
 
        0,                              /*tp_call*/
917
 
        (reprfunc)PyTclObject_str,      /*tp_str*/
918
 
        PyObject_GenericGetAttr,        /*tp_getattro*/
919
 
        0,                              /*tp_setattro*/
920
 
        0,                              /*tp_as_buffer*/
921
 
        Py_TPFLAGS_DEFAULT,             /*tp_flags*/
922
 
        0,                              /*tp_doc*/
923
 
        0,                              /*tp_traverse*/
924
 
        0,                              /*tp_clear*/
925
 
        PyTclObject_richcompare,        /*tp_richcompare*/
926
 
        0,                              /*tp_weaklistoffset*/
927
 
        0,                              /*tp_iter*/
928
 
        0,                              /*tp_iternext*/
929
 
        0,                              /*tp_methods*/
930
 
        0,                              /*tp_members*/
931
 
        PyTclObject_getsetlist,         /*tp_getset*/
932
 
        0,                              /*tp_base*/
933
 
        0,                              /*tp_dict*/
934
 
        0,                              /*tp_descr_get*/
935
 
        0,                              /*tp_descr_set*/
936
 
        0,                              /*tp_dictoffset*/
937
 
        0,                              /*tp_init*/
938
 
        0,                              /*tp_alloc*/
939
 
        0,                              /*tp_new*/
940
 
        0,                              /*tp_free*/
941
 
        0,                              /*tp_is_gc*/
 
901
    PyVarObject_HEAD_INIT(NULL, 0)
 
902
    "_tkinter.Tcl_Obj",                 /*tp_name*/
 
903
    sizeof(PyTclObject),                /*tp_basicsize*/
 
904
    0,                                  /*tp_itemsize*/
 
905
    /* methods */
 
906
    (destructor)PyTclObject_dealloc,/*tp_dealloc*/
 
907
    0,                                  /*tp_print*/
 
908
    0,                                  /*tp_getattr*/
 
909
    0,                                  /*tp_setattr*/
 
910
    0,                                  /*tp_reserved*/
 
911
    (reprfunc)PyTclObject_repr,         /*tp_repr*/
 
912
    0,                                  /*tp_as_number*/
 
913
    0,                                  /*tp_as_sequence*/
 
914
    0,                                  /*tp_as_mapping*/
 
915
    0,                                  /*tp_hash*/
 
916
    0,                                  /*tp_call*/
 
917
    (reprfunc)PyTclObject_str,          /*tp_str*/
 
918
    PyObject_GenericGetAttr,            /*tp_getattro*/
 
919
    0,                                  /*tp_setattro*/
 
920
    0,                                  /*tp_as_buffer*/
 
921
    Py_TPFLAGS_DEFAULT,                 /*tp_flags*/
 
922
    0,                                  /*tp_doc*/
 
923
    0,                                  /*tp_traverse*/
 
924
    0,                                  /*tp_clear*/
 
925
    PyTclObject_richcompare,            /*tp_richcompare*/
 
926
    0,                                  /*tp_weaklistoffset*/
 
927
    0,                                  /*tp_iter*/
 
928
    0,                                  /*tp_iternext*/
 
929
    0,                                  /*tp_methods*/
 
930
    0,                                  /*tp_members*/
 
931
    PyTclObject_getsetlist,             /*tp_getset*/
 
932
    0,                                  /*tp_base*/
 
933
    0,                                  /*tp_dict*/
 
934
    0,                                  /*tp_descr_get*/
 
935
    0,                                  /*tp_descr_set*/
 
936
    0,                                  /*tp_dictoffset*/
 
937
    0,                                  /*tp_init*/
 
938
    0,                                  /*tp_alloc*/
 
939
    0,                                  /*tp_new*/
 
940
    0,                                  /*tp_free*/
 
941
    0,                                  /*tp_is_gc*/
942
942
};
943
943
 
944
944
static Tcl_Obj*
945
945
AsObj(PyObject *value)
946
946
{
947
 
        Tcl_Obj *result;
948
 
        long longVal;
949
 
        int overflow;
 
947
    Tcl_Obj *result;
 
948
    long longVal;
 
949
    int overflow;
950
950
 
951
 
        if (PyBytes_Check(value))
952
 
                return Tcl_NewStringObj(PyBytes_AS_STRING(value),
953
 
                                        PyBytes_GET_SIZE(value));
954
 
        else if (PyBool_Check(value))
955
 
                return Tcl_NewBooleanObj(PyObject_IsTrue(value));
956
 
        else if (PyLong_CheckExact(value) &&
957
 
                 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
958
 
                  !overflow)) {
959
 
                /* If there is an overflow in the long conversion,
960
 
                   fall through to default object handling. */
961
 
                return Tcl_NewLongObj(longVal);
962
 
        }
963
 
        else if (PyFloat_Check(value))
964
 
                return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
965
 
        else if (PyTuple_Check(value)) {
966
 
                Tcl_Obj **argv = (Tcl_Obj**)
967
 
                        ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
968
 
                int i;
969
 
                if(!argv)
970
 
                  return 0;
971
 
                for(i=0;i<PyTuple_Size(value);i++)
972
 
                  argv[i] = AsObj(PyTuple_GetItem(value,i));
973
 
                result = Tcl_NewListObj(PyTuple_Size(value), argv);
974
 
                ckfree(FREECAST argv);
975
 
                return result;
976
 
        }
977
 
        else if (PyUnicode_Check(value)) {
978
 
                Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
979
 
                Py_ssize_t size = PyUnicode_GET_SIZE(value);
980
 
                /* This #ifdef assumes that Tcl uses UCS-2.
981
 
                   See TCL_UTF_MAX test above. */
 
951
    if (PyBytes_Check(value))
 
952
        return Tcl_NewStringObj(PyBytes_AS_STRING(value),
 
953
                                PyBytes_GET_SIZE(value));
 
954
    else if (PyBool_Check(value))
 
955
        return Tcl_NewBooleanObj(PyObject_IsTrue(value));
 
956
    else if (PyLong_CheckExact(value) &&
 
957
             ((longVal = PyLong_AsLongAndOverflow(value, &overflow)),
 
958
              !overflow)) {
 
959
        /* If there is an overflow in the long conversion,
 
960
           fall through to default object handling. */
 
961
        return Tcl_NewLongObj(longVal);
 
962
    }
 
963
    else if (PyFloat_Check(value))
 
964
        return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
 
965
    else if (PyTuple_Check(value)) {
 
966
        Tcl_Obj **argv = (Tcl_Obj**)
 
967
            ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
 
968
        int i;
 
969
        if(!argv)
 
970
          return 0;
 
971
        for(i=0;i<PyTuple_Size(value);i++)
 
972
          argv[i] = AsObj(PyTuple_GetItem(value,i));
 
973
        result = Tcl_NewListObj(PyTuple_Size(value), argv);
 
974
        ckfree(FREECAST argv);
 
975
        return result;
 
976
    }
 
977
    else if (PyUnicode_Check(value)) {
 
978
        Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
 
979
        Py_ssize_t size = PyUnicode_GET_SIZE(value);
 
980
        /* This #ifdef assumes that Tcl uses UCS-2.
 
981
           See TCL_UTF_MAX test above. */
982
982
#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
983
 
                Tcl_UniChar *outbuf = NULL;
984
 
                Py_ssize_t i;
985
 
                size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
986
 
                if (allocsize >= size)
987
 
                        outbuf = (Tcl_UniChar*)ckalloc(allocsize);
988
 
                /* Else overflow occurred, and we take the next exit */
989
 
                if (!outbuf) {
990
 
                        PyErr_NoMemory();
991
 
                        return NULL;
992
 
                }
993
 
                for (i = 0; i < size; i++) {
994
 
                        if (inbuf[i] >= 0x10000) {
995
 
                                /* Tcl doesn't do UTF-16, yet. */
996
 
                                PyErr_SetString(PyExc_ValueError,
997
 
                                                "unsupported character");
998
 
                                ckfree(FREECAST outbuf);
999
 
                                return NULL;
1000
 
                        }
1001
 
                        outbuf[i] = inbuf[i];
1002
 
                }
1003
 
                result = Tcl_NewUnicodeObj(outbuf, size);
1004
 
                ckfree(FREECAST outbuf);
1005
 
                return result;
 
983
        Tcl_UniChar *outbuf = NULL;
 
984
        Py_ssize_t i;
 
985
        size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
 
986
        if (allocsize >= size)
 
987
            outbuf = (Tcl_UniChar*)ckalloc(allocsize);
 
988
        /* Else overflow occurred, and we take the next exit */
 
989
        if (!outbuf) {
 
990
            PyErr_NoMemory();
 
991
            return NULL;
 
992
        }
 
993
        for (i = 0; i < size; i++) {
 
994
            if (inbuf[i] >= 0x10000) {
 
995
                /* Tcl doesn't do UTF-16, yet. */
 
996
                PyErr_SetString(PyExc_ValueError,
 
997
                                "unsupported character");
 
998
                ckfree(FREECAST outbuf);
 
999
                return NULL;
 
1000
            }
 
1001
            outbuf[i] = inbuf[i];
 
1002
        }
 
1003
        result = Tcl_NewUnicodeObj(outbuf, size);
 
1004
        ckfree(FREECAST outbuf);
 
1005
        return result;
1006
1006
#else
1007
 
                return Tcl_NewUnicodeObj(inbuf, size);
 
1007
        return Tcl_NewUnicodeObj(inbuf, size);
1008
1008
#endif
1009
1009
 
1010
 
        }
1011
 
        else if(PyTclObject_Check(value)) {
1012
 
                Tcl_Obj *v = ((PyTclObject*)value)->value;
1013
 
                Tcl_IncrRefCount(v);
1014
 
                return v;
1015
 
        }
1016
 
        else {
1017
 
                PyObject *v = PyObject_Str(value);
1018
 
                if (!v)
1019
 
                        return 0;
1020
 
                result = AsObj(v);
1021
 
                Py_DECREF(v);
1022
 
                return result;
1023
 
        }
 
1010
    }
 
1011
    else if(PyTclObject_Check(value)) {
 
1012
        Tcl_Obj *v = ((PyTclObject*)value)->value;
 
1013
        Tcl_IncrRefCount(v);
 
1014
        return v;
 
1015
    }
 
1016
    else {
 
1017
        PyObject *v = PyObject_Str(value);
 
1018
        if (!v)
 
1019
            return 0;
 
1020
        result = AsObj(v);
 
1021
        Py_DECREF(v);
 
1022
        return result;
 
1023
    }
1024
1024
}
1025
1025
 
1026
1026
static PyObject*
1027
1027
FromObj(PyObject* tkapp, Tcl_Obj *value)
1028
1028
{
1029
 
        PyObject *result = NULL;
1030
 
        TkappObject *app = (TkappObject*)tkapp;
1031
 
 
1032
 
        if (value->typePtr == NULL) {
1033
 
                return PyUnicode_FromStringAndSize(value->bytes,
1034
 
                                                   value->length);
1035
 
        }
1036
 
 
1037
 
        if (value->typePtr == app->BooleanType) {
1038
 
                result = value->internalRep.longValue ? Py_True : Py_False;
1039
 
                Py_INCREF(result);
1040
 
                return result;
1041
 
        }
1042
 
 
1043
 
        if (value->typePtr == app->ByteArrayType) {
1044
 
                int size;
1045
 
                char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
1046
 
                return PyBytes_FromStringAndSize(data, size);
1047
 
        }
1048
 
 
1049
 
        if (value->typePtr == app->DoubleType) {
1050
 
                return PyFloat_FromDouble(value->internalRep.doubleValue);
1051
 
        }
1052
 
 
1053
 
        if (value->typePtr == app->IntType) {
1054
 
                return PyLong_FromLong(value->internalRep.longValue);
1055
 
        }
1056
 
 
1057
 
        if (value->typePtr == app->ListType) {
1058
 
                int size;
1059
 
                int i, status;
1060
 
                PyObject *elem;
1061
 
                Tcl_Obj *tcl_elem;
1062
 
 
1063
 
                status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
1064
 
                if (status == TCL_ERROR)
1065
 
                        return Tkinter_Error(tkapp);
1066
 
                result = PyTuple_New(size);
1067
 
                if (!result)
1068
 
                        return NULL;
1069
 
                for (i = 0; i < size; i++) {
1070
 
                        status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
1071
 
                                                  value, i, &tcl_elem);
1072
 
                        if (status == TCL_ERROR) {
1073
 
                                Py_DECREF(result);
1074
 
                                return Tkinter_Error(tkapp);
1075
 
                        }
1076
 
                        elem = FromObj(tkapp, tcl_elem);
1077
 
                        if (!elem) {
1078
 
                                Py_DECREF(result);
1079
 
                                return NULL;
1080
 
                        }
1081
 
                        PyTuple_SetItem(result, i, elem);
1082
 
                }
1083
 
                return result;
1084
 
        }
1085
 
 
1086
 
        if (value->typePtr == app->ProcBodyType) {
1087
 
          /* fall through: return tcl object. */
1088
 
        }
1089
 
 
1090
 
        if (value->typePtr == app->StringType) {
 
1029
    PyObject *result = NULL;
 
1030
    TkappObject *app = (TkappObject*)tkapp;
 
1031
 
 
1032
    if (value->typePtr == NULL) {
 
1033
        return PyUnicode_FromStringAndSize(value->bytes,
 
1034
                                           value->length);
 
1035
    }
 
1036
 
 
1037
    if (value->typePtr == app->BooleanType) {
 
1038
        result = value->internalRep.longValue ? Py_True : Py_False;
 
1039
        Py_INCREF(result);
 
1040
        return result;
 
1041
    }
 
1042
 
 
1043
    if (value->typePtr == app->ByteArrayType) {
 
1044
        int size;
 
1045
        char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
 
1046
        return PyBytes_FromStringAndSize(data, size);
 
1047
    }
 
1048
 
 
1049
    if (value->typePtr == app->DoubleType) {
 
1050
        return PyFloat_FromDouble(value->internalRep.doubleValue);
 
1051
    }
 
1052
 
 
1053
    if (value->typePtr == app->IntType) {
 
1054
        return PyLong_FromLong(value->internalRep.longValue);
 
1055
    }
 
1056
 
 
1057
    if (value->typePtr == app->ListType) {
 
1058
        int size;
 
1059
        int i, status;
 
1060
        PyObject *elem;
 
1061
        Tcl_Obj *tcl_elem;
 
1062
 
 
1063
        status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
 
1064
        if (status == TCL_ERROR)
 
1065
            return Tkinter_Error(tkapp);
 
1066
        result = PyTuple_New(size);
 
1067
        if (!result)
 
1068
            return NULL;
 
1069
        for (i = 0; i < size; i++) {
 
1070
            status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
 
1071
                                      value, i, &tcl_elem);
 
1072
            if (status == TCL_ERROR) {
 
1073
                Py_DECREF(result);
 
1074
                return Tkinter_Error(tkapp);
 
1075
            }
 
1076
            elem = FromObj(tkapp, tcl_elem);
 
1077
            if (!elem) {
 
1078
                Py_DECREF(result);
 
1079
                return NULL;
 
1080
            }
 
1081
            PyTuple_SetItem(result, i, elem);
 
1082
        }
 
1083
        return result;
 
1084
    }
 
1085
 
 
1086
    if (value->typePtr == app->ProcBodyType) {
 
1087
      /* fall through: return tcl object. */
 
1088
    }
 
1089
 
 
1090
    if (value->typePtr == app->StringType) {
1091
1091
#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
1092
 
                PyObject *result;
1093
 
                int size;
1094
 
                Tcl_UniChar *input;
1095
 
                Py_UNICODE *output;
 
1092
        PyObject *result;
 
1093
        int size;
 
1094
        Tcl_UniChar *input;
 
1095
        Py_UNICODE *output;
1096
1096
 
1097
 
                size = Tcl_GetCharLength(value);
1098
 
                result = PyUnicode_FromUnicode(NULL, size);
1099
 
                if (!result)
1100
 
                        return NULL;
1101
 
                input = Tcl_GetUnicode(value);
1102
 
                output = PyUnicode_AS_UNICODE(result);
1103
 
                while (size--)
1104
 
                        *output++ = *input++;
1105
 
                return result;
 
1097
        size = Tcl_GetCharLength(value);
 
1098
        result = PyUnicode_FromUnicode(NULL, size);
 
1099
        if (!result)
 
1100
            return NULL;
 
1101
        input = Tcl_GetUnicode(value);
 
1102
        output = PyUnicode_AS_UNICODE(result);
 
1103
        while (size--)
 
1104
            *output++ = *input++;
 
1105
        return result;
1106
1106
#else
1107
 
                return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1108
 
                                             Tcl_GetCharLength(value));
 
1107
        return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
 
1108
                                     Tcl_GetCharLength(value));
1109
1109
#endif
1110
 
        }
 
1110
    }
1111
1111
 
1112
 
        return newPyTclObject(value);
 
1112
    return newPyTclObject(value);
1113
1113
}
1114
1114
 
1115
1115
#ifdef WITH_THREAD
1117
1117
TCL_DECLARE_MUTEX(call_mutex)
1118
1118
 
1119
1119
typedef struct Tkapp_CallEvent {
1120
 
        Tcl_Event ev;        /* Must be first */
1121
 
        TkappObject *self;
1122
 
        PyObject *args;
1123
 
        int flags;
1124
 
        PyObject **res;
1125
 
        PyObject **exc_type, **exc_value, **exc_tb;
1126
 
        Tcl_Condition *done;
 
1120
    Tcl_Event ev;            /* Must be first */
 
1121
    TkappObject *self;
 
1122
    PyObject *args;
 
1123
    int flags;
 
1124
    PyObject **res;
 
1125
    PyObject **exc_type, **exc_value, **exc_tb;
 
1126
    Tcl_Condition *done;
1127
1127
} Tkapp_CallEvent;
1128
1128
#endif
1129
1129
 
1130
1130
void
1131
1131
Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
1132
1132
{
1133
 
        int i;
1134
 
        for (i = 0; i < objc; i++)
1135
 
                Tcl_DecrRefCount(objv[i]);
1136
 
        if (objv != objStore)
1137
 
                ckfree(FREECAST objv);
 
1133
    int i;
 
1134
    for (i = 0; i < objc; i++)
 
1135
        Tcl_DecrRefCount(objv[i]);
 
1136
    if (objv != objStore)
 
1137
        ckfree(FREECAST objv);
1138
1138
}
1139
1139
 
1140
1140
/* Convert Python objects to Tcl objects. This must happen in the
1143
1143
static Tcl_Obj**
1144
1144
Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1145
1145
{
1146
 
        Tcl_Obj **objv = objStore;
1147
 
        int objc = 0, i;
1148
 
        if (args == NULL)
1149
 
                /* do nothing */;
1150
 
 
1151
 
        else if (!PyTuple_Check(args)) {
1152
 
                objv[0] = AsObj(args);
1153
 
                if (objv[0] == 0)
1154
 
                        goto finally;
1155
 
                objc = 1;
1156
 
                Tcl_IncrRefCount(objv[0]);
1157
 
        }
1158
 
        else {
1159
 
                objc = PyTuple_Size(args);
1160
 
 
1161
 
                if (objc > ARGSZ) {
1162
 
                        objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
1163
 
                        if (objv == NULL) {
1164
 
                                PyErr_NoMemory();
1165
 
                                objc = 0;
1166
 
                                goto finally;
1167
 
                        }
1168
 
                }
1169
 
 
1170
 
                for (i = 0; i < objc; i++) {
1171
 
                        PyObject *v = PyTuple_GetItem(args, i);
1172
 
                        if (v == Py_None) {
1173
 
                                objc = i;
1174
 
                                break;
1175
 
                        }
1176
 
                        objv[i] = AsObj(v);
1177
 
                        if (!objv[i]) {
1178
 
                                /* Reset objc, so it attempts to clear
1179
 
                                   objects only up to i. */
1180
 
                                objc = i;
1181
 
                                goto finally;
1182
 
                        }
1183
 
                        Tcl_IncrRefCount(objv[i]);
1184
 
                }
1185
 
        }
1186
 
        *pobjc = objc;
1187
 
        return objv;
 
1146
    Tcl_Obj **objv = objStore;
 
1147
    int objc = 0, i;
 
1148
    if (args == NULL)
 
1149
        /* do nothing */;
 
1150
 
 
1151
    else if (!PyTuple_Check(args)) {
 
1152
        objv[0] = AsObj(args);
 
1153
        if (objv[0] == 0)
 
1154
            goto finally;
 
1155
        objc = 1;
 
1156
        Tcl_IncrRefCount(objv[0]);
 
1157
    }
 
1158
    else {
 
1159
        objc = PyTuple_Size(args);
 
1160
 
 
1161
        if (objc > ARGSZ) {
 
1162
            objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
 
1163
            if (objv == NULL) {
 
1164
                PyErr_NoMemory();
 
1165
                objc = 0;
 
1166
                goto finally;
 
1167
            }
 
1168
        }
 
1169
 
 
1170
        for (i = 0; i < objc; i++) {
 
1171
            PyObject *v = PyTuple_GetItem(args, i);
 
1172
            if (v == Py_None) {
 
1173
                objc = i;
 
1174
                break;
 
1175
            }
 
1176
            objv[i] = AsObj(v);
 
1177
            if (!objv[i]) {
 
1178
                /* Reset objc, so it attempts to clear
 
1179
                   objects only up to i. */
 
1180
                objc = i;
 
1181
                goto finally;
 
1182
            }
 
1183
            Tcl_IncrRefCount(objv[i]);
 
1184
        }
 
1185
    }
 
1186
    *pobjc = objc;
 
1187
    return objv;
1188
1188
finally:
1189
 
        Tkapp_CallDeallocArgs(objv, objStore, objc);
1190
 
        return NULL;
 
1189
    Tkapp_CallDeallocArgs(objv, objStore, objc);
 
1190
    return NULL;
1191
1191
}
1192
1192
 
1193
1193
/* Convert the results of a command call into a Python objects. */
1195
1195
static PyObject*
1196
1196
Tkapp_CallResult(TkappObject *self)
1197
1197
{
1198
 
        PyObject *res = NULL;
1199
 
        if(self->wantobjects) {
1200
 
                Tcl_Obj *value = Tcl_GetObjResult(self->interp);
1201
 
                /* Not sure whether the IncrRef is necessary, but something
1202
 
                   may overwrite the interpreter result while we are
1203
 
                   converting it. */
1204
 
                Tcl_IncrRefCount(value);
1205
 
                res = FromObj((PyObject*)self, value);
1206
 
                Tcl_DecrRefCount(value);
1207
 
        } else {
1208
 
                const char *s = Tcl_GetStringResult(self->interp);
1209
 
                const char *p = s;
 
1198
    PyObject *res = NULL;
 
1199
    if(self->wantobjects) {
 
1200
        Tcl_Obj *value = Tcl_GetObjResult(self->interp);
 
1201
        /* Not sure whether the IncrRef is necessary, but something
 
1202
           may overwrite the interpreter result while we are
 
1203
           converting it. */
 
1204
        Tcl_IncrRefCount(value);
 
1205
        res = FromObj((PyObject*)self, value);
 
1206
        Tcl_DecrRefCount(value);
 
1207
    } else {
 
1208
        const char *s = Tcl_GetStringResult(self->interp);
 
1209
        const char *p = s;
1210
1210
 
1211
 
                res = PyUnicode_FromStringAndSize(s, (int)(p-s));
1212
 
        }
1213
 
        return res;
 
1211
        res = PyUnicode_FromStringAndSize(s, (int)(p-s));
 
1212
    }
 
1213
    return res;
1214
1214
}
1215
1215
 
1216
1216
#ifdef WITH_THREAD
1222
1222
static int
1223
1223
Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
1224
1224
{
1225
 
        Tcl_Obj *objStore[ARGSZ];
1226
 
        Tcl_Obj **objv;
1227
 
        int objc;
1228
 
        int i;
1229
 
        ENTER_PYTHON
1230
 
        objv = Tkapp_CallArgs(e->args, objStore, &objc);
1231
 
        if (!objv) {
1232
 
                PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
1233
 
                *(e->res) = NULL;
1234
 
        }
1235
 
        LEAVE_PYTHON
1236
 
        if (!objv)
1237
 
                goto done;
1238
 
        i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
1239
 
        ENTER_PYTHON
1240
 
        if (i == TCL_ERROR) {
1241
 
                *(e->res) = NULL;
1242
 
                *(e->exc_type) = NULL;
1243
 
                *(e->exc_tb) = NULL;
1244
 
                *(e->exc_value) = PyObject_CallFunction(
1245
 
                        Tkinter_TclError, "s",
1246
 
                        Tcl_GetStringResult(e->self->interp));
1247
 
        }
1248
 
        else {
1249
 
                *(e->res) = Tkapp_CallResult(e->self);
1250
 
        }
1251
 
        LEAVE_PYTHON
 
1225
    Tcl_Obj *objStore[ARGSZ];
 
1226
    Tcl_Obj **objv;
 
1227
    int objc;
 
1228
    int i;
 
1229
    ENTER_PYTHON
 
1230
    objv = Tkapp_CallArgs(e->args, objStore, &objc);
 
1231
    if (!objv) {
 
1232
        PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
 
1233
        *(e->res) = NULL;
 
1234
    }
 
1235
    LEAVE_PYTHON
 
1236
    if (!objv)
 
1237
        goto done;
 
1238
    i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
 
1239
    ENTER_PYTHON
 
1240
    if (i == TCL_ERROR) {
 
1241
        *(e->res) = NULL;
 
1242
        *(e->exc_type) = NULL;
 
1243
        *(e->exc_tb) = NULL;
 
1244
        *(e->exc_value) = PyObject_CallFunction(
 
1245
            Tkinter_TclError, "s",
 
1246
            Tcl_GetStringResult(e->self->interp));
 
1247
    }
 
1248
    else {
 
1249
        *(e->res) = Tkapp_CallResult(e->self);
 
1250
    }
 
1251
    LEAVE_PYTHON
1252
1252
 
1253
 
        Tkapp_CallDeallocArgs(objv, objStore, objc);
 
1253
    Tkapp_CallDeallocArgs(objv, objStore, objc);
1254
1254
done:
1255
 
        /* Wake up calling thread. */
1256
 
        Tcl_MutexLock(&call_mutex);
1257
 
        Tcl_ConditionNotify(e->done);
1258
 
        Tcl_MutexUnlock(&call_mutex);
1259
 
        return 1;
 
1255
    /* Wake up calling thread. */
 
1256
    Tcl_MutexLock(&call_mutex);
 
1257
    Tcl_ConditionNotify(e->done);
 
1258
    Tcl_MutexUnlock(&call_mutex);
 
1259
    return 1;
1260
1260
}
1261
1261
 
1262
1262
#endif
1276
1276
static PyObject *
1277
1277
Tkapp_Call(PyObject *selfptr, PyObject *args)
1278
1278
{
1279
 
        Tcl_Obj *objStore[ARGSZ];
1280
 
        Tcl_Obj **objv = NULL;
1281
 
        int objc, i;
1282
 
        PyObject *res = NULL;
1283
 
        TkappObject *self = (TkappObject*)selfptr;
1284
 
        int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
 
1279
    Tcl_Obj *objStore[ARGSZ];
 
1280
    Tcl_Obj **objv = NULL;
 
1281
    int objc, i;
 
1282
    PyObject *res = NULL;
 
1283
    TkappObject *self = (TkappObject*)selfptr;
 
1284
    int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL;
1285
1285
 
1286
 
        /* If args is a single tuple, replace with contents of tuple */
1287
 
        if (1 == PyTuple_Size(args)){
1288
 
                PyObject* item = PyTuple_GetItem(args, 0);
1289
 
                if (PyTuple_Check(item))
1290
 
                        args = item;
1291
 
        }
 
1286
    /* If args is a single tuple, replace with contents of tuple */
 
1287
    if (1 == PyTuple_Size(args)){
 
1288
        PyObject* item = PyTuple_GetItem(args, 0);
 
1289
        if (PyTuple_Check(item))
 
1290
            args = item;
 
1291
    }
1292
1292
#ifdef WITH_THREAD
1293
 
        if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1294
 
                /* We cannot call the command directly. Instead, we must
1295
 
                   marshal the parameters to the interpreter thread. */
1296
 
                Tkapp_CallEvent *ev;
1297
 
                Tcl_Condition cond = NULL;
1298
 
                PyObject *exc_type, *exc_value, *exc_tb;
1299
 
                if (!WaitForMainloop(self))
1300
 
                        return NULL;
1301
 
                ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
1302
 
                ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1303
 
                ev->self = self;
1304
 
                ev->args = args;
1305
 
                ev->res = &res;
1306
 
                ev->exc_type = &exc_type;
1307
 
                ev->exc_value = &exc_value;
1308
 
                ev->exc_tb = &exc_tb;
1309
 
                ev->done = &cond;
1310
 
 
1311
 
                Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
1312
 
 
1313
 
                if (res == NULL) {
1314
 
                        if (exc_type)
1315
 
                                PyErr_Restore(exc_type, exc_value, exc_tb);
1316
 
                        else
1317
 
                                PyErr_SetObject(Tkinter_TclError, exc_value);
1318
 
                }
1319
 
                Tcl_ConditionFinalize(&cond);
1320
 
        }
1321
 
        else
 
1293
    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
 
1294
        /* We cannot call the command directly. Instead, we must
 
1295
           marshal the parameters to the interpreter thread. */
 
1296
        Tkapp_CallEvent *ev;
 
1297
        Tcl_Condition cond = NULL;
 
1298
        PyObject *exc_type, *exc_value, *exc_tb;
 
1299
        if (!WaitForMainloop(self))
 
1300
            return NULL;
 
1301
        ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
 
1302
        ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
 
1303
        ev->self = self;
 
1304
        ev->args = args;
 
1305
        ev->res = &res;
 
1306
        ev->exc_type = &exc_type;
 
1307
        ev->exc_value = &exc_value;
 
1308
        ev->exc_tb = &exc_tb;
 
1309
        ev->done = &cond;
 
1310
 
 
1311
        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
 
1312
 
 
1313
        if (res == NULL) {
 
1314
            if (exc_type)
 
1315
                PyErr_Restore(exc_type, exc_value, exc_tb);
 
1316
            else
 
1317
                PyErr_SetObject(Tkinter_TclError, exc_value);
 
1318
        }
 
1319
        Tcl_ConditionFinalize(&cond);
 
1320
    }
 
1321
    else
1322
1322
#endif
1323
 
        {
1324
 
 
1325
 
                objv = Tkapp_CallArgs(args, objStore, &objc);
1326
 
                if (!objv)
1327
 
                        return NULL;
1328
 
 
1329
 
                ENTER_TCL
1330
 
 
1331
 
                i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1332
 
 
1333
 
                ENTER_OVERLAP
1334
 
 
1335
 
                if (i == TCL_ERROR)
1336
 
                        Tkinter_Error(selfptr);
1337
 
                else
1338
 
                        res = Tkapp_CallResult(self);
1339
 
 
1340
 
                LEAVE_OVERLAP_TCL
1341
 
 
1342
 
                Tkapp_CallDeallocArgs(objv, objStore, objc);
1343
 
        }
1344
 
        return res;
 
1323
    {
 
1324
 
 
1325
        objv = Tkapp_CallArgs(args, objStore, &objc);
 
1326
        if (!objv)
 
1327
            return NULL;
 
1328
 
 
1329
        ENTER_TCL
 
1330
 
 
1331
        i = Tcl_EvalObjv(self->interp, objc, objv, flags);
 
1332
 
 
1333
        ENTER_OVERLAP
 
1334
 
 
1335
        if (i == TCL_ERROR)
 
1336
            Tkinter_Error(selfptr);
 
1337
        else
 
1338
            res = Tkapp_CallResult(self);
 
1339
 
 
1340
        LEAVE_OVERLAP_TCL
 
1341
 
 
1342
        Tkapp_CallDeallocArgs(objv, objStore, objc);
 
1343
    }
 
1344
    return res;
1345
1345
}
1346
1346
 
1347
1347
 
1348
1348
static PyObject *
1349
1349
Tkapp_GlobalCall(PyObject *self, PyObject *args)
1350
1350
{
1351
 
        /* Could do the same here as for Tkapp_Call(), but this is not used
1352
 
           much, so I can't be bothered.  Unfortunately Tcl doesn't export a
1353
 
           way for the user to do what all its Global* variants do (save and
1354
 
           reset the scope pointer, call the local version, restore the saved
1355
 
           scope pointer). */
1356
 
 
1357
 
        char *cmd;
1358
 
        PyObject *res = NULL;
1359
 
 
1360
 
        CHECK_TCL_APPARTMENT;
1361
 
 
1362
 
        cmd  = Merge(args);
1363
 
        if (cmd) {
1364
 
                int err;
1365
 
                ENTER_TCL
1366
 
                err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
1367
 
                ENTER_OVERLAP
1368
 
                if (err == TCL_ERROR)
1369
 
                        res = Tkinter_Error(self);
1370
 
                else
1371
 
                        res = PyUnicode_FromString(Tkapp_Result(self));
1372
 
                LEAVE_OVERLAP_TCL
1373
 
                ckfree(cmd);
1374
 
        }
1375
 
 
1376
 
        return res;
 
1351
    /* Could do the same here as for Tkapp_Call(), but this is not used
 
1352
       much, so I can't be bothered.  Unfortunately Tcl doesn't export a
 
1353
       way for the user to do what all its Global* variants do (save and
 
1354
       reset the scope pointer, call the local version, restore the saved
 
1355
       scope pointer). */
 
1356
 
 
1357
    char *cmd;
 
1358
    PyObject *res = NULL;
 
1359
 
 
1360
    CHECK_TCL_APPARTMENT;
 
1361
 
 
1362
    cmd  = Merge(args);
 
1363
    if (cmd) {
 
1364
        int err;
 
1365
        ENTER_TCL
 
1366
        err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
 
1367
        ENTER_OVERLAP
 
1368
        if (err == TCL_ERROR)
 
1369
            res = Tkinter_Error(self);
 
1370
        else
 
1371
            res = PyUnicode_FromString(Tkapp_Result(self));
 
1372
        LEAVE_OVERLAP_TCL
 
1373
        ckfree(cmd);
 
1374
    }
 
1375
 
 
1376
    return res;
1377
1377
}
1378
1378
 
1379
1379
static PyObject *
1380
1380
Tkapp_Eval(PyObject *self, PyObject *args)
1381
1381
{
1382
 
        char *script;
1383
 
        PyObject *res = NULL;
1384
 
        int err;
1385
 
 
1386
 
        if (!PyArg_ParseTuple(args, "s:eval", &script))
1387
 
                return NULL;
1388
 
 
1389
 
        CHECK_TCL_APPARTMENT;
1390
 
 
1391
 
        ENTER_TCL
1392
 
        err = Tcl_Eval(Tkapp_Interp(self), script);
1393
 
        ENTER_OVERLAP
1394
 
        if (err == TCL_ERROR)
1395
 
                res = Tkinter_Error(self);
1396
 
        else
1397
 
                res = PyUnicode_FromString(Tkapp_Result(self));
1398
 
        LEAVE_OVERLAP_TCL
1399
 
        return res;
 
1382
    char *script;
 
1383
    PyObject *res = NULL;
 
1384
    int err;
 
1385
 
 
1386
    if (!PyArg_ParseTuple(args, "s:eval", &script))
 
1387
        return NULL;
 
1388
 
 
1389
    CHECK_TCL_APPARTMENT;
 
1390
 
 
1391
    ENTER_TCL
 
1392
    err = Tcl_Eval(Tkapp_Interp(self), script);
 
1393
    ENTER_OVERLAP
 
1394
    if (err == TCL_ERROR)
 
1395
        res = Tkinter_Error(self);
 
1396
    else
 
1397
        res = PyUnicode_FromString(Tkapp_Result(self));
 
1398
    LEAVE_OVERLAP_TCL
 
1399
    return res;
1400
1400
}
1401
1401
 
1402
1402
static PyObject *
1403
1403
Tkapp_GlobalEval(PyObject *self, PyObject *args)
1404
1404
{
1405
 
        char *script;
1406
 
        PyObject *res = NULL;
1407
 
        int err;
1408
 
 
1409
 
        if (!PyArg_ParseTuple(args, "s:globaleval", &script))
1410
 
                return NULL;
1411
 
 
1412
 
        CHECK_TCL_APPARTMENT;
1413
 
 
1414
 
        ENTER_TCL
1415
 
        err = Tcl_GlobalEval(Tkapp_Interp(self), script);
1416
 
        ENTER_OVERLAP
1417
 
        if (err == TCL_ERROR)
1418
 
                res = Tkinter_Error(self);
1419
 
        else
1420
 
                res = PyUnicode_FromString(Tkapp_Result(self));
1421
 
        LEAVE_OVERLAP_TCL
1422
 
        return res;
 
1405
    char *script;
 
1406
    PyObject *res = NULL;
 
1407
    int err;
 
1408
 
 
1409
    if (!PyArg_ParseTuple(args, "s:globaleval", &script))
 
1410
        return NULL;
 
1411
 
 
1412
    CHECK_TCL_APPARTMENT;
 
1413
 
 
1414
    ENTER_TCL
 
1415
    err = Tcl_GlobalEval(Tkapp_Interp(self), script);
 
1416
    ENTER_OVERLAP
 
1417
    if (err == TCL_ERROR)
 
1418
        res = Tkinter_Error(self);
 
1419
    else
 
1420
        res = PyUnicode_FromString(Tkapp_Result(self));
 
1421
    LEAVE_OVERLAP_TCL
 
1422
    return res;
1423
1423
}
1424
1424
 
1425
1425
static PyObject *
1426
1426
Tkapp_EvalFile(PyObject *self, PyObject *args)
1427
1427
{
1428
 
        char *fileName;
1429
 
        PyObject *res = NULL;
1430
 
        int err;
1431
 
 
1432
 
        if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
1433
 
                return NULL;
1434
 
 
1435
 
        CHECK_TCL_APPARTMENT;
1436
 
 
1437
 
        ENTER_TCL
1438
 
        err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
1439
 
        ENTER_OVERLAP
1440
 
        if (err == TCL_ERROR)
1441
 
                res = Tkinter_Error(self);
1442
 
 
1443
 
        else
1444
 
                res = PyUnicode_FromString(Tkapp_Result(self));
1445
 
        LEAVE_OVERLAP_TCL
1446
 
        return res;
 
1428
    char *fileName;
 
1429
    PyObject *res = NULL;
 
1430
    int err;
 
1431
 
 
1432
    if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
 
1433
        return NULL;
 
1434
 
 
1435
    CHECK_TCL_APPARTMENT;
 
1436
 
 
1437
    ENTER_TCL
 
1438
    err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
 
1439
    ENTER_OVERLAP
 
1440
    if (err == TCL_ERROR)
 
1441
        res = Tkinter_Error(self);
 
1442
 
 
1443
    else
 
1444
        res = PyUnicode_FromString(Tkapp_Result(self));
 
1445
    LEAVE_OVERLAP_TCL
 
1446
    return res;
1447
1447
}
1448
1448
 
1449
1449
static PyObject *
1450
1450
Tkapp_Record(PyObject *self, PyObject *args)
1451
1451
{
1452
 
        char *script;
1453
 
        PyObject *res = NULL;
1454
 
        int err;
1455
 
 
1456
 
        if (!PyArg_ParseTuple(args, "s", &script))
1457
 
                return NULL;
1458
 
 
1459
 
        CHECK_TCL_APPARTMENT;
1460
 
 
1461
 
        ENTER_TCL
1462
 
        err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
1463
 
        ENTER_OVERLAP
1464
 
        if (err == TCL_ERROR)
1465
 
                res = Tkinter_Error(self);
1466
 
        else
1467
 
                res = PyUnicode_FromString(Tkapp_Result(self));
1468
 
        LEAVE_OVERLAP_TCL
1469
 
        return res;
 
1452
    char *script;
 
1453
    PyObject *res = NULL;
 
1454
    int err;
 
1455
 
 
1456
    if (!PyArg_ParseTuple(args, "s", &script))
 
1457
        return NULL;
 
1458
 
 
1459
    CHECK_TCL_APPARTMENT;
 
1460
 
 
1461
    ENTER_TCL
 
1462
    err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
 
1463
    ENTER_OVERLAP
 
1464
    if (err == TCL_ERROR)
 
1465
        res = Tkinter_Error(self);
 
1466
    else
 
1467
        res = PyUnicode_FromString(Tkapp_Result(self));
 
1468
    LEAVE_OVERLAP_TCL
 
1469
    return res;
1470
1470
}
1471
1471
 
1472
1472
static PyObject *
1473
1473
Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
1474
1474
{
1475
 
        char *msg;
1476
 
 
1477
 
        if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
1478
 
                return NULL;
1479
 
        CHECK_TCL_APPARTMENT;
1480
 
 
1481
 
        ENTER_TCL
1482
 
        Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
1483
 
        LEAVE_TCL
1484
 
 
1485
 
        Py_INCREF(Py_None);
1486
 
        return Py_None;
 
1475
    char *msg;
 
1476
 
 
1477
    if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
 
1478
        return NULL;
 
1479
    CHECK_TCL_APPARTMENT;
 
1480
 
 
1481
    ENTER_TCL
 
1482
    Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
 
1483
    LEAVE_TCL
 
1484
 
 
1485
    Py_INCREF(Py_None);
 
1486
    return Py_None;
1487
1487
}
1488
1488
 
1489
1489
 
1490
 
 
 
1490
 
1491
1491
/** Tcl Variable **/
1492
1492
 
1493
1493
typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1496
1496
TCL_DECLARE_MUTEX(var_mutex)
1497
1497
 
1498
1498
typedef struct VarEvent {
1499
 
        Tcl_Event ev; /* must be first */
1500
 
        PyObject *self;
1501
 
        PyObject *args;
1502
 
        int flags;
1503
 
        EventFunc func;
1504
 
        PyObject **res;
1505
 
        PyObject **exc_type;
1506
 
        PyObject **exc_val;
1507
 
        Tcl_Condition *cond;
 
1499
    Tcl_Event ev; /* must be first */
 
1500
    PyObject *self;
 
1501
    PyObject *args;
 
1502
    int flags;
 
1503
    EventFunc func;
 
1504
    PyObject **res;
 
1505
    PyObject **exc_type;
 
1506
    PyObject **exc_val;
 
1507
    Tcl_Condition *cond;
1508
1508
} VarEvent;
1509
1509
#endif
1510
1510
 
1511
1511
static int
1512
1512
varname_converter(PyObject *in, void *_out)
1513
1513
{
1514
 
        char **out = (char**)_out;
1515
 
        if (PyBytes_Check(in)) {
1516
 
                *out = PyBytes_AsString(in);
1517
 
                return 1;
1518
 
        }
1519
 
        if (PyUnicode_Check(in)) {
1520
 
                *out = _PyUnicode_AsString(in);
1521
 
                return 1;
1522
 
        }
1523
 
        if (PyTclObject_Check(in)) {
1524
 
                *out = PyTclObject_TclString(in);
1525
 
                return 1;
1526
 
        }
1527
 
        /* XXX: Should give diagnostics. */
1528
 
        return 0;
 
1514
    char **out = (char**)_out;
 
1515
    if (PyBytes_Check(in)) {
 
1516
        *out = PyBytes_AsString(in);
 
1517
        return 1;
 
1518
    }
 
1519
    if (PyUnicode_Check(in)) {
 
1520
        *out = _PyUnicode_AsString(in);
 
1521
        return 1;
 
1522
    }
 
1523
    if (PyTclObject_Check(in)) {
 
1524
        *out = PyTclObject_TclString(in);
 
1525
        return 1;
 
1526
    }
 
1527
    /* XXX: Should give diagnostics. */
 
1528
    return 0;
1529
1529
}
1530
1530
 
1531
1531
#ifdef WITH_THREAD
1533
1533
static void
1534
1534
var_perform(VarEvent *ev)
1535
1535
{
1536
 
        *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1537
 
        if (!*(ev->res)) {
1538
 
                PyObject *exc, *val, *tb;
1539
 
                PyErr_Fetch(&exc, &val, &tb);
1540
 
                PyErr_NormalizeException(&exc, &val, &tb);
1541
 
                *(ev->exc_type) = exc;
1542
 
                *(ev->exc_val) = val;
1543
 
                Py_DECREF(tb);
1544
 
        }
 
1536
    *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
 
1537
    if (!*(ev->res)) {
 
1538
        PyObject *exc, *val, *tb;
 
1539
        PyErr_Fetch(&exc, &val, &tb);
 
1540
        PyErr_NormalizeException(&exc, &val, &tb);
 
1541
        *(ev->exc_type) = exc;
 
1542
        *(ev->exc_val) = val;
 
1543
        Py_DECREF(tb);
 
1544
    }
1545
1545
 
1546
1546
}
1547
1547
 
1548
1548
static int
1549
1549
var_proc(VarEvent* ev, int flags)
1550
1550
{
1551
 
        ENTER_PYTHON
1552
 
        var_perform(ev);
1553
 
        Tcl_MutexLock(&var_mutex);
1554
 
        Tcl_ConditionNotify(ev->cond);
1555
 
        Tcl_MutexUnlock(&var_mutex);
1556
 
        LEAVE_PYTHON
1557
 
        return 1;
 
1551
    ENTER_PYTHON
 
1552
    var_perform(ev);
 
1553
    Tcl_MutexLock(&var_mutex);
 
1554
    Tcl_ConditionNotify(ev->cond);
 
1555
    Tcl_MutexUnlock(&var_mutex);
 
1556
    LEAVE_PYTHON
 
1557
    return 1;
1558
1558
}
1559
1559
 
1560
1560
#endif
1563
1563
var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
1564
1564
{
1565
1565
#ifdef WITH_THREAD
1566
 
        TkappObject *self = (TkappObject*)selfptr;
1567
 
        if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1568
 
                TkappObject *self = (TkappObject*)selfptr;
1569
 
                VarEvent *ev;
1570
 
                PyObject *res, *exc_type, *exc_val;
1571
 
                Tcl_Condition cond = NULL;
1572
 
 
1573
 
                /* The current thread is not the interpreter thread.  Marshal
1574
 
                   the call to the interpreter thread, then wait for
1575
 
                   completion. */
1576
 
                if (!WaitForMainloop(self))
1577
 
                        return NULL;
1578
 
 
1579
 
                ev = (VarEvent*)ckalloc(sizeof(VarEvent));
1580
 
 
1581
 
                ev->self = selfptr;
1582
 
                ev->args = args;
1583
 
                ev->flags = flags;
1584
 
                ev->func = func;
1585
 
                ev->res = &res;
1586
 
                ev->exc_type = &exc_type;
1587
 
                ev->exc_val = &exc_val;
1588
 
                ev->cond = &cond;
1589
 
                ev->ev.proc = (Tcl_EventProc*)var_proc;
1590
 
                Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
1591
 
                Tcl_ConditionFinalize(&cond);
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
 
        }
 
1566
    TkappObject *self = (TkappObject*)selfptr;
 
1567
    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
 
1568
        TkappObject *self = (TkappObject*)selfptr;
 
1569
        VarEvent *ev;
 
1570
        PyObject *res, *exc_type, *exc_val;
 
1571
        Tcl_Condition cond = NULL;
 
1572
 
 
1573
        /* The current thread is not the interpreter thread.  Marshal
 
1574
           the call to the interpreter thread, then wait for
 
1575
           completion. */
 
1576
        if (!WaitForMainloop(self))
 
1577
            return NULL;
 
1578
 
 
1579
        ev = (VarEvent*)ckalloc(sizeof(VarEvent));
 
1580
 
 
1581
        ev->self = selfptr;
 
1582
        ev->args = args;
 
1583
        ev->flags = flags;
 
1584
        ev->func = func;
 
1585
        ev->res = &res;
 
1586
        ev->exc_type = &exc_type;
 
1587
        ev->exc_val = &exc_val;
 
1588
        ev->cond = &cond;
 
1589
        ev->ev.proc = (Tcl_EventProc*)var_proc;
 
1590
        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
 
1591
        Tcl_ConditionFinalize(&cond);
 
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
1600
#endif
1601
 
        /* Tcl is not threaded, or this is the interpreter thread. */
1602
 
        return func(selfptr, args, flags);
 
1601
    /* Tcl is not threaded, or this is the interpreter thread. */
 
1602
    return func(selfptr, args, flags);
1603
1603
}
1604
1604
 
1605
1605
static PyObject *
1606
1606
SetVar(PyObject *self, PyObject *args, int flags)
1607
1607
{
1608
 
        char *name1, *name2;
1609
 
        PyObject *newValue;
1610
 
        PyObject *res = NULL;
1611
 
        Tcl_Obj *newval, *ok;
 
1608
    char *name1, *name2;
 
1609
    PyObject *newValue;
 
1610
    PyObject *res = NULL;
 
1611
    Tcl_Obj *newval, *ok;
1612
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;
 
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;
1653
1653
}
1654
1654
 
1655
1655
static PyObject *
1656
1656
Tkapp_SetVar(PyObject *self, PyObject *args)
1657
1657
{
1658
 
        return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
 
1658
    return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
1659
1659
}
1660
1660
 
1661
1661
static PyObject *
1662
1662
Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
1663
1663
{
1664
 
        return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
 
1664
    return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1665
1665
}
1666
1666
 
1667
1667
 
1668
 
 
 
1668
 
1669
1669
static PyObject *
1670
1670
GetVar(PyObject *self, PyObject *args, int flags)
1671
1671
{
1672
 
        char *name1, *name2=NULL;
1673
 
        PyObject *res = NULL;
1674
 
        Tcl_Obj *tres;
1675
 
 
1676
 
        if (!PyArg_ParseTuple(args, "O&|s:getvar",
1677
 
                              varname_converter, &name1, &name2))
1678
 
                return NULL;
1679
 
 
1680
 
        ENTER_TCL
1681
 
        tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1682
 
        ENTER_OVERLAP
1683
 
        if (tres == NULL) {
1684
 
                PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
1685
 
        } else {
1686
 
                if (((TkappObject*)self)->wantobjects) {
1687
 
                        res = FromObj(self, tres);
1688
 
                }
1689
 
                else {
1690
 
                        res = PyUnicode_FromString(Tcl_GetString(tres));
1691
 
                }
1692
 
        }
1693
 
        LEAVE_OVERLAP_TCL
1694
 
        return res;
 
1672
    char *name1, *name2=NULL;
 
1673
    PyObject *res = NULL;
 
1674
    Tcl_Obj *tres;
 
1675
 
 
1676
    if (!PyArg_ParseTuple(args, "O&|s:getvar",
 
1677
                          varname_converter, &name1, &name2))
 
1678
        return NULL;
 
1679
 
 
1680
    ENTER_TCL
 
1681
    tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
 
1682
    ENTER_OVERLAP
 
1683
    if (tres == NULL) {
 
1684
        PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
 
1685
    } else {
 
1686
        if (((TkappObject*)self)->wantobjects) {
 
1687
            res = FromObj(self, tres);
 
1688
        }
 
1689
        else {
 
1690
            res = PyUnicode_FromString(Tcl_GetString(tres));
 
1691
        }
 
1692
    }
 
1693
    LEAVE_OVERLAP_TCL
 
1694
    return res;
1695
1695
}
1696
1696
 
1697
1697
static PyObject *
1698
1698
Tkapp_GetVar(PyObject *self, PyObject *args)
1699
1699
{
1700
 
        return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
 
1700
    return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
1701
1701
}
1702
1702
 
1703
1703
static PyObject *
1704
1704
Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
1705
1705
{
1706
 
        return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
 
1706
    return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1707
1707
}
1708
1708
 
1709
1709
 
1710
 
 
 
1710
 
1711
1711
static PyObject *
1712
1712
UnsetVar(PyObject *self, PyObject *args, int flags)
1713
1713
{
1714
 
        char *name1, *name2=NULL;
1715
 
        int code;
1716
 
        PyObject *res = NULL;
1717
 
 
1718
 
        if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
1719
 
                return NULL;
1720
 
 
1721
 
        ENTER_TCL
1722
 
        code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1723
 
        ENTER_OVERLAP
1724
 
        if (code == TCL_ERROR)
1725
 
                res = Tkinter_Error(self);
1726
 
        else {
1727
 
                Py_INCREF(Py_None);
1728
 
                res = Py_None;
1729
 
        }
1730
 
        LEAVE_OVERLAP_TCL
1731
 
        return res;
 
1714
    char *name1, *name2=NULL;
 
1715
    int code;
 
1716
    PyObject *res = NULL;
 
1717
 
 
1718
    if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
 
1719
        return NULL;
 
1720
 
 
1721
    ENTER_TCL
 
1722
    code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
 
1723
    ENTER_OVERLAP
 
1724
    if (code == TCL_ERROR)
 
1725
        res = Tkinter_Error(self);
 
1726
    else {
 
1727
        Py_INCREF(Py_None);
 
1728
        res = Py_None;
 
1729
    }
 
1730
    LEAVE_OVERLAP_TCL
 
1731
    return res;
1732
1732
}
1733
1733
 
1734
1734
static PyObject *
1735
1735
Tkapp_UnsetVar(PyObject *self, PyObject *args)
1736
1736
{
1737
 
        return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
 
1737
    return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
1738
1738
}
1739
1739
 
1740
1740
static PyObject *
1741
1741
Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
1742
1742
{
1743
 
        return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
 
1743
    return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1744
1744
}
1745
1745
 
1746
1746
 
1747
 
 
 
1747
 
1748
1748
/** Tcl to Python **/
1749
1749
 
1750
1750
static PyObject *
1751
1751
Tkapp_GetInt(PyObject *self, PyObject *args)
1752
1752
{
1753
 
        char *s;
1754
 
        int v;
 
1753
    char *s;
 
1754
    int v;
1755
1755
 
1756
 
        if (PyTuple_Size(args) == 1) {
1757
 
                PyObject* o = PyTuple_GetItem(args, 0);
1758
 
                if (PyLong_Check(o)) {
1759
 
                        Py_INCREF(o);
1760
 
                        return o;
1761
 
                }
1762
 
        }
1763
 
        if (!PyArg_ParseTuple(args, "s:getint", &s))
1764
 
                return NULL;
1765
 
        if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1766
 
                return Tkinter_Error(self);
1767
 
        return Py_BuildValue("i", v);
 
1756
    if (PyTuple_Size(args) == 1) {
 
1757
        PyObject* o = PyTuple_GetItem(args, 0);
 
1758
        if (PyLong_Check(o)) {
 
1759
            Py_INCREF(o);
 
1760
            return o;
 
1761
        }
 
1762
    }
 
1763
    if (!PyArg_ParseTuple(args, "s:getint", &s))
 
1764
        return NULL;
 
1765
    if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
 
1766
        return Tkinter_Error(self);
 
1767
    return Py_BuildValue("i", v);
1768
1768
}
1769
1769
 
1770
1770
static PyObject *
1771
1771
Tkapp_GetDouble(PyObject *self, PyObject *args)
1772
1772
{
1773
 
        char *s;
1774
 
        double v;
 
1773
    char *s;
 
1774
    double v;
1775
1775
 
1776
 
        if (PyTuple_Size(args) == 1) {
1777
 
                PyObject *o = PyTuple_GetItem(args, 0);
1778
 
                if (PyFloat_Check(o)) {
1779
 
                        Py_INCREF(o);
1780
 
                        return o;
1781
 
                }
1782
 
        }
1783
 
        if (!PyArg_ParseTuple(args, "s:getdouble", &s))
1784
 
                return NULL;
1785
 
        if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1786
 
                return Tkinter_Error(self);
1787
 
        return Py_BuildValue("d", v);
 
1776
    if (PyTuple_Size(args) == 1) {
 
1777
        PyObject *o = PyTuple_GetItem(args, 0);
 
1778
        if (PyFloat_Check(o)) {
 
1779
            Py_INCREF(o);
 
1780
            return o;
 
1781
        }
 
1782
    }
 
1783
    if (!PyArg_ParseTuple(args, "s:getdouble", &s))
 
1784
        return NULL;
 
1785
    if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
 
1786
        return Tkinter_Error(self);
 
1787
    return Py_BuildValue("d", v);
1788
1788
}
1789
1789
 
1790
1790
static PyObject *
1791
1791
Tkapp_GetBoolean(PyObject *self, PyObject *args)
1792
1792
{
1793
 
        char *s;
1794
 
        int v;
 
1793
    char *s;
 
1794
    int v;
1795
1795
 
1796
 
        if (PyTuple_Size(args) == 1) {
1797
 
                PyObject *o = PyTuple_GetItem(args, 0);
1798
 
                if (PyLong_Check(o)) {
1799
 
                        Py_INCREF(o);
1800
 
                        return o;
1801
 
                }
1802
 
        }
1803
 
        if (!PyArg_ParseTuple(args, "s:getboolean", &s))
1804
 
                return NULL;
1805
 
        if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1806
 
                return Tkinter_Error(self);
1807
 
        return PyBool_FromLong(v);
 
1796
    if (PyTuple_Size(args) == 1) {
 
1797
        PyObject *o = PyTuple_GetItem(args, 0);
 
1798
        if (PyLong_Check(o)) {
 
1799
            Py_INCREF(o);
 
1800
            return o;
 
1801
        }
 
1802
    }
 
1803
    if (!PyArg_ParseTuple(args, "s:getboolean", &s))
 
1804
        return NULL;
 
1805
    if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
 
1806
        return Tkinter_Error(self);
 
1807
    return PyBool_FromLong(v);
1808
1808
}
1809
1809
 
1810
1810
static PyObject *
1811
1811
Tkapp_ExprString(PyObject *self, PyObject *args)
1812
1812
{
1813
 
        char *s;
1814
 
        PyObject *res = NULL;
1815
 
        int retval;
1816
 
 
1817
 
        if (!PyArg_ParseTuple(args, "s:exprstring", &s))
1818
 
                return NULL;
1819
 
 
1820
 
        CHECK_TCL_APPARTMENT;
1821
 
 
1822
 
        ENTER_TCL
1823
 
        retval = Tcl_ExprString(Tkapp_Interp(self), s);
1824
 
        ENTER_OVERLAP
1825
 
        if (retval == TCL_ERROR)
1826
 
                res = Tkinter_Error(self);
1827
 
        else
1828
 
                res = Py_BuildValue("s", Tkapp_Result(self));
1829
 
        LEAVE_OVERLAP_TCL
1830
 
        return res;
 
1813
    char *s;
 
1814
    PyObject *res = NULL;
 
1815
    int retval;
 
1816
 
 
1817
    if (!PyArg_ParseTuple(args, "s:exprstring", &s))
 
1818
        return NULL;
 
1819
 
 
1820
    CHECK_TCL_APPARTMENT;
 
1821
 
 
1822
    ENTER_TCL
 
1823
    retval = Tcl_ExprString(Tkapp_Interp(self), s);
 
1824
    ENTER_OVERLAP
 
1825
    if (retval == TCL_ERROR)
 
1826
        res = Tkinter_Error(self);
 
1827
    else
 
1828
        res = Py_BuildValue("s", Tkapp_Result(self));
 
1829
    LEAVE_OVERLAP_TCL
 
1830
    return res;
1831
1831
}
1832
1832
 
1833
1833
static PyObject *
1834
1834
Tkapp_ExprLong(PyObject *self, PyObject *args)
1835
1835
{
1836
 
        char *s;
1837
 
        PyObject *res = NULL;
1838
 
        int retval;
1839
 
        long v;
1840
 
 
1841
 
        if (!PyArg_ParseTuple(args, "s:exprlong", &s))
1842
 
                return NULL;
1843
 
 
1844
 
        CHECK_TCL_APPARTMENT;
1845
 
 
1846
 
        ENTER_TCL
1847
 
        retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
1848
 
        ENTER_OVERLAP
1849
 
        if (retval == TCL_ERROR)
1850
 
                res = Tkinter_Error(self);
1851
 
        else
1852
 
                res = Py_BuildValue("l", v);
1853
 
        LEAVE_OVERLAP_TCL
1854
 
        return res;
 
1836
    char *s;
 
1837
    PyObject *res = NULL;
 
1838
    int retval;
 
1839
    long v;
 
1840
 
 
1841
    if (!PyArg_ParseTuple(args, "s:exprlong", &s))
 
1842
        return NULL;
 
1843
 
 
1844
    CHECK_TCL_APPARTMENT;
 
1845
 
 
1846
    ENTER_TCL
 
1847
    retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
 
1848
    ENTER_OVERLAP
 
1849
    if (retval == TCL_ERROR)
 
1850
        res = Tkinter_Error(self);
 
1851
    else
 
1852
        res = Py_BuildValue("l", v);
 
1853
    LEAVE_OVERLAP_TCL
 
1854
    return res;
1855
1855
}
1856
1856
 
1857
1857
static PyObject *
1858
1858
Tkapp_ExprDouble(PyObject *self, PyObject *args)
1859
1859
{
1860
 
        char *s;
1861
 
        PyObject *res = NULL;
1862
 
        double v;
1863
 
        int retval;
 
1860
    char *s;
 
1861
    PyObject *res = NULL;
 
1862
    double v;
 
1863
    int retval;
1864
1864
 
1865
 
        if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
1866
 
                return NULL;
1867
 
        CHECK_TCL_APPARTMENT;
1868
 
        PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
1869
 
        ENTER_TCL
1870
 
        retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
1871
 
        ENTER_OVERLAP
1872
 
        PyFPE_END_PROTECT(retval)
1873
 
        if (retval == TCL_ERROR)
1874
 
                res = Tkinter_Error(self);
1875
 
        else
1876
 
                res = Py_BuildValue("d", v);
1877
 
        LEAVE_OVERLAP_TCL
1878
 
        return res;
 
1865
    if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
 
1866
        return NULL;
 
1867
    CHECK_TCL_APPARTMENT;
 
1868
    PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
 
1869
    ENTER_TCL
 
1870
    retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
 
1871
    ENTER_OVERLAP
 
1872
    PyFPE_END_PROTECT(retval)
 
1873
    if (retval == TCL_ERROR)
 
1874
        res = Tkinter_Error(self);
 
1875
    else
 
1876
        res = Py_BuildValue("d", v);
 
1877
    LEAVE_OVERLAP_TCL
 
1878
    return res;
1879
1879
}
1880
1880
 
1881
1881
static PyObject *
1882
1882
Tkapp_ExprBoolean(PyObject *self, PyObject *args)
1883
1883
{
1884
 
        char *s;
1885
 
        PyObject *res = NULL;
1886
 
        int retval;
1887
 
        int v;
 
1884
    char *s;
 
1885
    PyObject *res = NULL;
 
1886
    int retval;
 
1887
    int v;
1888
1888
 
1889
 
        if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
1890
 
                return NULL;
1891
 
        CHECK_TCL_APPARTMENT;
1892
 
        ENTER_TCL
1893
 
        retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1894
 
        ENTER_OVERLAP
1895
 
        if (retval == TCL_ERROR)
1896
 
                res = Tkinter_Error(self);
1897
 
        else
1898
 
                res = Py_BuildValue("i", v);
1899
 
        LEAVE_OVERLAP_TCL
1900
 
        return res;
 
1889
    if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
 
1890
        return NULL;
 
1891
    CHECK_TCL_APPARTMENT;
 
1892
    ENTER_TCL
 
1893
    retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
 
1894
    ENTER_OVERLAP
 
1895
    if (retval == TCL_ERROR)
 
1896
        res = Tkinter_Error(self);
 
1897
    else
 
1898
        res = Py_BuildValue("i", v);
 
1899
    LEAVE_OVERLAP_TCL
 
1900
    return res;
1901
1901
}
1902
1902
 
1903
1903
 
1904
 
 
 
1904
 
1905
1905
static PyObject *
1906
1906
Tkapp_SplitList(PyObject *self, PyObject *args)
1907
1907
{
1908
 
        char *list;
1909
 
        int argc;
1910
 
        char **argv;
1911
 
        PyObject *v;
1912
 
        int i;
1913
 
 
1914
 
        if (PyTuple_Size(args) == 1) {
1915
 
                v = PyTuple_GetItem(args, 0);
1916
 
                if (PyTuple_Check(v)) {
1917
 
                        Py_INCREF(v);
1918
 
                        return v;
1919
 
                }
1920
 
        }
1921
 
        if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
1922
 
                return NULL;
1923
 
 
1924
 
        if (Tcl_SplitList(Tkapp_Interp(self), list,
1925
 
                          &argc, &argv) == TCL_ERROR)  {
1926
 
                PyMem_Free(list);
1927
 
                return Tkinter_Error(self);
1928
 
        }
1929
 
 
1930
 
        if (!(v = PyTuple_New(argc)))
1931
 
                goto finally;
1932
 
 
1933
 
        for (i = 0; i < argc; i++) {
1934
 
                PyObject *s = PyUnicode_FromString(argv[i]);
1935
 
                if (!s || PyTuple_SetItem(v, i, s)) {
1936
 
                        Py_DECREF(v);
1937
 
                        v = NULL;
1938
 
                        goto finally;
1939
 
                }
1940
 
        }
 
1908
    char *list;
 
1909
    int argc;
 
1910
    char **argv;
 
1911
    PyObject *v;
 
1912
    int i;
 
1913
 
 
1914
    if (PyTuple_Size(args) == 1) {
 
1915
        v = PyTuple_GetItem(args, 0);
 
1916
        if (PyTuple_Check(v)) {
 
1917
            Py_INCREF(v);
 
1918
            return v;
 
1919
        }
 
1920
    }
 
1921
    if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
 
1922
        return NULL;
 
1923
 
 
1924
    if (Tcl_SplitList(Tkapp_Interp(self), list,
 
1925
                      &argc, &argv) == TCL_ERROR)  {
 
1926
        PyMem_Free(list);
 
1927
        return Tkinter_Error(self);
 
1928
    }
 
1929
 
 
1930
    if (!(v = PyTuple_New(argc)))
 
1931
        goto finally;
 
1932
 
 
1933
    for (i = 0; i < argc; i++) {
 
1934
        PyObject *s = PyUnicode_FromString(argv[i]);
 
1935
        if (!s || PyTuple_SetItem(v, i, s)) {
 
1936
            Py_DECREF(v);
 
1937
            v = NULL;
 
1938
            goto finally;
 
1939
        }
 
1940
    }
1941
1941
 
1942
1942
  finally:
1943
 
        ckfree(FREECAST argv);
1944
 
        PyMem_Free(list);
1945
 
        return v;
 
1943
    ckfree(FREECAST argv);
 
1944
    PyMem_Free(list);
 
1945
    return v;
1946
1946
}
1947
1947
 
1948
1948
static PyObject *
1949
1949
Tkapp_Split(PyObject *self, PyObject *args)
1950
1950
{
1951
 
        PyObject *v;
1952
 
        char *list;
 
1951
    PyObject *v;
 
1952
    char *list;
1953
1953
 
1954
 
        if (PyTuple_Size(args) == 1) {
1955
 
                PyObject* o = PyTuple_GetItem(args, 0);
1956
 
                if (PyTuple_Check(o)) {
1957
 
                        o = SplitObj(o);
1958
 
                        return o;
1959
 
                }
1960
 
        }
1961
 
        if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
1962
 
                return NULL;
1963
 
        v = Split(list);
1964
 
        PyMem_Free(list);
1965
 
        return v;
 
1954
    if (PyTuple_Size(args) == 1) {
 
1955
        PyObject* o = PyTuple_GetItem(args, 0);
 
1956
        if (PyTuple_Check(o)) {
 
1957
            o = SplitObj(o);
 
1958
            return o;
 
1959
        }
 
1960
    }
 
1961
    if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
 
1962
        return NULL;
 
1963
    v = Split(list);
 
1964
    PyMem_Free(list);
 
1965
    return v;
1966
1966
}
1967
1967
 
1968
1968
static PyObject *
1969
1969
Tkapp_Merge(PyObject *self, PyObject *args)
1970
1970
{
1971
 
        char *s = Merge(args);
1972
 
        PyObject *res = NULL;
1973
 
 
1974
 
        if (s) {
1975
 
                res = PyUnicode_FromString(s);
1976
 
                ckfree(s);
1977
 
        }
1978
 
 
1979
 
        return res;
 
1971
    char *s = Merge(args);
 
1972
    PyObject *res = NULL;
 
1973
 
 
1974
    if (s) {
 
1975
        res = PyUnicode_FromString(s);
 
1976
        ckfree(s);
 
1977
    }
 
1978
 
 
1979
    return res;
1980
1980
}
1981
1981
 
1982
1982
 
1983
 
 
 
1983
 
1984
1984
/** Tcl Command **/
1985
1985
 
1986
1986
/* Client data struct */
1987
1987
typedef struct {
1988
 
        PyObject *self;
1989
 
        PyObject *func;
 
1988
    PyObject *self;
 
1989
    PyObject *func;
1990
1990
} PythonCmd_ClientData;
1991
1991
 
1992
1992
static int
1993
1993
PythonCmd_Error(Tcl_Interp *interp)
1994
1994
{
1995
 
        errorInCmd = 1;
1996
 
        PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1997
 
        LEAVE_PYTHON
1998
 
        return TCL_ERROR;
 
1995
    errorInCmd = 1;
 
1996
    PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
 
1997
    LEAVE_PYTHON
 
1998
    return TCL_ERROR;
1999
1999
}
2000
2000
 
2001
2001
/* This is the Tcl command that acts as a wrapper for Python
2004
2004
static int
2005
2005
PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
2006
2006
{
2007
 
        PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2008
 
        PyObject *self, *func, *arg, *res;
2009
 
        int i, rv;
2010
 
        Tcl_Obj *obj_res;
2011
 
 
2012
 
        ENTER_PYTHON
2013
 
 
2014
 
        /* TBD: no error checking here since we know, via the
2015
 
         * Tkapp_CreateCommand() that the client data is a two-tuple
2016
 
         */
2017
 
        self = data->self;
2018
 
        func = data->func;
2019
 
 
2020
 
        /* Create argument list (argv1, ..., argvN) */
2021
 
        if (!(arg = PyTuple_New(argc - 1)))
2022
 
                return PythonCmd_Error(interp);
2023
 
 
2024
 
        for (i = 0; i < (argc - 1); i++) {
2025
 
                PyObject *s = PyUnicode_FromString(argv[i + 1]);
2026
 
                if (!s || PyTuple_SetItem(arg, i, s)) {
2027
 
                        Py_DECREF(arg);
2028
 
                        return PythonCmd_Error(interp);
2029
 
                }
2030
 
        }
2031
 
        res = PyEval_CallObject(func, arg);
2032
 
        Py_DECREF(arg);
2033
 
 
2034
 
        if (res == NULL)
2035
 
                return PythonCmd_Error(interp);
2036
 
 
2037
 
        obj_res = AsObj(res);
2038
 
        if (obj_res == NULL) {
2039
 
                Py_DECREF(res);
2040
 
                return PythonCmd_Error(interp);
2041
 
        }
2042
 
        else {
2043
 
                Tcl_SetObjResult(interp, obj_res);
2044
 
                rv = TCL_OK;
2045
 
        }
2046
 
 
2047
 
        Py_DECREF(res);
2048
 
 
2049
 
        LEAVE_PYTHON
2050
 
 
2051
 
        return rv;
 
2007
    PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
 
2008
    PyObject *self, *func, *arg, *res;
 
2009
    int i, rv;
 
2010
    Tcl_Obj *obj_res;
 
2011
 
 
2012
    ENTER_PYTHON
 
2013
 
 
2014
    /* TBD: no error checking here since we know, via the
 
2015
     * Tkapp_CreateCommand() that the client data is a two-tuple
 
2016
     */
 
2017
    self = data->self;
 
2018
    func = data->func;
 
2019
 
 
2020
    /* Create argument list (argv1, ..., argvN) */
 
2021
    if (!(arg = PyTuple_New(argc - 1)))
 
2022
        return PythonCmd_Error(interp);
 
2023
 
 
2024
    for (i = 0; i < (argc - 1); i++) {
 
2025
        PyObject *s = PyUnicode_FromString(argv[i + 1]);
 
2026
        if (!s || PyTuple_SetItem(arg, i, s)) {
 
2027
            Py_DECREF(arg);
 
2028
            return PythonCmd_Error(interp);
 
2029
        }
 
2030
    }
 
2031
    res = PyEval_CallObject(func, arg);
 
2032
    Py_DECREF(arg);
 
2033
 
 
2034
    if (res == NULL)
 
2035
        return PythonCmd_Error(interp);
 
2036
 
 
2037
    obj_res = AsObj(res);
 
2038
    if (obj_res == NULL) {
 
2039
        Py_DECREF(res);
 
2040
        return PythonCmd_Error(interp);
 
2041
    }
 
2042
    else {
 
2043
        Tcl_SetObjResult(interp, obj_res);
 
2044
        rv = TCL_OK;
 
2045
    }
 
2046
 
 
2047
    Py_DECREF(res);
 
2048
 
 
2049
    LEAVE_PYTHON
 
2050
 
 
2051
    return rv;
2052
2052
}
2053
2053
 
2054
2054
static void
2055
2055
PythonCmdDelete(ClientData clientData)
2056
2056
{
2057
 
        PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
 
2057
    PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
2058
2058
 
2059
 
        ENTER_PYTHON
2060
 
        Py_XDECREF(data->self);
2061
 
        Py_XDECREF(data->func);
2062
 
        PyMem_DEL(data);
2063
 
        LEAVE_PYTHON
 
2059
    ENTER_PYTHON
 
2060
    Py_XDECREF(data->self);
 
2061
    Py_XDECREF(data->func);
 
2062
    PyMem_DEL(data);
 
2063
    LEAVE_PYTHON
2064
2064
}
2065
2065
 
2066
2066
 
2067
 
 
 
2067
 
2068
2068
 
2069
2069
#ifdef WITH_THREAD
2070
2070
TCL_DECLARE_MUTEX(command_mutex)
2071
2071
 
2072
2072
typedef struct CommandEvent{
2073
 
        Tcl_Event ev;
2074
 
        Tcl_Interp* interp;
2075
 
        char *name;
2076
 
        int create;
2077
 
        int *status;
2078
 
        ClientData *data;
2079
 
        Tcl_Condition *done;
 
2073
    Tcl_Event ev;
 
2074
    Tcl_Interp* interp;
 
2075
    char *name;
 
2076
    int create;
 
2077
    int *status;
 
2078
    ClientData *data;
 
2079
    Tcl_Condition *done;
2080
2080
} CommandEvent;
2081
2081
 
2082
2082
static int
2083
2083
Tkapp_CommandProc(CommandEvent *ev, int flags)
2084
2084
{
2085
 
        if (ev->create)
2086
 
                *ev->status = Tcl_CreateCommand(
2087
 
                        ev->interp, ev->name, PythonCmd,
2088
 
                        ev->data, PythonCmdDelete) == NULL;
2089
 
        else
2090
 
                *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
2091
 
        Tcl_MutexLock(&command_mutex);
2092
 
        Tcl_ConditionNotify(ev->done);
2093
 
        Tcl_MutexUnlock(&command_mutex);
2094
 
        return 1;
 
2085
    if (ev->create)
 
2086
        *ev->status = Tcl_CreateCommand(
 
2087
            ev->interp, ev->name, PythonCmd,
 
2088
            ev->data, PythonCmdDelete) == NULL;
 
2089
    else
 
2090
        *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
 
2091
    Tcl_MutexLock(&command_mutex);
 
2092
    Tcl_ConditionNotify(ev->done);
 
2093
    Tcl_MutexUnlock(&command_mutex);
 
2094
    return 1;
2095
2095
}
2096
2096
#endif
2097
2097
 
2098
2098
static PyObject *
2099
2099
Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
2100
2100
{
2101
 
        TkappObject *self = (TkappObject*)selfptr;
2102
 
        PythonCmd_ClientData *data;
2103
 
        char *cmdName;
2104
 
        PyObject *func;
2105
 
        int err;
2106
 
 
2107
 
        if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
2108
 
                return NULL;
2109
 
        if (!PyCallable_Check(func)) {
2110
 
                PyErr_SetString(PyExc_TypeError, "command not callable");
2111
 
                return NULL;
2112
 
        }
2113
 
 
2114
 
#ifdef WITH_THREAD
2115
 
        if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
2116
 
            !WaitForMainloop(self))
2117
 
                return NULL;
2118
 
#endif
2119
 
 
2120
 
        data = PyMem_NEW(PythonCmd_ClientData, 1);
2121
 
        if (!data)
2122
 
                return PyErr_NoMemory();
2123
 
        Py_INCREF(self);
2124
 
        Py_INCREF(func);
2125
 
        data->self = selfptr;
2126
 
        data->func = func;
2127
 
#ifdef WITH_THREAD
2128
 
        if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2129
 
                Tcl_Condition cond = NULL;
2130
 
                CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2131
 
                ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2132
 
                ev->interp = self->interp;
2133
 
                ev->create = 1;
2134
 
                ev->name = cmdName;
2135
 
                ev->data = (ClientData)data;
2136
 
                ev->status = &err;
2137
 
                ev->done = &cond;
2138
 
                Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2139
 
                Tcl_ConditionFinalize(&cond);
2140
 
        }
2141
 
        else
2142
 
#endif
2143
 
        {
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;
 
2101
    TkappObject *self = (TkappObject*)selfptr;
 
2102
    PythonCmd_ClientData *data;
 
2103
    char *cmdName;
 
2104
    PyObject *func;
 
2105
    int err;
 
2106
 
 
2107
    if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
 
2108
        return NULL;
 
2109
    if (!PyCallable_Check(func)) {
 
2110
        PyErr_SetString(PyExc_TypeError, "command not callable");
 
2111
        return NULL;
 
2112
    }
 
2113
 
 
2114
#ifdef WITH_THREAD
 
2115
    if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
 
2116
        !WaitForMainloop(self))
 
2117
        return NULL;
 
2118
#endif
 
2119
 
 
2120
    data = PyMem_NEW(PythonCmd_ClientData, 1);
 
2121
    if (!data)
 
2122
        return PyErr_NoMemory();
 
2123
    Py_INCREF(self);
 
2124
    Py_INCREF(func);
 
2125
    data->self = selfptr;
 
2126
    data->func = func;
 
2127
#ifdef WITH_THREAD
 
2128
    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
 
2129
        Tcl_Condition cond = NULL;
 
2130
        CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
 
2131
        ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
 
2132
        ev->interp = self->interp;
 
2133
        ev->create = 1;
 
2134
        ev->name = cmdName;
 
2135
        ev->data = (ClientData)data;
 
2136
        ev->status = &err;
 
2137
        ev->done = &cond;
 
2138
        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
 
2139
        Tcl_ConditionFinalize(&cond);
 
2140
    }
 
2141
    else
 
2142
#endif
 
2143
    {
 
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
2158
}
2159
2159
 
2160
2160
 
2161
 
 
 
2161
 
2162
2162
static PyObject *
2163
2163
Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
2164
2164
{
2165
 
        TkappObject *self = (TkappObject*)selfptr;
2166
 
        char *cmdName;
2167
 
        int err;
 
2165
    TkappObject *self = (TkappObject*)selfptr;
 
2166
    char *cmdName;
 
2167
    int err;
2168
2168
 
2169
 
        if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
2170
 
                return NULL;
 
2169
    if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
 
2170
        return NULL;
2171
2171
 
2172
2172
#ifdef WITH_THREAD
2173
 
        if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2174
 
                Tcl_Condition cond = NULL;
2175
 
                CommandEvent *ev;
2176
 
                ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
2177
 
                ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2178
 
                ev->interp = self->interp;
2179
 
                ev->create = 0;
2180
 
                ev->name = cmdName;
2181
 
                ev->status = &err;
2182
 
                ev->done = &cond;
2183
 
                Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
2184
 
                                 &command_mutex);
2185
 
                Tcl_ConditionFinalize(&cond);
2186
 
        }
2187
 
        else
 
2173
    if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
 
2174
        Tcl_Condition cond = NULL;
 
2175
        CommandEvent *ev;
 
2176
        ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
 
2177
        ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
 
2178
        ev->interp = self->interp;
 
2179
        ev->create = 0;
 
2180
        ev->name = cmdName;
 
2181
        ev->status = &err;
 
2182
        ev->done = &cond;
 
2183
        Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
 
2184
                         &command_mutex);
 
2185
        Tcl_ConditionFinalize(&cond);
 
2186
    }
 
2187
    else
2188
2188
#endif
2189
 
        {
2190
 
                ENTER_TCL
2191
 
                err = Tcl_DeleteCommand(self->interp, cmdName);
2192
 
                LEAVE_TCL
2193
 
        }
2194
 
        if (err == -1) {
2195
 
                PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2196
 
                return NULL;
2197
 
        }
2198
 
        Py_INCREF(Py_None);
2199
 
        return Py_None;
 
2189
    {
 
2190
        ENTER_TCL
 
2191
        err = Tcl_DeleteCommand(self->interp, cmdName);
 
2192
        LEAVE_TCL
 
2193
    }
 
2194
    if (err == -1) {
 
2195
        PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
 
2196
        return NULL;
 
2197
    }
 
2198
    Py_INCREF(Py_None);
 
2199
    return Py_None;
2200
2200
}
2201
2201
 
2202
2202
 
2203
 
 
 
2203
 
2204
2204
#ifdef HAVE_CREATEFILEHANDLER
2205
2205
/** File Handler **/
2206
2206
 
2207
2207
typedef struct _fhcdata {
2208
 
        PyObject *func;
2209
 
        PyObject *file;
2210
 
        int id;
2211
 
        struct _fhcdata *next;
 
2208
    PyObject *func;
 
2209
    PyObject *file;
 
2210
    int id;
 
2211
    struct _fhcdata *next;
2212
2212
} FileHandler_ClientData;
2213
2213
 
2214
2214
static FileHandler_ClientData *HeadFHCD;
2216
2216
static FileHandler_ClientData *
2217
2217
NewFHCD(PyObject *func, PyObject *file, int id)
2218
2218
{
2219
 
        FileHandler_ClientData *p;
2220
 
        p = PyMem_NEW(FileHandler_ClientData, 1);
2221
 
        if (p != NULL) {
2222
 
                Py_XINCREF(func);
2223
 
                Py_XINCREF(file);
2224
 
                p->func = func;
2225
 
                p->file = file;
2226
 
                p->id = id;
2227
 
                p->next = HeadFHCD;
2228
 
                HeadFHCD = p;
2229
 
        }
2230
 
        return p;
 
2219
    FileHandler_ClientData *p;
 
2220
    p = PyMem_NEW(FileHandler_ClientData, 1);
 
2221
    if (p != NULL) {
 
2222
        Py_XINCREF(func);
 
2223
        Py_XINCREF(file);
 
2224
        p->func = func;
 
2225
        p->file = file;
 
2226
        p->id = id;
 
2227
        p->next = HeadFHCD;
 
2228
        HeadFHCD = p;
 
2229
    }
 
2230
    return p;
2231
2231
}
2232
2232
 
2233
2233
static void
2234
2234
DeleteFHCD(int id)
2235
2235
{
2236
 
        FileHandler_ClientData *p, **pp;
 
2236
    FileHandler_ClientData *p, **pp;
2237
2237
 
2238
 
        pp = &HeadFHCD;
2239
 
        while ((p = *pp) != NULL) {
2240
 
                if (p->id == id) {
2241
 
                        *pp = p->next;
2242
 
                        Py_XDECREF(p->func);
2243
 
                        Py_XDECREF(p->file);
2244
 
                        PyMem_DEL(p);
2245
 
                }
2246
 
                else
2247
 
                        pp = &p->next;
2248
 
        }
 
2238
    pp = &HeadFHCD;
 
2239
    while ((p = *pp) != NULL) {
 
2240
        if (p->id == id) {
 
2241
            *pp = p->next;
 
2242
            Py_XDECREF(p->func);
 
2243
            Py_XDECREF(p->file);
 
2244
            PyMem_DEL(p);
 
2245
        }
 
2246
        else
 
2247
            pp = &p->next;
 
2248
    }
2249
2249
}
2250
2250
 
2251
2251
static void
2252
2252
FileHandler(ClientData clientData, int mask)
2253
2253
{
2254
 
        FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
2255
 
        PyObject *func, *file, *arg, *res;
2256
 
 
2257
 
        ENTER_PYTHON
2258
 
        func = data->func;
2259
 
        file = data->file;
2260
 
 
2261
 
        arg = Py_BuildValue("(Oi)", file, (long) mask);
2262
 
        res = PyEval_CallObject(func, arg);
2263
 
        Py_DECREF(arg);
2264
 
 
2265
 
        if (res == NULL) {
2266
 
                errorInCmd = 1;
2267
 
                PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2268
 
        }
2269
 
        Py_XDECREF(res);
2270
 
        LEAVE_PYTHON
 
2254
    FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
 
2255
    PyObject *func, *file, *arg, *res;
 
2256
 
 
2257
    ENTER_PYTHON
 
2258
    func = data->func;
 
2259
    file = data->file;
 
2260
 
 
2261
    arg = Py_BuildValue("(Oi)", file, (long) mask);
 
2262
    res = PyEval_CallObject(func, arg);
 
2263
    Py_DECREF(arg);
 
2264
 
 
2265
    if (res == NULL) {
 
2266
        errorInCmd = 1;
 
2267
        PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
 
2268
    }
 
2269
    Py_XDECREF(res);
 
2270
    LEAVE_PYTHON
2271
2271
}
2272
2272
 
2273
2273
static PyObject *
2274
2274
Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2275
2275
     /* args is (file, mask, func) */
2276
2276
{
2277
 
        FileHandler_ClientData *data;
2278
 
        PyObject *file, *func;
2279
 
        int mask, tfile;
2280
 
 
2281
 
        if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2282
 
                              &file, &mask, &func))
2283
 
                return NULL;
2284
 
 
2285
 
        CHECK_TCL_APPARTMENT;
2286
 
 
2287
 
        tfile = PyObject_AsFileDescriptor(file);
2288
 
        if (tfile < 0)
2289
 
                return NULL;
2290
 
        if (!PyCallable_Check(func)) {
2291
 
                PyErr_SetString(PyExc_TypeError, "bad argument list");
2292
 
                return NULL;
2293
 
        }
2294
 
 
2295
 
        data = NewFHCD(func, file, tfile);
2296
 
        if (data == NULL)
2297
 
                return NULL;
2298
 
 
2299
 
        /* Ought to check for null Tcl_File object... */
2300
 
        ENTER_TCL
2301
 
        Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
2302
 
        LEAVE_TCL
2303
 
        Py_INCREF(Py_None);
2304
 
        return Py_None;
 
2277
    FileHandler_ClientData *data;
 
2278
    PyObject *file, *func;
 
2279
    int mask, tfile;
 
2280
 
 
2281
    if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
 
2282
                          &file, &mask, &func))
 
2283
        return NULL;
 
2284
 
 
2285
    CHECK_TCL_APPARTMENT;
 
2286
 
 
2287
    tfile = PyObject_AsFileDescriptor(file);
 
2288
    if (tfile < 0)
 
2289
        return NULL;
 
2290
    if (!PyCallable_Check(func)) {
 
2291
        PyErr_SetString(PyExc_TypeError, "bad argument list");
 
2292
        return NULL;
 
2293
    }
 
2294
 
 
2295
    data = NewFHCD(func, file, tfile);
 
2296
    if (data == NULL)
 
2297
        return NULL;
 
2298
 
 
2299
    /* Ought to check for null Tcl_File object... */
 
2300
    ENTER_TCL
 
2301
    Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
 
2302
    LEAVE_TCL
 
2303
    Py_INCREF(Py_None);
 
2304
    return Py_None;
2305
2305
}
2306
2306
 
2307
2307
static PyObject *
2308
2308
Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
2309
2309
{
2310
 
        PyObject *file;
2311
 
        int tfile;
2312
 
 
2313
 
        if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
2314
 
                return NULL;
2315
 
 
2316
 
        CHECK_TCL_APPARTMENT;
2317
 
 
2318
 
        tfile = PyObject_AsFileDescriptor(file);
2319
 
        if (tfile < 0)
2320
 
                return NULL;
2321
 
 
2322
 
        DeleteFHCD(tfile);
2323
 
 
2324
 
        /* Ought to check for null Tcl_File object... */
2325
 
        ENTER_TCL
2326
 
        Tcl_DeleteFileHandler(tfile);
2327
 
        LEAVE_TCL
2328
 
        Py_INCREF(Py_None);
2329
 
        return Py_None;
 
2310
    PyObject *file;
 
2311
    int tfile;
 
2312
 
 
2313
    if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
 
2314
        return NULL;
 
2315
 
 
2316
    CHECK_TCL_APPARTMENT;
 
2317
 
 
2318
    tfile = PyObject_AsFileDescriptor(file);
 
2319
    if (tfile < 0)
 
2320
        return NULL;
 
2321
 
 
2322
    DeleteFHCD(tfile);
 
2323
 
 
2324
    /* Ought to check for null Tcl_File object... */
 
2325
    ENTER_TCL
 
2326
    Tcl_DeleteFileHandler(tfile);
 
2327
    LEAVE_TCL
 
2328
    Py_INCREF(Py_None);
 
2329
    return Py_None;
2330
2330
}
2331
2331
#endif /* HAVE_CREATEFILEHANDLER */
2332
2332
 
2333
 
 
 
2333
 
2334
2334
/**** Tktt Object (timer token) ****/
2335
2335
 
2336
2336
static PyTypeObject Tktt_Type;
2337
2337
 
2338
2338
typedef struct {
2339
 
        PyObject_HEAD
2340
 
        Tcl_TimerToken token;
2341
 
        PyObject *func;
 
2339
    PyObject_HEAD
 
2340
    Tcl_TimerToken token;
 
2341
    PyObject *func;
2342
2342
} TkttObject;
2343
2343
 
2344
2344
static PyObject *
2345
2345
Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
2346
2346
{
2347
 
        TkttObject *v = (TkttObject *)self;
2348
 
        PyObject *func = v->func;
 
2347
    TkttObject *v = (TkttObject *)self;
 
2348
    PyObject *func = v->func;
2349
2349
 
2350
 
        if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
2351
 
                return NULL;
2352
 
        if (v->token != NULL) {
2353
 
                Tcl_DeleteTimerHandler(v->token);
2354
 
                v->token = NULL;
2355
 
        }
2356
 
        if (func != NULL) {
2357
 
                v->func = NULL;
2358
 
                Py_DECREF(func);
2359
 
                Py_DECREF(v); /* See Tktt_New() */
2360
 
        }
2361
 
        Py_INCREF(Py_None);
2362
 
        return Py_None;
 
2350
    if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
 
2351
        return NULL;
 
2352
    if (v->token != NULL) {
 
2353
        Tcl_DeleteTimerHandler(v->token);
 
2354
        v->token = NULL;
 
2355
    }
 
2356
    if (func != NULL) {
 
2357
        v->func = NULL;
 
2358
        Py_DECREF(func);
 
2359
        Py_DECREF(v); /* See Tktt_New() */
 
2360
    }
 
2361
    Py_INCREF(Py_None);
 
2362
    return Py_None;
2363
2363
}
2364
2364
 
2365
2365
static PyMethodDef Tktt_methods[] =
2366
2366
{
2367
 
        {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
2368
 
        {NULL, NULL}
 
2367
    {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
 
2368
    {NULL, NULL}
2369
2369
};
2370
2370
 
2371
2371
static TkttObject *
2372
2372
Tktt_New(PyObject *func)
2373
2373
{
2374
 
        TkttObject *v;
2375
 
 
2376
 
        v = PyObject_New(TkttObject, &Tktt_Type);
2377
 
        if (v == NULL)
2378
 
                return NULL;
2379
 
 
2380
 
        Py_INCREF(func);
2381
 
        v->token = NULL;
2382
 
        v->func = func;
2383
 
 
2384
 
        /* Extra reference, deleted when called or when handler is deleted */
2385
 
        Py_INCREF(v);
2386
 
        return v;
 
2374
    TkttObject *v;
 
2375
 
 
2376
    v = PyObject_New(TkttObject, &Tktt_Type);
 
2377
    if (v == NULL)
 
2378
        return NULL;
 
2379
 
 
2380
    Py_INCREF(func);
 
2381
    v->token = NULL;
 
2382
    v->func = func;
 
2383
 
 
2384
    /* Extra reference, deleted when called or when handler is deleted */
 
2385
    Py_INCREF(v);
 
2386
    return v;
2387
2387
}
2388
2388
 
2389
2389
static void
2390
2390
Tktt_Dealloc(PyObject *self)
2391
2391
{
2392
 
        TkttObject *v = (TkttObject *)self;
2393
 
        PyObject *func = v->func;
2394
 
 
2395
 
        Py_XDECREF(func);
2396
 
 
2397
 
        PyObject_Del(self);
 
2392
    TkttObject *v = (TkttObject *)self;
 
2393
    PyObject *func = v->func;
 
2394
 
 
2395
    Py_XDECREF(func);
 
2396
 
 
2397
    PyObject_Del(self);
2398
2398
}
2399
2399
 
2400
2400
static PyObject *
2401
2401
Tktt_Repr(PyObject *self)
2402
2402
{
2403
 
        TkttObject *v = (TkttObject *)self;
2404
 
        char buf[100];
 
2403
    TkttObject *v = (TkttObject *)self;
 
2404
    char buf[100];
2405
2405
 
2406
 
        PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
2407
 
                        v->func == NULL ? ", handler deleted" : "");
2408
 
        return PyUnicode_FromString(buf);
 
2406
    PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
 
2407
                    v->func == NULL ? ", handler deleted" : "");
 
2408
    return PyUnicode_FromString(buf);
2409
2409
}
2410
2410
 
2411
2411
static PyTypeObject Tktt_Type =
2412
2412
{
2413
 
        PyVarObject_HEAD_INIT(NULL, 0)
2414
 
        "tktimertoken",                      /*tp_name */
2415
 
        sizeof(TkttObject),                  /*tp_basicsize */
2416
 
        0,                                   /*tp_itemsize */
2417
 
        Tktt_Dealloc,                        /*tp_dealloc */
2418
 
        0,                                   /*tp_print */
2419
 
        0,                                   /*tp_getattr */
2420
 
        0,                                   /*tp_setattr */
2421
 
        0,                                   /*tp_reserved */
2422
 
        Tktt_Repr,                           /*tp_repr */
2423
 
        0,                                   /*tp_as_number */
2424
 
        0,                                   /*tp_as_sequence */
2425
 
        0,                                   /*tp_as_mapping */
2426
 
        0,                                   /*tp_hash */
2427
 
        0,                                   /*tp_call*/
2428
 
        0,                                   /*tp_str*/
2429
 
        0,                                   /*tp_getattro*/
2430
 
        0,                                   /*tp_setattro*/
2431
 
        0,                                   /*tp_as_buffer*/
2432
 
        Py_TPFLAGS_DEFAULT,                  /*tp_flags*/
2433
 
        0,                                   /*tp_doc*/
2434
 
        0,                                   /*tp_traverse*/
2435
 
        0,                                   /*tp_clear*/
2436
 
        0,                                   /*tp_richcompare*/
2437
 
        0,                                   /*tp_weaklistoffset*/
2438
 
        0,                                   /*tp_iter*/
2439
 
        0,                                   /*tp_iternext*/
2440
 
        Tktt_methods,                        /*tp_methods*/
 
2413
    PyVarObject_HEAD_INIT(NULL, 0)
 
2414
    "tktimertoken",                          /*tp_name */
 
2415
    sizeof(TkttObject),                      /*tp_basicsize */
 
2416
    0,                                       /*tp_itemsize */
 
2417
    Tktt_Dealloc,                            /*tp_dealloc */
 
2418
    0,                                       /*tp_print */
 
2419
    0,                                       /*tp_getattr */
 
2420
    0,                                       /*tp_setattr */
 
2421
    0,                                       /*tp_reserved */
 
2422
    Tktt_Repr,                               /*tp_repr */
 
2423
    0,                                       /*tp_as_number */
 
2424
    0,                                       /*tp_as_sequence */
 
2425
    0,                                       /*tp_as_mapping */
 
2426
    0,                                       /*tp_hash */
 
2427
    0,                                       /*tp_call*/
 
2428
    0,                                       /*tp_str*/
 
2429
    0,                                       /*tp_getattro*/
 
2430
    0,                                       /*tp_setattro*/
 
2431
    0,                                       /*tp_as_buffer*/
 
2432
    Py_TPFLAGS_DEFAULT,                      /*tp_flags*/
 
2433
    0,                                       /*tp_doc*/
 
2434
    0,                                       /*tp_traverse*/
 
2435
    0,                                       /*tp_clear*/
 
2436
    0,                                       /*tp_richcompare*/
 
2437
    0,                                       /*tp_weaklistoffset*/
 
2438
    0,                                       /*tp_iter*/
 
2439
    0,                                       /*tp_iternext*/
 
2440
    Tktt_methods,                            /*tp_methods*/
2441
2441
};
2442
2442
 
2443
2443
 
2444
 
 
 
2444
 
2445
2445
/** Timer Handler **/
2446
2446
 
2447
2447
static void
2448
2448
TimerHandler(ClientData clientData)
2449
2449
{
2450
 
        TkttObject *v = (TkttObject *)clientData;
2451
 
        PyObject *func = v->func;
2452
 
        PyObject *res;
2453
 
 
2454
 
        if (func == NULL)
2455
 
                return;
2456
 
 
2457
 
        v->func = NULL;
2458
 
 
2459
 
        ENTER_PYTHON
2460
 
 
2461
 
        res  = PyEval_CallObject(func, NULL);
2462
 
        Py_DECREF(func);
2463
 
        Py_DECREF(v); /* See Tktt_New() */
2464
 
 
2465
 
        if (res == NULL) {
2466
 
                errorInCmd = 1;
2467
 
                PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
2468
 
        }
2469
 
        else
2470
 
                Py_DECREF(res);
2471
 
 
2472
 
        LEAVE_PYTHON
 
2450
    TkttObject *v = (TkttObject *)clientData;
 
2451
    PyObject *func = v->func;
 
2452
    PyObject *res;
 
2453
 
 
2454
    if (func == NULL)
 
2455
        return;
 
2456
 
 
2457
    v->func = NULL;
 
2458
 
 
2459
    ENTER_PYTHON
 
2460
 
 
2461
    res  = PyEval_CallObject(func, NULL);
 
2462
    Py_DECREF(func);
 
2463
    Py_DECREF(v); /* See Tktt_New() */
 
2464
 
 
2465
    if (res == NULL) {
 
2466
        errorInCmd = 1;
 
2467
        PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
 
2468
    }
 
2469
    else
 
2470
        Py_DECREF(res);
 
2471
 
 
2472
    LEAVE_PYTHON
2473
2473
}
2474
2474
 
2475
2475
static PyObject *
2476
2476
Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
2477
2477
{
2478
 
        int milliseconds;
2479
 
        PyObject *func;
2480
 
        TkttObject *v;
2481
 
 
2482
 
        if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2483
 
                              &milliseconds, &func))
2484
 
                return NULL;
2485
 
        if (!PyCallable_Check(func)) {
2486
 
                PyErr_SetString(PyExc_TypeError, "bad argument list");
2487
 
                return NULL;
2488
 
        }
2489
 
 
2490
 
        CHECK_TCL_APPARTMENT;
2491
 
 
2492
 
        v = Tktt_New(func);
2493
 
        if (v) {
2494
 
                v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2495
 
                                                  (ClientData)v);
2496
 
        }
2497
 
 
2498
 
        return (PyObject *) v;
 
2478
    int milliseconds;
 
2479
    PyObject *func;
 
2480
    TkttObject *v;
 
2481
 
 
2482
    if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
 
2483
                          &milliseconds, &func))
 
2484
        return NULL;
 
2485
    if (!PyCallable_Check(func)) {
 
2486
        PyErr_SetString(PyExc_TypeError, "bad argument list");
 
2487
        return NULL;
 
2488
    }
 
2489
 
 
2490
    CHECK_TCL_APPARTMENT;
 
2491
 
 
2492
    v = Tktt_New(func);
 
2493
    if (v) {
 
2494
        v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
 
2495
                                          (ClientData)v);
 
2496
    }
 
2497
 
 
2498
    return (PyObject *) v;
2499
2499
}
2500
2500
 
2501
 
 
 
2501
 
2502
2502
/** Event Loop **/
2503
2503
 
2504
2504
static PyObject *
2505
2505
Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
2506
2506
{
2507
 
        int threshold = 0;
2508
 
        TkappObject *self = (TkappObject*)selfptr;
 
2507
    int threshold = 0;
 
2508
    TkappObject *self = (TkappObject*)selfptr;
2509
2509
#ifdef WITH_THREAD
2510
 
        PyThreadState *tstate = PyThreadState_Get();
 
2510
    PyThreadState *tstate = PyThreadState_Get();
2511
2511
#endif
2512
2512
 
2513
 
        if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
2514
 
                return NULL;
2515
 
 
2516
 
        CHECK_TCL_APPARTMENT;
2517
 
        self->dispatching = 1;
2518
 
 
2519
 
        quitMainLoop = 0;
2520
 
        while (Tk_GetNumMainWindows() > threshold &&
2521
 
               !quitMainLoop &&
2522
 
               !errorInCmd)
2523
 
        {
2524
 
                int result;
 
2513
    if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
 
2514
        return NULL;
 
2515
 
 
2516
    CHECK_TCL_APPARTMENT;
 
2517
    self->dispatching = 1;
 
2518
 
 
2519
    quitMainLoop = 0;
 
2520
    while (Tk_GetNumMainWindows() > threshold &&
 
2521
           !quitMainLoop &&
 
2522
           !errorInCmd)
 
2523
    {
 
2524
        int result;
2525
2525
 
2526
2526
#ifdef WITH_THREAD
2527
 
                if (self->threaded) {
2528
 
                        /* Allow other Python threads to run. */
2529
 
                        ENTER_TCL
2530
 
                        result = Tcl_DoOneEvent(0);
2531
 
                        LEAVE_TCL
2532
 
                }
2533
 
                else {
2534
 
                        Py_BEGIN_ALLOW_THREADS
2535
 
                        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2536
 
                        tcl_tstate = tstate;
2537
 
                        result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2538
 
                        tcl_tstate = NULL;
2539
 
                        if(tcl_lock)PyThread_release_lock(tcl_lock);
2540
 
                        if (result == 0)
2541
 
                                Sleep(Tkinter_busywaitinterval);
2542
 
                        Py_END_ALLOW_THREADS
2543
 
                }
 
2527
        if (self->threaded) {
 
2528
            /* Allow other Python threads to run. */
 
2529
            ENTER_TCL
 
2530
            result = Tcl_DoOneEvent(0);
 
2531
            LEAVE_TCL
 
2532
        }
 
2533
        else {
 
2534
            Py_BEGIN_ALLOW_THREADS
 
2535
            if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
 
2536
            tcl_tstate = tstate;
 
2537
            result = Tcl_DoOneEvent(TCL_DONT_WAIT);
 
2538
            tcl_tstate = NULL;
 
2539
            if(tcl_lock)PyThread_release_lock(tcl_lock);
 
2540
            if (result == 0)
 
2541
                Sleep(Tkinter_busywaitinterval);
 
2542
            Py_END_ALLOW_THREADS
 
2543
        }
2544
2544
#else
2545
 
                result = Tcl_DoOneEvent(0);
 
2545
        result = Tcl_DoOneEvent(0);
2546
2546
#endif
2547
2547
 
2548
 
                if (PyErr_CheckSignals() != 0) {
2549
 
                        self->dispatching = 0;
2550
 
                        return NULL;
2551
 
                }
2552
 
                if (result < 0)
2553
 
                        break;
2554
 
        }
2555
 
        self->dispatching = 0;
2556
 
        quitMainLoop = 0;
 
2548
        if (PyErr_CheckSignals() != 0) {
 
2549
            self->dispatching = 0;
 
2550
            return NULL;
 
2551
        }
 
2552
        if (result < 0)
 
2553
            break;
 
2554
    }
 
2555
    self->dispatching = 0;
 
2556
    quitMainLoop = 0;
2557
2557
 
2558
 
        if (errorInCmd) {
2559
 
                errorInCmd = 0;
2560
 
                PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2561
 
                excInCmd = valInCmd = trbInCmd = NULL;
2562
 
                return NULL;
2563
 
        }
2564
 
        Py_INCREF(Py_None);
2565
 
        return Py_None;
 
2558
    if (errorInCmd) {
 
2559
        errorInCmd = 0;
 
2560
        PyErr_Restore(excInCmd, valInCmd, trbInCmd);
 
2561
        excInCmd = valInCmd = trbInCmd = NULL;
 
2562
        return NULL;
 
2563
    }
 
2564
    Py_INCREF(Py_None);
 
2565
    return Py_None;
2566
2566
}
2567
2567
 
2568
2568
static PyObject *
2569
2569
Tkapp_DoOneEvent(PyObject *self, PyObject *args)
2570
2570
{
2571
 
        int flags = 0;
2572
 
        int rv;
2573
 
 
2574
 
        if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
2575
 
                return NULL;
2576
 
 
2577
 
        ENTER_TCL
2578
 
        rv = Tcl_DoOneEvent(flags);
2579
 
        LEAVE_TCL
2580
 
        return Py_BuildValue("i", rv);
 
2571
    int flags = 0;
 
2572
    int rv;
 
2573
 
 
2574
    if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
 
2575
        return NULL;
 
2576
 
 
2577
    ENTER_TCL
 
2578
    rv = Tcl_DoOneEvent(flags);
 
2579
    LEAVE_TCL
 
2580
    return Py_BuildValue("i", rv);
2581
2581
}
2582
2582
 
2583
2583
static PyObject *
2584
2584
Tkapp_Quit(PyObject *self, PyObject *args)
2585
2585
{
2586
2586
 
2587
 
        if (!PyArg_ParseTuple(args, ":quit"))
2588
 
                return NULL;
 
2587
    if (!PyArg_ParseTuple(args, ":quit"))
 
2588
        return NULL;
2589
2589
 
2590
 
        quitMainLoop = 1;
2591
 
        Py_INCREF(Py_None);
2592
 
        return Py_None;
 
2590
    quitMainLoop = 1;
 
2591
    Py_INCREF(Py_None);
 
2592
    return Py_None;
2593
2593
}
2594
2594
 
2595
2595
static PyObject *
2596
2596
Tkapp_InterpAddr(PyObject *self, PyObject *args)
2597
2597
{
2598
2598
 
2599
 
        if (!PyArg_ParseTuple(args, ":interpaddr"))
2600
 
                return NULL;
 
2599
    if (!PyArg_ParseTuple(args, ":interpaddr"))
 
2600
        return NULL;
2601
2601
 
2602
 
        return PyLong_FromLong((long)Tkapp_Interp(self));
 
2602
    return PyLong_FromLong((long)Tkapp_Interp(self));
2603
2603
}
2604
2604
 
2605
 
static PyObject *
 
2605
static PyObject *
2606
2606
Tkapp_TkInit(PyObject *self, PyObject *args)
2607
2607
{
2608
 
        Tcl_Interp *interp = Tkapp_Interp(self);
2609
 
        const char * _tk_exists = NULL;
2610
 
        int err;
2611
 
 
2612
 
#ifdef TKINTER_PROTECT_LOADTK
2613
 
        /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
2614
 
         * first call failed.
2615
 
         * To avoid the deadlock, we just refuse the second call through
2616
 
         * a static variable.
2617
 
         */
2618
 
        if (tk_load_failed) {
2619
 
                PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
2620
 
                return NULL;
2621
 
        }
2622
 
#endif
2623
 
 
2624
 
        /* We want to guard against calling Tk_Init() multiple times */
2625
 
        CHECK_TCL_APPARTMENT;
2626
 
        ENTER_TCL
2627
 
        err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
2628
 
        ENTER_OVERLAP
2629
 
        if (err == TCL_ERROR) {
2630
 
                /* This sets an exception, but we cannot return right
2631
 
                   away because we need to exit the overlap first. */
2632
 
                Tkinter_Error(self);
2633
 
        } else {
2634
 
                _tk_exists = Tkapp_Result(self);
2635
 
        }
2636
 
        LEAVE_OVERLAP_TCL
2637
 
        if (err == TCL_ERROR) {
2638
 
                return NULL;
2639
 
        }
2640
 
        if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2641
 
                if (Tk_Init(interp)     == TCL_ERROR) {
2642
 
                        PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
2643
 
#ifdef TKINTER_PROTECT_LOADTK
2644
 
                        tk_load_failed = 1;
2645
 
#endif
2646
 
                        return NULL;
2647
 
                }
2648
 
        }
2649
 
        Py_INCREF(Py_None);
2650
 
        return Py_None;
 
2608
    Tcl_Interp *interp = Tkapp_Interp(self);
 
2609
    const char * _tk_exists = NULL;
 
2610
    int err;
 
2611
 
 
2612
#ifdef TKINTER_PROTECT_LOADTK
 
2613
    /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the
 
2614
     * first call failed.
 
2615
     * To avoid the deadlock, we just refuse the second call through
 
2616
     * a static variable.
 
2617
     */
 
2618
    if (tk_load_failed) {
 
2619
        PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG);
 
2620
        return NULL;
 
2621
    }
 
2622
#endif
 
2623
 
 
2624
    /* We want to guard against calling Tk_Init() multiple times */
 
2625
    CHECK_TCL_APPARTMENT;
 
2626
    ENTER_TCL
 
2627
    err = Tcl_Eval(Tkapp_Interp(self), "info exists     tk_version");
 
2628
    ENTER_OVERLAP
 
2629
    if (err == TCL_ERROR) {
 
2630
        /* This sets an exception, but we cannot return right
 
2631
           away because we need to exit the overlap first. */
 
2632
        Tkinter_Error(self);
 
2633
    } else {
 
2634
        _tk_exists = Tkapp_Result(self);
 
2635
    }
 
2636
    LEAVE_OVERLAP_TCL
 
2637
    if (err == TCL_ERROR) {
 
2638
        return NULL;
 
2639
    }
 
2640
    if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0)     {
 
2641
        if (Tk_Init(interp)             == TCL_ERROR) {
 
2642
            PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
 
2643
#ifdef TKINTER_PROTECT_LOADTK
 
2644
            tk_load_failed = 1;
 
2645
#endif
 
2646
            return NULL;
 
2647
        }
 
2648
    }
 
2649
    Py_INCREF(Py_None);
 
2650
    return Py_None;
2651
2651
}
2652
2652
 
2653
2653
static PyObject *
2654
2654
Tkapp_WantObjects(PyObject *self, PyObject *args)
2655
2655
{
2656
2656
 
2657
 
        int wantobjects = -1;
2658
 
        if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
2659
 
                return NULL;
2660
 
        if (wantobjects == -1)
2661
 
                return PyBool_FromLong(((TkappObject*)self)->wantobjects);
2662
 
        ((TkappObject*)self)->wantobjects = wantobjects;
 
2657
    int wantobjects = -1;
 
2658
    if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
 
2659
        return NULL;
 
2660
    if (wantobjects == -1)
 
2661
        return PyBool_FromLong(((TkappObject*)self)->wantobjects);
 
2662
    ((TkappObject*)self)->wantobjects = wantobjects;
2663
2663
 
2664
 
        Py_INCREF(Py_None);
2665
 
        return Py_None;
 
2664
    Py_INCREF(Py_None);
 
2665
    return Py_None;
2666
2666
}
2667
2667
 
2668
2668
static PyObject *
2669
2669
Tkapp_WillDispatch(PyObject *self, PyObject *args)
2670
2670
{
2671
2671
 
2672
 
        ((TkappObject*)self)->dispatching = 1;
 
2672
    ((TkappObject*)self)->dispatching = 1;
2673
2673
 
2674
 
        Py_INCREF(Py_None);
2675
 
        return Py_None;
 
2674
    Py_INCREF(Py_None);
 
2675
    return Py_None;
2676
2676
}
2677
2677
 
2678
 
 
 
2678
 
2679
2679
/**** Tkapp Method List ****/
2680
2680
 
2681
2681
static PyMethodDef Tkapp_methods[] =
2682
2682
{
2683
 
        {"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
2684
 
        {"wantobjects",        Tkapp_WantObjects, METH_VARARGS},
2685
 
        {"call",               Tkapp_Call, METH_VARARGS},
2686
 
        {"globalcall",         Tkapp_GlobalCall, METH_VARARGS},
2687
 
        {"eval",               Tkapp_Eval, METH_VARARGS},
2688
 
        {"globaleval",         Tkapp_GlobalEval, METH_VARARGS},
2689
 
        {"evalfile",           Tkapp_EvalFile, METH_VARARGS},
2690
 
        {"record",             Tkapp_Record, METH_VARARGS},
2691
 
        {"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
2692
 
        {"setvar",             Tkapp_SetVar, METH_VARARGS},
2693
 
        {"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
2694
 
        {"getvar",             Tkapp_GetVar, METH_VARARGS},
2695
 
        {"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
2696
 
        {"unsetvar",           Tkapp_UnsetVar, METH_VARARGS},
2697
 
        {"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
2698
 
        {"getint",             Tkapp_GetInt, METH_VARARGS},
2699
 
        {"getdouble",          Tkapp_GetDouble, METH_VARARGS},
2700
 
        {"getboolean",         Tkapp_GetBoolean, METH_VARARGS},
2701
 
        {"exprstring",         Tkapp_ExprString, METH_VARARGS},
2702
 
        {"exprlong",           Tkapp_ExprLong, METH_VARARGS},
2703
 
        {"exprdouble",         Tkapp_ExprDouble, METH_VARARGS},
2704
 
        {"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
2705
 
        {"splitlist",          Tkapp_SplitList, METH_VARARGS},
2706
 
        {"split",              Tkapp_Split, METH_VARARGS},
2707
 
        {"merge",              Tkapp_Merge, METH_VARARGS},
2708
 
        {"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
2709
 
        {"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
 
2683
    {"willdispatch",       Tkapp_WillDispatch, METH_NOARGS},
 
2684
    {"wantobjects",            Tkapp_WantObjects, METH_VARARGS},
 
2685
    {"call",                   Tkapp_Call, METH_VARARGS},
 
2686
    {"globalcall",             Tkapp_GlobalCall, METH_VARARGS},
 
2687
    {"eval",                   Tkapp_Eval, METH_VARARGS},
 
2688
    {"globaleval",             Tkapp_GlobalEval, METH_VARARGS},
 
2689
    {"evalfile",               Tkapp_EvalFile, METH_VARARGS},
 
2690
    {"record",                 Tkapp_Record, METH_VARARGS},
 
2691
    {"adderrorinfo",       Tkapp_AddErrorInfo, METH_VARARGS},
 
2692
    {"setvar",                 Tkapp_SetVar, METH_VARARGS},
 
2693
    {"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
 
2694
    {"getvar",                 Tkapp_GetVar, METH_VARARGS},
 
2695
    {"globalgetvar",       Tkapp_GlobalGetVar, METH_VARARGS},
 
2696
    {"unsetvar",               Tkapp_UnsetVar, METH_VARARGS},
 
2697
    {"globalunsetvar",     Tkapp_GlobalUnsetVar, METH_VARARGS},
 
2698
    {"getint",                 Tkapp_GetInt, METH_VARARGS},
 
2699
    {"getdouble",              Tkapp_GetDouble, METH_VARARGS},
 
2700
    {"getboolean",             Tkapp_GetBoolean, METH_VARARGS},
 
2701
    {"exprstring",             Tkapp_ExprString, METH_VARARGS},
 
2702
    {"exprlong",               Tkapp_ExprLong, METH_VARARGS},
 
2703
    {"exprdouble",             Tkapp_ExprDouble, METH_VARARGS},
 
2704
    {"exprboolean",        Tkapp_ExprBoolean, METH_VARARGS},
 
2705
    {"splitlist",              Tkapp_SplitList, METH_VARARGS},
 
2706
    {"split",                  Tkapp_Split, METH_VARARGS},
 
2707
    {"merge",                  Tkapp_Merge, METH_VARARGS},
 
2708
    {"createcommand",      Tkapp_CreateCommand, METH_VARARGS},
 
2709
    {"deletecommand",      Tkapp_DeleteCommand, METH_VARARGS},
2710
2710
#ifdef HAVE_CREATEFILEHANDLER
2711
 
        {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
2712
 
        {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
 
2711
    {"createfilehandler",  Tkapp_CreateFileHandler, METH_VARARGS},
 
2712
    {"deletefilehandler",  Tkapp_DeleteFileHandler, METH_VARARGS},
2713
2713
#endif
2714
 
        {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2715
 
        {"mainloop",           Tkapp_MainLoop, METH_VARARGS},
2716
 
        {"dooneevent",         Tkapp_DoOneEvent, METH_VARARGS},
2717
 
        {"quit",               Tkapp_Quit, METH_VARARGS},
2718
 
        {"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
2719
 
        {"loadtk",             Tkapp_TkInit, METH_NOARGS},
2720
 
        {NULL,                 NULL}
 
2714
    {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
 
2715
    {"mainloop",               Tkapp_MainLoop, METH_VARARGS},
 
2716
    {"dooneevent",             Tkapp_DoOneEvent, METH_VARARGS},
 
2717
    {"quit",                   Tkapp_Quit, METH_VARARGS},
 
2718
    {"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
 
2719
    {"loadtk",                 Tkapp_TkInit, METH_NOARGS},
 
2720
    {NULL,                     NULL}
2721
2721
};
2722
2722
 
2723
2723
 
2724
 
 
 
2724
 
2725
2725
/**** Tkapp Type Methods ****/
2726
2726
 
2727
2727
static void
2728
2728
Tkapp_Dealloc(PyObject *self)
2729
2729
{
2730
 
        /*CHECK_TCL_APPARTMENT;*/
2731
 
        ENTER_TCL
2732
 
        Tcl_DeleteInterp(Tkapp_Interp(self));
2733
 
        LEAVE_TCL
2734
 
        PyObject_Del(self);
2735
 
        DisableEventHook();
 
2730
    /*CHECK_TCL_APPARTMENT;*/
 
2731
    ENTER_TCL
 
2732
    Tcl_DeleteInterp(Tkapp_Interp(self));
 
2733
    LEAVE_TCL
 
2734
    PyObject_Del(self);
 
2735
    DisableEventHook();
2736
2736
}
2737
2737
 
2738
2738
static PyTypeObject Tkapp_Type =
2739
2739
{
2740
 
        PyVarObject_HEAD_INIT(NULL, 0)
2741
 
        "tkapp",                             /*tp_name */
2742
 
        sizeof(TkappObject),                 /*tp_basicsize */
2743
 
        0,                                   /*tp_itemsize */
2744
 
        Tkapp_Dealloc,                       /*tp_dealloc */
2745
 
        0,                                   /*tp_print */
2746
 
        0,                                   /*tp_getattr */
2747
 
        0,                                   /*tp_setattr */
2748
 
        0,                                   /*tp_reserved */
2749
 
        0,                                   /*tp_repr */
2750
 
        0,                                   /*tp_as_number */
2751
 
        0,                                   /*tp_as_sequence */
2752
 
        0,                                   /*tp_as_mapping */
2753
 
        0,                                   /*tp_hash */
2754
 
        0,                                   /*tp_call*/
2755
 
        0,                                   /*tp_str*/
2756
 
        0,                                   /*tp_getattro*/
2757
 
        0,                                   /*tp_setattro*/
2758
 
        0,                                   /*tp_as_buffer*/
2759
 
        Py_TPFLAGS_DEFAULT,                  /*tp_flags*/
2760
 
        0,                                   /*tp_doc*/
2761
 
        0,                                   /*tp_traverse*/
2762
 
        0,                                   /*tp_clear*/
2763
 
        0,                                   /*tp_richcompare*/
2764
 
        0,                                   /*tp_weaklistoffset*/
2765
 
        0,                                   /*tp_iter*/
2766
 
        0,                                   /*tp_iternext*/
2767
 
        Tkapp_methods,                       /*tp_methods*/
 
2740
    PyVarObject_HEAD_INIT(NULL, 0)
 
2741
    "tkapp",                                 /*tp_name */
 
2742
    sizeof(TkappObject),                     /*tp_basicsize */
 
2743
    0,                                       /*tp_itemsize */
 
2744
    Tkapp_Dealloc,                           /*tp_dealloc */
 
2745
    0,                                       /*tp_print */
 
2746
    0,                                       /*tp_getattr */
 
2747
    0,                                       /*tp_setattr */
 
2748
    0,                                       /*tp_reserved */
 
2749
    0,                                       /*tp_repr */
 
2750
    0,                                       /*tp_as_number */
 
2751
    0,                                       /*tp_as_sequence */
 
2752
    0,                                       /*tp_as_mapping */
 
2753
    0,                                       /*tp_hash */
 
2754
    0,                                       /*tp_call*/
 
2755
    0,                                       /*tp_str*/
 
2756
    0,                                       /*tp_getattro*/
 
2757
    0,                                       /*tp_setattro*/
 
2758
    0,                                       /*tp_as_buffer*/
 
2759
    Py_TPFLAGS_DEFAULT,                      /*tp_flags*/
 
2760
    0,                                       /*tp_doc*/
 
2761
    0,                                       /*tp_traverse*/
 
2762
    0,                                       /*tp_clear*/
 
2763
    0,                                       /*tp_richcompare*/
 
2764
    0,                                       /*tp_weaklistoffset*/
 
2765
    0,                                       /*tp_iter*/
 
2766
    0,                                       /*tp_iternext*/
 
2767
    Tkapp_methods,                           /*tp_methods*/
2768
2768
};
2769
2769
 
2770
2770
 
2771
 
 
 
2771
 
2772
2772
/**** Tkinter Module ****/
2773
2773
 
2774
2774
typedef struct {
2775
 
        PyObject* tuple;
2776
 
        int size; /* current size */
2777
 
        int maxsize; /* allocated size */
 
2775
    PyObject* tuple;
 
2776
    int size; /* current size */
 
2777
    int maxsize; /* allocated size */
2778
2778
} FlattenContext;
2779
2779
 
2780
2780
static int
2781
2781
_bump(FlattenContext* context, int size)
2782
2782
{
2783
 
        /* expand tuple to hold (at least) size new items.
2784
 
           return true if successful, false if an exception was raised */
2785
 
 
2786
 
        int maxsize = context->maxsize * 2;
2787
 
 
2788
 
        if (maxsize < context->size + size)
2789
 
                maxsize = context->size + size;
2790
 
 
2791
 
        context->maxsize = maxsize;
2792
 
 
2793
 
        return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
 
2783
    /* expand tuple to hold (at least) size new items.
 
2784
       return true if successful, false if an exception was raised */
 
2785
 
 
2786
    int maxsize = context->maxsize * 2;
 
2787
 
 
2788
    if (maxsize < context->size + size)
 
2789
        maxsize = context->size + size;
 
2790
 
 
2791
    context->maxsize = maxsize;
 
2792
 
 
2793
    return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
2794
2794
}
2795
2795
 
2796
2796
static int
2797
2797
_flatten1(FlattenContext* context, PyObject* item, int depth)
2798
2798
{
2799
 
        /* add tuple or list to argument tuple (recursively) */
2800
 
 
2801
 
        int i, size;
2802
 
 
2803
 
        if (depth > 1000) {
2804
 
                PyErr_SetString(PyExc_ValueError,
2805
 
                                "nesting too deep in _flatten");
2806
 
                return 0;
2807
 
        } else if (PyList_Check(item)) {
2808
 
                size = PyList_GET_SIZE(item);
2809
 
                /* preallocate (assume no nesting) */
2810
 
                if (context->size + size > context->maxsize &&
2811
 
                    !_bump(context, size))
2812
 
                        return 0;
2813
 
                /* copy items to output tuple */
2814
 
                for (i = 0; i < size; i++) {
2815
 
                        PyObject *o = PyList_GET_ITEM(item, i);
2816
 
                        if (PyList_Check(o) || PyTuple_Check(o)) {
2817
 
                                if (!_flatten1(context, o, depth + 1))
2818
 
                                        return 0;
2819
 
                        } else if (o != Py_None) {
2820
 
                                if (context->size + 1 > context->maxsize &&
2821
 
                                    !_bump(context, 1))
2822
 
                                        return 0;
2823
 
                                Py_INCREF(o);
2824
 
                                PyTuple_SET_ITEM(context->tuple,
2825
 
                                                 context->size++, o);
2826
 
                        }
2827
 
                }
2828
 
        } else if (PyTuple_Check(item)) {
2829
 
                /* same, for tuples */
2830
 
                size = PyTuple_GET_SIZE(item);
2831
 
                if (context->size + size > context->maxsize &&
2832
 
                    !_bump(context, size))
2833
 
                        return 0;
2834
 
                for (i = 0; i < size; i++) {
2835
 
                        PyObject *o = PyTuple_GET_ITEM(item, i);
2836
 
                        if (PyList_Check(o) || PyTuple_Check(o)) {
2837
 
                                if (!_flatten1(context, o, depth + 1))
2838
 
                                        return 0;
2839
 
                        } else if (o != Py_None) {
2840
 
                                if (context->size + 1 > context->maxsize &&
2841
 
                                    !_bump(context, 1))
2842
 
                                        return 0;
2843
 
                                Py_INCREF(o);
2844
 
                                PyTuple_SET_ITEM(context->tuple,
2845
 
                                                 context->size++, o);
2846
 
                        }
2847
 
                }
2848
 
        } else {
2849
 
                PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2850
 
                return 0;
2851
 
        }
2852
 
        return 1;
 
2799
    /* add tuple or list to argument tuple (recursively) */
 
2800
 
 
2801
    int i, size;
 
2802
 
 
2803
    if (depth > 1000) {
 
2804
        PyErr_SetString(PyExc_ValueError,
 
2805
                        "nesting too deep in _flatten");
 
2806
        return 0;
 
2807
    } else if (PyList_Check(item)) {
 
2808
        size = PyList_GET_SIZE(item);
 
2809
        /* preallocate (assume no nesting) */
 
2810
        if (context->size + size > context->maxsize &&
 
2811
            !_bump(context, size))
 
2812
            return 0;
 
2813
        /* copy items to output tuple */
 
2814
        for (i = 0; i < size; i++) {
 
2815
            PyObject *o = PyList_GET_ITEM(item, i);
 
2816
            if (PyList_Check(o) || PyTuple_Check(o)) {
 
2817
                if (!_flatten1(context, o, depth + 1))
 
2818
                    return 0;
 
2819
            } else if (o != Py_None) {
 
2820
                if (context->size + 1 > context->maxsize &&
 
2821
                    !_bump(context, 1))
 
2822
                    return 0;
 
2823
                Py_INCREF(o);
 
2824
                PyTuple_SET_ITEM(context->tuple,
 
2825
                                 context->size++, o);
 
2826
            }
 
2827
        }
 
2828
    } else if (PyTuple_Check(item)) {
 
2829
        /* same, for tuples */
 
2830
        size = PyTuple_GET_SIZE(item);
 
2831
        if (context->size + size > context->maxsize &&
 
2832
            !_bump(context, size))
 
2833
            return 0;
 
2834
        for (i = 0; i < size; i++) {
 
2835
            PyObject *o = PyTuple_GET_ITEM(item, i);
 
2836
            if (PyList_Check(o) || PyTuple_Check(o)) {
 
2837
                if (!_flatten1(context, o, depth + 1))
 
2838
                    return 0;
 
2839
            } else if (o != Py_None) {
 
2840
                if (context->size + 1 > context->maxsize &&
 
2841
                    !_bump(context, 1))
 
2842
                    return 0;
 
2843
                Py_INCREF(o);
 
2844
                PyTuple_SET_ITEM(context->tuple,
 
2845
                                 context->size++, o);
 
2846
            }
 
2847
        }
 
2848
    } else {
 
2849
        PyErr_SetString(PyExc_TypeError, "argument must be sequence");
 
2850
        return 0;
 
2851
    }
 
2852
    return 1;
2853
2853
}
2854
2854
 
2855
2855
static PyObject *
2856
2856
Tkinter_Flatten(PyObject* self, PyObject* args)
2857
2857
{
2858
 
        FlattenContext context;
2859
 
        PyObject* item;
2860
 
 
2861
 
        if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2862
 
                return NULL;
2863
 
 
2864
 
        context.maxsize = PySequence_Size(item);
2865
 
        if (context.maxsize < 0)
2866
 
                return NULL;
2867
 
        if (context.maxsize == 0)
2868
 
                return PyTuple_New(0);
2869
 
 
2870
 
        context.tuple = PyTuple_New(context.maxsize);
2871
 
        if (!context.tuple)
2872
 
                return NULL;
2873
 
 
2874
 
        context.size = 0;
2875
 
 
2876
 
        if (!_flatten1(&context, item,0))
2877
 
                return NULL;
2878
 
 
2879
 
        if (_PyTuple_Resize(&context.tuple, context.size))
2880
 
                return NULL;
2881
 
 
2882
 
        return context.tuple;
 
2858
    FlattenContext context;
 
2859
    PyObject* item;
 
2860
 
 
2861
    if (!PyArg_ParseTuple(args, "O:_flatten", &item))
 
2862
        return NULL;
 
2863
 
 
2864
    context.maxsize = PySequence_Size(item);
 
2865
    if (context.maxsize < 0)
 
2866
        return NULL;
 
2867
    if (context.maxsize == 0)
 
2868
        return PyTuple_New(0);
 
2869
 
 
2870
    context.tuple = PyTuple_New(context.maxsize);
 
2871
    if (!context.tuple)
 
2872
        return NULL;
 
2873
 
 
2874
    context.size = 0;
 
2875
 
 
2876
    if (!_flatten1(&context, item,0))
 
2877
        return NULL;
 
2878
 
 
2879
    if (_PyTuple_Resize(&context.tuple, context.size))
 
2880
        return NULL;
 
2881
 
 
2882
    return context.tuple;
2883
2883
}
2884
2884
 
2885
2885
static PyObject *
2886
2886
Tkinter_Create(PyObject *self, PyObject *args)
2887
2887
{
2888
 
        char *screenName = NULL;
2889
 
        char *baseName = NULL; /* XXX this is not used anymore;
2890
 
                                  try getting rid of it. */
2891
 
        char *className = NULL;
2892
 
        int interactive = 0;
2893
 
        int wantobjects = 0;
2894
 
        int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
2895
 
        int sync = 0; /* pass -sync to wish */
2896
 
        char *use = NULL; /* pass -use to wish */
2897
 
 
2898
 
        className = "Tk";
2899
 
 
2900
 
        if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
2901
 
                              &screenName, &baseName, &className,
2902
 
                              &interactive, &wantobjects, &wantTk,
2903
 
                              &sync, &use))
2904
 
                return NULL;
2905
 
 
2906
 
        return (PyObject *) Tkapp_New(screenName, className,
2907
 
                                      interactive, wantobjects, wantTk,
2908
 
                                      sync, use);
 
2888
    char *screenName = NULL;
 
2889
    char *baseName = NULL; /* XXX this is not used anymore;
 
2890
                              try getting rid of it. */
 
2891
    char *className = NULL;
 
2892
    int interactive = 0;
 
2893
    int wantobjects = 0;
 
2894
    int wantTk = 1;     /* If false, then Tk_Init() doesn't get called */
 
2895
    int sync = 0; /* pass -sync to wish */
 
2896
    char *use = NULL; /* pass -use to wish */
 
2897
 
 
2898
    className = "Tk";
 
2899
 
 
2900
    if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
 
2901
                          &screenName, &baseName, &className,
 
2902
                          &interactive, &wantobjects, &wantTk,
 
2903
                          &sync, &use))
 
2904
        return NULL;
 
2905
 
 
2906
    return (PyObject *) Tkapp_New(screenName, className,
 
2907
                                  interactive, wantobjects,     wantTk,
 
2908
                                  sync, use);
2909
2909
}
2910
2910
 
2911
2911
static PyObject *
2912
2912
Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2913
2913
{
2914
 
        int new_val;
2915
 
        if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2916
 
                return NULL;
2917
 
        if (new_val < 0) {
2918
 
                PyErr_SetString(PyExc_ValueError,
2919
 
                                "busywaitinterval must be >= 0");
2920
 
                return NULL;
2921
 
        }
2922
 
        Tkinter_busywaitinterval = new_val;
2923
 
        Py_INCREF(Py_None);
2924
 
        return Py_None;
 
2914
    int new_val;
 
2915
    if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
 
2916
        return NULL;
 
2917
    if (new_val < 0) {
 
2918
        PyErr_SetString(PyExc_ValueError,
 
2919
                        "busywaitinterval must be >= 0");
 
2920
        return NULL;
 
2921
    }
 
2922
    Tkinter_busywaitinterval = new_val;
 
2923
    Py_INCREF(Py_None);
 
2924
    return Py_None;
2925
2925
}
2926
2926
 
2927
2927
static char setbusywaitinterval_doc[] =
2935
2935
static PyObject *
2936
2936
Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2937
2937
{
2938
 
        return PyLong_FromLong(Tkinter_busywaitinterval);
 
2938
    return PyLong_FromLong(Tkinter_busywaitinterval);
2939
2939
}
2940
2940
 
2941
2941
static char getbusywaitinterval_doc[] =
2946
2946
 
2947
2947
static PyMethodDef moduleMethods[] =
2948
2948
{
2949
 
        {"_flatten",           Tkinter_Flatten, METH_VARARGS},
2950
 
        {"create",             Tkinter_Create, METH_VARARGS},
2951
 
        {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2952
 
                               setbusywaitinterval_doc},
2953
 
        {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2954
 
                               METH_NOARGS, getbusywaitinterval_doc},
2955
 
        {NULL,                 NULL}
 
2949
    {"_flatten",           Tkinter_Flatten, METH_VARARGS},
 
2950
    {"create",             Tkinter_Create, METH_VARARGS},
 
2951
    {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
 
2952
                           setbusywaitinterval_doc},
 
2953
    {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
 
2954
                           METH_NOARGS, getbusywaitinterval_doc},
 
2955
    {NULL,                 NULL}
2956
2956
};
2957
2957
 
2958
2958
#ifdef WAIT_FOR_STDIN
2963
2963
static void
2964
2964
MyFileProc(void *clientData, int mask)
2965
2965
{
2966
 
        stdin_ready = 1;
 
2966
    stdin_ready = 1;
2967
2967
}
2968
2968
#endif
2969
2969
 
2975
2975
EventHook(void)
2976
2976
{
2977
2977
#ifndef MS_WINDOWS
2978
 
        int tfile;
 
2978
    int tfile;
2979
2979
#endif
2980
2980
#ifdef WITH_THREAD
2981
 
        PyEval_RestoreThread(event_tstate);
 
2981
    PyEval_RestoreThread(event_tstate);
2982
2982
#endif
2983
 
        stdin_ready = 0;
2984
 
        errorInCmd = 0;
 
2983
    stdin_ready = 0;
 
2984
    errorInCmd = 0;
2985
2985
#ifndef MS_WINDOWS
2986
 
        tfile = fileno(stdin);
2987
 
        Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
 
2986
    tfile = fileno(stdin);
 
2987
    Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
2988
2988
#endif
2989
 
        while (!errorInCmd && !stdin_ready) {
2990
 
                int result;
 
2989
    while (!errorInCmd && !stdin_ready) {
 
2990
        int result;
2991
2991
#ifdef MS_WINDOWS
2992
 
                if (_kbhit()) {
2993
 
                        stdin_ready = 1;
2994
 
                        break;
2995
 
                }
 
2992
        if (_kbhit()) {
 
2993
            stdin_ready = 1;
 
2994
            break;
 
2995
        }
2996
2996
#endif
2997
2997
#if defined(WITH_THREAD) || defined(MS_WINDOWS)
2998
 
                Py_BEGIN_ALLOW_THREADS
2999
 
                if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
3000
 
                tcl_tstate = event_tstate;
3001
 
 
3002
 
                result = Tcl_DoOneEvent(TCL_DONT_WAIT);
3003
 
 
3004
 
                tcl_tstate = NULL;
3005
 
                if(tcl_lock)PyThread_release_lock(tcl_lock);
3006
 
                if (result == 0)
3007
 
                        Sleep(Tkinter_busywaitinterval);
3008
 
                Py_END_ALLOW_THREADS
 
2998
        Py_BEGIN_ALLOW_THREADS
 
2999
        if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
 
3000
        tcl_tstate = event_tstate;
 
3001
 
 
3002
        result = Tcl_DoOneEvent(TCL_DONT_WAIT);
 
3003
 
 
3004
        tcl_tstate = NULL;
 
3005
        if(tcl_lock)PyThread_release_lock(tcl_lock);
 
3006
        if (result == 0)
 
3007
            Sleep(Tkinter_busywaitinterval);
 
3008
        Py_END_ALLOW_THREADS
3009
3009
#else
3010
 
                result = Tcl_DoOneEvent(0);
 
3010
        result = Tcl_DoOneEvent(0);
3011
3011
#endif
3012
3012
 
3013
 
                if (result < 0)
3014
 
                        break;
3015
 
        }
 
3013
        if (result < 0)
 
3014
            break;
 
3015
    }
3016
3016
#ifndef MS_WINDOWS
3017
 
        Tcl_DeleteFileHandler(tfile);
 
3017
    Tcl_DeleteFileHandler(tfile);
3018
3018
#endif
3019
 
        if (errorInCmd) {
3020
 
                errorInCmd = 0;
3021
 
                PyErr_Restore(excInCmd, valInCmd, trbInCmd);
3022
 
                excInCmd = valInCmd = trbInCmd = NULL;
3023
 
                PyErr_Print();
3024
 
        }
 
3019
    if (errorInCmd) {
 
3020
        errorInCmd = 0;
 
3021
        PyErr_Restore(excInCmd, valInCmd, trbInCmd);
 
3022
        excInCmd = valInCmd = trbInCmd = NULL;
 
3023
        PyErr_Print();
 
3024
    }
3025
3025
#ifdef WITH_THREAD
3026
 
        PyEval_SaveThread();
 
3026
    PyEval_SaveThread();
3027
3027
#endif
3028
 
        return 0;
 
3028
    return 0;
3029
3029
}
3030
3030
 
3031
3031
#endif
3034
3034
EnableEventHook(void)
3035
3035
{
3036
3036
#ifdef WAIT_FOR_STDIN
3037
 
        if (PyOS_InputHook == NULL) {
 
3037
    if (PyOS_InputHook == NULL) {
3038
3038
#ifdef WITH_THREAD
3039
 
                event_tstate = PyThreadState_Get();
 
3039
        event_tstate = PyThreadState_Get();
3040
3040
#endif
3041
 
                PyOS_InputHook = EventHook;
3042
 
        }
 
3041
        PyOS_InputHook = EventHook;
 
3042
    }
3043
3043
#endif
3044
3044
}
3045
3045
 
3047
3047
DisableEventHook(void)
3048
3048
{
3049
3049
#ifdef WAIT_FOR_STDIN
3050
 
        if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
3051
 
                PyOS_InputHook = NULL;
3052
 
        }
 
3050
    if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
 
3051
        PyOS_InputHook = NULL;
 
3052
    }
3053
3053
#endif
3054
3054
}
3055
3055
 
3058
3058
static void
3059
3059
ins_long(PyObject *d, char *name, long val)
3060
3060
{
3061
 
        PyObject *v = PyLong_FromLong(val);
3062
 
        if (v) {
3063
 
                PyDict_SetItemString(d, name, v);
3064
 
                Py_DECREF(v);
3065
 
        }
 
3061
    PyObject *v = PyLong_FromLong(val);
 
3062
    if (v) {
 
3063
        PyDict_SetItemString(d, name, v);
 
3064
        Py_DECREF(v);
 
3065
    }
3066
3066
}
3067
3067
static void
3068
3068
ins_string(PyObject *d, char *name, char *val)
3069
3069
{
3070
 
        PyObject *v = PyUnicode_FromString(val);
3071
 
        if (v) {
3072
 
                PyDict_SetItemString(d, name, v);
3073
 
                Py_DECREF(v);
3074
 
        }
 
3070
    PyObject *v = PyUnicode_FromString(val);
 
3071
    if (v) {
 
3072
        PyDict_SetItemString(d, name, v);
 
3073
        Py_DECREF(v);
 
3074
    }
3075
3075
}
3076
3076
 
3077
3077
 
3078
3078
static struct PyModuleDef _tkintermodule = {
3079
 
        PyModuleDef_HEAD_INIT,
3080
 
        "_tkinter",
3081
 
        NULL,
3082
 
        -1,
3083
 
        moduleMethods,
3084
 
        NULL,
3085
 
        NULL,
3086
 
        NULL,
3087
 
        NULL
 
3079
    PyModuleDef_HEAD_INIT,
 
3080
    "_tkinter",
 
3081
    NULL,
 
3082
    -1,
 
3083
    moduleMethods,
 
3084
    NULL,
 
3085
    NULL,
 
3086
    NULL,
 
3087
    NULL
3088
3088
};
3089
3089
 
3090
3090
PyMODINIT_FUNC
3091
3091
PyInit__tkinter(void)
3092
3092
{
3093
 
        PyObject *m, *d, *uexe, *cexe;
 
3093
    PyObject *m, *d, *uexe, *cexe;
3094
3094
 
3095
 
        if (PyType_Ready(&Tkapp_Type) < 0)
3096
 
                return NULL;
 
3095
    if (PyType_Ready(&Tkapp_Type) < 0)
 
3096
        return NULL;
3097
3097
 
3098
3098
#ifdef WITH_THREAD
3099
 
        tcl_lock = PyThread_allocate_lock();
 
3099
    tcl_lock = PyThread_allocate_lock();
3100
3100
#endif
3101
3101
 
3102
 
        m = PyModule_Create(&_tkintermodule);
3103
 
        if (m == NULL)
3104
 
                return NULL;
3105
 
 
3106
 
        d = PyModule_GetDict(m);
3107
 
        Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
3108
 
        PyDict_SetItemString(d, "TclError", Tkinter_TclError);
3109
 
 
3110
 
        ins_long(d, "READABLE", TCL_READABLE);
3111
 
        ins_long(d, "WRITABLE", TCL_WRITABLE);
3112
 
        ins_long(d, "EXCEPTION", TCL_EXCEPTION);
3113
 
        ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
3114
 
        ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
3115
 
        ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
3116
 
        ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
3117
 
        ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
3118
 
        ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
3119
 
        ins_string(d, "TK_VERSION", TK_VERSION);
3120
 
        ins_string(d, "TCL_VERSION", TCL_VERSION);
3121
 
 
3122
 
        PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
3123
 
 
3124
 
        if (PyType_Ready(&Tktt_Type) < 0)
3125
 
                return NULL;
3126
 
        PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
3127
 
 
3128
 
        Py_TYPE(&PyTclObject_Type) = &PyType_Type;
3129
 
        PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
 
3102
    m = PyModule_Create(&_tkintermodule);
 
3103
    if (m == NULL)
 
3104
        return NULL;
 
3105
 
 
3106
    d = PyModule_GetDict(m);
 
3107
    Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
 
3108
    PyDict_SetItemString(d, "TclError", Tkinter_TclError);
 
3109
 
 
3110
    ins_long(d, "READABLE", TCL_READABLE);
 
3111
    ins_long(d, "WRITABLE", TCL_WRITABLE);
 
3112
    ins_long(d, "EXCEPTION", TCL_EXCEPTION);
 
3113
    ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
 
3114
    ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
 
3115
    ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
 
3116
    ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
 
3117
    ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
 
3118
    ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
 
3119
    ins_string(d, "TK_VERSION", TK_VERSION);
 
3120
    ins_string(d, "TCL_VERSION", TCL_VERSION);
 
3121
 
 
3122
    PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
 
3123
 
 
3124
    if (PyType_Ready(&Tktt_Type) < 0)
 
3125
        return NULL;
 
3126
    PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
 
3127
 
 
3128
    Py_TYPE(&PyTclObject_Type) = &PyType_Type;
 
3129
    PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
3130
3130
 
3131
3131
#ifdef TK_AQUA
3132
 
        /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3133
 
         * start waking up.  Note that Tcl_FindExecutable will do this, this
3134
 
         * code must be above it! The original warning from
3135
 
         * tkMacOSXAppInit.c is copied below.
3136
 
         *
3137
 
         * NB - You have to swap in the Tk Notifier BEFORE you start up the
3138
 
         * Tcl interpreter for now.  It probably should work to do this
3139
 
         * in the other order, but for now it doesn't seem to.
3140
 
         *
3141
 
         */
3142
 
        Tk_MacOSXSetupTkNotifier();
 
3132
    /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
 
3133
     * start waking up.  Note that Tcl_FindExecutable will do this, this
 
3134
     * code must be above it! The original warning from
 
3135
     * tkMacOSXAppInit.c is copied below.
 
3136
     *
 
3137
     * NB - You have to swap in the Tk Notifier BEFORE you start up the
 
3138
     * Tcl interpreter for now.  It probably should work to do this
 
3139
     * in the other order, but for now it doesn't seem to.
 
3140
     *
 
3141
     */
 
3142
    Tk_MacOSXSetupTkNotifier();
3143
3143
#endif
3144
3144
 
3145
3145
 
3146
 
        /* This helps the dynamic loader; in Unicode aware Tcl versions
3147
 
           it also helps Tcl find its encodings. */
3148
 
        uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3149
 
        if (uexe) {
3150
 
                cexe = PyUnicode_AsEncodedString(uexe, 
3151
 
                                                 Py_FileSystemDefaultEncoding, 
3152
 
                                                 NULL);
3153
 
                if (cexe)
3154
 
                        Tcl_FindExecutable(PyBytes_AsString(cexe));
3155
 
                Py_XDECREF(cexe);
3156
 
                Py_DECREF(uexe);
3157
 
        }
 
3146
    /* This helps the dynamic loader; in Unicode aware Tcl versions
 
3147
       it also helps Tcl find its encodings. */
 
3148
    uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
 
3149
    if (uexe) {
 
3150
        cexe = PyUnicode_AsEncodedString(uexe,
 
3151
                                         Py_FileSystemDefaultEncoding,
 
3152
                                         NULL);
 
3153
        if (cexe)
 
3154
            Tcl_FindExecutable(PyBytes_AsString(cexe));
 
3155
        Py_XDECREF(cexe);
 
3156
        Py_DECREF(uexe);
 
3157
    }
3158
3158
 
3159
 
        if (PyErr_Occurred()) {
3160
 
                Py_DECREF(m);
3161
 
                return NULL;
3162
 
        }
 
3159
    if (PyErr_Occurred()) {
 
3160
        Py_DECREF(m);
 
3161
        return NULL;
 
3162
    }
3163
3163
 
3164
3164
#if 0
3165
 
        /* This was not a good idea; through <Destroy> bindings,
3166
 
           Tcl_Finalize() may invoke Python code but at that point the
3167
 
           interpreter and thread state have already been destroyed! */
3168
 
        Py_AtExit(Tcl_Finalize);
 
3165
    /* This was not a good idea; through <Destroy> bindings,
 
3166
       Tcl_Finalize() may invoke Python code but at that point the
 
3167
       interpreter and thread state have already been destroyed! */
 
3168
    Py_AtExit(Tcl_Finalize);
3169
3169
#endif
3170
 
        return m;
 
3170
    return m;
3171
3171
}