home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / gemlib27.lzh / GEMLIB27 / WINMAIN.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  34KB  |  1,372 lines

  1. /* multi-window terminal emulation Version 0.2, May 29th 1986
  2.  *
  3.  * (C) Copyright 1986 Hans-Martin Mosner, University of Dortmund, Germany
  4.  * You may freely use and distribute this program as source
  5.  * and/or binary provided you make no profit with it.
  6.  */
  7.  
  8. #ifdef __GNUC__
  9. #  define __OLD_WAY__    /* for evnt_multi() */
  10. #  include <gemfast.h>
  11. #  include <aesbind.h>
  12. #  include <vdibind.h>
  13. #else
  14. #  include <obdefs.h>
  15. #  include <gemdefs.h>
  16. #  include <bios.h>
  17. #  include <xbios.h>
  18. #endif
  19. #include <osbind.h>
  20. #include <stdio.h>
  21. #include "wind.h"
  22. #include "uw.h"
  23. #include "windefs.h"
  24.  
  25. #define FIRSTOBJ DABOUT
  26. #define LASTOBJ PRTSTOP
  27.  
  28.  
  29. /* global constants
  30.  */
  31.  
  32. extern    int        gl_apid;
  33. extern    struct    wi_str    w[];
  34.  
  35. #ifndef __GNUC__    /* Gnu bindings have these */
  36. int    contrl[12];
  37. int    intin[128];
  38. int    ptsin[128];
  39. int    intout[128];
  40. int    ptsout[128];
  41. #endif
  42. int    work_in[11];
  43. int    work_out[57];
  44. int    pxyarray[20];
  45. int    msgbuff[8];
  46.  
  47. int    phys_handle, handle;
  48.  
  49. /*
  50.  * Variables used by various routines (miscellaneous).
  51.  */
  52.  
  53. long    dummy;                /* dummy return variable */
  54. int    scr_x, scr_y, scr_w, scr_h;    /* size of screen */
  55. int    key;                /* the key pressed */
  56. int    tmp;                /* temporary for anything... */
  57. char    alert[300];            /* used for alerts */
  58. int    xsiz, ysiz;            /* temporarys for size of window */
  59.  
  60. /*
  61.  * Character stuff (fonts, keymaps).
  62.  */
  63. FNT    *fnttbl[10];            /* List of pointers to fonts avail */
  64. int    fontsavail;            /* Number of fonts available */
  65. FNT    *tempfont;            /* font pointer */
  66. char    *oldshifted;            /* Pointer to old shifted key map. */
  67. char    *oldnormal;            /* Pointer to old normal key map. */
  68. char    *oldcapslock;            /* Pointer to old caps lock key map. */
  69. int    menu_key_map[0x80];        /* menu objects indexed by key map
  70.                        (alt key) read from object file */
  71. int fontmenuobj[] =            /* array of font menu object numbers */
  72.   { FNTBIG,
  73.     FNTSYS,
  74.     FNTOWN,
  75.     FNTALT,
  76.     FNTTINY,
  77.     FNTUNKNW,
  78.     /* Add new font menu items here! */
  79.     0
  80.   };
  81. extern    FNT    *loadfont();
  82.  
  83. /*
  84.  * State (loosely defined).
  85.  */
  86. int    tick;                /* used for flashing cursor */
  87. int    outport;            /* ports used with uw */
  88. int    inwind, outwind;        /* windows for input/output */
  89. int    uw_runs;            /* is uw running ? */
  90. FNT    *curfont;            /* font in use */
  91. int    mouse;                /* is mouse visible ? */
  92. int    menonoff;            /* Menu toggle. */
  93. int    m1inout;            /* mouse event  enter = 0  exit = 1 */
  94. int    sel_inp_mode;            /* input select with right button */
  95. extern int highlighted_wdes;        /* window with text highligted */
  96. #define LOCKLEN 30            /* Max length of lock password */
  97. char    lockword[LOCKLEN];        /* lock password */
  98. char    lockbld[LOCKLEN];        /* lock password build area*/
  99. extern int kermwdes;            /* port number for kermit window */
  100.  
  101. /*
  102.  * Options (somewhat loosely defined).
  103.  */
  104. int    fast;                /* flag for fast open/close */
  105. int    overstrike;            /* flag for character drawing */
  106. int    sliders;            /* flag for sliders on new windows */
  107. int    titles;                /* flag for titles on new windows */
  108. int    audibell;            /* Audible bell. */
  109. int    visibell;            /* Visible bell. */
  110. int    toponbel;            /* Top window on bell. */
  111.  
  112. FUNCSTRING fstrings[NFSTRINGS];        /* storage for function key bodys */
  113.  
  114. char    pastebuff[4096] = "";        /* 50 full lines of text */
  115.  
  116. char    confpath[80] = ".\\*.*";    /* initial config file path */
  117. char    confname[40] = "win.cnf";    /* initial config file name */
  118. int    confbutt;            /* button from fsel_input */
  119.  
  120. /*
  121.  * Screen forms, objects, and other similar goodies...
  122.  */
  123. MFDB    screen_mf;
  124.  
  125. OBJECT    *obj_tmp, *menubar;
  126. TEDINFO    *ted_tmp;
  127. TEDINFO    *ted_fnum;
  128.  
  129. extern struct iorec old_iorec;    /* copy of old rs_232 io record from winio.c */
  130.  
  131. MFORM    rmbmform[1];
  132. MFORM    lckmform[1];
  133.  
  134. #define    CHECKWIN    if (!outwind) break
  135.  
  136. /*
  137.  * The program code...
  138.  */
  139.  
  140. extern    char    *getmem();
  141. #ifdef    MWC
  142. #include <linea.h>
  143. #endif
  144.  
  145. /*
  146.  * If LOCATE is defined, it is assumed to be the path to check after
  147.  * "." for standard files (fonts, config files, etc.).
  148.  */
  149. #ifndef    LOCATE
  150. #define    locate(n)    n
  151. #else
  152. char    locpath[64] = LOCATE;
  153.  
  154. char    *
  155. locate (name)
  156. char    *name;
  157. {
  158.     int    fd;
  159.     static    char    new[80];
  160.  
  161.     close(fd = open(name, 0));
  162.     if (fd >= 0)
  163.         return (name);
  164.  
  165.     sprintf(new, "%s\\%s", locpath, name);
  166.     close(fd = open(new, 0));
  167.     return (fd >= 0? new: name);
  168. }
  169. #endif
  170.  
  171. startup()
  172. {
  173. int i,j;
  174. char *tmpfnt;
  175. static char my_shft_map[128];
  176. static char my_norm_map[128];
  177.  
  178. #ifndef    MWC
  179. register GEMFONT **a5;        /* this is really register A5 */
  180. #endif
  181.  
  182.   /* start up everything: appl_init, menu, and the like
  183.    */
  184.   appl_init();
  185.   rsrc_load(locate("wind.rsc"));
  186.   rsrc_gaddr(R_TREE, MENUBAR, &menubar);
  187.  
  188.   /*
  189.    * Fill menu_key_map by scaning object strings for ALTINDICATOR.
  190.    */
  191.   for (i = FIRSTOBJ; i <= LASTOBJ; i++)
  192.     if (menubar[i].ob_type == G_STRING)
  193.     {
  194.       char * found;
  195.       char * index();
  196.  
  197.       found = index((char *)menubar[i].ob_spec, ALTINDICATOR);
  198.       if (found != NULL)
  199.       {
  200.         menu_key_map[*(++found) & 0x7f] = i;
  201. #ifdef DEBUG
  202.         printf("menu_key_map[%c] = %d\n", *found, i);
  203. #endif
  204.       }
  205.     }
  206.  
  207. /*  objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0, CHECKED, 0); *already done*/
  208.   menu_bar(menubar, menonoff = 1);
  209.   m1inout = 1;
  210.   audibell = 1;
  211.   visibell = 1;
  212.   sliders = 1;
  213.   titles = 1;
  214.  
  215.   /* set mouse symbol to arrow
  216.    */
  217.   graf_mouse(ARROW, NULL);
  218.   mouse = 1;
  219.  
  220.   /* get screen handle and sizes;
  221.    * open virtual workstation
  222.    */
  223.   phys_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
  224.   wind_get(0, WF_WORKXYWH, &scr_x, &scr_y, &scr_w, &scr_h);
  225.   work_in[0] = Getrez() + 2;
  226.   for (i=1; i<10; work_in[i++]=1);
  227.   work_in[10] = 2;
  228.   handle = phys_handle;
  229.   v_opnvwk(work_in, &handle, work_out);
  230.  
  231.   /* set up screen mfdb
  232.    */
  233.  
  234.   screen_mf.ptr = NULL;
  235.   screen_mf.wpix = 640;
  236.   screen_mf.hpix = 400;
  237.   screen_mf.wwords = 40;
  238.   screen_mf.format = 0;
  239.   screen_mf.planes = 1;
  240.  
  241.   /*
  242.    * now set up the system fonts
  243.    */
  244.   fontsavail = 0;
  245.   if ((curfont = getmem((long)sizeof(FNT))) != NULL)
  246.   {
  247. #ifdef    MWC
  248.     linea0();
  249.     tmpfnt = la_init.li_a1[2]->font_data;    /* 8 x 16 system font */
  250. #else
  251. #ifdef __GNUC__
  252.     asm volatile
  253.     ("\
  254.           .word 0xa000; \
  255.           movel a1,%0"
  256.      :"=g"(a5)
  257.      :
  258.      : "d0", "d1", "d2", "a0", "a1", "a2"
  259.      );
  260. #else
  261.     asm("dc.w $a000");        /* get font addresses from line A */
  262.     asm("move.l a1,a5");        /* put it into A5 */
  263. #endif
  264.     tmpfnt = a5[2]->ft_data;
  265. #endif
  266.     for (i=0; i<128; i++)
  267.       for (j=0; j<16; j++)
  268.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  269.     curfont->inc_x = 8;
  270.     curfont->inc_y = 16;
  271.  
  272.     set_menu_string("8 x 16 sys font", fontmenuobj[fontsavail]);
  273.  
  274.     curfont->def_win_x = 80;    /* Set default window size */
  275.     curfont->def_win_y = 24;
  276.  
  277.     gen_hash(curfont, &curfont->f_hash);
  278.  
  279.     fnttbl[fontsavail] = curfont;
  280.     fontsavail++;
  281.   }
  282.   /* set up 6 x 6 system font */
  283.   if ((curfont = getmem((long)sizeof(FNT))) != NULL)
  284.   {
  285. #ifdef    MWC
  286.     linea0();
  287.     tmpfnt = la_init.li_a1[0]->font_data;
  288. #else
  289. #ifdef __GNUC__
  290.     asm volatile
  291.     ("\
  292.           .word 0xa000; \
  293.           movel a1,%0"
  294.      :"=g"(a5)
  295.      :
  296.      : "d0", "d1", "d2", "a0", "a1", "a2"
  297.      );
  298. #else
  299.     asm("dc.w $a000");        /* get font addresses from line A */
  300.     asm("move.l a1,a5");        /* put it into A5 */
  301. #endif
  302.     tmpfnt = a5[0]->ft_data;
  303. #endif
  304.     for (i=0; i<128; i++){ /* for each character (first 128) */
  305.       int bitpos, index, offset;
  306.  
  307.       bitpos = i*6;
  308.       index = bitpos >> 3;
  309.       offset = bitpos & ~(~0<<3);
  310.       for (j=0; j<6; j++) /* for each pixel row in character */
  311.         curfont->f_data[i*16+j+1] = ((tmpfnt[index+j*192] << offset) +
  312.       (tmpfnt[index+j*192+1] >> (8-offset) & ~(~0<<offset)))>>2 & 63;
  313.       curfont->f_data[i*16+0] = 0; /* extra empty row */
  314.     }
  315.     curfont->inc_x = 6;
  316.     curfont->inc_y = 7;
  317.  
  318.     /*
  319.      * The 6x6 system font can be made better.  (dot the i etc.)
  320.      * This is a bad hack, but it makes it easier to read.
  321.      */
  322.     curfont->f_data[105*16+1] = 8;
  323.     curfont->f_data[105*16+2] = 0;
  324.     curfont->f_data[105*16+5] = 8;
  325.     curfont->f_data[106*16+5] = 20;
  326.     curfont->f_data[106*16+6] = 8;
  327.     curfont->f_data[106*16+2] = 0;
  328.  
  329.     curfont->def_win_x = 80;    /* Set default window size */
  330.     curfont->def_win_y = 40;
  331.  
  332.     set_menu_string("6 x 7 sys font", fontmenuobj[fontsavail]);
  333.     gen_hash(curfont, &curfont->f_hash);
  334.  
  335.     fnttbl[fontsavail] = curfont;
  336.     fontsavail++;
  337.   }
  338.  
  339.   /*
  340.    * Load font file(s) if any.
  341.    */
  342.  
  343.   if (curfont = loadfont("windstd.fnt")) /* yes, I want the assignment (=). */
  344.   {
  345.     objc_change(menubar, fontmenuobj[fontsavail-1], 0, 0, 0, 0, 0, CHECKED, 0);
  346.     curfont->def_win_x = 80;    /* Set default window size */
  347.     curfont->def_win_y = 24;
  348.   }
  349.   else {
  350.     objc_change(menubar, FNTSYS, 0, 0, 0, 0, 0, CHECKED, 0);
  351.     curfont = fnttbl[fontsavail - 1];
  352.   }
  353.  
  354.   if (tempfont = loadfont("windalt.fnt"))
  355.   {
  356.     tempfont->def_win_x = 80;    /* Set default window size */
  357.     tempfont->def_win_y = 32;
  358.   }
  359.  
  360.   if (tempfont = loadfont("windtny.fnt"))
  361.   {
  362.     tempfont->def_win_x = 80;    /* Set default window size */
  363.     tempfont->def_win_y = 48;
  364.   }
  365.   if (tempfont = loadfont("windoth.fnt"))
  366.   {
  367.     tempfont->def_win_x = 80;    /* Set default window size */
  368.     tempfont->def_win_y = 24;
  369.   }
  370.   
  371.   /*
  372.    * Disable unused font entrys.
  373.    */
  374.   for (i = fontsavail; fontmenuobj[i] != 0; i++)
  375.   {
  376.     set_menu_string("unavailable font", fontmenuobj[i]);
  377.     objc_change(menubar, fontmenuobj[i], 0, 0, 0, 0, 0, DISABLED, 0);
  378.   }
  379.     
  380.  
  381.   /* set up the serial line (XON/XOFF flow control)
  382.    */
  383.  
  384.   Rsconf(-1, 1, -1, -1, -1, -1);
  385.  
  386.   /* Initalize function keys to default values.
  387.    */
  388.   for (i=0; i<NFSTRINGS; i++)
  389.   {
  390.     sprintf(fstrings[i], "^A%d^M", i);
  391.   }
  392.   fstrings[NFSTRINGS-1][0] = '\0'; /* last function zero length for coding */
  393.  
  394.   /* Set up the key tables to use the help key for break.
  395.    */
  396.   oldshifted = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_shifted;
  397.   oldnormal = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_normal;
  398.   oldcapslock = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_capslock;
  399.  
  400.   for (i=0; i<128; i++) { /* copy bios tables */
  401.     my_shft_map[i] = oldshifted[i];
  402.     my_norm_map[i] = oldnormal[i];
  403.   }
  404.  
  405.   my_shft_map[KC_HELP] = 0x6f; /* except help key */
  406.   for (i=KC_F1; i<=KC_F10; i++) { /* and function keys */
  407.     my_norm_map[i] = 0x6f;
  408.   }
  409. #ifdef COMMENT
  410.   /*
  411.    * These keys must be decoded manualy so that the field editing
  412.    * of gem will not be impacted.
  413.    */
  414.   my_norm_map[KC_CDOWN] = 0x0a; /* and cursor motion keys (for adm31) */
  415.   my_norm_map[KC_CLEFT] = 0x08;
  416.   my_norm_map[KC_CRIGHT] = 0x0c;
  417.   my_norm_map[KC_CUP] = 0x0b;
  418. #endif
  419. /* (void) Keytbl(my_norm_map, my_shft_map, my_norm_map); */
  420.   (void) Keytbl(my_norm_map, my_shft_map, -1L);
  421.   
  422.   form_dial(FMD_START, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h);
  423.   form_dial(FMD_FINISH, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h);
  424.   
  425.   /*
  426.    * Read initial configuration file if any
  427.    */
  428.   read_config("", locate(confname));
  429. }
  430.  
  431. finish()
  432. {
  433. int i;
  434. struct iorec *ioptr;
  435.  
  436.   /* close all windows and clean up
  437.    */
  438.  
  439.   if (uw_runs) xmitcmd(CB_FN_MAINT|CB_MF_EXIT);
  440.   for (i=0; i<MAX_WIND; i++)
  441.     w_close(i);
  442.   (void) Keytbl(oldnormal, oldshifted, oldcapslock); /* restore key maps */
  443.  
  444.   if (old_iorec.io_bufsiz != 0) {
  445.     ioptr = Iorec(0);    /* restore rs_232 io record */
  446.     *ioptr = old_iorec;
  447.   }
  448.  
  449.   menu_bar(menubar, 0);
  450.   v_clsvwk(handle);
  451.   appl_exit();
  452.   exit(0);
  453. }
  454.  
  455. memory()
  456. {
  457. long m = Malloc(-1L);
  458.  
  459.   sprintf(alert, "[0][Free memory: %ld bytes][Ok]", m);
  460.   form_alert(1, alert);
  461. }
  462.  
  463. #ifdef MWC
  464.   long _stksiz = 4096l;        /* Tell Mark Williams C we need 4k stack */
  465. #endif
  466. main()
  467. {
  468.   int    event;
  469.   int    menuitem = 0;        /* Alt sequence mapped to menu item */
  470.   int    cx, cy, cw, ch;
  471.   int    mx, my, mb, mk;        /* mouse coordinates from event_multi */
  472.   int    ww, wh;            /* window width & height for move */
  473.   int    buttonstate = 2;    /* button state to wait for next. */
  474.   int    clicks;            /* number of clicks seen by evnt_multi. */
  475.   register int    cnt;
  476.   int    funcindex = 0;
  477.   int    regionflag = 0;        /* indicates region selection in progress */
  478.   int    locked = 0;        /* keyboard and mouse locked with password ?*/
  479.   startup();
  480.  
  481.   xsiz = curfont->def_win_x;
  482.   ysiz = curfont->def_win_y;
  483.  
  484. init:
  485.   w_open(1, "Terminal", xsiz, ysiz);
  486.   outport = 1;
  487.   inwind = outwind = find_wind(1);
  488.   printer_mark(outwind);
  489.  
  490.   for (;;)
  491.   {
  492.     if (!mouse)
  493.     {
  494.       graf_mouse(M_ON, NULL);
  495.       ++mouse;
  496.     }
  497.     if (menuitem)
  498.     {
  499.       event = MU_MESAG;
  500.       msgbuff[0] = MN_SELECTED;
  501.       msgbuff[4] = menuitem;
  502.       menuitem = 0;
  503.     }
  504.     else
  505.     {
  506.       event = evnt_multi(MU_MESAG | MU_KEYBD | MU_TIMER | MU_BUTTON | MU_M1,
  507.     2, 2, buttonstate,
  508.     m1inout, scr_x, scr_y, scr_w, scr_h,
  509.     0, 0, 0, 0, 0,
  510. #ifdef __GNUC__
  511.     msgbuff, 0, 15,
  512. #else
  513.     msgbuff, 15, 0,
  514. #endif
  515.     &mx, &my, &mb, &mk,
  516.     &key, &clicks);
  517.     }
  518.  
  519.     if (event & MU_KEYBD)
  520.     if (locked) {
  521.       static char lockkey[LOCKLEN];
  522.       static int lockindex;
  523.       int keyval = key & 0xff;
  524.       
  525.       if (keyval == '\r') {
  526.         lockkey[lockindex] = '\0';
  527.         if (strcmp (lockkey, lockword) == 0) {
  528.           graf_mouse(ARROW, &dummy);
  529.           menu_bar(menubar, menonoff);
  530.       locked = 0;
  531.     }
  532.     lockindex = 0;
  533.       }
  534.       else 
  535.         if (lockindex < LOCKLEN - 1)
  536.           lockkey[lockindex++] = keyval;
  537.     }
  538.     else
  539.     {
  540.       int i, j;
  541.       int outcount;
  542.       int keyindex = key >> 8;
  543.       int keyval = key & 0xff;
  544.       int funcindex = NFSTRINGS;
  545.       char outputstring[MAXFUNCLEN];
  546.  
  547. #ifdef DEBUG
  548.       printf("keyindex = %x, keyval = %x\n", keyindex, keyval);
  549. #endif
  550.  
  551.       /*
  552.        * Decode key for function keys or other special keys
  553.        * This section could be made faster at the expense of less clear
  554.        * code.  It seems to be fast enough for now. (How fast can you type?)
  555.        * It should probrably be table driven.
  556.        */
  557.       if (keyindex >= KC_F1 || (keyval == 0 
  558.         && keyindex != 0x39 /* ctl-space */ && keyindex != 3 /* ctl-@ */))
  559.       {    /* decode these keys manualy */
  560.         if (keyindex >= KC_F1 && keyindex <= KC_F10) /* Unshifted F keys */
  561.         {
  562.       if (keyval == 0x6f)    /* plain function key */
  563.         funcindex = keyindex - KC_F1;
  564.  
  565.       else if (keyval == 0x0f)/* control function key */
  566.         funcindex = keyindex - KC_F1 + 10;
  567.  
  568.       else if (keyval == 0)    /* alt function key */
  569.         funcindex = keyindex - KC_F1 + 30;
  570.         }
  571.  
  572.         else if (keyindex >= KC_F1+25 && keyindex <= KC_F10+25) /* shift F */
  573.           funcindex = keyindex - KC_F1 - 25 + 20;
  574.  
  575.     else if (key == (KC_CDOWN << 8))
  576.       keyval = 0x0a;
  577.  
  578.     else if (key == (KC_CLEFT << 8))
  579.       keyval = 0x08;
  580.  
  581.     else if (key == (KC_CRIGHT << 8))
  582.       keyval = 0x0c;
  583.  
  584.     else if (key == (KC_CUP << 8))
  585.       keyval = 0x0b;
  586.  
  587.         else if (key == 0x626f) /* break key (shift help) */
  588.         {
  589.           long    clk_time;
  590.     
  591.       clk_time = clock();
  592.       Rsconf(-1, -1, -1, -1, 9, -1); /* set break condition */
  593.       while (clock() - clk_time < BREAK_TICKS); /* delay while break is sent */
  594.       Rsconf(-1, -1, -1, -1, 1, -1); /* clear break condition */
  595.       funcindex = NFSTRINGS - 1; /* last function key is zero length */
  596.     }
  597.     else if (keyval == 0)
  598.     {    /* check if alt key used to select menu entry */
  599.       if (keyindex >= 0x78 && keyindex <= 0x7e)
  600.       {    /* alt number used to select window number */
  601.         int newwind = keyindex - 0x77;
  602.  
  603.         if (find_port(newwind) > 0)
  604.           w_top(newwind);
  605.       }
  606.       else
  607.       {    /* alt key short-hand--fake menu message next time around */
  608.         menuitem = menu_key_map[oldnormal[keyindex] & 0x7f];
  609. #ifdef DEBUG
  610.         printf("menu keyindex = %x, char = %c, menuitem = %d\n",
  611.           keyindex, oldnormal[keyindex], menuitem);
  612. #endif
  613.       }
  614.       funcindex = NFSTRINGS - 1; /* last function key is zero length */
  615.     }
  616.       }
  617.       if (funcindex < NFSTRINGS) /* if function key */
  618.       {        /* copy function string to outputstring decoding ^ */
  619.     j=0;
  620.     outcount = 0;
  621.         for (i=0; fstrings[funcindex][i] != '\0'; i++)
  622.     {
  623.       outputstring[j] = fstrings[funcindex][i];
  624.       if (outputstring[j] == '^')
  625.       {
  626.         i++;
  627.         if (fstrings[funcindex][i] == '?')
  628.           outputstring[j] = '\177';
  629.         else if (fstrings[funcindex][i] != '^')
  630.           outputstring[j] = fstrings[funcindex][i] & 0x1f;
  631.       }
  632.       j++;
  633.     }
  634.     outcount = j;
  635.       }
  636.       else    /* normal key press */
  637.       {
  638.         outputstring[0] = keyval & 0x7f;
  639.     outcount = 1;
  640.       }
  641.       /*
  642.        * Now output outcount characters which are stored in outputstring.
  643.        */
  644.       proto_out(outport, outputstring, outcount);
  645.     }
  646.  
  647.     if (event & MU_TIMER)
  648.     {
  649.       if (tick++ > 20)
  650.       {
  651.     w_flash(outwind, 2);
  652.     tick = 0;
  653.     if (kermwdes) kermtimchk();
  654.       }
  655.       /* act on any input from serial port */
  656.       if (proto_in () < 0) goto init    /* uw mode ended? */;
  657.     }
  658.  
  659.     if (event & MU_MESAG)
  660.     {
  661.       switch (msgbuff[0])
  662.       {
  663.       case MN_SELECTED:
  664.     switch (msgbuff[4])
  665.     {
  666.     case REMSHELL:
  667.     case SHELLOTH:
  668.     case SHELL32:
  669.     case SHELL24:
  670.     case SHELL12:
  671.     case SHELL8:
  672.       if (msgbuff[4] == REMSHELL)
  673.       {    /* default window size */
  674.             xsiz = curfont->def_win_x;
  675.         ysiz = curfont->def_win_y;
  676.       }
  677.       else if (msgbuff[4] == SHELLOTH)
  678.       {
  679.         if (!size_dial()) break;
  680.       }
  681.       else
  682.       {    /* size specified in menu string */
  683.         char *ent_str;
  684.  
  685.         ent_str = (char *) menubar[msgbuff[4]].ob_spec;
  686.         sscanf(ent_str, "%*s%d%*s%d", &ysiz, &xsiz);
  687.       }
  688.       if (uw_runs)
  689.       {
  690.         tmp = w_open(0, "Terminal", xsiz, ysiz);
  691.         if (tmp)
  692.         {
  693.           outport = tmp;
  694.           outwind = find_wind(tmp);
  695.           xmitcmd(CB_FN_NEWW|tmp);
  696.         }
  697.       } else
  698.       {
  699.         form_alert(1, "[1][UW is not running][Ok]");
  700.       }
  701.       break;
  702.  
  703.     case LOCCOPY:
  704.       for (cnt=1; cnt<MAX_WIND; cnt++)
  705.       {
  706.         if (!find_wind(cnt))
  707.         {
  708.           break;        /* a free port */
  709.         }
  710.       }
  711.       if (cnt < MAX_WIND)
  712.       {
  713.         static int c[8];
  714.         struct wi_str *wp1 = &w[outwind];
  715.         struct wi_str *wp2;
  716.         outport = w_open(cnt, "Local Copy", wp1->x_chrs, wp1->y_chrs);
  717.         outwind = find_wind(outport);
  718.         wp2 = &w[outwind];
  719.         c[0] = wp1->m_off;
  720.         c[1] = wp1->top_y;
  721.         c[2] = c[0] + wp1->wi_mf.wpix;
  722.         c[3] = c[1] + wp1->wi_mf.hpix;
  723.         c[4] = wp2->m_off;
  724.         c[5] = wp2->top_y;
  725.         c[6] = c[4] + wp2->wi_mf.wpix;
  726.         c[7] = c[5] + wp2->wi_mf.hpix;
  727.         vro_cpyfm(handle, FM_COPY, c, &wp1->wi_mf, &wp2->wi_mf);
  728.         wp2->w_local = TRUE;
  729.       }
  730.       break;
  731.  
  732.     case WINRESIZ:
  733.       if (!size_dial()) break;
  734.       w_resize(outwind, xsiz, ysiz);
  735.       break;
  736.  
  737.     case FQUIT:
  738.       finish();
  739.  
  740.     case FQUITUW:
  741.       if (uw_runs)
  742.       {
  743.       int i;
  744.         xmitcmd(CB_FN_MAINT|CB_MF_EXIT);
  745.         uw_runs = 0;
  746.         for (i=1; i<8; i++)
  747.         {
  748.           w_close(find_wind(i));
  749.         }
  750.         menu_tnormal(menubar, msgbuff[3], 1);
  751.         goto init;
  752.       }
  753.       break;
  754.  
  755.     case LOADCONF:
  756.       fsel_input(confpath, confname, &confbutt);
  757.       if (confbutt) 
  758.         read_config(confpath, confname);
  759.       break;
  760.  
  761.     case SAVECONF:
  762.       fsel_input(confpath, confname, &confbutt);
  763.       if (confbutt) 
  764.         write_config(confpath, confname);
  765.       break;
  766.  
  767.     case CAPTURE:
  768.       if (outwind)
  769.       {
  770.         WI_STR *wp = &w[outwind];
  771.  
  772.         fsel_input(wp->wi_fpath, wp->wi_fname, &confbutt);
  773.         if (confbutt)
  774.           setcapture(wp);
  775.       }
  776.       break;
  777.  
  778.     case COMMAND:
  779.       do_exec();
  780.       break;
  781.  
  782.     case SETPATH:
  783.       do_path();
  784.       break;
  785.  
  786.     case KERMIT:
  787.       kerminit(outwind);
  788.       break;
  789.  
  790.     case FLOCKKEY:
  791.       s_dial(LOCKINFO, 1);
  792.       cnt = 0;
  793.       while ((key = evnt_keybd() & 0xff) != '\r') {
  794.         if (key == '\033') {    /* ESC means use old password */
  795.           locked = 1;
  796.           strcpy(lockbld, lockword);
  797.           break;
  798.         }
  799.         if (cnt < LOCKLEN - 1)
  800.           lockbld[cnt++] = key;
  801.       }
  802.       while (! locked) {
  803.         lockbld[cnt] = '\0';
  804.         locked = 1;
  805.         cnt = 0;
  806.         while ((key = (evnt_keybd() & 0xff)) != '\r')
  807.           if (cnt < LOCKLEN - 1)
  808.             if (key != lockbld[cnt++]) {
  809.           locked = 0;
  810.           lockbld[cnt - 1] = key;
  811.         }
  812.         if (lockbld[cnt] != '\0')
  813.           locked = 0;
  814.       }
  815.       if (lockbld[0] == '\0')
  816.         locked = 0;
  817.       if (locked) {
  818.         strcpy(lockword, lockbld);
  819.         menu_bar(menubar, 0);
  820.         graf_mouse(USER_DEF, lckmform);
  821.       }
  822.       s_dial(LOCKINFO, 2);
  823.       break;
  824.  
  825.     case DABOUT:
  826.       if (s_dial(ABOUT, 3) == MOREINF1)
  827.       {
  828.         if (s_dial(INFO1, 3) == CONT1)
  829.         {    /* give short help screens */
  830.           if (s_dial(INFO2, 3) == CONT2)
  831.           {
  832.             if (s_dial(INFO3, 3) == CONT3)
  833.             {
  834.               if (s_dial(INFO4, 3) == CONT4)
  835.               {
  836.             s_dial(INFO5, 3);
  837.               }
  838.             }
  839.           }
  840.         }
  841.       }
  842.       break;
  843.  
  844.     case WRENAME:
  845.       CHECKWIN;
  846.       rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  847.       ted_tmp = (TEDINFO *) obj_tmp[FLD1].ob_spec;
  848.       strcpy(ted_tmp->te_ptext, w[outwind].name);
  849.       form_center(obj_tmp, &cx, &cy, &cw, &ch);
  850.       form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  851.       if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  852.       objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  853.       tmp = form_do(obj_tmp, FLD1);
  854.       if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  855.       form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  856.       objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  857.       if (tmp == OKRENAME) w_rename(outwind, (char *) ted_tmp->te_ptext);
  858.       break;
  859.  
  860.     case FUNCTKEY:
  861.       rsrc_gaddr(R_TREE, FUNCTEDT, &obj_tmp);
  862.       ted_fnum = (TEDINFO *) obj_tmp[FUNCNAME].ob_spec;
  863.       sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  864.       ted_tmp = (TEDINFO *) obj_tmp[FUNCBODY].ob_spec;
  865.       strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  866.       form_center(obj_tmp, &cx, &cy, &cw, &ch);
  867.       form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  868.       if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  869.       objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  870.       tmp = 0;
  871.       while (tmp != FUNCEXIT)
  872.       {
  873.         int i;
  874.         
  875.         tmp = form_do(obj_tmp, FUNCNAME);
  876.         switch (tmp)
  877.         {
  878.         case FUNCSHOW:
  879.           funcindex = atoi(ted_fnum->te_ptext) - 1;
  880.           if (funcindex < 0)
  881.             funcindex = NFSTRINGS - 3;
  882.           else if (funcindex > NFSTRINGS - 3)
  883.             funcindex = 0;
  884.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  885.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  886.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  887.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  888.           break;
  889.         case FUNCPREV:
  890.           funcindex --;
  891.           if (funcindex < 0)
  892.             funcindex = NFSTRINGS - 3;
  893.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  894.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  895.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  896.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  897.           break;
  898.         case FUNCNEXT:
  899.           funcindex ++;
  900.           if (funcindex > NFSTRINGS - 3)
  901.             funcindex = 0;
  902.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  903.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  904.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  905.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  906.           break;
  907.         case FUNCENT:
  908.           funcindex = atoi(ted_fnum->te_ptext) - 1;
  909.           strcpy(fstrings[funcindex], ted_tmp->te_ptext);
  910.           fstrings[funcindex][i] = ted_tmp->te_ptext[i];
  911.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  912.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  913.           break;
  914.         }
  915.         objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 1);
  916.       }
  917.       if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  918.       form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  919.       objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  920.       break;
  921.  
  922.     case MFREE:
  923.       memory();
  924.       break;
  925.  
  926.     case MFAST:
  927.       menu_icheck(menubar, MFAST, fast);
  928.       fast = !fast;
  929.       break;
  930.  
  931.     case OVERSTRI:
  932.       overstrike = !overstrike;
  933.       menu_icheck(menubar, OVERSTRI, overstrike);
  934.       break;
  935.  
  936.     case FNTSYS:
  937.     case FNTOWN:
  938.     case FNTALT:
  939.     case FNTBIG:
  940.     case FNTTINY:
  941.     case FNTUNKNW:
  942.     /* Add new font menu items here! */
  943.       for (cnt = 0; fontmenuobj[cnt] != 0; cnt++)
  944.       {
  945.         if (fontmenuobj[cnt] != msgbuff[4])
  946.         {
  947.           if (cnt < fontsavail)
  948.             objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0,
  949.           NONE, 0);
  950.           else
  951.             objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0,
  952.           DISABLED, 0);
  953.         }
  954.         else
  955.           curfont = fnttbl[cnt];
  956.       }
  957.       objc_change(menubar, msgbuff[4], 0, 0, 0, 0, 0, CHECKED, 0);
  958.       break;
  959.  
  960.     case PRTBOTOM:
  961.       if (outwind)
  962.       {
  963.         w[outwind].ptr_status = LOG_BOTOM;
  964.         printer_mark(outwind);
  965.         w_rename(outwind, NULL);
  966.       }
  967.       break;
  968.  
  969.     case PRTTOP:
  970.       if (outwind)
  971.       {
  972.         w[outwind].ptr_status = LOG_TOP;
  973.         printer_mark(outwind);
  974.         w_rename(outwind, NULL);
  975.       }
  976.       break;
  977.  
  978.     case PRTWIND:
  979.       if (outwind)
  980.       {
  981.         printer_mark(outwind);
  982.         dump_window(outwind);
  983.       }
  984.       break;
  985.  
  986.     case PRTSTOP:
  987.       if (outwind)
  988.       {
  989.         w[outwind].ptr_status = LOG_NONE;
  990.         printer_mark(outwind);
  991.         w_rename(outwind, NULL);
  992.       }
  993.       break;
  994.  
  995.     case INPUTWIN:
  996.     case PASTE:
  997.       sel_inp_mode = msgbuff[4];
  998.       graf_mouse(USER_DEF, rmbmform);
  999.       break;
  1000.  
  1001.     case RESETAUX:
  1002.       if (rs232_reset())
  1003.         Cauxout(0x11);    /* send XOFF    */
  1004.       break;
  1005.  
  1006.     case ASSRD:        /* Assert RTS/DTR. */
  1007.         Offgibit(~0x18);
  1008.         break;
  1009.  
  1010.     case RESRD:        /* Reset RTS/DTR. */
  1011.         Ongibit(0x18);
  1012.         break;
  1013.  
  1014.     case AUDIBELL:
  1015.       audibell = !audibell;
  1016.       objc_change(menubar, AUDIBELL, 0, 0, 0, 0, 0,
  1017.         audibell? CHECKED: 0, 0);
  1018.       break;
  1019.  
  1020.     case VISIBELL:
  1021.       visibell = !visibell;
  1022.       objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0,
  1023.         visibell? CHECKED: 0, 0);
  1024.       break;
  1025.  
  1026.     case TOPONBEL:
  1027.       toponbel = !toponbel;
  1028.       objc_change(menubar, TOPONBEL, 0, 0, 0, 0, 0,
  1029.         toponbel? CHECKED: 0, 0);
  1030.       break;
  1031.       
  1032.     case SHRNKWIN:    /* Shrink window to iconic size */
  1033.       if (outwind)
  1034.       {
  1035.         outwind = w_shrink(outwind);
  1036.         outport = find_port(outwind);
  1037.       }
  1038.       break;
  1039.  
  1040.     case BOTTOMTO:    /* send bottom window to top */
  1041.       w_bottom();
  1042.       break;
  1043.  
  1044.     case WINSTYLE:    /* enable/disable sliders and arrows for new windows */
  1045.       sliders = !sliders;
  1046.       menu_icheck(menubar, WINSTYLE, sliders);
  1047.       break;
  1048.  
  1049.     case HIDEWIN:    /* send top window to bottom */
  1050.       if (outwind = w_hide())
  1051.       {
  1052.         outport = find_port(outwind);
  1053.         printer_mark(outwind);
  1054.       }
  1055.       break;
  1056.  
  1057.     case MOVEWIN:
  1058.       if (outwind)
  1059.       {
  1060.         graf_mouse(POINT_HAND, &dummy);
  1061.         evnt_button(1, 1, 1, &mx, &my, &dummy, &dummy);
  1062.         wind_get(outwind, WF_CURRXYWH, &dummy, &dummy, &ww, &wh);
  1063.         if (graf_dragbox(ww, wh, mx, my,
  1064.           scr_x, scr_y, scr_w + ww, scr_h + wh, &mx, &my))
  1065.             w_move(outwind, mx, my, ww, wh);
  1066.         graf_mouse(sel_inp_mode? USER_DEF: ARROW, rmbmform);
  1067.       }
  1068.       break;
  1069.  
  1070.     case OSIZEWIN:
  1071.       if (outwind)
  1072.       {
  1073.         outwind = w_full(outwind);
  1074.         outport = find_port(outwind);
  1075.       }
  1076.       break;
  1077.  
  1078.     case CLOSEWIN:
  1079.       if (outwind = proto_close(outwind))
  1080.       {
  1081.         printer_mark(outwind);
  1082.         outport = find_port(outwind);
  1083.       }
  1084.       if (!uw_runs && !find_wind(1))
  1085.       {
  1086.         menu_tnormal(menubar, msgbuff[3], 1);
  1087.         goto init;
  1088.       }
  1089.       break;
  1090.  
  1091.     case WINTITLE:    /* enable/disable window headers */
  1092.       titles = !titles;
  1093.       menu_icheck(menubar, WINTITLE, titles);
  1094.       break;
  1095.  
  1096.     case SETCONF:    /* set rs232 port configuration */
  1097.       getrsconf();
  1098.       if (s_dial(RSCONF, 3) == RCOK)
  1099.         setrsconf();
  1100.       break;
  1101.  
  1102.     case WINCLEAR:    /* clear current window */
  1103.       if (outwind)
  1104.       {
  1105.         w[outwind].ptr_status = LOG_NONE;
  1106.         w_output(outwind, "\032");
  1107.       }
  1108.       break;
  1109.     }
  1110.     menu_tnormal(menubar, msgbuff[3], 1);
  1111.     break;
  1112.  
  1113.       case WM_NEWTOP:
  1114.       case WM_TOPPED:
  1115.     if (!locked)
  1116.       w_top(msgbuff[3]);
  1117.     break;
  1118.  
  1119.       case WM_SIZED:
  1120.       case WM_MOVED:
  1121.     if (!locked)
  1122.       w_move(msgbuff[3], msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1123.     break;
  1124.  
  1125.       case WM_CLOSED:
  1126.         if (locked) break;
  1127.     if (cnt = proto_close(msgbuff[3]))
  1128.     {
  1129.       if (msgbuff[3] == outwind)    /* was keyboard input window closed? */
  1130.         outwind = cnt;
  1131.       printer_mark(outwind);
  1132.       outport = find_port(outwind);
  1133.     }
  1134.     if (!uw_runs && !find_wind(1))
  1135.     {
  1136.       goto init;
  1137.     }
  1138.     break;
  1139.  
  1140.       case WM_REDRAW:
  1141.         if (highlighted_wdes == msgbuff[3])
  1142.     {    /* this window has highlighted text, redraw all of window*/
  1143.       register struct wi_str *wp = &w[msgbuff[3]];
  1144.       w_redraw(msgbuff[3], FM_COPY, wp->x, wp->y, wp->w, wp->h);
  1145.     }
  1146.     else
  1147.       /* redraw only damaged part */
  1148.       w_redraw(msgbuff[3], FM_COPY, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1149.     break;
  1150.  
  1151.       case WM_FULLED:
  1152.     if (locked) break;
  1153.     outwind = w_full(msgbuff[3]);
  1154.     outport = find_port(outwind);
  1155.     break;
  1156.  
  1157.       case WM_ARROWED:
  1158.     if (!locked)
  1159.       w_arrow(msgbuff[3], msgbuff[4]);
  1160.     break;
  1161.  
  1162.       case WM_HSLID:
  1163.       case WM_VSLID:
  1164.     if (!locked)
  1165.       w_slide(msgbuff[3], msgbuff[0] == WM_HSLID, msgbuff[4]);
  1166.     break;
  1167.       }
  1168.     }
  1169.     if ((event & MU_BUTTON) && ! locked)
  1170.     {
  1171.       if (sel_inp_mode && buttonstate) /* select input mode and button down */
  1172.       {
  1173.         int found;
  1174.  
  1175.     graf_mouse(ARROW, &dummy);
  1176.     if ((found = wind_find(mx, my)) != 0) {
  1177.       outwind = found;
  1178.       outport = find_port(outwind);
  1179.       if (sel_inp_mode == PASTE)
  1180.           proto_out(outport, pastebuff, (int)strlen(pastebuff));
  1181.     }
  1182.     evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1183.     buttonstate = 0;
  1184.     sel_inp_mode = FALSE;
  1185.       }
  1186.       else if (my < scr_y)    /* is mouse on menu bar? */
  1187.       {    /* yes, disable menu bar if button down */
  1188.         if (buttonstate)
  1189.     {
  1190.           objc_change(menubar, DESK, 0, 0, 0, 0, 0,
  1191.             menonoff? DISABLED: NORMAL, menonoff);
  1192.           menu_bar(menubar, menonoff = !menonoff);
  1193.       if (menonoff)
  1194.         graf_mouse(ARROW, &dummy);
  1195.       else
  1196.         graf_mouse(USER_DEF, rmbmform);
  1197.       evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1198.       buttonstate = 0;
  1199.     }
  1200.       }
  1201.       else    /* button click in work area */
  1202.       {    /* handle text selection or output or mouse packet */
  1203.         int found, found1, x1, y1, x2, y2, w_x, w_y, w_w, w_h;
  1204.  
  1205.     if ((found = wind_find(mx, my)) != 0)
  1206.     {
  1207.       wind_get(found, WF_WORKXYWH, &w_x, &w_y, &w_w, &w_h);
  1208.       if (mx >= w_x && mx < w_x + w_w && my >= w_y && my <w_y + w_h)
  1209.       { /* in window, fill paste buffer */
  1210.         if (clicks > 1 && buttonstate)
  1211.         {
  1212.           y1 = (my - w_y - Y0) / w[found].font->inc_y;
  1213.           copy_text(found, 0, y1, w[found].x_chrs - 1, y1, pastebuff);
  1214.           evnt_button(3, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1215.           regionflag = 0;
  1216.         }
  1217.         else if (buttonstate)    /* if button down */
  1218.         {
  1219.           x1 = (mx - w_x - X0) / w[found].font->inc_x;
  1220.           y1 = (my - w_y - Y0) / w[found].font->inc_y;
  1221.           regionflag = 1;
  1222.           found1 = found;
  1223.         }
  1224.         else if (regionflag && found == found1)
  1225.         {    /* button up */
  1226.           x2 = (mx - w_x - X0) / w[found].font->inc_x;
  1227.           y2 = (my - w_y - Y0) / w[found].font->inc_y;
  1228.           if (y2 == y1 && x2 == x1)
  1229.           {     /* simple click on char; select word */
  1230.             copy_word(found, x1, y1, pastebuff);
  1231.           }
  1232.           else if (y2 > y1 || (y2 == y1 && x2 > x1))
  1233.             copy_text(found, x1, y1, x2-1, y2, pastebuff);
  1234.           else
  1235.         copy_text(found, x2+1, y2, x1, y1, pastebuff);
  1236.         }
  1237.       }
  1238.       else
  1239.       { /* in border */
  1240.         /* send paste buffer and select keyboard window*/
  1241.         if (buttonstate)    /* if button down */
  1242.         {
  1243.           char * pptr = pastebuff;
  1244.           outwind = found;
  1245.           outport = find_port(outwind);
  1246.           if (clicks > 1)
  1247.               proto_out(outport, pptr, (int)strlen(pptr));
  1248.         }
  1249.         regionflag = 0;
  1250.       }
  1251.     }
  1252.     else
  1253.     {    /* not in window or border */
  1254.         /* clear paste buffer and erase any current marks */
  1255.       pastebuff[0] = '\0';
  1256.       regionflag = 0;
  1257.       copy_text(1, 1, 1, 0, 0, pastebuff);
  1258.     }
  1259.       }
  1260.       buttonstate = buttonstate? 0: 2;    /* toggle buttonstate */
  1261.     }
  1262.     if (event & MU_M1)    /* mouse moved into or out of work area */
  1263.     {
  1264.       if (!sel_inp_mode && !menonoff && !locked)
  1265.     graf_mouse(m1inout? USER_DEF: ARROW, rmbmform);
  1266.       m1inout = ! m1inout;
  1267.     }
  1268.   }
  1269. }
  1270. /*
  1271.  * printer_mark(wnd) places check marks in the apropriate places in the
  1272.  * printer menu.
  1273.  */
  1274. printer_mark (wnd)
  1275. {
  1276.     objc_change(menubar, PRTBOTOM, 0, 0, 0, 0, 0,
  1277.       (w[wnd].ptr_status & LOG_BOTOM)? CHECKED: NONE, 0);
  1278.  
  1279.     objc_change(menubar, PRTTOP, 0, 0, 0, 0, 0,
  1280.       (w[wnd].ptr_status & LOG_TOP)? CHECKED: NONE, 0);
  1281. }
  1282.  
  1283. /*
  1284.  * s_dial performs a simple dialog with buttons and text only.
  1285.  * The index of the terminating button is returned.
  1286.  * If action == 1, the dialog is displayed.  If action == 2, it is
  1287.  * removed.  If action == 3, both operations are done and form_do is
  1288.  * called.
  1289.  */
  1290. int s_dial(tree, action)
  1291. int tree, action;
  1292. {
  1293.   int tmp = 0;
  1294.   int cx, cy, cw, ch;
  1295.   OBJECT *obj_tmp;
  1296.  
  1297.   rsrc_gaddr(R_TREE, tree, &obj_tmp);
  1298.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1299.   if (action & 1) {
  1300.     form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1301.     if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1302.     objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1303.   }
  1304.   if (action == 3) {
  1305.     tmp = form_do(obj_tmp, 0);
  1306.   }
  1307.   if (action & 2) {
  1308.     if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1309.     form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1310.     objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1311.   }
  1312.     return (tmp);
  1313. }
  1314.  
  1315. /*
  1316.  * set_menu_string sets the menu string for the specified menu object to
  1317.  * newstr.
  1318.  */
  1319. set_menu_string(newstr, object)
  1320. register char * newstr;
  1321. int object;
  1322. {
  1323.   register char * oldstr;
  1324.  
  1325.   oldstr = (char *) menubar[object].ob_spec + 2;
  1326.   while (*oldstr && *newstr)
  1327.     *oldstr++ = *newstr++;
  1328.   if (*oldstr)
  1329.       *oldstr = ' ';
  1330. }
  1331.  
  1332. size_dial()
  1333. {
  1334.   /*
  1335.    * Enter rows and columns dialog
  1336.    */
  1337.   int cx, cy, cw, ch;
  1338.   char *rowstr, *colstr;
  1339.   rsrc_gaddr(R_TREE, WINDSIZE, &obj_tmp);
  1340.   ted_tmp = (TEDINFO *) obj_tmp[WINDROWS].ob_spec;
  1341.   rowstr = ((char *)ted_tmp->te_ptext);
  1342.   if (atoi(rowstr) < 2)
  1343.     strcpy (rowstr, "24");
  1344.   ted_tmp = (TEDINFO *) obj_tmp[WINDCOLS].ob_spec;
  1345.   colstr = ((char *)ted_tmp->te_ptext);
  1346.   if (atoi(colstr) < 2)
  1347.     strcpy (colstr, "80");
  1348.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1349.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1350.   if (!fast)
  1351.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1352.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1353.   tmp = form_do(obj_tmp, WINDROWS);
  1354.   if (!fast)
  1355.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1356.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1357.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1358.   if (tmp == WINDCANC)
  1359.     return(FALSE);
  1360.   xsiz = atoi(colstr);
  1361.   ysiz = atoi(rowstr);
  1362.   if (xsiz < 2)
  1363.     xsiz = 2;
  1364.   if (xsiz > 300)
  1365.     xsiz = 300;
  1366.   if (ysiz < 2)
  1367.     ysiz = 2;
  1368.   if (ysiz > 300)
  1369.     ysiz = 300;
  1370.   return (TRUE);
  1371. }
  1372.