OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkCmds.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkCmds.c --
3
 *
4
 *      This file contains a collection of Tk-related Tcl commands
5
 *      that didn't fit in any particular file of the toolkit.
6
 *
7
 * Copyright (c) 1990-1994 The Regents of the University of California.
8
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
9
 * Copyright (c) 1998 by Scriptics Corporation.
10
 *
11
 * See the file "license.terms" for information on usage and redistribution
12
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13
 *
14
 * RCS: @(#) $Id: tkCmds.c,v 1.1.1.1 2002-01-16 10:25:51 markom Exp $
15
 */
16
 
17
#include "tkPort.h"
18
#include "tkInt.h"
19
#include <errno.h>
20
 
21
/*
22
 * Forward declarations for procedures defined later in this file:
23
 */
24
 
25
static TkWindow *       GetToplevel _ANSI_ARGS_((Tk_Window tkwin));
26
static char *           WaitVariableProc _ANSI_ARGS_((ClientData clientData,
27
                            Tcl_Interp *interp, char *name1, char *name2,
28
                            int flags));
29
static void             WaitVisibilityProc _ANSI_ARGS_((ClientData clientData,
30
                            XEvent *eventPtr));
31
static void             WaitWindowProc _ANSI_ARGS_((ClientData clientData,
32
                            XEvent *eventPtr));
33
 
34
/*
35
 *----------------------------------------------------------------------
36
 *
37
 * Tk_BellObjCmd --
38
 *
39
 *      This procedure is invoked to process the "bell" Tcl command.
40
 *      See the user documentation for details on what it does.
41
 *
42
 * Results:
43
 *      A standard Tcl result.
44
 *
45
 * Side effects:
46
 *      See the user documentation.
47
 *
48
 *----------------------------------------------------------------------
49
 */
50
 
51
int
52
Tk_BellObjCmd(clientData, interp, objc, objv)
53
    ClientData clientData;      /* Main window associated with interpreter. */
54
    Tcl_Interp *interp;         /* Current interpreter. */
55
    int objc;                   /* Number of arguments. */
56
    Tcl_Obj *CONST objv[];      /* Argument objects. */
57
{
58
    Tk_Window tkwin = (Tk_Window) clientData;
59
    int index;
60
    char *string;
61
    static char *optionStrings[] = {
62
        "-displayof",   NULL
63
    };
64
 
65
    if ((objc != 1) && (objc != 3)) {
66
        Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window?");
67
        return TCL_ERROR;
68
    }
69
 
70
    if (objc == 3) {
71
        if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
72
                &index) != TCL_OK) {
73
            return TCL_ERROR;
74
        }
75
        string = Tcl_GetStringFromObj(objv[2], NULL);
76
        tkwin = Tk_NameToWindow(interp, string, tkwin);
77
        if (tkwin == NULL) {
78
            return TCL_ERROR;
79
        }
80
    }
81
    XBell(Tk_Display(tkwin), 0);
82
    XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
83
    XFlush(Tk_Display(tkwin));
84
    return TCL_OK;
85
}
86
 
87
/*
88
 *----------------------------------------------------------------------
89
 *
90
 * Tk_BindCmd --
91
 *
92
 *      This procedure is invoked to process the "bind" Tcl command.
93
 *      See the user documentation for details on what it does.
94
 *
95
 * Results:
96
 *      A standard Tcl result.
97
 *
98
 * Side effects:
99
 *      See the user documentation.
100
 *
101
 *----------------------------------------------------------------------
102
 */
103
 
104
int
105
Tk_BindCmd(clientData, interp, argc, argv)
106
    ClientData clientData;      /* Main window associated with interpreter. */
107
    Tcl_Interp *interp;         /* Current interpreter. */
108
    int argc;                   /* Number of arguments. */
109
    char **argv;                /* Argument strings. */
110
{
111
    Tk_Window tkwin = (Tk_Window) clientData;
112
    TkWindow *winPtr;
113
    ClientData object;
114
 
115
    if ((argc < 2) || (argc > 4)) {
116
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
117
                " window ?pattern? ?command?\"", (char *) NULL);
118
        return TCL_ERROR;
119
    }
120
    if (argv[1][0] == '.') {
121
        winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
122
        if (winPtr == NULL) {
123
            return TCL_ERROR;
124
        }
125
        object = (ClientData) winPtr->pathName;
126
    } else {
127
        winPtr = (TkWindow *) clientData;
128
        object = (ClientData) Tk_GetUid(argv[1]);
129
    }
130
 
131
    if (argc == 4) {
132
        int append = 0;
133
        unsigned long mask;
134
 
135
        if (argv[3][0] == 0) {
136
            return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable,
137
                    object, argv[2]);
138
        }
139
        if (argv[3][0] == '+') {
140
            argv[3]++;
141
            append = 1;
142
        }
143
        mask = Tk_CreateBinding(interp, winPtr->mainPtr->bindingTable,
144
                object, argv[2], argv[3], append);
145
        if (mask == 0) {
146
            return TCL_ERROR;
147
        }
148
    } else if (argc == 3) {
149
        char *command;
150
 
151
        command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
152
                object, argv[2]);
153
        if (command == NULL) {
154
            Tcl_ResetResult(interp);
155
            return TCL_OK;
156
        }
157
        interp->result = command;
158
    } else {
159
        Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
160
    }
161
    return TCL_OK;
162
}
163
 
164
/*
165
 *----------------------------------------------------------------------
166
 *
167
 * TkBindEventProc --
168
 *
169
 *      This procedure is invoked by Tk_HandleEvent for each event;  it
170
 *      causes any appropriate bindings for that event to be invoked.
171
 *
172
 * Results:
173
 *      None.
174
 *
175
 * Side effects:
176
 *      Depends on what bindings have been established with the "bind"
177
 *      command.
178
 *
179
 *----------------------------------------------------------------------
180
 */
181
 
182
void
183
TkBindEventProc(winPtr, eventPtr)
184
    TkWindow *winPtr;                   /* Pointer to info about window. */
185
    XEvent *eventPtr;                   /* Information about event. */
186
{
187
#define MAX_OBJS 20
188
    ClientData objects[MAX_OBJS], *objPtr;
189
    static Tk_Uid allUid = NULL;
190
    TkWindow *topLevPtr;
191
    int i, count;
192
    char *p;
193
    Tcl_HashEntry *hPtr;
194
 
195
    if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) {
196
        return;
197
    }
198
 
199
    objPtr = objects;
200
    if (winPtr->numTags != 0) {
201
        /*
202
         * Make a copy of the tags for the window, replacing window names
203
         * with pointers to the pathName from the appropriate window.
204
         */
205
 
206
        if (winPtr->numTags > MAX_OBJS) {
207
            objPtr = (ClientData *) ckalloc((unsigned)
208
                    (winPtr->numTags * sizeof(ClientData)));
209
        }
210
        for (i = 0; i < winPtr->numTags; i++) {
211
            p = (char *) winPtr->tagPtr[i];
212
            if (*p == '.') {
213
                hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
214
                if (hPtr != NULL) {
215
                    p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
216
                } else {
217
                    p = NULL;
218
                }
219
            }
220
            objPtr[i] = (ClientData) p;
221
        }
222
        count = winPtr->numTags;
223
    } else {
224
        objPtr[0] = (ClientData) winPtr->pathName;
225
        objPtr[1] = (ClientData) winPtr->classUid;
226
        for (topLevPtr = winPtr;
227
                (topLevPtr != NULL) && !(topLevPtr->flags & TK_TOP_LEVEL);
228
                topLevPtr = topLevPtr->parentPtr) {
229
            /* Empty loop body. */
230
        }
231
        if ((winPtr != topLevPtr) && (topLevPtr != NULL)) {
232
            count = 4;
233
            objPtr[2] = (ClientData) topLevPtr->pathName;
234
        } else {
235
            count = 3;
236
        }
237
        if (allUid == NULL) {
238
            allUid = Tk_GetUid("all");
239
        }
240
        objPtr[count-1] = (ClientData) allUid;
241
    }
