home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / mg2a / part15 < prev    next >
Encoding:
Text File  |  1989-02-03  |  43.5 KB  |  1,808 lines

  1. Path: xanth!mcnc!ncsuvx!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ames!necntc!ncoast!allbery
  2. From: BLARSON@ECLA.USC.EDU (Bob Larson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i039: mg 2a part 15 of 15
  5. Message-ID: <12401571940.21.BLARSON@ECLA.USC.EDU>
  6. Date: 27 May 88 05:49:18 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
  9. Lines: 1795
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. comp.sources.misc: Volume 3, Issue 39
  13. Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
  14. Archive-Name: mg2a/Part15
  15.  
  16. #    This is a shell archive.
  17. #    Remove everything above and including the cut line.
  18. #    Then run the rest of the file through sh.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar:    Shell Archiver
  22. #    Run the following text with /bin/sh to create:
  23. #    sys/vms/ttyio.c
  24. #    sys/vms/mgmailedit.com
  25. #    sys/atari/maketop.mwc
  26. #    sys/atari/chrdef.h
  27. #    sys/amiga/ttykbd.c
  28. #    sys/amiga/ttymenu.c
  29. #    sys/amiga/ttymouse.c
  30. #    sys/amiga/varargs.h
  31. #    sys/amiga/iconify/iconify.c
  32. #    sys/amiga/iconify/iconify.h
  33. # This archive created: Mon May 23 18:14:27 1988
  34. # By:    blarson
  35. if test -d sys
  36. then true
  37. else mkdir sys
  38. fi
  39. if test -d sys/atari
  40. then true
  41. else mkdir sys/atari
  42. fi
  43. if test -d sys/vms
  44. then true
  45. else mdkir sys/vms
  46. fi
  47. if test -d sys/amiga
  48. then true
  49. else mkdir sys/amiga
  50. fi
  51. cat << \SHAR_EOF > sys/vms/ttyio.c
  52. /*
  53.  * Name:    MicroGnuEmacs
  54.  *        VAX/VMS terminal I/O.
  55.  *        o 16-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  56.  *          Turn off TTSYNC so ^S and ^Q are sent to program.
  57.  *          To get this back, compile with -DFLOWCONTROL
  58.  *        o 10-Jul-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  59.  *          Add setttysize(), typeahead() and panic() for Gnu v30
  60.  *        o 21-Jul-87 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  61.  *          Use transmit speed from iosb instead of receive, which
  62.  *          is only valid if different from the transmit speed...
  63.  */
  64. #include    "def.h"
  65.  
  66. #include    <stsdef.h>
  67. #include    <ssdef.h>
  68. #include    <descrip.h>
  69. #include    <iodef.h>
  70. #include    <ttdef.h>
  71. #include    <tt2def.h>
  72.  
  73. #define    NIBUF    128            /* Probably excessive.        */
  74. #define    NOBUF    512            /* Not too big for 750/730.    */
  75. #define    EFN    0            /* Event flag            */
  76.  
  77. char    obuf[NOBUF];            /* Output buffer        */
  78. int    nobuf;                /* # of bytes in above        */
  79. char    ibuf[NIBUF];            /* Input buffer            */
  80. int    nibuf;                /* # of bytes in above        */
  81. int    ibufi;                /* Read index            */
  82. int    oldmode[3];            /* Old TTY mode bits        */
  83. int    newmode[3];            /* New TTY mode bits        */
  84. short    iochan;                /* TTY I/O channel        */
  85. int    nrow;                /* Terminal size, rows.        */
  86. int    ncol;                /* Terminal size, columns.    */
  87. short    ospeed;                /* Terminal output speed    */
  88.                     /* for termcap library        */
  89.  
  90. /*
  91.  * This routines gets called once, to set up the
  92.  * terminal channel.
  93.  * On VMS we find the translation of the SYS$COMMAND:
  94.  * logical name, assign a channel to it, and set it raw.
  95.  */
  96.  
  97. ttopen()
  98. {
  99.     struct    dsc$descriptor    idsc;
  100.     struct    dsc$descriptor    odsc;
  101.     char    oname[40];
  102.     int    iosb[2];
  103.     int    status;
  104.  
  105.     odsc.dsc$a_pointer = "SYS$COMMAND";
  106.     odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  107.     odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  108.     odsc.dsc$b_class   = DSC$K_CLASS_S;
  109.     idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  110.     idsc.dsc$b_class   = DSC$K_CLASS_S;
  111.     do {
  112.         idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  113.         idsc.dsc$w_length  = odsc.dsc$w_length;
  114.         odsc.dsc$a_pointer = &oname[0];
  115.         odsc.dsc$w_length  = sizeof(oname);
  116.         status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  117.         if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  118.             exit(status);
  119.         if (oname[0] == 0x1B) {
  120.             odsc.dsc$a_pointer += 4;
  121.             odsc.dsc$w_length  -= 4;
  122.         }
  123.     } while (status == SS$_NORMAL);
  124.     status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  125.     if (status != SS$_NORMAL)
  126.         exit(status);
  127.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  128.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  129.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  130.         exit(status);
  131.  
  132.     nrow = (oldmode[1]>>24) & 0xFF;        /* Terminal length.    */
  133.     if (nrow > NROW)
  134.         nrow = NROW;
  135.     ncol = (oldmode[0]>>16) & 0xFFFF;    /* Width.        */
  136.     if (ncol > NCOL)
  137.         ncol = NCOL;
  138.     ospeed = (iosb[0]>>16) & 0xFF;        /* Speed (for termcap)    */
  139.     newmode[0] = oldmode[0];        /* Only in version 4.    */
  140. #ifdef    FLOWCONTROL
  141.     newmode[1] = oldmode[1] | TT$M_NOECHO | TT$M_TTSYNC;
  142. #else
  143.     newmode[1] = (oldmode[1] | TT$M_NOECHO) & ~TT$M_TTSYNC;
  144. #endif
  145.     newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  146.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  147.               newmode, sizeof(newmode), 0, 0, 0, 0);
  148.  
  149.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  150.         exit(status);
  151. }
  152.  
  153. /*
  154.  * This function gets called just
  155.  * before we go back home to the command interpreter.
  156.  * On VMS it puts the terminal back in a reasonable state.
  157.  */
  158. ttclose()
  159. {
  160.     int    status;
  161.     int    iosb[2];
  162.  
  163.     ttflush();
  164.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  165.              oldmode, sizeof(oldmode), 0, 0, 0, 0);
  166.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  167.         exit(status);
  168.     status = SYS$DASSGN(iochan);
  169.     if (status != SS$_NORMAL)
  170.         exit(status);
  171. }
  172.  
  173. /*
  174.  * Write a character to the display.
  175.  * On VMS, terminal output is buffered, and
  176.  * we just put the characters in the big array,
  177.  * after checking for overflow.
  178.  */
  179. ttputc(c)
  180. {
  181.     if (nobuf >= NOBUF)
  182.         ttflush();
  183.     obuf[nobuf++] = c;
  184. }
  185.  
  186. /*
  187.  * This function does the real work of
  188.  * flushing out buffered I/O on VMS. All
  189.  * we do is blast out the block with a write call. No status
  190.  * checking is done on the write, because there isn't anything
  191.  * clever that can be done, and because you will see the
  192.  * error as a messed up screen.
  193.  */
  194. ttflush()
  195. {
  196.     int    iosb[2];
  197.  
  198.     if (nobuf != 0) {
  199.         SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  200.         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  201.         nobuf = 0;
  202.     }
  203. }
  204.  
  205. /*
  206.  * Read a character from the terminal,
  207.  * performing no editing and doing no echo at all.
  208.  * More complex in VMS that almost anyplace else,
  209.  * which figures.
  210.  */
  211. ttgetc()
  212. {
  213.     int    status;
  214.     int    iosb[2];
  215.     int    term[2];
  216.  
  217.     term[0] = 0;
  218.     term[1] = 0;
  219.     while (ibufi >= nibuf) {
  220.         ibufi   = 0;
  221.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  222.              iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  223.         if (status != SS$_NORMAL)
  224.             continue;
  225.         status = iosb[0] & 0xFFFF;
  226.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  227.             continue;
  228.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  229.         if (nibuf == 0) {
  230.             status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  231.                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  232.             if (status != SS$_NORMAL)
  233.                 continue;
  234.             if ((iosb[0]&0xFFFF) != SS$_NORMAL)
  235.                 continue;
  236.             nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  237.         }
  238.     }
  239.     return (ibuf[ibufi++] & 0xFF);
  240. }
  241.  
  242. /*
  243.  * Internal check for new terminal size.
  244.  * Do this *before* setting terminal modes, so
  245.  * the size changes are kept when.
  246.  */
  247. ckttysize()
  248. {
  249.     int status, mode[3], iosb[2], wid, len;
  250.  
  251.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  252.               mode, sizeof(mode), 0, 0, 0, 0);
  253.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  254.         panic("ckttsize: can't sense terminal modes!");
  255.  
  256.     /* save new page length */
  257.     len = (mode[1] >> 24) & 0xFF;
  258.     oldmode[1] = (oldmode[1] & 0x00FFFFFF) | (len << 24);
  259.     newmode[1] = (newmode[1] & 0x00FFFFFF) | (len << 24);
  260.  
  261.     /* save new page width */
  262.     wid = (mode[0] >> 16) & 0xFF;
  263.     oldmode[0] = (oldmode[0] & 0x0000FFFF) | (wid << 16);
  264.     newmode[0] = (newmode[0] & 0x0000FFFF) | (wid << 16);
  265. }
  266.  
  267. /*
  268.  * Tell Emacs how big the terminal is now,
  269.  * making sure the page size is in the range
  270.  * 1..NROW.
  271.  */
  272.  
  273. setttysize()
  274. {
  275.     nrow = (newmode[1]>>24) & 0xFF;        /* Length.        */
  276.     if (nrow > NROW)
  277.         nrow = NROW;
  278.  
  279.     ncol = (newmode[0]>>16) & 0xFFFF;    /* Width.        */
  280.     if (ncol > NCOL)
  281.         ncol = NCOL;
  282. }
  283.  
  284. /*
  285.  * Return the number of characters in the
  286.  * typeahead buffer.
  287.  */
  288.  
  289. typeahead()
  290. {
  291.     int    status, SYS$QIOW(), iosb[2], mode[2];
  292.  
  293.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE|IO$M_TYPEAHDCNT,
  294.             iosb, 0, 0, mode, sizeof(mode), 0, 0, 0, 0);
  295.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  296.         exit(status);
  297.     return (mode[0] & 0xFFFF);    /* # characters in typeahead buf */
  298. }
  299.  
  300. #ifndef    NO_DPROMPT
  301. /*
  302.  * Attempt to read for one character.  Return TRUE if the
  303.  * read times out after 2 seconds, return immediately with
  304.  * FALSE if the user enters something.
  305.  */
  306. ttwait()
  307. {
  308.     int    status;
  309.     int    iosb[2];
  310.     int    term[2];
  311.  
  312.     term[0] = 0;                /* no termination char for read */
  313.     term[1] = 0;
  314.     while (ibufi >= nibuf) {    /* anything in the buffer?    */
  315.         ibufi   = 0;        /* nope, read 1 char w/timeout    */
  316.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  317.              iosb, 0, 0, ibuf, 1, 2, term, 0, 0);
  318.         if (status != SS$_NORMAL)
  319.             continue;        /* did read succeed ?         */
  320.         status = iosb[0] & 0xFFFF;    /* yes, get secondary status */
  321.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  322.             continue;        /* try again if bad         */
  323.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);/* store # chars read  */
  324.         if (status == SS$_TIMEOUT)
  325.             return (TRUE);        /* the read timed out         */
  326.     }
  327.     return (FALSE);                /* read did not time out     */
  328. }
  329. #endif
  330.  
  331. /*
  332.  * Just exit, as quickly as we can.
  333.  */
  334.  
  335. panic(s)
  336. char *s;
  337. {
  338.     fprintf(stderr,"panic: %s\n\n", s);
  339.     ttclose();        /* set the terminal back to sane state... */
  340.     exit(SS$_ABORT);    /* go away! */
  341. }
  342. SHAR_EOF
  343. cat << \SHAR_EOF > sys/vms/mgmailedit.com
  344. $    Verify = 'F$Verify(0)
  345. $ ! Command procedure to invoke MG from MAIL.  You should
  346. $ ! have the symbol MG globally defined, either as
  347. $ !
  348. $ !    MG :== $dev:[dir]MG
  349. $ !
  350. $ ! Then
  351. $ !    DEFINE MAIL$EDIT dev:[dir]MGMAILEDIT.COM
  352. $ !
  353. $ ! to make MAIL look for this file.
  354. $ !
  355. $ ! or, if using the kept-fork capability,
  356. $ !
  357. $ !    MG :== @dev:[dir]MG.COM
  358. $ !
  359. $ ! Inputs:
  360. $ !
  361. $ !    P1 = Input file name.
  362. $ !    P2 = Output file name.
  363. $ !
  364. $ ! The default directory is the same as the parent process.
  365. $ !
  366. $ ! Copy the input file to the output file, then invoke MG on it.
  367. $ !
  368. $ Set Noon
  369. $ Define/Job MG$AttachTo "''F$Process()'"
  370. $ If P2 .Nes. "" .AND. P1 .Nes. "" Then Copy 'P1' 'P2'
  371. $ Define/User Sys$Input Sys$Command
  372. $ MG 'P2'
  373. $ If F$Trnlnm("MG$AttachTo") .Nes. "" Then - ! MG.COM might have done it already
  374.     Deassign/Job MG$AttachTo
  375. $ If Verify Then -
  376.     Set Verify
  377. SHAR_EOF
  378. cat << \SHAR_EOF > sys/atari/maketop.mwc
  379. #
  380. # MWC Makefile for MG (Atari ST)
  381. #
  382. #    Marion Hakanson        Jan '88
  383. #
  384. # Copy this file to "makefile" in the top level MG directory,
  385. # and make sure the atari stuff is in SYSDIR below.  Then just
  386. # run "make" in the top level directory.
  387.  
  388. # Warning:  This makefile depends on having $(POUND) set to '#',
  389. # either on the make command line or in the shell environment.
  390. # Note that $(POUND) is a hack to get around the fact that
  391. # there is no way to put a literal "#" in a MWC make action.
  392. # I just put "setenv POUND '#'" in my PROFILE.
  393.  
  394. SYSLIB    = libsys.a
  395. SYSDIR  = sys\atari
  396. LIBS    = $(SYSDIR)\$(SYSLIB)
  397.  
  398. # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags,
  399. # and doesn't get passed to lint.
  400.  
  401. CDEFS    = 
  402. CFLAGS    = -O -DMWC $(CDEFS)
  403.  
  404. # Objects which only depend on the "standard" includes
  405. OBJS    = basic.o dir.o dired.o file.o line.o paragraph.o \
  406.       random.o region.o version.o window.o word.o
  407.  
  408. # Those with unique requirements
  409. IND    = buffer.o display.o echo.o extend.o help.o kbd.o keymap.o \
  410.       macro.o main.o match.o modes.o regex.o re_search.o search.o
  411.  
  412. OBJ = $(OBJS) $(IND)
  413.  
  414. SRCS    = basic.c dir.c dired.c file.c line.c match.c paragraph.c \
  415.       random.c region.c search.c version.c window.c word.c \
  416.       buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \
  417.       macro.c main.c modes.c regex.c re_search.c
  418.  
  419. OINCS =    ttydef.h sysdef.h chrdef.h
  420. INCS =    def.h
  421.  
  422. all:
  423.     cd $(SYSDIR); make -f makesys.mwc \
  424.         "SYSLIB=$(SYSLIB)" "CFLAGS=$(CFLAGS)" $@
  425.     make xmg.ttp
  426.  
  427. xmg.ttp:    $(OBJ) $(SYSDIR)\$(SYSLIB)
  428.     $(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS)
  429.  
  430. # strip mg once you're satisfied it'll run -- makes it much smaller
  431. strip:
  432.     strip xmg.ttp
  433.  
  434.  
  435. $(OBJS):    $(INCS) $(OINCS)
  436.  
  437. regex.o re_search.o:    $(INCS) $(OINCS) regex.h
  438.  
  439. extend.o help.o kbd.o:    $(INCS) $(OINCS) macro.h kbd.h key.h
  440.  
  441. main.o re_search.o search.o:    $(INCS) $(OINCS) macro.h
  442.  
  443. match.o:    $(INCS) $(OINCS) key.h
  444.  
  445. buffer.o display.o keymap.o modes.o:    $(INCS) $(OINCS) kbd.h
  446.  
  447. echo.o macro.o:    $(INCS) $(OINCS) key.h macro.h
  448.  
  449. echo.o:    varargs.h
  450.  
  451.  
  452. sysdef.h: $(SYSDIR)\sysdef.h
  453.     echo '$(POUND)include "$(SYSDIR)\sysdef.h"' > $@
  454.  
  455. ttydef.h: $(SYSDIR)\ttydef.h
  456.     echo '$(POUND)include "$(SYSDIR)\ttydef.h"' > $@
  457.  
  458. chrdef.h: $(SYSDIR)\chrdef.h
  459.     echo '$(POUND)include "$(SYSDIR)\chrdef.h"' > $@
  460.  
  461. varargs.h: $(SYSDIR)\varargs.h
  462.     echo '$(POUND)include "$(SYSDIR)\varargs.h"' > $@
  463.  
  464.  
  465. clean:
  466.     cd $(SYSDIR); make -f makesys.mwc \
  467.         "SYSLIB=$(SYSLIB)" "CFLAGS=$(CFLAGS)" $@
  468.     -rm $(OBJ) $(OINCS) varargs.h xmg.ttp
  469.  
  470. SHAR_EOF
  471. cat << \SHAR_EOF > sys/atari/chrdef.h
  472. /* chrdef.h -- sample character attribute macros
  473.  *
  474.  * author :  Sandra Loosemore
  475.  * date   :  26 Oct 1987
  476.  *
  477.  * This file works for the Atari ST 8-bit character set.  It probably
  478.  *    won't work for other character encodings.
  479.  *
  480.  */
  481.  
  482.  
  483. #define _W    0x01            /* Word.            */
  484. #define _U    0x02            /* Upper case letter.        */
  485. #define _L    0x04            /* Lower case letter.        */
  486. #define _C    0x08            /* Control.            */
  487. #define _P    0x10            /* end of sentence punctuation    */
  488.  
  489. #define ISWORD(c)    ((cinfo[(c)]&_W)!=0)
  490. #define ISCTRL(c)    ((cinfo[(c)]&_C)!=0)
  491. #define ISUPPER(c)    ((cinfo[(c)]&_U)!=0)
  492. #define ISLOWER(c)    ((cinfo[(c)]&_L)!=0)
  493. #define ISEOSP(c)    ((cinfo[(c)]&_P)!=0)
  494. #define TOUPPER(c)    (cupper[(c)])
  495. #define TOLOWER(c)    (clower[(c)])
  496. #define ISDIGIT(c)    (((c) >= '0') && ((c) <= '9'))
  497.  
  498. extern char cupper[];
  499. extern char clower[];
  500. extern char cinfo[];
  501.  
  502.  
  503. /*
  504.  * generally useful thing for chars
  505.  */
  506. #define CCHR(x)        ((x) ^ 0x40)    /* CCHR('?') == DEL */
  507. #define CHARMASK(c)    ((c)&0xff)
  508. SHAR_EOF
  509. cat << \SHAR_EOF > sys/amiga/ttykbd.c
  510. /*
  511.  * Name:    MG 2a
  512.  *         Amiga virtual terminal keyboard, default console keymap.
  513.  * Created:    Mic Kaczmarczik (mic@emx.cc.utexas.edu)
  514.  * Last edit:    May 14, 1988
  515.  */
  516.  
  517. #undef    TRUE
  518. #undef    FALSE
  519. #include    "def.h"
  520. #include    "kbd.h"
  521.  
  522. /*
  523.  * List of function key names, from KFIRST to KLAST
  524.  */
  525. #ifdef    FKEYS
  526. char    *keystrings[] = {
  527.     "Up",        "Down",        "Left",        "Right",
  528.     "Shift-Up",    "Shift-Down",    "Shift-Left",    "Shift-Right",
  529.     "Help",        "The menu",    "The resize gadget", "The mouse",
  530.     "F1",        "F2",        "F3",        "F4",
  531.     "F5",        "F6",        "F7",        "F8",
  532.     "F9",        "F10",        "Shift-F1",    "Shift-F2",
  533.     "Shift-F3",    "Shift-F4",    "Shift-F5",    "Shift-F6",
  534.     "Shift-F7",    "Shift-F8",    "Shift-F9",    "Shift-F10",
  535.     "Mouse",            "Ctrl-Mouse",
  536.     "Shift-Mouse",            "Shift-Ctrl-Mouse",
  537.     "Meta-Mouse",            "Meta-Ctrl-Mouse",
  538.     "Meta-Shift-Mouse",        "Meta-Shift-Ctrl-Mouse",
  539.     "Mode-Mouse",            "Ctrl-Mode-Mouse",
  540.     "Shift-Mode-Mouse",        "Shift-Ctrl-Mode-Mouse",
  541.     "Meta-Mode-Mouse",        "Meta-Ctrl-Mode-Mouse",
  542.     "Meta-Shift-Mode-Mouse",    "Meta-Shift-Ctrl-Mode-Mouse",
  543.     "Echo-Mouse",            "Ctrl-Echo-Mouse",
  544.     "Shift-Echo-Mouse",        "Shift-Ctrl-Echo-Mouse",
  545.     "Meta-Echo-Mouse",        "Meta-Ctrl-Echo-Mouse",
  546.     "Meta-Shift-Echo-Mouse",    "Meta-Shift-Ctrl-Echo-Mouse"
  547. };
  548. #endif
  549.  
  550. /*
  551.  * Read in a key, doing whatever low-level mapping of ASCII code to
  552.  * 11 bit code.  This has become a bit easier since keymaps.
  553.  */
  554. #define    CSI    0x9b
  555.  
  556. getkbd()
  557. {
  558.     register int c;
  559. #ifdef    FKEYS
  560.     register int    n;
  561. #endif
  562. loop:
  563.     if ((c = ttgetc()) == CSI) {
  564.         c = ttgetc();
  565. #ifdef    FKEYS
  566.         if (c == '?') {            /* HELP key        */
  567.             ttgetc();        /* discard '~'        */
  568.             return (KHELP);
  569.         }
  570.         /* Arrow keys */
  571.         if (c == 'A')
  572.             return (KUP);
  573.         if (c == 'B')
  574.             return (KDOWN);
  575.         if (c == 'C')
  576.             return (KRIGHT);
  577.         if (c == 'D')
  578.             return (KLEFT);
  579.         if (c == 'T')
  580.             return (KSUP);
  581.         if (c == 'S')
  582.             return (KSDOWN);
  583.  
  584.         /* Shifted left, right arrow */
  585.         if (c == ' ') {
  586.             c = ttgetc();
  587.             if (c == 'A' || c == '@')
  588.                 return ((c == 'A') ? (KSLEFT) : (KSRIGHT));
  589.             goto loop;        /* try again, sucker */
  590.         }
  591.  
  592.         /* Function keys    */
  593.         if (c >= '0' && c <= '9') {
  594.             n = 0;
  595.             do {
  596.                 n = 10*n + c - '0';
  597.                 c = ttgetc();
  598.             } while (c>='0' && c<='9');
  599.             if (c == '~' && n < 20)
  600.                 return (n < 9) ? (KF1 + n) : (KSF1 + (n - 10));
  601.             else 
  602.                 goto loop;    /* Try again */
  603.         }
  604. #endif
  605.         goto loop;        /* Try again */
  606.     }
  607.     return (c);
  608. }
  609.  
  610. /*
  611.  * Terminal specific keymap initialization, calling bind() to get
  612.  * things done.  All the keys bound here are done globally.
  613.  */
  614.  
  615. VOID
  616. ttykeymapinit()
  617. {
  618. #ifdef    FKEYS
  619.     KCHAR        c;
  620.     register KEYMAP **mapp = &map_table[0].p_map;
  621. #endif
  622.     static KCHAR    esc_bs[] = { CCHR('['), CCHR('H') };
  623.     static KCHAR    esc_del[] = { CCHR('['), CCHR('?') };
  624.     
  625. #define    BINDC(k,s) (c = k, bindkey(mapp, s, &c, 1))
  626. #define    BINDM(m,s) bindkey(mapp, s, m, (sizeof(m)/sizeof(KCHAR)))
  627.     
  628.     /* Swap the backspace and del keys, at least in normal usage.
  629.      * This loses the help feature of CTRL-H, but we rebind
  630.      * CTRL-_ to do the same thing. Under FKEYS, the Help key
  631.      * calls describe-key-briefly.
  632.      */
  633.     BINDC(CCHR('_'),    "help-help");    /* CTRL-Backspace */
  634.     BINDM(esc_bs,        "backward-kill-word");
  635.     BINDC(CCHR('H'),    "delete-backward-char");
  636.  
  637.     BINDC(CCHR('?'),    "delete-char");
  638.     BINDM(esc_del,        "kill-word");
  639. }
  640.  
  641. SHAR_EOF
  642. cat << \SHAR_EOF > sys/amiga/ttymenu.c
  643. /*
  644.  * ttymenu.c
  645.  *
  646.  * Incorporates the browser, for rummaging around on disks,
  647.  * and the usual Emacs editing command menu
  648.  *
  649.  *    Copyright (c) 1986, Mike Meyer
  650.  *    Mic Kaczmarczik did a few things along the way.
  651.  *
  652.  * Permission is hereby granted to distribute this program, so long as
  653.  * this source file is distributed with it, and this copyright notice
  654.  * is not removed from the file.
  655.  *
  656.  */
  657.  
  658. #include <exec/types.h>
  659. #include <libraries/dos.h>
  660. #include <libraries/dosextens.h>
  661. #include <intuition/intuition.h>
  662. #undef    TRUE
  663. #undef    FALSE
  664. #include "def.h"
  665. #ifndef    NO_MACRO
  666. #include "macro.h"
  667. #endif    
  668.  
  669. extern struct Menu        *AutoMenu ;
  670. extern struct Window        *EmW ;
  671.  
  672. #ifdef    LATTICE
  673. static VOID    Add_Devices(ULONG) ;
  674. #else
  675. static VOID    Add_Devices() ;
  676. #endif
  677.  
  678. #define MNUM(menu,item,sub) (SHIFTMENU(menu)|SHIFTITEM(item)|SHIFTSUB(sub))
  679.  
  680. #ifdef    BROWSER
  681. #define LONGEST_NAME    80    /* Longest file name we can deal with    */
  682.  
  683. # ifdef    LATTICE
  684. char *strchr(char *, int);
  685. # else
  686. char *index();            /* find first instance of c in s    */
  687. #define    strchr(s, c) index(s, c)
  688. # endif
  689.  
  690. # ifdef    MENU
  691. #define    FIRSTMENU    1
  692. # else
  693. #define    FIRSTMENU    0
  694. # endif
  695.  
  696. #endif    BROWSER
  697.  
  698. #ifdef    MENU
  699. /*
  700.  * When ttgetc() sees a menu selection event, it stuffs the sequence
  701.  * KMENU <menu><item><subitem> into the input buffer
  702.  *
  703.  * The menu item names are chosen to be relatively close to the extended
  704.  * function names, so a user can usually figure out the key binding of
  705.  * a menu item by searching through the "display-bindings" buffer
  706.  * for something that's close.
  707.  */
  708.  
  709. /*
  710.  * Commands for managing files and buffers
  711.  */
  712.  
  713. extern    int    filevisit();
  714. extern    int    poptofile();
  715. extern    int    fileinsert();
  716. extern    int    filesave();
  717. extern    int    filewrite();
  718. #ifndef    NO_DIRED
  719. extern    int    dired();
  720. #endif
  721. extern    int    usebuffer();
  722. extern    int    poptobuffer();
  723. extern    int    killbuffer();
  724. extern    int    listbuffers();
  725. extern    int    savebuffers();
  726. extern    int    quit();
  727.  
  728. static struct MenuBinding FileItems[] = {
  729.     { "Find File         C-x C-f",    filevisit    },
  730.     { "Pop To File       C-x 4 f",    poptofile    },
  731.     { "Insert File       C-x i",    fileinsert    },
  732.     { "Save File         C-x C-s",    filesave    },
  733.     { "Write File        C-x C-w",    filewrite    },
  734. #ifndef    NO_DIRED
  735.     { "Dired         C-x d",    dired        },
  736. #endif
  737.     { "Switch To Buffer  C-x b",    usebuffer    },
  738.     { "Pop To Buffer     C-x 4 b",    poptobuffer    },
  739.     { "Kill Buffer       C-x k",    killbuffer    },
  740.     { "List Buffers      C-x C-b",    listbuffers    },
  741.     { "Save Buffers      C-x s",    savebuffers    },
  742.     { "Save And Exit     C-x C-c",    quit        }
  743. };
  744.  
  745. /*
  746.  * Commands for various editing functions
  747.  */
  748.  
  749. extern    int    yank();
  750. extern    int    openline();
  751. extern    int    killline();
  752. extern    int    deblank();
  753. extern    int    justone();
  754. extern    int    indent();
  755. extern    int    twiddle();
  756. extern    int    quote();
  757.  
  758. static struct MenuBinding EditItems[] = {
  759.     { "Yank                 C-y",    yank        },
  760.     { "Blank Line           C-o ",    openline    },
  761.     { "Kill Line            C-k",    killline    },
  762.     { "Delete Blank Lines   C-x C-o",deblank    },
  763.     { "Delete Blanks        M-SPC",    justone        },
  764.     { "Newline And Indent   C-j",    indent        },
  765.     { "Transpose Characters C-t",    twiddle        },
  766.     { "Quoted Insert        C-q",    quote        }
  767. };
  768.  
  769. /*
  770.  * Movement commands
  771.  */
  772.  
  773. extern    int    forwpage();
  774. extern    int    backpage();
  775. extern    int    gotobol();
  776. extern    int    gotobob();
  777. extern    int    gotoeol();
  778. extern    int    gotoeob();
  779. extern    int    gotoline();
  780. extern    int    showcpos();
  781.  
  782. static struct MenuBinding MoveItems[] = {
  783.     { "Scroll Up       C-v",    forwpage    },
  784.     { "Scroll Down     M-v",    backpage    },
  785.     { "Start Of Line   C-a",    gotobol        },
  786.     { "Start Of Buffer M-<",    gotobob        },
  787.     { "End Of Line     C-e",    gotoeol        },
  788.     { "End Of Buffer   M->",    gotoeob        },
  789.     { "Goto Line",            gotoline    },
  790.     { "Show Cursor     C-x =",    showcpos    }
  791. };
  792.  
  793. /*
  794.  * Commands for searching and replacing
  795.  */
  796.  
  797. extern    int    forwisearch();
  798. extern    int    backisearch();
  799. extern    int    searchagain();
  800. extern    int    forwsearch();
  801. extern    int    backsearch();
  802. extern    int    queryrepl();
  803.  
  804. static struct MenuBinding SearchItems[] = {
  805.     { "I-Search Forward  C-s",    forwisearch    },
  806.     { "I-Search Backward C-r",    backisearch    },
  807.     { "Search Again",        searchagain    },
  808.     { "Search Forward    M-s",    forwsearch    },
  809.     { "Search Backward   M-r",    backsearch    },
  810.     { "Query Replace     M-%",    queryrepl    }
  811. };
  812.  
  813. /*
  814.  * Commands that manipulate words
  815.  */
  816. extern    int    forwword();
  817. extern    int    backword();
  818. extern    int    delfword();
  819. extern    int    delbword ();
  820. extern    int    capword();
  821. extern    int    lowerword();
  822. extern    int    upperword();
  823.  
  824. static struct MenuBinding WordItems[] = {
  825.     { "Forward Word       M-f",    forwword    },
  826.     { "Backward Word      M-b",    backword    },
  827.     { "Kill Word          M-d",    delfword    },
  828.     { "Backward Kill Word M-DEL",    delbword     },
  829.     { "Capitalize Word    M-c",    capword        },
  830.     { "Downcase Word      M-l",    lowerword    },
  831.     { "Upcase Word        M-u",    upperword    }
  832. };
  833.  
  834. /*
  835.  * Commands relating to paragraphs
  836.  */
  837. extern    int    gotoeop();
  838. extern    int    gotobop();
  839. extern    int    fillpara();
  840. extern    int    setfillcol();
  841. extern    int    killpara();
  842. extern    int    fillmode();
  843.  
  844. static struct MenuBinding ParaItems[] = {
  845.     { "Forward Paragraph  M-]",    gotoeop        },
  846.     { "Backward Paragraph M-[",    gotobop        },
  847.     { "Fill Paragraph     M-q",    fillpara    },
  848.     { "Set Fill Column    C-x f",    setfillcol    },
  849.     { "Kill Paragraph",        killpara    },
  850.     { "Auto Fill Mode",        fillmode    }
  851. };
  852.  
  853. /*
  854.  * Region stuff
  855.  */
  856. extern    int    setmark();
  857. extern    int    swapmark();
  858. extern    int    killregion();
  859. extern    int    copyregion();
  860. extern    int    lowerregion();
  861. extern    int    upperregion();
  862.  
  863. static struct MenuBinding RegionItems[] = {
  864.     { "Set Mark            C-@",    setmark        },
  865.     { "Exch Point And Mark C-x C-x",swapmark    },
  866.     { "Kill Region         C-w",    killregion    },
  867.     { "Copy Region As Kill M-w",    copyregion    },
  868.     { "Downcase Region     C-x C-l",lowerregion    },
  869.     { "Upcase Region       C-x C-u",upperregion    }
  870. };
  871.  
  872. /*
  873.  * Commands for manipulating windows
  874.  */
  875.  
  876. extern    int    splitwind();
  877. extern    int    delwind();
  878. extern    int    onlywind();
  879. extern    int    nextwind();
  880. #ifdef    PREVWIND
  881. extern    int    prevwind();
  882. #endif
  883. extern    int    enlargewind();
  884. extern    int    shrinkwind();
  885. extern    int    refresh();
  886. extern    int    reposition();
  887. extern    int    togglewindow();
  888. #ifdef    CHANGE_FONT
  889. extern    int    setfont();
  890. #endif
  891.  
  892. static struct MenuBinding WindowItems[] = {
  893.     { "Split Window         C-x 2", splitwind    },
  894.     { "Delete Window        C-x 0",    delwind        },
  895.     { "Delete Other Windows C-x 1",    onlywind    },
  896.     { "Next Window          C-x o",    nextwind    },
  897. #ifdef    PREVWIND
  898.     { "Up Window",            prevwind    },
  899. #endif
  900.     { "Enlarge Window       C-x ^",    enlargewind    },
  901.     { "Shrink Window",        shrinkwind    },
  902.     { "Redraw Display",        refresh        },
  903.     { "Recenter             C-l",    reposition    },
  904.     { "Toggle Border",        togglewindow    },
  905. #ifdef    CHANGE_FONT
  906.     { "Set Font",            setfont        }
  907. #endif
  908. };
  909.  
  910. /*
  911.  * Miscellaneous commands
  912.  */
  913.  
  914. extern    int    definemacro();
  915. extern    int    finishmacro();
  916. extern    int    executemacro();
  917. extern    int    extend();
  918. extern    int    bindtokey();
  919. extern    int    desckey();
  920. extern    int    wallchart();
  921. extern    int    showversion();
  922. extern    int    spawncli();
  923.  
  924. static struct MenuBinding MiscItems[] = {
  925.     { "Start Kbd Macro   C-x (",    definemacro    },
  926.     { "End Kbd Macro     C-x )",    finishmacro    },
  927.     { "Call Kbd Macro    C-x e",    executemacro    },
  928.     { "Execute Command   M-x",    extend        },
  929.     { "Global Set Key",        bindtokey    },
  930.     { "Describe Key      C-h c",    desckey        },
  931.     { "Describe Bindings C-h b",    wallchart    },
  932.     { "Emacs Version",        showversion    },
  933.     { "New CLI           C-z",    spawncli    }
  934. };
  935.  
  936. /*
  937.  * The following table contains the titles, number of items, and
  938.  * pointers to, the individual menus.
  939.  */
  940.  
  941. static struct MenuInfo EMInfo[] = {
  942.     { "File  ",        NITEMS(FileItems),    &FileItems[0]    },
  943.     { "Edit  ",        NITEMS(EditItems),    &EditItems[0]    },
  944.     { "Move  ",         NITEMS(MoveItems),    &MoveItems[0]    },
  945.     { "Search  ",        NITEMS(SearchItems),    &SearchItems[0] },
  946.     { "Word  ",        NITEMS(WordItems),    &WordItems[0]    },
  947.     { "Paragraph  ",    NITEMS(ParaItems),    &ParaItems[0]    },
  948.     { "Region  ",        NITEMS(RegionItems),    &RegionItems[0]    },
  949.     { "Window  ",        NITEMS(WindowItems),    &WindowItems[0] },
  950.     { "Miscellaneous  ",    NITEMS(MiscItems),    &MiscItems[0]    }
  951. };
  952.  
  953. /* There are three cases to deal with; the menu alone, the Browser
  954.  * alone, and both of them together.  We #define some things to make
  955.  * life a little easier to deal with
  956.  */
  957. # ifdef    BROWSER
  958. #  define Edit_Menu_Init() Menu_Add("Edit ", TRUE, FALSE) 
  959. #  define Edit_Menu_Add(n) Menu_Item_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0,FALSE)
  960. #  define Edit_Item_Add(n) Menu_SubItem_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0,FALSE)
  961. # else
  962. #  define Edit_Menu_Init() cinf = NULL    /* harmless */
  963. #  define Edit_Menu_Add(n) n[strlen(n)-1] = '\0'; Menu_Add(n, TRUE, FALSE)
  964. #  define Edit_Item_Add(n) Menu_Item_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0,FALSE)
  965. # endif    BROWSER
  966.  
  967. #endif    MENU
  968.  
  969. /*
  970.  * Initialize the Emacs menu
  971.  */
  972.  
  973. struct Menu * InitEmacsMenu(EmW)
  974. struct Window *EmW;
  975. {
  976. #ifdef    MENU
  977.     register struct MenuInfo *cinf;
  978.     register struct MenuBinding *lastbinding, *cb;
  979.     struct MenuInfo *lastinfo;
  980. #endif
  981.  
  982.     Menu_Init() ;            /* init the menu        */
  983.  
  984. #ifdef    MENU
  985.     Edit_Menu_Init() ;        /* Set up for editing menu    */
  986.     lastinfo = &EMInfo[NITEMS(EMInfo)];    /* loop sentinel    */    
  987.     for (cinf = EMInfo; cinf < lastinfo; cinf++) {
  988.         Edit_Menu_Add(cinf->Name);
  989.         lastbinding = &cinf->Items[cinf->NumItems];
  990.         for (cb = cinf->Items; cb < lastbinding; cb++)
  991.             Edit_Item_Add(cb->Command);
  992.     }
  993. #endif    MENU
  994.  
  995. #ifdef    BROWSER
  996.     Menu_Add("Disks ", TRUE, FALSE) ;/* name is already there */
  997.     Add_Devices(DLT_DEVICE);    /* devices first */
  998.     Add_Devices(DLT_VOLUME);    /* mounted volume names next */
  999.     Add_Devices(DLT_DIRECTORY);    /* assigned directories last */
  1000. #endif    BROWSER
  1001.     return     AutoMenu ;
  1002. }
  1003.  
  1004. /*
  1005.  * amigamenu() -- handles a menu pick.
  1006.  */
  1007.  
  1008. amigamenu(f, n) {
  1009.     unsigned short        menunum, itemnum, subnum, Menu_Number;
  1010.     char            *name;
  1011.     register PF        fp;
  1012.  
  1013. #ifdef    BROWSER
  1014.     register unsigned short    level, i, dirp;
  1015.     register char        *cp;
  1016.     int            stat;
  1017.     struct MenuItem        *ItemAddress() ;
  1018.  
  1019.     /* State variables that describe the current directory */
  1020.     static char        Dir_Name[LONGEST_NAME] ;
  1021.     static unsigned short    Menu_Level = 0 ;
  1022. #endif
  1023.  
  1024. #ifndef    NO_MACRO
  1025.     if (inmacro) 
  1026.         return (FALSE);    /* menu picks aren't recorded */
  1027. #endif
  1028.  
  1029.     /* read the menu, item, and subitem codes from the input stream */
  1030.     menunum = getkey(FALSE) - MN_OFFSET;
  1031.     itemnum = getkey(FALSE) - MN_OFFSET;
  1032.     subnum = getkey(FALSE) - MN_OFFSET;
  1033.  
  1034. #ifndef    NO_MACRO
  1035.     if (macrodef) {        /* menu picks can't be practically recorded */
  1036.         ewprintf("Can't record menu selections");
  1037.         return (FALSE);
  1038.     }
  1039. #endif
  1040.  
  1041.     Menu_Number = (USHORT)
  1042.         (SHIFTMENU(menunum) | SHIFTITEM(itemnum) | SHIFTSUB(subnum));
  1043.  
  1044. #ifndef    BROWSER
  1045. # ifdef    MENU
  1046.     fp = EMInfo[menunum].Items[itemnum].Function;
  1047.     return (*(fp)(f, n));
  1048. # endif
  1049. #else    /* we're using the Browser */
  1050. # ifdef    MENU
  1051.     /* Handle commands from the Edit menu when using the Browser */
  1052.     if (0 == menunum) {
  1053.         fp = EMInfo[itemnum].Items[subnum].Function;
  1054.         return ((*fp)(f, n));
  1055.     }
  1056. # endif
  1057.     /* Here when a selection was made in a Browser menu */
  1058.     name = (char *)((struct IntuiText *)
  1059.         (ItemAddress(AutoMenu,(ULONG) Menu_Number) -> ItemFill))
  1060.         -> IText ;
  1061.     level = MENUNUM(Menu_Number) - FIRSTMENU;
  1062.  
  1063.     /* Got what we want, so clear the menu to avoid confusing the user */
  1064.     ClearMenuStrip(EmW) ;
  1065.  
  1066.     /* set dirp to FALSE if the name is not a directory or disk */
  1067.     dirp = (strchr(name, '/') != NULL || strchr(name, ':') != NULL) ;
  1068.  
  1069.     /* First, set the directory name right */
  1070.     if (level > Menu_Level)            /* Not possible, die */
  1071.         panic("impossible menu_level in amigamenu");
  1072.     else if (level == 0)            /* picked a new disk */
  1073.         Dir_Name[0] = '\0' ;
  1074.     else if (level < Menu_Level) {        /* Throw away some levels */
  1075.         for (i = 1, cp = strchr(Dir_Name, ':'); i < level; i++) {
  1076.             if (cp == NULL) return FALSE;
  1077.             cp = strchr(cp, '/') ;
  1078.             }
  1079.         if (cp == NULL) panic("broken file name in amigamenu");
  1080.         *++cp = '\0' ;
  1081.         }
  1082.     /* else Menu_Level == level, chose a file a current level */
  1083.  
  1084.     /* Now, fix up the menu and it's state variable */
  1085.     while (Menu_Level > level) {
  1086.         Menu_Level-- ;
  1087.         Menu_Pop() ;
  1088.         }
  1089.  
  1090.     /* If we added a file, visit it, else add a
  1091.      * new directory level to the menu.
  1092.      */
  1093.     if (!dirp)
  1094.         stat = Display_File(Dir_Name, name) ;
  1095.     else {
  1096.         Menu_Level++ ;
  1097.         (void) strncat(Dir_Name, name,
  1098.             LONGEST_NAME - strlen(Dir_Name) - 1) ;
  1099.         stat = Add_Dir(Dir_Name, name) ;
  1100.     }
  1101.     SetMenuStrip(EmW, AutoMenu) ;
  1102.     return stat ;
  1103. #endif    BROWSER
  1104. }
  1105.  
  1106. #ifdef    BROWSER
  1107. /*
  1108.  * Display_File - Go fetch a the requested file into a window.
  1109.  */
  1110. Display_File(dir, file) char *dir, *file; {
  1111.     register BUFFER    *bp, *findbuffer();
  1112.     int        s;
  1113.     char        File_Name[LONGEST_NAME], *fn, *adjustname();
  1114.  
  1115.     (void) strcpy(File_Name, dir);
  1116.     (void) strncat(File_Name, file, LONGEST_NAME - strlen(File_Name) - 1) ;
  1117.     fn = adjustname(File_Name);
  1118.     if ((bp = findbuffer(fn)) == NULL) return FALSE;
  1119.     curbp = bp;
  1120.     if (showbuffer(bp, curwp, WFHARD) != TRUE) return FALSE;
  1121.     if (bp->b_fname[0] == 0)
  1122.         return (readin(fn));        /* Read it in.    */
  1123.     return TRUE;
  1124.     }
  1125. /*
  1126.  * Add_Dir - given a dir and a name, add the menu name with the files in
  1127.  *    dir as entries.  Use AllocMem() in order to make
  1128.  *      sure the file info block is on a longword boundary.
  1129.  */
  1130. static
  1131. Add_Dir(dir, name) char *dir, *name; {
  1132.     register char            *last_char ;
  1133.     register struct FileLock    *my_lock, *Lock() ;
  1134.     unsigned short            count ;
  1135.     int                stat = FALSE;
  1136.     static char            Name_Buf[LONGEST_NAME] ;
  1137.     char                *AllocMem();
  1138.     struct    FileInfoBlock        *File_Info;
  1139.  
  1140.     if ((File_Info = (struct FileInfoBlock *)
  1141.         AllocMem((LONG)sizeof(struct FileInfoBlock), 0L)) == NULL)
  1142.         return (FALSE);
  1143.  
  1144.     /* Fix up the trailing / if it needs it */
  1145.     last_char = &dir[strlen(dir) - 1] ;
  1146.     if (*last_char == '/') *last_char = '\0' ;
  1147.  
  1148.     /* Now, start on the directory */
  1149.     if ((my_lock = Lock(dir, ACCESS_READ)) == NULL) goto out;
  1150.  
  1151.     if (!Examine(my_lock, File_Info)) goto out;
  1152.     if (File_Info -> fib_DirEntryType < 0L)
  1153.         goto out;
  1154.  
  1155.     if (Menu_Add(name, TRUE, TRUE) == 0) goto out;
  1156.     for (count = 0; ExNext(my_lock, File_Info) 
  1157.             || IoErr() != ERROR_NO_MORE_ENTRIES; count++)
  1158.         if (File_Info -> fib_DirEntryType < 0L) {
  1159.             if (Menu_Item_Add(File_Info -> fib_FileName,
  1160.                 (USHORT)ITEMENABLED, 0L, (BYTE)0, TRUE)
  1161.                     == MNUM(NOMENU, NOITEM, NOSUB))
  1162.                     break ;
  1163.             }
  1164.         else {
  1165.             (void) strcpy(Name_Buf, File_Info -> fib_FileName) ;
  1166.             (void) strcat(Name_Buf, "/") ;
  1167.             if (Menu_Item_Add(Name_Buf,
  1168.                 (USHORT) ITEMENABLED, 0L, (BYTE)0, TRUE)
  1169.                      == MNUM(NOMENU, NOITEM, NOSUB))
  1170.                 break ;
  1171.             }
  1172.     if (count == 0) Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0, FALSE) ;
  1173.  
  1174.     /* Put everything back */
  1175.     if (*last_char == '\0') *last_char = '/' ;
  1176.     stat = TRUE;
  1177. out:
  1178.     UnLock(my_lock) ;
  1179.     FreeMem(File_Info, (LONG) sizeof(struct FileInfoBlock));
  1180.     return stat;
  1181.     }
  1182.  
  1183. /*
  1184.  * Add all the devices currently known by the system
  1185.  * to the current menu, based on the type of device
  1186.  * list entry desired.  Disable multitasking while
  1187.  * we look inside the device list, so we don't fly off
  1188.  * into space while traversing it.
  1189.  */
  1190. struct DosLibrary    *DosBase;
  1191. extern APTR        OpenLibrary();
  1192.  
  1193. static VOID
  1194. Add_Devices(devtype)
  1195. ULONG devtype;
  1196. {
  1197.     register struct DeviceList    *devlist;
  1198.     struct RootNode            *rootnode;
  1199.     struct DosInfo            *dosinfo;
  1200.     UBYTE                buffer[80];
  1201.     int                ramflag = 0;
  1202.  
  1203.     /* if you've gotten this far, none of these will be null. */
  1204.     DosBase = (struct DosLibrary *) OpenLibrary(DOSNAME,0L);
  1205.  
  1206.     Forbid();            /* let's be careful out there... */
  1207.     rootnode = (struct RootNode *) DosBase->dl_Root;
  1208.     dosinfo = (struct DosInfo *) BADDR(rootnode->rn_Info);
  1209.     devlist = (struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  1210.  
  1211.     while (devlist) {
  1212.         /* select by specified device type */
  1213.         if (devlist->dl_Type != devtype) {
  1214.             devlist = (struct DeviceList *) BADDR(devlist->dl_Next);
  1215.             continue;
  1216.         }
  1217.  
  1218.         /* convert device's name into AmigaDOS name and concat a ":" */
  1219.         btocstr((BPTR) devlist->dl_Name,buffer,sizeof(buffer));
  1220.         strcat(buffer,":");
  1221.  
  1222.         /* Always add volumes and assigned directories. However,
  1223.          * disks should be the only devices added to the list. Magic
  1224.          * disk test courtesy of Phillip Lindsay, Commodore-Amiga Inc.
  1225.          */
  1226.         if (devtype != DLT_DEVICE)
  1227.             Menu_Item_Add(buffer, (USHORT)ITEMENABLED,
  1228.                     0L, (BYTE)0, TRUE);
  1229.         else if (devlist->dl_Task) {    /* why does this work? */
  1230.             Menu_Item_Add(buffer, (USHORT)ITEMENABLED,
  1231.                     0L, (BYTE)0, TRUE);
  1232.             if (!strcmp(buffer,"RAM:")) ramflag = 1;
  1233.         }
  1234.         devlist = (struct DeviceList *) BADDR(devlist->dl_Next);
  1235.     }
  1236.     /* if ramdisk isn't loaded yet, add it anyway */
  1237.     if ((devtype == DLT_DEVICE) && !ramflag)
  1238.         Menu_Item_Add("RAM:",(USHORT)ITEMENABLED, 0L, (BYTE) 0, FALSE);
  1239.     Permit();
  1240.     CloseLibrary(DosBase);
  1241. }
  1242.  
  1243. btocstr(bp,buf,bufsiz)
  1244. BPTR bp;
  1245. char *buf;
  1246. int bufsiz;
  1247. {
  1248.     register UBYTE    *cp;
  1249.     register int    len, i;
  1250.  
  1251.     cp = (UBYTE *) BADDR(bp);
  1252.     len = (int) *(cp++);
  1253.     len = (len > bufsiz) ? bufsiz : len;    /* truncate if necessary */
  1254.     for (i = 0; i < len; i++)
  1255.         buf[i] = *(cp++);
  1256.     buf[i] = '\0';
  1257.     return (len < bufsiz);            /* return FALSE if truncated */
  1258. }
  1259.  
  1260. #endif    BROWSER
  1261. SHAR_EOF
  1262. cat << \SHAR_EOF > sys/amiga/ttymouse.c
  1263. /*
  1264.  * Name:    MG 2a
  1265.  *        Commodore Amiga mouse handling 
  1266.  * Created:    Distant past
  1267.  * Last edit:    28-Nov-87  mic@emx.cc.utexas.edu
  1268.  */
  1269.  
  1270. #include <exec/types.h>
  1271. #include <intuition/intuition.h>
  1272. #undef    TRUE
  1273. #undef    FALSE
  1274. #include "def.h"
  1275. #ifndef    NO_MACRO
  1276. #include "macro.h"
  1277. #endif
  1278.  
  1279. extern    int    ttmouse();
  1280. extern    int    forwline();
  1281. extern    int    forwchar();
  1282. extern    int    setmark();
  1283. extern    int    isetmark();
  1284.  
  1285. /* stuff for go-to-window-and-do-it functions */
  1286. extern    int    reposition();
  1287. extern    int    delfword();
  1288. extern    int    killline();
  1289. extern    int    forwdel();
  1290. extern    int    justone();
  1291. extern    int    killregion();
  1292. extern    int    yank();
  1293. extern    int    forwpage();
  1294. extern    int    backpage();
  1295. extern    int    splitwind();
  1296. extern    int    delwind();
  1297. extern    int    gotobob();
  1298. extern    int    gotoeob();
  1299. extern    int    enlargewind();
  1300. extern    int    shrinkwind();
  1301.  
  1302. /*
  1303.  * Handle the mouse click that's been passed by ttgetc() and position
  1304.  * dot where the user pointed at.  If this is the same position
  1305.  * where the user pointed the last time, set the mark, whether or
  1306.  * not this is a true double-click. This isn't a true double-click,
  1307.  * but it does most of what we want.
  1308.  */
  1309.  
  1310. static USHORT    oldrow = HUGE, oldcol = HUGE;    /* last mouse click    */
  1311. static USHORT    newrow, newcol;            /* next mouse click    */
  1312.  
  1313. amigamouse(f, n)
  1314. {
  1315.     if (!dottomouse())            /* sets newrow, newcol    */
  1316.         return (FALSE);
  1317.     if ((newrow == oldrow) && (newcol == oldcol))
  1318.         setmark(FFRAND, 1);        /* double-click        */
  1319.     oldrow = newrow;                /* save state        */
  1320.     oldcol = newcol;
  1321.     return (TRUE);
  1322. }
  1323.  
  1324. /*
  1325.  * Recenter on selected line
  1326.  */
  1327. mreposition(f, n)
  1328. {
  1329.     if (!dottomouse())
  1330.         return (FALSE);
  1331.     return (reposition(f, n));
  1332. }
  1333.  
  1334. /*
  1335.  * Delete word after selected char
  1336.  */
  1337. mdelfword(f, n)
  1338. {
  1339.     if (!dottomouse())
  1340.         return (FALSE);
  1341.     return (delfword(f, n));
  1342. }
  1343.  
  1344. /*
  1345.  * Move to selection, kill line
  1346.  */
  1347. mkillline(f, n)
  1348. {
  1349.     if (!dottomouse())
  1350.         return (FALSE);
  1351.     return (killline(f, n));
  1352. }
  1353.  
  1354. /*
  1355.  * Move to selection, kill word
  1356.  */
  1357. mforwdel(f, n)
  1358. {
  1359.     if (!dottomouse())
  1360.         return (FALSE);
  1361.     return (forwdel(f, n));
  1362. }
  1363.  
  1364. /*
  1365.  * Move to selection, kill line
  1366.  */
  1367. mdelwhite(f, n)
  1368. {
  1369.     if (!dottomouse())
  1370.         return (FALSE);
  1371.     return (justone(f, n));
  1372. }
  1373.  
  1374. /*
  1375.  * Set mark, move to selection, kill region.
  1376.  */
  1377. mkillregion(f, n)
  1378. {
  1379.     register struct LINE *p_old;
  1380.     register short    o_old;
  1381.  
  1382.     p_old = curwp->w_markp;        /* Save old mark */
  1383.     o_old = curwp->w_marko;
  1384.     isetmark();                /* and set current one */
  1385.     if (!dottomouse()) {
  1386.         curwp->w_markp = p_old;    /* Oops - put mark back */
  1387.         curwp->w_marko = o_old;
  1388.         return (FALSE);
  1389.         }
  1390.     return (killregion(f, n));
  1391. }
  1392.  
  1393. /*
  1394.  * Move to selection, yank kill buffer
  1395.  */
  1396. myank(f, n)
  1397. {
  1398.     if (!dottomouse())
  1399.         return (FALSE);
  1400.     return (yank(f, n));
  1401. }
  1402.  
  1403. /*
  1404.  * Select window pointed to by mouse, then scroll down
  1405.  */
  1406.  
  1407. mforwpage(f, n)
  1408. {
  1409.     if (!dottomouse())
  1410.         return (FALSE);
  1411.     return (forwpage(f, n));
  1412. }
  1413.  
  1414. /*
  1415.  * Select buffer, scroll page down
  1416.  */
  1417. mbackpage(f, n)
  1418. {
  1419.     if (!dottomouse())
  1420.         return (FALSE);
  1421.     return (backpage(f, n));
  1422. }
  1423.  
  1424. /*
  1425.  * Select the window, split it.
  1426.  */
  1427. msplitwind(f, n)
  1428. {
  1429.     if (!dottomouse())
  1430.         return (FALSE);
  1431.     return (splitwind(f, n));
  1432. }
  1433.  
  1434. /*
  1435.  * Select the buffer, delete it.
  1436.  */
  1437. mdelwind(f, n)
  1438. {
  1439.     if (!dottomouse())
  1440.         return (FALSE);
  1441.     return (delwind(f, n));
  1442. }
  1443.  
  1444. /*
  1445.  * Select window, goto beginning of buffer
  1446.  */
  1447. mgotobob(f, n)
  1448. {
  1449.     if (!dottomouse())
  1450.         return (FALSE);
  1451.     return (gotobob(f, n));
  1452. }
  1453.  
  1454. /*
  1455.  * Select window, go to end of buffer
  1456.  */
  1457. mgotoeob(f, n)
  1458. {
  1459.     if (!dottomouse())
  1460.         return (FALSE);
  1461.     return (gotoeob(f, n));
  1462. }
  1463.  
  1464. /*
  1465.  * Select window, enlarge it.
  1466.  */
  1467. menlargewind(f, n)
  1468. {
  1469.     if (!dottomouse())
  1470.         return (FALSE);
  1471.     return (enlargewind(f, n));
  1472. }
  1473.     
  1474. /*
  1475.  * Select window, shrink it.
  1476.  */
  1477. mshrinkwind(f, n)
  1478. {
  1479.     if (!dottomouse())
  1480.         return (FALSE);
  1481.     return (shrinkwind(f, n));
  1482. }
  1483.  
  1484. /*
  1485.  * Utility routine to move dot to where the user clicked.  If in
  1486.  * mode line, chooses that buffer as the one to work on.
  1487.  */
  1488.  
  1489. static dottomouse()
  1490. {
  1491.     register WINDOW *wp;
  1492.     register int    dot;
  1493.     register int    col;
  1494.     register int    c;
  1495.     int        getkey();
  1496.  
  1497. #ifndef    NO_MACRO
  1498.     if (inmacro)
  1499.         return FALSE;    /* can't record mouse clicks */
  1500. #endif
  1501.  
  1502.     /* read the next 2 characters to get the col, row info, using
  1503.      * getkey() to record them (or re-read them if in a macro).
  1504.      */
  1505.     newcol = getkey(FALSE) - M_X_ZERO;
  1506.     newrow = getkey(FALSE) - M_Y_ZERO;
  1507.  
  1508. #ifndef    NO_MACRO
  1509.     if (macrodef) {        /* menu picks can't be practically recorded */
  1510.         ewprintf("Can't record mouse clicks");
  1511.         return (FALSE);
  1512.     }
  1513. #endif
  1514.  
  1515.     /* find out which window was clicked in                */
  1516.     for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
  1517.         if ((newrow >= wp->w_toprow) && 
  1518.             (newrow <= (wp->w_toprow + wp->w_ntrows)))
  1519.             break;
  1520.  
  1521.     if (wp == NULL)                /* echo line        */
  1522.         return (ABORT);
  1523.     else if (newrow == wp->w_toprow + wp->w_ntrows) {/* mode line */
  1524.         curwp = wp;            /* just change buffer     */
  1525.         curbp = wp->w_bufp;
  1526.     } else {
  1527.         /* move to selected window, move dot to top left    */
  1528.         curwp = wp;
  1529.         curbp = wp->w_bufp;
  1530.         curwp->w_dotp = wp->w_linep;
  1531.         curwp->w_doto = 0;
  1532.  
  1533.         /* go forward the correct # of lines         */
  1534.         forwline(FFRAND, newrow - curwp->w_toprow);
  1535.     
  1536.         /* go forward the correct # of characters    */
  1537.         /* need to count them out because of tabs    */
  1538.         col = dot = 0;
  1539.         while ((col < newcol) && (dot < llength(curwp->w_dotp))) {
  1540.             c = lgetc(curwp->w_dotp, dot++);
  1541.             if (c == CCHR('I'))
  1542.                 col |= 0x07;
  1543.             else if (ISCTRL(c) != FALSE)
  1544.                 ++col;
  1545.             ++col;
  1546.         }
  1547.         if (col > newcol) dot--;    /* back up to tab/ctrl char */
  1548.         forwchar(FFRAND, dot);
  1549.     }
  1550.     return (TRUE);
  1551. }
  1552. SHAR_EOF
  1553. cat << \SHAR_EOF > sys/amiga/varargs.h
  1554. /*
  1555.  * Varargs, for use on AmigaDOS with the Lattice C compiler,
  1556.  *    or (maybe?) the Manx compiler with 32-bit ints.
  1557.  *    Blatantly lifted from 4.2BSD.
  1558.  */
  1559.  
  1560. typedef char        *va_list;
  1561. #define va_dcl        int va_alist;
  1562. #define va_start(pv)    pv = (char *) &va_alist
  1563. #define va_end(pv)    /* Naught to do... */
  1564. #define va_arg(pv, t)    ((t *) (pv += sizeof(t)))[-1]
  1565. SHAR_EOF
  1566. cat << \SHAR_EOF > sys/amiga/iconify/iconify.c
  1567. /*  :ts=8 bk=0
  1568.  *
  1569.  * iconify.c:    You asked for it, you got it.
  1570.  *
  1571.  * Copyright 1987 by Leo L. Schwab.
  1572.  * Permission is hereby granted for use in any and all programs, both
  1573.  * Public Domain and commercial in nature, provided this Copyright notice
  1574.  * is left intact.  Purveyors of programs, at their option, may wish observe
  1575.  * the following conditions (in the spirit of hackerdom):
  1576.  *    1: You send me a free, registered copy of the program that uses the
  1577.  *       iconify feature,
  1578.  *    2: If you're feeling really nice, a mention in the program's
  1579.  *       documentation of my name would be neat.
  1580.  *
  1581.  *                     8712.10        (415) 456-3960
  1582.  */
  1583. #include <exec/types.h>
  1584. #include <devices/timer.h>
  1585. #include <intuition/intuition.h>
  1586. #include "iconify.h"
  1587.  
  1588. /*
  1589.  * It is recommended that the tick rate not be made too rapid to avoid
  1590.  * bogging down the system.
  1591.  */
  1592. #define    TICKS_PER_SECOND    10
  1593.  
  1594. /*
  1595.  * Some programmers may not wish to have the added functionality of the
  1596.  * ICON_FUNCTION feature.  If you're such a programmer, you may comment out
  1597.  * the following #define, which will eliminate the code to handle function
  1598.  * calls, and make iconify() even smaller.
  1599.  */
  1600. #define    USE_FUNCTIONS
  1601.  
  1602. /*
  1603.  * Jim Mackraz suggested making icons easily identifiable by outside
  1604.  * programs, so this constant gets stuffed into the UserData field.
  1605.  */
  1606. #define    ICON    0x49434f4eL        /*  'ICON'  */
  1607.  
  1608.  
  1609. extern void    *OpenWindow(), *GetMsg(), *CreatePort(), *CreateExtIO(),
  1610.         *CheckIO();
  1611. extern long    OpenDevice(), DoubleClick();
  1612.  
  1613.  
  1614. static struct Gadget gadget = {
  1615.     NULL,
  1616.     0, 0, 0, 0,
  1617.     NULL,                /*  Set later  */
  1618.     GADGIMMEDIATE,
  1619.     WDRAGGING,            /*  Observe the Magic!  */
  1620.     NULL,                /*  Set later  */
  1621.     NULL, NULL, NULL, NULL,
  1622.     0, 0
  1623. };
  1624.  
  1625. static struct NewWindow windef = {
  1626.     0, 0, 0, 0,            /*  Set later  */
  1627.     -1, -1,
  1628.     GADGETDOWN,
  1629.     BORDERLESS | SMART_REFRESH | NOCAREREFRESH,
  1630.     &gadget,
  1631.     NULL, NULL, NULL, NULL,        /*  Lotsa these  */
  1632.     0, 0, 0, 0,
  1633.     WBENCHSCREEN
  1634. };
  1635.  
  1636. static struct Window        *win;
  1637.  
  1638. #ifdef USE_FUNCTIONS
  1639. static struct timerequest    *tr;
  1640. static struct MsgPort        *reply;
  1641. #endif
  1642.  
  1643.  
  1644. iconify (left, top, width, height, screen, ptr, type)
  1645. UWORD *left, *top, width, height;
  1646. struct Screen *screen;
  1647. APTR ptr;
  1648. int type;
  1649. {
  1650.     register struct IntuiMessage    *msg;
  1651.     long                secs = 0, mics = 0,
  1652.                     cs, cm,
  1653.                     class,
  1654.                     sigmask;
  1655.  
  1656.     windef.LeftEdge        = *left;
  1657.     windef.TopEdge        = *top;
  1658.     windef.Width        = width;
  1659.     windef.Height        = height;
  1660.     windef.Type = (windef.Screen = screen) ? CUSTOMSCREEN : WBENCHSCREEN;
  1661.  
  1662.     gadget.Flags        = GADGHCOMP | GRELWIDTH | GRELHEIGHT;
  1663.  
  1664.     switch (type & 3) {
  1665.     case ICON_IMAGE:
  1666.         gadget.Flags        |= GADGIMAGE;
  1667.     case ICON_BORDER:
  1668.         gadget.GadgetRender    = ptr;
  1669.         break;
  1670.  
  1671.     case ICON_FUNCTION:
  1672. #ifdef USE_FUNCTIONS
  1673.         gadget.GadgetRender    = NULL;
  1674. #else
  1675.         return (0);
  1676. #endif
  1677.         break;
  1678.  
  1679.     default:
  1680.         return (0);
  1681.     }
  1682.  
  1683.     if (!openstuff ())
  1684.         return (0);
  1685.     sigmask = 1L << win -> UserPort -> mp_SigBit;
  1686.  
  1687. #ifdef USE_FUNCTIONS
  1688.     if (type == ICON_FUNCTION) {
  1689.         sigmask |= 1L << reply -> mp_SigBit;
  1690.         tr -> tr_node.io_Command= TR_ADDREQUEST;
  1691.         tr -> tr_time.tv_secs    = 0;
  1692.         tr -> tr_time.tv_micro    = (1000000L / TICKS_PER_SECOND);
  1693.         SendIO (tr);
  1694.         /*
  1695.          * Make initialization call to user's function.
  1696.          * Isn't typecasting wonderful?  :-|
  1697.          */
  1698.         (* ((void (*)()) ptr)) (win, (WORD) 1);
  1699.     }
  1700. #endif
  1701.  
  1702.     while (1) {
  1703.         Wait (sigmask);
  1704.  
  1705. #ifdef USE_FUNCTIONS
  1706.         if (GetMsg (reply)) {
  1707.             /*
  1708.              * Call user's function to do something to the icon.
  1709.              */
  1710.             (* ((void (*)()) ptr)) (win, (WORD) 0);
  1711.             tr -> tr_time.tv_secs    = 0;
  1712.             tr -> tr_time.tv_micro    =
  1713.              (1000000L / TICKS_PER_SECOND);
  1714.             SendIO (tr);
  1715.         }
  1716. #endif
  1717.  
  1718.         if (msg = GetMsg (win -> UserPort)) {
  1719.             class = msg -> Class;
  1720.             cs = msg -> Seconds;
  1721.             cm = msg -> Micros;
  1722.             ReplyMsg (msg);
  1723.  
  1724.             if (class == GADGETDOWN) {
  1725.                 if (DoubleClick (secs, mics, cs, cm))
  1726.                     break;
  1727.                 secs = cs;  mics = cm;
  1728.             }
  1729.         }
  1730.     }
  1731.  
  1732. #ifdef USE_FUNCTIONS
  1733.     if (type == ICON_FUNCTION) {
  1734.         AbortIO (tr);
  1735.         WaitIO (tr);
  1736.     }
  1737. #endif
  1738.  
  1739.     *left = win -> LeftEdge;
  1740.     *top = win -> TopEdge;
  1741.     closestuff ();
  1742.     return (1);
  1743. }
  1744.  
  1745. static
  1746. openstuff ()
  1747. {
  1748.     if (!(win = OpenWindow (&windef)))
  1749.         return (0);
  1750.     win -> UserData = (BYTE *) ICON;
  1751.         
  1752. #ifdef USE_FUNCTIONS
  1753.     if (!(reply = CreatePort (NULL, NULL)) ||
  1754.         !(tr = CreateExtIO (reply, (long) sizeof (*tr))) ||
  1755.         OpenDevice (TIMERNAME, UNIT_VBLANK, tr, 0L)) {
  1756.         closestuff ();
  1757.         return (0);
  1758.     }
  1759. #endif
  1760.  
  1761.     return (1);
  1762. }
  1763.  
  1764. static
  1765. closestuff ()
  1766. {
  1767. #ifdef USE_FUNCTIONS
  1768.     if (tr) {
  1769.         if (tr -> tr_node.io_Device)
  1770.             CloseDevice (tr);
  1771.         DeleteExtIO (tr, (long) sizeof (*tr));
  1772.     }
  1773.     if (reply)        DeletePort (reply);
  1774. #endif
  1775.  
  1776.     if (win)        CloseWindow (win);
  1777. }
  1778. SHAR_EOF
  1779. cat << \SHAR_EOF > sys/amiga/iconify/iconify.h
  1780. /*  :ts=8 bk=0
  1781.  *
  1782.  * iconify.h:    Should be used by all programs intending to use iconify.c.
  1783.  *
  1784.  * Copyright 1987 by Leo L. Schwab.
  1785.  * Permission is hereby granted for use in any and all programs, both
  1786.  * Public Domain and commercial in nature, provided this Copyright notice
  1787.  * is left intact.  Purveyors of programs, at their option, may wish observe
  1788.  * the following conditions (in the spirit of hackerdom):
  1789.  *    1: You send me a free, registered copy of the program that uses the
  1790.  *       iconify feature,
  1791.  *    2: If you're feeling really nice, a mention in the program's
  1792.  *       documentation of my name would be neat.
  1793.  *
  1794.  *                     8712.10        (415) 456-3960
  1795.  */
  1796.  
  1797. #define    ICON_IMAGE    0
  1798. #define    ICON_BORDER    1
  1799. #define    ICON_FUNCTION    2
  1800.  
  1801. /*  Suggested icon size for a standard (640 x 200) WorkBench screen.  */
  1802. #define    ICONWIDTH    ((UWORD) 50)
  1803. #define    ICONHEIGHT    ((UWORD) 25)
  1804. SHAR_EOF
  1805. #    End of shell archive
  1806. exit 0
  1807. -------
  1808.