4 * This file contains a collection of Ck-related Tcl commands
5 * that didn't fit in any particular file of the toolkit.
7 * Copyright (c) 1990-1994 The Regents of the University of California.
8 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
9 * Copyright (c) 1995 Christian Werner
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
18 static char * WaitVariableProc _ANSI_ARGS_((ClientData clientData,
19 Tcl_Interp *interp, char *name1, char *name2,
21 static void WaitVisibilityProc _ANSI_ARGS_((ClientData clientData,
23 static void WaitWindowProc _ANSI_ARGS_((ClientData clientData,
28 *----------------------------------------------------------------------
32 * This procedure is invoked to process the "destroy" Tcl command.
33 * See the user documentation for details on what it does.
36 * A standard Tcl result.
39 * See the user documentation.
41 *----------------------------------------------------------------------
45 Ck_DestroyCmd(clientData, interp, argc, argv)
46 ClientData clientData; /* Main window associated with
48 Tcl_Interp *interp; /* Current interpreter. */
49 int argc; /* Number of arguments. */
50 char **argv; /* Argument strings. */
53 CkWindow *mainPtr = (CkWindow *) clientData;
56 for (i = 1; i < argc; i++) {
57 winPtr = Ck_NameToWindow(interp, argv[i], mainPtr);
60 Ck_DestroyWindow(winPtr);
66 *----------------------------------------------------------------------
70 * This procedure is invoked to process the "exit" Tcl command.
71 * See the user documentation for details on what it does.
72 * Note: this command replaces the Tcl "exit" command in order
73 * to properly destroy all windows.
76 * A standard Tcl result.
79 * See the user documentation.
81 *----------------------------------------------------------------------
85 Ck_ExitCmd(clientData, interp, argc, argv)
86 ClientData clientData; /* Main window associated with
88 Tcl_Interp *interp; /* Current interpreter. */
89 int argc; /* Number of arguments. */
90 char **argv; /* Argument strings. */
92 extern CkMainInfo *ckMainInfo;
93 int index = 1, noclear = 0, value = 0;
97 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
98 " ?-noclear? ?returnCode?\"", (char *) NULL);
101 if (argc > 1 && strcmp(argv[1], "-noclear") == 0) {
106 Tcl_GetInt(interp, argv[index], &value) != TCL_OK) {
110 if (ckMainInfo != NULL) {
112 ckMainInfo->flags |= CK_NOCLR_ON_EXIT;
114 ckMainInfo->flags &= ~CK_NOCLR_ON_EXIT;
116 Ck_DestroyWindow((CkWindow *) clientData);
118 endwin(); /* just in case */
119 #if (TCL_MAJOR_VERSION >= 8)
129 *----------------------------------------------------------------------
133 * This procedure is invoked to process the "lower" Tcl command.
134 * See the user documentation for details on what it does.
137 * A standard Tcl result.
140 * See the user documentation.
142 *----------------------------------------------------------------------
146 Ck_LowerCmd(clientData, interp, argc, argv)
147 ClientData clientData; /* Main window associated with
149 Tcl_Interp *interp; /* Current interpreter. */
150 int argc; /* Number of arguments. */
151 char **argv; /* Argument strings. */
153 CkWindow *mainPtr = (CkWindow *) clientData;
154 CkWindow *winPtr, *other;
156 if ((argc != 2) && (argc != 3)) {
157 Tcl_AppendResult(interp, "wrong # args: should be \"",
158 argv[0], " window ?belowThis?\"", (char *) NULL);
162 winPtr = Ck_NameToWindow(interp, argv[1], mainPtr);
168 other = Ck_NameToWindow(interp, argv[2], mainPtr);
172 if (Ck_RestackWindow(winPtr, CK_BELOW, other) != TCL_OK) {
173 Tcl_AppendResult(interp, "can't lower \"", argv[1], "\" below \"",
174 argv[2], "\"", (char *) NULL);
181 *----------------------------------------------------------------------
185 * This procedure is invoked to process the "raise" Tcl command.
186 * See the user documentation for details on what it does.
189 * A standard Tcl result.
192 * See the user documentation.
194 *----------------------------------------------------------------------
198 Ck_RaiseCmd(clientData, interp, argc, argv)
199 ClientData clientData; /* Main window associated with
201 Tcl_Interp *interp; /* Current interpreter. */
202 int argc; /* Number of arguments. */
203 char **argv; /* Argument strings. */
205 CkWindow *mainPtr = (CkWindow *) clientData;
206 CkWindow *winPtr, *other;
208 if ((argc != 2) && (argc != 3)) {
209 Tcl_AppendResult(interp, "wrong # args: should be \"",
210 argv[0], " window ?aboveThis?\"", (char *) NULL);
214 winPtr = Ck_NameToWindow(interp, argv[1], mainPtr);
220 other = Ck_NameToWindow(interp, argv[2], mainPtr);
224 if (Ck_RestackWindow(winPtr, CK_ABOVE, other) != TCL_OK) {
225 Tcl_AppendResult(interp, "can't raise \"", argv[1], "\" above \"",
226 argv[2], "\"", (char *) NULL);
233 *----------------------------------------------------------------------
237 * This procedure is invoked to process the "bell" Tcl command.
238 * See the user documentation for details on what it does.
241 * A standard Tcl result.
244 * See the user documentation.
246 *----------------------------------------------------------------------
250 Ck_BellCmd(clientData, interp, argc, argv)
251 ClientData clientData; /* Main window associated with
253 Tcl_Interp *interp; /* Current interpreter. */
254 int argc; /* Number of arguments. */
255 char **argv; /* Argument strings. */
263 *----------------------------------------------------------------------
267 * This procedure is invoked to process the "update" Tcl command.
268 * See the user documentation for details on what it does.
271 * A standard Tcl result.
274 * See the user documentation.
276 *----------------------------------------------------------------------
280 Ck_UpdateCmd(clientData, interp, argc, argv)
281 ClientData clientData; /* Main window associated with
283 Tcl_Interp *interp; /* Current interpreter. */
284 int argc; /* Number of arguments. */
285 char **argv; /* Argument strings. */
287 CkWindow *mainPtr = (CkWindow *) clientData;
291 flags = TK_DONT_WAIT;
292 else if (argc == 2) {
293 if (strncmp(argv[1], "screen", strlen(argv[1])) == 0) {
295 Ck_EventuallyRefresh(mainPtr);
298 if (strncmp(argv[1], "idletasks", strlen(argv[1])) != 0) {
299 Tcl_AppendResult(interp, "bad argument \"", argv[1],
300 "\": must be idletasks or screen", (char *) NULL);
303 flags = TK_IDLE_EVENTS;
305 Tcl_AppendResult(interp, "wrong # args: should be \"",
306 argv[0], " ?idletasks|screen?\"", (char *) NULL);
311 * Handle all pending events, and repeat over and over
312 * again until all pending events have been handled.
315 while (Tk_DoOneEvent(flags) != 0) {
316 /* Empty loop body */
320 * Must clear the interpreter's result because event handlers could
321 * have executed commands.
324 Tcl_ResetResult(interp);
329 *----------------------------------------------------------------------
333 * This procedure is invoked to process the "curses" Tcl command.
334 * See the user documentation for details on what it does.
337 * A standard Tcl result.
340 * See the user documentation.
342 *----------------------------------------------------------------------
346 Ck_CursesCmd(clientData, interp, argc, argv)
347 ClientData clientData; /* Main window associated with
349 Tcl_Interp *interp; /* Current interpreter. */
350 int argc; /* Number of arguments. */
351 char **argv; /* Argument strings. */
353 CkWindow *winPtr = (CkWindow *) clientData;
354 CkMainInfo *mainPtr = winPtr->mainPtr;
359 Tcl_AppendResult(interp, "wrong # args: should be \"",
360 argv[0], " option ?arg?\"", (char *) NULL);
364 length = strlen(argv[1]);
365 if ((c == 'b') && (strncmp(argv[1], "barcode", length) == 0)) {
366 return CkBarcodeCmd(clientData, interp, argc, argv);
367 } else if ((c == 'b') && (strncmp(argv[1], "baudrate", length) == 0)) {
371 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
372 " ", argv[1], "\"", (char *) NULL);
375 sprintf(buf, "%d", baudrate());
376 Tcl_AppendResult(interp, buf, (char *) NULL);
378 } else if ((c == 'e') && (strncmp(argv[1], "encoding", length) == 0)) {
380 return Ck_GetEncoding(interp);
382 return Ck_SetEncoding(interp, argv[2]);
384 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
385 " ", argv[1], " ?name?\"", (char *) NULL);
388 } else if ((c == 'g') && (strncmp(argv[1], "gchar", length) == 0)) {
392 if (Ck_GetGChar(interp, argv[2], &gchar) != TCL_OK)
394 sprintf(interp->result, "%d", gchar);
395 } else if (argc == 4) {
396 if (Tcl_GetInt(interp, argv[3], &gchar) != TCL_OK)
398 if (Ck_SetGChar(interp, argv[2], gchar) != TCL_OK)
401 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
402 " ", argv[1], " charName ?value?\"", (char *) NULL);
405 } else if ((c == 'h') && (strncmp(argv[1], "haskey", length) == 0)) {
407 Tcl_AppendResult(interp, "wrong # args: should be \"",
408 argv[0], " haskey ?keySym?\"", (char *) NULL);
412 return CkAllKeyNames(interp);
413 return CkTermHasKey(interp, argv[2]);
414 } else if ((c == 'p') && (strncmp(argv[1], "purgeinput", length) == 0)) {
416 Tcl_AppendResult(interp, "wrong # args: should be \"",
417 argv[0], " purgeinput\"", (char *) NULL);
420 while (getch() != ERR) {
421 /* Empty loop body. */
424 } else if ((c == 'r') && (strncmp(argv[1], "refreshdelay", length) == 0)) {
428 sprintf(buf, "%d", mainPtr->refreshDelay);
429 Tcl_AppendResult(interp, buf, (char *) NULL);
431 } else if (argc == 3) {
434 if (Tcl_GetInt(interp, argv[2], &delay) != TCL_OK)
436 mainPtr->refreshDelay = delay < 0 ? 0 : delay;
439 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
440 " ", argv[1], " ?milliseconds?\"", (char *) NULL);
443 } else if ((c == 'r') && (strncmp(argv[1], "reversekludge", length)
448 interp->result = (mainPtr->flags & CK_REVERSE_KLUDGE) ?
450 } else if (argc == 3) {
451 if (Tcl_GetBoolean(interp, argv[2], &onoff) != TCL_OK)
453 mainPtr->flags |= CK_REVERSE_KLUDGE;
455 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
456 " ", argv[1], " ?bool?\"", (char *) NULL);
459 } else if ((c == 's') && (strncmp(argv[1], "screendump", length) == 0)) {
467 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
468 " ", argv[1], " filename\"", (char *) NULL);
471 fileName = Tcl_TildeSubst(interp, argv[2], &buffer);
472 if (fileName == NULL) {
473 Tcl_DStringFree(&buffer);
477 ret = scr_dump(fileName);
478 Tcl_DStringFree(&buffer);
480 interp->result = "screen dump failed";
485 interp->result = "screen dump not supported by this curses";
488 } else if ((c == 's') && (strncmp(argv[1], "suspend", length) == 0)) {
490 Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
491 " ", argv[1], "\"", (char *) NULL);
494 #if !defined(__WIN32__) && !defined(DJGPP)
498 kill(getpid(), SIGTSTP);
500 kill(getpid(), SIGSTOP);
502 Ck_EventuallyRefresh(winPtr);
505 Tcl_AppendResult(interp, "bad option \"", argv[1],
506 "\": must be barcode, baudrate, encoding, gchar, haskey, ",
507 "purgeinput, refreshdelay, reversekludge, screendump or suspend",
515 *----------------------------------------------------------------------
519 * This procedure is invoked to process the "winfo" Tcl command.
520 * See the user documentation for details on what it does.
523 * A standard Tcl result.
526 * See the user documentation.
528 *----------------------------------------------------------------------
532 Ck_WinfoCmd(clientData, interp, argc, argv)
533 ClientData clientData; /* Main window associated with
535 Tcl_Interp *interp; /* Current interpreter. */
536 int argc; /* Number of arguments. */
537 char **argv; /* Argument strings. */
539 CkWindow *mainPtr = (CkWindow *) clientData;
544 #define SETUP(name) \
549 winPtr = Ck_NameToWindow(interp, argv[2], mainPtr); \
550 if (winPtr == NULL) { \
556 Tcl_AppendResult(interp, "wrong # args: should be \"",
557 argv[0], " option ?arg?\"", (char *) NULL);
561 length = strlen(argv[1]);
562 if ((c == 'c') && (strncmp(argv[1], "children", length) == 0)
565 for (winPtr = winPtr->childList; winPtr != NULL;
566 winPtr = winPtr->nextPtr) {
567 Tcl_AppendElement(interp, winPtr->pathName);
569 } else if ((c == 'c') && (strncmp(argv[1], "containing", length) == 0)
573 argName = "containing";
576 if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK ||
577 Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
580 winPtr = Ck_GetWindowXY(mainPtr->mainPtr, &x, &y, 0);
581 if (winPtr != NULL) {
582 interp->result = winPtr->pathName;
584 } else if ((c == 'd') && (strncmp(argv[1], "depth", length) == 0)) {
586 interp->result = (winPtr->mainPtr->flags & CK_HAS_COLOR) ? "3" : "1";
587 } else if ((c == 'e') && (strncmp(argv[1], "exists", length) == 0)) {
592 if (Ck_NameToWindow(interp, argv[2], mainPtr) == NULL) {
593 interp->result = "0";
595 interp->result = "1";
597 } else if ((c == 'g') && (strncmp(argv[1], "geometry", length) == 0)) {
599 sprintf(interp->result, "%dx%d+%d+%d", winPtr->width,
600 winPtr->height, winPtr->x, winPtr->y);
601 } else if ((c == 'h') && (strncmp(argv[1], "height", length) == 0)) {
603 sprintf(interp->result, "%d", winPtr->height);
604 } else if ((c == 'i') && (strncmp(argv[1], "ismapped", length) == 0)
607 interp->result = (winPtr->flags & CK_MAPPED) ? "1" : "0";
608 } else if ((c == 'm') && (strncmp(argv[1], "manager", length) == 0)) {
610 if (winPtr->geomMgrPtr != NULL)
611 interp->result = winPtr->geomMgrPtr->name;
612 } else if ((c == 'n') && (strncmp(argv[1], "name", length) == 0)) {
614 interp->result = (char *) winPtr->nameUid;
615 } else if ((c == 'c') && (strncmp(argv[1], "class", length) == 0)) {
617 interp->result = (char *) winPtr->classUid;
618 } else if ((c == 'p') && (strncmp(argv[1], "parent", length) == 0)) {
620 if (winPtr->parentPtr != NULL)
621 interp->result = winPtr->parentPtr->pathName;
622 } else if ((c == 'r') && (strncmp(argv[1], "reqheight", length) == 0)
625 sprintf(interp->result, "%d", winPtr->reqHeight);
626 } else if ((c == 'r') && (strncmp(argv[1], "reqwidth", length) == 0)
629 sprintf(interp->result, "%d", winPtr->reqWidth);
630 } else if ((c == 'r') && (strncmp(argv[1], "rootx", length) == 0)
635 Ck_GetRootGeometry(winPtr, &x, NULL, NULL, NULL);
636 sprintf(interp->result, "%d", x);
637 } else if ((c == 'r') && (strncmp(argv[1], "rooty", length) == 0)
642 Ck_GetRootGeometry(winPtr, NULL, &y, NULL, NULL);
643 sprintf(interp->result, "%d", y);
644 } else if ((c == 's') && (strncmp(argv[1], "screenheight", length) == 0)
646 SETUP("screenheight");
647 sprintf(interp->result, "%d", winPtr->mainPtr->winPtr->height);
648 } else if ((c == 's') && (strncmp(argv[1], "screenwidth", length) == 0)
650 SETUP("screenwidth");
651 sprintf(interp->result, "%d", winPtr->mainPtr->winPtr->width);
652 } else if ((c == 't') && (strncmp(argv[1], "toplevel", length) == 0)) {
654 for (; winPtr != NULL; winPtr = winPtr->parentPtr) {
655 if (winPtr->flags & CK_TOPLEVEL) {
656 interp->result = winPtr->pathName;
660 } else if ((c == 'w') && (strncmp(argv[1], "width", length) == 0)) {
662 sprintf(interp->result, "%d", winPtr->width);
663 } else if ((c == 'x') && (argv[1][1] == '\0')) {
665 sprintf(interp->result, "%d", winPtr->x);
666 } else if ((c == 'y') && (argv[1][1] == '\0')) {
668 sprintf(interp->result, "%d", winPtr->y);
670 Tcl_AppendResult(interp, "bad option \"", argv[1],
671 "\": must be children, class, containing, depth ",
672 "exists, geometry, height, ",
673 "ismapped, manager, name, parent, ",
674 "reqheight, reqwidth, rootx, rooty, ",
675 "screenheight, screenwidth, ",
676 "toplevel, width, x, or y", (char *) NULL);
682 Tcl_AppendResult(interp, "wrong # arguments: must be \"",
683 argv[0], " ", argName, " window\"", (char *) NULL);
688 *----------------------------------------------------------------------
692 * This procedure is invoked to process the "bind" Tcl command.
693 * See the user documentation for details on what it does.
696 * A standard Tcl result.
699 * See the user documentation.
701 *----------------------------------------------------------------------
705 Ck_BindCmd(clientData, interp, argc, argv)
706 ClientData clientData; /* Main window associated with interpreter. */
707 Tcl_Interp *interp; /* Current interpreter. */
708 int argc; /* Number of arguments. */
709 char **argv; /* Argument strings. */
711 CkWindow *mainWin = (CkWindow *) clientData;
715 if ((argc < 2) || (argc > 4)) {
716 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
717 " window ?pattern? ?command?\"", (char *) NULL);
720 if (argv[1][0] == '.') {
721 winPtr = (CkWindow *) Ck_NameToWindow(interp, argv[1], mainWin);
722 if (winPtr == NULL) {
725 object = (ClientData) winPtr->pathName;
727 winPtr = (CkWindow *) clientData;
728 object = (ClientData) Ck_GetUid(argv[1]);
734 if (argv[3][0] == 0) {
735 return Ck_DeleteBinding(interp, winPtr->mainPtr->bindingTable,
738 if (argv[3][0] == '+') {
742 if (Ck_CreateBinding(interp, winPtr->mainPtr->bindingTable,
743 object, argv[2], argv[3], append) != TCL_OK) {
746 } else if (argc == 3) {
749 command = Ck_GetBinding(interp, winPtr->mainPtr->bindingTable,
751 if (command == NULL) {
752 Tcl_ResetResult(interp);
755 interp->result = command;
757 Ck_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
763 *----------------------------------------------------------------------
767 * This procedure is invoked by Ck_HandleEvent for each event; it
768 * causes any appropriate bindings for that event to be invoked.
774 * Depends on what bindings have been established with the "bind"
777 *----------------------------------------------------------------------
781 CkBindEventProc(winPtr, eventPtr)
782 CkWindow *winPtr; /* Pointer to info about window. */
783 CkEvent *eventPtr; /* Information about event. */
786 ClientData objects[MAX_OBJS], *objPtr;
787 static Ck_Uid allUid = NULL;
793 if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) {
798 if (winPtr->numTags != 0) {
800 * Make a copy of the tags for the window, replacing window names
801 * with pointers to the pathName from the appropriate window.
804 if (winPtr->numTags > MAX_OBJS) {
805 objPtr = (ClientData *) ckalloc(winPtr->numTags *
806 sizeof (ClientData));
808 for (i = 0; i < winPtr->numTags; i++) {
809 p = (char *) winPtr->tagPtr[i];
811 hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
813 p = ((CkWindow *) Tcl_GetHashValue(hPtr))->pathName;
818 objPtr[i] = (ClientData) p;
820 count = winPtr->numTags;
822 objPtr[0] = (ClientData) winPtr->pathName;
823 objPtr[1] = (ClientData) winPtr->classUid;
824 for (topLevPtr = winPtr; topLevPtr != NULL &&
825 !(topLevPtr->flags & CK_TOPLEVEL);
826 topLevPtr = topLevPtr->parentPtr) {
827 /* Empty loop body. */
829 if (winPtr != topLevPtr && topLevPtr != NULL) {
830 objPtr[2] = (ClientData) topLevPtr->pathName;
834 if (allUid == NULL) {
835 allUid = Ck_GetUid("all");
837 objPtr[count - 1] = (ClientData) allUid;
839 Ck_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, winPtr,
841 if (objPtr != objects) {
842 ckfree((char *) objPtr);
847 *----------------------------------------------------------------------
851 * This procedure is invoked to process the "bindtags" Tcl command.
852 * See the user documentation for details on what it does.
855 * A standard Tcl result.
858 * See the user documentation.
860 *----------------------------------------------------------------------
864 Ck_BindtagsCmd(clientData, interp, argc, argv)
865 ClientData clientData; /* Main window associated with interpreter. */
866 Tcl_Interp *interp; /* Current interpreter. */
867 int argc; /* Number of arguments. */
868 char **argv; /* Argument strings. */
870 CkWindow *mainWin = (CkWindow *) clientData;
871 CkWindow *winPtr, *winPtr2;
875 if ((argc < 2) || (argc > 3)) {
876 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
877 " window ?tags?\"", (char *) NULL);
880 winPtr = (CkWindow *) Ck_NameToWindow(interp, argv[1], mainWin);
881 if (winPtr == NULL) {
885 if (winPtr->numTags == 0) {
886 Tcl_AppendElement(interp, winPtr->pathName);
887 Tcl_AppendElement(interp, winPtr->classUid);
888 for (winPtr2 = winPtr; winPtr2 != NULL &&
889 !(winPtr2->flags & CK_TOPLEVEL);
890 winPtr2 = winPtr2->parentPtr) {
891 /* Empty loop body. */
893 if (winPtr != winPtr2 && winPtr2 != NULL)
894 Tcl_AppendElement(interp, winPtr2->pathName);
895 Tcl_AppendElement(interp, "all");
897 for (i = 0; i < winPtr->numTags; i++) {
898 Tcl_AppendElement(interp, (char *) winPtr->tagPtr[i]);
903 if (winPtr->tagPtr != NULL) {
904 CkFreeBindingTags(winPtr);
906 if (argv[2][0] == 0) {
909 if (Tcl_SplitList(interp, argv[2], &tagArgc, &tagArgv) != TCL_OK) {
912 winPtr->numTags = tagArgc;
913 winPtr->tagPtr = (ClientData *) ckalloc(tagArgc * sizeof(ClientData));
914 for (i = 0; i < tagArgc; i++) {
920 * Handle names starting with "." specially: store a malloc'ed
921 * string, rather than a Uid; at event time we'll look up the
922 * name in the window table and use the corresponding window,
926 copy = (char *) ckalloc((unsigned) (strlen(p) + 1));
928 winPtr->tagPtr[i] = (ClientData) copy;
930 winPtr->tagPtr[i] = (ClientData) Ck_GetUid(p);
933 ckfree((char *) tagArgv);
938 *----------------------------------------------------------------------
940 * CkFreeBindingTags --
942 * This procedure is called to free all of the binding tags
943 * associated with a window; typically it is only invoked where
944 * there are window-specific tags.
950 * Any binding tags for winPtr are freed.
952 *----------------------------------------------------------------------
956 CkFreeBindingTags(winPtr)
957 CkWindow *winPtr; /* Window whose tags are to be released. */
962 for (i = 0; i < winPtr->numTags; i++) {
963 p = (char *) (winPtr->tagPtr[i]);
966 * Names starting with "." are malloced rather than Uids, so
967 * they have to be freed.
973 ckfree((char *) winPtr->tagPtr);
975 winPtr->tagPtr = NULL;
979 *----------------------------------------------------------------------
983 * This procedure is invoked to process the "tkwait" Tcl command.
984 * See the user documentation for details on what it does.
987 * A standard Tcl result.
990 * See the user documentation.
992 *----------------------------------------------------------------------
996 Ck_TkwaitCmd(clientData, interp, argc, argv)
997 ClientData clientData; /* Main window associated with
999 Tcl_Interp *interp; /* Current interpreter. */
1000 int argc; /* Number of arguments. */
1001 char **argv; /* Argument strings. */
1003 CkWindow *mainPtr = (CkWindow *) clientData;
1008 Tcl_AppendResult(interp, "wrong # args: should be \"",
1009 argv[0], " variable|visible|window name\"", (char *) NULL);
1013 length = strlen(argv[1]);
1014 if ((c == 'v') && (strncmp(argv[1], "variable", length) == 0)
1016 if (Tcl_TraceVar(interp, argv[2],
1017 TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
1018 WaitVariableProc, (ClientData) &done) != TCL_OK) {
1025 Tcl_UntraceVar(interp, argv[2],
1026 TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
1027 WaitVariableProc, (ClientData) &done);
1028 } else if ((c == 'v') && (strncmp(argv[1], "visibility", length) == 0)
1032 winPtr = Ck_NameToWindow(interp, argv[2], mainPtr);
1033 if (winPtr == NULL) {
1036 Ck_CreateEventHandler(winPtr,
1037 CK_EV_MAP | CK_EV_UNMAP | CK_EV_EXPOSE | CK_EV_DESTROY,
1038 WaitVisibilityProc, (ClientData) &done);
1043 Ck_DeleteEventHandler(winPtr,
1044 CK_EV_MAP | CK_EV_UNMAP | CK_EV_EXPOSE | CK_EV_DESTROY,
1045 WaitVisibilityProc, (ClientData) &done);
1046 } else if ((c == 'w') && (strncmp(argv[1], "window", length) == 0)) {
1049 winPtr = Ck_NameToWindow(interp, argv[2], mainPtr);
1050 if (winPtr == NULL) {
1053 Ck_CreateEventHandler(winPtr, CK_EV_DESTROY,
1054 WaitWindowProc, (ClientData) &done);
1060 * Note: there's no need to delete the event handler. It was
1061 * deleted automatically when the window was destroyed.
1064 Tcl_AppendResult(interp, "bad option \"", argv[1],
1065 "\": must be variable, visibility, or window", (char *) NULL);
1070 * Clear out the interpreter's result, since it may have been set
1071 * by event handlers.
1074 Tcl_ResetResult(interp);
1079 WaitVariableProc(clientData, interp, name1, name2, flags)
1080 ClientData clientData; /* Pointer to integer to set to 1. */
1081 Tcl_Interp *interp; /* Interpreter containing variable. */
1082 char *name1; /* Name of variable. */
1083 char *name2; /* Second part of variable name. */
1084 int flags; /* Information about what happened. */
1086 int *donePtr = (int *) clientData;
1089 return (char *) NULL;
1093 WaitVisibilityProc(clientData, eventPtr)
1094 ClientData clientData; /* Pointer to integer to set to 1. */
1095 CkEvent *eventPtr; /* Information about event (not used). */
1097 int *donePtr = (int *) clientData;
1103 WaitWindowProc(clientData, eventPtr)
1104 ClientData clientData; /* Pointer to integer to set to 1. */
1105 CkEvent *eventPtr; /* Information about event. */
1107 int *donePtr = (int *) clientData;
1109 if (eventPtr->type == CK_EV_DESTROY) {