tkCmds.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:53k
源码类别:

通讯编程

开发平台:

Visual C++

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