home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume17 / tcl-editor / part13 / command.c
Encoding:
C/C++ Source or Header  |  1992-03-18  |  39.1 KB  |  1,700 lines

  1. /* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/command.c,v 1.12 1992/03/04 17:07:18 crowley Exp crowley $ */
  2.  
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "pt.h"
  7. #include <X11/keysym.h>
  8. #include <X11/StringDefs.h>
  9.  
  10. /* remember whether to erase the description message */
  11. int lastOnTopline = 0;
  12.  
  13. /* remember the last command the user selected (for help) */
  14. int lastCommand = FDONOTHING;
  15.  
  16. /* some status (or mode) flags and move/copy pending data */
  17. int movePending = 0;
  18. int copyPending = 0;
  19. struct window *pendWindow = NULL;
  20. Offset pendPosition;
  21.  
  22. /* keyboard macro */
  23. char macroText[102];
  24. int macroIndex = 0;
  25. int macroSize = 0;
  26. int macroState = 0;
  27.  
  28. /* for multiple exposes, keep the maximum bounds */
  29. static int minx = 999999, miny = 999999, maxx = 0, maxy = 0;
  30.  
  31. char *
  32. command( fn, arg1, arg2, arg3, arg4, arg5, arg6 )
  33.     PointCommand fn;
  34.     char *arg1;
  35.     char *arg2;
  36.     char *arg3;
  37.     char *arg4;
  38.     char *arg5;
  39.     char *arg6;
  40. {
  41.     extern char msgBuffer[];
  42.     extern char textBuffer[];
  43.     extern char homeDirectory[];
  44.     extern int debug;
  45.     extern struct window *selWindow;
  46.     extern Offset selBegin, selEnd;
  47.     extern int overType;
  48.     extern int lastOnTopline;
  49.     extern int lastCommand;
  50.     extern int macroIndex;
  51.     extern int macroSize;
  52.     extern int macroState;
  53.     extern int selMode;
  54.     extern int lastFn;
  55.     extern int errno;
  56.     extern struct openFile *files;
  57.     extern struct optionItem options[];
  58.     extern struct window *windowList;
  59.     extern int copyPending, movePending;
  60.     extern struct window *pendWindow;
  61.     extern Offset pendPosition;
  62.     extern int topOnFind;
  63.     extern long timeOfLastSave;
  64.     extern Offset mm_cp;
  65.     extern Cursor mainCursor;
  66.     extern Cursor currentCursor;
  67.     extern Cursor dupCursor;
  68.     extern Display *MainDisplay;
  69.     extern BrowserData *mainBrowser;
  70.     extern BrowserData *activeBrowser;
  71.     extern BrowserData *browserList;
  72.     extern struct window * activeWindow;
  73. #ifdef HYPERTEXT
  74.     extern DBM *currentDB;
  75.     extern Document currentDocument;
  76.     extern int hypertextOn;
  77. #endif
  78.     extern int tkScrolling;
  79.     extern Tcl_Interp * interp;
  80.     extern char * textGeometry;
  81.     extern char * browserGeometry;
  82.     extern char * textFont;
  83.     extern char * browserFont;
  84.     extern char * returnString;
  85.     extern Tk_Window TkMainWindow;
  86.     extern int scrollDown;
  87.     extern int intervalRows;
  88.     extern int linesOverFind;
  89.     extern struct window * scroll_window;
  90.  
  91.     int n, ret, row1, col1, col2;
  92.     Offset cp;
  93.     char ch;
  94.     char *fileName, *str;
  95.     struct window *w2;
  96.     struct window *saveSelWindow;
  97.     char * ret_string = NULL;
  98.     int int1, int2, int3, int4, int5, int6;
  99.     struct window * w = activeWindow;
  100.     BrowserData * browser;
  101.     struct changeItem * last_change;
  102.     struct openFile * ff;
  103.     Offset saveSelBegin, saveSelEnd;
  104.  
  105. /* since we are about to issue a command, we do not need to erase */
  106. /* the command description on the top line (so don't) */
  107. lastOnTopline = 0;
  108.  
  109. switch( fn ) {
  110.  
  111. /*********************** EVENT HANDLER COMMANDS ***************************/
  112. case FBARRIER: {
  113.     int x, y;
  114.     struct fontDataStruct *font = &(w->font);
  115.     (void)Tcl_GetInt( interp, arg1, &int1 );
  116.     OffsetToXY( w, int1, &row1, &col1 );
  117.     if( row1 < 0 ) {
  118.         printf("offset %d is not in the window\n", row1);
  119.         break;
  120.     }
  121.     x = w->leftMargin + col1 * font->width;
  122.     y = w->topMargin + (row1+1) * font->height - 2;
  123.     XDrawLine( MainDisplay, w->x_window_id, font->gc_normal,
  124.         x, y, x-3, y+3 );
  125.     XDrawLine( MainDisplay, w->x_window_id, font->gc_normal,
  126.         x, y-1, x-3, y+2 );
  127.     XDrawLine( MainDisplay, w->x_window_id, font->gc_normal,
  128.         x, y, x+3, y+3 );
  129.     XDrawLine( MainDisplay, w->x_window_id, font->gc_normal,
  130.         x, y-1, x+3, y+2 );
  131.     break;
  132. }
  133. #ifdef XXXXXX
  134.     if( strcmp(arg1,"grab")==0 ) {
  135.         Tk_Window tkwin;
  136.         char name [100];
  137.         
  138.         sprintf( name, "%s.VScrollAndText", w->tk_pathname );
  139.         tkwin = Tk_NameToWindow( interp, name, w->tk_toplevel );
  140.         XGrabPointer(
  141.             MainDisplay,
  142.             Tk_WindowId(w->tk_toplevel),
  143.             True,
  144.             ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
  145.             GrabModeAsync,
  146.             GrabModeAsync,
  147.             (debug==0 ? Tk_WindowId(w->tk_toplevel)
  148.                   : Tk_WindowId(tkwin) ),
  149.             None,
  150.             CurrentTime
  151.         );
  152.     } else {
  153.         XUngrabPointer( MainDisplay, CurrentTime );
  154.     }
  155.     break;
  156. #endif
  157.  
  158. case FCONFIGURE:
  159.     w = FindWindowByTkName( arg1 );
  160.     if( w == NULL ) {
  161.         browser = FindBrowserByTkName( arg1 );
  162.         if( browser == NULL ) {
  163.             printf("FCONFIGURE: window %s was not found\n", arg1);
  164.             break;
  165.         }
  166.         NewFilelist( browser );
  167.         break;
  168.     }
  169.     WorkspaceResized( w );
  170.     break;
  171.  
  172. case FENTERTEXT:
  173.     w2 = FindWindowByTkName( arg1 );
  174.     if( w2 == NULL ) {
  175. #ifdef DEBUG_UPDATE
  176.         printf("FENTERTEXT: window %s not found\n", arg1);
  177. #endif
  178.         break;
  179.     }
  180.     activeWindow = w2;
  181.     XDefineCursor( MainDisplay, activeWindow->x_window_id, currentCursor );
  182.     break;
  183.  
  184. case FENTERBROWSER:
  185.     activeBrowser = FindBrowserByTkName( arg1 );
  186.     chdir( activeBrowser->cwd );
  187.     break;
  188.  
  189. case FEXPOSE:
  190.     w = FindWindowByTkName( arg1 );
  191.     if( w == NULL ) {
  192. #ifdef DEBUG_UPDATE
  193.         printf("FEXPOSE: window %s not found\n", arg1);
  194. #endif
  195.         break;
  196.     }
  197.     (void)Tcl_GetInt( interp, arg2, &int2 );
  198.     if( int2 < minx )
  199.         minx = int2;
  200.     (void)Tcl_GetInt( interp, arg3, &int3 );
  201.     if( int3 < miny )
  202.         miny = int3;
  203.     (void)Tcl_GetInt( interp, arg4, &int4 );
  204.     int4 += int2;    /* get right x-coord */
  205.     if( int4 > maxx )
  206.         maxx = int4;
  207.     (void)Tcl_GetInt( interp, arg5, &int5 );
  208.     int5 += int3;    /* get bottom y-coord */
  209.     if( int5 > maxy )
  210.         maxy = int5;
  211.     (void)Tcl_GetInt( interp, arg6, &int6 );
  212.     if( int6 > 0 )    /* more expose events yet to come */
  213.         break;
  214.     repaint( w, minx, miny, maxx, maxy );
  215.     maxx = maxy = 0;
  216.     minx = miny = 999999;    /* bigger than any screen ? */
  217.     break;
  218.  
  219. case FHSCROLL:
  220.     if( w == NULL )
  221.         break;
  222.     if( striccmp(arg1,"press")==0 )
  223.         n = 1;
  224.     else if( striccmp(arg1,"release")==0 )
  225.         n = 2;
  226.     else if( striccmp(arg1,"motion")==0 )
  227.         n = 3;
  228.     else
  229.         n = 0;
  230.     if( n == tkScrolling )
  231.         break;
  232.     (void)Tcl_GetInt( interp, arg2, &int2 );
  233.     if( n == 1 ) {
  234.         (void)Tcl_GetInt( interp, arg3, &int3 );
  235.     }
  236.     HScroll( w, n, int2, int3 );
  237.     break;
  238.  
  239. case FKEY:
  240.     if( w == NULL ) {
  241.         printf("FKEY: window is NULL\n");
  242.         break;
  243.     }
  244.     (void)Tcl_GetInt( interp, arg1, &int1 );
  245.     (void)Tcl_GetInt( interp, arg2, &int2 );
  246.     HandleKey( int1, int2 );
  247.     break;
  248.  
  249. case FMOUSE:
  250.     w = FindWindowByTkName( arg1 );
  251.     if( w == NULL ) {
  252.         printf("FMOUSE: window %s not found\n", arg1);
  253.         break;
  254.     }
  255.     (void)Tcl_GetInt( interp, arg3, &int3 );
  256.     (void)Tcl_GetInt( interp, arg4, &int4 );
  257.     Mouse( w, arg2, int3, int4 );
  258.     break;
  259.  
  260. case FVSCROLL:
  261.     if( w == NULL ) {
  262.         printf("FVSCROLL: window is NULL\n");
  263.         break;
  264.     }
  265.     if( striccmp(arg1,"press")==0 )
  266.         n = 1;
  267.     else if( striccmp(arg1,"release")==0 )
  268.         n = 2;
  269.     else if( striccmp(arg1,"motion")==0 )
  270.         n = 3;
  271.     else
  272.         n = 0;
  273.     if( tkScrolling ) {
  274.         if( n != 0 )
  275.             break;
  276.         else
  277.             int3 = 0;
  278.     } else {
  279.         if( n == 0 )
  280.             break;
  281.         else
  282.             (void)Tcl_GetInt( interp, arg3, &int3 );
  283.     }
  284.     (void)Tcl_GetInt( interp, arg2, &int2 );
  285.     VScroll( w, n, int2, int3 );
  286.     break;
  287.  
  288. /*********************** MACRO COMMANDS ***************************/
  289. case FWAITFORRETURNSTRING:
  290.     PtFree( returnString );
  291.     returnString = PtMalloc( 50 , "string" );
  292.     returnString[0] = '\0';
  293.     while( returnString[0] == '\0' ) {
  294.         Tk_DoOneEvent( 0 );
  295.     }
  296.     break;
  297.  
  298. case FPOINTSELECTION:
  299. if( striccmp(arg1,"set")==0 ) {
  300.     if( arg2[0] != '\0' ) {
  301.         (void)Tcl_GetInt( interp, arg2, &selBegin );
  302.         if( selBegin < 0 )
  303.             selBegin = 0;
  304.     }
  305.     if( arg3[0] != '\0' ) {
  306.         cp = fileSize(selWindow->fileId);
  307.         if( selEnd >= cp ) {
  308.             selEnd = cp - 1;
  309.         }
  310.     }
  311.     (void)Tcl_GetInt( interp, arg3, &selEnd );
  312.     if( arg4[0] != '\0' ) {
  313.         w = FindWindowByTkName( arg4 );
  314.         if( w == NULL ) {
  315.             printf("FPOINTSELECTION: window %s not found\n",
  316.                 arg4);
  317.             break;
  318.         }
  319.         selWindow = w;
  320.     }
  321.     if( arg5[0] != '\0' ) {
  322.         if( strcmp(arg5,"char")==0 )
  323.             selMode = SELCHAR;
  324.         else if( strcmp(arg5,"word")==0 )
  325.             selMode = SELWORD;
  326.         else
  327.             selMode = SELLINE;
  328.     }
  329. } else if( arg1[0] == '\0' || striccmp(arg1,"get")==0 ){
  330.     switch( selMode ) {
  331.         case SELCHAR: str = "char"; break;
  332.         case SELWORD: str = "word"; break;
  333.         case SELLINE: str = "line"; break;
  334.     }
  335.     sprintf( textBuffer, "%d %d %s %s %d", selBegin, selEnd,
  336.         selWindow==NULL ?
  337.             "NoSelection" : selWindow->tk_pathname,
  338.         str, LineNumberOfSelection() );
  339.     ret_string = textBuffer;
  340.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  341. } else {     /* must be a 'Sel return' */
  342.     n = 256;
  343. try_again:
  344.     ret_string = (char *)PtMalloc( n, "selection" );
  345.     ret = getSelection( ret_string, 0, n );
  346.     if( !ret ) {    /* did we get the whole selection? */
  347.         /* if not, double the buffer and try again */
  348.         n *= 2;
  349.         PtFree( ret_string );
  350.         goto try_again;
  351.     }
  352.     /* do we need to escape things? */
  353.     if( striccmp(arg1,"escaped")==0 ) {
  354.         /* first count the number of braces */
  355.         row1 = 0;
  356.         str = ret_string;
  357.         while( (ch = *str++) != '\0' ) {
  358.             if( ch == '{' || ch == '}' )
  359.                 ++row1;
  360.         }
  361.         if( row1 > 0 ) {
  362.             /* allocate space for the escaped version */
  363.             char * new_space = (char *)PtMalloc(
  364.                 row1 + (str - ret_string) + 1,
  365.                 "selection" );
  366.             /* copy and escape */
  367.             char * from = ret_string;
  368.             char * to = new_space;
  369.             while( 1 ) {
  370.                 ch = *from++;
  371.                 if( ch == '{' || ch == '}' )
  372.                     *to++ = '\\';
  373.                 *to++ = ch;
  374.                 if( ch == '\0' )
  375.                     break;
  376.             }
  377.             PtFree( ret_string );
  378.             ret_string = new_space;
  379.         }
  380.     }
  381.     Tcl_SetResult( interp, ret_string, (Tcl_FreeProc *)PtFree );
  382. }
  383. break;
  384.  
  385. case FGETFILECHARS:
  386.     (void)Tcl_GetInt( interp, arg1, &int1 );
  387.     (void)Tcl_GetInt( interp, arg2, &int2 );
  388.     if( int1 < 0 )
  389.         int1 = 0;
  390.     if( int2 >= int1 + MSGBUFFERSIZE )
  391.         int2 = MSGBUFFERSIZE - 1;
  392.     if( arg3[0] != '\0' )
  393.         w = FindWindowByTkName( arg3 );
  394.     if( w == NULL ) {
  395.         printf("FGETFILECHARS: window %s not found\n", arg3);
  396.         break;
  397.     }
  398.     n = w->fileId;
  399.     str = textBuffer;
  400.     while( int1 <= int2 )
  401.         *str++ = getFileByte( n, int1++ );
  402.     ret_string = textBuffer;
  403.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  404.     break;
  405.  
  406. case FSCROLLWINDOW:
  407.     if( arg3[0] != '\0' )
  408.         w = FindWindowByTkName( arg3 );
  409.     if( w == NULL ) {
  410.         printf("FSCROLLWINDOW: window %s not found\n", arg3);
  411.         break;
  412.     }
  413.     /* default is to scroll down one page */
  414.     /* 'page' or a numerical count ? */
  415.     if(arg2[0] == '\0' || striccmp(arg2,"page")==0 )
  416.         intervalRows = w->nRows - 2;
  417.     else
  418.         intervalRows = atoi( arg2 );
  419.     /* 'up' or 'down' ? */
  420.     if( arg1[0] != '\0' && striccmp(arg1,"up")==0 )
  421.         scrollDown = 0;
  422.     else
  423.         scrollDown = 1;
  424.     scroll_window = w;
  425.     (void)DoOneVScroll();
  426.     break;
  427.  
  428. case FGETROWCOL:
  429.     if( arg2[0] != '\0' )
  430.         w = FindWindowByTkName( arg2 );
  431.     if( w == NULL ) {
  432.         printf("FGETROWCOL: window %s not found\n", arg2);
  433.         break;
  434.     }
  435.     if( arg1[0] == '\0' )
  436.         cp = selBegin;
  437.     else
  438.         cp = atoi( arg1 );
  439.     OffsetToXY( w, cp, &col1, &col2 );
  440.     sprintf( textBuffer, "%d %d", col1, col2 );
  441.     ret_string = textBuffer;
  442.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  443.     break;
  444.  
  445. case FWINDOWNAME:
  446.     if( strcmp(arg1,"set") == 0 ) {
  447.         w = FindWindowByTkName( arg3 );
  448.         if( w == NULL ) {
  449.             printf("FWINDOWNAME: window %s not found\n", arg3);
  450.             break;
  451.         }
  452.         if( strcmp(arg2,"active") == 0 )
  453.             activeWindow = w;
  454.         else
  455.             selWindow = w;
  456.     } else {
  457.         if( strcmp(arg2,"active") == 0 )
  458.             ret_string = activeWindow->tk_pathname;
  459.         else
  460.             ret_string = selWindow->tk_pathname;
  461.         Tcl_SetResult( interp, ret_string, TCL_STATIC );
  462.     }
  463.     break;
  464.  
  465. case FGETWINDOWINFO:
  466.     if( arg1[0] != '\0' )
  467.         w = FindWindowByTkName( arg1 );
  468.     if( w == NULL ) {
  469.         printf("FGETWINDOWINFO: window %s not found\n", arg1);
  470.         break;
  471.     }
  472.     sprintf( msgBuffer, "%d %d %d %d %d %d %d %d %d %d",
  473.         w->posTopline, w->posBotline,
  474.         w->numTopline, w->numBotline,
  475.         w->indent, w->nRows, w->nCols,
  476.         w->x_window_id, w->tk_toplevel, w->tk_text );
  477.     ret_string = msgBuffer;
  478.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  479.     break;
  480.  
  481. case FGETFILEINFO: {
  482.     struct openFile * ff;
  483.     if( arg1[0] != '\0' )
  484.         w = FindWindowByTkName( arg1 );
  485.     if( w == NULL ) {
  486.         printf("FGETFILEINFO: window %s not found\n", arg1);
  487.         break;
  488.     }
  489.     ff = &files[w->fileId];
  490.     sprintf( msgBuffer, "%s %d %d %d",
  491.         ff->origName, ff->fileSize, ff->origFileSize, ff->flags );
  492.     ret_string = msgBuffer;
  493.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  494.     break;
  495. }
  496.  
  497. case FINSERTSTRING:
  498.     if( selWindow == NULL )
  499.         break;
  500.     n = strlen( arg1 );
  501.     if( arg2[0] != '\0' && strcmp(arg2,"noupdate")==0 )
  502.         ret = 0;
  503.     else
  504.         ret = 1;
  505.     if( n < 10 && ret ) {
  506.         while( *arg1 != '\0' )
  507.             insChar( *arg1++, ret );
  508.     } else {
  509.         while( *arg1 != '\0' )
  510.             insertChar( *arg1++ );
  511.         if( ret )
  512.             drawWindow( selWindow );
  513.     }
  514.     break;
  515.  
  516. /**************************** SEARCH COMMANDS **************************/
  517. case FSEARCHFORS:
  518.     if( arg3[0] != '\0' )
  519.         w = FindWindowByTkName( arg3 );
  520.     if( w == NULL ) {
  521.         printf("FSEARCHFORS: window %s not found\n", arg3);
  522.         break;
  523.     }
  524.     if( arg2[0] == '\0' || striccmp(arg2,"forward")==0 )
  525.         n = 0;
  526.     else
  527.         n = 1;
  528.     if( arg4[0] == '\0' || strcmp(arg4,"update")==0 )
  529.         col1 = UPDATEWINDOWS;
  530.     else
  531.         col1 = NOUPDATE;
  532.     n = searchFor( w, n, arg1, col1, linesOverFind );
  533.     sprintf( textBuffer, "%d", n );
  534.     ret_string = textBuffer;
  535.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  536.     break;
  537.  
  538. case FREGEXSEARCH:
  539.     if( arg3[0] != '\0' )
  540.         w = FindWindowByTkName( arg3 );
  541.     if( w == NULL ) {
  542.         printf("FSEARCHFORS: window %s not found\n", arg3);
  543.         break;
  544.     }
  545.     if( arg2[0] == '\0' || striccmp(arg2,"forward")==0 )
  546.         n = 0;
  547.     else
  548.         n = 1;
  549.     if( arg4[0] == '\0' || strcmp(arg4,"update")==0 )
  550.         col1 = UPDATEWINDOWS;
  551.     else
  552.         col1 = NOUPDATE;
  553.     n = RegexSearch( w, n, arg1, col1, linesOverFind );
  554.     sprintf( textBuffer, "%d", n );
  555.     ret_string = textBuffer;
  556.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  557.     break;
  558.  
  559. case FCTAG:
  560.     findCTag( arg1 );
  561.     break;
  562.  
  563. case FREPEATSEARCH:
  564.     if( arg2[0] != '\0' )
  565.         w = FindWindowByTkName( arg2 );
  566.     if( w == NULL ) {
  567.         printf("FREPEATSEARCH: window %s not found\n", arg2);
  568.         break;
  569.     }
  570.     (void)searchFor( w, (striccmp(arg1,"backward")==0), NULL, 1,
  571.                             linesOverFind );
  572.     break;
  573.  
  574. case FREPLACE:
  575.     if( arg4[0] != '\0' )
  576.         w = FindWindowByTkName( arg4 );
  577.     if( w == NULL ) {
  578.         printf("FREPLACE: window %s not found\n", arg4);
  579.         break;
  580.     }
  581.     if( arg3[0] == '\0' || striccmp(arg3,"inselection")!=0 )
  582.         n = 0;
  583.     else 
  584.         n = 1;
  585.     replaceText( w, arg1, arg2, n );
  586.     break;
  587.  
  588. case FREGEXREPLACEONE:
  589.     if( arg4[0] != '\0' )
  590.         w = FindWindowByTkName( arg4 );
  591.     if( w == NULL ) {
  592.         printf("FREPLACE: window %s not found\n", arg4);
  593.         break;
  594.     }
  595.     if(  striccmp(arg3,"one")!=0 ) {
  596.         n = RegexReplaceOne( w, arg1, arg2 );
  597.         sprintf( textBuffer, "%d", n );
  598.         ret_string = textBuffer;
  599.         Tcl_SetResult( interp, ret_string, TCL_STATIC );
  600.         break;
  601.     }
  602.     break;
  603.  
  604. case FREGEXREPLACEALL:
  605.     if( arg3[0] == '\0' || striccmp(arg3,"inselection")!=0 )
  606.         n = 0;
  607.     else 
  608.         n = 1;
  609.     RegexReplaceAll( w, arg1, arg2, n );
  610.     break;
  611.  
  612. case FMATCHCHAR:    /* find the matching character */
  613.     matchChar();
  614.     break;
  615.  
  616. #define SEARCH_LETTER_BUFFER_SIZE    80
  617.  
  618. case FSEARCHLETTER:
  619. {
  620.     static char searchString[SEARCH_LETTER_BUFFER_SIZE];
  621.     static int searchStringIndex = 0;
  622.     static int searchMode = 0;
  623.     char ch;
  624.  
  625.     if( arg3[0] != '\0' )
  626.         w = FindWindowByTkName( arg3 );
  627.     if( w == NULL ) {
  628.         printf("FSEARCHLETTER: window %s not found\n", arg3);
  629.         break;
  630.     }
  631.     (void)Tcl_GetInt( interp, arg1, &int1 );
  632.     if( int1 <= 127 ) {
  633.         ch = (char)int1;
  634.         (void)Tcl_GetInt( interp, arg2, &int2 );
  635.         if( int2 & ControlMask )
  636.             ch &= 0x1f;
  637.     } else {
  638.         int1 &= 0xff;
  639.         /* ignore shift keys */
  640.         if( 0xe1 <= int1 && int1 <= 0xee )
  641.             return ret_string;
  642.         ch = '\0';
  643.     }
  644.     if( ch == '\0' ) {
  645.         searchStringIndex = 0;
  646.         searchMode = 0;
  647.         break;
  648.     } else if( ch == '\b' || ch == '\177' ) {
  649.         if( searchStringIndex > 0 )
  650.             --searchStringIndex;
  651.         else
  652.             searchMode = 1;
  653.         break;
  654.     }
  655.     /* start over on overflows */
  656.     if( searchStringIndex >= SEARCH_LETTER_BUFFER_SIZE )
  657.         searchStringIndex = 0;
  658.     searchString[searchStringIndex++] = ch;
  659.     if( w != NULL ) {
  660.         /* terminate and copy string into the search buffer */
  661.         searchString[searchStringIndex] = '\0';
  662.         if( searchStringIndex > 1 )
  663.             /* we want to find this string again if it matches */
  664.             /* with the additional letter added */
  665.             --selBegin;
  666.         (void)searchFor( w, searchMode, searchString, 1,
  667.                             linesOverFind );
  668.     }
  669.     break;
  670. }
  671.  
  672. /************************** TEXT CHANGING COMMANDS *************************/
  673. case FINSASCII:
  674.     Tcl_GetInt( interp, arg1, &n );
  675.     insChar( (unsigned char)n, 1 );
  676.     break;
  677.  
  678. case FINSERT:
  679.     if( arg1[0] == '\0' || strcmp(arg1,"update")==0 )
  680.         n = UPDATEWINDOWS;
  681.     else
  682.         n = NOUPDATE;
  683.     if( selWindow == NULL )
  684.         break;
  685.     insScrap( 1, n );
  686.     break;
  687.  
  688. case FCHANGECASE: {
  689.     int wasChanged;
  690.     Offset sEnd = selEnd;    /* since selEnd will change in the loop */
  691.     int row, col, fid, n;
  692.     int how;
  693.     Offset beginCp;
  694.  
  695.     if( selWindow == NULL )
  696.         break;
  697.     if( arg1[0] == '\0' || striccmp(arg1,"toggle")==0 )
  698.         how = 2;
  699.     else if( striccmp(arg1,"tolower")==0 )
  700.         how = 1;
  701.     else
  702.         how =0;
  703.     fid = selWindow->fileId;
  704.     while( selBegin <= sEnd ) {
  705.         ch = (char)getFileByte( fid, selBegin );
  706.         if( !isalpha(ch) ) {
  707.             /* pass over the character if it is not alpha */
  708.             goto redrawSelection;
  709.         }
  710.         wasChanged = 0;
  711.         if( isupper(ch) && how != 0 ) {
  712.             ch = tolower(ch);
  713.             wasChanged = 1;
  714.         } else if( islower(ch) && how != 1 ) {
  715.             ch = toupper(ch);
  716.             wasChanged = 1;
  717.         }
  718.         if( wasChanged ) {
  719.             saveSelBegin = selEnd = selBegin;
  720.             (void)deleteChars(selWindow->fileId, NOUPDATE, 0);
  721.             selEnd = selBegin = saveSelBegin;
  722.             insChar( ch, 1 );
  723.         } else {
  724.     redrawSelection:
  725.             n = -1;
  726.             beginCp = prevLine( selWindow->fileId, selBegin, &n );
  727.             OffsetToXY( selWindow, ++selBegin, &row, &col );
  728.             selEnd = selBegin;
  729.             DrawSection( selWindow, beginCp, row, col-1, row, col );
  730.         }
  731.     }
  732.     selEnd = selBegin;
  733.     break;
  734. }
  735.  
  736. case FJUSTIFY:
  737.     if( w == NULL )
  738.         break;
  739.     justifyLines();
  740.     break;
  741.  
  742. case FDELETE:
  743.     if( arg1[0] == '\0' || strcmp(arg1,"update")==0 )
  744.         n = UPDATEWINDOWS;
  745.     else
  746.         n = NOUPDATE;
  747.     if( selWindow == NULL )
  748.         break;
  749.     (void)deleteChars(selWindow->fileId, n, 1);
  750.     break;
  751.  
  752. case FEXCHSCRAP:
  753.     if( selWindow == NULL )
  754.         break;
  755.     exchWithScrap();
  756.     break;
  757.  
  758. case FCOPYSCRAP:
  759.     if( selWindow == NULL )
  760.         break;
  761.     copyToScrap(selWindow, selBegin, selEnd);
  762.     msg("The selection has been copied to the scrap buffer", 1);
  763.     break;
  764.  
  765. case FCOPYTO:    /* copy selection to this point */
  766.     n = COPY;
  767.     goto moveAndCopy;
  768.  
  769. case FMOVETO:    /* move selection to this point */
  770.     n = MOVE;
  771. moveAndCopy:
  772.     if( w == NULL )
  773.         break;
  774.     /* adjust to the selection mode */
  775.     cp = mm_cp;    /* hidden parameter from userInput */
  776.     /* adjustSelMode always uses selWindow so we have to fool it */
  777.     /* be setting selWindow before the call and resetting it after */
  778.     saveSelWindow = selWindow;
  779.     selWindow = w;
  780.     cp = adjustSelMode( cp );
  781.     selWindow = saveSelWindow;
  782.     drawSelection( 1 );
  783.     copyMove(selWindow, selBegin, selEnd, w, cp, n);
  784.     break;
  785.  
  786. case FCOPYFROM:
  787.     if( selWindow == NULL )
  788.         break;
  789.     if( copyPending ) {
  790.         drawSelection( 1 );
  791.         copyMove(selWindow, selBegin, selEnd, pendWindow, pendPosition,
  792.                                     COPY);
  793.         currentCursor = mainCursor;
  794.         XDefineCursor(MainDisplay, selWindow->x_window_id,
  795.                                 currentCursor);
  796.         copyPending = 0;
  797.     } else {
  798.         XDefineCursor( MainDisplay, selWindow->x_window_id, dupCursor);
  799.         currentCursor = dupCursor;
  800.         copyPending = 1;
  801.         pendWindow = selWindow;
  802.         pendPosition = selBegin;
  803.     }
  804.     break;
  805.  
  806. case FMOVEFROM:
  807.     if( selWindow == NULL )
  808.         break;
  809.     if( movePending ) {
  810.         copyMove(selWindow, selBegin, selEnd, pendWindow, pendPosition,
  811.                                     MOVE);
  812.         movePending = 0;
  813.         msg( NULL, 0 );
  814.     } else {
  815.         msg("Extract mode", 4);
  816.         movePending = 1;
  817.         pendWindow = selWindow;
  818.         pendPosition = selBegin;
  819.     }
  820.     break;
  821.  
  822. case FREDO:
  823.     if( arg2[0] != '\0' )
  824.         w = FindWindowByTkName( arg2 );
  825.     if( w == NULL ) {
  826.         printf("FREDO: window %s not found\n", arg1);
  827.         break;
  828.     }
  829.     if( arg1[0] != '\0' )
  830.         (void)Tcl_GetInt( interp, arg1, &int1 );
  831.     else
  832.         int1 = 1;
  833.     redo( &files[w->fileId], int1 );
  834.     break;
  835.  
  836. case FAGAIN:
  837.     n = 1;
  838.     if( arg1[0] != '\0' ) {
  839.         if( striccmp(arg1,"thisfile")==0 )
  840.             n = 0;
  841.         else
  842.             w = FindWindowByTkName( arg1 );
  843.     }
  844.     if( w == NULL ) {
  845.         printf("FAGAIN: window %s not found\n", arg1);
  846.         break;
  847.     }
  848.     again( &files[w->fileId], n );
  849.     break;
  850.  
  851. case FUNDO:
  852.     if( arg2[0] != '\0' )
  853.         w = FindWindowByTkName( arg2 );
  854.     if( w == NULL ) {
  855.         printf("FUNDO: window %s not found\n", arg1);
  856.         break;
  857.     }
  858.     ff = &files[w->fileId];
  859.     if( arg1[0] != '\0' ) {
  860.         last_change = GetCurrentChange( ff );
  861.         if( strcmp(arg1,"end")==0 ) {
  862.             last_change->flags |= BLOCK_UNDO_END;
  863.             break;
  864.         } else if( strcmp(arg1,"begin")==0 ) {
  865.             last_change->flags |= BLOCK_UNDO_BEGIN;
  866.             break;
  867.         } else if( strcmp(arg1,"update")==0 ) {
  868.             UpdateUndoList( ff );
  869.             break;
  870.         } else
  871.             (void)Tcl_GetInt( interp, arg1, &int1 );
  872.     } else
  873.         int1 = 1;
  874.     undo( ff, int1 );
  875.     break;
  876.  
  877. /************************** FILE POSITIONING COMMANDS ***********************/
  878. case FBOTFILE:
  879.     if( arg1[0] != '\0' )
  880.         w = FindWindowByTkName( arg1 );
  881.     if( w == NULL ) {
  882.         printf("FBOTFILE: window %s not found\n", arg1);
  883.         break;
  884.     }
  885.     bottomFile(w);
  886.     break;
  887.  
  888. case FGOTOSELECTION:
  889.     if( w == NULL )
  890.         break;
  891.     doGoSel(w);
  892.     break;
  893.  
  894. case FGOBACKTO:
  895.     if( arg1[0] != '\0' )
  896.         w = FindWindowByTkName( arg1 );
  897.     if( w == NULL ) {
  898.         printf("FGOBACKTO: window %s not found\n", arg1);
  899.         break;
  900.     }
  901.     doGoto( w, w->rowLastline, 0 );
  902.     break;
  903.  
  904. case FGOTOLINE:
  905.     if( arg3[0] != '\0' )
  906.         w = FindWindowByTkName( arg3 );
  907.     if( w == NULL ) {
  908.         printf("FGOTOLINE: window %s not found\n", arg3);
  909.         break;
  910.     }
  911.     if( arg1[0] == '\0' )
  912.         int1 = 1;
  913.     else
  914.         (void)Tcl_GetInt( interp, arg1, &int1 );
  915.     if( arg2[0] == '\0' || striccmp(arg2,"lof")==0 )
  916.         int2 = 1;
  917.     else
  918.         int2 = 0;
  919.     doGoto( w, int1, int2 );
  920.     break;
  921.  
  922. case FGOTODIGIT:
  923. {
  924.     static int lineNumber = 0;
  925.     if( arg2[0] != '\0' )
  926.         w = FindWindowByTkName( arg2 );
  927.     if( w == NULL ) {
  928.         printf("FGOTODIGIT: window %s not found\n", arg2);
  929.         break;
  930.     }
  931.     if( arg1[0] != '\0' && isdigit( arg1[0] ) )
  932.         lineNumber = 10*lineNumber + arg1[0] - '0';
  933.     else {
  934.         doGoto( w, lineNumber, 1 );
  935.         lineNumber = 0;
  936.     }
  937.     break;
  938. }
  939.  
  940. case FMOVESEL:
  941.     int3 = 0;
  942.     saveSelBegin = -1;
  943.     if( arg3[0] == '\0' || strcmp(arg3,"update")==0 )
  944.         int3 = 1;
  945.     else if (strcmp(arg3,"nosel")==0 ) {
  946.         saveSelBegin = selBegin;
  947.         saveSelEnd = selEnd;
  948.     }
  949.     (void)cursor( arg1, arg2, int3 );
  950.     if( saveSelBegin >= 0 ) {
  951.         selBegin = saveSelBegin;
  952.         selEnd = saveSelEnd;
  953.     }
  954.     sprintf( msgBuffer, "%d", selBegin );
  955.     Tcl_SetResult( interp, msgBuffer, TCL_STATIC );
  956.     break;
  957.  
  958. /************************ WINDOW MANAGEMENT COMMANDS ***********************/
  959. case FSETTEXTCOLOR:
  960.     if( arg4[0] != '\0' )
  961.         w = FindWindowByTkName( arg4 );
  962.     if( w == NULL ) {
  963.         printf("FSETTEXTCOLOR: window %s not found\n", arg4);
  964.         break;
  965.     }
  966.     if( arg2[0] == '\0' || striccmp(arg2,"normal")==0 )
  967.         int2 = 1;
  968.     else
  969.         int2 = 0;
  970.     if( arg3[0] == '\0' || striccmp(arg3,"foreground")==0 )
  971.         int3 = 1;
  972.     else
  973.         int3 = 0;
  974.     SetTextColor( w, int2, int3, arg1 );
  975.     drawWindow( w );
  976.     break;
  977.  
  978. case FBROWSER:
  979.     if( arg2[0] != '\0' && striccmp(arg2,"small")==0 )
  980.         n = 0;
  981.     else
  982.         n = 1;
  983.     CreateNewBrowser( n, arg1 );
  984.     ret_string = activeBrowser->tk_pathname;
  985.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  986.     break;
  987.  
  988. case FWINDOWFONT:
  989.     if( arg2[0] != '\0' )
  990.         w = FindWindowByTkName( arg2 );
  991.     if( w == NULL ) {
  992.         printf("FWINDOWFONT: window %s not found\n", arg2);
  993.         break;
  994.     }
  995.     if( arg1[0] == '\0' )
  996.         arg1 = textFont;
  997.     /* copy it into the window's font name */
  998.     PtFree( w->font.name );
  999.     w->font.name = PtMalloc(strlen(arg1)+1, "font name");
  1000.     strcpy(w->font.name, arg1);
  1001.     /* indicate that the font is not yet loaded */
  1002.     w->font.height = 0;
  1003.     /* redraw the window with the new font */
  1004.     WorkspaceResized( w );
  1005.     XClearWindow( MainDisplay, w->x_window_id );
  1006.     drawWindow( w );
  1007.     break;
  1008.  
  1009. case FBROWSERFONT:
  1010.     if( arg1[0] == '\0' )
  1011.         arg1 = browserFont;
  1012.     ChangeBrowserFontTo( activeBrowser, arg1 );
  1013.     /* redraw the file list */
  1014.     NewFilelist( activeBrowser );
  1015.     break;
  1016.  
  1017. case FLOWER:
  1018.     if( arg1[0] != '\0' )
  1019.         w = FindWindowByTkName( arg1 );
  1020.     if( w == NULL ) {
  1021.         printf("FLOWER: window %s not found\n", arg1);
  1022.         break;
  1023.     }
  1024.     XLowerWindow( MainDisplay, Tk_WindowId(w->tk_toplevel) );
  1025.     break;
  1026.  
  1027. case FRAISE:
  1028.     if( arg1[0] != '\0' )
  1029.         w = FindWindowByTkName( arg1 );
  1030.     if( w == NULL ) {
  1031.         printf("FRAISE: window %s not found\n", arg1);
  1032.         break;
  1033.     }
  1034.     XRaiseWindow( MainDisplay, Tk_WindowId(w->tk_toplevel) );
  1035.     break;
  1036.  
  1037. case FCD:
  1038.     if( arg1[0] == '\0' )
  1039.         arg1 = "~";
  1040.     n = chdir( Tcl_TildeSubst(interp,arg1) );
  1041.     (void)ExecTclCommand( "if [file exists .ptdirrc] {source .ptdirrc}" );
  1042.     if( n == -1 ) {
  1043.         extern int errno;
  1044.         extern int sys_nerr;
  1045.         extern char *sys_errlist[];
  1046.         if( errno < sys_nerr )
  1047.             fileName = sys_errlist[errno];
  1048.         else
  1049.             fileName = "";
  1050.         sprintf( msgBuffer, "Change directory failed: %s", fileName );
  1051.         msg( msgBuffer , 1 );
  1052.     }
  1053.     NewFilelist( activeBrowser );
  1054.     break;
  1055.  
  1056. case FOPENWINDOW:
  1057.     if( arg1[0] == '\0' )
  1058.         arg1 = "NoFileName";
  1059.     FixName( arg1 );
  1060.     if( arg2[0] == '\0' )
  1061.         arg2 = textGeometry;
  1062.     w = GetNewFile( NULL, arg1, arg2 );
  1063.     if( w != NULL )
  1064.         ret_string = w->tk_pathname;
  1065.     else
  1066.         ret_string = "";
  1067.     Tcl_SetResult( interp, ret_string, TCL_STATIC );
  1068.     break;
  1069.  
  1070. case FCLOSEWINDOW:
  1071.     if( arg2[0] != '\0' )
  1072.         w = FindWindowByTkName( arg2 );
  1073.     if( w == NULL ) {
  1074. #ifdef DEBUG_UPDATE
  1075.         printf("FCLOSEWINDOW: window %s not found\n", arg2);
  1076. #endif
  1077.         break;
  1078.     }
  1079.     if( arg1[0] == '\0' || striccmp(arg1,"ask")==0 )
  1080.         n = 1;
  1081.     else if( striccmp(arg1,"nosave")==0 )
  1082.         n = 2;
  1083.     else
  1084.         n = 0;
  1085.     if( w == NULL )
  1086.         break;
  1087.     (void)closeWindow(w, n);
  1088.     break;
  1089.  
  1090. case FRAISELISTWINDOW:
  1091.     if( arg2 == NULL || arg2[0] == '\0' )
  1092.         arg2 = textGeometry;
  1093.     (void)Tcl_GetInt( interp, arg1, &int1 );
  1094.     RaiseListWindow( int1, arg2 );
  1095.     break;
  1096.  
  1097. case FCLOSEBROWSER: {    /* close the active browser */
  1098.     BrowserData *browser = browserList;
  1099.     BrowserData *prev_browser, *next_browser;
  1100.     
  1101.     /* find activeBrowser on the browser list */
  1102.     while( browser != activeBrowser && browser != NULL )
  1103.         browser = browser->nextBrowser;
  1104.     if( browser == NULL ) {
  1105.         printf("ERROR: activeBrowser not on browserList\n");
  1106.         return ret_string;
  1107.     }
  1108.     /* do not allow the toplevel window to be deleted */
  1109.     if( browser == mainBrowser ) {
  1110.         msg( "Cannot close the main browser window", 1 );
  1111.         break;
  1112.     }
  1113.  
  1114.     /* reduce the use count for this FileListData */
  1115.     ReduceUseCount( browser->fileListData );
  1116.  
  1117.     /* unlink browser from the list of browsers */
  1118.     prev_browser = browser->prevBrowser;
  1119.     next_browser = browser->nextBrowser;
  1120.     if( prev_browser == NULL ) {
  1121.         /* activeBrowser is first in the browserList */
  1122.         if( next_browser == NULL ) {
  1123.             /* deleting last browser -- do not allow this */
  1124.             msg("Cannot delete the last browser", 1);
  1125.             return ret_string;
  1126.         } else {
  1127.             /* terminate chain and fix up activeBrowser */
  1128.             next_browser->prevBrowser = NULL;
  1129.             activeBrowser = next_browser;
  1130.             browserList = next_browser;
  1131.         }
  1132.     } else {
  1133.         prev_browser->nextBrowser = next_browser;
  1134.         if( next_browser != NULL )
  1135.             next_browser->prevBrowser = prev_browser;
  1136.         activeBrowser = prev_browser;
  1137.         /* browserList points to a previous browser so its okay */
  1138.     }
  1139.     Tk_DestroyWindow( browser->tk_toplevel );
  1140.     PtFree( (char *)browser );
  1141.     break;
  1142. }
  1143.  
  1144.  
  1145. case FWRITEFILE:
  1146.     if( arg1[0] != '\0' )
  1147.         w = FindWindowByTkName( arg1 );
  1148.     if( w == NULL ) {
  1149.         printf("FWRITEFILE: window %s not found\n", arg1);
  1150.         break;
  1151.     }
  1152.     writeFile( w );
  1153.     break;
  1154.  
  1155. case FSAVEFILE:
  1156.     if( arg1[0] != '\0' )
  1157.         w = FindWindowByTkName( arg1 );
  1158.     if( w == NULL ) {
  1159.         printf("FSAVEFILE: window %s not found\n", arg1);
  1160.         break;
  1161.     }
  1162.     saveFile(w);
  1163.     break;
  1164.  
  1165. case FSAVEALL:
  1166.     w2 = windowList;
  1167.     while( w2 != NULL ) {
  1168.         if( files[w2->fileId].flags & IS_CHANGED )
  1169.             saveFile(w2);
  1170.         w2 = w2->nextWindow;
  1171.     }
  1172.     timeOfLastSave = time(NULL);
  1173.     break;
  1174.  
  1175. case FZOOM:
  1176.     if( arg1[0] != '\0' )
  1177.         w = FindWindowByTkName( arg1 );
  1178.     if( w == NULL ) {
  1179.         printf("FZOOM: window %s not found\n", arg1);
  1180.         break;
  1181.     }
  1182.     if( arg2[0] == '\0' || strcmp(arg2,"vertical")== 0 )
  1183.         n = 0;
  1184.     else
  1185.         n = 1;
  1186.     ZoomWindow( w, n );
  1187.     break;
  1188.  
  1189. /****************************** OTHER COMMANDS *****************************/
  1190. case FREADONLY:
  1191.     if( arg1[0] != '\0' )
  1192.         w = FindWindowByTkName( arg1 );
  1193.     if( w == NULL ) {
  1194.         printf("FREADONLY: window %s not found\n", arg1);
  1195.         break;
  1196.     }
  1197.     if( files[w->fileId].flags & READ_ONLY ) {
  1198.         /* file is readOnly now.  Only allow writing if the */
  1199.         /* file being edited has DOS write permission */
  1200.         /* check for read and write permissions (6 => RW) */
  1201.         if( access(files[w->fileId].origName, 6) == 0 )
  1202.             files[w->fileId].flags &= ~READ_ONLY;
  1203.     } else
  1204.         /* allow any file to be readOnly */
  1205.         files[w->fileId].flags |= READ_ONLY;
  1206.     break;
  1207.  
  1208. case FLINENUMBERS:
  1209.     if( arg1[0] != '\0' )
  1210.         w = FindWindowByTkName( arg1 );
  1211.     if( w == NULL ) {
  1212.         printf("FLINENUMBERS: window %s not found\n", arg1);
  1213.         break;
  1214.     }
  1215.     switch( arg2[0] ) {
  1216.     case '1':
  1217.         w->lineNumbers = 1;
  1218.         break;
  1219.     case '0':
  1220.         w->lineNumbers = 0;
  1221.         break;
  1222.     default:
  1223.         w->lineNumbers = !(w->lineNumbers);
  1224.         break;
  1225.     }
  1226.     drawWindow( w );
  1227.     break;
  1228.  
  1229. case FCANCEL:
  1230.     if( copyPending ) {
  1231.         currentCursor = mainCursor;
  1232.         XDefineCursor(MainDisplay, selWindow->x_window_id,
  1233.                                 currentCursor);
  1234.         copyPending = 0;
  1235.     }
  1236.     if( movePending ) {
  1237.         movePending = 0;
  1238.         msg(NULL, 0);
  1239.     }
  1240.     break;
  1241.  
  1242. case FOPTION:
  1243.     if( striccmp(arg1,"set")==0 ) {
  1244.         SetPointOption( arg2, arg3 );
  1245.     } else {
  1246.         ret_string = GetPointOption( arg2 );
  1247.         Tcl_SetResult( interp, ret_string, TCL_STATIC );
  1248.     }
  1249.     break;
  1250.  
  1251. case FINFORMONCLOSE:
  1252.     w = FindWindowByTkName( arg1 );
  1253.     if( w == NULL ) {
  1254.         printf("FINFORMONCLOSE: window %s not found\n", arg1);
  1255.         break;
  1256.     }
  1257.     n = strlen( arg2 ) + strlen( arg3 ) + 2;
  1258.     w->closeInform = (char *)PtMalloc( n, "string" );
  1259.     sprintf( w->closeInform, "%s %s", arg2, arg3 );
  1260.     break;
  1261.  
  1262.  
  1263. case FQUITPOINT:
  1264.     /* first see if any files have changed */
  1265.     w2 = windowList;
  1266.     while(  w2 != NULL ) {
  1267.         /* see if the file has been edited */
  1268.         if( files[w2->fileId].flags & IS_CHANGED )
  1269.             goto areChanges;
  1270.         w2 = w2->nextWindow;
  1271.     }
  1272.     /* no changes, so quit */
  1273.     goto exitPoint;
  1274.  
  1275. areChanges:
  1276.         if( arg1[0] == '\0' || striccmp(arg1,"ask")==0 )
  1277.                 n = 1;
  1278.     if( striccmp(arg1,"save")==0 )
  1279.         n = 0;
  1280.     else
  1281.         n = 2;
  1282.     while( windowList != NULL ) {
  1283.         ret = closeWindow( windowList, n );
  1284.         if( ret == -1 ) {
  1285.             msg("Window close failed, quit cancelled", 1);
  1286.             break;
  1287.         }
  1288.     }
  1289.     /* closeWindow removes a window from windowList and sets */
  1290.     /* windowList to NULL when it is empty -- therefor */
  1291.     /* this look really will terminate */
  1292.  
  1293. exitPoint:
  1294. #ifdef HYPERTEXT
  1295.        if( hypertextOn )
  1296.         CloseHypertext();
  1297. #endif
  1298.     /* TCL/TK CLEANUP */
  1299.     Tk_DestroyWindow( TkMainWindow );
  1300.     Tcl_DeleteInterp( interp );
  1301.     exit( 0 );
  1302.     break;
  1303.  
  1304. case FREDRAW:
  1305.     if( arg1[0] != '\0' )
  1306.         w = FindWindowByTkName( arg1 );
  1307.     if( w == NULL ) {
  1308.         printf("FREDRAW: window %s not found\n", arg1);
  1309.         break;
  1310.     }
  1311.     drawWindow( w );
  1312.     break;
  1313.  
  1314. case FDONOTHING:
  1315.     break;
  1316.  
  1317. case FSHOWUNDOS:
  1318.     if( w == NULL )
  1319.         break;
  1320.     ShowUndos( &files[w->fileId] );
  1321.     break;
  1322.  
  1323. case FPRINTSTATS:
  1324.     PrintStats( 1 );
  1325.     break;
  1326.  
  1327. #ifdef HYPERTEXT
  1328. case FADDFILETODOCUMENT:
  1329.     AddFileToDocument( w );
  1330.     sprintf(msgBuffer, "Added file %s into an Anasazi document %s",
  1331.         &(files[w->fileId].origName[w->nameOffset]),
  1332.         w->document->name);
  1333.     msg( msgBuffer, 1 );
  1334. /***** debug output *****/
  1335. printf( "%s\n", msgBuffer );
  1336. printf("file is %s (%d)\nblock is %s (%d)\nmap is %s (%d)\nview is %s (%d)\n",
  1337. w->file->name, w->file->this_one, w->block->name, w->block->this_one,
  1338. w->blockMap->name, w->blockMap->this_one, w->view->name, w->view->this_one);
  1339. /***** debug output *****/
  1340.     drawWindow( w );
  1341.     break;
  1342.  
  1343. case FCREATEDOCUMENT:
  1344.     break;
  1345.  
  1346. case FCREATEBLOCK:
  1347. {
  1348.     Block block;
  1349.     AttributeID attrID = PickAttribute( w->document,
  1350.             "Pick attribute for the new block" );
  1351.  
  1352.     if( attrID != NullObject ) {
  1353.         extern struct openFile *files;
  1354.         int fid;
  1355.         struct openFile *ff;
  1356.         Attribute attribute;
  1357.  
  1358.         block = CreateBlock( w->db, w->document, "block",
  1359.                         attrID, 0, NullObject );
  1360. /***** debug output *****/
  1361. attribute = GetAttribute( currentDB, attrID, NO_ALLOCATE);
  1362. printf("Created block %s (block ID=%d) with attribute %s (attribute ID=%d)\n",
  1363. block->name, block->this_one, attribute->name, attribute->this_one);
  1364. /***** debug output *****/
  1365.  
  1366.         drawSelection( 1 );    /* erase the selection */
  1367.  
  1368.         fid = w->fileId;
  1369.         ff = &files[fid];
  1370.  
  1371.         /* convert selBegin and selEnd to the underlying (real) file */
  1372.         ret = GetRealSelection( ff, 0/*get both selBegin and selEnd*/);
  1373.  
  1374.         /* free the piece list of the old view */
  1375.         FreeOldViewPieces( ff );
  1376.  
  1377.         /* insert the new block into the real file */
  1378.         w->fileId = w->realFileId;
  1379.         (void)InsertBlock( block->this_one );
  1380.  
  1381.         /* create a new piece table for the view */
  1382.         w->fileId = CreateViewFile( w );
  1383.  
  1384.         /* free the block structure since we are done with it */
  1385.         PtFree( (char *)block );
  1386.         drawWindow( w );
  1387.     }
  1388.     break;
  1389. }
  1390.  
  1391. case FCREATEATTRIBUTE:
  1392. {
  1393.     Attribute attribute;
  1394.  
  1395.     sprintf( msgBuffer, "MakeModalEntry {%s} {%s} {%s} {%s}",
  1396.         "Create Attribute", "Name of attribute to create",
  1397.         "Create attribute", "Cancel" );
  1398.     (void)ExecTclCommand( msgBuffer );
  1399.     command( FWAITFORRETURNSTRING, "", "", "", "", "", "" );
  1400.     if( strcmp(returnString,"XXXcancelXXX") != 0 ) {
  1401.         attribute = CreateAttribute( currentDB, currentDocument,
  1402.                         returnString );
  1403. /***** debug output *****/
  1404. printf("Created attribute %s with ID=%d\n",attribute->name,attribute->this_one);
  1405. /***** debug output *****/
  1406.         PtFree( (char *)attribute );
  1407.     }
  1408.     break;
  1409. }
  1410.  
  1411. case FCREATEMAP:
  1412. {
  1413.     Map map;
  1414.     char *s, *box_name;
  1415.     PickListItem * itemList, *item;
  1416.  
  1417.     sprintf( msgBuffer, "MakeModalEntry {%s} {%s} {%s} {%s}",
  1418.         "Create Map", "Name of map to create",
  1419.         "Create map", "Cancel" );
  1420.     (void)ExecTclCommand( msgBuffer );
  1421.     command( FWAITFORRETURNSTRING, "", "", "", "", "", "" );
  1422.     if( strcmp(returnString,"XXXcancelXXX") != 0 ) {
  1423.         map = CreateMap( currentDB, currentDocument, returnString );
  1424. /***** debug output *****/
  1425. printf("Created map %s with ID=%d\n",map->name,map->this_one);
  1426. /***** debug output *****/
  1427.         /* get the list of items */
  1428.         itemList = GenerateIDList( currentDocument->firstAttribute,
  1429.             AttributeMagic );
  1430.         sprintf( msgBuffer, "MakeMapBox" );
  1431.         s = ExecTclCommand( msgBuffer );
  1432.         /* make a copy of the name */
  1433.         box_name = (char *)PtMalloc( strlen(s)+1, "name" );
  1434.         strcpy( box_name, s );
  1435.         /* fill the list box */
  1436.         item = itemList;
  1437.         while( itemList != NULL ) {
  1438.             sprintf( msgBuffer, "%s.alist.items insert end {%s}",
  1439.                         box_name, item->name );
  1440.             (void)ExecTclCommand( msgBuffer );
  1441.             item = item->next;
  1442.         }
  1443.         PtFree( (char *)box_name );
  1444.  
  1445.         command( FWAITFORRETURNSTRING, "", "", "", "", "", "" );
  1446.         if( strcmp(returnString,"XXXcancelXXX") != 0 ) {
  1447.             int i, n, b[MAP_SIZE];
  1448.             Attribute attribute;
  1449.             for( i = 0; i < MAP_SIZE; ++i )
  1450.                 b[i] = 0;
  1451.             n = sscanf( returnString, "%d %d %d %d %d",
  1452.                 &b[0], &b[1], &b[2], &b[3], &b[4]);
  1453. /***** debug output *****/
  1454. printf("This map will show block types:\n");
  1455. for( i = 0; i < n; ++i ) {
  1456.     attribute = GetAttribute( currentDB, (ID)b[i], NO_ALLOCATE );
  1457.     if( attribute == NULL )
  1458.         printf("Attribute ID %d is invalid\n", b[i]);
  1459.     else {
  1460.         printf("\t%s (%d)\n", attribute->name, b[i]);
  1461.         map->domain[i] = b[i];
  1462.     }
  1463. }
  1464. printf("\n");
  1465. /***** debug output *****/
  1466.             PutMap( currentDB, map, 0 );
  1467.         }
  1468.         PtFree( (char *)map );
  1469.         FreeIDList( itemList );
  1470.     }
  1471.     break;
  1472. }
  1473.  
  1474. case FCREATELINK:
  1475.     DumpTables();
  1476.     break;
  1477.  
  1478. case FCREATEVIEW:
  1479.     break;
  1480.  
  1481. case FCHANGEMAP:
  1482. {
  1483.     Map map;
  1484.     int i;
  1485.     MapID mapID = PickMap( w->document, "Pick map to change to" );
  1486.  
  1487.     if( mapID != NullObject ) {
  1488.         /* get the map */
  1489.         map = GetMap( currentDB, mapID, ALLOCATE );
  1490.         if( map == NULL ) {
  1491.             printf("Map ID %d not found\n", mapID );
  1492.             break;
  1493.         }
  1494.  
  1495.         /* free the old map (if any) and install the new one */
  1496.         PtFree( (char *)(w->blockMap) );
  1497.         w->blockMap = map;
  1498.  
  1499.         printf("Current map will show block types:\n");
  1500.         for( i = 0; i < MAP_SIZE && map->domain[i]!=NullObject; ++i ) {
  1501.             Attribute attribute;
  1502.             attribute = GetAttribute( currentDB,
  1503.                         map->domain[i], NO_ALLOCATE );
  1504.             if( attribute == NULL )
  1505.                 printf("Attribute ID %d is invalid\n",
  1506.                         map->domain[i]);
  1507.             else
  1508.                 printf("\t%s (%d)\n", attribute->name,
  1509.                         attribute->this_one);
  1510.         }
  1511.  
  1512.         /* free the piece list of the old view */
  1513.         FreeOldViewPieces( &(files[w->fileId]) );
  1514.  
  1515.         /* create a piece table for the new view */
  1516.         w->fileId = CreateViewFile( w );
  1517.  
  1518.         drawWindow( w );
  1519.     }
  1520.     break;
  1521. }
  1522.  
  1523. case FSHOWATTRIBUTES:
  1524. {
  1525.     AttributeID attributeID;
  1526.     Attribute attribute;
  1527.  
  1528. /***** debug output *****/
  1529. attributeID = currentDocument->firstAttribute;
  1530. printf("\n*** List of all defined attributes ***\n");
  1531. while( attributeID != NullObject ) {
  1532.     attribute = GetAttribute( currentDB, attributeID, NO_ALLOCATE );
  1533.     printf("%s (%d)\n", attribute->name, attribute->this_one );
  1534.     attributeID = attribute->next;
  1535. }
  1536. /***** debug output *****/
  1537.     attributeID = PickAttribute( currentDocument, "Show attributes" );
  1538.     break;
  1539. }
  1540.  
  1541. case FSHOWBLOCKS:
  1542. {
  1543.     BlockID blockID;
  1544.     Block block;
  1545.     int i;
  1546.  
  1547. /***** debug output *****/
  1548. blockID = currentDocument->firstBlock;
  1549. printf("\n*** List of all defined blocks ***\n");
  1550. while( blockID != NullObject ) {
  1551.     block = GetBlock( currentDB, blockID, NO_ALLOCATE );
  1552.     printf("%s (%d) fileID=%d @ %d, attributes:",
  1553.         block->name, block->this_one, block->file, block->hint );
  1554.     for( i = 0; i < MAX_ATTRIBUTES; ++i ) {
  1555.         if( block->attribute[i] == NullObject )
  1556.             break;
  1557.         printf(" %d", block->attribute[i]);
  1558.     }
  1559.     printf("\n");
  1560.     blockID = block->next;
  1561. }
  1562. /***** debug output *****/
  1563.     blockID = PickBlock( currentDocument, "Show blocks" );
  1564.     break;
  1565. }
  1566.  
  1567. case FSHOWDOCUMENTS:
  1568.     printf("\n*** The current document ***\n");
  1569.     printf("%s (%d), next free=%d, initial view=%d\n",
  1570.         currentDocument->name, currentDocument->this_one,
  1571.         currentDocument->nextFreeID, currentDocument->initialView );
  1572.     break;
  1573.  
  1574. case FSHOWFILES:
  1575. {
  1576.     FileID fileID;
  1577.     File file;
  1578.  
  1579. /***** debug output *****/
  1580. fileID = currentDocument->firstFile;
  1581. printf("\n*** List of all defined files ***\n");
  1582. while( fileID != NullObject ) {
  1583.     file = GetFile( currentDB, fileID, NO_ALLOCATE );
  1584.     printf("%s (%d)\n", file->name, file->this_one );
  1585.     fileID = file->next;
  1586. }
  1587. /***** debug output *****/
  1588. /***** debug output *****/
  1589.     fileID = PickFile( currentDocument, "Show files" );
  1590.     break;
  1591. }
  1592.  
  1593. case FSHOWLINKS:
  1594. {    LinkID linkID;
  1595.     Link link;
  1596.     int i;
  1597.  
  1598. /***** debug output *****/
  1599. linkID = currentDocument->firstLink;
  1600. printf("\n*** List of all defined links ***\n");
  1601. while( linkID != NullObject ) {
  1602.     link = GetLink( currentDB, linkID, NO_ALLOCATE );
  1603.     printf("%s (%d) fromID=%d toID=%d, attributes:",
  1604.         link->name, link->this_one, link->from, link->to );
  1605.     for( i = 0; i < MAX_ATTRIBUTES; ++i ) {
  1606.         if( link->attribute[i] == NullObject )
  1607.             break;
  1608.         printf(" %d", link->attribute[i]);
  1609.     }
  1610.     printf("\n");
  1611.     linkID = link->next;
  1612. }
  1613. /***** debug output *****/
  1614.     linkID = PickLink( currentDocument, "Show links" );
  1615.     break;
  1616. }
  1617.  
  1618. case FSHOWMAPS:
  1619. {
  1620.     MapID mapID;
  1621.     Map map;
  1622.  
  1623. /***** debug output *****/
  1624. mapID = currentDocument->firstMap;
  1625. printf("\n*** List of all defined maps ***\n");
  1626. while( mapID != NullObject ) {
  1627.     int i;
  1628.     map = GetMap( currentDB, mapID, ALLOCATE );
  1629.     printf("%s (%d)\n", map->name, map->this_one );
  1630.     for( i = 0; i < MAP_SIZE && map->domain[i]!=NullObject; ++i ) {
  1631.         Attribute attribute;
  1632.         attribute = GetAttribute( currentDB, map->domain[i],
  1633.                                 NO_ALLOCATE );
  1634.         if( attribute == NULL )
  1635.             printf("Attribute ID %d is invalid\n",
  1636.                     map->domain[i]);
  1637.         else
  1638.             printf("\t%s (%d)\n", attribute->name,
  1639.                     attribute->this_one);
  1640.     }
  1641.     mapID = map->next;
  1642.     PtFree( (char *)map );
  1643. }
  1644. /***** debug output *****/
  1645.     mapID = PickMap( currentDocument, "Show maps" );
  1646.     break;
  1647. }
  1648.  
  1649. case FSHOWTEXTS:
  1650. {
  1651.     TextID textID;
  1652.     Text text;
  1653.  
  1654. /***** debug output *****/
  1655. textID = currentDocument->firstText;
  1656. printf("\n*** List of all defined texts ***\n");
  1657. while( textID != NullObject ) {
  1658.     text = GetText( currentDB, textID, NO_ALLOCATE );
  1659.     printf("%s (%d)\n", text->s, text->this_one );
  1660.     textID = text->next;
  1661. }
  1662. /***** debug output *****/
  1663.     textID = PickText( currentDocument, "Show texts" );
  1664.     break;
  1665. }
  1666.  
  1667. case FSHOWVIEWS:
  1668. {    ViewID viewID;
  1669.     View view;
  1670.  
  1671. /***** debug output *****/
  1672. viewID = currentDocument->firstView;
  1673. printf("\n*** List of all defined views ***\n");
  1674. while( viewID != NullObject ) {
  1675.     view = GetView( currentDB, viewID, NO_ALLOCATE );
  1676.     printf("%s (%d), block=%d, fromLinkMap=%d, toLinkMap=%d, blockMap=%d\n",
  1677.         view->name, view->this_one, view->blockID,
  1678.         view->fromLinkMap, view->toLinkMap,
  1679.         view->blockMap );
  1680.     viewID = view->next;
  1681. }
  1682. /***** debug output *****/
  1683.     viewID = PickView( currentDocument, "Show views" );
  1684.     break;
  1685. }
  1686. #endif
  1687.  
  1688. default:
  1689.     sprintf(msgBuffer, "No action is defined for command %d", fn);
  1690.     msg(msgBuffer, 1);
  1691.     break;
  1692. }
  1693. lastFn = fn;
  1694. if( fn != FDONOTHING && fn > 0 ) 
  1695.     lastCommand = fn;
  1696.  
  1697. return ret_string;
  1698. }
  1699.  
  1700.