home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header * Header built automatically - do not edit! *************
- *
- * (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
- *
- * Name .....: Console.c
- * Created ..: Monday 21-Jan-91 20:12
- * Revision .: 1
- *
- * Date Author Comment
- * ========= ======== ====================
- * 14-Apr-91 Olsen Rewrote double-dead-key support.
- * 05-Feb-91 Olsen Added double-dead-key support.
- * 21-Jan-91 Olsen Created this file!
- *
- * $Revision Header ********************************************************/
-
- #include "TermGlobal.h"
-
- /* Capture(APTR Buffer,LONG Size):
- *
- * Send the buffer contents to the display/disk capture.
- */
-
- VOID
- Capture(APTR Buffer,LONG Size)
- {
- struct MenuItem *SomeItem;
-
- /* We are parsing a control sequence, don't buffer it! */
-
- if(!InSequence)
- StoreBuffer(Buffer,Size);
-
- /* Write to capture file. */
-
- if(FileCapture)
- {
- if(!FWrite(FileCapture,Buffer,Size,1))
- {
- BlockWindows();
-
- /* We had an error writing to the file. */
-
- switch(MyEasyRequest(NULL,"Error writing to capture\nfile %s!","Ignore Error|Close & Discard File|Close File",CaptureName))
- {
- case 0: break;
-
- case 1: Close(FileCapture);
-
- DeleteFile(CaptureName);
-
- if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
- SomeItem -> Flags &= ~CHECKED;
-
- FileCapture = NULL;
-
- break;
-
- case 2: Close(FileCapture);
-
- if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
- SomeItem -> Flags &= ~CHECKED;
-
- FileCapture = NULL;
-
- if(!GetFileSize(CaptureName))
- DeleteFile(CaptureName);
-
- break;
- }
-
- ReleaseWindows();
- }
- }
-
- /* Send the buffer to the printer (ignore ANSI control
- * sequences).
- */
-
- if(PrinterCapture)
- {
- if(*((UBYTE *)Buffer) != '\033' && !InSequence)
- {
- if(!FWrite(FileCapture,Buffer,Size,1))
- {
- BlockWindows();
-
- if(!MyEasyRequest(NULL,"Error writing to printer!","Ignore Error|Close Printer"))
- {
- Close(PrinterCapture);
-
- if(SomeItem = FindThisItem(MEN_CAPTUREPRINTER))
- SomeItem -> Flags &= ~CHECKED;
-
- PrinterCapture = NULL;
- }
-
- ReleaseWindows();
- }
- }
- }
- }
-
- /* HandleCursor(UBYTE Char):
- *
- * This routine handles the somewhat strange behaviour of
- * an assorted set of keys in VT100 applications mode.
- */
-
- BYTE
- HandleCursor(UBYTE Char)
- {
- STATIC struct
- {
- UBYTE Char;
- UBYTE *VanillaString;
- UBYTE *ApplicationString;
- } Table[18] =
- {
- CUP, "\033[A", "\033OA",
- CDN, "\033[B", "\033OB",
- CFW, "\033[C", "\033OC",
- CBK, "\033[D", "\033OD",
-
- '0', "0", "\033Op",
- '1', "1", "\033Oq",
- '2', "2", "\033Or",
- '3', "3", "\033Os",
- '4', "4", "\033Ot",
- '5', "5", "\033Ou",
- '6', "6", "\033Ov",
- '7', "7", "\033Ow",
- '8', "8", "\033Ox",
- '9', "9", "\033Oy",
- '-', "-", "\033Om",
- '*', "*", "\033Ol",
- '.', ".", "\033On",
- '\r', "\r", "\033OM"
- };
-
- BYTE i;
-
- /* Look for the cursor keys first. */
-
- for(i = 0 ; i < 4 ; i++)
- {
- if(Table[i] . Char == Char)
- {
- if(Config . CursorApp)
- SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
- else
- SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
-
- return(TRUE);
- }
- }
-
- /* Then take a look at the numeric pad. */
-
- for(i = 4 ; i < 18 ; i++)
- {
- if(Table[i] . Char == Char)
- {
- if(Config . NumApp)
- SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
- else
- {
- if(i == 17)
- {
- switch(Config . SendCR)
- {
- case CR_IGNORE: break;
-
- case CR_ASCR: SerWrite("\r",1);
- break;
-
- case CR_ASCRLF: SerWrite("\r\n",2);
- break;
- }
- }
- else
- SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
- }
-
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* DoBackspace():
- *
- * Special function: perform backspace.
- */
-
- VOID
- DoBackspace()
- {
- Capture("\b",1);
-
- if(CursorX)
- {
- ClearCursor();
-
- CursorX--;
-
- /* If destructive, shift the remaining line
- * one character to the right.
- */
-
- if(Config . DestructiveBackspace)
- {
- BackupRender();
-
- SetBPen(RPort,0);
-
- RasterEraseCharacters(1);
-
- ScrollRaster(RPort,8,0,CursorX * 8,CursorY * 8,Window -> Width - 1,(CursorY + 1) * 8 - 1);
-
- BackupRender();
- }
-
- SetCursor();
- }
- }
-
- /* Raise(UWORD Colour):
- *
- * Make an RGB value brighter.
- */
-
- STATIC UWORD
- Raise(UWORD Colour)
- {
- SHORT r,g,b;
-
- r = ((Colour >> 8) & 0xF) + 4;
- g = ((Colour >> 4) & 0xF) + 4;
- b = ((Colour ) & 0xF) + 4;
-
- if(r > 15)
- r = 15;
-
- if(g > 15)
- g = 15;
-
- if(b > 15)
- b = 15;
-
- return(r << 8 | g << 4 | b);
- }
-
- /* VisualBeep():
- *
- * `Beep' the screen visually.
- */
-
- STATIC BYTE
- VisualBeep()
- {
- struct UCopList *UserCopperList;
-
- /* Create a user copper list. */
-
- if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_PUBLIC|MEMF_CLEAR))
- {
- SHORT i;
-
- /* Initialize for 35 commands. */
-
- CINIT(UserCopperList,2 + 16 + 16 + 1);
-
- /* Wait until first line of window. */
-
- CWAIT(UserCopperList,Window -> TopEdge,0);
-
- /* Set the light colours. */
-
- for(i = 0 ; i < 16 ; i++)
- CMOVE(UserCopperList,custom . color[i],Raise(GetRGB4(Screen -> ViewPort . ColorMap,i)));
-
- /* Wait until bottom of window. */
-
- CWAIT(UserCopperList,Window -> TopEdge + Window -> Height - 1,0);
-
- /* Set the standard colours. */
-
- for(i = 0 ; i < 16 ; i++)
- CMOVE(UserCopperList,custom . color[i],GetRGB4(Screen -> ViewPort . ColorMap,i));
-
- /* Finish list. */
-
- CEND(UserCopperList);
-
- /* Lock the screen. */
-
- LockLayers(&Screen -> LayerInfo);
-
- /* Install user copper list... */
-
- Screen -> ViewPort . UCopIns = UserCopperList;
-
- /* ...and display it. */
-
- RethinkDisplay();
-
- return(TRUE);
- }
- }
-
- /* DoSomeBeep():
- *
- * Special function: beep the terminal.
- */
-
- VOID
- DoSomeBeep()
- {
- /* Handle the visual part. */
-
- if(Config . VisibleBell)
- {
- if(VisualBeep())
- {
- if(Config . AudibleBell)
- Beep();
-
- Delay(25);
-
- /* Remove the copper list. */
-
- FreeVPortCopLists(&Screen -> ViewPort);
-
- /* Really remove it. */
-
- RemakeDisplay();
-
- /* Unlock screen layers. */
-
- UnlockLayers(&Screen -> LayerInfo);
- }
- else
- {
- if(Config . AudibleBell)
- Beep();
- }
- }
- else
- {
- /* Let it beep. */
-
- if(Config . AudibleBell)
- Beep();
-
- Delay(25);
- }
-
- if(!Config . CaptureFilter)
- Capture("\a",1);
- }
-
- /* DoLF():
- *
- * Special function: perform line feed.
- */
-
- VOID
- DoLF()
- {
- ClearCursor();
-
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- }
-
- /* DoIgnore():
- *
- * Special function: don't do anything.
- */
-
- VOID
- DoIgnore()
- {
- }
-
- /* DoCR_LF():
- *
- * Special function: perform carriage return and line feed.
- */
-
- VOID
- DoCR_LF()
- {
- ClearCursor();
-
- CursorX = 0;
-
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
-
- if(Config . CaptureFilter)
- Capture("\n",1);
- else
- Capture("\r\n",2);
- }
-
- /* DoFF():
- *
- * Special function: perform form feed.
- */
-
- VOID
- DoFF()
- {
- ClearCursor();
-
- if(Config . NewLine)
- {
- CursorX = 0;
-
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
-
- if(Config . CaptureFilter)
- Capture("\n",1);
- else
- Capture("\r\n",2);
- }
- else
- {
- EraseScreen("2");
-
- CursorX = CursorY = 0;
-
- SetCursor();
-
- if(Config . CaptureFilter)
- Capture("\n",1);
- else
- Capture("\f",1);
- }
- }
-
- /* DoLF_FF_VT():
- *
- * Special function: handle line feed, form feed and vertical
- * tab.
- */
-
- VOID
- DoLF_FF_VT()
- {
- if(Config . NewLine)
- DoCR_LF();
- else
- DoLF();
- }
-
- /* DoCR():
- *
- * Special function: handle carriage return.
- */
-
- VOID
- DoCR()
- {
- if(Config . NewLine)
- DoCR_LF();
- else
- {
- ClearCursor();
-
- CursorX = 0;
-
- SetCursor();
-
- if(Config . CaptureFilter)
- Capture("\n",1);
- else
- Capture("\r",1);
- }
- }
-
- /* DoTab():
- *
- * Special function: handle tab, move cursor to next
- * tab stop.
- */
-
- VOID
- DoTab()
- {
- ClearCursor();
-
- if(CursorX < LastColumn)
- {
- SHORT i;
-
- for(i = CursorX + 1 ; i <= LastColumn ; i++)
- {
- if(TabStops[i])
- {
- CursorX = i;
-
- SetCursor();
-
- Capture("\t",1);
-
- return;
- }
- }
- }
-
- Capture("\t",1);
-
- CursorX = 0;
-
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
- }
- }
-
- /* SpillTheBeans(UBYTE *Buffer,LONG Size):
- *
- * Output a buffer of given size to the terminal
- * window.
- */
-
- VOID
- SpillTheBeans(UBYTE *Buffer,LONG Size)
- {
- /* The slow method: insert characters at of the
- * initial cursor position and shift the remaining
- * screen characters to the right.
- */
-
- if(Config . InsertChar)
- {
- /* Do we still have a character in the
- * magnificient buffer?
- */
-
- while(Size--)
- {
- /* Shift the character(s) over. */
-
- if(CursorX != LastColumn)
- {
- RasterShiftChar();
-
- ShiftChar();
- }
-
- /* The cursor hasn't hit the right
- * margin, has it? So let's print a
- * single character.
- */
-
- ClearCursor();
-
- if(CursorX++ <= LastColumn)
- {
- /* Real-time font scaling
- * enabled?
- */
-
- if(Config . FontScale)
- {
- if(CursorX != LastColumn)
- {
- RasterShiftChar();
-
- ShiftChar();
- }
-
- CursorX--;
-
- PrintScaled(*Buffer++);
- }
- else
- {
- RasterPutString(Buffer,1);
-
- Text(RPort,Buffer,1);
-
- Buffer++;
- }
- }
- else
- {
- /* Cursor is positioned at
- * the right hand side of the
- * display. If auto-wrap is
- * enabled, perform some
- * kind of CR/LF, else leave
- * the cursor where it is.
- */
-
- if(Config . AutoWrap)
- {
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- CursorY++;
-
- Capture("\n",1);
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- CursorY++;
-
- Capture("\n",1);
- }
-
- CursorX = 0;
- }
- else
- CursorX = LastColumn;
- }
-
- SetCursor();
- }
- }
- else
- {
- /* Do we still have a character in the
- * magnificient buffer?
- */
-
- while(Size > 0)
- {
- /* Cursor is positioned at
- * the right hand side of the
- * display. If auto-wrap is
- * enabled, perform some
- * kind of CR/LF, else leave
- * the cursor where it is and
- * quit the show.
- */
-
- ClearCursor();
-
- if(CursorX > LastColumn)
- {
- if(Config . AutoWrap)
- {
- CursorX = 0;
-
- if(UseRegion)
- {
- if(CursorY == Bottom)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
-
- Capture("\n",1);
- }
- else
- {
- if(CursorY == LastLine)
- ScrollRegion(8);
- else
- {
- CursorY++;
-
- SetCursor();
- }
-
- Capture("\n",1);
- }
- }
- else
- {
- CursorX = LastColumn;
-
- SetCursor();
-
- return;
- }
- }
- else
- {
- /* Real-time font scaling
- * enabled?
- */
-
- if(Config . FontScale)
- {
- while(CursorX <= LastColumn && Size)
- {
- PrintScaled(*Buffer++);
-
- Size--;
- }
-
- SetCursor();
- }
- else
- {
- SHORT Offset;
-
- /* We won't have to take
- * care of characters to shift.
- * We'll collect as many
- * characters in the buffer as will
- * fit into the current line
- * and print them.
- */
-
- if((Offset = LastColumn + 1 - CursorX) > Size)
- Offset = Size;
-
- RasterPutString(Buffer,Offset);
-
- Text(RPort,Buffer,Offset);
-
- Size -= Offset;
-
- CursorX += Offset;
-
- SetCursor();
- }
- }
- }
- }
- }
-
- /* ConWrite(APTR Buffer,LONG Size):
- *
- * Write a string to the console window.
- */
-
- VOID
- ConWrite(APTR Buffer,LONG Size)
- {
- STATIC UBYTE StringBuffer[200],BufSize = 0;
- UBYTE *Char = Buffer;
-
- /* Run down the buffer. */
-
- while(Size--)
- {
- /* Are we parsing a control sequence? */
-
- if(InSequence)
- {
- if(*Char == ESC)
- {
- DoCancel();
- InSequence = TRUE;
-
- if(!Config . CaptureFilter)
- Capture("\033",1);
- }
- else
- {
- if(!Config . CaptureFilter)
- Capture(Char,1);
-
- /* See if we are already done. */
-
- InSequence = ParseCode(*Char++);
- }
- }
- else
- {
- /* This looks like a control sequence
- * introducing character.
- */
-
- if(*Char == ESC || *Char == CSI)
- {
- if(BufSize)
- {
- Capture(&StringBuffer[0],BufSize);
-
- SpillTheBeans(&StringBuffer[0],BufSize);
-
- BufSize = 0;
- }
-
- /* So we're in TTY mode,
- * escape the `escape' character
- * and continue.
- */
-
- if(Config . Emulation == EMULATION_TTY)
- {
- if(*Char == ESC)
- {
- StringBuffer[BufSize++] = '^';
- StringBuffer[BufSize++] = '[';
-
- if(!Config . CaptureFilter)
- Capture("\033",1);
- }
- else
- {
- /* Fake a CSI. */
-
- StringBuffer[BufSize++] = '^';
- StringBuffer[BufSize++] = '[';
-
- if(!Config . CaptureFilter)
- Capture("\033[",2);
- }
- }
- else
- {
- if(*Char == ESC)
- {
- InSequence = TRUE;
-
- if(!Config . CaptureFilter)
- Capture("\033",1);
- }
- else
- CSIFake();
- }
-
- Char++;
- }
- else
- {
- /* Stuff the character into
- * the buffer.
- */
-
- StringBuffer[BufSize++] = *Char++;
-
- /* If buffer is full, spill it. */
-
- if(BufSize == 200)
- {
- Capture(&StringBuffer[0],BufSize);
-
- SpillTheBeans(&StringBuffer[0],BufSize);
-
- BufSize = 0;
- }
- }
- }
- }
-
- /* Any characters in the buffer we didn't process yet? */
-
- if(!InSequence && BufSize)
- {
- Capture(&StringBuffer[0],BufSize);
-
- SpillTheBeans(&StringBuffer[0],BufSize);
-
- BufSize = 0;
- }
- }
-
- /* ConProcess(UBYTE *String,LONG Size):
- *
- * Process the contents of a string to be sent to the
- * console window.
- */
-
- VOID
- ConProcess(UBYTE *String,LONG Size)
- {
- LONG i,j;
-
- /* In quiet mode no characters are echoed to the
- * console window, they are just passed through
- * the data flow filter. This mode is enabled
- * by the dial panel.
- */
-
- if(Quiet)
- {
- for(i = 0 ; i < Size ; i++)
- FlowFilter(String[i]);
- }
- else
- {
- /* If the current font is Topaz, some bytes
- * will need to be filtered since they are not
- * defined as valid ASCII characters.
- */
-
- if(Config . Font == FONT_TOPAZ)
- {
- for(i = 0, j = 0 ; i < Size ; i++)
- {
- FlowFilter(String[i]);
-
- if(IsPrintable(String[i]))
- {
- /* This character is
- * associated with a
- * special function
- * (bell, xon, xoff, etc.).
- */
-
- if(SpecialMap[String[i]] != -1)
- {
- if(j)
- {
- ConWrite(SharedBuffer,j);
-
- j = 0;
- }
-
- SpecialKeys[SpecialMap[String[i]]] . Routine();
- }
- else
- {
- /* Put the character
- * into the buffer
- * and empty it if
- * necessary.
- */
-
- SharedBuffer[j] = String[i];
-
- if(j++ == 512)
- {
- ConWrite(SharedBuffer,j);
-
- j = 0;
- }
- }
- }
- }
- }
- else
- {
- /* In IBM font mode, any character gives
- * a sensible result.
- */
-
- for(i = 0, j = 0 ; i < Size ; i++)
- {
- FlowFilter(String[i]);
-
- if(SpecialMap[String[i]] != -1)
- {
- if(j)
- {
- ConWrite(SharedBuffer,j);
-
- j = 0;
- }
-
- SpecialKeys[SpecialMap[String[i]]] . Routine();
- }
- else
- {
- SharedBuffer[j] = String[i];
-
- if(j++ == 512)
- {
- ConWrite(SharedBuffer,j);
-
- j = 0;
- }
- }
- }
- }
-
- if(j)
- ConWrite(SharedBuffer,j);
- }
- }
-
- /* ConWrites(UBYTE *String,...):
- *
- * Output a string to the console.
- */
-
- VOID __stdargs
- ConWrites(UBYTE *String,...)
- {
- va_list VarArgs;
-
- va_start(VarArgs,String);
- VSPrintf(SharedBuffer,String,VarArgs);
- va_end(VarArgs);
-
- ConProcess(SharedBuffer,strlen(SharedBuffer));
- }
-
- /* KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer):
- *
- * Convert a raw key information according to the
- * current keymap settings.
- */
-
- UBYTE
- KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer)
- {
- if(Buffer)
- Buffer[0] = 0;
-
- if(Massage -> Class == IDCMP_RAWKEY)
- {
- /* These are the sequences mapped to special
- * control keys (cursor keys, function keys,
- * the help key).
- */
-
- STATIC struct
- {
- UBYTE *RawCode;
- UBYTE Result;
- } ConversionTable[16] =
- {
- (UBYTE *)"A", CUP,
- (UBYTE *)"B", CDN,
- (UBYTE *)"C", CFW,
- (UBYTE *)"D", CBK,
-
- (UBYTE *)"?~", HLP,
-
- (UBYTE *)"0~", FN1,
- (UBYTE *)"1~", FN2,
- (UBYTE *)"2~", FN3,
- (UBYTE *)"3~", FN4,
- (UBYTE *)"4~", FN5,
- (UBYTE *)"5~", FN6,
- (UBYTE *)"6~", FN7,
- (UBYTE *)"7~", FN8,
- (UBYTE *)"8~", FN9,
- (UBYTE *)"9~", F10
- };
-
- /* Key was pressed, not released. */
-
- if(!(Massage -> Code & IECODE_UP_PREFIX))
- {
- UBYTE ConvertBuffer[257],i;
- ULONG Qualifier = Massage -> Qualifier;
-
- /* If it's a function key clear the qualifier. */
-
- if(Massage -> Code >= 80 && Massage -> Code <= 89)
- Qualifier = 0;
-
- /* Clear the buffer. */
-
- memset(&ConvertBuffer[0],0,257);
-
- /* Convert the key. */
-
- FakeInputEvent -> ie_Code = Massage -> Code;
- FakeInputEvent -> ie_Qualifier = Qualifier;
- FakeInputEvent -> ie_position . ie_addr = *((APTR *)Massage -> IAddress);
-
- if(RawKeyConvert(FakeInputEvent,(UBYTE *)ConvertBuffer,257,NULL) > 0)
- {
- if(ConvertBuffer[0])
- {
- if(Buffer)
- strcpy(Buffer,ConvertBuffer);
-
- /* Translated sequence starts
- * with a CSI, let's have a look
- * at the associated control
- * key.
- */
-
- if(ConvertBuffer[0] == CSI)
- {
- for(i = 0 ; i < 16 ; i++)
- {
- if(!StrCmp(&ConvertBuffer[1],ConversionTable[i] . RawCode))
- {
- ConvertBuffer[0] = ConversionTable[i] . Result;
-
- if(Buffer)
- {
- Buffer[0] = ConversionTable[i] . Result;
- Buffer[1] = 0;
- }
-
- break;
- }
- }
- }
-
- return(ConvertBuffer[0]);
- }
- }
- }
- }
-
- return(0);
- }
-