home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-03 | 58.7 KB | 2,426 lines |
- Path: xanth!mcnc!ece-csc!ncsuvx!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ames!necntc!ncoast!allbery
- From: BLARSON@ECLA.USC.EDU (Bob Larson)
- Newsgroups: comp.sources.misc
- Subject: v03i038: mg 2a part 14 of 15
- Message-ID: <12401301436.47.BLARSON@ECLA.USC.EDU>
- Date: 26 May 88 05:03:23 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
- Lines: 2413
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 38
- Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
- Archive-Name: mg2a/Part14
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # sys/amiga/alloca.asm
- # sys/amiga/menustack.c
- # sys/amiga/offset.c
- # sys/amiga/sleep.c
- # sys/amiga/spawn.c
- # sys/amiga/sysdef.h
- # sys/amiga/sysinit.c
- # sys/amiga/tty.c
- # sys/amiga/ttydef.h
- # sys/amiga/ttyicon.c
- # sys/amiga/ttyio.c
- # This archive created: Mon May 23 18:10:12 1988
- # By: blarson
- if test -d sys
- then true
- else mkdir sys
- fi
- if test -d sys/amiga
- then true
- else mkdir sys/amiga
- fi
- cat << \SHAR_EOF > sys/amiga/alloca.asm
- *
- * alloca()
- *
- * This routine was written by Stephen Walton, swalton@solar.stanford.edu,
- * a rank asm amateur, to attempt to provide the alloca() function for Manx
- * Aztec C on the Amiga. It probably does horrible illegal things to the
- * stack but seems to mostly work.
- *
- * This subroutine expects a single int as argument, and returns a pointer
- * to a block of memory of that size allocated off the local stack. Thus,
- * this memory is automatically freed when the current subroutine exits.
- *
- * This version for the default Manx settings (int = 16 bits). To use
- * with int=32 bits, simply change both the ".w" to ".l"
- *
- xdef _alloca
- _alloca
- move.l a7,a1 ; Save current value of stack pointer
- move.w 4(a7),d0 ; Number of bytes needed
- suba.w d0,a7 ; Move stack up that many places
- move.l (a1),(a7) ; Place return address in proper place
- move.l a7,d0 ; Return value into d0
- add.l #6,d0 ; plus amount by which stack is popped
- rts ; And back we go
- SHAR_EOF
- cat << \SHAR_EOF > sys/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.
- * Modified again by MPK to allow subitems again (non-stacking), and
- * fix bug when visiting files not in last menu.
- *
- * Modified once again by MPK to avoid calling strsave() if desired. This
- * is controlled by the newly-added last parameter to *_Add(), which
- * indicates whether the menu name should be saved off by strsave().
- * I suppose *not* saving strings might break on a system where
- * MEMF_PUBLIC meant something, but I think that's far in the future...
- */
-
- #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 Screen WBInfo; /* For Screen width & Height */
- #define SCREENHEIGHT (WBInfo . Height)
- #define SCREENWIDTH (WBInfo . Width)
-
- 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 */
-
- #ifdef LATTICE
- void
- #endif
- 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;
- }
-
- #ifdef LATTICE
- void
- #endif
- 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 */
- }
-
- #ifdef LATTICE
- void
- #endif
- Menu_Pop()
- {
-
- if ((Top = RemHead(&Memory)) == NULL) return;
- 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;
- LastMenu->NextMenu = NULL; /* Tie off the menu list */
- 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, saveit)
- char *name;
- int enabled;
- int saveit;
- {
- 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 = saveit ? strsave(name) : 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, saveit)
- char *name; /* name of menu item */
- USHORT flags;
- LONG mux; /* mutual exclusion mask */
- BYTE ch; /* command sequence character, if COMMSEQ */
- int saveit; /* save name using strsave? */
- {
- 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 *)(saveit ? strsave(name) : 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, saveit)
- char *name, ch;
- USHORT flags;
- LONG mux;
- int saveit;
- {
- 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 *)(saveit ? strsave(name) : 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
- cat << \SHAR_EOF > sys/amiga/offset.c
- /*
- * Used to return number of bytes member is from start of structure type.
- * This is used because Manx 3.20a can't handle Bob's OFFSET macro
- */
-
- char *offset_dummy = 0;
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/sleep.c
- /*
- * Name: MicroEmacs
- * AmigaDOS sleep function
- * Version: 31
- * Last Edit: 18-Apr-86
- * Created: 18-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- */
-
- /* There are really 60 ticks/second, but I don't want to wait that */
- /* long when matching parentheses... */
- #define TICKS 45
- extern long Delay();
-
- #ifdef LATTICE
- void
- #endif
- sleep(n)
- int n;
- {
- if (n > 0)
- Delay((long) n * TICKS);
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/spawn.c
- /*
- * Name: MG
- * Version: 2x
- * Spawn an AmigaDOS subprocess
- * Last edit: 05-Sep-1987
- * By: ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- */
-
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #undef TRUE
- #undef FALSE
- #include "def.h" /* AFTER system files to avoid redef's */
-
- /*
- * Create a subjob with a copy of the command intrepreter in it.
- * This is really a way to get a new copy of the CLI, because
- * we don't wait around for the new process to quit. Note the use
- * of a file handle to nil: to avoid the "endcli" message going out
- * to Emacs's standard output.
- */
-
- spawncli(f, n)
- {
- struct FileHandle *nil, *Open();
-
- ewprintf("[Starting new CLI]");
- nil = Open("NIL:", MODE_NEWFILE);
- if (nil == (struct FileHandle *) 0) { /* highly unlikely */
- ewprintf("Can't create nil file handle");
- return (FALSE);
- }
- Execute("NEWCLI \"CON:0/0/640/200/MicroEmacs Subprocess\"",nil,nil);
- Close(nil);
- return (TRUE);
- }
-
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/sysdef.h
- /*
- * Name: MicroEMACS
- * Version: MG 2a
- * Commodore Amiga system header file.
- */
-
- /* Neither can lattice 4 */
- extern char *offset_dummy; /* Manx 3.2 can't handle 0-> */
- #define OFFSET(type,member) \
- ((char *)&(((type *)offset_dummy)->member)-(char *)((type *)offset_dummy))
-
- #ifdef MANX
- #define PCC 0 /* "[]" works. */
- #else
- #define PCC 1 /* "[]" does not work. */
- #endif
-
- #define VARARGS
- #define DPROMPT /* we always want delayed prompts */
- #define KBLOCK 4096 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
- #define SYSINIT sysinit() /* System-specific initialization */
- #define SYSCLEANUP syscleanup() /* System-specific cleanup */
- #define MALLOCROUND(m) (m+=7,m&=~7) /* Round up to 8 byte boundary */
- #define NULL ((char *) 0) /* These are crass, but */
- #define EOF -1 /* will work` */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
- #define BDC1 ':' /* Buffer names. */
- #define BDC2 '/'
-
-
- /*
- * Typedefs for internal key type and how big a region can be.
- */
-
- typedef short KCHAR; /* type used to represent Emacs characters */
- typedef long RSIZE; /* size of a region */
-
- #define MAXPATH 128 /* longest expected directory path */
-
- #define bcopy(src,dest,len) movmem(src,dest,len)
-
- #define fncmp Strcmp
-
- #ifndef NO_DIRED
- #define rename(s1,s2) (Rename(s1,s2) == -1 ? 0 : -1)
- #define unlinkdir(s1) (DeleteFile(s1) == -1 ? 0 : -1)
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/sysinit.c
- /*
- * Name: MG 2a
- *
- * Very early-on system-specific initialization for whatever's
- * necessary.
- * Last edit: 05-May-88, Stephen Walton, swalton@solar.stanford.edu
- * Created: Stephen Walton, 3-Dec-87.
- *
- */
- #include <libraries/dosextens.h>
- #include "sysdef.h"
-
- #undef FALSE
- #undef TRUE
- #define TRUE 1
- #define FALSE 0
-
- #ifdef USE_ARP
- struct Library *ArpBase;
- extern struct Library *OpenLibrary();
- #endif
-
- #ifndef NO_DIR
- extern struct Task *FindTask();
- static BPTR StartLock;
- char MyDirName[MAXPATH];
- extern BPTR DupLock(), CurrentDir();
- #endif NO_DIR
-
- sysinit()
- {
- long len;
- BPTR MyDirLock;
-
- #ifdef USE_ARP
- if (!(ArpBase = OpenLibrary("arp.library", 0L)))
- panic("Compiled with USE_ARP, but arp.library not found");
- #endif
- #ifndef NO_DIR
- /*
- * The following attempt to be clever assigns the external StartLock
- * to the lock on the current directory, then switches our CurrentDir
- * to a duplicate of that lock so we can restore the original lock
- * on exit.
- */
-
- StartLock = ((struct Process *)FindTask(0L))->pr_CurrentDir;
- (void) CurrentDir(MyDirLock = DupLock(StartLock));
- len = PathName(MyDirLock, MyDirName, MAXPATH/31L);
- #endif NO_DIR
- }
-
- /*
- * System dependent cleanup for the Amiga.
- */
- syscleanup()
- {
- UnLock(CurrentDir(StartLock)); /* restore startup directory */
- #ifdef USE_ARP
- if (ArpBase)
- CloseLibrary(ArpBase);
- #endif
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/tty.c
- /*
- * Name: MG 2a
- * Amiga console device virtual terminal display
- * Last Edit: 29-Nov-87 mic@emx.cc.utexas.edu
- * Created: 19-Apr-86 mic@emx.cc.utexas.edu
- *
- * Drives the Amiga console device display. The code is basically
- * like the termcap driver in that it uses the console device
- * scrolling region. It also has some hacks to manage the console
- * device colors. The latest hack is to inform the terminal I/O
- * driver when we intend to do an escape sequence; this allows the
- * terminal I/O driver to turn off the cursor without breaking up
- * the sequences, leading to a garbled screen.
- */
-
- #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>
- #ifndef MANX
- #include <intuition/intuitionbase.h>
- #endif
- #include <intuition/intuition.h>
-
- #undef TRUE
- #undef FALSE
- #include "def.h"
-
- #define BEL 0x07 /* BEL character. */
- #define ESC 0x1B /* ESC character. */
- #define LF 0x0A /* Linefeed character */
- #define CSI 0x9B /* Command Sequence Introducer */
-
- 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
-
- #ifdef LATTICE
- VOID asciiparm(int) ;
- #else
- VOID asciiparm() ;
- #endif
- VOID ttnowindow() ;
- VOID ttwindow() ;
-
- /*
- * Initialize the terminal when the editor
- * Initialize the virtual terminal.
- * Set the console device's top edge below
- * the front-to-back gadgets, to avoid
- * garbage when scrolling.
- */
- VOID
- ttinit()
- {
- ttputc(CSI);
- asciiparm(TOP_OFFSET);
- ttputc('y');
- }
-
- /*
- * Clean up the terminal, in anticipation of
- * a return to the command interpreter. This
- * is a no-op on the Amiga, since the window
- * is deleted anyway.
- */
- VOID
- 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!
- */
- VOID
- ttmove(row, col)
- {
- if (ttrow!=row || ttcol!=col) {
- ttnflush(8); /* flush if buffer too full */
- ttputc(CSI);
- asciiparm(row+1);
- ttputc(';');
- asciiparm(col+1);
- ttputc('H');
- ttrow = row;
- ttcol = col;
- }
- }
-
- /*
- * Erase to end of line.
- */
- VOID
- tteeol()
- {
- ttnflush(2); /* flush if not enough room to fit in buffer */
- ttputc(CSI);
- ttputc('K');
- }
-
- /*
- * Erase to end of page.
- */
- VOID
- tteeop()
- {
- ttnflush(12); /* flush (but only if not enough room for seq */
- ttputc(CSI);
- asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
- ttputc(';');
- asciiparm(text_fg);
- ttputc(';');
- asciiparm(text_bg);
- ttputc('m');
- ttputc(CSI); /* clear to end of display */
- ttputc('J');
- }
-
- /*
- * Make a noise.
- */
- VOID
- ttbeep()
- {
- ttputc(BEL);
- ttflush();
- }
-
- /*
- * Convert a number to decimal
- * ascii, and write it out. Used to
- * deal with numeric arguments.
- */
- VOID
- 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.
- */
- 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) {
- ttwindow(row, bot);
- ttnflush(4); /* don't break the sequence */
- ttputc(CSI);
- asciiparm(nchunk);
- ttputc('T'); /* Scroll scrolling region down */
- ttnowindow();
- }
- }
-
- /*
- * 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. It's really easy with the console
- * device scrolling region.
- */
- VOID
- ttdell(row, bot, nchunk)
- {
- if (row == bot) { /* One line special case */
- ttmove(row, 0);
- tteeol();
- return;
- }
- if (nchunk > 0) {
- ttwindow(row, bot);
- ttnflush(4); /* don't break esc. sequence */
- ttputc(CSI);
- asciiparm(nchunk);
- ttputc('S'); /* Scroll scrolling region up */
- ttnowindow();
- }
- ttrow = HUGE;
- ttcol = HUGE;
- ttmove(bot-nchunk,0);
- }
-
- /*
- * This routine sets the scrolling window on the display to go from line
- * "top" to line "bot" (origin 0, inclusive). The caller checks for the
- * pathalogical 1 line scroll window that doesn't work right on all
- * systems, and avoids it. The "ttrow" and "ttcol" variables are set
- * to a crazy value to ensure that ttmove() actually does something.
- */
-
- extern struct Window *EmW; /* The window MG uses */
-
- VOID
- ttwindow(top,bot)
- {
- if (tttop != top || ttbot != bot) {
- ttnflush(10); /* Flush if necessary */
- ttputc(CSI); /* Home cursor */
- ttputc('H');
-
- ttputc(CSI); /* Set top offset */
- asciiparm(TOP_OFFSET + top * FontHeight(EmW));
- ttputc('y');
-
- ttputc(CSI);
- asciiparm(bot - top + 1); /* Set page length */
- ttputc('t');
-
- ttrow = HUGE; /* Force cursor reset */
- ttcol = HUGE;
- tttop = top; /* Save region state */
- ttbot = bot;
- }
- }
-
- /*
- * Switch to full screen scrolling
- */
- VOID
- ttnowindow()
- {
- ttnflush(10); /* Flush if necessary */
- ttputc(CSI); /* Home cursor */
- ttputc('H');
-
- ttputc(CSI); /* Set top offset to normal */
- asciiparm(TOP_OFFSET);
- ttputc('y');
-
- ttputc(CSI); /* Set page length to nrow */
- asciiparm(nrow);
- ttputc('t');
-
- ttrow = HUGE; /* Make cursor unknown. */
- ttcol = HUGE;
- tttop = HUGE;
- ttbot = HUGE;
- }
-
- #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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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)
- {
- register int s;
- char buf[2];
-
- if (!(f & FFARG)) {
- 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.
- */
-
- VOID
- ttcolor(color)
- register int color;
- {
- if (color != tthue) {
- ttnflush(12); /* Flush if necessary */
- if (color == CTEXT) { /* Normal video. */
- ttputc(CSI); /* Reset to 0 */
- ttputc('m');
- ttputc(CSI); /* Set text style */
- asciiparm(text_rendition);
- ttputc(';');
- asciiparm(text_fg);
- ttputc(';');
- asciiparm(text_bg);
- ttputc('m');
- } else if (color == CMODE) { /* Standout mode */
- ttputc(CSI); /* Reset to 0 */
- ttputc('m');
- ttputc(CSI); /* Set standout mode */
- 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.
- */
-
- VOID
- ttresize()
- {
- setttysize();
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/ttydef.h
- /*
- * Name: MicroEMACS
- * Amiga console device virtual terminal header file
- * Version: MG 2a
- * Last edit: 28-Nov-87 ...!seismo!ut-sally!ut-ngp!mic (mic@emx.cc.utexas.edu)
- * Created: 20-Apr-86 ...!seismo!ut-sally!ut-ngp!mic
- */
-
- #define GOSLING /* Compile in fancy display. */
- #define TOP_OFFSET 11 /* # raster lines from top of window */
-
- #ifndef NROW
- #define NROW 51 /* Max rows (interlaced screen) */
- #endif
-
- #ifndef NCOL
- #define NCOL 85 /* Max cols (MoreRows, borderless) */
- #endif
-
- #ifndef LR_BORDER
- #define LR_BORDER (3 + 20) /* Vertical border size (pixels) */
- #endif
-
- #ifndef TB_BORDER
- #define TB_BORDER (TOP_OFFSET + 2) /* Horizontal border size (pixels)*/
- #endif
-
- #ifndef INIT_ROWS
- #define INIT_ROWS 24 /* Desired initial window height */
- #endif
-
- #ifndef INIT_COLS
- #define INIT_COLS 80 /* Desired initial window width */
- #endif
-
- /*
- * Function key codes (using 16-bit KEY values)
- */
- #define KFIRST 0x100
-
- #define KUP 0x100
- #define KDOWN 0x101
- #define KLEFT 0x102
- #define KRIGHT 0x103
-
- #define KSUP 0x104
- #define KSDOWN 0x105
- #define KSLEFT 0x106
- #define KSRIGHT 0x107
-
- #define KHELP 0x108
- #define KMENU 0x109
- #define KRESIZE 0x10A
-
- #define KF1 0x10C
- #define KF2 0x10D
- #define KF3 0x10E
- #define KF4 0x10F
- #define KF5 0x110
- #define KF6 0x111
- #define KF7 0x112
- #define KF8 0x113
- #define KF9 0x114
- #define KF10 0x115
-
- #define KSF1 0x116
- #define KSF2 0x117
- #define KSF3 0x118
- #define KSF4 0x119
- #define KSF5 0x11A
- #define KSF6 0x11B
- #define KSF7 0x11C
- #define KSF8 0x11D
- #define KSF9 0x11E
- #define KSF10 0x11F
-
- #define KW___MOUSE 0x120
- #define KW__CMOUSE 0x121
- #define KW_S_MOUSE 0x122
- #define KW_SCMOUSE 0x123
- #define KWA__MOUSE 0x124
- #define KWA_CMOUSE 0x125
- #define KWAS_MOUSE 0x126
- #define KWASCMOUSE 0x127
- #define KM___MOUSE 0x128
- #define KM__CMOUSE 0x129
- #define KM_S_MOUSE 0x12A
- #define KM_SCMOUSE 0x12B
- #define KMA__MOUSE 0x12C
- #define KMA_CMOUSE 0x12D
- #define KMAS_MOUSE 0x12E
- #define KMASCMOUSE 0x12F
- #define KE___MOUSE 0x130
- #define KE__CMOUSE 0x131
- #define KE_S_MOUSE 0x132
- #define KE_SCMOUSE 0x133
- #define KEA__MOUSE 0x134
- #define KEA_CMOUSE 0x135
- #define KEAS_MOUSE 0x136
- #define KEASCMOUSE 0x137
-
- #define KLAST KEASCMOUSE
-
- /*
- * Mouse key encoding stuff... The bit fields are:
- *
- * 4 3 2 1 0
- * | where | ALT | SHIFT | CTRL
- *
- * Where ALT, SHIFT, and CTRL indicate qualifiers, and the 2-bit
- * where field indicates whether the click was (initially) in a window,
- * a mode line, or the echo line. The mouse functions are smart enough
- * to remap themselves if necessary; we implement these as keys so
- * users can rebind things to their taste.
- */
- #define M_X_ZERO ' '
- #define M_Y_ZERO ' '
- #define MQ_OFFSET 0x40
- #define MQ_NOQUAL 0x00
- #define MQ_CTRL 0x01
- #define MQ_SHIFT 0x02
- #define MQ_ALT 0x04
- #define MQ_WINDOW 0x00
- #define MQ_MODE 0x08
- #define MQ_ECHO 0x10
- #define MQ_WHERE(m) (m & 0x18) /* get where field */
- #define MQ_QUALS(m) (m & 0x07) /* get qualifier field */
-
- /*
- * 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.
- */
- #define MN_OFFSET ' ' /* menu char - ' ' = real code */
- struct MenuBinding {
- char *Command;
- int (*Function)();
- };
-
- 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
- cat << \SHAR_EOF > sys/amiga/ttyicon.c
- /*
- * Name: MG 2a
- * Iconify the MG window using Leo Schwab's iconify() routine.
- * Last Edit: 07-Jan-88 mic@emx.utexas.edu
- * Created: 04-Jan-88 mic@emx.utexas.edu
- */
-
- #ifdef DO_ICONIFY
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include "iconify.h"
- #undef TRUE
- #undef FALSE
- #include "def.h"
-
- /*
- * Simple Mg 2a icon image. We need a more imaginative one.
- */
-
- UWORD mg2a[160] = {
- /* Bit Plane #0 */
-
- 0x0000,0x0000,0x0000,0x0000,
- 0x3fff,0xffff,0xffff,0xf000,
- 0x3fff,0xffff,0xffff,0xf000,
- 0x3c00,0x0000,0x0000,0xf000,
- 0x3cc1,0x8f80,0x0000,0xf000,
- 0x3ce3,0x9ce0,0x0000,0xf000,
- 0x3cf7,0xb800,0x0000,0xf000,
- 0x3cff,0xb9e0,0x0000,0xf000,
- 0x3cfb,0xb8e0,0x0000,0xf000,
- 0x3ce3,0x9ce3,0xf000,0xf000,
- 0x3ce3,0x8fe7,0x3800,0xf000,
- 0x3c00,0x0000,0x39f8,0xf000,
- 0x3c00,0x0000,0xf01c,0xf000,
- 0x3c00,0x0003,0x80fc,0xf000,
- 0x3c00,0x0007,0x3b1c,0xf000,
- 0x3c00,0x0007,0xf9ee,0xf000,
- 0x3c00,0x0000,0x0000,0xf000,
- 0x3fff,0xffff,0xffff,0xf000,
- 0x3fff,0xffff,0xffff,0xf000,
- 0x0000,0x0000,0x0000,0x0000,
-
- /* Bit Plane #1 */
-
- 0xffff,0xffff,0xffff,0xfc00,
- 0xffff,0xffff,0xffff,0xfc00,
- 0xf000,0x0000,0x0000,0x3c00,
- 0xf000,0x0000,0x0000,0x3c00,
- 0xf040,0x8000,0x0000,0x3c00,
- 0xf020,0x8420,0x0000,0x3c00,
- 0xf010,0x8800,0x0000,0x3c00,
- 0xf000,0x8820,0x0000,0x3c00,
- 0xf020,0x8820,0x0000,0x3c00,
- 0xf020,0x8420,0x1000,0x3c00,
- 0xf020,0x8021,0x0800,0x3c00,
- 0xf000,0x0000,0x0808,0x3c00,
- 0xf000,0x0000,0x1004,0x3c00,
- 0xf000,0x0000,0x8004,0x3c00,
- 0xf000,0x0001,0x0804,0x3c00,
- 0xf000,0x0000,0x0802,0x3c00,
- 0xf000,0x0000,0x0000,0x3c00,
- 0xf000,0x0000,0x0000,0x3c00,
- 0xffff,0xffff,0xffff,0xfc00,
- 0xffff,0xffff,0xffff,0xfc00
- };
-
- static struct Image iconimg = { /* Icon Image */
- 0, 0,
- 54, 20, 2,
- NULL, /* filled in later */
- 0x3, 0,
- NULL
- };
-
- /*
- * Iconify MG's window using tthide(), iconify(), and ttshow().
- */
-
- int tticon(f, n)
- {
- static UWORD iconX = 0, iconY = 0;
- UWORD *chipbitmap;
- struct Image *chipimg;
- extern short toggling;
- extern APTR AllocMem();
-
- /* copy the bitmap into chip memory */
- if (NULL == (chipbitmap = (UWORD * )
- AllocMem((ULONG) sizeof(mg2a), MEMF_CHIP | MEMF_PUBLIC))) {
- ewprintf("Can't allocate image bitmap");
- return FALSE;
- }
- bcopy((char *)mg2a, (char *)chipbitmap, (int) sizeof(mg2a));
-
- /* copy the image structure too */
- if (NULL == (chipimg = (struct Image *)
- AllocMem((ULONG) sizeof(iconimg), MEMF_CHIP | MEMF_PUBLIC))) {
- FreeMem(chipbitmap, (ULONG) sizeof(iconimg));
- ewprintf("Can't allocate image structure");
- return FALSE;
- }
- bcopy((char *)&iconimg, (char *)chipimg, (int) sizeof(iconimg));
- chipimg->ImageData = chipbitmap;
-
- /* hide the window, display the icon, then redisplay the window */
- tthide(FALSE); /* not resizing */
-
- iconify(&iconX, &iconY, chipimg->Width, chipimg->Height, NULL,
- (APTR) chipimg, (int) ICON_IMAGE); /* iconify */
- FreeMem(chipimg, (ULONG) sizeof(iconimg));
- FreeMem(chipbitmap, (ULONG) sizeof(mg2a));
-
- ttshow(FALSE); /* no resize */
- return TRUE;
- }
- #endif DO_ICONIFY
- SHAR_EOF
- cat << \SHAR_EOF > sys/amiga/ttyio.c
- /*
- * Name: MG 2a
- * Amiga terminal window I/O, with all kinds o' trimmings.
- * This module is 'way too big.
- * Last Edit: 01-Dec-87 mic@emx.cc.utexas.edu
- * Created: 21-Apr-86 mic@emx.cc.utexas.edu
- */
-
- /*
- * 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 <devices/inputevent.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>
- #include <intuition/intuitionbase.h>
- #include <libraries/diskfont.h>
-
- #undef TRUE /* avoid redefinition messages */
- #undef FALSE
- #include "def.h" /* includes sysdef.h and ttydef.h */
-
- /*
- * External Amiga functions.
- */
- 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();
- #ifndef V11
- extern LONG GetScreenData();
- #endif
- extern int OpenConsole();
- extern char *OpenLibrary();
- extern struct Window *OpenWindow();
- extern struct TextFont *OpenDiskFont();
- extern LONG RectFill();
- extern LONG ReplyMsg();
- extern LONG RawKeyConvert();
- 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
-
- #ifdef MANX
- extern int Enable_Abort; /* Do NOT allow abort! */
- #endif
-
- /*
- * External MG functions and variables
- */
- extern int quit(); /* Defined by "main.c" */
- extern char version[]; /* Version information */
- extern int ttrow; /* Current cursor row */
- extern int use_metakey; /* Do meta characters? */
-
- /*
- * Non-int internal functions. P?() is used to conditionally indicate
- * ANSI-style prototype arguments for compilers (i.e. Lattice) that
- * support them.
- */
- #ifdef LATTICE
- #define P1(a) a,
- #define P2(a,b) a,b
- #define P3(a,b,c) a,b,c
- #else
- #define P1(a)
- #define P2(a,b)
- #define P3(a,b,c)
- #endif
-
- VOID panic(P1(char *));
- VOID setttysize();
- VOID ttclose();
- VOID ttflush();
- VOID ttnflush(P1(int));
- VOID ttputc(P1(unsigned char));
-
- static VOID cleanup();
- static VOID firstwin();
- static VOID qkey(P1(KCHAR));
- #ifdef DO_MENU
- static VOID qmenu(P1(USHORT));
- #endif
- #ifdef MOUSE
- static VOID qmouse(P3(SHORT, SHORT, USHORT));
- #endif
- static VOID ttreopen(P1(int)) ;
- static VOID setmaxima() ;
- static struct Screen *wbscreen();
-
- /*
- * Library bases (used by glue libraries)
- */
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- ULONG DiskfontBase;
-
- /*
- * Intuition window and menu variables. MG gets used a lot, because it
- * gets reconfigured on the fly for the amiga-set-font and toggle-border
- * operations.
- */
-
- #define WINDOWGADGETS (WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE)
- #define WINDOWFLAGS (WINDOWGADGETS | ACTIVATE)
-
- struct NewWindow MG = {
- 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
- INTUITICKS | RAWKEY |
- 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 */
- 220,40, /* minimum size (small!) */
- 0, 0, /* maximum size (set by ttopen) */
- WBENCHSCREEN /* screen in which to open */
- };
-
- static short borderless = TRUE; /* Flag for borderless window */
- static short toggle_zooms = TRUE; /* Does toggling border zoom? */
- static int last_top, last_left, last_height, last_width;
-
- struct Window *EmW = NULL; /* Our window */
- struct Screen *EmS = NULL; /* Our screen (usually WB) */
- short toggling = FALSE; /* Prevent menu wiping */
- #ifndef V11
- struct Screen WBInfo; /* Info about the WB screen */
- #endif
- struct TextFont *EmFont = NULL; /* Our font (usually TOPAZ_xx) */
-
- #ifdef DO_MENU
- static struct Menu *EmacsMenu = NULL; /* Our menu */
- #endif
-
- static ULONG class; /* Intuition event */
- static USHORT code, /* information */
- qualifier;
- static APTR address;
- static SHORT x, y;
- static LONG intuitionMsgBit; /* Signal bit */
- #define INTUITION_MESSAGE ((LONG) (1L << intuitionMsgBit))
-
- /* * * * * * * * * * * * * console I/O * * * * * * * * * * * * * * * * */
-
- #define CSI 0x9b /* Command Sequence Introducer */
- #define NOBUF 512 /* About 1/4 screen */
- #define NIBUF 256 /* Input buffer */
-
- static KCHAR ibuf[NIBUF]; /* keyboard input buffer */
- static int ibufo, nibuf; /* head, # of bytes in ibuf */
-
- #ifndef PROMPTWAIT
- #define PROMPTWAIT 20 /* ticks to wait before timeout */
- #endif
- static LONG tickcount; /* # intuiticks since last char */
-
- static struct MsgPort *conWritePort = NULL; /* I/O ports */
- static struct IOStdReq *conWriteMsg = NULL; /* I/O messages */
- struct Device *ConsoleDevice; /* used by RawKeyConvert*/
- static unsigned char outbuf[NOBUF+7]; /* output buffer */
- static unsigned char *obuf; /* first output char */
- int nobuf; /* # of bytes in above */
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, cols. */
-
- /* * * * * * * * * functions to open/reopen the window * * * * * * * * * */
-
- /*
- * Open up the virtual terminal MG communicates with. Set up the window,
- * console, and menu strip.
- */
-
- ttopen()
- {
-
- #ifdef MANX
- Enable_Abort = 0; /* Disable ^C */
- #endif
-
- /* firstwin() is only called the very first time we open the window */
- if (toggling == FALSE)
- firstwin();
-
- /* Set the window size, set the flags and title, and open it */
-
- setmaxima();
- MG.Flags = WINDOWFLAGS;
- MG.Flags |= borderless ? BORDERLESS : WINDOWSIZING;
- MG.Title = (UBYTE *) &version[0];
-
- if ((EmW = OpenWindow(&MG)) == NULL)
- cleanup();
- SetFont(EmW->RPort, EmFont);
-
- /* Once the window is created, get the Intuition signal bit, set up
- * the menu, and tell the virtual terminal how big it is.
- */
- setttysize();
- intuitionMsgBit = EmW->UserPort->mp_SigBit;
- #ifdef DO_MENU
- if (toggling == FALSE)
- EmacsMenu = InitEmacsMenu(EmW);
- if (EmacsMenu == NULL)
- cleanup();
- SetMenuStrip(EmW, EmacsMenu);
- #endif
-
- /* Attach a console device (purely for output now) to our window
- */
-
- if ((conWritePort = CreatePort("Emacs.con.write", 0L)) == NULL)
- cleanup();
- if ((conWriteMsg = CreateStdIO(conWritePort)) == NULL)
- cleanup();
-
- if (OpenConsole(conWriteMsg,NULL,EmW) != 0)
- cleanup();
-
- ConsoleDevice = conWriteMsg->io_Device;
- nibuf = ibufo = 0;
-
- return (0);
- }
-
- /*
- * Set up the initial state of the window. Opens up libraries, decides how
- * big the initial window should be, and whether it should be borderless.
- */
-
- static VOID firstwin()
- {
- GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L);
- if (GfxBase == NULL) /* Graphics lib */
- cleanup();
-
- IntuitionBase = (struct IntuitionBase *) /* Intuition */
- OpenLibrary("intuition.library", 0L);
- if (IntuitionBase == NULL)
- cleanup();
-
- DiskfontBase = (ULONG) OpenLibrary("diskfont.library", 0L);
- if (DiskfontBase == NULL)
- cleanup();
-
- /* Get our screen and font, then figure out if we can go borderless
- */
- if ((EmS = wbscreen()) == NULL)
- cleanup();
- EmFont = OpenDiskFont(EmS->Font);
- if ((EmS->Width >= ((INIT_COLS * EmFont->tf_XSize) + LR_BORDER)) &&
- (EmS->Height >= ((INIT_ROWS * EmFont->tf_YSize) + TB_BORDER)))
- borderless = FALSE;
-
- /* Set the size of the initial window and fake the last one
- */
- last_width = MG.Width = EmS->Width;
- last_height = MG.Height = EmS->Height;
- last_left = MG.LeftEdge = 0;
- last_top = MG.TopEdge = 0;
-
- bcopy(outbuf,"\x9b0 p", 4); /* preload cursor off sequence */
- obuf = outbuf + 4;
- }
-
- /*
- * Make sure the window isn't bigger than NROW * NCOL, while accounting
- * for borders & such. Since the window might not be at its largest right
- * now, deadstop both the current width and the maxwidth.
- */
-
- static VOID setmaxima()
- {
- register int maxw, maxh;
-
- MG.MaxWidth = EmS->Width;
- MG.MaxHeight = EmS->Height;
- maxw = NCOL * EmFont->tf_XSize + (borderless ? 0 : LR_BORDER);
- maxh = NROW * EmFont->tf_YSize + (borderless ? TOP_OFFSET : TB_BORDER);
-
- if (MG.MaxWidth > maxw) MG.MaxWidth = maxw;
- if (MG.Width > maxw) MG.Width = maxw;
-
- if (MG.MaxHeight > maxh) MG.MaxHeight = maxh;
- if (MG.Height > maxh) MG.Height = maxh;
- }
-
-
- /* Return a pointer the workbench screen, using GetScreenData() to do
- * things like a good citizen. Left the V11 code in as a reminder
- * that what works is not always the _best_ way to do things.
- * Thanks to Tom Rokicki for reminding me (mpk) this had to be done.
- */
-
- static struct Screen
- *wbscreen()
- {
- #ifndef V11
- return GetScreenData(&WBInfo, (ULONG) sizeof(WBInfo),
- WBENCHSCREEN, NULL) ? &WBInfo : ((struct Screen *)NULL);
- #else
- register struct Screen *s;
- Forbid();
- for (s = IntuitionBase->FirstScreen; s ; s = s->NextScreen)
- if ((s->Flags & SCREENTYPE) == WBENCHSCREEN)
- break;
- Permit();
- return (s);
- #endif
- }
-
- /*
- * Hide the window and open it up again. If resize is TRUE, they're
- * being called as part of a resize operation, so assume that the
- * NewWindow structure is set correctly. Otherwise, store the current
- * window size and position in the NewWindow structure.
- *
- * These two functions are split so we can do things like ttreopen() and
- * tticon() cleanly.
- */
-
- VOID
- tthide(resize)
- int resize;
- {
- toggling = TRUE;
- if (resize == FALSE) { /* if we're resizing, */
- MG.LeftEdge = EmW->LeftEdge; /* use current window size */
- MG.TopEdge = EmW->TopEdge;
- MG.Width = EmW->Width;
- MG.Height = EmW->Height;
- }
- ttclose(); /* reset to zero */
- }
-
- VOID
- ttshow(resize)
- int resize;
- {
- ttopen(); /* re-open tty window */
- ttinit(); /* re-initalize tty */
- sgarbf = TRUE; /* screen was trashed */
- if (resize == TRUE)
- nrow = ncol = -1; /* trash screen size */
- refresh(); /* and redraw it */
- toggling = FALSE; /* Ok, done */
- }
-
- /*
- * ttreopen() was split into the two functions above when tticon()
- * was introduced.
- */
-
- static VOID
- ttreopen(resize)
- int resize;
- {
- tthide(resize);
- ttshow(resize);
- }
-
- /* * * * * * * * * * * * functions to close the window * * * * * * * * */
-
- /*
- * Close the virtual terminal. If toggling, don't release all
- * the other resources we've allocated.
- */
- VOID
- ttclose()
- {
- ttflush();
- CloseDevice(conWriteMsg);
- DeleteStdIO(conWriteMsg); conWriteMsg = NULL;
- DeletePort(conWritePort); conWritePort = NULL;
- #ifdef DO_MENU
- ClearMenuStrip(EmW);
- #endif
- CloseWindow(EmW);
- if (toggling == FALSE)
- cleanup(); /* clean up everything */
- #ifdef MANX
- Enable_Abort = 1;
- #endif
- }
-
-
- /*
- * Clean up. Done only when we're really closing up shop
- */
-
- static VOID
- cleanup()
- {
- if (conWriteMsg) DeleteStdIO(conWriteMsg);
- if (conWritePort) DeletePort(conWritePort);
- #ifdef DO_MENU
- if (EmacsMenu) DisposeMenus(EmacsMenu);
- #endif
- if (EmFont) CloseFont(EmFont);
- if (DiskfontBase) CloseLibrary(DiskfontBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GfxBase) CloseLibrary(GfxBase);
- }
-
- /* * * * * * * * functions that diddle the window and reopen it * * * * * */
-
- /*
- * Toggle between a borderless window and a sizeable window. This lets you
- * use the whole screen if you want. Bound to "amiga-toggle-border".
- */
-
- togglewindow(f, n)
- {
-
- if ((borderless = !borderless) == TRUE) {/* *always* save last */
- last_top = EmW->TopEdge; /* bordered window size */
- last_left = EmW->LeftEdge;
- last_width = EmW->Width;
- last_height = EmW->Height;
- }
-
- if (toggle_zooms == FALSE) { /* just use current size */
- ttreopen(FALSE);
- return (TRUE);
- }
-
- /* zooming -- if borderless, go as big as possible. If
- * bordered, set to last saved value of bordered window
- */
- if (borderless) {
- MG.LeftEdge = 0;
- MG.TopEdge = 0;
- MG.Width = MG.MaxWidth;
- MG.Height = MG.MaxHeight;
- } else {
- MG.LeftEdge = last_left;
- MG.TopEdge = last_top;
- MG.Width = last_width;
- MG.Height = last_height;
- }
- ttreopen(TRUE); /* open with new size */
- return (TRUE);
- }
-
- /*
- * Modify the action of "amiga-toggle-border", reporting outcome to user.
- * Bound to "amiga-zoom-mode".
- */
- togglezooms(f, n)
- {
- toggle_zooms = !toggle_zooms;
- ewprintf("Toggling border %s",
- toggle_zooms ? "expands window to screen size" :
- "retains current window size");
- return (TRUE);
- }
-
- #ifdef CHANGE_FONT
- /*
- * Select a different font for the MG window. This 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 11
- * under 1.2) to edit with.
- */
-
- setfont(f, n)
- {
- register int s, size;
- register struct TextFont *newfont;
- char fontname[80], fontpath[84], fontsize[3];
- struct TextAttr ta;
-
- /* If negative size, reset to default font
- */
- if ((f & FFARG) && (n <= 0)) {
- CloseFont(EmFont); /* return old font */
- EmFont = OpenDiskFont(EmS->Font); /* screen's default */
- ttreopen(FALSE); /* no resize */
- ewprintf("Now using default font");
- return (TRUE);
- }
-
- if ((s = ereply("Font name: ",fontname, sizeof(fontname))) != TRUE)
- return (s);
- strcpy(fontpath,fontname);
- strncat(fontpath,".font",sizeof(fontpath));/* make name */
-
- /* Get font size */
- if (f & FFARG)
- size = n;
- else {
- if ((s = ereply("Font size: ",
- fontsize, sizeof(fontsize))) != TRUE)
- return (s);
- size = atoi(fontsize);
- }
-
- /* Set up text attributes */
- ta.ta_Name = (UBYTE *)fontpath;
- ta.ta_YSize = size;
- ta.ta_Style = FS_NORMAL;
- ta.ta_Flags = 0;
-
- /* 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);
- }
-
- /* 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 reopen with the new one */
- CloseFont(EmFont);
- EmFont = newfont;
- ttreopen(FALSE);
- ewprintf("Now using font %s %d",fontname,EmFont->tf_YSize);
- return (TRUE);
- }
- #endif
-
- /* * * * * * * * * * * * * console output functions * * * * * * * * * * * * */
-
- /*
- * Write a single character to the screen. Buffered for speed, so ttflush()
- * does all the work.
- */
- VOID
- ttputc(c)
- unsigned char c;
- {
- obuf[nobuf++] = c;
- if (nobuf >= NOBUF)
- ttflush();
- }
-
- /*
- * Flush characters from the output buffer. If the # of characters is
- * greater than a certain ad-hoc value, turn the cursor off while doing
- * the write. To avoid extra writes, the output buffer has been preloaded
- * with the cursor-off sequence. Outbuf is large enough to hold the extra
- * 7 characters.
- */
- #define MIN_OFF 8
- VOID
- ttflush()
- {
- if (nobuf > 0) {
- if (nobuf <= MIN_OFF) /* don't turn off for short writes */
- ConWrite(conWriteMsg, obuf, nobuf);
- else {
- obuf[nobuf++] = '\x9b';
- obuf[nobuf++] = ' ';
- obuf[nobuf++] = 'p';
- ConWrite(conWriteMsg, outbuf, nobuf + 4);
- }
- nobuf = 0;
- }
- }
-
- /*
- * The caller intends to output an escape sequence, but only flush
- * the buffer if there's not enough room to hold the complete sequence.
- * This avoids breaking up escape sequences when we turn the cursor
- * off in ttflush(), at the expense of some extra function calls.
- */
- VOID ttnflush(n)
- int n;
- {
- if ((nobuf + n) > NOBUF)
- ttflush();
- }
-
- /* * * * * * * * * * * * * console input functions * * * * * * * * * * * * */
-
- /*
- * Read a character (really a KCHAR, > 8 bits), blocking till a character
- * is put in the input buffer and can be returned.
- */
- ttgetc()
- {
- return handle_kbd(FALSE);
- }
-
- /*
- * Return TRUE if we've waited for 2 seconds and nothing has happened,
- * else return false.
- */
-
- ttwait()
- {
- return handle_kbd(TRUE); /* time out after 2 sec */
- }
-
- /*
- * Common routine for handling character input, with and without timeout.
- * Handle events until:
- *
- * 1) a character is put in the input buffer
- * 2) if timeout == TRUE, PROMPTWAIT IntuiTicks have gone by
- *
- * If timeout == FALSE, the input character is returned and removed from
- * the input buffer.
- *
- * If timeout == TRUE, returns TRUE if the read timed out, else FALSE.
- * Leaves any character typed in the input buffer.
- */
-
- static handle_kbd(timeout)
- register int timeout;
- {
- register struct IntuiMessage *message; /* IDCMP message */
- register LONG wakeupmask; /* which signals? */
- register int charfound; /* got a character yet? */
- KCHAR k;
-
- tickcount = 0; /* *always* zero the count */
- if (nibuf) /* any chars? return if so */
- return timeout ? FALSE : nextkey();
-
- charfound = FALSE; /* nope -- have to wait */
- do {
- wakeupmask = Wait(INTUITION_MESSAGE);
-
- /* Handle Intuiticks specially for speed */
- while(message = GetMsg(EmW->UserPort))
- if (message->Class == INTUITICKS) {
- tickcount++;
- ReplyMsg(message);
- } else if (dispatch(message) == TRUE)
- charfound = TRUE;
-
- /* time out if enough ticks have gone by without
- * any keyboard input. We do this *after* all the
- * events in the current list have been dispatched.
- */
- if (timeout && (tickcount > PROMPTWAIT))
- break;
- } while (charfound == FALSE);
-
-
- /* If called by ttwait(), return FALSE if a character was found.
- * Else return the next character in the input buffer
- */
- return timeout ? (!charfound) : nextkey();
- }
-
- /*
- * Handle the events we handle... The result returned indicates if we've put
- * a character in the input buffer.
- */
- #ifdef DO_METAKEY
- #define IEQUALIFIER_ALT (IEQUALIFIER_RALT | IEQUALIFIER_LALT)
- #endif
-
- 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;
-
- static struct InputEvent FakedEvent = { NULL, IECLASS_RAWKEY, 0, 0, 0 };
- unsigned char keybuf[64], altbuf[64];
- int keylen, altlen, i;
- #ifndef V11
- APTR deadcodes;
- #endif
-
- 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;
- #ifndef V11
- if (class == RAWKEY) /* get dead key info */
- deadcodes = (APTR) *address;
- #endif
- ReplyMsg(msg); /* return it to Intuition */
-
- switch(class) { /* see what the fuss is about */
- case RAWKEY:
- FakedEvent.ie_Code = code;
- FakedEvent.ie_Qualifier = qualifier;
- #ifndef V11
- FakedEvent.ie_EventAddress = deadcodes;
- #endif
- keylen = (int) RawKeyConvert(&FakedEvent,
- keybuf, (LONG)sizeof(keybuf), NULL);
-
- #ifdef DO_METAKEY
- /* Special mapping for ALT-ed keys. The intent is to get
- * around keymaps where the ALT'ed characters map to
- * things other than (0x80 | (c)). This may not work
- * for all possible keymaps, but it seems to be ok
- * for the keymaps distributed with 1.2.
- */
- if ((qualifier & IEQUALIFIER_ALT) && use_metakey) {
- FakedEvent.ie_Qualifier &= ~IEQUALIFIER_ALT;
- altlen = (int) RawKeyConvert(&FakedEvent, altbuf,
- (LONG)sizeof(altbuf), NULL);
- if (altlen == 1)
- altbuf[0] |= 0x80;
- for (i = 0; i < altlen ; i++)
- qkey((KCHAR) altbuf[i]);
- return (altlen > 0) ? TRUE : FALSE;
- }
- #endif
- /* non-ALTed key */
- for (i = 0; i < keylen; i++)
- qkey((KCHAR) keybuf[i]);
- return (keylen > 0) ? TRUE : FALSE;
- break;
-
- #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 KMENU 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.
- * I may break down and do this asynchronously...
- */
- qkey(KRESIZE);
- return (TRUE); /* we done (finally) */
- break;
-
- case CLOSEWINDOW:
- /* Calling quit() directly is not a guaranteed win. */
- quit(FFRAND, 1);
- return (FALSE);
- break;
-
- default:
- panic("HandleMsg: unknown event!!!");
- break;
- }
- return(FALSE);
- }
-
- /*
- * 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.
- */
- VOID
- setttysize()
- {
- nrow = (EmW->Height - TOP_OFFSET
- - 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.
- */
- VOID
- 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 *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /*
- * Return next key in the input buffer, if any available. Returns -1 if not.
- */
- static int
- nextkey()
- {
- register KCHAR k;
-
- if (nibuf <= 0) { /* shouldn't happen, but could... */
- nibuf = 0;
- return -1;
- } else {
- k = ibuf[ibufo++];
- nibuf--;
- ibufo %= NIBUF;
- return (int) k;
- }
- }
-
- /*
- * Return true if there are some characters available in the input buffer.
- */
- typeahead()
- {
- return (nibuf > 0);
- }
-
- /*
- * Add a key to the input queue
- */
- static VOID
- qkey(k)
- KCHAR k;
- {
- if (nibuf < NIBUF)
- ibuf[(ibufo + nibuf++) % NIBUF] = k;
- }
-
- #ifdef MOUSE
- /*
- * Add a mouse event to the input queue, calculating the row and column
- * value from the current height and width of the window's font.
- */
-
- static VOID
- qmouse(x, y, qual)
- SHORT x, y;
- USHORT qual;
- {
- register int myqual = MQ_NOQUAL;
- register int row, col;
- register WINDOW *wp;
-
- /* get row, column */
- col = (x - EmW->BorderLeft) / FontWidth(EmW);
- row = (y - TOP_OFFSET) / FontHeight(EmW);
-
- /* find out which kind of window was clicked in */
- for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
- if ((row >= wp->w_toprow) &&
- (row <= (wp->w_toprow + wp->w_ntrows)))
- break;
- if (wp == NULL)
- myqual |= MQ_ECHO;
- else if (row == (wp->w_toprow + wp->w_ntrows))
- myqual |= MQ_MODE;
- else
- myqual |= MQ_WINDOW;
-
- /* figure out qualifiers */
- if (qual & IEQUALIFIER_CONTROL)
- myqual |= MQ_CTRL;
- if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_LSHIFT))
- myqual |= MQ_SHIFT;
- if (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
- myqual |= MQ_ALT;
-
- /*
- * Queue up the whole mess. If user didn't click in the echo
- * line, transmit the x, y values to the mouse function
- */
- qkey(KW___MOUSE + myqual);
- if (MQ_WHERE(myqual) != MQ_ECHO) {
- qkey(M_X_ZERO + col);
- qkey(M_Y_ZERO + row);
- }
- }
- #endif
-
- #ifdef DO_MENU
- /*
- * Add a menu event to the queue.
- */
- static VOID
- qmenu(code)
- USHORT code;
- {
- qkey(KMENU); /* menu key sequence */
- qkey(((KCHAR) MENUNUM(code)) + MN_OFFSET);
- qkey(((KCHAR) ITEMNUM(code)) + MN_OFFSET);
- qkey(((KCHAR) SUBNUM(code)) + MN_OFFSET);
- }
- #endif
- SHAR_EOF
- # End of shell archive
- exit 0
- -------
-