home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / misc / shell.c < prev    next >
C/C++ Source or Header  |  1993-01-01  |  16KB  |  698 lines

  1. /*
  2.  * Copyright (c) 1993 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. /**********************************************************************/
  23. /*
  24.  *  The variable below is the default prompt, stored in the "prompt"
  25.  *  variable
  26.  */
  27.  
  28. #define PROMPT  "grabsh: "
  29. /**********************************************************************/
  30.  
  31. #include "tk.h"
  32.  
  33. #include "all.h"
  34.  
  35. #include <sys/time.h>
  36. #include <sys/param.h>
  37. #include <string.h>
  38.  
  39.  
  40. /* from frames.h */
  41. #define USE_MAD        0
  42. #define USE_MSE        1
  43.  
  44. #define USE_HALF    0
  45. #define USE_FULL    1
  46.  
  47. /**********************************************************************/
  48.  
  49. /*
  50.  * Command used to initialize wish:
  51.  */
  52.  
  53. char initCmd[] = "source $tk_library/wish.tcl";
  54.  
  55. Tk_Window w;            /* NULL means window has been deleted. */
  56. Tk_TimerToken timeToken = 0;
  57. int idleHandler = 0;
  58. Tcl_Interp *interp;
  59. int x, y;
  60. Tcl_CmdBuf buffer;
  61. int tty;
  62. extern int Tk_SquareCmd _ANSI_ARGS_((ClientData clientData,
  63.     Tcl_Interp *interp, int argc, char **argv));
  64. extern int ListDirectory _ANSI_ARGS_((ClientData nulldata, Tcl_Interp *interp,
  65.              int argc, char **argv));
  66. extern int ChangeDirectory _ANSI_ARGS_((ClientData nulldata, Tcl_Interp *interp,
  67.              int argc, char **argv));
  68. extern int SetBrowseGlob _ANSI_ARGS_((ClientData nulldata, Tcl_Interp *interp,
  69.            int argc, char **argv));
  70.  
  71.  
  72. /*
  73.  * ENCODING PARAMETERS
  74.  *
  75.  */
  76. int numInputFiles = 0;
  77. char *inputFiles[1024];        /* should change */
  78. char currentPath[MAXPATHLEN];
  79.  
  80. static char    outputFileName[256];
  81. static char    inputConversion[1024];
  82. static char    pixelSearch[1024];
  83. static char    pattern[1024];
  84. static int IQScale, PQScale, BQScale;
  85. static int searchRange;
  86. static char    Psearch[1024];
  87. static char    Bsearch[1024];
  88. static char    conversion[1024];
  89. static char    format[1024];
  90. static int    gopSize;
  91. static int    spf;
  92. static int    height, width;
  93.  
  94.  
  95. int SetOutputFileName (nulldata, interp, argc, argv)
  96. ClientData nulldata;
  97. Tcl_Interp *interp;
  98. int argc;
  99. char **argv;
  100. {
  101.     if (argc == 2 )
  102.     {
  103.     strcpy(outputFileName, argv[1]);
  104.  
  105.     numInputFiles = 0;
  106.  
  107.     return TCL_OK;
  108.     }
  109.  
  110.     Tcl_AppendResult (interp, 
  111.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  112.     return TCL_ERROR;
  113. }
  114.  
  115.  
  116. int SetConversion (nulldata, interp, argc, argv)
  117. ClientData nulldata;
  118. Tcl_Interp *interp;
  119. int argc;
  120. char **argv;
  121. {
  122.     if (argc == 2 )
  123.     {
  124.     strcpy(conversion, argv[1]);
  125.     return TCL_OK;
  126.     }
  127.  
  128.     Tcl_AppendResult (interp, 
  129.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  130.     return TCL_ERROR;
  131. }
  132.  
  133.  
  134. int SetGOPSize (nulldata, interp, argc, argv)
  135. ClientData nulldata;
  136. Tcl_Interp *interp;
  137. int argc;
  138. char **argv;
  139. {
  140.     if (argc == 2 )
  141.     {
  142.     gopSize = atoi(argv[1]);
  143.     return TCL_OK;
  144.     }
  145.  
  146.     Tcl_AppendResult (interp, 
  147.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  148.     return TCL_ERROR;
  149. }
  150.  
  151.  
  152. int SetSPF (nulldata, interp, argc, argv)
  153. ClientData nulldata;
  154. Tcl_Interp *interp;
  155. int argc;
  156. char **argv;
  157. {
  158.     if (argc == 2 )
  159.     {
  160.     spf = atoi(argv[1]);
  161.     return TCL_OK;
  162.     }
  163.  
  164.     Tcl_AppendResult (interp, 
  165.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  166.     return TCL_ERROR;
  167. }
  168.  
  169.  
  170. int SetDimensions (nulldata, interp, argc, argv)
  171. ClientData nulldata;
  172. Tcl_Interp *interp;
  173. int argc;
  174. char **argv;
  175. {
  176.     if (argc == 3 )
  177.     {
  178.     width = atoi(argv[1]);
  179.     height = atoi(argv[2]);
  180.     return TCL_OK;
  181.     }
  182.  
  183.     Tcl_AppendResult (interp, 
  184.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  185.     return TCL_ERROR;
  186. }
  187.  
  188.  
  189. int SetPatternString (nulldata, interp, argc, argv)
  190. ClientData nulldata;
  191. Tcl_Interp *interp;
  192. int argc;
  193. char **argv;
  194. {
  195.     if (argc == 2 )
  196.     {
  197.     strcpy(pattern, argv[1]);
  198.  
  199.     return TCL_OK;
  200.     }
  201.  
  202.     Tcl_AppendResult (interp, 
  203.             "wrong args: should be \"", argv[0]," filename\"", (char *) NULL);
  204.     return TCL_ERROR;
  205. }
  206.  
  207.  
  208. int EncodeCmd (nulldata, interp, argc, argv)
  209. ClientData nulldata;
  210. Tcl_Interp *interp;
  211. int argc;
  212. char **argv;
  213. {
  214.     if (argc == 1 )
  215.     {
  216.     FILE *fpointer;
  217.     register int index;
  218.  
  219.     fpointer = fopen("tcl.param", "w");
  220.         fprintf(fpointer, "# mpeg_encode parameter file created by tcl interface\n");
  221.         fprintf(fpointer, "PATTERN\t%s\n", pattern);
  222.         fprintf(fpointer, "OUTPUT\t%s\n", outputFileName);
  223.         fprintf(fpointer, "BASE_FILE_FORMAT\t%s\n", format);
  224.         fprintf(fpointer, "GOP_SIZE\t%d\n", gopSize);
  225.         fprintf(fpointer, "SLICES_PER_FRAME\t%d\n", spf);
  226.         fprintf(fpointer, "PIXEL\t%s\n", pixelSearch);
  227.         fprintf(fpointer, "RANGE\t%d\n", searchRange);
  228.         fprintf(fpointer, "PSEARCH_ALG\t%s\n", Psearch);
  229.         fprintf(fpointer, "BSEARCH_ALG\t%s\n", Bsearch);
  230.         fprintf(fpointer, "IQSCALE\t%d\n", IQScale);
  231.         fprintf(fpointer, "PQSCALE\t%d\n", PQScale);
  232.         fprintf(fpointer, "BQSCALE\t%d\n", BQScale);
  233.         fprintf(fpointer, "YUV_SIZE\t%dx%d\n", width, height);
  234.         fprintf(fpointer, "INPUT_CONVERT\t%s\n", conversion);
  235.         fprintf(fpointer, "INPUT_DIR\t%s\n", currentPath);
  236.         fprintf(fpointer, "INPUT\n");
  237.         for ( index = 0; index < numInputFiles; index++ )
  238.         fprintf(fpointer, "%s\n", inputFiles[index]);
  239.         fprintf(fpointer, "END_INPUT\n");
  240.         fprintf(fpointer, "REFERENCE_FRAME ORIGINAL\n");
  241.     fclose(fpointer);
  242.  
  243.     system("mpeg_encode tcl.param");
  244.  
  245.     return TCL_OK;
  246.     }
  247.  
  248.     Tcl_AppendResult (interp, 
  249.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  250.     return TCL_ERROR;
  251. }
  252.  
  253.  
  254. int SetPixelSearchCmd (nulldata, interp, argc, argv)
  255. ClientData nulldata;
  256. Tcl_Interp *interp;
  257. int argc;
  258. char **argv;
  259. {
  260.     if (argc == 2 )
  261.     {
  262.     strcpy(pixelSearch, argv[1]);
  263.  
  264.     return TCL_OK;
  265.     }
  266.  
  267.     Tcl_AppendResult (interp, 
  268.             "wrong args: should be \"", argv[0]," type\"", (char *) NULL);
  269.     return TCL_ERROR;
  270. }
  271.  
  272.  
  273.  
  274. int SetSearchRangeCmd (nulldata, interp, argc, argv)
  275. ClientData nulldata;
  276. Tcl_Interp *interp;
  277. int argc;
  278. char **argv;
  279. {
  280.     if (argc == 2 )
  281.     {
  282.     searchRange = atoi(argv[1]);
  283.  
  284.     return TCL_OK;
  285.     }
  286.  
  287.     Tcl_AppendResult (interp, 
  288.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  289.     return TCL_ERROR;
  290. }
  291.  
  292.  
  293. int SetPSearchCmd (nulldata, interp, argc, argv)
  294. ClientData nulldata;
  295. Tcl_Interp *interp;
  296. int argc;
  297. char **argv;
  298. {
  299.     if (argc == 2 )
  300.     {
  301.     strcpy(Psearch, argv[1]);
  302.  
  303.     return TCL_OK;
  304.     }
  305.  
  306.     Tcl_AppendResult (interp, 
  307.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  308.     return TCL_ERROR;
  309. }
  310.  
  311.  
  312. int SetFormatCmd (nulldata, interp, argc, argv)
  313. ClientData nulldata;
  314. Tcl_Interp *interp;
  315. int argc;
  316. char **argv;
  317. {
  318.     if (argc == 2 )
  319.     {
  320.     strcpy(format, argv[1]);
  321.  
  322.     return TCL_OK;
  323.     }
  324.  
  325.     Tcl_AppendResult (interp, 
  326.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  327.     return TCL_ERROR;
  328. }
  329.  
  330.  
  331. int SetBSearchCmd (nulldata, interp, argc, argv)
  332. ClientData nulldata;
  333. Tcl_Interp *interp;
  334. int argc;
  335. char **argv;
  336. {
  337.     if (argc == 2 )
  338.     {
  339.     strcpy(Bsearch, argv[1]);
  340.  
  341.     return TCL_OK;
  342.     }
  343.  
  344.     Tcl_AppendResult (interp, 
  345.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  346.     return TCL_ERROR;
  347. }
  348.  
  349.  
  350. int SetQScaleCmd (nulldata, interp, argc, argv)
  351. ClientData nulldata;
  352. Tcl_Interp *interp;
  353. int argc;
  354. char **argv;
  355. {
  356.     if (argc == 4 )
  357.     {
  358.     IQScale = atoi(argv[1]);
  359.     PQScale = atoi(argv[2]);
  360.     BQScale = atoi(argv[3]);
  361.  
  362.     return TCL_OK;
  363.     }
  364.  
  365.     Tcl_AppendResult (interp, 
  366.             "wrong args: should be \"", argv[0]," 3nums\"", (char *) NULL);
  367.     return TCL_ERROR;
  368. }
  369.  
  370.  
  371. int NextInputFile (nulldata, interp, argc, argv)
  372. ClientData nulldata;
  373. Tcl_Interp *interp;
  374. int argc;
  375. char **argv;
  376. {
  377.     if (argc == 2 )
  378.     {
  379.     inputFiles[numInputFiles] = (char *) malloc(256*sizeof(char));
  380.  
  381.     strcpy(inputFiles[numInputFiles], argv[1]);
  382.     numInputFiles++;
  383.  
  384.     return TCL_OK;
  385.     }
  386.  
  387.     Tcl_AppendResult (interp, 
  388.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  389.     return TCL_ERROR;
  390. }
  391.  
  392.  
  393. int PlayOutput (nulldata, interp, argc, argv)
  394. ClientData nulldata;
  395. Tcl_Interp *interp;
  396. int argc;
  397. char **argv;
  398. {
  399.     char command[256];
  400.  
  401.     /* ignore argc, argv */
  402.     sprintf(command, "mpeg_play %s", outputFileName);
  403.     fprintf(stdout, "DOING:  %s\n", command);
  404.  
  405.     system(command);
  406.  
  407.     return TCL_OK;
  408. }
  409.  
  410.  
  411. /*
  412.  * Information for testing out command-line options:
  413.  */
  414.  
  415. int synchronize = 0;
  416. char *fileName = NULL;
  417. char *name = NULL;
  418. char *display = NULL;
  419. char *geometry = NULL;
  420.  
  421. Tk_ArgvInfo argTable[] = {
  422.     {"-file", TK_ARGV_STRING, (char *) NULL, (char *) &fileName,
  423.     "File from which to read commands"},
  424.     {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry,
  425.     "Initial geometry for window"},
  426.     {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,
  427.     "Display to use"},
  428.     {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name,
  429.     "Name to use for application"},
  430.     {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize,
  431.     "Use synchronous mode for display server"},
  432.     {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
  433.     (char *) NULL}
  434. };
  435.  
  436. void StdinProc(clientData, mask)
  437.     ClientData clientData;        /* Not used. */
  438.     int mask;
  439. {
  440.     char line[200];
  441.     static int gotPartial = 0;
  442.     char *cmd;
  443.     int result;
  444.  
  445.     if (mask & TK_READABLE) {
  446.     if (fgets(line, 200, stdin) == NULL) {
  447.         if (!gotPartial) {
  448.         if (tty) {
  449.             Tcl_Eval(interp, "destroy .", 0, (char **) NULL);
  450.             exit(0);
  451.         } else {
  452.             Tk_DeleteFileHandler(0);
  453.         }
  454.         return;
  455.         } else {
  456.         line[0] = 0;
  457.         }
  458.     }
  459.     cmd = Tcl_AssembleCmd(buffer, line);
  460.     if (cmd == NULL) {
  461.         gotPartial = 1;
  462.         return;
  463.     }
  464.     gotPartial = 0;
  465.     result = Tcl_RecordAndEval(interp, cmd, 0);
  466.     if (*interp->result != 0) {
  467.         if ((result != TCL_OK) || (tty)) {
  468.         printf("%s\n", interp->result);
  469.         }
  470.     }
  471.     if (tty) {
  472.         printf(Tcl_GetVar (interp, "prompt", TCL_GLOBAL_ONLY));
  473.         fflush(stdout);
  474.     }
  475.     }
  476. }
  477.  
  478. static void StructureProc(clientData, eventPtr)
  479.     ClientData clientData;    /* Information about window. */
  480.     XEvent *eventPtr;        /* Information about event. */
  481. {
  482.     if (eventPtr->type == DestroyNotify) {
  483.     w = NULL;
  484.     }
  485. }
  486.  
  487. /*
  488.  * Procedure to map initial window.  This is invoked as a do-when-idle
  489.  * handler.  Wait for all other when-idle handlers to be processed
  490.  * before mapping the window, so that the window's correct geometry
  491.  * has been determined.
  492.  */
  493.  
  494. static void DelayedMap(clientData)
  495.     ClientData clientData;    /* Not used. */
  496. {
  497.  
  498.     while (Tk_DoOneEvent(1) != 0) {
  499.     /* Empty loop body. */
  500.     }
  501.     if (w == NULL) {
  502.     return;
  503.     }
  504.     Tk_MapWindow(w);
  505. }
  506.  
  507. /************************************************************************/
  508.  
  509. int USleepCmd (nulldata, interp, argc, argv)
  510. /* Perform usleep */
  511. ClientData nulldata;
  512. Tcl_Interp *interp;
  513. int argc;
  514. char **argv;
  515. {
  516.     int num;
  517.     if (argc == 2 && sscanf(argv[1],"%d",&num)) {
  518.         usleep(num);
  519.         return TCL_OK;
  520.     }
  521.     Tcl_AppendResult (interp, 
  522.             "wrong args: should be \"", argv[0]," num\"", (char *) NULL);
  523.     return TCL_ERROR;
  524. }
  525.  
  526. /************************************************************************/
  527.  
  528. int main(argc, argv)
  529.     int argc;
  530.     char **argv;
  531. {
  532.     char *args, *p, *msg;
  533.     char buf[20];
  534.     int result;
  535.     Tk_3DBorder border;
  536.  
  537.     strcpy(inputConversion, "*");
  538.  
  539.     ResetPath();    /* reset directory for browsing */
  540.  
  541.     interp = Tcl_CreateInterp();
  542.  
  543. #ifdef TCL_MEM_DEBUG
  544.     Tcl_InitMemory(interp);
  545. #endif
  546.  
  547.     if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, argTable, 0)
  548.         != TCL_OK) {
  549.     fprintf(stderr, "%s\n", interp->result);
  550.     exit(1);
  551.     }
  552.     if (name == NULL) {
  553.     if (fileName != NULL) {
  554.         p = fileName;
  555.     } else {
  556.         p = argv[0];
  557.     }
  558.     name = strrchr(p, '/');
  559.     if (name != NULL) {
  560.         name++;
  561.     } else {
  562.         name = p;
  563.     }
  564.     }
  565.  
  566.     w = Tk_CreateMainWindow(interp, display, name);
  567.     if (w == NULL) {
  568.     fprintf(stderr, "%s\n", interp->result);
  569.     exit(1);
  570.     }
  571.     Tk_SetClass(w, "Tk");
  572.     Tk_CreateEventHandler(w, StructureNotifyMask, StructureProc,
  573.         (ClientData) NULL);
  574.     Tk_DoWhenIdle(DelayedMap, (ClientData) NULL);
  575.     tty = isatty(0);
  576.  
  577.     args = Tcl_Merge(argc-1, argv+1);
  578.     Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
  579.     ckfree(args);
  580.     sprintf(buf, "%d", argc-1);
  581.     Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);
  582.     Tcl_SetVar (interp, "prompt", PROMPT, TCL_GLOBAL_ONLY);
  583.  
  584.     if (synchronize) {
  585.     XSynchronize(Tk_Display(w), True);
  586.     }
  587.     Tk_GeometryRequest(w, 200, 200);
  588.     border = Tk_Get3DBorder(interp, w, None, "#4eee94");
  589.     if (border == NULL) {
  590.     Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
  591.     Tk_SetWindowBackground(w, WhitePixelOfScreen(Tk_Screen(w)));
  592.     } else {
  593.     Tk_SetBackgroundFromBorder(w, border);
  594.     }
  595.     XSetForeground(Tk_Display(w), DefaultGCOfScreen(Tk_Screen(w)),
  596.         BlackPixelOfScreen(Tk_Screen(w)));
  597.  
  598.     Tcl_CreateCommand (interp, "usleep", USleepCmd, (ClientData) 0,
  599.     (void (*) ()) NULL);
  600.  
  601.     Tcl_CreateCommand (interp, "SetOutputFileName", SetOutputFileName, (ClientData) 0,
  602.     (void (*) ()) NULL);
  603.  
  604.     Tcl_CreateCommand (interp, "SetConversion", SetConversion, (ClientData) 0,
  605.     (void (*) ()) NULL);
  606.  
  607.     Tcl_CreateCommand (interp, "SetBrowseGlob", SetBrowseGlob, (ClientData) 0,
  608.     (void (*) ()) NULL);
  609.  
  610.     Tcl_CreateCommand (interp, "SetFormat", SetFormatCmd, (ClientData) 0,
  611.     (void (*) ()) NULL);
  612.  
  613.     Tcl_CreateCommand (interp, "SetPSearch", SetPSearchCmd, (ClientData) 0,
  614.     (void (*) ()) NULL);
  615.  
  616.     Tcl_CreateCommand (interp, "SetGOPSize", SetGOPSize, (ClientData) 0,
  617.     (void (*) ()) NULL);
  618.  
  619.     Tcl_CreateCommand (interp, "SetSPF", SetSPF, (ClientData) 0,
  620.     (void (*) ()) NULL);
  621.  
  622.     Tcl_CreateCommand (interp, "SetDimensions", SetDimensions, (ClientData) 0,
  623.     (void (*) ()) NULL);
  624.  
  625.     Tcl_CreateCommand (interp, "SetBSearch", SetBSearchCmd, (ClientData) 0,
  626.     (void (*) ()) NULL);
  627.  
  628.     Tcl_CreateCommand (interp, "SetPatternString", SetPatternString, (ClientData) 0,
  629.     (void (*) ()) NULL);
  630.  
  631.     Tcl_CreateCommand (interp, "SetSearchRange", SetSearchRangeCmd, (ClientData) 0,
  632.     (void (*) ()) NULL);
  633.  
  634.     Tcl_CreateCommand (interp, "SetQScale", SetQScaleCmd, (ClientData) 0,
  635.     (void (*) ()) NULL);
  636.  
  637.     Tcl_CreateCommand (interp, "encode", EncodeCmd, (ClientData) 0,
  638.     (void (*) ()) NULL);
  639.  
  640.     Tcl_CreateCommand (interp, "SetPixelSearch", SetPixelSearchCmd,
  641.                (ClientData) 0, (void (*) ()) NULL);
  642.  
  643.     Tcl_CreateCommand (interp, "PlayOutput", PlayOutput, (ClientData) 0,
  644.     (void (*) ()) NULL);
  645.  
  646.     Tcl_CreateCommand (interp, "NextInputFile", NextInputFile, (ClientData) 0,
  647.     (void (*) ()) NULL);
  648.  
  649.     Tcl_CreateCommand (interp, "ListDirectory", ListDirectory, (ClientData) 0,
  650.     (void (*) ()) NULL);
  651.  
  652.     Tcl_CreateCommand (interp, "ChangeDirectory", ChangeDirectory, (ClientData) 0,
  653.     (void (*) ()) NULL);
  654.  
  655.     if (geometry != NULL) {
  656.     Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY);
  657.     }
  658.  
  659.     result = Tcl_Eval(interp, initCmd, 0, (char **) NULL);
  660.     if (result != TCL_OK) {
  661.     goto error;
  662.     }
  663.  
  664.     if (fileName != NULL) {
  665.     result = Tcl_VarEval(interp, "source ", fileName, (char *) NULL);
  666.     if (result != TCL_OK) {
  667.         goto error;
  668.     }
  669.     tty = 0;
  670.     } else {
  671.     tty = isatty(0);
  672.     Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0);
  673.     if (tty) {
  674.         printf(Tcl_GetVar (interp, "prompt", TCL_GLOBAL_ONLY));
  675.     }
  676.     }
  677.  
  678.     fflush(stdout);
  679.     buffer = Tcl_CreateCmdBuf();
  680.     (void) Tcl_Eval(interp, "update", 0, (char **) NULL);
  681.  
  682.     Tk_MainLoop();
  683.  
  684.     Tcl_DeleteInterp(interp);
  685.     Tcl_DeleteCmdBuf(buffer);
  686.     exit(0);
  687.  
  688. error:
  689.     msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
  690.     if (msg == NULL) {
  691.     msg = interp->result;
  692.     }
  693.     fprintf(stderr, "%s\n", msg);
  694.     Tcl_Eval(interp, "destroy .", 0, (char **) NULL);
  695.     exit(1);
  696.     return 0;
  697. }
  698.