242
    Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
243
            count, objPtr);
244
    if (objPtr != objects) {
245
        ckfree((char *) objPtr);
246
    }
247
}
248
 
249
/*
250
 *----------------------------------------------------------------------
251
 *
252
 * Tk_BindtagsCmd --
253
 *
254
 *      This procedure is invoked to process the "bindtags" Tcl command.
255
 *      See the user documentation for details on what it does.
256
 *
257
 * Results:
258
 *      A standard Tcl result.
259
 *
260
 * Side effects:
261
 *      See the user documentation.
262
 *
263
 *----------------------------------------------------------------------
264
 */
265
 
266
int
267
Tk_BindtagsCmd(clientData, interp, argc, argv)
268
    ClientData clientData;      /* Main window associated with interpreter. */
269
    Tcl_Interp *interp;         /* Current interpreter. */
270
    int argc;                   /* Number of arguments. */
271
    char **argv;                /* Argument strings. */
272
{
273
    Tk_Window tkwin = (Tk_Window) clientData;
274
    TkWindow *winPtr, *winPtr2;
275
    int i, tagArgc;
276
    char *p, **tagArgv;
277
 
278
    if ((argc < 2) || (argc > 3)) {
279
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
280
                " window ?tags?\"", (char *) NULL);
281
        return TCL_ERROR;
282
    }
283
    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
284
    if (winPtr == NULL) {
285
        return TCL_ERROR;
286
    }
287
    if (argc == 2) {
288
        if (winPtr->numTags == 0) {
289
            Tcl_AppendElement(interp, winPtr->pathName);
290
            Tcl_AppendElement(interp, winPtr->classUid);
291
            for (winPtr2 = winPtr;
292
                    (winPtr2 != NULL) && !(winPtr2->flags & TK_TOP_LEVEL);
293
                    winPtr2 = winPtr2->parentPtr) {
294
                /* Empty loop body. */
295
            }
296
            if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
297
                Tcl_AppendElement(interp, winPtr2->pathName);
298
            }
299
            Tcl_AppendElement(interp, "all");
300
        } else {
301
            for (i = 0; i < winPtr->numTags; i++) {
302
                Tcl_AppendElement(interp, (char *) winPtr->tagPtr[i]);
303
            }
304
        }
305
        return TCL_OK;
306
    }
307
    if (winPtr->tagPtr != NULL) {
308
        TkFreeBindingTags(winPtr);
309
    }
310
    if (argv[2][0] == 0) {
311
        return TCL_OK;
312
    }
313
    if (Tcl_SplitList(interp, argv[2], &tagArgc, &tagArgv) != TCL_OK) {
314
        return TCL_ERROR;
315
    }
316
    winPtr->numTags = tagArgc;
317
    winPtr->tagPtr = (ClientData *) ckalloc((unsigned)
318
            (tagArgc * sizeof(ClientData)));
319
    for (i = 0; i < tagArgc; i++) {
320
        p = tagArgv[i];
321
        if (p[0] == '.') {
322
            char *copy;
323
 
324
            /*
325
             * Handle names starting with "." specially: store a malloc'ed
326
             * string, rather than a Uid;  at event time we'll look up the
327
             * name in the window table and use the corresponding window,
328
             * if there is one.
329
             */
330
 
331
            copy = (char *) ckalloc((unsigned) (strlen(p) + 1));
332
            strcpy(copy, p);
333
            winPtr->tagPtr[i] = (ClientData) copy;
334
        } else {
335
            winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p);
336
        }
337
    }
338
    ckfree((char *) tagArgv);
339
    return TCL_OK;
340
}
341
 
342
/*
343
 *----------------------------------------------------------------------
344
 *
345
 * TkFreeBindingTags --
346
 *
347
 *      This procedure is called to free all of the binding tags
348
 *      associated with a window;  typically it is only invoked where
349
 *      there are window-specific tags.
350
 *
351
 * Results:
352
 *      None.
353
 *
354
 * Side effects:
355
 *      Any binding tags for winPtr are freed.
356
 *
357
 *----------------------------------------------------------------------
358
 */
359
 
360
void
361
TkFreeBindingTags(winPtr)
362
    TkWindow *winPtr;           /* Window whose tags are to be released. */
363
{
364
    int i;
365
    char *p;
366
 
367
    for (i = 0; i < winPtr->numTags; i++) {
368
        p = (char *) (winPtr->tagPtr[i]);
369
        if (*p == '.') {
370
            /*
371
             * Names starting with "." are malloced rather than Uids, so
372
             * they have to be freed.
373
             */
374
 
375
            ckfree(p);
376
        }
377
    }
378
    ckfree((char *) winPtr->tagPtr);
379
    winPtr->numTags = 0;
380
    winPtr->tagPtr = NULL;
381
}
382
 
383
/*
384
 *----------------------------------------------------------------------
385
 *
386
 * Tk_DestroyCmd --
387
 *
388
 *      This procedure is invoked to process the "destroy" Tcl command.
389
 *      See the user documentation for details on what it does.
390
 *
391
 * Results:
392
 *      A standard Tcl result.
393
 *
394
 * Side effects:
395
 *      See the user documentation.
396
 *
397
 *----------------------------------------------------------------------
398
 */
399
 
400
int
401
Tk_DestroyCmd(clientData, interp, argc, argv)
402
    ClientData clientData;              /* Main window associated with
403
                                 * interpreter. */
404
    Tcl_Interp *interp;         /* Current interpreter. */
405
    int argc;                   /* Number of arguments. */
406
    char **argv;                /* Argument strings. */
407
{
408
    Tk_Window window;
409
    Tk_Window tkwin = (Tk_Window) clientData;
410
    int i;
411
 
412
    for (i = 1; i < argc; i++) {
413
        window = Tk_NameToWindow(interp, argv[i], tkwin);
414
        if (window == NULL) {
415
            Tcl_ResetResult(interp);
416
            continue;
417
        }
418
        Tk_DestroyWindow(window);
419
        if (window == tkwin) {
420
            /*
421
             * We just deleted the main window for the application! This
422
             * makes it impossible to do anything more (tkwin isn't
423
             * valid anymore).
424
             */
425
 
426
            break;
427
         }
428
    }
429
    return TCL_OK;
430
}
431
 
432
/*
433
 *----------------------------------------------------------------------
434
 *
435
 * Tk_LowerCmd --
436
 *
437
 *      This procedure is invoked to process the "lower" Tcl command.
438
 *      See the user documentation for details on what it does.
439
 *
440
 * Results:
441
 *      A standard Tcl result.
442
 *
443
 * Side effects:
444
 *      See the user documentation.
445
 *
446
 *----------------------------------------------------------------------
447
 */
