home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i013: A Micro-Emacs variant that resembles GNU Emacs
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: Bob Larson <seismo!usc-oberon!blarson>
- Mod.sources: Volume 8, Issue 13
- Archive-name: micrognu/Part06
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # tty/amiga/ttydef.h
- # tty/amiga/console.c
- # tty/amiga/menustack.c
- # tty/amiga/tty.c
- # tty/amiga/ttyio.c
- # tty/amiga/ttymenu.c
- # This archive created: Sat Nov 15 15:26:59 1986
- export PATH; PATH=/bin:$PATH
- if test ! -d tty/amiga
- then
- mkdir tty/amiga
- fi
- if test ! -d sys/amiga
- then
- mkdir sys/amiga
- fi
- if test -f 'tty/amiga/ttydef.h'
- then
- echo shar: will not over-write existing file "'tty/amiga/ttydef.h'"
- else
- cat << \SHAR_EOF > 'tty/amiga/ttydef.h'
- /*
- * Name: MicroEMACS
- * Amiga console device virtual terminal header file
- * Version: Gnu v30
- * Last edit: 26-Aug-86
- * Created: 20-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- */
- #define GOSLING /* Compile in fancy display. */
-
- #define NROW 48 /* Max rows (only in interlace) */
- #define NCOL 80 /* Columns (borderless window) */
-
- /*
- * Special keys for the default Amiga console device keymap.
- * Function key codes are in the form <CSI>v~
- * where v is a 1 or 2-digit code between 0 and 19,
- * so they comprise the first 20 entries in the key
- * table. The next 12 entries are for the help and
- * arrow keys.
- */
- #define KF1 K01
- #define KF2 K02
- #define KF3 K03
- #define KF4 K04
- #define KF5 K05
- #define KF6 K06
- #define KF7 K07
- #define KF8 K08
- #define KF9 K09
- #define KF10 K0A
- #define KSF1 K0B
- #define KSF2 K0C
- #define KSF3 K0D
- #define KSF4 K0E
- #define KSF5 K0F
- #define KSF6 K10
- #define KSF7 K11
- #define KSF8 K12
- #define KSF9 K13
- #define KSF10 K14
- #define KUP K15
- #define KSUP K16
- #define KDOWN K17
- #define KSDOWN K18
- #define KLEFT K19
- #define KSLEFT K1A
- #define KRIGHT K1B
- #define KSRIGHT K1C
- #define KHELP K1D
-
- /* The 'menu' key doesn't really appear on the
- * Amiga keyboard. When ttgetc() sees a menu
- * event, it saves the menu number and item,
- * then stuffs the sequence for KMENU into
- * the input buffer.
- */
- #define KMENU K1E
-
- /*
- * Intuition menu interface. Each set of menu items
- * kept in a table of MenuBinding structures, which
- * is in turn kept in a table of MenuInfo structures.
- *
- * These tables are indexed via the menu and item
- * numbers to find the internal extended name of
- * the function associated with a certain item.
- */
- struct MenuBinding {
- char *Command;
- char *Binding;
- };
-
- struct MenuInfo {
- char *Name; /* name of menu */
- short NumItems; /* # of items */
- struct MenuBinding *Items; /* item name, internal binding */
- };
-
- #define NITEMS(arr) (sizeof(arr) / (sizeof(arr[0])))
-
- /*
- * If either MENU, or BROWSER is defined, we need to define
- * DO_MENU to get the code for dealing with menu selections
- * compiled in.
- */
-
- #ifdef MENU
- #define DO_MENU
- #else
- #ifdef BROWSER
- #define DO_MENU
- #endif BROWSER
- #endif MENU
-
- /*
- * MODE_RENDITION and TEXT_RENDITION
- * determine the way the mode line and
- * text area are rendered (using the SGR
- * sequence). TEXT_* and MODE_* set the
- * foreground (FG) and background (BG)
- * color to the specified number. If you
- * #define CHANGE_COLOR, you can redefine
- * these dynamically.
- */
-
- #ifndef MODE_RENDITION
- #define MODE_RENDITION 7
- #endif
-
- #ifndef TEXT_RENDITION
- #define TEXT_RENDITION 0
- #endif
-
- #ifndef TEXT_FG
- #define TEXT_FG 1
- #endif
-
- #ifndef TEXT_BG
- #define TEXT_BG 0
- #endif
-
- #ifndef MODE_FG
- #define MODE_FG 1
- #endif
-
- #ifndef MODE_BG
- #define MODE_BG 0
- #endif
-
- /*
- * Return the width and height of
- * the default font for a window.
- */
-
- #define FontWidth(w) (w)->RPort->TxWidth
- #define FontHeight(w) (w)->RPort->TxHeight
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'tty/amiga/console.c'
- then
- echo shar: will not over-write existing file "'tty/amiga/console.c'"
- else
- cat << \SHAR_EOF > 'tty/amiga/console.c'
- /*
- * These functions are taken directly from the
- * console.device chapter in the Amiga V1.1
- * ROM Kernel Manual.
- */
- #include <exec/types.h>
- #include <exec/io.h>
- #include <devices/console.h>
- #include <libraries/dos.h>
- #include <intuition/intuition.h>
-
- extern LONG OpenDevice();
- extern LONG DoIO();
- extern LONG SendIO();
-
- /*
- * Open a console device, given a read request
- * and a write request message.
- */
-
- int OpenConsole(writerequest,readrequest,window)
- struct IOStdReq *writerequest;
- struct IOStdReq *readrequest;
- struct Window *window;
- {
- LONG error;
- writerequest->io_Data = (APTR) window;
- writerequest->io_Length = (ULONG) sizeof(*window);
- error = OpenDevice("console.device", 0L, writerequest, 0L);
-
- /* clone required parts of the request */
- readrequest->io_Device = writerequest->io_Device;
- readrequest->io_Unit = writerequest->io_Unit;
- return((int) error);
- }
-
- /*
- * Output a single character
- * to a specified console
- */
-
- int ConPutChar(request,character)
- struct IOStdReq *request;
- char character;
- {
- #ifdef V11
- register int x;
- #endif
- request->io_Command = CMD_WRITE;
- request->io_Data = (APTR)&character;
- request->io_Length = (ULONG)1;
- DoIO(request);
- /* caution: read comments in manual! */
- return(0);
- }
-
- /*
- * Output a NULL-terminated string of
- * characters to a console
- */
-
- int ConPutStr(request,string)
- struct IOStdReq *request;
- char *string;
- {
- #ifdef V11
- register int x;
- #endif
- request->io_Command = CMD_WRITE;
- request->io_Data = (APTR)string;
- request->io_Length = (LONG)-1;
- DoIO(request);
- return(0);
- }
-
- /*
- * Write out a string of predetermined
- * length to the console
- */
-
- int ConWrite(request,string,len)
- struct IOStdReq *request;
- char *string;
- int len;
- {
- #ifdef V11
- register int x;
- #endif
- request->io_Command = CMD_WRITE;
- request->io_Data = (APTR)string;
- request->io_Length = (LONG)len;
- DoIO(request);
- return(0);
- }
-
- /*
- * Queue up a read request
- * to a console
- */
-
- int QueueRead(request,whereto)
- struct IOStdReq *request;
- char *whereto;
- {
- #ifdef V11
- register int x;
- #endif
- request->io_Command = CMD_READ;
- request->io_Data = (APTR)whereto;
- request->io_Length = (LONG)1;
- SendIO(request);
- return(0);
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'tty/amiga/menustack.c'
- then
- echo shar: will not over-write existing file "'tty/amiga/menustack.c'"
- else
- cat << \SHAR_EOF > 'tty/amiga/menustack.c'
- /*
- * Simple menu package. Needs lotsa work to handle some cases.
- *
- * Copyright 1985
- * Louis A. Mamakos
- * Software & Stuff
- * 14813 Ashford Place
- * Laurel, MD 20707
- *
- * For non-commerical use only. This program, or any modifications, may not
- * be sold or incorporated into any product without prior permission from the
- * author.
- *
- * Modified by mwm to handle "stacking" menus.
- * NB - adding item to a menu that's been "popped" back to doesn't work,
- * and probably never will.
- */
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/ports.h>
- #include <exec/devices.h>
- #include <exec/memory.h>
- #include <hardware/blit.h>
- #include <graphics/copper.h>
- #include <graphics/regions.h>
- #include <graphics/rastport.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gels.h>
- #include <intuition/intuition.h>
-
- #define MNUM(menu,item,sub) (SHIFTMENU(menu)|SHIFTITEM(item)|SHIFTSUB(sub))
- #define Menu_Clear DisposeMenus /* For ttyio.c */
-
- extern char *AllocMem();
- extern char *AllocRemember();
-
- struct Mem_Node {
- struct Node mn_Node;
- struct Remember mn_Memory;
- struct Menu *mn_Menu;
- } *Top, *RemHead();
-
- extern struct NewWindow MicroEMACS ; /* For Screen width & Height */
- #define SCREENHEIGHT (MicroEMACS . MaxHeight)
- #define SCREENWIDTH (MicroEMACS . MaxWidth)
-
- static struct List Memory;
- static int Cur_Menu, Cur_MenuItem, Cur_SubItem;
- static struct Menu *LastMenu;
- static struct MenuItem *LastMenuItem, *LastSubItem;
-
- struct Menu *AutoMenu; /* menu struct being dynamically built */
-
- char *strsave(); /* Save a string in the remember list */
-
- Menu_Init()
- {
- Memory.lh_Head = (struct Node *) &(Memory.lh_Tail);
- Memory.lh_TailPred = (struct Node *) &(Memory.lh_Head);
- Memory.lh_Tail = NULL;
- Memory.lh_Type = NT_MEMORY;
- Top = NULL;
- Cur_Menu = Cur_MenuItem = Cur_SubItem = -1;
- AutoMenu = LastMenu = NULL; /* no menu chain yet */
- LastMenuItem = LastSubItem = NULL;
- }
-
- Menu_Clear()
- {
-
- while ((Top = RemHead(&Memory)) != NULL) {
- FreeRemember(&(Top->mn_Memory), (LONG)TRUE);
- FreeMem(Top, (LONG)sizeof(struct Mem_Node));
- }
- Menu_Init(); /* Just for safeties sake */
- }
-
- Menu_Pop()
- {
-
- if ((Top = RemHead(&Memory)) == NULL) return NULL;
- FreeRemember(&(Top->mn_Memory), (LONG)TRUE);
- FreeMem(Top, (LONG)sizeof(struct Mem_Node));
- /* Now, set Top back to the real list head */
- Top = (struct Mem_Node *) Memory.lh_Head;
- LastMenu = Top->mn_Menu;
- LastMenuItem = NULL; /* Wrong, but you can't add items here anyway */
- LastSubItem = NULL; /* ditto */
- Cur_Menu--;
- }
- /*
- * Add a MENU item. Args are the text of the menu item, and an enable
- * flag. Returns an Intuition type menu number, with the MenuItem and
- * Menu SubItem being NOITEM and NOSUB. The MENUITEM part is valid.
- */
- /* dummy Intuitext used to calculate length of menu names */
- static struct IntuiText itd = {
- AUTOFRONTPEN, AUTOBACKPEN, JAM2, 1, 1, NULL, NULL, NULL
- };
-
- Menu_Add(name, enabled)
- char *name;
- int enabled;
- {
- register struct Menu *m;
-
- if ((Top = (struct Mem_Node *) AllocMem(
- (LONG)sizeof(struct Mem_Node), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- return NULL;
- Top->mn_Node.ln_Type = NT_MEMORY;
-
- if ((m = (struct Menu *)AllocRemember(&(Top->mn_Memory),
- (LONG)sizeof (struct Menu), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- return NULL;
- Top->mn_Menu = m;
-
- if (LastMenu == NULL)
- AutoMenu = m; /* first menu on list */
- else
- LastMenu->NextMenu = m; /* link it in */
-
- LastMenuItem = NULL; /* end of previous MenuItem list */
- LastSubItem = NULL;
- Cur_MenuItem = Cur_SubItem = -1; /* reset item numbers */
- if (LastMenu == NULL)
- m->LeftEdge = 0;
- else
- m->LeftEdge = LastMenu->LeftEdge + LastMenu->Width;
- m->TopEdge = 0;
- itd.IText = (UBYTE *)name;
- m->Width = IntuiTextLength(&itd);
- Top->mn_Node.ln_Name = m->MenuName = strsave(name);
- m->Height = 0;
- m->Flags = enabled ? MENUENABLED : 0;
- m->FirstItem = NULL;
- LastMenu = m;
-
- AddHead(&Memory, Top);
- return MNUM(++Cur_Menu, NOITEM, NOSUB);
- }
-
- /*
- * Add a menu item to the current MENU. Note that Add_Menu *must* be
- * called before this function.
- */
- Menu_Item_Add(name, flags, mux, ch)
- char *name; /* name of menu item */
- USHORT flags;
- LONG mux; /* mutual exclusion mask */
- BYTE ch; /* command sequence character, if COMMSEQ */
- {
- register struct MenuItem *m, *n;
- register struct IntuiText *it;
-
- flags &= CHECKIT|CHECKED|COMMSEQ|MENUTOGGLE|ITEMENABLED|HIGHCOMP|HIGHBOX;
- if (LastMenu == NULL)
- return MNUM(NOMENU, NOITEM, NOSUB);
-
- if ((m = (struct MenuItem *) AllocRemember(&(Top->mn_Memory),
- (LONG)sizeof(struct MenuItem), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- return MNUM(NOMENU, NOITEM, NOSUB);
-
- LastSubItem = NULL; /* terminate possible list of subitems */
- Cur_SubItem = -1;
- if (LastMenuItem == NULL)
- LastMenu->FirstItem = m;
- else
- LastMenuItem->NextItem = m;
- m->Flags = flags | ITEMTEXT;
- /*
- * Check for highlight mode: if none selected, use HIGHCOMP
- */
- if ((m->Flags & (HIGHCOMP | HIGHBOX)) == 0)
- m->Flags |= HIGHCOMP;
- m->Command = ch;
- m->MutualExclude = mux;
- m->SubItem = NULL;
- m->ItemFill = (APTR) AllocRemember(&(Top->mn_Memory),
- (LONG)sizeof(struct IntuiText), MEMF_PUBLIC | MEMF_CLEAR);
- it = (struct IntuiText *) m->ItemFill;
- it->FrontPen = AUTOFRONTPEN;
- it->BackPen = AUTOBACKPEN;
- it->DrawMode = JAM2;
- if (flags & CHECKIT)
- it->LeftEdge = CHECKWIDTH + 1;
- else
- it->LeftEdge = 1;
- it->TopEdge = 1;
- it->ITextFont = NULL; /* default font */
- it->IText = (UBYTE *)strsave(name);
- it->NextText = NULL;
- if (LastMenuItem == NULL) {
- m->TopEdge = 2;
- m->LeftEdge = 0;
- } else if (LastMenuItem->TopEdge + 40 > SCREENHEIGHT) {
- m->TopEdge = 2;
- m->LeftEdge = LastMenuItem->LeftEdge + LastMenuItem->Width + 12;
- if (m->LeftEdge > SCREENWIDTH) {
- LastMenuItem->NextItem = NULL;
- LastMenuItem->Flags &= ~ITEMENABLED;
- return MNUM(NOMENU, NOITEM, NOSUB);
- }
- } else {
- m->TopEdge = LastMenuItem->TopEdge + 10;
- m->LeftEdge = LastMenuItem->LeftEdge;
- }
- m->Width = 0;
- if (flags & CHECKIT)
- m->Width += CHECKWIDTH;
- if (flags & COMMSEQ)
- m->Width += COMMWIDTH + 20;
- m->Width += IntuiTextLength(m->ItemFill);
- m->Height = 10;
- /*
- * Check last menu item's width to see if it is larger than this
- * item's. If new item is larger, then update width of all other
- * items.
- */
- if (LastMenuItem) {
- if (LastMenuItem->Width > m->Width)
- m->Width = LastMenuItem->Width;
- else {
- register short delta = m->Width - LastMenuItem->Width;
-
- for (n = LastMenu->FirstItem; n != m; n = n->NextItem) {
- n->Width = m->Width;
- if (n->LeftEdge > 0) n->LeftEdge += delta;
- }
- if (m->LeftEdge > 0) m->LeftEdge += delta;
- }
- }
- LastMenuItem = m;
- return MNUM(Cur_Menu, ++Cur_MenuItem, NOSUB);
- }
-
-
-
- Menu_SubItem_Add(name, flags, mux, ch)
- char *name, ch;
- USHORT flags;
- LONG mux;
- {
- register struct MenuItem *m, *n;
- register struct IntuiText *it;
-
- flags &= CHECKIT|CHECKED|COMMSEQ|MENUTOGGLE|ITEMENABLED|HIGHCOMP|HIGHBOX;
- if (LastMenuItem == NULL)
- return MNUM(NOMENU, NOITEM, NOSUB);
-
- if ((m = (struct MenuItem *) AllocRemember(&(Top->mn_Memory),
- (LONG)sizeof(struct MenuItem), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- return MNUM(NOMENU, NOITEM, NOSUB);
-
- if (LastSubItem == NULL)
- LastMenuItem->SubItem = m;
- else
- LastSubItem->NextItem = m;
- m->Flags = flags | ITEMTEXT;
- /*
- * check for highlight mode. If none selected, use HIGHCOMP
- */
- if ((m->Flags & (HIGHCOMP|HIGHBOX)) == 0)
- m->Flags |= HIGHCOMP;
- m->Command = ch;
- m->MutualExclude = mux;
- m->SubItem = NULL;
- m->ItemFill = (APTR) AllocRemember(&(Top->mn_Memory),
- (LONG)sizeof(struct IntuiText), MEMF_PUBLIC | MEMF_CLEAR);
- it = (struct IntuiText *) m->ItemFill;
- it->FrontPen = AUTOFRONTPEN;
- it->BackPen = AUTOBACKPEN;
- it->DrawMode = JAM2;
- if (flags & CHECKIT)
- it->LeftEdge = CHECKWIDTH + 1;
- else
- it->LeftEdge = 1;
- it->TopEdge = 1;
- it->ITextFont = NULL; /* default font */
- it->IText = (UBYTE *)strsave(name);
- it->NextText = NULL;
- m->LeftEdge = LastMenuItem->Width + 10;
- m->Width = 0;
- if (LastSubItem == NULL)
- m->TopEdge = 1;
- else
- m->TopEdge = LastSubItem->TopEdge + 10;
- if (flags & CHECKIT)
- m->Width += CHECKWIDTH;
- if (flags & COMMSEQ)
- m->Width += COMMWIDTH + 20;
- m->Width += IntuiTextLength(m->ItemFill);
- m->Height = 10;
- /*
- * Check last menu item's width to see if it is larger than this
- * item's. If new item is larger, then update width of all other
- * items.
- */
- if (LastSubItem) {
- if (LastSubItem->Width > m->Width)
- m->Width = LastSubItem->Width;
- else
- for (n = LastMenuItem->SubItem; n != m; n = n->NextItem)
- n->Width = m->Width;
- }
- LastSubItem = m;
- return MNUM(Cur_Menu, Cur_MenuItem, ++Cur_SubItem);
- }
-
- char *
- strsave(string) char *string; {
- char *out ;
-
- out = (char *) AllocRemember(&(Top->mn_Memory), (LONG)(strlen(string) + 1),
- MEMF_PUBLIC) ;
- if (out == NULL) return NULL ;
-
- (void) strcpy(out, string) ;
- return out ;
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'tty/amiga/tty.c'
- then
- echo shar: will not over-write existing file "'tty/amiga/tty.c'"
- else
- cat << \SHAR_EOF > 'tty/amiga/tty.c'
- /*
- * Name: MicroEMACS
- * Amiga console device virtual terminal display
- * Version: GNU v30
- * Last Edit: 23-Aug-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Created: 19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- *
- * Drives the Amiga console device display. The code
- * is a combination of the Heath and ANSI terminal drivers,
- * plus some hacks to manage the console device colors.
- */
-
- #include "def.h"
-
- #define BEL 0x07 /* BEL character. */
- #define ESC 0x1B /* ESC character. */
-
- extern int ttrow;
- extern int ttcol;
- extern int tttop;
- extern int ttbot;
- extern int tthue;
-
- int tceeol = 3; /* Costs, ANSI display. */
- int tcinsl = 17;
- int tcdell = 16;
-
-
- #ifdef CHANGE_COLOR
- short mode_rendition = MODE_RENDITION, /* set standard colors */
- text_rendition = TEXT_RENDITION,
- text_fg = TEXT_FG + 30,
- text_bg = TEXT_BG + 40,
- mode_fg = MODE_FG + 30,
- mode_bg = MODE_BG + 40;
- #else /* colors are hard-coded */
- #define mode_rendition MODE_RENDITION
- #define text_rendition TEXT_RENDITION
- #define text_fg (TEXT_FG + 30)
- #define text_bg (TEXT_BG + 40)
- #define mode_fg (MODE_FG + 30)
- #define mode_bg (MODE_BG + 40)
- #endif
-
- /*
- * Initialize the terminal when the editor
- * gets started up. A no-op for the Amiga
- */
- ttinit()
- {
- }
-
- /*
- * Clean up the terminal, in anticipation of
- * a return to the command interpreter. This
- * is a no-op on the Amiga.
- */
- tttidy()
- {
- }
-
- /*
- * Move the cursor to the specified
- * origin 0 row and column position. Try to
- * optimize out extra moves; redisplay may
- * have left the cursor in the right
- * location last time!
- */
- ttmove(row, col)
- {
- if (ttrow!=row || ttcol!=col) {
- ttputc(ESC);
- ttputc('[');
- asciiparm(row+1);
- ttputc(';');
- asciiparm(col+1);
- ttputc('H');
- ttrow = row;
- ttcol = col;
- }
- }
-
- /*
- * Erase to end of line.
- */
- tteeol()
- {
- ttputc(ESC);
- ttputc('[');
- ttputc('K');
- }
-
- /*
- * Erase to end of page.
- */
- tteeop()
- {
- ttputc(ESC); /* reinforce current color values */
- ttputc('[');
- asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
- ttputc(';');
- asciiparm(text_fg);
- ttputc(';');
- asciiparm(text_bg);
- ttputc('m');
-
- ttputc(ESC); /* clear to end of display */
- ttputc('[');
- ttputc('J');
- }
-
- /*
- * Make a noise.
- */
- ttbeep()
- {
- ttputc(BEL);
- ttflush();
- }
-
- /*
- * Convert a number to decimal
- * ascii, and write it out. Used to
- * deal with numeric arguments.
- */
- asciiparm(n)
- register int n;
- {
- if (n > 9)
- asciiparm(n/10);
- ttputc((n%10) + '0');
- }
-
- /*
- * Insert a block of blank lines onto the
- * screen, using a scrolling region that starts at row
- * "row" and extends down to row "bot". Deal with the one
- * line case, which is a little bit special, with special
- * case code.
- *
- * Since we don't really have a scrolling region,
- * delete the block of lines that would have been deleted if
- * we'd had one, then insert blank lines to move the rest
- * of the screen back to where it belongs. This idea from
- * the Heath driver.
- */
- VOID ttinsl(row, bot, nchunk)
- {
- if (row == bot) { /* Funny case. */
- if (nchunk != 1)
- panic("ttinsl: nchunk != 1");
- ttmove(row, 0);
- tteeol();
- return;
- }
- ttmove(1+bot-nchunk, 0);
- if (nchunk > 0) { /* Delete a chunk of lines */
- ttputc(ESC); /* nchunk in size. Rest of */
- ttputc('['); /* screen moves up. */
- asciiparm(nchunk);
- ttputc('M');
- }
- ttmove(row, 0);
- if (nchunk > 0) { /* Insert a chunk nchunk in size*/
- ttputc(ESC); /* before current line, sliding */
- ttputc('['); /* rest of screen down. */
- asciiparm(nchunk);
- ttputc('L');
- }
- ttrow = row; /* End up on current line */
- ttcol = 0;
- }
-
- /*
- * Delete a block of lines, with the uppermost
- * line at row "row", in a screen slice that extends to
- * row "bot". The "nchunk" is the number of lines that have
- * to be deleted. This is done by deleting nchunk lines at the
- * appropriate spot, then inserting nchunk lines to make up for
- * the empty space at the bottom of the virtual scrolling region.
- */
- VOID ttdell(row, bot, nchunk)
- {
- if (row == bot) { /* One line special case */
- ttmove(row, 0);
- tteeol();
- return;
- }
- if (nchunk > 0) {
- ttmove(row, 0);
- ttputc(ESC);
- ttputc('[');
- asciiparm(nchunk);
- ttputc('M');
- }
- ttmove(1+bot-nchunk,0);
- if (nchunk > 0) {
- ttputc(ESC); /* For all lines in chunk */
- ttputc('['); /* INS line before bottom */
- asciiparm(nchunk); /* Bottom of window (and rest */
- ttputc('L'); /* of screen) moves down */
- }
- ttrow = HUGE;
- ttcol = HUGE;
- ttmove(bot-nchunk,0);
- }
-
- /*
- * No-op.
- */
- ttwindow(top,bot)
- {
- }
-
- /*
- * No-op.
- */
- ttnowindow()
- {
- }
-
- #ifdef CHANGE_COLOR
- /*
- * Set the rendition of the mode line by
- * selecting colors from the following:
- * 0 -- plain text
- * 1 -- bold-face
- * 3 -- italic
- * 4 -- underscore
- * 7 -- inverse video
- * Certain of these selections may be less than
- * appealing :-)
- */
-
- ttmode(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Set mode line rendition (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- mode_rendition = n; /* store the color */
- sgarbf = TRUE;
- return (TRUE);
- }
-
- /*
- * Set the rendition of the text area.
- * Most of these selections will be
- * less than appealing :-]
- */
-
- tttext(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Set text rendition (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- text_rendition = n; /* store the color */
- sgarbf = TRUE;
- return (TRUE);
- }
-
- /*
- * Set foreground color for entire window
- * to a value between 30 and 37, which
- * corresponds to the arguments 0-7.
- * This requires a total refresh, which
- * sets up the screen.
- */
-
- textforeground(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Text foreground color (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- text_fg = n + 30;
- sgarbf = TRUE;
- return (TRUE);
- }
-
- /*
- * Set background color for entire window
- * to a value between 40 and 47 inclusive.
- */
-
- textbackground(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Text background color (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- text_bg = n + 40;
- sgarbf = TRUE;
- return (TRUE);
- }
-
- /*
- * Set foreground color for entire the mode line
- */
-
- modeforeground(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Mode line foreground color (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- mode_fg = n + 30;
- sgarbf = TRUE;
- return (TRUE);
- }
-
- /*
- * Set background color for the mode line
- */
-
- modebackground(f, n, k)
- {
- register int s;
- char buf[2];
-
- if (f == FALSE) {
- if ((s = ereply("Mode line background color (0-7): ",
- buf, sizeof(buf))) != TRUE)
- return (s);
- n = atoi(buf);
- }
- if (n < 0 || n > 7)
- return (FALSE);
-
- mode_bg = n + 40;
- sgarbf = TRUE;
- return (TRUE);
- }
- #endif
-
- /*
- * Set the current writing color to the
- * specified color. Watch for color changes that are
- * not going to do anything (the color is already right)
- * and don't send anything to the display.
- */
-
- ttcolor(color)
- register int color;
- {
- if (color != tthue) {
- if (color == CTEXT) { /* Normal video. */
- ttputc(ESC); /* Reset to 0 */
- ttputc('[');
- ttputc('m');
- ttputc(ESC); /* Set text style */
- ttputc('[');
- asciiparm(text_rendition);
- ttputc(';');
- asciiparm(text_fg);
- ttputc(';');
- asciiparm(text_bg);
- ttputc('m');
- } else if (color == CMODE) { /* Standout mode */
- ttputc(ESC); /* Reset to 0 */
- ttputc('[');
- ttputc('m');
- ttputc(ESC); /* Set standout mode */
- ttputc('[');
- asciiparm(mode_rendition);
- ttputc(';');
- asciiparm(mode_fg); /* Use mode line colors */
- ttputc(';');
- asciiparm(mode_bg);
- ttputc('m');
- }
- tthue = color; /* Save the color. */
- }
- }
-
- /*
- * This routine is called by the
- * "refresh the screen" command to try and resize
- * the display. The new size, which must be deadstopped
- * to not exceed the NROW and NCOL limits, is stored
- * back into "nrow" and "ncol". Display can always deal
- * with a screen NROW by NCOL. Look in "window.c" to
- * see how the caller deals with a change.
- * On the Amiga, we make the Intuition terminal driver
- * do all the work.
- */
-
- ttresize()
- {
- setttysize();
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'tty/amiga/ttyio.c'
- then
- echo shar: will not over-write existing file "'tty/amiga/ttyio.c'"
- else
- cat << \SHAR_EOF > 'tty/amiga/ttyio.c'
- /*
- * Name: MicroEmacs
- * Amiga terminal-dependent I/O (Intuition)
- * Created: 21-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- */
-
- /*
- * Lots of includes.
- */
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/tasks.h>
- #include <exec/ports.h>
- #include <exec/io.h>
- #include <devices/console.h>
- #include <libraries/dos.h>
- #include <graphics/clip.h>
- #include <graphics/view.h>
- #include <graphics/rastport.h>
- #include <graphics/layers.h>
- #include <graphics/text.h>
- #include <graphics/gfxbase.h>
- #include <intuition/intuition.h>
- #ifdef CHANGE_FONT
- #include <libraries/diskfont.h>
- #endif
-
- #undef TRUE /* avoid redefinition messages */
- #undef FALSE
- #include "def.h" /* includes sysdef.h and ttydef.h */
-
- /*
- * External Amiga functions. Declared explicitly
- * to avoid problems with different compilers.
- */
- extern LONG AbortIO();
- extern LONG CloseDevice();
- extern LONG CloseLibrary();
- extern LONG CloseWindow();
- extern struct MsgPort *CreatePort();
- extern struct IOStdReq *CreateStdIO();
- extern LONG DeletePort();
- extern LONG DeleteStdIO();
- extern struct IntuiMessage *GetMsg();
- extern int OpenConsole();
- extern char *OpenLibrary();
- extern struct Window *OpenWindow();
- #ifdef CHANGE_FONT
- extern struct TextFont *OpenDiskFont();
- #endif
- extern LONG RectFill();
- extern LONG ReplyMsg();
- extern LONG SetAPen();
- extern LONG SetDrMd();
- extern LONG Wait();
-
- #ifdef DO_MENU
- extern LONG ClearMenuStrip(); /* menu functions */
- extern struct Menu *InitEmacsMenu();
- extern struct MenuItem *ItemAddress();
- extern LONG SetMenuStrip();
- #endif
-
- extern int Enable_Abort; /* Do NOT allow abort! */
-
- /*
- * External MicroEmacs functions and variables
- */
- extern int quit(); /* Defined by "main.c" */
- extern char *version; /* Version information */
-
- /*
- * Library bases (used by glue libraries)
- */
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- #ifdef CHANGE_FONT
- ULONG DiskfontBase;
- #endif
-
- /*
- * Intuition window and menu variables
- */
- #define WINDOWGADGETS (WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE)
-
- static short borderless = TRUE; /* Flag for borderless window */
- static short leftedge = 0, /* Last top left position */
- topedge = 0,
- width = 640,
- height = 200;
-
- struct NewWindow MicroEMACS = {
- 0, 0, /* start position */
- 0, 0, /* width, height (set by ttopen)*/
- 0, 1, /* detail pen, block pen */
- #ifdef DO_MENU
- MENUPICK | /* If menu is used */
- #endif
- #ifdef MOUSE
- MOUSEBUTTONS | /* If mouse is used */
- #endif
- CLOSEWINDOW | NEWSIZE, /* IDCMP flags */
- 0, /* window flags (set by ttopen) */
- NULL, /* pointer to first user gadget */
- NULL, /* pointer to user checkmark */
- NULL, /* title (filled in later) */
- NULL, /* pointer to screen (none) */
- NULL, /* pointer to superbitmap */
- 359,101, /* minimum size (with TOPAZ_80) */
- 0, 0, /* maximum size (set by ttopen) */
- WBENCHSCREEN /* screen in which to open */
- };
-
- struct Window *EmW; /* Our window */
- static short toggling = FALSE; /* Prevent menu wiping */
-
- #ifdef DO_MENU
- static struct Menu *EmacsMenu = NULL; /* Our menu */
- #endif
- #ifdef CHANGE_FONT
- static struct TextFont *EmFont = NULL;
- #endif
-
- /*
- * The bridge between Intuition events and Emacs' single
- * input stream...
- */
- static USHORT class, /* Intuition event */
- code, /* information */
- qualifier;
- static APTR address;
- static SHORT x, y;
- static LONG intuitionMsgBit; /* Signal bit */
- #define INTUITION_MESSAGE ((LONG) (1L << intuitionMsgBit))
-
- /*
- * To more thoroughly handle Intuition events, we buffer
- * them into a circular queue until other routines ask
- * for the information carried in them.
- */
- #define NIBUF 256 /* Rather roomy... */
- #define EVT_KBD 0
- #define EVT_MOUSE 1
- #define EVT_MENU 2
- #define NULLEVT ((struct event *) 0)
-
- struct event {
- USHORT type; /* What is it? */
- union {
- UBYTE ch; /* Keyboard event */
- struct { /* Mouse click */
- SHORT row, col; /* location in character raster */
- USHORT qualifier;
- } mouse;
- USHORT code; /* Menu event */
- } data;
- } ibuf[NIBUF]; /* Input buffer */
- int ibufo, nibuf; /* head, # of bytes in ibuf */
-
- /*
- * Console output
- */
- #define CSI 0x9b /* Command Sequence Introducer */
- #define ESC 0x1b /* Escape key */
- #define NOBUF 512 /* About 1/4 screen */
-
- static struct MsgPort *consoleWritePort; /* I/O ports */
- static struct MsgPort *consoleReadPort;
- static struct IOStdReq *consoleWriteMsg; /* I/O messages */
- static struct IOStdReq *consoleReadMsg;
- static LONG consoleMsgBit; /* signal bit */
- #define CONSOLE_MESSAGE ((LONG) (1L << consoleMsgBit))
- static unsigned char letter; /* Console input buffer */
-
- static unsigned char obuf[NOBUF]; /* Terminal output buffer */
- int nobuf; /* # of bytes in above */
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
- extern int ttrow; /* Current cursor row */
-
- /*
- * Open up the virtual terminal MicroEMACS communicates with.
- * Set up the window, console, and menu strip.
- */
-
- ttopen()
- {
- register struct Screen *s;
-
- Enable_Abort = 0; /* Disable ^C */
-
- GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library", (LONG) 0);
- if (GfxBase == NULL) /* Graphics lib */
- cleanup(1);
-
- IntuitionBase = (struct IntuitionBase *) /* Intuition */
- OpenLibrary("intuition.library", (LONG) 0);
- if (IntuitionBase == NULL)
- cleanup(2);
-
- #ifdef CHANGE_FONT
- DiskfontBase = (ULONG) OpenLibrary("diskfont.library", (LONG)0);
- if (DiskfontBase == NULL)
- cleanup(21);
- #endif
- /*
- * Create our window. Set window flags based on the current
- * value of the borderless flag, and the maximum size of the
- * window based on the size of the first screen in the screen
- * list with screen type WBENCHSCREEN (of which there had better
- * be *EXACTLY* one, right???...). To avoid possible crashes
- * if user is moving screens around, turn off multitasking
- * during the loop.
- */
- Forbid(); /* user might be moving screen */
- for (s = IntuitionBase->FirstScreen; s ; s = s->NextScreen)
- if ((s->Flags & SCREENTYPE) == WBENCHSCREEN)
- break;
- MicroEMACS.MaxWidth = s->Width;
- MicroEMACS.MaxHeight = s->Height;
- Permit();
-
- /* Set the window size based on the last one that was open,
- * if it was borderless. Otherwise make it fill the screen.
- * Set max/min widths based on current screen size.
- *
- * Set flags and window title, then open window
- */
- if (borderless) {
- MicroEMACS.Flags = WINDOWGADGETS | ACTIVATE | BORDERLESS;
- #ifdef TOGGLE_ZOOMS
- MicroEMACS.LeftEdge = 0;
- MicroEMACS.TopEdge = 0;
- MicroEMACS.Width = MicroEMACS.MaxWidth;
- MicroEMACS.Height = MicroEMACS.MaxHeight;
- #endif
- } else {
- MicroEMACS.Flags = WINDOWGADGETS | ACTIVATE | WINDOWSIZING;
- #ifndef TOGGLE_ZOOMS
- }
- #endif
- MicroEMACS.LeftEdge = leftedge;
- MicroEMACS.TopEdge = topedge;
- MicroEMACS.Width = width;
- MicroEMACS.Height = height;
- #ifdef TOGGLE_ZOOMS
- }
- #endif
- MicroEMACS.Title = (UBYTE *) version; /* name for window */
- if ((EmW = OpenWindow(&MicroEMACS)) == NULL)
- cleanup(3);
-
- #ifdef CHANGE_FONT
- /* If the user requested a different font for the text, EmFont
- * will be non-null, so set the font for the RastPort. The
- * conole device will pick this up when we open it later on.
- */
- if (EmFont)
- SetFont(EmW->RPort, EmFont);
- #endif
-
- /* Once the window is created, get the Intuition signal bit,
- * set up the menu, and tell the virtual terminal how big
- * it is.
- */
- intuitionMsgBit = EmW->UserPort->mp_SigBit;
- #ifdef DO_MENU
- if (toggling == FALSE)
- EmacsMenu = InitEmacsMenu(EmW);
- SetMenuStrip(EmW, EmacsMenu);
- #endif
- setttysize();
-
- /* Set up the console device. Create the necessary read/write
- * ports and messages, attach the console device thus created
- * to our window, initialize the console input buffer, and
- * queue the first read to the console.
- */
-
- consoleWritePort = CreatePort("Emacs.con.write",(LONG) 0);
- if (consoleWritePort == NULL)
- cleanup(4);
- consoleWriteMsg = CreateStdIO(consoleWritePort);
- if (consoleWriteMsg == NULL)
- cleanup(5);
-
- consoleReadPort = CreatePort("Emacs.con.read",(LONG) 0);
- if (consoleReadPort == NULL)
- cleanup(6);
- consoleReadMsg = CreateStdIO(consoleReadPort);
- if (consoleReadMsg == NULL)
- cleanup(7);
-
- if (OpenConsole(consoleWriteMsg,consoleReadMsg,EmW) != 0)
- cleanup(8);
- consoleMsgBit = consoleReadPort->mp_SigBit;
-
- QueueRead(consoleReadMsg,&letter);
- nibuf = ibufo = 0;
-
- return (0);
- }
-
- /*
- * Close the virtual terminal, aborting any
- * I/O to the console device and de-allocating
- * everything we have allocated.
- */
- ttclose()
- {
- ttflush();
- AbortIO(consoleReadMsg);
- CloseDevice(consoleWriteMsg);
- cleanup(0);
- Enable_Abort = 1;
- }
-
- /*
- * Toggle between a borderless window
- * and a sizeable window. This lets you
- * use the whole screen if you want.
- * Bound to "toggle-window-hack" by
- * ttykbd.c
- */
-
- togglewindow(f, n, k)
- {
- toggling = TRUE; /* Notify the system */
- #ifdef TOGGLE_ZOOMS
- if (!borderless) {
- #endif
- leftedge = EmW->LeftEdge; /* save window state */
- topedge = EmW->TopEdge;
- width = EmW->Width;
- height = EmW->Height;
- #ifdef TOGGLE_ZOOMS
- }
- #endif
- ttclose(); /* reset to zero */
-
- borderless = !borderless; /* toggle window flag */
- ttopen(); /* re-open tty window */
- sgarbf = TRUE; /* screen was trashed */
- nrow = ncol = -1; /* trash screen size */
- refresh(); /* and redraw it */
- toggling = FALSE; /* Ok, done */
- return (TRUE);
- }
-
- #ifdef CHANGE_FONT
- /*
- * Select a different font for the Emacs window.
- * This obviously does not work very well
- * with proportional fonts, so we ask the
- * user to confirm before he uses one.
- * It's available if you want to be able
- * to use your own disk font (or Topaz 15
- * under 1.2) to edit with.
- */
-
- setfont(f, n, k)
- {
- register int s, size;
- register struct TextFont *newfont;
- char fontname[80], fontpath[84], fontsize[3];
- struct TextAttr ta;
-
- /* Get font size */
- if (f == TRUE)
- size = n;
- else {
- if ((s = ereply("Font size: ",
- fontsize, sizeof(fontsize))) != TRUE)
- return (s);
- size = atoi(fontsize);
- }
-
- if (size <= 0) { /* reset to default font */
- if (EmFont)
- CloseFont(EmFont);
- EmFont = NULL;
- } else { /* user wants to set a new font name */
- if ((s = ereply("Font name (e.g. topaz): ",
- fontname, sizeof(fontname))) != TRUE)
- return (s);
- strcpy(fontpath,fontname);
- strncat(fontpath,".font",sizeof(fontpath));/* make name */
-
- /* set up text attributes */
- ta.ta_Name = (UBYTE *)fontpath;
- ta.ta_YSize = size;
- ta.ta_Style = FS_NORMAL;
- ta.ta_Flags = 0; /* use either */
-
- /* Look for the font */
- ewprintf("Looking for %s %d...",fontname,size);
- if ((newfont = OpenDiskFont(&ta)) == NULL) {
- ewprintf("Can't find %s %d!",fontname,size);
- return (FALSE);
- } else { /* Found it! Check before using it. */
- if ((newfont->tf_YSize != size) && ((s = eyesno(
- "Size unavailable - use closest"))!=TRUE)){
- CloseFont(newfont);
- return (FALSE);
- }
- if ((newfont->tf_Flags & FPF_PROPORTIONAL) &&
- (((s = eyesno("Use proportional font")))!=TRUE)){
- CloseFont(newfont);
- return (FALSE);
- }
- /* Get rid of old font and cache the new one */
- if (EmFont)
- CloseFont(EmFont);
- EmFont = newfont;
- }
- }
-
- /* Now that the font is selected, close the window. */
- toggling = TRUE; /* Notify the system */
- ttclose(); /* reset to zero */
- ttopen(); /* re-open w/new font */
- nrow = -1; /* trash size */
- ncol = -1; /* so refresh() works */
- refresh(); /* redo whole screen */
- if (size > 0)
- ewprintf("Now using font %s %d",fontname,EmFont->tf_YSize);
- else
- ewprintf("Now using default font");
- return (TRUE);
- }
- #endif
-
- /*
- * Write a single character to the screen.
- * Buffered for extra speed, so ttflush()
- * does all the work.
- */
- ttputc(c)
- unsigned char c;
- {
- obuf[nobuf++] = c;
- if (nobuf >= NOBUF)
- ttflush();
- }
-
- /*
- * Flush characters from the output buffer.
- * Just blast it out with a console write call.
- */
- ttflush()
- {
- if (nobuf > 0) {
- ConWrite(consoleWriteMsg, obuf, nobuf);
- nobuf = 0;
- }
- }
-
- /*
- * Get a character for Emacs, without echo or
- * translation. Basically, handle Intuition
- * events until we get one that signifies
- * a character was typed in some way.
- */
- ttgetc()
- {
- register struct IntuiMessage *message; /* IDCMP message */
- register LONG wakeupmask; /* which signals? */
- register int charfound; /* got a character yet? */
- unsigned char nextchar(); /* return next char evt */
-
- if (striptochar()) /* any chars in buffer? */
- return (int) (nextchar() & 0xFF);
-
- charfound = FALSE; /* nope -- have to wait */
- do {
- wakeupmask = Wait(INTUITION_MESSAGE|CONSOLE_MESSAGE);
-
- if (wakeupmask & CONSOLE_MESSAGE) { /* keyboard */
- GetMsg(consoleReadPort); /* free message */
- qchar(letter); /* do this FIRST */
- QueueRead(consoleReadMsg, &letter);
- charfound = TRUE;
- }
-
- if (wakeupmask & INTUITION_MESSAGE) /* Intuition */
- while(message = GetMsg(EmW->UserPort))
- if (dispatch(message) == TRUE)
- charfound = TRUE;
- } while (charfound == FALSE);
-
- return (int) (nextchar() & 0xFF); /* found a character! */
- }
-
- /*
- * Handle the events we handle... The result
- * returned indicates if we've put a character
- * in the input buffer.
- */
- static dispatch(msg)
- register struct IntuiMessage *msg;
- {
- #ifdef DO_MENU
- register struct MenuItem *item;
- #endif
- register int txheight, txwidth;
- register struct RastPort *rp;
- int dx, dy, fgpen, drmode;
-
- class = msg->Class; /* grab the info before we */
- code = msg->Code; /* reply to the message */
- qualifier = msg->Qualifier;
- address = msg->IAddress;
- x = msg->MouseX;
- y = msg->MouseY;
- ReplyMsg(msg); /* return it to Intuition */
-
- switch(class) { /* see what the fuss is about */
- #ifdef DO_MENU
- case MENUPICK:
- if (code == MENUNULL)
- return (FALSE);
- while (code != MENUNULL) {/* handle multiple selection */
- qmenu(code);
- item = ItemAddress(EmacsMenu,(LONG) code);
- code = item->NextSelect;
- }
- return (TRUE); /* puts <CSI>M~ in event queue */
- break;
- #endif
-
- #ifdef MOUSE
- case MOUSEBUTTONS: /* fake the mouse key */
- if (code != SELECTDOWN) /* ignore SELECTUP */
- return (FALSE);
- qmouse(x, y, qualifier);
- return (TRUE);
- break;
- #endif
- case NEWSIZE:
- /* Sometimes when you resize the window to make it
- * smaller, garbage is left at the right and bottom
- * sides of the window. This code is devoted to
- * (somehow) getting rid of this garbage. Any
- * suggestions?
- */
-
- rp = EmW->RPort;
- fgpen = rp->FgPen; /* save params */
- drmode = rp->DrawMode;
- SetDrMd(rp, (LONG) JAM1);
- SetAPen(rp, (LONG) EmW->RPort->BgPen);
-
- /* Check the bottom of the window
- */
- txheight = EmW->Height - EmW->BorderTop - EmW->BorderBottom;
- if (dy = (txheight % FontHeight(EmW)))
- RectFill(rp,
- (LONG) EmW->BorderLeft,
- (LONG) EmW->BorderTop + txheight - dy - 1,
- (LONG) (EmW->Width - 1) - EmW->BorderRight,
- (LONG) (EmW->Height - 1) - EmW->BorderBottom);
-
- /* Check the right side
- */
- txwidth = EmW->Width - EmW->BorderLeft - EmW->BorderRight;
- if (dx = txwidth % FontWidth(EmW))
- RectFill(rp,
- (LONG) EmW->BorderLeft + txwidth - dx - 1,
- (LONG) EmW->BorderTop,
- (LONG) (EmW->Width - 1) - EmW->BorderRight,
- (LONG) (EmW->Height - 1) - EmW->BorderBottom);
-
- SetDrMd(rp, (LONG) drmode);
- SetAPen(rp, (LONG) fgpen); /* restore colors */
-
- /* Tell the console device to resize itself */
- ttputc(CSI);
- ttputc('t');
- ttputc(CSI);
- ttputc('u');
- ttflush();
-
- /* Signal the editor that a new size has occurred */
- qchar(ESC);
- qchar('\f');
-
- return (TRUE); /* we done (finally) */
- break;
-
- case CLOSEWINDOW: /* Call quit() directly */
- quit(FALSE, 1, KRANDOM);
- return (FALSE);
- break;
- default:
- panic("HandleMsg: unknown event!!!");
- break;
- }
- return(FALSE);
- }
-
- #ifdef DO_MENU
- /*
- * Return the next menu selection number to
- * the caller. Used by "ttymenu.c".
- */
- ttmenu(codep)
- USHORT *codep;
- {
- register struct event *e;
- struct event *nextevt();
-
- e = nextevt();
- if (e->type != EVT_MENU)
- return (FALSE);
-
- *codep = e->data.code;
- remevt(); /* remove event by hand */
- return (TRUE);
- }
- #endif
-
- #ifdef MOUSE
- /*
- * Return the next mouse click values to
- * the caller. *Rowp and *colp will contain
- * the row and column where the mouse click occured.
- * This is so that only the terminal driver has
- * to know about the size of the window's font.
- * If the flag argument f is FALSE, the mouse event
- * is *not* removed from the queue, allowing routines
- * that need to (mainly getmouse()) to peek at it.
- */
- ttmouse(f, rowp,colp,qualp)
- int f;
- USHORT *rowp, *colp, *qualp;
- {
- register struct event *e;
- struct event *nextevt();
-
- e = nextevt();
- if (e->type != EVT_MOUSE)
- return (FALSE); /* next isn't mouse evt */
-
- *colp = e->data.mouse.col;
- *rowp = e->data.mouse.row;
- *qualp = e->data.mouse.qualifier;
- if (f)
- remevt(); /* remove the event */
- return (TRUE);
- }
- #endif
-
- /*
- * Return the current size of the virtual
- * terminal in nrow and ncol, making sure
- * we don't go beyond the size of the internal
- * video array.
- * Assumes the current font is monospaced
- * (not always safe bet any more :-) :-).
- */
- setttysize()
- {
- nrow = (EmW->Height - EmW->BorderTop
- - EmW->BorderBottom) / FontHeight(EmW);
- ncol = (EmW->Width - EmW->BorderLeft
- - EmW->BorderRight) / FontWidth(EmW);
- if (nrow < 1)
- nrow = 1;
- if (nrow > NROW)
- nrow = NROW;
- if (ncol < 1)
- ncol = 1;
- if (ncol > NCOL)
- ncol = NCOL;
- }
-
- /*
- * Exit as soon as possible, after displaying
- * the message.
- */
- panic(s)
- char *s;
- {
- ewprintf(s); /* put message at bottom */
- Delay((ULONG) 90); /* wait 1.5 seconds */
- ttclose(); /* get rid of window &resources */
- exit(10000); /* go 'way */
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Event buffer management *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /*
- * If the buffer's full, crap out, else
- * return a pointer to the (ibufo + nibuf)'th
- * event record (mod NIBUF). Postincrement
- * nibuf so it points at the next record and
- * also keeps track of how many events
- * are in the buffer.
- */
- static struct event *newevt()
- {
- return ((nibuf < NIBUF) ?
- (ibuf + ((ibufo + nibuf++) % NIBUF)) : NULLEVT);
- }
-
- /*
- * Return pointer to next item in queue,
- * *without* removing it.
- */
- static struct event *nextevt()
- {
- return (nibuf ? (ibuf + ibufo) : NULLEVT);
- }
-
- /*
- * Move buffer pointer to next item in queue.
- */
- static remevt()
- {
- if (nibuf <= 0)
- nibuf = 0;
- else {
- nibuf--;
- ibufo++;
- ibufo %= NIBUF; /* wrap around in buffer */
- }
- }
-
- /*
- * Return true if there are some characters available
- * in the buffer. Unlike striptochar, don't do anything
- * to the input buffer, just return a value.
- */
- typeahead()
- {
- register int bufp;
-
- for (bufp = 0; bufp < nibuf; bufp++)
- if (ibuf[(ibufo + bufp) % NIBUF].type == EVT_KBD)
- return (TRUE);
- return (FALSE);
- }
-
- /*
- * See if there are any characters queued,
- * stripping any other events that may
- * be in the way. *Don't* remove the character
- * from the queue.
- */
- static striptochar()
- {
- register struct event *e;
-
- while (e = nextevt())
- if (e->type == EVT_KBD)
- return (TRUE);
- else
- remevt();
- return (FALSE);
- }
-
- /*
- * Return next character in event buffer.
- */
- static unsigned char nextchar()
- {
- register struct event *e;
-
- if (e = nextevt()) {
- remevt();
- return (e->data.ch);
- }
- else
- return ((unsigned char) 0); /* shouldn't happen */
- }
-
- /*
- * Add a keyboard event to the queue
- */
- static qchar(c)
- unsigned char c;
- {
- register struct event *e;
-
- if (e = newevt()) {
- e->type = EVT_KBD;
- e->data.ch = c;
- }
- }
-
- #ifdef MOUSE
- /*
- * Add a mouse event to the queue, calculating
- * the row and column value from the current height
- * and width of the window's font.
- */
- static qmouse(x, y, qual)
- SHORT x, y;
- USHORT qual;
- {
- register struct event *e;
-
- qchar(CSI);
- qchar('P');
- qchar('~');
- if (e = newevt()) {
- e->type = EVT_MOUSE;
- e->data.mouse.col = (x - EmW->BorderLeft) / FontWidth(EmW);
- e->data.mouse.row = (y - EmW->BorderTop) / FontHeight(EmW);
- e->data.mouse.qualifier = qual;
- }
- }
- #endif
-
- #ifdef DO_MENU
- /*
- * Add a menu key to queue
- */
- static qmenu(code)
- USHORT code;
- {
- register struct event *e;
-
- qchar(CSI); /* menu key sequence */
- qchar('M');
- qchar('~');
- if (e = newevt()) {
- e->type = EVT_MENU;
- e->data.code = code;
- }
- }
- #endif
-
- /*
- * Clean up.
- *
- * Fall through all the possible cases (0 means
- * get rid of everything and start with the case
- * that fits the error situation).
- */
-
- static cleanup(prob)
- {
- switch (prob) {
- case 0: /* just clean everything up
-
- case 8: /* couldn't open console device */
- DeleteStdIO(consoleReadMsg);
- case 7: /* couldn't get console read msg */
- DeletePort(consoleReadPort);
- case 6: /* couldn't get console read port */
- DeleteStdIO(consoleWriteMsg);
- case 5: /* couldn't get console write msg */
- DeletePort(consoleWritePort);
- case 4: /* couldn't get console write port */
- #ifdef CHANGE_FONT
- if ((toggling == FALSE) && EmFont)
- CloseFont(EmFont);/* access_count-- */
- #endif
- #ifdef DO_MENU
- if (toggling == FALSE) {
- ClearMenuStrip(EmW);
- DisposeMenus(EmacsMenu);
- }
- #endif
- CloseWindow(EmW);
- case 3: /* couldn't open window */
- #ifdef CHANGE_FONT
- CloseLibrary(DiskfontBase);
- #endif
- case 21: /* couldn't open DiskfontBase */
- CloseLibrary(IntuitionBase);
- case 2: /* couldn't open IntuitionBase */
- CloseLibrary(GfxBase);
- case 1: /* couldn't open GfxBase -- do nothing */
- break;
- }
- return(0);
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'tty/amiga/ttymenu.c'
- then
- echo shar: will not over-write existing file "'tty/amiga/ttymenu.c'"
- else
- cat << \SHAR_EOF > 'tty/amiga/ttymenu.c'
- /*
- * ttymenu.c
- *
- * Incorporates the browser, for rummaging around on disks,
- * and the usual Emacs editing command menu
- *
- * Copyright (c) 1986, Mike Meyer
- * Manxification and Edit menu by Mic Kaczmarczik (no charge :-)
- *
- * Permission is hereby granted to distribute this program, so long as
- * this source file is distributed with it, and this copyright notice
- * is not removed from the file.
- *
- */
-
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <intuition/intuition.h>
- #undef TRUE
- #undef FALSE
- #include "def.h"
-
- extern struct Menu *AutoMenu ;
- extern struct Window *EmW ;
-
- #define MNUM(menu,item,sub) (SHIFTMENU(menu)|SHIFTITEM(item)|SHIFTSUB(sub))
-
- #ifdef BROWSER
- #define LONGEST_NAME 80 /* Longest file name we can deal with */
-
- # ifndef MANX
- char *strchr(char *, int);
- # else
- char *index(); /* find first instance of c in s */
- #define strchr(s, c) index(s, c)
- # endif
-
- # ifdef MENU
- #define FIRSTMENU 1
- # else
- #define FIRSTMENU 0
- # endif
-
- #endif BROWSER
-
- #ifdef MENU
- /*
- * When ttgetc() sees a menu selection event, it stuffs
- * the sequence <CSI>M~ into the input buffer, and
- * caches the menu number and item number for later.
- * This sequence is translated into the internal key code
- * KMENU, similar to KHELP and the other function keys.
- *
- * The menu item names are chosen to be relatively close
- * to the extended function names, so a user can usually
- * figure out the key binding of a menu item by searching
- * through the "display-bindings" buffer for something
- * that's close.
- */
-
- /*
- * Commands for managing files and buffers
- */
-
- static struct MenuBinding FileItems[] = {
- { "Find File C-x C-f", "find-file" },
- { "Pop To File C-x 4 f", "find-file-other-window" },
- { "Insert File C-x i", "insert-file" },
- { "Save File C-x C-s", "save-buffer" },
- { "Write File C-x C-w", "write-file" },
- { "Switch To Buffer C-x b", "switch-to-buffer" },
- { "Pop To Buffer C-x 4 b", "switch-to-buffer-other-window" },
- { "Kill Buffer C-x k", "kill-buffer" },
- { "List Buffers C-x C-b", "list-buffers" },
- { "Save Buffers C-x s", "save-some-buffers" },
- { "Save And Exit C-x C-c", "save-buffers-kill-emacs" }
- };
-
- /*
- * Commands for various editing functions
- */
-
- static struct MenuBinding EditItems[] = {
- { "Yank C-y", "yank" },
- { "Blank Line C-o ", "open-line" },
- { "Kill Line C-k", "kill-line" },
- { "Delete Blank Lines C-x C-o","delete-blank-lines" },
- { "Delete Blanks M-SPC", "just-one-space" },
- { "Newline And Indent C-j", "newline-and-indent" },
- { "Transpose Characters C-t", "transpose-chars" },
- { "Quoted Insert C-q", "quoted-insert" }
- };
-
- /*
- * Movement commands
- */
-
- static struct MenuBinding MoveItems[] = {
- { "Scroll Up C-v", "scroll-up" },
- { "Scroll Down M-v", "scroll-down" },
- { "Start Of Line C-a", "beginning-of-line" },
- { "Start Of Buffer M-<", "beginning-of-buffer" },
- { "End Of Line C-e", "end-of-line" },
- { "End Of Buffer M->", "end-of-buffer" },
- { "Goto Line", "goto-line" },
- { "Show Cursor C-x =", "what-cursor-position" }
- };
-
- /*
- * Commands for searching and replacing
- */
-
- static struct MenuBinding SearchItems[] = {
- { "I-Search Forward C-s", "isearch-forward" },
- { "I-Search Backward C-r", "isearch-backward" },
- { "Search Again", "search-again" },
- { "Search Forward M-s", "search-forward" },
- { "Search Backward M-r", "search-backward" },
- { "Query Replace M-%", "query-replace" }
- };
-
- /*
- * Commands that manipulate words
- */
- static struct MenuBinding WordItems[] = {
- { "Forward Word M-f", "forward-word" },
- { "Backward Word M-b", "backward-word" },
- { "Kill Word M-d", "kill-word" },
- { "Backward Kill Word M-DEL", "backward-kill-word" },
- { "Capitalize Word M-c", "capitalize-word" },
- { "Downcase Word M-l", "downcase-word" },
- { "Upcase Word M-u", "upcase-word" }
- };
-
- static struct MenuBinding ParaItems[] = {
- { "Forward Paragraph M-]", "forward-paragraph" },
- { "Backward Paragraph M-[", "backward-paragraph" },
- { "Fill Paragraph M-q", "fill-paragraph" },
- { "Set Fill Column C-x f", "set-fill-column" },
- { "Kill Paragraph", "kill-paragraph" },
- { "Auto Fill Mode", "auto-fill-mode" }
- };
-
- /*
- * Region stuff
- */
-
- static struct MenuBinding RegionItems[] = {
- { "Set Mark C-@", "set-mark-command" },
- { "Exch Point And Mark C-x C-x","exchange-point-and-mark" },
- { "Kill Region C-w", "kill-region" },
- { "Copy Region As Kill M-w", "copy-region-as-kill" },
- { "Downcase Region C-x C-l","downcase-region" },
- { "Upcase Region C-x C-u","upcase-region" }
- };
-
- /*
- * Commands for manipulating windows
- */
-
- static struct MenuBinding WindowItems[] = {
- { "Split Window C-x 2", "split-window-vertically" },
- { "Delete Window C-x 0", "delete-window" },
- { "Delete Other Windows C-x 1", "delete-other-windows" },
- { "Down Window C-x o", "next-window" },
- { "Up Window", "previous-window" },
- { "Enlarge Window C-x ^", "enlarge-window" },
- { "Shrink Window", "shrink-window" },
- { "Redraw Display", "redraw-display" },
- { "Recenter C-l", "recenter" },
- { "Toggle Border", "toggle-window-hack" },
- #ifdef CHANGE_FONT
- { "Set Font", "set-font" }
- #endif
- };
-
- /*
- * Miscellaneous commands
- */
-
- static struct MenuBinding MiscItems[] = {
- { "Start Kbd Macro C-x (", "start-kbd-macro" },
- { "End Kbd Macro C-x )", "end-kbd-macro" },
- { "Call Kbd Macro C-x e", "call-last-kbd-macro" },
- { "Execute Command M-x", "execute-extended-command" },
- { "Global Set Key", "global-set-key" },
- { "Global Unset Key", "global-unset-key" },
- { "Describe Key C-h c", "describe-key-briefly", },
- { "Describe Bindings C-h b", "describe-bindings" },
- { "Emacs Version", "emacs-version" },
- { "New CLI C-z", "suspend-emacs" }
- };
-
- /*
- * The following table contains the titles, number of
- * items, and pointers to, the individual menus.
- */
-
- static struct MenuInfo EMInfo[] = {
- { "File ", NITEMS(FileItems), &FileItems[0] },
- { "Edit ", NITEMS(EditItems), &EditItems[0] },
- { "Move ", NITEMS(MoveItems), &MoveItems[0] },
- { "Search ", NITEMS(SearchItems), &SearchItems[0] },
- { "Word ", NITEMS(WordItems), &WordItems[0] },
- { "Paragraph ", NITEMS(ParaItems), &ParaItems[0] },
- { "Region ", NITEMS(RegionItems), &RegionItems[0] },
- { "Window ", NITEMS(WindowItems), &WindowItems[0] },
- { "Miscellaneous ", NITEMS(MiscItems), &MiscItems[0] }
- };
-
- /* There are three cases to deal with; the menu alone, the Browser
- * alone, and both of them together. We #define some things to make
- * life a little easier to deal with
- */
- # ifdef BROWSER
- # define Edit_Menu_Init() Menu_Add("Edit ", TRUE)
- # define Edit_Menu_Add(n) Menu_Item_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0)
- # define Edit_Item_Add(n) Menu_SubItem_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0)
- # else
- # define Edit_Menu_Init() cinf = NULL /* harmless */
- # define Edit_Menu_Add(n) n[strlen(n)-1] = '\0'; Menu_Add(n, TRUE)
- # define Edit_Item_Add(n) Menu_Item_Add(n,(USHORT)ITEMENABLED,0L,(BYTE)0)
- # endif BROWSER
-
- #endif MENU
-
- /*
- * Heeere we go!!!!
- */
-
- struct Menu * InitEmacsMenu(EmW)
- struct Window *EmW;
- {
- #ifdef MENU
- register struct MenuInfo *cinf, *lastinfo;
- register struct MenuBinding *cb, *lastbinding;
- #endif
-
- Menu_Init() ; /* init the menu */
-
- #ifdef MENU
-
- Edit_Menu_Init() ; /* Set up for editing menu */
- lastinfo = &EMInfo[NITEMS(EMInfo)]; /* loop sentinel */
- for (cinf = EMInfo; cinf < lastinfo; cinf++) {
- Edit_Menu_Add(cinf->Name);
- lastbinding = &cinf->Items[cinf->NumItems];
- for (cb = cinf->Items; cb < lastbinding; cb++)
- Edit_Item_Add(cb->Command);
- }
- #endif MENU
-
- #ifdef BROWSER
- Menu_Add("Disks ", TRUE) ;
- Menu_Item_Add("Df0:", (USHORT) ITEMENABLED, 0L, (BYTE) 0) ;
- Menu_Item_Add("Df1:", (USHORT) ITEMENABLED, 0L, (BYTE) 0) ;
- Menu_Item_Add("Ram:", (USHORT) ITEMENABLED, 0L, (BYTE) 0) ;
- #endif BROWSER
-
- return AutoMenu ;
- }
-
- /*
- * amigamenu() -- handles a menu pick.
- */
-
- amigamenu(f, n, k) {
- unsigned short Menu_Number;
- char *name;
- int ttmenu(); /* in ttyio.c */
-
- #ifdef BROWSER
- register unsigned short level, i, dirp;
- register char *cp;
- int stat;
- struct MenuItem *ItemAddress() ;
-
- /* State variables that describe the current directory */
- static char Dir_Name[LONGEST_NAME] ;
- static unsigned short Menu_Level = 0 ;
- #endif
- #ifdef MENU
- SYMBOL *sp;
- #endif
-
- if (!ttmenu(&Menu_Number)) return FALSE; /* get menu number */
-
- #ifndef BROWSER
- # ifdef MENU
- name = EMInfo[MENUNUM(Menu_Number)].Items[ITEMNUM(Menu_Number)].Binding;
- if ((sp=symlookup(name)) != NULL)
- return ((*sp->s_funcp)(f, n, KRANDOM));
- panic("Unknown menu command!"); /* trouble! */
- # endif
- #else /* we're using the Browser */
- # ifdef MENU
- /* Handle commands from the Edit menu when using the Browser */
- if (0 == MENUNUM(Menu_Number)) {
- name = EMInfo[ITEMNUM(Menu_Number)].Items[SUBNUM(Menu_Number)].Binding;
- if ((sp=symlookup(name)) != NULL)
- return ((*sp->s_funcp)(f, n, KRANDOM));
- panic("Unknown menu command!"); /* trouble! */
- }
- # endif
- /* Here when a selection was made in a Browser menu */
- name = (char *)((struct IntuiText *)
- (ItemAddress(AutoMenu,(ULONG) Menu_Number) -> ItemFill))
- -> IText ;
- level = MENUNUM(Menu_Number) - FIRSTMENU;
-
- /* Got what we want, so clear the menu to avoid confusing the user */
- ClearMenuStrip(EmW) ;
-
- /* set dirp to FALSE if the name is not a directory or disk */
- dirp = (strchr(name, '/') != NULL || strchr(name, ':') != NULL) ;
-
- /* First, set the directory name right */
- if (level > Menu_Level) /* Not possible, die */
- panic("impossible menu_level in amigamenu");
- else if (level == 0) /* picked a new disk */
- Dir_Name[0] = '\0' ;
- else if (level < Menu_Level) { /* Throw away some levels */
- for (i = 1, cp = strchr(Dir_Name, ':'); i < level; i++) {
- if (cp == NULL) return FALSE;
- cp = strchr(cp, '/') ;
- }
- if (cp == NULL) panic("broken file name in amigamenu");
- *++cp = '\0' ;
- }
- /* else Menu_Level == level, chose a file a current level */
-
- /* Now, fix up the menu and it's state variable */
- while (Menu_Level > level) {
- Menu_Level-- ;
- Menu_Pop() ;
- }
-
- /* If we added a directory, tack it onto the name */
- if (dirp) {
- Menu_Level++ ;
- (void) strncat(Dir_Name, name,
- LONGEST_NAME - strlen(Dir_Name) - 1) ;
- }
-
- /* Now, tell the user all about it */
- if (dirp) stat = Add_Dir(Dir_Name, name) ;
- else stat = Display_File(Dir_Name, name) ;
- SetMenuStrip(EmW, AutoMenu) ;
- return stat ;
- #endif BROWSER
- }
-
- #ifdef BROWSER
- /*
- * Display_File - Go fetch a the requested file into a window.
- */
- Display_File(dir, file) char *dir, *file; {
- register BUFFER *bp, *findbuffer();
- int s;
- char File_Name[LONGEST_NAME];
-
- (void) strcpy(File_Name, dir);
- (void) strncat(File_Name, file, LONGEST_NAME - strlen(File_Name) - 1) ;
- if ((bp = findbuffer(File_Name, &s)) == NULL) return s;
- curbp = bp;
- if (showbuffer(bp, curwp, WFHARD) != TRUE) return FALSE;
- if (bp->b_fname[0] == 0)
- return (readin(File_Name)); /* Read it in. */
- return TRUE;
- }
- /*
- * Add_Dir - given a dir and a name, add the menu name with the files in
- * dir as entries. Use AllocMem() in order to make
- * sure the file info block is on a longword boundary.
- */
- static
- Add_Dir(dir, name) char *dir, *name; {
- register char *last_char ;
- register struct FileLock *my_lock, *Lock() ;
- unsigned short count ;
- int stat = FALSE;
- static char Name_Buf[LONGEST_NAME] ;
- char *AllocMem();
- struct FileInfoBlock *File_Info;
-
- if ((File_Info = (struct FileInfoBlock *)
- AllocMem((LONG)sizeof(struct FileInfoBlock), 0L)) == NULL)
- return (FALSE);
-
- /* Fix up the trailing / if it needs it */
- last_char = &dir[strlen(dir) - 1] ;
- if (*last_char == '/') *last_char = '\0' ;
-
- /* Now, start on the directory */
- if ((my_lock = Lock(dir, ACCESS_READ)) == NULL) goto out;
-
- if (!Examine(my_lock, File_Info)) goto out;
- if (File_Info -> fib_DirEntryType < 0L)
- goto out;
-
- if (Menu_Add(name, TRUE) == 0) return NULL;
- for (count = 0; ExNext(my_lock, File_Info)
- || IoErr() != ERROR_NO_MORE_ENTRIES; count++)
- if (File_Info -> fib_DirEntryType < 0L) {
- if (Menu_Item_Add(File_Info -> fib_FileName,
- (USHORT)ITEMENABLED, 0L, (BYTE)0)
- == MNUM(NOMENU, NOITEM, NOSUB))
- break ;
- }
- else {
- (void) strcpy(Name_Buf, File_Info -> fib_FileName) ;
- (void) strcat(Name_Buf, "/") ;
- if (Menu_Item_Add(Name_Buf,
- (USHORT) ITEMENABLED, 0L, (BYTE)0)
- == MNUM(NOMENU, NOITEM, NOSUB))
- break ;
- }
- if (count == 0) Menu_Item_Add("EMPTY", (USHORT)0, 0L, (BYTE)0) ;
-
- /* Put everything back */
- if (*last_char == '\0') *last_char = '/' ;
- stat = TRUE;
- out:
- UnLock(my_lock) ;
- FreeMem(File_Info, (LONG) sizeof(struct FileInfoBlock));
- return stat;
- }
- #endif BROWSER
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-