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