448
 
449
        /* ARGSUSED */
450
int
451
Tk_LowerCmd(clientData, interp, argc, argv)
452
    ClientData clientData;      /* Main window associated with
453
                                 * interpreter. */
454
    Tcl_Interp *interp;         /* Current interpreter. */
455
    int argc;                   /* Number of arguments. */
456
    char **argv;                /* Argument strings. */
457
{
458
    Tk_Window mainwin = (Tk_Window) clientData;
459
    Tk_Window tkwin, other;
460
 
461
    if ((argc != 2) && (argc != 3)) {
462
        Tcl_AppendResult(interp, "wrong # args: should be \"",
463
                argv[0], " window ?belowThis?\"", (char *) NULL);
464
        return TCL_ERROR;
465
    }
466
 
467
    tkwin = Tk_NameToWindow(interp, argv[1], mainwin);
468
    if (tkwin == NULL) {
469
        return TCL_ERROR;
470
    }
471
    if (argc == 2) {
472
        other = NULL;
473
    } else {
474
        other = Tk_NameToWindow(interp, argv[2], mainwin);
475
        if (other == NULL) {
476
            return TCL_ERROR;
477
        }
478
    }
479
    if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) {
480
        Tcl_AppendResult(interp, "can't lower \"", argv[1], "\" below \"",
481
                argv[2], "\"", (char *) NULL);
482
        return TCL_ERROR;
483
    }
484
    return TCL_OK;
485
}
486
 
487
/*
488
 *----------------------------------------------------------------------
489
 *
490
 * Tk_RaiseCmd --
491
 *
492
 *      This procedure is invoked to process the "raise" Tcl command.
493
 *      See the user documentation for details on what it does.
494
 *
495
 * Results:
496
 *      A standard Tcl result.
497
 *
498
 * Side effects:
499
 *      See the user documentation.
500
 *
501
 *----------------------------------------------------------------------
502
 */
503
 
504
        /* ARGSUSED */
505
int
506
Tk_RaiseCmd(clientData, interp, argc, argv)
507
    ClientData clientData;      /* Main window associated with
508
                                 * interpreter. */
509
    Tcl_Interp *interp;         /* Current interpreter. */
510
    int argc;                   /* Number of arguments. */
511
    char **argv;                /* Argument strings. */
512
{
513
    Tk_Window mainwin = (Tk_Window) clientData;
514
    Tk_Window tkwin, other;
515
 
516
    if ((argc != 2) && (argc != 3)) {
517
        Tcl_AppendResult(interp, "wrong # args: should be \"",
518
                argv[0], " window ?aboveThis?\"", (char *) NULL);
519
        return TCL_ERROR;
520
    }
521
 
522
    tkwin = Tk_NameToWindow(interp, argv[1], mainwin);
523
    if (tkwin == NULL) {
524
        return TCL_ERROR;
525
    }
526
    if (argc == 2) {
527
        other = NULL;
528
    } else {
529
        other = Tk_NameToWindow(interp, argv[2], mainwin);
530
        if (other == NULL) {
531
            return TCL_ERROR;
532
        }
533
    }
534
    if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) {
535
        Tcl_AppendResult(interp, "can't raise \"", argv[1], "\" above \"",
536
                argv[2], "\"", (char *) NULL);
537
        return TCL_ERROR;
538
    }
539
    return TCL_OK;
540
}
541
 
542
/*
543
 *----------------------------------------------------------------------
544
 *
545
 * Tk_TkObjCmd --
546
 *
547
 *      This procedure is invoked to process the "tk" Tcl command.
548
 *      See the user documentation for details on what it does.
549
 *
550
 * Results:
551
 *      A standard Tcl result.
552
 *
553
 * Side effects:
554
 *      See the user documentation.
555
 *
556
 *----------------------------------------------------------------------
557
 */
558
 
559
int
560
Tk_TkObjCmd(clientData, interp, objc, objv)
561
    ClientData clientData;      /* Main window associated with interpreter. */
562
    Tcl_Interp *interp;         /* Current interpreter. */
563
    int objc;                   /* Number of arguments. */
564
    Tcl_Obj *CONST objv[];      /* Argument objects. */
565
{
566
    int index;
567
    Tk_Window tkwin;
568
    static char *optionStrings[] = {
569
        "appname",      "scaling",      NULL
570
    };
571
    enum options {
572
        TK_APPNAME,     TK_SCALING
573
    };
574
 
575
    tkwin = (Tk_Window) clientData;
576
 
577
    if (objc < 2) {
578
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
579
        return TCL_ERROR;
580
    }
581
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
582
            &index) != TCL_OK) {
583
        return TCL_ERROR;
584
    }
585
 
586
    switch ((enum options) index) {
587
        case TK_APPNAME: {
588
            TkWindow *winPtr;
589
            char *string;
590
 
591
            winPtr = (TkWindow *) tkwin;
592
 
593
            if (objc > 3) {
594
                Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
595
                return TCL_ERROR;
596
            }
597
            if (objc == 3) {
598
                string = Tcl_GetStringFromObj(objv[2], NULL);
599
                winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
600
            }
601
            Tcl_SetStringObj(Tcl_GetObjResult(interp), winPtr->nameUid, -1);
602
            break;
603
        }
604
        case TK_SCALING: {
605
            Screen *screenPtr;
606
            int skip, width, height;
607
            double d;
608
 
609
            screenPtr = Tk_Screen(tkwin);
610
 
611
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
612
            if (skip < 0) {
613
                return TCL_ERROR;
614
            }
615
            if (objc - skip == 2) {
616
                d = 25.4 / 72;
617
                d *= WidthOfScreen(screenPtr);
618
                d /= WidthMMOfScreen(screenPtr);
619
                Tcl_SetDoubleObj(Tcl_GetObjResult(interp), d);
620
            } else if (objc - skip == 3) {
621
                if (Tcl_GetDoubleFromObj(interp, objv[2 + skip], &d) != TCL_OK) {
622
                    return TCL_ERROR;
623
                }
624
                d = (25.4 / 72) / d;
625
                width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
626
                if (width <= 0) {
627
                    width = 1;
628
                }
629
                height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
630
                if (height <= 0) {
631
                    height = 1;
632
                }
633
                WidthMMOfScreen(screenPtr) = width;
634
                HeightMMOfScreen(screenPtr) = height;
635
            } else {
636
                Tcl_WrongNumArgs(interp, 2, objv,
637
                        "?-displayof window? ?factor?");
638
                return TCL_ERROR;
639
            }
640
            break;
641
        }
642
    }
643
    return TCL_OK;
644
}
645
 
646
/*
647
 *----------------------------------------------------------------------
648
 *
649
 * Tk_TkwaitCmd --
650
 *
651
 *      This procedure is invoked to process the "tkwait" Tcl command.
652
 *      See the user documentation for details on what it does.
653
 *
654
 * Results:
655
 *      A standard Tcl result.
656
 *
657
 * Side effects:
658
 *      See the user documentation.
659
 *
660
 *----------------------------------------------------------------------
661
 */
662
 
663
        /* ARGSUSED */
664
int
665
Tk_TkwaitCmd(clientData, interp, argc, argv)
666
    ClientData clientData;      /* Main window associated with
667
                                 * interpreter. */
