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-1997 Sun Microsystems, Inc.
9 * Copyright (c) 2000 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.31 2002/09/02 19:16:23 hobbs Exp $
15 */
16
17 #include "tkPort.h"
18 #include "tkInt.h"
19 #include <errno.h>
20
21 #if defined(WIN32)
22 #include "tkWinInt.h"
23 #else
24 #if defined(MAC_TCL)
25 #include "tkMacInt.h"
26 #elif defined(MAC_OSX_TK)
27 #include "tkMacOSXInt.h"
28 #else
29 #include "tkUnixInt.h"
30 #endif
31 #endif
32 /*
33 * Forward declarations for procedures defined later in this file:
34 */
35
36 static TkWindow * GetToplevel _ANSI_ARGS_((Tk_Window tkwin));
37 static char * WaitVariableProc _ANSI_ARGS_((ClientData clientData,
38 Tcl_Interp *interp, Var name1,
39 CONST char *name2, int flags));
40 static void WaitVisibilityProc _ANSI_ARGS_((ClientData clientData,
41 XEvent *eventPtr));
42 static void WaitWindowProc _ANSI_ARGS_((ClientData clientData,
43 XEvent *eventPtr));
44
45 /*
46 *----------------------------------------------------------------------
47 *
48 * Tk_BellObjCmd --
49 *
50 * This procedure is invoked to process the "bell" Tcl command.
51 * See the user documentation for details on what it does.
52 *
53 * Results:
54 * A standard Tcl result.
55 *
56 * Side effects:
57 * See the user documentation.
58 *
59 *----------------------------------------------------------------------
60 */
61
62 int
Tk_BellObjCmd(clientData,interp,objc,objv)63 Tk_BellObjCmd(clientData, interp, objc, objv)
64 ClientData clientData; /* Main window associated with interpreter. */
65 Tcl_Interp *interp; /* Current interpreter. */
66 int objc; /* Number of arguments. */
67 Tcl_Obj *CONST objv[]; /* Argument objects. */
68 {
69 static CONST char *bellOptions[] = {"-displayof", "-nice", (char *) NULL};
70 enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
71 Tk_Window tkwin = (Tk_Window) clientData;
72 int i, index, nice = 0;
73
74 if (objc > 4) {
75 Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
76 return TCL_ERROR;
77 }
78
79 for (i = 1; i < objc; i++) {
80 if (Tcl_GetIndexFromObj(interp, objv[i], bellOptions, "option", 0,
81 &index) != TCL_OK) {
82 return TCL_ERROR;
83 }
84 switch ((enum options) index) {
85 case TK_BELL_DISPLAYOF:
86 if (++i >= objc) {
87 Tcl_WrongNumArgs(interp, 1, objv,
88 "?-displayof window? ?-nice?");
89 return TCL_ERROR;
90 }
91 tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
92 if (tkwin == NULL) {
93 return TCL_ERROR;
94 }
95 break;
96 case TK_BELL_NICE:
97 nice = 1;
98 break;
99 }
100 }
101 XBell(Tk_Display(tkwin), 0);
102 if (!nice) {
103 XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
104 }
105 XFlush(Tk_Display(tkwin));
106 return TCL_OK;
107 }
108
109 /*
110 *----------------------------------------------------------------------
111 *
112 * Tk_BindObjCmd --
113 *
114 * This procedure is invoked to process the "bind" Tcl command.
115 * See the user documentation for details on what it does.
116 *
117 * Results:
118 * A standard Tcl result.
119 *
120 * Side effects:
121 * See the user documentation.
122 *
123 *----------------------------------------------------------------------
124 */
125
126 int
Tk_BindObjCmd(clientData,interp,objc,objv)127 Tk_BindObjCmd(clientData, interp, objc, objv)
128 ClientData clientData; /* Main window associated with interpreter. */
129 Tcl_Interp *interp; /* Current interpreter. */
130 int objc; /* Number of arguments. */
131 Tcl_Obj *CONST objv[]; /* Argument objects. */
132 {
133 Tk_Window tkwin = (Tk_Window) clientData;
134 TkWindow *winPtr;
135 ClientData object;
136 char *string;
137
138 if ((objc < 2) || (objc > 4)) {
139 Tcl_WrongNumArgs(interp, 1, objv, "window ?pattern? ?command?");
140 return TCL_ERROR;
141 }
142 string = Tcl_GetString(objv[1]);
143
144 /*
145 * Bind tags either a window name or a tag name for the first argument.
146 * If the argument starts with ".", assume it is a window; otherwise, it
147 * is a tag.
148 */
149
150 if (string[0] == '.') {
151 winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
152 if (winPtr == NULL) {
153 return TCL_ERROR;
154 }
155 object = (ClientData) winPtr->pathName;
156 } else {
157 winPtr = (TkWindow *) clientData;
158 object = (ClientData) Tk_GetUid(string);
159 }
160
161 /*
162 * If there are four arguments, the command is modifying a binding. If
163 * there are three arguments, the command is querying a binding. If there
164 * are only two arguments, the command is querying all the bindings for
165 * the given tag/window.
166 */
167
168 if (objc == 4) {
169 int append = 0;
170 unsigned long mask;
171 char *sequence, *script;
172 sequence = Tcl_GetString(objv[2]);
173 script = Tcl_GetString(objv[3]);
174
175 /*
176 * If the script is null, just delete the binding.
177 */
178
179 if (script[0] == 0) {
180 return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable,
181 object, sequence);
182 }
183
184 /*
185 * If the script begins with "+", append this script to the existing
186 * binding.
187 */
188
189 if (script[0] == '+') {
190 script++;
191 append = 1;
192 }
193 mask = Tk_CreateBinding(interp, winPtr->mainPtr->bindingTable,
194 object, sequence, objv[3], append);
195 if (mask == 0) {
196 return TCL_ERROR;
197 }
198 } else if (objc == 3) {
199 Tcl_Obj *command;
200
201 command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
202 object, Tcl_GetString(objv[2]));
203 if (command == NULL) {
204 Tcl_ResetResult(interp);
205 return TCL_OK;
206 }
207 Tcl_SetObjResult(interp,command);
208 } else {
209 Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
210 }
211 return TCL_OK;
212 }
213
214 /*
215 *----------------------------------------------------------------------
216 *
217 * TkBindEventProc --
218 *
219 * This procedure is invoked by Tk_HandleEvent for each event; it
220 * causes any appropriate bindings for that event to be invoked.
221 *
222 * Results:
223 * None.
224 *
225 * Side effects:
226 * Depends on what bindings have been established with the "bind"
227 * command.
228 *
229 *----------------------------------------------------------------------
230 */
231
232 void
TkBindEventProc(winPtr,eventPtr)233 TkBindEventProc(winPtr, eventPtr)
234 TkWindow *winPtr; /* Pointer to info about window. */
235 XEvent *eventPtr; /* Information about event. */
236 {
237 #define MAX_OBJS 20
238 ClientData objects[MAX_OBJS], *objPtr;
239 TkWindow *topLevPtr;
240 int i, count;
241 char *p;
242 Tcl_HashEntry *hPtr;
243
244 if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) {
245 return;
246 }
247
248 objPtr = objects;
249 if (winPtr->numTags != 0) {
250 /*
251 * Make a copy of the tags for the window, replacing window names
252 * with pointers to the pathName from the appropriate window.
253 */
254
255 if (winPtr->numTags > MAX_OBJS) {
256 objPtr = (ClientData *) ckalloc((unsigned)
257 (winPtr->numTags * sizeof(ClientData)));
258 }
259 for (i = 0; i < winPtr->numTags; i++) {
260 p = (char *) winPtr->tagPtr[i];
261 if (*p == '.') {
262 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
263 if (hPtr != NULL) {
264 p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
265 } else {
266 p = NULL;
267 }
268 }
269 objPtr[i] = (ClientData) p;
270 }
271 count = winPtr->numTags;
272 } else {
273 objPtr[0] = (ClientData) winPtr->pathName;
274 objPtr[1] = (ClientData) winPtr->classUid;
275 for (topLevPtr = winPtr;
276 (topLevPtr != NULL) && !(topLevPtr->flags & TK_TOP_HIERARCHY);
277 topLevPtr = topLevPtr->parentPtr) {
278 /* Empty loop body. */
279 }
280 if ((winPtr != topLevPtr) && (topLevPtr != NULL)) {
281 count = 4;
282 objPtr[2] = (ClientData) topLevPtr->pathName;
283 } else {
284 count = 3;
285 }
286 objPtr[count-1] = (ClientData) Tk_GetUid("all");
287 }
288 Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
289 count, objPtr);
290 if (objPtr != objects) {
291 ckfree((char *) objPtr);
292 }
293 }
294
295 /*
296 *----------------------------------------------------------------------
297 *
298 * Tk_BindtagsObjCmd --
299 *
300 * This procedure is invoked to process the "bindtags" Tcl command.
301 * See the user documentation for details on what it does.
302 *
303 * Results:
304 * A standard Tcl result.
305 *
306 * Side effects:
307 * See the user documentation.
308 *
309 *----------------------------------------------------------------------
310 */
311
312 int
Tk_BindtagsObjCmd(clientData,interp,objc,objv)313 Tk_BindtagsObjCmd(clientData, interp, objc, objv)
314 ClientData clientData; /* Main window associated with interpreter. */
315 Tcl_Interp *interp; /* Current interpreter. */
316 int objc; /* Number of arguments. */
317 Tcl_Obj *CONST objv[]; /* Argument objects. */
318 {
319 Tk_Window tkwin = (Tk_Window) clientData;
320 TkWindow *winPtr, *winPtr2;
321 int i, length;
322 char *p;
323 Tcl_Obj *listPtr, **tags;
324
325 if ((objc < 2) || (objc > 3)) {
326 Tcl_WrongNumArgs(interp, 1, objv, "window ?taglist?");
327 return TCL_ERROR;
328 }
329 winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
330 tkwin);
331 if (winPtr == NULL) {
332 return TCL_ERROR;
333 }
334 if (objc == 2) {
335 listPtr = Tcl_NewObj();
336 Tcl_IncrRefCount(listPtr);
337 if (winPtr->numTags == 0) {
338 Tcl_ListObjAppendElement(interp, listPtr,
339 Tcl_NewStringObj(winPtr->pathName, -1));
340 Tcl_ListObjAppendElement(interp, listPtr,
341 Tcl_NewStringObj(winPtr->classUid, -1));
342 winPtr2 = winPtr;
343 while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) {
344 winPtr2 = winPtr2->parentPtr;
345 }
346 if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
347 Tcl_ListObjAppendElement(interp, listPtr,
348 Tcl_NewStringObj(winPtr2->pathName, -1));
349 }
350 Tcl_ListObjAppendElement(interp, listPtr,
351 Tcl_NewStringObj("all", -1));
352 } else {
353 for (i = 0; i < winPtr->numTags; i++) {
354 Tcl_ListObjAppendElement(interp, listPtr,
355 Tcl_NewStringObj((char *)winPtr->tagPtr[i], -1));
356 }
357 }
358 Tcl_SetObjResult(interp, listPtr);
359 Tcl_DecrRefCount(listPtr);
360 return TCL_OK;
361 }
362 if (winPtr->tagPtr != NULL) {
363 TkFreeBindingTags(winPtr);
364 }
365 if (Tcl_ListObjGetElements(interp, objv[2], &length, &tags) != TCL_OK) {
366 return TCL_ERROR;
367 }
368 if (length == 0) {
369 return TCL_OK;
370 }
371
372 winPtr->numTags = length;
373 winPtr->tagPtr = (ClientData *) ckalloc((unsigned)
374 (length * sizeof(ClientData)));
375 for (i = 0; i < length; i++) {
376 p = Tcl_GetString(tags[i]);
377 if (p[0] == '.') {
378 char *copy;
379
380 /*
381 * Handle names starting with "." specially: store a malloc'ed
382 * string, rather than a Uid; at event time we'll look up the
383 * name in the window table and use the corresponding window,
384 * if there is one.
385 */
386
387 copy = (char *) ckalloc((unsigned) (strlen(p) + 1));
388 strcpy(copy, p);
389 winPtr->tagPtr[i] = (ClientData) copy;
390 } else {
391 winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p);
392 }
393 }
394 return TCL_OK;
395 }
396
397 /*
398 *----------------------------------------------------------------------
399 *
400 * TkFreeBindingTags --
401 *
402 * This procedure is called to free all of the binding tags
403 * associated with a window; typically it is only invoked where
404 * there are window-specific tags.
405 *
406 * Results:
407 * None.
408 *
409 * Side effects:
410 * Any binding tags for winPtr are freed.
411 *
412 *----------------------------------------------------------------------
413 */
414
415 void
TkFreeBindingTags(winPtr)416 TkFreeBindingTags(winPtr)
417 TkWindow *winPtr; /* Window whose tags are to be released. */
418 {
419 int i;
420 char *p;
421
422 for (i = 0; i < winPtr->numTags; i++) {
423 p = (char *) (winPtr->tagPtr[i]);
424 if (*p == '.') {
425 /*
426 * Names starting with "." are malloced rather than Uids, so
427 * they have to be freed.
428 */
429
430 ckfree(p);
431 }
432 }
433 ckfree((char *) winPtr->tagPtr);
434 winPtr->numTags = 0;
435 winPtr->tagPtr = NULL;
436 }
437
438 /*
439 *----------------------------------------------------------------------
440 *
441 * Tk_DestroyObjCmd --
442 *
443 * This procedure is invoked to process the "destroy" Tcl command.
444 * See the user documentation for details on what it does.
445 *
446 * Results:
447 * A standard Tcl result.
448 *
449 * Side effects:
450 * See the user documentation.
451 *
452 *----------------------------------------------------------------------
453 */
454
455 int
Tk_DestroyObjCmd(clientData,interp,objc,objv)456 Tk_DestroyObjCmd(clientData, interp, objc, objv)
457 ClientData clientData; /* Main window associated with
458 * interpreter. */
459 Tcl_Interp *interp; /* Current interpreter. */
460 int objc; /* Number of arguments. */
461 Tcl_Obj *CONST objv[]; /* Argument objects. */
462 {
463 Tk_Window window;
464 Tk_Window tkwin = (Tk_Window) clientData;
465 int i;
466
467 for (i = 1; i < objc; i++) {
468 window = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
469 if (window == NULL) {
470 Tcl_ResetResult(interp);
471 continue;
472 }
473 Tk_DestroyWindow(window);
474 if (window == tkwin) {
475 /*
476 * We just deleted the main window for the application! This
477 * makes it impossible to do anything more (tkwin isn't
478 * valid anymore).
479 */
480
481 break;
482 }
483 }
484 return TCL_OK;
485 }
486
487 /*
488 *----------------------------------------------------------------------
489 *
490 * Tk_LowerObjCmd --
491 *
492 * This procedure is invoked to process the "lower" 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
Tk_LowerObjCmd(clientData,interp,objc,objv)506 Tk_LowerObjCmd(clientData, interp, objc, objv)
507 ClientData clientData; /* Main window associated with
508 * interpreter. */
509 Tcl_Interp *interp; /* Current interpreter. */
510 int objc; /* Number of arguments. */
511 Tcl_Obj *CONST objv[]; /* Argument objects. */
512 {
513 Tk_Window mainwin = (Tk_Window) clientData;
514 Tk_Window tkwin, other;
515
516 if ((objc != 2) && (objc != 3)) {
517 Tcl_WrongNumArgs(interp, 1, objv, "window ?belowThis?");
518 return TCL_ERROR;
519 }
520
521 tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
522 if (tkwin == NULL) {
523 return TCL_ERROR;
524 }
525 if (objc == 2) {
526 other = NULL;
527 } else {
528 other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
529 if (other == NULL) {
530 return TCL_ERROR;
531 }
532 }
533 if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) {
534 Tcl_AppendResult(interp, "can't lower \"", Tcl_GetString(objv[1]),
535 "\" below \"", (other ? Tcl_GetString(objv[2]) : ""),
536 "\"", (char *) NULL);
537 return TCL_ERROR;
538 }
539 return TCL_OK;
540 }
541
542 /*
543 *----------------------------------------------------------------------
544 *
545 * Tk_RaiseObjCmd --
546 *
547 * This procedure is invoked to process the "raise" 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 /* ARGSUSED */
560 int
Tk_RaiseObjCmd(clientData,interp,objc,objv)561 Tk_RaiseObjCmd(clientData, interp, objc, objv)
562 ClientData clientData; /* Main window associated with
563 * interpreter. */
564 Tcl_Interp *interp; /* Current interpreter. */
565 int objc; /* Number of arguments. */
566 Tcl_Obj *CONST objv[]; /* Argument objects. */
567 {
568 Tk_Window mainwin = (Tk_Window) clientData;
569 Tk_Window tkwin, other;
570
571 if ((objc != 2) && (objc != 3)) {
572 Tcl_WrongNumArgs(interp, 1, objv, "window ?aboveThis?");
573 return TCL_ERROR;
574 }
575
576 tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), mainwin);
577 if (tkwin == NULL) {
578 return TCL_ERROR;
579 }
580 if (objc == 2) {
581 other = NULL;
582 } else {
583 other = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainwin);
584 if (other == NULL) {
585 return TCL_ERROR;
586 }
587 }
588 if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) {
589 Tcl_AppendResult(interp, "can't raise \"", Tcl_GetString(objv[1]),
590 "\" above \"", (other ? Tcl_GetString(objv[2]) : ""),
591 "\"", (char *) NULL);
592 return TCL_ERROR;
593 }
594 return TCL_OK;
595 }
596
597 /*
598 *----------------------------------------------------------------------
599 *
600 * Tk_TkObjCmd --
601 *
602 * This procedure is invoked to process the "tk" Tcl command.
603 * See the user documentation for details on what it does.
604 *
605 * Results:
606 * A standard Tcl result.
607 *
608 * Side effects:
609 * See the user documentation.
610 *
611 *----------------------------------------------------------------------
612 */
613
614 int
Tk_TkObjCmd(clientData,interp,objc,objv)615 Tk_TkObjCmd(clientData, interp, objc, objv)
616 ClientData clientData; /* Main window associated with interpreter. */
617 Tcl_Interp *interp; /* Current interpreter. */
618 int objc; /* Number of arguments. */
619 Tcl_Obj *CONST objv[]; /* Argument objects. */
620 {
621 int index;
622 Tk_Window tkwin;
623 static CONST char *optionStrings[] = {
624 "appname", "caret", "scaling", "useinputmethods",
625 "windowingsystem", NULL
626 };
627 enum options {
628 TK_APPNAME, TK_CARET, TK_SCALING, TK_USE_IM,
629 TK_WINDOWINGSYSTEM
630 };
631
632 tkwin = (Tk_Window) clientData;
633
634 if (objc < 2) {
635 Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
636 return TCL_ERROR;
637 }
638 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
639 &index) != TCL_OK) {
640 return TCL_ERROR;
641 }
642
643 switch ((enum options) index) {
644 case TK_APPNAME: {
645 TkWindow *winPtr;
646 char *string;
647
648 if (Tcl_IsSafe(interp)) {
649 Tcl_SetResult(interp,
650 "appname not accessible in a safe interpreter",
651 TCL_STATIC);
652 return TCL_ERROR;
653 }
654
655 winPtr = (TkWindow *) tkwin;
656
657 if (objc > 3) {
658 Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
659 return TCL_ERROR;
660 }
661 if (objc == 3) {
662 string = Tcl_GetStringFromObj(objv[2], NULL);
663 winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
664 }
665 Tcl_AppendResult(interp, winPtr->nameUid, NULL);
666 break;
667 }
668 case TK_CARET: {
669 Tcl_Obj *objPtr;
670 TkCaret *caretPtr;
671 Tk_Window window;
672 static CONST char *caretStrings[]
673 = { "-x", "-y", "-height", NULL };
674 enum caretOptions
675 { TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT };
676
677 if ((objc < 3) || ((objc > 4) && !(objc & 1))) {
678 Tcl_WrongNumArgs(interp, 2, objv,
679 "window ?-x x? ?-y y? ?-height height?");
680 return TCL_ERROR;
681 }
682 window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
683 if (window == NULL) {
684 return TCL_ERROR;
685 }
686 caretPtr = &(((TkWindow *) window)->dispPtr->caret);
687 if (objc == 3) {
688 /*
689 * Return all the current values
690 */
691 objPtr = Tcl_NewObj();
692 Tcl_ListObjAppendElement(interp, objPtr,
693 Tcl_NewStringObj("-height", 7));
694 Tcl_ListObjAppendElement(interp, objPtr,
695 Tcl_NewIntObj(caretPtr->height));
696 Tcl_ListObjAppendElement(interp, objPtr,
697 Tcl_NewStringObj("-x", 2));
698 Tcl_ListObjAppendElement(interp, objPtr,
699 Tcl_NewIntObj(caretPtr->x));
700 Tcl_ListObjAppendElement(interp, objPtr,
701 Tcl_NewStringObj("-y", 2));
702 Tcl_ListObjAppendElement(interp, objPtr,
703 Tcl_NewIntObj(caretPtr->y));
704 Tcl_SetObjResult(interp, objPtr);
705 } else if (objc == 4) {
706 int value;
707 /*
708 * Return the current value of the selected option
709 */
710 if (Tcl_GetIndexFromObj(interp, objv[3], caretStrings,
711 "caret option", 0, &index) != TCL_OK) {
712 return TCL_ERROR;
713 }
714 if (index == TK_CARET_X) {
715 value = caretPtr->x;
716 } else if (index == TK_CARET_Y) {
717 value = caretPtr->y;
718 } else /* if (index == TK_CARET_HEIGHT) -- last case */ {
719 value = caretPtr->height;
720 }
721 Tcl_SetIntObj(Tcl_GetObjResult(interp), value);
722 } else {
723 int i, value, x = 0, y = 0, height = -1;
724
725 for (i = 3; i < objc; i += 2) {
726 if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
727 "caret option", 0, &index) != TCL_OK) ||
728 (Tcl_GetIntFromObj(interp, objv[i+1], &value)
729 != TCL_OK)) {
730 return TCL_ERROR;
731 }
732 if (index == TK_CARET_X) {
733 x = value;
734 } else if (index == TK_CARET_Y) {
735 y = value;
736 } else /* if (index == TK_CARET_HEIGHT) -- last case */ {
737 height = value;
738 }
739 }
740 if (height < 0) {
741 height = Tk_Height(window);
742 }
743 Tk_SetCaretPos(window, x, y, height);
744 }
745 break;
746 }
747 case TK_SCALING: {
748 Screen *screenPtr;
749 int skip, width, height;
750 double d;
751
752 if (Tcl_IsSafe(interp)) {
753 Tcl_SetResult(interp,
754 "scaling not accessible in a safe interpreter",
755 TCL_STATIC);
756 return TCL_ERROR;
757 }
758
759 screenPtr = Tk_Screen(tkwin);
760
761 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
762 if (skip < 0) {
763 return TCL_ERROR;
764 }
765 if (objc - skip == 2) {
766 d = 25.4 / 72;
767 d *= WidthOfScreen(screenPtr);
768 d /= WidthMMOfScreen(screenPtr);
769 Tcl_SetDoubleObj(Tcl_GetObjResult(interp), d);
770 } else if (objc - skip == 3) {
771 if (Tcl_GetDoubleFromObj(interp, objv[2+skip], &d) != TCL_OK) {
772 return TCL_ERROR;
773 }
774 d = (25.4 / 72) / d;
775 width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
776 if (width <= 0) {
777 width = 1;
778 }
779 height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
780 if (height <= 0) {
781 height = 1;
782 }
783 WidthMMOfScreen(screenPtr) = width;
784 HeightMMOfScreen(screenPtr) = height;
785 } else {
786 Tcl_WrongNumArgs(interp, 2, objv,
787 "?-displayof window? ?factor?");
788 return TCL_ERROR;
789 }
790 break;
791 }
792 case TK_USE_IM: {
793 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
794 int skip;
795
796 if (Tcl_IsSafe(interp)) {
797 Tcl_SetResult(interp,
798 "useinputmethods not accessible in a safe interpreter",
799 TCL_STATIC);
800 return TCL_ERROR;
801 }
802
803 skip = TkGetDisplayOf(interp, objc-2, objv+2, &tkwin);
804 if (skip < 0) {
805 return TCL_ERROR;
806 } else if (skip) {
807 dispPtr = ((TkWindow *) tkwin)->dispPtr;
808 }
809 if ((objc - skip) == 3) {
810 /*
811 * In the case where TK_USE_INPUT_METHODS is not defined,
812 * this will be ignored and we will always return 0.
813 * That will indicate to the user that input methods
814 * are just not available.
815 */
816 int boolVal;
817 if (Tcl_GetBooleanFromObj(interp, objv[2+skip], &boolVal)
818 != TCL_OK) {
819 return TCL_ERROR;
820 }
821 #ifdef TK_USE_INPUT_METHODS
822 if (boolVal) {
823 dispPtr->flags |= TK_DISPLAY_USE_IM;
824 } else {
825 dispPtr->flags &= ~TK_DISPLAY_USE_IM;
826 }
827 #endif /* TK_USE_INPUT_METHODS */
828 } else if ((objc - skip) != 2) {
829 Tcl_WrongNumArgs(interp, 2, objv,
830 "?-displayof window? ?boolean?");
831 return TCL_ERROR;
832 }
833 Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
834 (int) (dispPtr->flags & TK_DISPLAY_USE_IM));
835 break;
836 }
837 case TK_WINDOWINGSYSTEM: {
838 CONST char *windowingsystem;
839
840 if (objc != 2) {
841 Tcl_WrongNumArgs(interp, 2, objv, NULL);
842 return TCL_ERROR;
843 }
844 #if defined(WIN32)
845 windowingsystem = "win32";
846 #elif defined(MAC_TCL)
847 windowingsystem = "classic";
848 #elif defined(MAC_OSX_TK)
849 windowingsystem = "aqua";
850 #else
851 windowingsystem = "x11";
852 #endif
853 Tcl_SetStringObj(Tcl_GetObjResult(interp), windowingsystem, -1);
854 break;
855 }
856 }
857 return TCL_OK;
858 }
859
860 /*
861 *----------------------------------------------------------------------
862 *
863 * Tk_TkwaitObjCmd --
864 *
865 * This procedure is invoked to process the "tkwait" Tcl command.
866 * See the user documentation for details on what it does.
867 *
868 * Results:
869 * A standard Tcl result.
870 *
871 * Side effects:
872 * See the user documentation.
873 *
874 *----------------------------------------------------------------------
875 */
876
877 /* ARGSUSED */
878 int
Tk_TkwaitObjCmd(clientData,interp,objc,objv)879 Tk_TkwaitObjCmd(clientData, interp, objc, objv)
880 ClientData clientData; /* Main window associated with
881 * interpreter. */
882 Tcl_Interp *interp; /* Current interpreter. */
883 int objc; /* Number of arguments. */
884 Tcl_Obj *CONST objv[]; /* Argument objects. */
885 {
886 Tk_Window tkwin = (Tk_Window) clientData;
887 int done, index;
888 static CONST char *optionStrings[] = { "variable", "visibility", "window",
889 (char *) NULL };
890 enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW };
891
892 if (objc != 3) {
893 Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name");
894 return TCL_ERROR;
895 }
896
897 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
898 &index) != TCL_OK) {
899 return TCL_ERROR;
900 }
901
902 switch ((enum options) index) {
903 case TKWAIT_VARIABLE: {
904 if (Lang_TraceVar(interp, objv[2],
905 TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
906 WaitVariableProc, (ClientData) &done) != TCL_OK) {
907 return TCL_ERROR;
908 }
909 done = 0;
910 while (!done) {
911 Tcl_DoOneEvent(0);
912 }
913 Lang_UntraceVar(interp, objv[2],
914 TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
915 WaitVariableProc, (ClientData) &done);
916 break;
917 }
918
919 case TKWAIT_VISIBILITY: {
920 Tk_Window window;
921
922 window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
923 if (window == NULL) {
924 return TCL_ERROR;
925 }
926 Tk_CreateEventHandler(window,
927 VisibilityChangeMask|StructureNotifyMask,
928 WaitVisibilityProc, (ClientData) &done);
929 done = 0;
930 while (!done) {
931 Tcl_DoOneEvent(0);
932 }
933 if (done != 1) {
934 /*
935 * Note that we do not delete the event handler because it
936 * was deleted automatically when the window was destroyed.
937 */
938
939 Tcl_ResetResult(interp);
940 Tcl_AppendResult(interp, "window \"", Tcl_GetString(objv[2]),
941 "\" was deleted before its visibility changed",
942 (char *) NULL);
943 return TCL_ERROR;
944 }
945 Tk_DeleteEventHandler(window,
946 VisibilityChangeMask|StructureNotifyMask,
947 WaitVisibilityProc, (ClientData) &done);
948 break;
949 }
950
951 case TKWAIT_WINDOW: {
952 Tk_Window window;
953
954 window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
955 if (window == NULL) {
956 return TCL_ERROR;
957 }
958 Tk_CreateEventHandler(window, StructureNotifyMask,
959 WaitWindowProc, (ClientData) &done);
960 done = 0;
961 while (!done) {
962 Tcl_DoOneEvent(0);
963 }
964 /*
965 * Note: there's no need to delete the event handler. It was
966 * deleted automatically when the window was destroyed.
967 */
968 break;
969 }
970 }
971
972 /*
973 * Clear out the interpreter's result, since it may have been set
974 * by event handlers.
975 */
976
977 Tcl_ResetResult(interp);
978 return TCL_OK;
979 }
980
981 /* ARGSUSED */
982 static char *
WaitVariableProc(clientData,interp,name1,name2,flags)983 WaitVariableProc(clientData, interp, name1, name2, flags)
984 ClientData clientData; /* Pointer to integer to set to 1. */
985 Tcl_Interp *interp; /* Interpreter containing variable. */
986 Var name1; /* Name of variable. */
987 CONST char *name2; /* Second part of variable name. */
988 int flags; /* Information about what happened. */
989 {
990 int *donePtr = (int *) clientData;
991
992 *donePtr = 1;
993 return (char *) NULL;
994 }
995
996 /*ARGSUSED*/
997 static void
WaitVisibilityProc(clientData,eventPtr)998 WaitVisibilityProc(clientData, eventPtr)
999 ClientData clientData; /* Pointer to integer to set to 1. */
1000 XEvent *eventPtr; /* Information about event (not used). */
1001 {
1002 int *donePtr = (int *) clientData;
1003
1004 if (eventPtr->type == VisibilityNotify) {
1005 *donePtr = 1;
1006 }
1007 if (eventPtr->type == DestroyNotify) {
1008 *donePtr = 2;
1009 }
1010 }
1011
1012 static void
WaitWindowProc(clientData,eventPtr)1013 WaitWindowProc(clientData, eventPtr)
1014 ClientData clientData; /* Pointer to integer to set to 1. */
1015 XEvent *eventPtr; /* Information about event. */
1016 {
1017 int *donePtr = (int *) clientData;
1018
1019 if (eventPtr->type == DestroyNotify) {
1020 *donePtr = 1;
1021 }
1022 }
1023
1024 /*
1025 *----------------------------------------------------------------------
1026 *
1027 * Tk_UpdateObjCmd --
1028 *
1029 * This procedure is invoked to process the "update" Tcl command.
1030 * See the user documentation for details on what it does.
1031 *
1032 * Results:
1033 * A standard Tcl result.
1034 *
1035 * Side effects:
1036 * See the user documentation.
1037 *
1038 *----------------------------------------------------------------------
1039 */
1040
1041 /* ARGSUSED */
1042 int
Tk_UpdateObjCmd(clientData,interp,objc,objv)1043 Tk_UpdateObjCmd(clientData, interp, objc, objv)
1044 ClientData clientData; /* Main window associated with
1045 * interpreter. */
1046 Tcl_Interp *interp; /* Current interpreter. */
1047 int objc; /* Number of arguments. */
1048 Tcl_Obj *CONST objv[]; /* Argument objects. */
1049 {
1050 static CONST char *updateOptions[] = {"idletasks", (char *) NULL};
1051 int flags, index;
1052 TkDisplay *dispPtr;
1053
1054 if (objc == 1) {
1055 flags = TCL_DONT_WAIT;
1056 } else if (objc == 2) {
1057 if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0,
1058 &index) != TCL_OK) {
1059 return TCL_ERROR;
1060 }
1061 flags = TCL_IDLE_EVENTS;
1062 } else {
1063 Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?");
1064 return TCL_ERROR;
1065 }
1066
1067 /*
1068 * Handle all pending events, sync all displays, and repeat over
1069 * and over again until all pending events have been handled.
1070 * Special note: it's possible that the entire application could
1071 * be destroyed by an event handler that occurs during the update.
1072 * Thus, don't use any information from tkwin after calling
1073 * Tcl_DoOneEvent.
1074 */
1075
1076 while (1) {
1077 while (Tcl_DoOneEvent(flags) != 0) {
1078 /* Empty loop body */
1079 }
1080 for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
1081 dispPtr = dispPtr->nextPtr) {
1082 XSync(dispPtr->display, False);
1083 }
1084 if (Tcl_DoOneEvent(flags) == 0) {
1085 break;
1086 }
1087 }
1088
1089 /*
1090 * Must clear the interpreter's result because event handlers could
1091 * have executed commands.
1092 */
1093
1094 Tcl_ResetResult(interp);
1095 return TCL_OK;
1096 }
1097
1098 /*
1099 *----------------------------------------------------------------------
1100 *
1101 * Tk_WinfoObjCmd --
1102 *
1103 * This procedure is invoked to process the "winfo" Tcl command.
1104 * See the user documentation for details on what it does.
1105 *
1106 * Results:
1107 * A standard Tcl result.
1108 *
1109 * Side effects:
1110 * See the user documentation.
1111 *
1112 *----------------------------------------------------------------------
1113 */
1114
1115 int
Tk_WinfoObjCmd(clientData,interp,objc,objv)1116 Tk_WinfoObjCmd(clientData, interp, objc, objv)
1117 ClientData clientData; /* Main window associated with
1118 * interpreter. */
1119 Tcl_Interp *interp; /* Current interpreter. */
1120 int objc; /* Number of arguments. */
1121 Tcl_Obj *CONST objv[]; /* Argument objects. */
1122 {
1123 int index, x, y, width, height, useX, useY, class, skip;
1124 char *string;
1125 TkWindow *winPtr;
1126 Tk_Window tkwin;
1127 Tcl_Obj *resultPtr;
1128
1129 static TkStateMap visualMap[] = {
1130 {PseudoColor, "pseudocolor"},
1131 {GrayScale, "grayscale"},
1132 {DirectColor, "directcolor"},
1133 {TrueColor, "truecolor"},
1134 {StaticColor, "staticcolor"},
1135 {StaticGray, "staticgray"},
1136 {-1, NULL}
1137 };
1138 static CONST char *optionStrings[] = {
1139 "cells", "children", "class", "colormapfull",
1140 "depth", "geometry", "height", "id",
1141 "ismapped", "manager", "name", "parent",
1142 "pointerx", "pointery", "pointerxy", "reqheight",
1143 "reqwidth", "rootx", "rooty", "screen",
1144 "screencells", "screendepth", "screenheight", "screenwidth",
1145 "screenmmheight","screenmmwidth","screenvisual","server",
1146 "toplevel", "viewable", "visual", "visualid",
1147 "vrootheight", "vrootwidth", "vrootx", "vrooty",
1148 "width", "x", "y",
1149
1150 "atom", "atomname", "containing", "interps",
1151 "pathname",
1152
1153 "exists", "fpixels", "pixels", "rgb",
1154 "visualsavailable",
1155
1156 NULL
1157 };
1158 enum options {
1159 WIN_CELLS, WIN_CHILDREN, WIN_CLASS, WIN_COLORMAPFULL,
1160 WIN_DEPTH, WIN_GEOMETRY, WIN_HEIGHT, WIN_ID,
1161 WIN_ISMAPPED, WIN_MANAGER, WIN_NAME, WIN_PARENT,
1162 WIN_POINTERX, WIN_POINTERY, WIN_POINTERXY, WIN_REQHEIGHT,
1163 WIN_REQWIDTH, WIN_ROOTX, WIN_ROOTY, WIN_SCREEN,
1164 WIN_SCREENCELLS,WIN_SCREENDEPTH,WIN_SCREENHEIGHT,WIN_SCREENWIDTH,
1165 WIN_SCREENMMHEIGHT,WIN_SCREENMMWIDTH,WIN_SCREENVISUAL,WIN_SERVER,
1166 WIN_TOPLEVEL, WIN_VIEWABLE, WIN_VISUAL, WIN_VISUALID,
1167 WIN_VROOTHEIGHT,WIN_VROOTWIDTH, WIN_VROOTX, WIN_VROOTY,
1168 WIN_WIDTH, WIN_X, WIN_Y,
1169
1170 WIN_ATOM, WIN_ATOMNAME, WIN_CONTAINING, WIN_INTERPS,
1171 WIN_PATHNAME,
1172
1173 WIN_EXISTS, WIN_FPIXELS, WIN_PIXELS, WIN_RGB,
1174 WIN_VISUALSAVAILABLE
1175 };
1176
1177 tkwin = (Tk_Window) clientData;
1178
1179 if (objc < 2) {
1180 Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
1181 return TCL_ERROR;
1182 }
1183 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
1184 &index) != TCL_OK) {
1185 return TCL_ERROR;
1186 }
1187
1188 if (index < WIN_ATOM) {
1189 if (objc != 3) {
1190 Tcl_WrongNumArgs(interp, 2, objv, "window");
1191 return TCL_ERROR;
1192 }
1193 string = Tcl_GetStringFromObj(objv[2], NULL);
1194 tkwin = Tk_NameToWindow(interp, string, tkwin);
1195 if (tkwin == NULL) {
1196 return TCL_ERROR;
1197 }
1198 }
1199 winPtr = (TkWindow *) tkwin;
1200 resultPtr = Tcl_GetObjResult(interp);
1201
1202 switch ((enum options) index) {
1203 case WIN_CELLS: {
1204 Tcl_SetIntObj(resultPtr, Tk_Visual(tkwin)->map_entries);
1205 break;
1206 }
1207 case WIN_CHILDREN: {
1208 Tcl_Obj *strPtr;
1209
1210 winPtr = winPtr->childList;
1211 for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
1212 if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
1213 strPtr = LangWidgetObj(interp,(Tk_Window) winPtr);
1214 Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
1215 }
1216 }
1217 break;
1218 }
1219 case WIN_CLASS: {
1220 Tcl_SetStringObj(resultPtr, Tk_Class(tkwin), -1);
1221 break;
1222 }
1223 case WIN_COLORMAPFULL: {
1224 Tcl_SetBooleanObj(resultPtr,
1225 TkpCmapStressed(tkwin, Tk_Colormap(tkwin)));
1226 break;
1227 }
1228 case WIN_DEPTH: {
1229 Tcl_SetIntObj(resultPtr, Tk_Depth(tkwin));
1230 break;
1231 }
1232 case WIN_GEOMETRY: {
1233 char buf[16 + TCL_INTEGER_SPACE * 4];
1234
1235 sprintf(buf, "%dx%d+%d+%d", Tk_Width(tkwin), Tk_Height(tkwin),
1236 Tk_X(tkwin), Tk_Y(tkwin));
1237 Tcl_SetStringObj(resultPtr, buf, -1);
1238 break;
1239 }
1240 case WIN_HEIGHT: {
1241 Tcl_SetIntObj(resultPtr, Tk_Height(tkwin));
1242 break;
1243 }
1244 case WIN_ID: {
1245 char buf[TCL_INTEGER_SPACE];
1246
1247 Tk_MakeWindowExist(tkwin);
1248 TkpPrintWindowId(buf, Tk_WindowId(tkwin));
1249 Tcl_SetStringObj(resultPtr, buf, -1);
1250 break;
1251 }
1252 case WIN_ISMAPPED: {
1253 Tcl_SetBooleanObj(resultPtr, (int) Tk_IsMapped(tkwin));
1254 break;
1255 }
1256 case WIN_MANAGER: {
1257 if (winPtr->geomMgrPtr != NULL) {
1258 Tcl_SetStringObj(resultPtr, winPtr->geomMgrPtr->name, -1);
1259 }
1260 break;
1261 }
1262 case WIN_NAME: {
1263 Tcl_SetStringObj(resultPtr, Tk_Name(tkwin), -1);
1264 break;
1265 }
1266 case WIN_PARENT: {
1267 if (winPtr->parentPtr != NULL) {
1268 Tcl_SetObjResult(interp, LangWidgetObj(interp, (Tk_Window) winPtr->parentPtr));
1269 }
1270 break;
1271 }
1272 case WIN_POINTERX: {
1273 useX = 1;
1274 useY = 0;
1275 goto pointerxy;
1276 }
1277 case WIN_POINTERY: {
1278 useX = 0;
1279 useY = 1;
1280 goto pointerxy;
1281 }
1282 case WIN_POINTERXY: {
1283 useX = 1;
1284 useY = 1;
1285
1286 pointerxy:
1287 winPtr = GetToplevel(tkwin);
1288 if (winPtr == NULL) {
1289 x = -1;
1290 y = -1;
1291 } else {
1292 TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
1293 }
1294 if (useX & useY) {
1295 Tcl_IntResults(interp, 2, 0, x, y);
1296 } else if (useX) {
1297 Tcl_SetIntObj(resultPtr, x);
1298 } else {
1299 Tcl_SetIntObj(resultPtr, y);
1300 }
1301 break;
1302 }
1303 case WIN_REQHEIGHT: {
1304 Tcl_SetIntObj(resultPtr, Tk_ReqHeight(tkwin));
1305 break;
1306 }
1307 case WIN_REQWIDTH: {
1308 Tcl_SetIntObj(resultPtr, Tk_ReqWidth(tkwin));
1309 break;
1310 }
1311 case WIN_ROOTX: {
1312 Tk_GetRootCoords(tkwin, &x, &y);
1313 Tcl_SetIntObj(resultPtr, x);
1314 break;
1315 }
1316 case WIN_ROOTY: {
1317 Tk_GetRootCoords(tkwin, &x, &y);
1318 Tcl_SetIntObj(resultPtr, y);
1319 break;
1320 }
1321 case WIN_SCREEN: {
1322 char buf[TCL_INTEGER_SPACE];
1323
1324 sprintf(buf, "%d", Tk_ScreenNumber(tkwin));
1325 Tcl_AppendStringsToObj(resultPtr, Tk_DisplayName(tkwin), ".",
1326 buf, NULL);
1327 break;
1328 }
1329 case WIN_SCREENCELLS: {
1330 Tcl_SetIntObj(resultPtr, CellsOfScreen(Tk_Screen(tkwin)));
1331 break;
1332 }
1333 case WIN_SCREENDEPTH: {
1334 Tcl_SetIntObj(resultPtr, DefaultDepthOfScreen(Tk_Screen(tkwin)));
1335 break;
1336 }
1337 case WIN_SCREENHEIGHT: {
1338 Tcl_SetIntObj(resultPtr, HeightOfScreen(Tk_Screen(tkwin)));
1339 break;
1340 }
1341 case WIN_SCREENWIDTH: {
1342 Tcl_SetIntObj(resultPtr, WidthOfScreen(Tk_Screen(tkwin)));
1343 break;
1344 }
1345 case WIN_SCREENMMHEIGHT: {
1346 Tcl_SetIntObj(resultPtr, HeightMMOfScreen(Tk_Screen(tkwin)));
1347 break;
1348 }
1349 case WIN_SCREENMMWIDTH: {
1350 Tcl_SetIntObj(resultPtr, WidthMMOfScreen(Tk_Screen(tkwin)));
1351 break;
1352 }
1353 case WIN_SCREENVISUAL: {
1354 class = DefaultVisualOfScreen(Tk_Screen(tkwin))->class;
1355 goto visual;
1356 }
1357 case WIN_SERVER: {
1358 TkGetServerInfo(interp, tkwin);
1359 break;
1360 }
1361 case WIN_TOPLEVEL: {
1362 winPtr = GetToplevel(tkwin);
1363 if (winPtr != NULL) {
1364 Tcl_ResetResult(interp);
1365 Tcl_SetObjResult(interp, LangWidgetObj(interp, (Tk_Window) winPtr));
1366 }
1367 break;
1368 }
1369 case WIN_VIEWABLE: {
1370 int viewable = 0;
1371 for ( ; ; winPtr = winPtr->parentPtr) {
1372 if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {
1373 break;
1374 }
1375 if (winPtr->flags & TK_TOP_HIERARCHY) {
1376 viewable = 1;
1377 break;
1378 }
1379 }
1380
1381 Tcl_SetBooleanObj(resultPtr, viewable);
1382 break;
1383 }
1384 case WIN_VISUAL: {
1385 class = Tk_Visual(tkwin)->class;
1386
1387 visual:
1388 string = TkFindStateString(visualMap, class);
1389 if (string == NULL) {
1390 string = "unknown";
1391 }
1392 Tcl_SetStringObj(resultPtr, string, -1);
1393 break;
1394 }
1395 case WIN_VISUALID: {
1396 char buf[TCL_INTEGER_SPACE];
1397
1398 sprintf(buf, "0x%x",
1399 (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin)));
1400 Tcl_SetStringObj(resultPtr, buf, -1);
1401 break;
1402 }
1403 case WIN_VROOTHEIGHT: {
1404 Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1405 Tcl_SetIntObj(resultPtr, height);
1406 break;
1407 }
1408 case WIN_VROOTWIDTH: {
1409 Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1410 Tcl_SetIntObj(resultPtr, width);
1411 break;
1412 }
1413 case WIN_VROOTX: {
1414 Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1415 Tcl_SetIntObj(resultPtr, x);
1416 break;
1417 }
1418 case WIN_VROOTY: {
1419 Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
1420 Tcl_SetIntObj(resultPtr, y);
1421 break;
1422 }
1423 case WIN_WIDTH: {
1424 Tcl_SetIntObj(resultPtr, Tk_Width(tkwin));
1425 break;
1426 }
1427 case WIN_X: {
1428 Tcl_SetIntObj(resultPtr, Tk_X(tkwin));
1429 break;
1430 }
1431 case WIN_Y: {
1432 Tcl_SetIntObj(resultPtr, Tk_Y(tkwin));
1433 break;
1434 }
1435
1436 /*
1437 * Uses -displayof.
1438 */
1439
1440 case WIN_ATOM: {
1441 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1442 if (skip < 0) {
1443 return TCL_ERROR;
1444 }
1445 if (objc - skip != 3) {
1446 Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
1447 return TCL_ERROR;
1448 }
1449 objv += skip;
1450 string = Tcl_GetStringFromObj(objv[2], NULL);
1451 Tcl_SetLongObj(resultPtr, (long) Tk_InternAtom(tkwin, string));
1452 break;
1453 }
1454 case WIN_ATOMNAME: {
1455 CONST char *name;
1456 long id;
1457
1458 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1459 if (skip < 0) {
1460 return TCL_ERROR;
1461 }
1462 if (objc - skip != 3) {
1463 Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
1464 return TCL_ERROR;
1465 }
1466 objv += skip;
1467 if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) {
1468 return TCL_ERROR;
1469 }
1470 name = Tk_GetAtomName(tkwin, (Atom) id);
1471 if (strcmp(name, "?bad atom?") == 0) {
1472 string = Tcl_GetStringFromObj(objv[2], NULL);
1473 Tcl_AppendStringsToObj(resultPtr,
1474 "no atom exists with id \"", string, "\"", NULL);
1475 return TCL_ERROR;
1476 }
1477 Tcl_SetStringObj(resultPtr, name, -1);
1478 break;
1479 }
1480 case WIN_CONTAINING: {
1481 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1482 if (skip < 0) {
1483 return TCL_ERROR;
1484 }
1485 if (objc - skip != 4) {
1486 Tcl_WrongNumArgs(interp, 2, objv,
1487 "?-displayof window? rootX rootY");
1488 return TCL_ERROR;
1489 }
1490 objv += skip;
1491 string = Tcl_GetStringFromObj(objv[2], NULL);
1492 if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
1493 return TCL_ERROR;
1494 }
1495 string = Tcl_GetStringFromObj(objv[3], NULL);
1496 if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
1497 return TCL_ERROR;
1498 }
1499 tkwin = Tk_CoordsToWindow(x, y, tkwin);
1500 if (tkwin != NULL) {
1501 Tcl_ResetResult(interp);
1502 Tcl_SetObjResult(interp, LangWidgetObj(interp, tkwin));
1503 }
1504 break;
1505 }
1506 case WIN_INTERPS: {
1507 int result;
1508
1509 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1510 if (skip < 0) {
1511 return TCL_ERROR;
1512 }
1513 if (objc - skip != 2) {
1514 Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
1515 return TCL_ERROR;
1516 }
1517 result = TkGetInterpNames(interp, tkwin);
1518 return result;
1519 }
1520 case WIN_PATHNAME: {
1521 Window id;
1522
1523 skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
1524 if (skip < 0) {
1525 return TCL_ERROR;
1526 }
1527 if (objc - skip != 3) {
1528 Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
1529 return TCL_ERROR;
1530 }
1531 if (TkpScanWindowId(interp, objv[2+skip], &id) != TCL_OK) {
1532 return TCL_ERROR;
1533 }
1534 winPtr = (TkWindow *)Tk_IdToWindow(Tk_Display(tkwin), id);
1535 if ((winPtr == NULL) ||
1536 (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) {
1537 string = Tcl_GetStringFromObj(objv[2 + skip], NULL);
1538 Tcl_AppendStringsToObj(resultPtr, "window id \"", string,
1539 "\" doesn't exist in this application", (char *) NULL);
1540 return TCL_ERROR;
1541 }
1542
1543 /*
1544 * If the window is a utility window with no associated path
1545 * (such as a wrapper window or send communication window), just
1546 * return an empty string.
1547 */
1548
1549 tkwin = (Tk_Window) winPtr;
1550 if (Tk_PathName(tkwin) != NULL) {
1551 Tcl_ResetResult(interp);
1552 Tcl_SetObjResult(interp, LangWidgetObj(interp,tkwin));
1553 }
1554 break;
1555 }
1556
1557 /*
1558 * objv[3] is window.
1559 */
1560
1561 case WIN_EXISTS: {
1562 int alive;
1563
1564 if (objc != 3) {
1565 Tcl_WrongNumArgs(interp, 2, objv, "window");
1566 return TCL_ERROR;
1567 }
1568 string = Tcl_GetStringFromObj(objv[2], NULL);
1569 winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
1570 Tcl_ResetResult(interp);
1571 resultPtr = Tcl_GetObjResult(interp);
1572
1573 alive = 1;
1574 if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) {
1575 alive = 0;
1576 }
1577 Tcl_SetBooleanObj(resultPtr, alive);
1578 break;
1579 }
1580 case WIN_FPIXELS: {
1581 double mm, pixels;
1582
1583 if (objc != 4) {
1584 Tcl_WrongNumArgs(interp, 2, objv, "window number");
1585 return TCL_ERROR;
1586 }
1587 string = Tcl_GetStringFromObj(objv[2], NULL);
1588 tkwin = Tk_NameToWindow(interp, string, tkwin);
1589 if (tkwin == NULL) {
1590 return TCL_ERROR;
1591 }
1592 string = Tcl_GetStringFromObj(objv[3], NULL);
1593 if (Tk_GetScreenMM(interp, tkwin, string, &mm) != TCL_OK) {
1594 return TCL_ERROR;
1595 }
1596 pixels = mm * WidthOfScreen(Tk_Screen(tkwin))
1597 / WidthMMOfScreen(Tk_Screen(tkwin));
1598 Tcl_SetDoubleObj(resultPtr, pixels);
1599 break;
1600 }
1601 case WIN_PIXELS: {
1602 int pixels;
1603
1604 if (objc != 4) {
1605 Tcl_WrongNumArgs(interp, 2, objv, "window number");
1606 return TCL_ERROR;
1607 }
1608 string = Tcl_GetStringFromObj(objv[2], NULL);
1609 tkwin = Tk_NameToWindow(interp, string, tkwin);
1610 if (tkwin == NULL) {
1611 return TCL_ERROR;
1612 }
1613 string = Tcl_GetStringFromObj(objv[3], NULL);
1614 if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
1615 return TCL_ERROR;
1616 }
1617 Tcl_SetIntObj(resultPtr, pixels);
1618 break;
1619 }
1620 case WIN_RGB: {
1621 XColor *colorPtr;
1622
1623 if (objc != 4) {
1624 Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
1625 return TCL_ERROR;
1626 }
1627 string = Tcl_GetStringFromObj(objv[2], NULL);
1628 tkwin = Tk_NameToWindow(interp, string, tkwin);
1629 if (tkwin == NULL) {
1630 return TCL_ERROR;
1631 }
1632 string = Tcl_GetStringFromObj(objv[3], NULL);
1633 colorPtr = Tk_GetColor(interp, tkwin, string);
1634 if (colorPtr == NULL) {
1635 return TCL_ERROR;
1636 }
1637 Tcl_IntResults(interp, 3, 0, colorPtr->red, colorPtr->green,
1638 colorPtr->blue);
1639 Tk_FreeColor(colorPtr);
1640 break;
1641 }
1642 case WIN_VISUALSAVAILABLE: {
1643 XVisualInfo template, *visInfoPtr;
1644 int count, i;
1645 int includeVisualId;
1646 Tcl_Obj *strPtr;
1647 char buf[16 + TCL_INTEGER_SPACE];
1648 char visualIdString[TCL_INTEGER_SPACE];
1649
1650 if (objc == 3) {
1651 includeVisualId = 0;
1652 } else if ((objc == 4)
1653 && (strcmp(Tcl_GetStringFromObj(objv[3], NULL),
1654 "includeids") == 0)) {
1655 includeVisualId = 1;
1656 } else {
1657 Tcl_WrongNumArgs(interp, 2, objv, "window ?includeids?");
1658 return TCL_ERROR;
1659 }
1660
1661 string = Tcl_GetStringFromObj(objv[2], NULL);
1662 tkwin = Tk_NameToWindow(interp, string, tkwin);
1663 if (tkwin == NULL) {
1664 return TCL_ERROR;
1665 }
1666
1667 template.screen = Tk_ScreenNumber(tkwin);
1668 visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
1669 &template, &count);
1670 if (visInfoPtr == NULL) {
1671 Tcl_SetStringObj(resultPtr,
1672 "can't find any visuals for screen", -1);
1673 return TCL_ERROR;
1674 }
1675 for (i = 0; i < count; i++) {
1676 string = TkFindStateString(visualMap, visInfoPtr[i].class);
1677 if (string == NULL) {
1678 strcpy(buf, "unknown");
1679 } else {
1680 sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
1681 }
1682 if (includeVisualId) {
1683 sprintf(visualIdString, " 0x%x",
1684 (unsigned int) visInfoPtr[i].visualid);
1685 strcat(buf, visualIdString);
1686 }
1687 strPtr = Tcl_NewStringObj(buf, -1);
1688 Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
1689 }
1690 XFree((char *) visInfoPtr);
1691 break;
1692 }
1693 }
1694 return TCL_OK;
1695 }
1696
1697 #if 0
1698 /*
1699 *----------------------------------------------------------------------
1700 *
1701 * Tk_WmObjCmd --
1702 *
1703 * This procedure is invoked to process the "wm" Tcl command.
1704 * See the user documentation for details on what it does.
1705 *
1706 * Results:
1707 * A standard Tcl result.
1708 *
1709 * Side effects:
1710 * See the user documentation.
1711 *
1712 *----------------------------------------------------------------------
1713 */
1714
1715 /* ARGSUSED */
1716 int
1717 Tk_WmObjCmd(clientData, interp, objc, objv)
1718 ClientData clientData; /* Main window associated with
1719 * interpreter. */
1720 Tcl_Interp *interp; /* Current interpreter. */
1721 int objc; /* Number of arguments. */
1722 Tcl_Obj *CONST objv[]; /* Argument objects. */
1723 {
1724 Tk_Window tkwin;
1725 TkWindow *winPtr;
1726
1727 static CONST char *optionStrings[] = {
1728 "aspect", "client", "command", "deiconify",
1729 "focusmodel", "frame", "geometry", "grid",
1730 "group", "iconbitmap", "iconify", "iconmask",
1731 "iconname", "iconposition", "iconwindow", "maxsize",
1732 "minsize", "overrideredirect", "positionfrom", "protocol",
1733 "resizable", "sizefrom", "state", "title",
1734 "tracing", "transient", "withdraw", (char *) NULL
1735 };
1736 enum options {
1737 TKWM_ASPECT, TKWM_CLIENT, TKWM_COMMAND, TKWM_DEICONIFY,
1738 TKWM_FOCUSMOD, TKWM_FRAME, TKWM_GEOMETRY, TKWM_GRID,
1739 TKWM_GROUP, TKWM_ICONBMP, TKWM_ICONIFY, TKWM_ICONMASK,
1740 TKWM_ICONNAME, TKWM_ICONPOS, TKWM_ICONWIN, TKWM_MAXSIZE,
1741 TKWM_MINSIZE, TKWM_OVERRIDE, TKWM_POSFROM, TKWM_PROTOCOL,
1742 TKWM_RESIZABLE, TKWM_SIZEFROM, TKWM_STATE, TKWM_TITLE,
1743 TKWM_TRACING, TKWM_TRANSIENT, TKWM_WITHDRAW
1744 };
1745
1746 tkwin = (Tk_Window) clientData;
1747
1748 if (objc < 2) {
1749 Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg?");
1750 return TCL_ERROR;
1751 }
1752 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
1753 &index) != TCL_OK) {
1754 return TCL_ERROR;
1755 }
1756
1757 if (index == TKWM_TRACING) {
1758 int wmTracing;
1759 TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
1760
1761 if ((objc != 2) && (objc != 3)) {
1762 Tcl_WrongNumArgs(interp, 1, objv, "tracing ?boolean?");
1763 return TCL_ERROR;
1764 }
1765 if (objc == 2) {
1766 Tcl_SetObjResult(interp,
1767 Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_WM_TRACING));
1768 return TCL_OK;
1769 }
1770 if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
1771 return TCL_ERROR;
1772 }
1773 if (wmTracing) {
1774 dispPtr->flags |= TK_DISPLAY_WM_TRACING;
1775 } else {
1776 dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
1777 }
1778 return TCL_OK;
1779 }
1780
1781 if (objc < 3) {
1782 Tcl_WrongNumArgs(interp, 2, objv, "window ?arg?");
1783 return TCL_ERROR;
1784 }
1785
1786 winPtr = (TkWindow *) Tk_NameToWindow(interp,
1787 Tcl_GetString(objv[2]), tkwin);
1788 if (winPtr == NULL) {
1789 return TCL_ERROR;
1790 }
1791 if (!(winPtr->flags & TK_TOP_LEVEL)) {
1792 Tcl_AppendResult(interp, "window \"", winPtr->pathName,
1793 "\" isn't a top-level window", (char *) NULL);
1794 return TCL_ERROR;
1795 }
1796
1797 switch ((enum options) index) {
1798 case TKWM_ASPECT: {
1799 TkpWmAspectCmd(interp, tkwin, winPtr, objc, objv);
1800 break;
1801 }
1802 case TKWM_CLIENT: {
1803 TkpWmClientCmd(interp, tkwin, winPtr, objc, objv);
1804 break;
1805 }
1806 case TKWM_COMMAND: {
1807 TkpWmCommandCmd(interp, tkwin, winPtr, objc, objv);
1808 break;
1809 }
1810 case TKWM_DEICONIFY: {
1811 TkpWmDeiconifyCmd(interp, tkwin, winPtr, objc, objv);
1812 break;
1813 }
1814 case TKWM_FOCUSMOD: {
1815 TkpWmFocusmodCmd(interp, tkwin, winPtr, objc, objv);
1816 break;
1817 }
1818 case TKWM_FRAME: {
1819 TkpWmFrameCmd(interp, tkwin, winPtr, objc, objv);
1820 break;
1821 }
1822 case TKWM_GEOMETRY: {
1823 TkpWmGeometryCmd(interp, tkwin, winPtr, objc, objv);
1824 break;
1825 }
1826 case TKWM_GRID: {
1827 TkpWmGridCmd(interp, tkwin, winPtr, objc, objv);
1828 break;
1829 }
1830 case TKWM_GROUP: {
1831 TkpWmGroupCmd(interp, tkwin, winPtr, objc, objv);
1832 break;
1833 }
1834 case TKWM_ICONBMP: {
1835 TkpWmIconbitmapCmd(interp, tkwin, winPtr, objc, objv);
1836 break;
1837 }
1838 case TKWM_ICONIFY: {
1839 TkpWmIconifyCmd(interp, tkwin, winPtr, objc, objv);
1840 break;
1841 }
1842 case TKWM_ICONMASK: {
1843 TkpWmIconmaskCmd(interp, tkwin, winPtr, objc, objv);
1844 break;
1845 }
1846 case TKWM_ICONNAME: {
1847 /* slight Unix variation */
1848 TkpWmIconnameCmd(interp, tkwin, winPtr, objc, objv);
1849 break;
1850 }
1851 case TKWM_ICONPOS: {
1852 /* nearly same - 1 line more on Unix */
1853 TkpWmIconpositionCmd(interp, tkwin, winPtr, objc, objv);
1854 break;
1855 }
1856 case TKWM_ICONWIN: {
1857 TkpWmIconwindowCmd(interp, tkwin, winPtr, objc, objv);
1858 break;
1859 }
1860 case TKWM_MAXSIZE: {
1861 /* nearly same, win diffs */
1862 TkpWmMaxsizeCmd(interp, tkwin, winPtr, objc, objv);
1863 break;
1864 }
1865 case TKWM_MINSIZE: {
1866 /* nearly same, win diffs */
1867 TkpWmMinsizeCmd(interp, tkwin, winPtr, objc, objv);
1868 break;
1869 }
1870 case TKWM_OVERRIDE: {
1871 /* almost same */
1872 TkpWmOverrideCmd(interp, tkwin, winPtr, objc, objv);
1873 break;
1874 }
1875 case TKWM_POSFROM: {
1876 /* Equal across platforms */
1877 TkpWmPositionfromCmd(interp, tkwin, winPtr, objc, objv);
1878 break;
1879 }
1880 case TKWM_PROTOCOL: {
1881 /* Equal across platforms */
1882 TkpWmProtocolCmd(interp, tkwin, winPtr, objc, objv);
1883 break;
1884 }
1885 case TKWM_RESIZABLE: {
1886 /* almost same */
1887 TkpWmResizableCmd(interp, tkwin, winPtr, objc, objv);
1888 break;
1889 }
1890 case TKWM_SIZEFROM: {
1891 /* Equal across platforms */
1892 TkpWmSizefromCmd(interp, tkwin, winPtr, objc, objv);
1893 break;
1894 }
1895 case TKWM_STATE: {
1896 TkpWmStateCmd(interp, tkwin, winPtr, objc, objv);
1897 break;
1898 }
1899 case TKWM_TITLE: {
1900 TkpWmTitleCmd(interp, tkwin, winPtr, objc, objv);
1901 break;
1902 }
1903 case TKWM_TRANSIENT: {
1904 TkpWmTransientCmd(interp, tkwin, winPtr, objc, objv);
1905 break;
1906 }
1907 case TKWM_WITHDRAW: {
1908 TkpWmWithdrawCmd(interp, tkwin, winPtr, objc, objv);
1909 break;
1910 }
1911 }
1912
1913 updateGeom:
1914 if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
1915 Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
1916 wmPtr->flags |= WM_UPDATE_PENDING;
1917 }
1918 return TCL_OK;
1919 }
1920 #endif
1921
1922 /*
1923 *----------------------------------------------------------------------
1924 *
1925 * TkGetDisplayOf --
1926 *
1927 * Parses a "-displayof window" option for various commands. If
1928 * present, the literal "-displayof" should be in objv[0] and the
1929 * window name in objv[1].
1930 *
1931 * Results:
1932 * The return value is 0 if the argument strings did not contain
1933 * the "-displayof" option. The return value is 2 if the
1934 * argument strings contained both the "-displayof" option and
1935 * a valid window name. Otherwise, the return value is -1 if
1936 * the window name was missing or did not specify a valid window.
1937 *
1938 * If the return value was 2, *tkwinPtr is filled with the
1939 * token for the window specified on the command line. If the
1940 * return value was -1, an error message is left in interp's
1941 * result object.
1942 *
1943 * Side effects:
1944 * None.
1945 *
1946 *----------------------------------------------------------------------
1947 */
1948
1949 int
TkGetDisplayOf(interp,objc,objv,tkwinPtr)1950 TkGetDisplayOf(interp, objc, objv, tkwinPtr)
1951 Tcl_Interp *interp; /* Interpreter for error reporting. */
1952 int objc; /* Number of arguments. */
1953 Tcl_Obj *CONST objv[]; /* Argument objects. If it is present,
1954 * "-displayof" should be in objv[0] and
1955 * objv[1] the name of a window. */
1956 Tk_Window *tkwinPtr; /* On input, contains main window of
1957 * application associated with interp. On
1958 * output, filled with window specified as
1959 * option to "-displayof" argument, or
1960 * unmodified if "-displayof" argument was not
1961 * present. */
1962 {
1963 char *string;
1964 int length;
1965
1966 if (objc < 1) {
1967 return 0;
1968 }
1969 string = Tcl_GetStringFromObj(objv[0], &length);
1970 if ((length >= 2) &&
1971 (strncmp(string, "-displayof", (unsigned) length) == 0)) {
1972 if (objc < 2) {
1973 Tcl_SetStringObj(Tcl_GetObjResult(interp),
1974 "value for \"-displayof\" missing", -1);
1975 return -1;
1976 }
1977 string = Tcl_GetStringFromObj(objv[1], NULL);
1978 *tkwinPtr = Tk_NameToWindow(interp, string, *tkwinPtr);
1979 if (*tkwinPtr == NULL) {
1980 return -1;
1981 }
1982 return 2;
1983 }
1984 return 0;
1985 }
1986
1987 /*
1988 *----------------------------------------------------------------------
1989 *
1990 * TkDeadAppCmd --
1991 *
1992 * If an application has been deleted then all Tk commands will be
1993 * re-bound to this procedure.
1994 *
1995 * Results:
1996 * A standard Tcl error is reported to let the user know that
1997 * the application is dead.
1998 *
1999 * Side effects:
2000 * See the user documentation.
2001 *
2002 *----------------------------------------------------------------------
2003 */
2004
2005 /* ARGSUSED */
2006 int
TkDeadAppCmd(clientData,interp,argc,objv)2007 TkDeadAppCmd(clientData, interp, argc, objv)
2008 ClientData clientData; /* Dummy. */
2009 Tcl_Interp *interp; /* Current interpreter. */
2010 int argc; /* Number of arguments. */
2011 Tcl_Obj *CONST *objv; /* Argument strings. */
2012 {
2013 Tcl_AppendResult(interp, "can't invoke \"", Tcl_GetString(objv[0]),
2014 "\" command: application has been destroyed", (char *) NULL);
2015 return TCL_ERROR;
2016 }
2017
2018 /*
2019 *----------------------------------------------------------------------
2020 *
2021 * GetToplevel --
2022 *
2023 * Retrieves the toplevel window which is the nearest ancestor of
2024 * of the specified window.
2025 *
2026 * Results:
2027 * Returns the toplevel window or NULL if the window has no
2028 * ancestor which is a toplevel.
2029 *
2030 * Side effects:
2031 * None.
2032 *
2033 *----------------------------------------------------------------------
2034 */
2035
2036 static TkWindow *
GetToplevel(tkwin)2037 GetToplevel(tkwin)
2038 Tk_Window tkwin; /* Window for which the toplevel should be
2039 * deterined. */
2040 {
2041 TkWindow *winPtr = (TkWindow *) tkwin;
2042
2043 while (!(winPtr->flags & TK_TOP_LEVEL)) {
2044 winPtr = winPtr->parentPtr;
2045 if (winPtr == NULL) {
2046 return NULL;
2047 }
2048 }
2049 return winPtr;
2050 }
2051
2052
2053
2054
2055
2056