668
    Tcl_Interp *interp;         /* Current interpreter. */
669
    int argc;                   /* Number of arguments. */
670
    char **argv;                /* Argument strings. */
671
{
672
    Tk_Window tkwin = (Tk_Window) clientData;
673
    int c, done;
674
    size_t length;
675
 
676
    if (argc != 3) {
677
        Tcl_AppendResult(interp, "wrong # args: should be \"",
678
                argv[0], " variable|visibility|window name\"", (char *) NULL);
679
        return TCL_ERROR;
680
    }
681
    c = argv[1][0];
682
    length = strlen(argv[1]);
683
    if ((c == 'v') && (strncmp(argv[1], "variable", length) == 0)
684
            && (length >= 2)) {
685
        if (Tcl_TraceVar(interp, argv[2],
686
                TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
687
                WaitVariableProc, (ClientData) &done) != TCL_OK) {
688
            return TCL_ERROR;
689
        }
690
        done = 0;
691
        while (!done) {
692
            Tcl_DoOneEvent(0);
693
        }
694
        Tcl_UntraceVar(interp, argv[2],
695
                TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
696
                WaitVariableProc, (ClientData) &done);
697
    } else if ((c == 'v') && (strncmp(argv[1], "visibility", length) == 0)
698
            && (length >= 2)) {
699
        Tk_Window window;
700
 
701
        window = Tk_NameToWindow(interp, argv[2], tkwin);
702
        if (window == NULL) {
703
            return TCL_ERROR;
704
        }
705
        Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask,
706
            WaitVisibilityProc, (ClientData) &done);
707
        done = 0;
708
        while (!done) {
709
            Tcl_DoOneEvent(0);
710
        }
711
        if (done != 1) {
712
            /*
713
             * Note that we do not delete the event handler because it
714
             * was deleted automatically when the window was destroyed.
715
             */
716
 
717
            Tcl_ResetResult(interp);
718
            Tcl_AppendResult(interp, "window \"", argv[2],
719
                    "\" was deleted before its visibility changed",
720
                    (char *) NULL);
721
            return TCL_ERROR;
722
        }
723
        Tk_DeleteEventHandler(window, VisibilityChangeMask|StructureNotifyMask,
724
            WaitVisibilityProc, (ClientData) &done);
725
    } else if ((c == 'w') && (strncmp(argv[1], "window", length) == 0)) {
726
        Tk_Window window;
727
 
728
        window = Tk_NameToWindow(interp, argv[2], tkwin);
729
        if (window == NULL) {
730
            return TCL_ERROR;
731
        }
732
        Tk_CreateEventHandler(window, StructureNotifyMask,
733
            WaitWindowProc, (ClientData) &done);
734
        done = 0;
735
        while (!done) {
736
            Tcl_DoOneEvent(0);
737
        }
738
        /*
739
         * Note:  there's no need to delete the event handler.  It was
740
         * deleted automatically when the window was destroyed.
741
         */
742
    } else {
743
        Tcl_AppendResult(interp, "bad option \"", argv[1],
744
                "\": must be variable, visibility, or window", (char *) NULL);
745
        return TCL_ERROR;
746
    }
747
 
748
    /*
749
     * Clear out the interpreter's result, since it may have been set
750
     * by event handlers.
751
     */
752
 
753
    Tcl_ResetResult(interp);
754
    return TCL_OK;
755
}
756
 
757
        /* ARGSUSED */
758
static char *
759
WaitVariableProc(clientData, interp, name1, name2, flags)
760
    ClientData clientData;      /* Pointer to integer to set to 1. */
761
    Tcl_Interp *interp;         /* Interpreter containing variable. */
762
    char *name1;                /* Name of variable. */
763
    char *name2;                /* Second part of variable name. */
764
    int flags;                  /* Information about what happened. */
765
{
766
    int *donePtr = (int *) clientData;
767
 
768
    *donePtr = 1;
769
    return (char *) NULL;
770
}
771
 
772
        /*ARGSUSED*/
773
static void
774
WaitVisibilityProc(clientData, eventPtr)
775
    ClientData clientData;      /* Pointer to integer to set to 1. */
776
    XEvent *eventPtr;           /* Information about event (not used). */
777
{
778
    int *donePtr = (int *) clientData;
779
 
780
    if (eventPtr->type == VisibilityNotify) {
781
        *donePtr = 1;
782
    }
783
    if (eventPtr->type == DestroyNotify) {
784
        *donePtr = 2;
785
    }
786
}
787
 
788
static void
789
WaitWindowProc(clientData, eventPtr)
790
    ClientData clientData;      /* Pointer to integer to set to 1. */
791
    XEvent *eventPtr;           /* Information about event. */
792
{
793
    int *donePtr = (int *) clientData;
794
 
795
    if (eventPtr->type == DestroyNotify) {
796
        *donePtr = 1;
797
    }
798
}
799
 
800
/*
801
 *----------------------------------------------------------------------
802
 *
803
 * Tk_UpdateCmd --
804
 *
805
 *      This procedure is invoked to process the "update" Tcl command.
806
 *      See the user documentation for details on what it does.
807
 *
808
 * Results:
809
 *      A standard Tcl result.
810
 *
811
 * Side effects:
812
 *      See the user documentation.
813
 *
814
 *----------------------------------------------------------------------
815
 */
816
 
817
        /* ARGSUSED */
818
int
819
Tk_UpdateCmd(clientData, interp, argc, argv)
820
    ClientData clientData;      /* Main window associated with
821
                                 * interpreter. */
822
    Tcl_Interp *interp;         /* Current interpreter. */
823
    int argc;                   /* Number of arguments. */
824
    char **argv;                /* Argument strings. */
825
{
826
    int flags;
827
    TkDisplay *dispPtr;
828
 
829
    if (argc == 1) {
830
        flags = TCL_DONT_WAIT;
831
    } else if (argc == 2) {
832
        if (strncmp(argv[1], "idletasks", strlen(argv[1])) != 0) {
833
            Tcl_AppendResult(interp, "bad option \"", argv[1],
834
                    "\": must be idletasks", (char *) NULL);
835
            return TCL_ERROR;
836
        }
837
        flags = TCL_IDLE_EVENTS;
838
    } else {
839
        Tcl_AppendResult(interp, "wrong # args: should be \"",
840
                argv[0], " ?idletasks?\"", (char *) NULL);
841
        return TCL_ERROR;
842
    }
843
 
844
    /*
845
     * Handle all pending events, sync all displays, and repeat over
846
     * and over again until all pending events have been handled.
847
     * Special note:  it's possible that the entire application could
848
     * be destroyed by an event handler that occurs during the update.
849
     * Thus, don't use any information from tkwin after calling
850
     * Tcl_DoOneEvent.
851
     */
852
 
853
    while (1) {
854
        while (Tcl_DoOneEvent(flags) != 0) {
855
            /* Empty loop body */
856
        }
857
        for (dispPtr = tkDisplayList; dispPtr != NULL;
858
                dispPtr = dispPtr->nextPtr) {
859
            XSync(dispPtr->display, False);
860
        }
861
        if (Tcl_DoOneEvent(flags) == 0) {
862
            break;
863
        }
864
    }
865
 
866
    /*
867
     * Must clear the interpreter's result because event handlers could
868
     * have executed commands.
869
     */
870
 
871
    Tcl_ResetResult(interp);
872
    return TCL_OK;
873
}
874
 
875
/*
876
 *----------------------------------------------------------------------
877
 *
878
 * Tk_WinfoObjCmd --
879
 *
880
 *      This procedure is invoked to process the "winfo" Tcl command.
881
 *      See the user documentation for details on what it does.
882
 *
883
 * Results:
884
 *      A standard Tcl result.
885
 *
886
 * Side effects:
887
 *      See the user documentation.
888
 *
889
 *----------------------------------------------------------------------
890
 */
891
 
892
int
893
Tk_WinfoObjCmd(clientData, interp, objc, objv)
894
    ClientData clientData;      /* Main window associated with
895
                                 * interpreter. */
896
    Tcl_Interp *interp;         /* Current interpreter. */
897
    int objc;                   /* Number of arguments. */
898
    Tcl_Obj *CONST objv[];      /* Argument objects. */
899
{
900
    int index, x, y, width, height, useX, useY, class, skip;
901
    char buf[128];
902
    char *string;
903
    TkWindow *winPtr;
904
    Tk_Window tkwin;
905
 
906
    static TkStateMap visualMap[] = {
907
        {PseudoColor,   "pseudocolor"},
908
        {GrayScale,     "grayscale"},
909
        {DirectColor,   "directcolor"},
910
        {TrueColor,     "truecolor"},
911
        {StaticColor,   "staticcolor"},
912
        {StaticGray,    "staticgray"},
913
        {-1,            NULL}
914
    };
915
    static char *optionStrings[] = {
916
        "cells",        "children",     "class",        "colormapfull",
917
        "depth",        "geometry",     "height",       "id",
918
        "ismapped",     "manager",      "name",         "parent",
919
        "pointerx",     "pointery",     "pointerxy",    "reqheight",
920
        "reqwidth",     "rootx",        "rooty",        "screen",
921
        "screencells",  "screendepth",  "screenheight", "screenwidth",
922
        "screenmmheight","screenmmwidth","screenvisual","server",
923
        "toplevel",     "viewable",     "visual",       "visualid",
924
        "vrootheight",  "vrootwidth",   "vrootx",       "vrooty",
925
        "width",        "x",            "y",
926
 
927
        "atom",         "atomname",     "containing",   "interps",
928
        "pathname",
929
 
930
        "exists",       "fpixels",      "pixels",       "rgb",
931
        "visualsavailable",
932
 
933
        NULL
934
    };
935
    enum options {
936
        WIN_CELLS,      WIN_CHILDREN,   WIN_CLASS,      WIN_COLORMAPFULL,
937
        WIN_DEPTH,      WIN_GEOMETRY,   WIN_HEIGHT,     WIN_ID,
938
        WIN_ISMAPPED,   WIN_MANAGER,    WIN_NAME,       WIN_PARENT,
939
        WIN_POINTERX,   WIN_POINTERY,   WIN_POINTERXY,  WIN_REQHEIGHT,
940
        WIN_REQWIDTH,   WIN_ROOTX,      WIN_ROOTY,      WIN_SCREEN,
941
        WIN_SCREENCELLS,WIN_SCREENDEPTH,WIN_SCREENHEIGHT,WIN_SCREENWIDTH,
942
        WIN_SCREENMMHEIGHT,WIN_SCREENMMWIDTH,WIN_SCREENVISUAL,WIN_SERVER,
943
        WIN_TOPLEVEL,   WIN_VIEWABLE,   WIN_VISUAL,     WIN_VISUALID,
944
        WIN_VROOTHEIGHT,WIN_VROOTWIDTH, WIN_VROOTX,     WIN_VROOTY,
945
        WIN_WIDTH,      WIN_X,          WIN_Y,
946
 
947
        WIN_ATOM,       WIN_ATOMNAME,   WIN_CONTAINING, WIN_INTERPS,
948
        WIN_PATHNAME,
949
 
950
        WIN_EXISTS,     WIN_FPIXELS,    WIN_PIXELS,     WIN_RGB,
951
        WIN_VISUALSAVAILABLE
952
    };
953
 
954
    tkwin = (Tk_Window) clientData;
955
 
956
    if (objc < 2) {
957
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
958
        return TCL_ERROR;
959
    }
960
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
961
            &index) != TCL_OK) {
962
        return TCL_ERROR;
963
    }
964
 
965
    if (index < WIN_ATOM) {
966
        if (objc != 3) {
967
            Tcl_WrongNumArgs(interp, 2, objv, "window");
968
            return TCL_ERROR;
969
        }
970
        string = Tcl_GetStringFromObj(objv[2], NULL);
971
        tkwin = Tk_NameToWindow(interp, string, tkwin);
972
        if (tkwin == NULL) {
973
            return TCL_ERROR;
974
        }
975
    }
976
    winPtr = (TkWindow *) tkwin;
977
 
978
    switch ((enum options) index) {
979
        case WIN_CELLS: {
980
            Tcl_ResetResult(interp);
981
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
982
                    Tk_Visual(tkwin)->map_entries);
983
            break;
984
        }
985
        case WIN_CHILDREN: {
986
            Tcl_Obj *strPtr;
987
 
988
            Tcl_ResetResult(interp);
989
            winPtr = winPtr->childList;
990
            for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
991
                strPtr = Tcl_NewStringObj(winPtr->pathName, -1);
992
                Tcl_ListObjAppendElement(NULL,
993
                     Tcl_GetObjResult(interp), strPtr);
994
            }
995
            break;
996
        }
997
        case WIN_CLASS: {
998
            Tcl_ResetResult(interp);
999
            Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_Class(tkwin), -1);
1000
            break;
1001
        }
1002
        case WIN_COLORMAPFULL: {
1003
            Tcl_ResetResult(interp);
1004
            Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
1005
                    TkpCmapStressed(tkwin, Tk_Colormap(tkwin)));
1006
            break;
1007
        }
1008
        case WIN_DEPTH: {
1009
            Tcl_ResetResult(interp);
1010
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Depth(tkwin));
1011
            break;
1012
        }
1013
        case WIN_GEOMETRY: {
1014
            Tcl_ResetResult(interp);
1015
            sprintf(buf, "%dx%d+%d+%d", Tk_Width(tkwin), Tk_Height(tkwin),
1016
                    Tk_X(tkwin), Tk_Y(tkwin));
1017
            Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1);
1018
            break;
1019
        }
1020
        case WIN_HEIGHT: {
1021
            Tcl_ResetResult(interp);
1022
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Height(tkwin));
1023
            break;
1024
        }
1025
        case WIN_ID: {
1026
            Tk_MakeWindowExist(tkwin);
1027
            TkpPrintWindowId(buf, Tk_WindowId(tkwin));
1028
            Tcl_ResetResult(interp);
1029
            Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1);
1030
            break;
1031
        }
1032
        case WIN_ISMAPPED: {
1033
            Tcl_ResetResult(interp);
1034
            Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
1035
                    (int) Tk_IsMapped(tkwin));
1036
            break;
1037
        }
1038
        case WIN_MANAGER: {
1039
            Tcl_ResetResult(interp);
1040
            if (winPtr->geomMgrPtr != NULL) {
1041
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1042
                        winPtr->geomMgrPtr->name, -1);
1043
            }
1044
            break;
1045
        }
1046
        case WIN_NAME: {
1047
            Tcl_ResetResult(interp);
1048
            Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_Name(tkwin), -1);
1049
            break;
1050
        }
1051
        case WIN_PARENT: {
1052
            Tcl_ResetResult(interp);
1053
            if (winPtr->parentPtr != NULL) {
1054
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1055
                        winPtr->parentPtr->pathName, -1);
1056
            }
1057
            break;
1058
        }
1059
        case WIN_POINTERX: {
1060
            useX = 1;
1061
            useY = 0;
1062
            goto pointerxy;
1063
        }
1064
        case WIN_POINTERY: {
1065
            useX = 0;
1066
            useY = 1;
1067
            goto pointerxy;
1068
        }
1069
        case WIN_POINTERXY: {
1070
            useX = 1;
1071
            useY = 1;
1072
 
1073
            pointerxy:
1074
            winPtr = GetToplevel(tkwin);
1075
            if (winPtr == NULL) {
1076
                x = -1;
1077
                y = -1;
1078
            } else {
1079
                TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
1080
            }
1081
            Tcl_ResetResult(interp);
1082
            if (useX & useY) {
1083
                sprintf(buf, "%d %d", x, y);
1084
                Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1);
1085
            } else if (useX) {
1086
                Tcl_SetIntObj(Tcl_GetObjResult(interp), x);
1087
            } else {
1088
                Tcl_SetIntObj(Tcl_GetObjResult(interp), y);
1089
            }
1090
            break;
1091
        }
1092
        case WIN_REQHEIGHT: {
1093
            Tcl_ResetResult(interp);
1094
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_ReqHeight(tkwin));
1095
            break;
1096
        }
1097
        case WIN_REQWIDTH: {
1098
            Tcl_ResetResult(interp);
1099
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_ReqWidth(tkwin));
1100
            break;
1101
        }
1102
        case WIN_ROOTX: {
1103
            Tk_GetRootCoords(tkwin, &x, &y);
1104
            Tcl_ResetResult(interp);
1105
            Tcl_SetIntObj(Tcl_GetObjResult(interp), x);
1106
            break;
1107
        }
1108
        case WIN_ROOTY: {
1109
            Tk_GetRootCoords(tkwin, &x, &y);
1110
            Tcl_ResetResult(interp);
1111
            Tcl_SetIntObj(Tcl_GetObjResult(interp), y);
1112
            break;
1113
        }
1114
        case WIN_SCREEN: {
1115
            sprintf(buf, "%d", Tk_ScreenNumber(tkwin));
1116
            Tcl_ResetResult(interp);
1117
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1118
                    Tk_DisplayName(tkwin), ".", buf, NULL);
1119
            break;
1120
        }
1121
        case WIN_SCREENCELLS: {
1122
            Tcl_ResetResult(interp);
1123
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1124
                    CellsOfScreen(Tk_Screen(tkwin)));
1125
            break;
1126
        }
1127
        case WIN_SCREENDEPTH: {
1128
            Tcl_ResetResult(interp);
1129
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1130
                    DefaultDepthOfScreen(Tk_Screen(tkwin)));
1131
            break;
1132
        }
1133
        case WIN_SCREENHEIGHT: {
1134
            Tcl_ResetResult(interp);
1135
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1136
                    HeightOfScreen(Tk_Screen(tkwin)));
1137
            break;
1138
        }
1139
        case WIN_SCREENWIDTH: {
1140
            Tcl_ResetResult(interp);
1141
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1142
                    WidthOfScreen(Tk_Screen(tkwin)));
1143
            break;
1144
        }
1145
        case WIN_SCREENMMHEIGHT: {
1146
            Tcl_ResetResult(interp);
1147
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1148
                    HeightMMOfScreen(Tk_Screen(tkwin)));
1149
            break;
1150
        }
1151
        case WIN_SCREENMMWIDTH: {
1152
            Tcl_ResetResult(interp);
1153
            Tcl_SetIntObj(Tcl_GetObjResult(interp),
1154
                    WidthMMOfScreen(Tk_Screen(tkwin)));
1155
            break;
1156
        }
1157
        case WIN_SCREENVISUAL: {
1158
            class = DefaultVisualOfScreen(Tk_Screen(tkwin))->class;
1159
            goto visual;
1160
        }
1161
        case WIN_SERVER: {
1162
            TkGetServerInfo(interp, tkwin);
1163
            break;
1164
        }
1165
        case WIN_TOPLEVEL: {
1166
            winPtr = GetToplevel(tkwin);
1167
            if (winPtr != NULL) {
1168
                Tcl_ResetResult(interp);
1169
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1170
                        winPtr->pathName, -1);
1171
            }
1172
            break;
1173
        }
1174
        case WIN_VIEWABLE: {
1175
            int viewable;
1176
 
1177
            viewable = 0;
1178
            for ( ; ; winPtr = winPtr->parentPtr) {
1179
                if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {
1180
                    break;
1181
                }
1182
                if (winPtr->flags & TK_TOP_LEVEL) {
1183
                    viewable = 1;
1184
                    break;
1185
                }
1186
            }
1187
            Tcl_ResetResult(interp);
1188
            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), viewable);
1189
            break;
1190
        }
1191
        case WIN_VISUAL: {
1192
            class = Tk_Visual(tkwin)->class;
1193
 
1194
            visual:
1195
            string = TkFindStateString(visualMap, class);
1196
            if (string == NULL) {
1197
                string = "unknown";
1198
            }
1199
            Tcl_ResetResult(interp);
1200
            Tcl_SetStringObj(Tcl_GetObjResult(interp), string, -1);
1201
            break;
1202
        }
1203
        case WIN_VISUALID: {
1204
            Tcl_ResetResult(interp);
1205
            sprintf(buf, "0x%x",
1206
                    (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin)));
1207
            Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1);
1208
            break;
1209
        }
1210
        case WIN_VROOTHEIGHT: {
1211
            Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1212
            Tcl_ResetResult(interp);
1213
            Tcl_SetIntObj(Tcl_GetObjResult(interp), height);
1214
            break;
1215
        }
1216
        case WIN_VROOTWIDTH: {
1217
            Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1218
            Tcl_ResetResult(interp);
1219
            Tcl_SetIntObj(Tcl_GetObjResult(interp), width);
1220
            break;
1221
        }
1222
        case WIN_VROOTX: {
1223
            Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1224
            Tcl_ResetResult(interp);
1225
            Tcl_SetIntObj(Tcl_GetObjResult(interp), x);
1226
            break;
1227
        }
1228
        case WIN_VROOTY: {
1229
            Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1230
            Tcl_ResetResult(interp);
1231
            Tcl_SetIntObj(Tcl_GetObjResult(interp), y);
1232
            break;
1233
        }
1234
        case WIN_WIDTH: {
1235
            Tcl_ResetResult(interp);
1236
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Width(tkwin));
1237
            break;
1238
        }
1239
        case WIN_X: {
1240
            Tcl_ResetResult(interp);
1241
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_X(tkwin));
1242
            break;
1243
        }
1244
        case WIN_Y: {
1245
            Tcl_ResetResult(interp);
1246
            Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Y(tkwin));
1247
            break;
1248
        }
1249
 
1250
        /*
1251
         * Uses -displayof.
1252
         */
1253
 
1254
        case WIN_ATOM: {
1255
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1256
            if (skip < 0) {
1257
                return TCL_ERROR;
1258
            }
1259
            if (objc - skip != 3) {
1260
                Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
1261
                return TCL_ERROR;
1262
            }
1263
            objv += skip;
1264
            string = Tcl_GetStringFromObj(objv[2], NULL);
1265
            Tcl_ResetResult(interp);
1266
            Tcl_SetLongObj(Tcl_GetObjResult(interp),
1267
                    (long) Tk_InternAtom(tkwin, string));
1268
            break;
1269
        }
1270
        case WIN_ATOMNAME: {
1271
            char *name;
1272
            long id;
1273
 
1274
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1275
            if (skip < 0) {
1276
                return TCL_ERROR;
1277
            }
1278
            if (objc - skip != 3) {
1279
                Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
1280
                return TCL_ERROR;
1281
            }
1282
            objv += skip;
1283
            if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) {
1284
                return TCL_ERROR;
1285
            }
1286
            Tcl_ResetResult(interp);
1287
            name = Tk_GetAtomName(tkwin, (Atom) id);
1288
            if (strcmp(name, "?bad atom?") == 0) {
1289
                string = Tcl_GetStringFromObj(objv[2], NULL);
1290
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1291
                        "no atom exists with id \"", string, "\"", NULL);
1292
                return TCL_ERROR;
1293
            }
1294
            Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1);
1295
            break;
1296
        }
1297
        case WIN_CONTAINING: {
1298
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1299
            if (skip < 0) {
1300
                return TCL_ERROR;
1301
            }
1302
            if (objc - skip != 4) {
1303
                Tcl_WrongNumArgs(interp, 2, objv,
1304
                        "?-displayof window? rootX rootY");
1305
                return TCL_ERROR;
1306
            }
1307
            objv += skip;
1308
            string = Tcl_GetStringFromObj(objv[2], NULL);
1309
            if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
1310
                return TCL_ERROR;
1311
            }
1312
            string = Tcl_GetStringFromObj(objv[3], NULL);
1313
            if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
1314
                return TCL_ERROR;
1315
            }
1316
            tkwin = Tk_CoordsToWindow(x, y, tkwin);
1317
            if (tkwin != NULL) {
1318
                Tcl_ResetResult(interp);
1319
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1320
                        Tk_PathName(tkwin), -1);
1321
            }
1322
            break;
1323
        }
1324
        case WIN_INTERPS: {
1325
            int result;
1326
 
1327
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1328
            if (skip < 0) {
1329
                return TCL_ERROR;
1330
            }
1331
            if (objc - skip != 2) {
1332
                Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
1333
                return TCL_ERROR;
1334
            }
1335
            result = TkGetInterpNames(interp, tkwin);
1336
            return result;
1337
        }
1338
        case WIN_PATHNAME: {
1339
            int id;
1340
 
1341
            skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1342
            if (skip < 0) {
1343
                return TCL_ERROR;
1344
            }
1345
            if (objc - skip != 3) {
1346
                Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
1347
                return TCL_ERROR;
1348
            }
1349
            string = Tcl_GetStringFromObj(objv[2 + skip], NULL);
1350
            if (TkpScanWindowId(interp, string, &id) != TCL_OK) {
1351
                return TCL_ERROR;
1352
            }
1353
            winPtr = (TkWindow *)
1354
                    Tk_IdToWindow(Tk_Display(tkwin), (Window) id);
1355
            if ((winPtr == NULL) ||
1356
                    (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) {
1357
                Tcl_ResetResult(interp);
1358
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1359
                        "window id \"", string,
1360
                        "\" doesn't exist in this application", (char *) NULL);
1361
                return TCL_ERROR;
1362
            }
1363
 
1364
            /*
1365
             * If the window is a utility window with no associated path
1366
             * (such as a wrapper window or send communication window), just
1367
             * return an empty string.
1368
             */
1369
 
1370
            tkwin = (Tk_Window) winPtr;
1371
            if (Tk_PathName(tkwin) != NULL) {
1372
                Tcl_ResetResult(interp);
1373
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1374
                        Tk_PathName(tkwin), -1);
1375
            }
1376
            break;
1377
        }
1378
 
1379
        /*
1380
         * objv[3] is window.
1381
         */
1382
 
1383
        case WIN_EXISTS: {
1384
            int alive;
1385
 
1386
            if (objc != 3) {
1387
                Tcl_WrongNumArgs(interp, 2, objv, "window");
1388
                return TCL_ERROR;
1389
            }
1390
            string = Tcl_GetStringFromObj(objv[2], NULL);
1391
            winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
1392
            alive = 1;
1393
            if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) {
1394
                alive = 0;
1395
            }
1396
            Tcl_ResetResult(interp); /* clear any error msg */
1397
            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), alive);
1398
            break;
1399
        }
1400
        case WIN_FPIXELS: {
1401
            double mm, pixels;
1402
 
1403
            if (objc != 4) {
1404
                Tcl_WrongNumArgs(interp, 2, objv, "window number");
1405
                return TCL_ERROR;
1406
            }
1407
            string = Tcl_GetStringFromObj(objv[2], NULL);
1408
            tkwin = Tk_NameToWindow(interp, string, tkwin);
1409
            if (tkwin == NULL) {
1410
                return TCL_ERROR;
1411
            }
1412
            string = Tcl_GetStringFromObj(objv[3], NULL);
1413
            if (Tk_GetScreenMM(interp, tkwin, string, &mm) != TCL_OK) {
1414
                return TCL_ERROR;
1415
            }
1416
            pixels = mm * WidthOfScreen(Tk_Screen(tkwin))
1417
                / WidthMMOfScreen(Tk_Screen(tkwin));
1418
            Tcl_ResetResult(interp);
1419
            Tcl_SetDoubleObj(Tcl_GetObjResult(interp), pixels);
1420
            break;
1421
        }
1422
        case WIN_PIXELS: {
1423
            int pixels;
1424
 
1425
            if (objc != 4) {
1426
                Tcl_WrongNumArgs(interp, 2, objv, "window number");
1427
                return TCL_ERROR;
1428
            }
1429
            string = Tcl_GetStringFromObj(objv[2], NULL);
1430
            tkwin = Tk_NameToWindow(interp, string, tkwin);
1431
            if (tkwin == NULL) {
1432
                return TCL_ERROR;
1433
            }
1434
            string = Tcl_GetStringFromObj(objv[3], NULL);
1435
            if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
1436
                return TCL_ERROR;
1437
            }
1438
            Tcl_ResetResult(interp);
1439
            Tcl_SetIntObj(Tcl_GetObjResult(interp), pixels);
1440
            break;
1441
        }
1442
        case WIN_RGB: {
1443
            XColor *colorPtr;
1444
 
1445
            if (objc != 4) {
1446
                Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
1447
                return TCL_ERROR;
1448
            }
1449
            string = Tcl_GetStringFromObj(objv[2], NULL);
1450
            tkwin = Tk_NameToWindow(interp, string, tkwin);
1451
            if (tkwin == NULL) {
1452
                return TCL_ERROR;
1453
            }
1454
            string = Tcl_GetStringFromObj(objv[3], NULL);
1455
            colorPtr = Tk_GetColor(interp, tkwin, string);
1456
            if (colorPtr == NULL) {
1457
                return TCL_ERROR;
1458
            }
1459
            sprintf(buf, "%d %d %d", colorPtr->red, colorPtr->green,
1460
                    colorPtr->blue);
1461
            Tk_FreeColor(colorPtr);
1462
            Tcl_ResetResult(interp);
1463
            Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1);
1464
            break;
1465
        }
1466
        case WIN_VISUALSAVAILABLE: {
1467
            XVisualInfo template, *visInfoPtr;
1468
            int count, i;
1469
            char visualIdString[16];
1470
            int includeVisualId;
1471
            Tcl_Obj *strPtr;
1472
 
1473
            if (objc == 3) {
1474
                includeVisualId = 0;
1475
            } else if ((objc == 4)
1476
                    && (strcmp(Tcl_GetStringFromObj(objv[3], NULL),
1477
                            "includeids") == 0)) {
1478
                includeVisualId = 1;
1479
            } else {
1480
                Tcl_WrongNumArgs(interp, 2, objv, "window ?includeids?");
1481
                return TCL_ERROR;
1482
            }
1483
 
1484
            string = Tcl_GetStringFromObj(objv[2], NULL);
1485
            tkwin = Tk_NameToWindow(interp, string, tkwin);
1486
            if (tkwin == NULL) {
1487
                return TCL_ERROR;
1488
            }
1489
 
1490
            template.screen = Tk_ScreenNumber(tkwin);
1491
            visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
1492
                    &template, &count);
1493
            Tcl_ResetResult(interp);
1494
            if (visInfoPtr == NULL) {
1495
                Tcl_SetStringObj(Tcl_GetObjResult(interp),
1496
                        "can't find any visuals for screen", -1);
1497
                return TCL_ERROR;
1498
            }
1499
            for (i = 0; i < count; i++) {
1500
                string = TkFindStateString(visualMap, visInfoPtr[i].class);
1501
                if (string == NULL) {
1502
                    strcpy(buf, "unknown");
1503
                } else {
1504
                    sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
1505
                }
1506
                if (includeVisualId) {
1507
                    sprintf(visualIdString, " 0x%x",
1508
                            (unsigned int) visInfoPtr[i].visualid);
1509
                    strcat(buf, visualIdString);
1510
                }
1511
                strPtr = Tcl_NewStringObj(buf, -1);
1512
                Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
1513
                        strPtr);
1514
            }
1515
            XFree((char *) visInfoPtr);
1516
            break;
1517
        }
1518
    }
1519
    return TCL_OK;
1520
}
1521
 
1522
/*
1523
 *----------------------------------------------------------------------
1524
 *
1525
 * TkGetDisplayOf --
1526
 *
1527
 *      Parses a "-displayof window" option for various commands.  If
1528
 *      present, the literal "-displayof" should be in objv[0] and the
1529
 *      window name in objv[1].
1530
 *
1531
 * Results:
1532
 *      The return value is 0 if the argument strings did not contain
1533
 *      the "-displayof" option.  The return value is 2 if the
1534
 *      argument strings contained both the "-displayof" option and
1535
 *      a valid window name.  Otherwise, the return value is -1 if
1536
 *      the window name was missing or did not specify a valid window.
1537
 *
1538
 *      If the return value was 2, *tkwinPtr is filled with the
1539
 *      token for the window specified on the command line.  If the
1540
 *      return value was -1, an error message is left in interp's
1541
 *      result object.
1542
 *
1543
 * Side effects:
1544
 *      None.
1545
 *
1546
 *----------------------------------------------------------------------
1547
 */
1548
 
1549
int
1550
TkGetDisplayOf(interp, objc, objv, tkwinPtr)
1551
    Tcl_Interp *interp;         /* Interpreter for error reporting. */
1552
    int objc;                   /* Number of arguments. */
1553
    Tcl_Obj *CONST objv[];      /* Argument objects. If it is present,
1554
                                 * "-displayof" should be in objv[0] and
1555
                                 * objv[1] the name of a window. */
1556
    Tk_Window *tkwinPtr;        /* On input, contains main window of
1557
                                 * application associated with interp.  On
1558
                                 * output, filled with window specified as
1559
                                 * option to "-displayof" argument, or
1560
                                 * unmodified if "-displayof" argument was not
1561
                                 * present. */
1562
{
1563
    char *string;
1564
    int length;
1565
 
1566
    if (objc < 1) {
1567
        return 0;
1568
    }
1569
    string = Tcl_GetStringFromObj(objv[0], &length);
1570
    if ((length >= 2) && (strncmp(string, "-displayof", (unsigned) length) == 0)) {
1571
        if (objc < 2) {
1572
            Tcl_SetStringObj(Tcl_GetObjResult(interp),
1573
                    "value for \"-displayof\" missing", -1);
1574
            return -1;
1575
        }
1576
        string = Tcl_GetStringFromObj(objv[1], NULL);
1577
        *tkwinPtr = Tk_NameToWindow(interp, string, *tkwinPtr);
1578
        if (*tkwinPtr == NULL) {
1579
            return -1;
1580
        }
1581
        return 2;
1582
    }
1583
    return 0;
1584
}
1585
 
1586
/*
1587
 *----------------------------------------------------------------------
1588
 *
1589
 * TkDeadAppCmd --
1590
 *
1591
 *      If an application has been deleted then all Tk commands will be
1592
 *      re-bound to this procedure.
1593
 *
1594
 * Results:
1595
 *      A standard Tcl error is reported to let the user know that
1596
 *      the application is dead.
1597
 *
1598
 * Side effects:
1599
 *      See the user documentation.
1600
 *
1601
 *----------------------------------------------------------------------
1602
 */
1603
 
1604
        /* ARGSUSED */
1605
int
1606
TkDeadAppCmd(clientData, interp, argc, argv)
1607
    ClientData clientData;      /* Dummy. */
1608
    Tcl_Interp *interp;         /* Current interpreter. */
1609
    int argc;                   /* Number of arguments. */
1610
    char **argv;                /* Argument strings. */
1611
{
1612
    Tcl_AppendResult(interp, "can't invoke \"", argv[0],
1613
            "\" command:  application has been destroyed", (char *) NULL);
1614
    return TCL_ERROR;
1615
}
1616
 
1617
/*
1618
 *----------------------------------------------------------------------
1619
 *
1620
 * GetToplevel --
1621
 *
1622
 *      Retrieves the toplevel window which is the nearest ancestor of
1623
 *      of the specified window.
1624
 *
1625
 * Results:
1626
 *      Returns the toplevel window or NULL if the window has no
1627
 *      ancestor which is a toplevel.
1628
 *
1629
 * Side effects:
1630
 *      None.
1631
 *
1632
 *----------------------------------------------------------------------
1633
 */
1634
 
1635
static TkWindow *
1636
GetToplevel(tkwin)
1637
    Tk_Window tkwin;            /* Window for which the toplevel should be
1638
                                 * deterined. */
1639
{
1640
     TkWindow *winPtr = (TkWindow *) tkwin;
1641
 
1642
     while (!(winPtr->flags & TK_TOP_LEVEL)) {
1643
         winPtr = winPtr->parentPtr;
1644
         if (winPtr == NULL) {
1645
             return NULL;
1646
         }
1647
     }
1648
     return winPtr;
1649
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.