amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (03/04/91)
Submitted-by: sie@fulcrum.bt.co.uk (Simon Raybould)
Posting-number: Volume 91, Issue 037
Archive-name: libraries/curses-1.22/part05
#!/bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 5 (of 8)."
# Contents: src/curses.c
# Wrapped by tadguy@ab20 on Sun Mar 3 18:04:29 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/curses.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/curses.c'\"
else
echo shar: Extracting \"'src/curses.c'\" \(44718 characters\)
sed "s/^X//" >'src/curses.c' <<'END_OF_FILE'
X/*
X *
X * Module : curses.c
X *
X * Description : AMIGA CURSES package.
X *
X * Author : Simon Raybould (sie@fulcrum.bt.co.uk)
X *
X * Date V1.00a : 16th February 1990
X * V1.10 : 30th July 1990
X * V1.20a : 4th October 1990
X * V1.20 : 7th November 1990
X * V1.21 : 2nd December 1990 minor fixes
X * V1.22 : 7th January 1991 bug fixes
X *
X */
X
X
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X#include <intuition/screens.h>
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <devices/audio.h>
X
X#include "acurses.h"
X
X
X/* Main background screen */
Xstatic struct NewScreen NewScreen = {
X 0, /* LeftEdge */
X 0, /* TopEdge */
X 0, /* Width */
X 0, /* Height */
X 4, /* No. Bitplanes */
X 0, 1, /* DetailPen, BlockPen */
X HIRES, /* ViewModes */
X CUSTOMSCREEN, /* Screen type */
X (struct TextAttr *)NULL, /* default font */
X "Curses screen", /* Screen Title */
X (struct Gadget *)NULL, /* Gadget list */
X (struct BitMap *)NULL /* custom bitmap */
X};
X
X/* Main background window */
Xstatic struct NewWindow NewWindow = {
X 0, /* Left edge */
X 0, /* Top edge */
X 0, /* Width */
X 0, /* Height */
X -1, -1, /* Pens */
X RAWKEY, /* IDCMP flags */
X ACTIVATE | BORDERLESS, /* Window flags */
X NULL, /* First gadget */
X NULL, /* Image data */
X NULL, /* Title */
X NULL, /* Pointer to screen structure */
X NULL, /* Super BitMap ? */
X 0,0,0,0, /* MIN/MAX sizing */
X CUSTOMSCREEN /* Type of screen */
X};
X
X/*
X * Make author appear when right mouse button is pressed.
X */
X
Xstatic struct Menu _CursesMenu = {
X NULL, 0, 0, 0, 0, 0,
X " AMIGA CURSES by Simon J Raybould (sie@fulcrum.bt.co.uk) V1.22 07.Jan.1991",
X NULL, 0, 0, 0, 0
X};
X
X/*
X * Should initialise all of these to NULL to be certain that
X * CleanExit() will function correctly. Most compilers will do this
X * anyway, but better safe than GURUed.
X */
X
Xstruct IntuitionBase *IntuitionBase = NULL;
Xstruct GfxBase *GfxBase = NULL;
X
Xstruct ConsoleDevice *ConsoleDevice = NULL;
Xstatic struct IOStdReq ioreq;
Xstatic struct Screen *CursesScreen = NULL;
Xstatic struct Window *CursesWindow = NULL;
X
Xstatic struct RastPort *RPort;
Xstatic struct ViewPort *VPort;
X
Xstatic unsigned char CursesFlags; /* Global flags */
Xstatic short CursorCol = 0,CursorLine = 0,LCursorLine = -1,LCursorCol = -1;
Xstatic struct WindowState *HeadWindowList = (struct WindowState *)NULL;
Xstatic struct RefreshElement *HeadRefreshList=(struct RefreshElement *)NULL;
Xstatic struct IOAudio *AIOptr;
Xstatic struct MsgPort *port;
Xstatic ULONG device;
Xstatic BYTE *sound_data;
Xstatic UBYTE whichannel[] = { 1, 2, 4, 8 };
X
X/*
X * void internal functions
X */
X
Xstatic void CleanExit(), CleanUp(), DoEcho();
Xstatic void ZapCursor(), DrawCursor();
X
X/* Define a blank mouse pointer */
Xstatic USHORT __chip MyMsPtr[] = { 0, 0, 0, 0 };
X
X#define NCOLOURS 32
X
Xstatic UWORD ColourTable[] = {
X 0x000, 0xfff, 0xff0, 0xf80, 0x00f, 0xf0f, 0x0ff, 0xfff,
X 0x620, 0xe50, 0x9f1, 0xeb0, 0x55f, 0x92f, 0x0f8, 0xccc,
X 0x000, 0xd22, 0x000, 0xabc, 0x444, 0x555, 0x666, 0x777,
X 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff
X};
X
XWINDOW *stdscr = (WINDOW *)NULL, *curscr = (WINDOW *)NULL;
Xint LINES=24, COLS=80; /* Defaults */
X
X/*
X * Need to be global so that flushinp() can reset them !
X */
Xstatic unsigned char GetchRPos = 0, GetchWPos = 0;
X
X/*
X * Start of code.
X */
X
Xinitscr()
X{
X ULONG IBaseLock;
X char *Ptr, *getenv();
X int Tmp;
X
X /*
X * It would be devestating if someone called initscr() twice
X * so make the second call fail.
X */
X if(CursesFlags & CFLAG_INITSCR)
X return ERR;
X
X CursesFlags |= CFLAG_INITSCR; /* Mark that we have called initscr() */
X
X if((IntuitionBase = (struct IntuitionBase *)
X OpenLibrary("intuition.library", 0)) == NULL) {
X fprintf(stderr, "Failed to open Intuition library");
X CleanExit(10);
X }
X IBaseLock = LockIBase(0L);
X NewScreen.Height = NewWindow.Height = IntuitionBase->ActiveScreen->Height;
X NewScreen.Width = NewWindow.Width = IntuitionBase->ActiveScreen->Width;
X UnlockIBase(IBaseLock);
X /* Set interlace if height >= 400 */
X if(NewScreen.Height>=400)
X NewScreen.ViewModes |= LACE;
X LINES = NewScreen.Height/8;
X COLS = NewScreen.Width/8;
X /* if LINES and/or COLS set as environment variables then use them */
X if((Ptr = getenv("LINES"))) {
X Tmp = atoi(Ptr);
X if(Tmp>0 && Tmp<=LINES)
X LINES = Tmp;
X }
X if((Ptr = getenv("COLS"))) {
X Tmp = atoi(Ptr);
X if(Tmp>0 && Tmp<=COLS)
X COLS = Tmp;
X }
X /* Open graphics library */
X if((GfxBase = (struct GfxBase *)
X OpenLibrary("graphics.library", 0))==NULL) {
X fprintf(stderr, "Failed to open Graphics library");
X CleanExit(10);
X }
X /*
X * must have the console.device opened to use RawKeyConvert()
X */
X
X if(OpenDevice("console.device",-1L,(struct IORequest *)&ioreq,0L))
X CleanExit(10);
X ConsoleDevice=(struct ConsoleDevice *)ioreq.io_Device;
X
X if((CursesScreen=(struct Screen *)OpenScreen(&NewScreen)) == NULL) {
X fprintf(stderr, "Failed to open Screen");
X CleanExit(10);
X }
X RPort = &(CursesScreen->RastPort);
X VPort = &(CursesScreen->ViewPort);
X LoadRGB4(VPort, ColourTable, NCOLOURS);
X SetDrMd(RPort, JAM2);
X SetAPen(RPort, 1);
X NewWindow.Screen = CursesScreen; /* Must do this !! */
X if((CursesWindow=(struct Window *)OpenWindow(&NewWindow)) == NULL) {
X fprintf(stderr, "Failed to open Window\n");
X CleanExit(10);
X }
X SetMenuStrip(CursesWindow, &_CursesMenu);
X SetPointer(CursesWindow, MyMsPtr, 0, 0, 0, 0); /*Remove mouse pointer*/
X /* Create stdscr and curscr */
X stdscr = newwin(LINES, COLS, 0, 0);
X curscr = newwin(LINES, COLS, 0, 0); /* used for redraws */
X clearok(curscr, TRUE); /* Clear curscr on every refresh */
X
X CursesFlags = CFLAG_ECHO | CFLAG_NLCR | CFLAG_CURSOR | CFLAG_INITSCR;
X return OK;
X}
X
X/*
X * Close the screen and libraries.
X */
X
Xendwin() /* called from main prior to exit. */
X{
X void ZapWindows();
X
X if(!(CursesFlags & CFLAG_INITSCR)) { /* haven't called initscr() */
X return ERR;
X }
X ZapWindows(HeadWindowList);
X CleanUp();
X CursesFlags &= ~CFLAG_INITSCR; /* Mark that we have called endwin() */
X return OK;
X}
X
X/* Recursive routine to zap all windows and release data structures */
Xstatic void ZapWindows(WinStat)
X struct WindowState *WinStat;
X{
X if(!WinStat)
X return;
X if(WinStat->Next)
X ZapWindows(WinStat->Next); /* Recurse */
X delwin(&WinStat->Window);
X}
X
Xstatic void CleanExit(RetCode)
X int RetCode;
X{
X CleanUp();
X exit(RetCode);
X}
X
Xstatic void CleanUp()
X{
X if(CursesWindow)
X CloseWindow(CursesWindow);
X if(CursesScreen)
X CloseScreen(CursesScreen);
X if(GfxBase)
X CloseLibrary((struct Library *)GfxBase);
X if(IntuitionBase)
X CloseLibrary((struct Library *)IntuitionBase);
X}
X
Xinit_color(n, r, g, b)
X short n;
X unsigned char r, g, b;
X{
X if(n<0 || n>15 || r>1000 || g>1000 || b>1000)
X return ERR;
X /* If 0 then leave, else subtract 1 */
X if(r) r--;
X if(g) g--;
X if(g) g--;
X
X SetRGB4(VPort, n, r*16/1000, g*16/1000, b*16/1000);
X return OK;
X}
X
Xstart_color()
X{
X return OK; /* No initialisation required to get colours going */
X}
X
Xhas_colors()
X{
X return TRUE; /* Yes baby we have colours on this bitch */
X}
X
X/*
X * static because not implemented yet.
X */
Xstatic color_content(color, r, g, b)
X short color, *r, *g, *b;
X{
X return OK;
X}
X
Xwaddstr(WinPtr, Str)
X WINDOW *WinPtr;
X char *Str;
X{
X struct WindowState *WinStat, *PWinStat = NULL;
X short TmpAttrs;
X
X if(!*Str)
X return OK;
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X if(WinStat->ParentWin)
X if(!(PWinStat = (struct WindowState *)WinStat->ParentWin->_WinStat))
X return ERR;
X
X WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
X WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
X if(PWinStat) {
X PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].Touched = TRUE;
X PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].StartCol, WinPtr->_curx + WinPtr->_begx);
X }
X while(*Str) {
X switch(*Str) {
X case '\t':
X do {
X WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx] = ' ';
X WinStat->LnArry[WinPtr->_cury].ATTRS[WinPtr->_curx++] = WinPtr->_attrs;
X } while(WinPtr->_curx % 8);
X break;
X case '\n':
X WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
X TmpAttrs = WinPtr->_attrs;
X wattrset(WinPtr, 0); /* better to call wattrset in case I change attrs */
X wclrtoeol(WinPtr);
X wattrset(WinPtr, TmpAttrs);
X if(PWinStat)
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol=max(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol,WinPtr->_curx+WinPtr->_begx-1);
X WinPtr->_curx = 0;
X WinPtr->_cury++;
X if(WinPtr->_cury > WinStat->ScrollBot) {
X if(WinPtr->_scroll)
X scroll(WinPtr);
X WinPtr->_cury = WinStat->ScrollBot;
X }
X if(*(Str + 1)) { /* If there is more then touch this line too */
X WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
X WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
X if(PWinStat) {
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].Touched = TRUE;
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol, WinPtr->_curx+WinPtr->_begx);
X }
X }
X break;
X default:
X WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx] = *Str;
X WinStat->LnArry[WinPtr->_cury].ATTRS[WinPtr->_curx] = WinPtr->_attrs;
X WinPtr->_curx++;
X break;
X }
X /* If hit right edge of window then increment _cury */
X if(WinPtr->_curx > WinPtr-> _maxx) {
X WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
X WinPtr->_curx = 0;
X WinPtr->_cury++;
X if(WinPtr->_cury > WinStat->ScrollBot) {
X if(WinPtr->_scroll)
X scroll(WinPtr);
X WinPtr->_cury = WinStat->ScrollBot;
X }
X if(WinPtr->_cury > WinPtr->_maxy)
X WinPtr->_cury = WinPtr->_maxy;
X if(*(Str + 1)) { /* If there is more then touch this line too */
X WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
X WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
X if(PWinStat) {
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].Touched = TRUE;
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol, WinPtr->_curx+WinPtr->_begx);
X }
X }
X }
X Str++;
X }
X WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
X if(PWinStat)
X PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol = max(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol, WinPtr->_curx+WinPtr->_begx-1);
X return OK;
X}
X
Xwaddch(WinPtr, c)
X WINDOW *WinPtr;
X char c;
X{
X char *str = " ";
X
X *str = c;
X return waddstr(WinPtr, str);
X}
X
Xwinsch(WinPtr, c)
X WINDOW *WinPtr;
X char c;
X{
X int i;
X struct WindowState *WinStat;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X /* shuffle line along to the right */
X for (i = WinPtr->_maxx; i > WinPtr->_curx; i--)
X WinStat->LnArry[WinPtr->_cury].Line[i] = WinStat->LnArry[WinPtr->_cury].Line[i-1];
X WinStat->LnArry[WinPtr->_cury].Line[i] = c;
X WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
X WinStat->LnArry[WinPtr->_cury].EndCol = WinPtr->_maxx;
X WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
X
X return OK;
X}
X
Xwdelch(WinPtr)
X WINDOW *WinPtr;
X{
X int i;
X struct WindowState *WinStat;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X /* shuffle line along to the left */
X for (i = WinPtr->_curx; i < WinPtr->_maxx; i++)
X WinStat->LnArry[WinPtr->_cury].Line[i] = WinStat->LnArry[WinPtr->_cury].Line[i+1];
X WinStat->LnArry[WinPtr->_cury].Line[i] = ' '; /* Blank last char */
X WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
X WinStat->LnArry[WinPtr->_cury].EndCol = WinPtr->_maxx;
X WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
X
X return OK;
X}
X
Xwclear(WinPtr)
X WINDOW *WinPtr;
X{
X int Line, Col;
X struct WindowState *WinStat;
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X for(Line=0; Line<WinStat->NLines; Line++) {
X memset(WinStat->LnArry[Line].Line, ' ', WinPtr->_maxx + 1);
X memset(WinStat->LnArry[Line].LRLine, ' ', WinPtr->_maxx + 1);
X for(Col = 0; Col <= WinPtr->_maxx; Col++) {
X WinStat->LnArry[Line].ATTRS[Col] = WinPtr->_attrs;
X WinStat->LnArry[Line].LRATTRS[Col] = WinPtr->_attrs;
X }
X WinStat->LnArry[Line].Touched = FALSE;
X WinStat->LnArry[Line].StartCol = WinPtr->_maxx;
X WinStat->LnArry[Line].EndCol = 0;
X }
X WinPtr->_curx = 0;
X WinPtr->_cury = 0;
X WinPtr->_cls = TRUE;
X return OK;
X}
X
Xwerase(WinPtr)
X WINDOW *WinPtr;
X{
X int Line, Col;
X struct WindowState *WinStat;
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X /* Blank screen image */
X for(Line=0; Line<WinStat->NLines; Line++) {
X memset(WinStat->LnArry[Line].Line, ' ', WinPtr->_maxx + 1);
X for(Col = 0; Col <= WinPtr->_maxx; Col++)
X WinStat->LnArry[Line].ATTRS[Col] = WinPtr->_attrs;
X WinStat->LnArry[Line].Touched = TRUE;
X WinStat->LnArry[Line].StartCol = 0;
X WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
X }
X WinPtr->_curx = 0;
X WinPtr->_cury = 0;
X return OK;
X}
X
Xclearok(WinPtr, flag)
X WINDOW *WinPtr;
X int flag;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_clear = (flag) ? TRUE : FALSE;
X
X return OK;
X}
X
Xwclrtoeol(WinPtr)
X WINDOW *WinPtr;
X{
X short x, y;
X int len;
X char Buffer[100];
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X x = WinPtr->_curx;
X y = WinPtr->_cury;
X
X len = WinPtr->_maxx - WinPtr->_curx + 1;
X memset(Buffer, ' ', len);
X Buffer[len] = '\0';
X
X waddstr(WinPtr, Buffer);
X wmove(WinPtr, y, x);
X
X return OK;
X}
X
Xwclrtobot(WinPtr)
X WINDOW *WinPtr;
X{
X short x, y;
X int i;
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X x = WinPtr->_curx;
X y = WinPtr->_cury;
X
X wclrtoeol(WinPtr);
X for(i = WinPtr->_cury + 1; i <= WinPtr->_maxy; i++) {
X wmove(WinPtr, i, 0);
X wclrtoeol(WinPtr);
X }
X wmove(WinPtr, y, x);
X
X return OK;
X}
X
Xstatic int GetNextChar(WinPtr)
X WINDOW *WinPtr;
X{
X static unsigned char buffer[RAWBUFSIZ], BufPos = 0, NumChars = 0;
X int Class, i;
X struct IntuiMessage *Message;
X static struct InputEvent ievent = { NULL, IECLASS_RAWKEY, 0, 0, 0 };
X
X if(BufPos < NumChars) /* If we still hav some chars then return next */
X return (int)buffer[BufPos++];
X
X while (BufPos == NumChars) {
X /* Get message if there is one allready queued */
X Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
X if(!Message) {
X /* Nuffin yet */
X if(WinPtr->_nodelay) /* If non-blocking return ERR */
X return ERR;
X else { /* Wait for character */
X Wait(1<<CursesWindow->UserPort->mp_SigBit);
X Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
X }
X }
X if(!Message) /* Try again */
X continue;
X
X Class = Message->Class;
X switch(Class) {
X case RAWKEY:
X BufPos = 0;
X ievent.ie_Code = Message->Code;
X ievent.ie_Qualifier = Message->Qualifier;
X ievent.ie_position.ie_addr = *((APTR*)Message->IAddress);
X NumChars = RawKeyConvert(&ievent, buffer, RAWBUFSIZ, 0L);
X ReplyMsg((struct Message *)Message);
X if(!NumChars) /* If no characters then try again */
X break;
X if(CursesFlags & CFLAG_ECHO)
X for(i=0; i<NumChars; i++)
X DoEcho(WinPtr, buffer[i]);
X /* Translate id keypad set to TRUE */
X if(WinPtr->_use_keypad) {
X switch(NumChars) {
X case 1:
X NumChars = 0; /* Translation will use up all chars */
X return (int)buffer[0];
X case 2: /* ARROW KEY */
X NumChars = 0; /* Translation will use up all chars */
X if(buffer[0] != 155)
X return -1;
X switch(buffer[1]) {
X case 65: return KEY_UP;
X case 66: return KEY_DOWN;
X case 67: return KEY_RIGHT;
X case 68: return KEY_LEFT;
X default: return -1;
X }
X case 3: /* FUNCTION KEY */
X NumChars = 0; /* Translation will use up all chars */
X if(buffer[0] != 155)
X return -1;
X if(buffer[2] != 126)
X return -1;
X if(buffer[1] == 63)
X return KEY_HELP;
X return KEY_F0 + (buffer[1] - 48); /* KEY_F0 = F1 */
X default:
X NumChars = 0; /* Translation will use up all chars */
X return -1;
X }
X }
X break;
X default:
X ReplyMsg((struct Message *)Message);
X break;
X }
X }
X return (int)buffer[BufPos++];
X}
X
Xflushinp()
X{
X GetchRPos = 0;
X GetchWPos = 0;
X return OK;
X}
X
Xwgetch(WinPtr)
X WINDOW *WinPtr;
X{
X static int buffer[256]; /* Cyclic buffer */
X static unsigned char forward = FALSE;
X int Ret;
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X while(GetchRPos == GetchWPos || (!(CursesFlags & CFLAG_CBREAK) && !forward)) {
X if(WinPtr->_nodelay)
X return GetNextChar(WinPtr);
X if((Ret = GetNextChar(WinPtr)) >= 0)
X buffer[GetchWPos++] = Ret;
X if(Ret == (int)'\r')
X forward = TRUE;
X }
X if(buffer[GetchRPos] == '\r') {
X buffer[GetchRPos] = '\n';
X forward = FALSE;
X }
X return((int)buffer[GetchRPos++]);
X}
X
Xwgetstr(WinPtr, ptr)
X WINDOW *WinPtr;
X char *ptr;
X{
X char done = FALSE, *BuffStart;
X unsigned char TempFlag; /* Used to restore flags after */
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X BuffStart = ptr;
X
X /* Will need to be in CBREAK mode for this */
X TempFlag = CursesFlags;
X CursesFlags |= CFLAG_CBREAK;
X while(!done) {
X switch(*ptr = wgetch(WinPtr)) {
X case -1: /* wgetch() returned ERROR */
X *ptr = '\0';
X CursesFlags = TempFlag;
X return -1;
X case '\n':
X case '\r':
X *ptr = '\0';
X done = TRUE;
X break;
X case '\b':
X if(--ptr < BuffStart) /* Don't move before start */
X ptr = BuffStart;
X else if(CursesFlags & CFLAG_ECHO) {
X /* Do BS SP BS processing */
X mvcur(CursorLine, CursorCol, CursorLine, CursorCol - 1); /* BS */
X DoEcho(WinPtr, ' '); /* SP */
X mvcur(CursorLine, CursorCol, CursorLine, CursorCol - 1); /* BS */
X }
X break;
X default:
X ptr++;
X break;
X }
X }
X CursesFlags = TempFlag;
X return 0;
X}
X
Xwinch(WinPtr)
X WINDOW *WinPtr;
X{
X struct WindowState *WinStat;
X
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X return (int)WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx];
X}
X
Xstatic void DoEcho(WinPtr, c)
X WINDOW *WinPtr;
X char c;
X{
X short x, y;
X struct WindowState *WinStat;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return;
X
X if(c == BS || c == CR) /* Don't echo Backspace or Return */
X return;
X
X x = CursorCol * 8;
X y = 6 + CursorLine * 8;
X ZapCursor();
X SetDrMd(RPort, JAM2);
X SetAPen(RPort, WinPtr->_attrs & 0x0f);
X Move(RPort, x, y);
X Text(RPort, &c, 1);
X DrawCursor();
X /* Update curscr */
X if(WinPtr != curscr) {
X wmove(curscr, CursorLine, CursorCol);
X waddch(curscr, c);
X }
X /* Update Line structure */
X WinStat->LnArry[CursorLine-WinPtr->_begy].Line[CursorCol-WinPtr->_begx] = c;
X WinStat->LnArry[CursorLine-WinPtr->_begy].LRLine[CursorCol-WinPtr->_begx] = c;
X WinStat->LnArry[CursorLine-WinPtr->_begy].ATTRS[CursorCol-WinPtr->_begx] = WinPtr->_attrs;
X WinStat->LnArry[CursorLine-WinPtr->_begy].LRATTRS[CursorCol-WinPtr->_begx] = WinPtr->_attrs;
X /* Move current position one to the right */
X if(++WinPtr->_curx > WinPtr->_maxx)
X WinPtr->_curx = WinPtr->_maxx;
X mvcur(CursorLine, CursorCol, CursorLine, CursorCol + 1);
X}
X
Xwmove(WinPtr, Line, Col)
X WINDOW *WinPtr;
X short Line, Col;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X if(Line<0 || Line>WinPtr->_maxy)
X return ERR;
X if(Col<0 || Col>WinPtr->_maxx)
X return ERR;
X WinPtr -> _cury = Line;
X WinPtr -> _curx = Col;
X WinPtr -> _flags |= CWF_MOVED;
X return OK;
X}
X
Xmvcur(CurLine, CurCol, NewLine, NewCol)
X int CurLine, CurCol, NewLine, NewCol;
X{
X /* Could check CurLine and CurCol but this would make it fail too often */
X ZapCursor();
X CursorLine = NewLine;
X CursorCol = NewCol;
X DrawCursor();
X return OK;
X}
X
Xprintw(fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X char *fmt;
X double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X int Ret;
X char buffer[BUFSIZ];
X
X Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X waddstr(stdscr, buffer);
X return Ret;
X}
X
Xwprintw(WinPtr, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X WINDOW *WinPtr;
X char *fmt;
X double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X int Ret;
X char buffer[BUFSIZ];
X
X Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X waddstr(WinPtr, buffer);
X return Ret;
X}
X
Xmvprintw(Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X short Line, Col;
X char *fmt;
X double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X int Ret;
X char buffer[BUFSIZ];
X
X Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X wmove(stdscr, Line, Col);
X waddstr(stdscr, buffer);
X return Ret;
X}
X
Xmvwprintw(WinPtr, Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X WINDOW *WinPtr;
X short Line, Col;
X char *fmt;
X double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X int Ret;
X char buffer[BUFSIZ];
X
X Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X wmove(WinPtr, Line, Col);
X waddstr(WinPtr, buffer);
X return Ret;
X}
X
Xwrefresh(WinPtr)
X WINDOW *WinPtr;
X{
X int i, j;
X unsigned long style;
X short Line;
X struct WindowState *WinStat;
X char Buffer[BUFSIZ];
X void Optimise();
X
X if(WinPtr == curscr)
X touchwin(WinPtr);
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X ZapCursor();
X /*
X * It is possible for no printing since last refresh, but for
X * a move to have been done...
X */
X if(WinPtr->_flags & CWF_MOVED) {
X WinPtr->_flags &= ~CWF_MOVED;
X CursorLine = WinPtr->_cury + WinPtr->_begy;
X CursorCol = WinPtr->_curx + WinPtr->_begx;
X }
X /*
X * If clearok has been called, then clear on every refresh.
X */
X if(WinPtr->_clear || WinPtr->_cls) {
X WinPtr->_cls = FALSE;
X SetAPen(RPort, 0);
X SetDrMd(RPort, JAM2);
X RectFill(RPort, (WinPtr->_begx * 8), (WinPtr->_begy * 8),
X ((WinPtr->_begx + WinPtr->_maxx) * 8) + 7,
X ((WinPtr->_begy + WinPtr->_maxy) * 8 + 7));
X }
X if(CursesFlags & CFLAG_CURSOR) {
X CursorLine = WinPtr->_cury + WinPtr->_begy;
X CursorCol = WinPtr->_curx + WinPtr->_begx;
X }
X for(Line=0; Line<WinStat->NLines; Line++) {
X /* if clearok set then must refresh everything */
X if(WinPtr->_clear) {
X memset(WinStat->LnArry[Line].LRLine, ' ', WinPtr->_maxx+1);
X WinStat->LnArry[Line].Touched = TRUE;
X WinStat->LnArry[Line].StartCol = 0;
X WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
X }
X Optimise(&WinStat->LnArry[Line]);
X if(WinStat->LnArry[Line].Touched) {
X j = WinStat->LnArry[Line].StartCol;
X for(i=WinStat->LnArry[Line].StartCol + 1; i<=WinStat->LnArry[Line].EndCol; i++) {
X if(WinStat->LnArry[Line].ATTRS[i] != WinStat->LnArry[Line].ATTRS[j]) {
X /* Print what we've got */
X SetAPen(RPort, WinStat->LnArry[Line].ATTRS[j] & 017);
X if(WinStat->LnArry[Line].ATTRS[j] & (A_REVERSE | A_STANDOUT))
X SetDrMd(RPort, JAM2|INVERSVID);
X else
X SetDrMd(RPort, JAM2);
X style = FS_NORMAL;
X if(WinStat->LnArry[Line].ATTRS[j] & A_BOLD)
X style |= FSF_BOLD;
X if(WinStat->LnArry[Line].ATTRS[j] & A_UNDERLINE)
X style |= FSF_UNDERLINED;
X SetSoftStyle(RPort, style, ~0L);
X Move(RPort, (j+WinPtr->_begx) * 8, 6 + (Line+WinPtr->_begy) * 8);
X Text(RPort, &WinStat->LnArry[Line].Line[j], i-j);
X /*
X * Update the record of the current screen state.
X */
X if(WinPtr != curscr) {
X wmove(curscr, Line+WinPtr->_begy, j+WinPtr->_begx);
X memcpy(Buffer, &WinStat->LnArry[Line].Line[j], i-j);
X Buffer[i-j] = '\0';
X waddstr(curscr, Buffer);
X }
X j = i;
X }
X }
X if(j < i) {
X SetAPen(RPort, WinStat->LnArry[Line].ATTRS[j] & 017);
X if(WinStat->LnArry[Line].ATTRS[j] & (A_STANDOUT | A_REVERSE))
X SetDrMd(RPort, JAM2|INVERSVID);
X else
X SetDrMd(RPort, JAM2);
X style = FS_NORMAL;
X if(WinStat->LnArry[Line].ATTRS[j] & A_BOLD)
X style |= FSF_BOLD;
X if(WinStat->LnArry[Line].ATTRS[j] & A_UNDERLINE)
X style |= FSF_UNDERLINED;
X SetSoftStyle(RPort, style, ~0L);
X Move(RPort, (j+WinPtr->_begx) * 8, 6 + (Line+WinPtr->_begy) * 8);
X Text(RPort, &(WinStat->LnArry[Line].Line[j]), i-j);
X /*
X * Update the record of the current screen state.
X */
X if(WinPtr != curscr) {
X wmove(curscr, Line+WinPtr->_begy, j+WinPtr->_begx);
X memcpy(Buffer, &WinStat->LnArry[Line].Line[j], i-j);
X Buffer[i-j] = '\0';
X waddstr(curscr, Buffer);
X }
X }
X WinStat->LnArry[Line].Touched = FALSE;
X WinStat->LnArry[Line].StartCol = WinPtr->_maxx;
X WinStat->LnArry[Line].EndCol = 0;
X }
X /*
X * Copy line and attrs to LR for Optimise code
X */
X memcpy(WinStat->LnArry[Line].LRLine, WinStat->LnArry[Line].Line, WinPtr->_maxx+1);
X memcpy(WinStat->LnArry[Line].LRATTRS, WinStat->LnArry[Line].ATTRS, sizeof(short) * (WinPtr->_maxx+1));
X }
X DrawCursor();
X return OK;
X}
X
Xstatic void ToggleCursor(Line, Col)
X{
X SetDrMd(RPort, JAM2 | INVERSVID | COMPLEMENT);
X Move(RPort, Col*8, 6 + Line*8);
X Text(RPort, " ", 1);
X}
X
Xstatic void
X ZapCursor()
X{
X /* If there was a cursor then blank it */
X if(LCursorCol >= 0 && LCursorLine >= 0)
X ToggleCursor(LCursorLine, LCursorCol);
X
X LCursorCol = LCursorLine = -1;
X}
X
Xstatic void DrawCursor()
X{
X /* Draw cursor */
X if(CursesFlags & CFLAG_CURSOR)
X ToggleCursor(CursorLine, CursorCol);
X
X if(CursesFlags & CFLAG_CURSOR) {
X LCursorCol = CursorCol;
X LCursorLine = CursorLine;
X } else {
X LCursorCol = -1;
X LCursorLine = -1;
X }
X}
X
Xscanw(fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X char *fmt;
X long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X char buffer[BUFSIZ];
X
X wgetstr(stdscr, buffer);
X return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X}
X
Xwscanw(WinPtr, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X WINDOW *WinPtr;
X char *fmt;
X long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X char buffer[BUFSIZ];
X
X wgetstr(WinPtr, buffer);
X return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X}
X
Xmvscanw(Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X short Line, Col;
X char *fmt;
X long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X char buffer[BUFSIZ];
X
X wmove(stdscr, Line, Col);
X wgetstr(stdscr, buffer);
X return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X}
X
Xmvwscanw(WinPtr, Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
X WINDOW *WinPtr;
X short Line, Col;
X char *fmt;
X long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
X{
X char buffer[BUFSIZ];
X
X wmove(WinPtr, Line, Col);
X wgetstr(WinPtr, buffer);
X return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
X}
X
Xwstandout(WinPtr)
X WINDOW *WinPtr;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_attrs |= A_STANDOUT;
X}
X
Xwstandend(WinPtr)
X WINDOW *WinPtr;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_attrs &= ~A_STANDOUT;
X}
X
Xwattrset(WinPtr, attr)
X WINDOW *WinPtr;
X short attr;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X /*
X * Older code may inadvertently reset the attributes and set the
X * forground colour to 0, in this case, set it to white.
X */
X if(!(attr & 017))
X attr |= COLOR_WHITE;
X
X WinPtr->_attrs = attr;
X return OK;
X}
X
Xwattron(WinPtr, attr)
X WINDOW *WinPtr;
X short attr;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X /* If attributes contain a colour change then mask off old colour */
X if(attr & 017)
X WinPtr->_attrs &= ~017;
X
X WinPtr->_attrs |= attr;
X return OK;
X}
X
Xwattroff(WinPtr, attr)
X WINDOW *WinPtr;
X short attr;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_attrs &= ~attr;
X return OK;
X}
X
Xcbreak()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags |= CFLAG_CBREAK;
X return OK;
X}
X
Xnocbreak()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags &= ~CFLAG_CBREAK;
X return OK;
X}
X
Xraw()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags |= CFLAG_CBREAK;
X return OK;
X}
X
Xnoraw()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags &= ~CFLAG_CBREAK;
X return OK;
X}
X
Xidlok(WinPtr, flag)
X WINDOW *WinPtr;
X int flag;
X{
X /* This function is to enable hardware insert/delete line */
X return OK;
X}
X
Xwinsertln(WinPtr)
X WINDOW *WinPtr;
X{
X Scroll(WinPtr, WinPtr->_cury, WinPtr->_maxy, SCROLL_DOWN);
X return OK;
X}
X
Xwdeleteln(WinPtr)
X WINDOW *WinPtr;
X{
X Scroll(WinPtr, WinPtr->_cury, WinPtr->_maxy, SCROLL_UP);
X return OK;
X}
X
Xnodelay(WinPtr, flag)
X WINDOW *WinPtr;
X int flag;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_nodelay = flag;
X return OK;
X}
X
Xecho()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags |= CFLAG_ECHO;
X return OK;
X}
X
Xnoecho()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X CursesFlags &= ~CFLAG_ECHO;
X return OK;
X}
X
Xkeypad(WinPtr, flag)
X WINDOW *WinPtr;
X char flag;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X WinPtr->_use_keypad = flag?TRUE:FALSE;
X
X return OK;
X}
X
Xbeep()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X AIOptr = (struct IOAudio *) AllocMem(sizeof(struct IOAudio), MEMF_CHIP|MEMF_PUBLIC);
X if(!AIOptr)
X exit(1);
X
X port = (struct MsgPort *)CreatePort(0, 0);
X if(!port) {
X FreeMem(AIOptr, sizeof(struct IOAudio));
X return ERR;
X }
X
X AIOptr->ioa_Request.io_Message.mn_ReplyPort = port;
X AIOptr->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
X AIOptr->ioa_Request.io_Command = ADCMD_ALLOCATE;
X AIOptr->ioa_Request.io_Flags = ADIOF_NOWAIT;
X AIOptr->ioa_AllocKey = 0;
X AIOptr->ioa_Data = whichannel;
X AIOptr->ioa_Length = sizeof(whichannel);
X
X device = OpenDevice("audio.device", 0L, (struct IORequest *)AIOptr, 0L);
X if(device) {
X printf("Curses beep() - Can't open Audio Device\n");
X FreeMem(AIOptr, sizeof(struct IOAudio));
X return ERR;
X }
X
X sound_data = (UBYTE *) AllocMem(SOUNDLENGTH, MEMF_CHIP|MEMF_PUBLIC);
X if(!sound_data) {
X FreeMem(AIOptr, sizeof(struct IOAudio));
X return ERR;
X }
X
X sound_data[0]=127;
X sound_data[1]=-127;
X
X AIOptr->ioa_Request.io_Message.mn_ReplyPort = port;
X AIOptr->ioa_Request.io_Command = CMD_WRITE;
X AIOptr->ioa_Request.io_Flags = ADIOF_PERVOL;
X AIOptr->ioa_Data = sound_data;
X AIOptr->ioa_Cycles = 200;
X AIOptr->ioa_Length = SOUNDLENGTH;
X AIOptr->ioa_Period = 2000;
X AIOptr->ioa_Volume = 64;
X
X BeginIO((struct IORequest *)AIOptr);
X WaitIO((struct IORequest *)AIOptr);
X
X FreeMem(sound_data, SOUNDLENGTH);
X DeletePort(port);
X CloseDevice((struct IORequest *)AIOptr);
X FreeMem(AIOptr, sizeof(struct IOAudio));
X}
X
Xflash()
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X DisplayBeep(CursesScreen);
X}
X
Xleaveok(WinPtr, flag)
X WINDOW *WinPtr;
X int flag;
X{
X if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
X return ERR;
X
X if(flag) {
X CursorCol = CursorLine = -1;
X CursesFlags &= ~CFLAG_CURSOR;
X } else {
X CursesFlags |= CFLAG_CURSOR;
X }
X return OK;
X}
X
Xresetty()
X{
X return OK;
X}
X
Xsavetty()
X{
X return OK;
X}
X
Xresetterm()
X{
X return OK;
X}
X
Xfixterm()
X{
X return OK;
X}
X
Xsaveterm()
X{
X return OK;
X}
X
Xbaudrate()
X{
X return 9600;
X}
X
Xnl()
X{
X CursesFlags |= CFLAG_NLCR;
X return OK;
X}
X
Xnonl()
X{
X CursesFlags &= ~CFLAG_NLCR;
X return OK;
X}
X
Xcrmode()
X{
X return (cbreak());
X}
X
Xnocrmode()
X{
X return (nocbreak());
X}
X
Xbox(WinPtr, vert, hor)
X WINDOW *WinPtr;
X char vert, hor;
X{
X int i;
X short CurY, CurX;
X
X CurY = WinPtr->_cury;
X CurX = WinPtr->_curx;
X
X if(vert < 32 || vert > 126)
X vert = '|';
X if(hor < 32 || hor > 126)
X hor = '-';
X
X for(i=0; i<=WinPtr->_maxx; i++) {
X mvwaddch(WinPtr, 0, i, hor); /* Top horizontal */
X mvwaddch(WinPtr, WinPtr->_maxy, i, hor); /* Bottom horizontal */
X }
X for(i=1; i<WinPtr->_maxy; i++) {
X mvwaddch(WinPtr, i, 0, vert); /* Left vertical */
X mvwaddch(WinPtr, i, WinPtr->_maxx, vert); /* Right vertical */
X }
X WinPtr -> _cury = CurY;
X WinPtr -> _curx = CurX;
X return OK;
X}
X
XWINDOW *subwin(Orig, NLines, NCols, StartLine, StartCol)
X WINDOW *Orig;
X unsigned int NLines, NCols, StartLine, StartCol;
X{
X WINDOW *WinPtr, *CreatWindow();
X
X if(!(WinPtr = CreatWindow(NLines, NCols, StartLine, StartCol, Orig))) {
X printf("WARNING - subwin() failed, returning stdscr !!\n");
X return stdscr; /* Failed */
X }
X return WinPtr;
X}
X
XWINDOW *newwin(NLines, NCols, StartLine, StartCol)
X unsigned int NLines, NCols, StartLine, StartCol;
X{
X WINDOW *WinPtr, *CreatWindow();
X
X if(!(WinPtr = CreatWindow(NLines, NCols, StartLine, StartCol, NULL))) {
X printf("WARNING - newwin() failed, returning stdscr !!\n");
X return stdscr; /* Failed */
X }
X wclear(WinPtr);
X return WinPtr;
X}
X
X/* Orig is NULL and StartCol/Line are not used for newwin() calls */
Xstatic WINDOW *CreatWindow(NLines, NCols, StartLine, StartCol, Orig)
X int NLines, NCols, StartLine, StartCol;
X WINDOW *Orig;
X{
X int Line, j;
X struct WindowState *NewWinStat, *TmpWinPtr, *OrgWinStat = NULL;
X char *malloc();
X
X /* If either are zero then make them max */
X if(!NLines)
X NLines = LINES - StartLine;
X if(!NCols)
X NCols = COLS - StartCol;
X
X if(NLines>LINES || NCols>COLS || StartLine>LINES || StartCol>COLS)
X return (struct WINDOW *)NULL;
X
X if(StartLine < 0)
X StartLine = 0;
X if(StartCol < 0)
X StartCol = 0;
X if(Orig)
X OrgWinStat = (struct WindowState *)Orig->_WinStat;
X
X /* Create a new WinStat structure */
X if((NewWinStat=(struct WindowState *)malloc(sizeof(struct WindowState)))
X == (struct WindowState *)NULL) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X NewWinStat->ParentWin = Orig;
X NewWinStat->Next = (struct WindowState *)NULL;
X NewWinStat->Prev = (struct WindowState *)NULL;
X NewWinStat->ScrollTop = 0;
X NewWinStat->ScrollBot = NLines - 1;
X NewWinStat->NLines = NLines;
X /* Allocate space for LnArry[] */
X if(!(NewWinStat->LnArry = (struct LineElement *)malloc(sizeof(struct LineElement)*LINES))) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X /* Allocate space for Line, LRLine e.t.c */
X for(Line = 0; Line < NLines; Line++) {
X if(OrgWinStat) { /* If this is a subwindow */
X /* Set up pointers into parent window */
X NewWinStat->LnArry[Line].Line =
X &OrgWinStat->LnArry[Line+StartLine].Line[StartCol];
X NewWinStat->LnArry[Line].LRLine =
X &OrgWinStat->LnArry[Line+StartLine].LRLine[StartCol];
X NewWinStat->LnArry[Line].ATTRS =
X &OrgWinStat->LnArry[Line+StartLine].ATTRS[StartCol];
X NewWinStat->LnArry[Line].LRATTRS =
X &OrgWinStat->LnArry[Line+StartLine].LRATTRS[StartCol];
X } else { /* New window, allocate space for lines */
X /* malloc lines and ATTRS */
X if((NewWinStat->LnArry[Line].Line = malloc(NCols)) == NULL) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X if((NewWinStat->LnArry[Line].LRLine = malloc(NCols)) == NULL) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X if((NewWinStat->LnArry[Line].ATTRS =
X (short *)malloc(NCols*sizeof(short))) == NULL) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X if((NewWinStat->LnArry[Line].LRATTRS =
X (short *)malloc(NCols*sizeof(short))) == NULL) {
X fprintf(stderr, "CreatWindow() - Not enough memory\n");
X return (struct WINDOW *)NULL;
X }
X /* The optimiser will untouch any lines not used */
X memset(NewWinStat->LnArry[Line].LRLine, ' ', NCols);
X for(j=0; j<NCols; j++)
X NewWinStat->LnArry[Line].LRATTRS[j] = A_NORMAL | COLOR_WHITE;
X }
X NewWinStat->LnArry[Line].Touched = FALSE;
X NewWinStat->LnArry[Line].StartCol = NCols;
X NewWinStat->LnArry[Line].EndCol = 0;
X }
X /* Add to Window Stat list */
X if(HeadWindowList) {
X TmpWinPtr = HeadWindowList;
X while(TmpWinPtr->Next)
X TmpWinPtr = TmpWinPtr->Next;
X TmpWinPtr->Next = NewWinStat;
X NewWinStat->Prev = TmpWinPtr;
X } else {
X /* This is the first window i.e. stdscr */
X HeadWindowList = NewWinStat;
X }
X /* Initialise state of the window structure */
X NewWinStat->Window._cury = 0;
X NewWinStat->Window._curx = 0;
X NewWinStat->Window._maxy = NLines - 1;
X NewWinStat->Window._maxx = NCols - 1;
X NewWinStat->Window._begy = StartLine;
X NewWinStat->Window._begx = StartCol;
X NewWinStat->Window._flags = 0;
X NewWinStat->Window._attrs = A_NORMAL | COLOR_WHITE;
X NewWinStat->Window._clear = FALSE;
X NewWinStat->Window._cls = TRUE;
X NewWinStat->Window._scroll = FALSE;
X NewWinStat->Window._use_keypad = 0;
X NewWinStat->Window._use_meta = 0;
X NewWinStat->Window._nodelay = 0;
X NewWinStat->Window._WinStat = (char *)NewWinStat;
X
X return &NewWinStat->Window;
X}
X
Xtouchwin(WinPtr)
X WINDOW *WinPtr;
X{
X struct WindowState *WinStat;
X int Line;
X
X if(!(CursesFlags & CFLAG_INITSCR))
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X for(Line=0; Line<WinStat->NLines; Line++) {
X WinStat->LnArry[Line].Touched = TRUE;
X /* Mark whole line as refreshable */
X WinStat->LnArry[Line].StartCol = 0;
X WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
X /* Dump optimisation */
X memset(WinStat->LnArry[Line].LRLine, 0, WinPtr->_maxx+1);
X }
X return OK;
X}
X
Xdelwin(WinPtr)
X WINDOW *WinPtr;
X{
X struct WindowState *WinStat;
X int LineNo;
X
X if(!(CursesFlags & CFLAG_INITSCR))
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X if(!WinStat->ParentWin) {
X /* If it's a real window, free up Line, LRLine, ATTRS, LRATTRS */
X for(LineNo=0; LineNo<WinStat->NLines; LineNo++) {
X free(WinStat->LnArry[LineNo].Line);
X free(WinStat->LnArry[LineNo].LRLine);
X free(WinStat->LnArry[LineNo].ATTRS);
X free(WinStat->LnArry[LineNo].LRATTRS);
X }
X }
X /* Free up LnArry[] */
X free(WinStat->LnArry);
X /* Remove the winstat from the list */
X if(WinStat == HeadWindowList) { /* if this is first window (stdscr) */
X HeadWindowList = WinStat->Next;
X if(HeadWindowList)
X HeadWindowList->Prev = (struct WindowState *)NULL;
X } else {
X if(WinStat->Next)
X WinStat->Next->Prev = WinStat->Prev;
X if(WinStat->Prev)
X WinStat->Prev->Next = WinStat->Next;
X }
X /* Free the winstat */
X free(WinStat);
X return OK;
X}
X
X
Xmvwin(WinPtr, NewLine, NewCol)
X WINDOW *WinPtr;
X short NewLine, NewCol;
X{
X if(!(CursesFlags & CFLAG_INITSCR))
X return ERR;
X
X WinPtr->_begx = NewCol;
X WinPtr->_begy = NewLine;
X if(touchwin(WinPtr) == ERR)
X return ERR;
X return OK;
X}
X
Xscroll(WinPtr)
X WINDOW *WinPtr;
X{
X struct WindowState *WinStat;
X
X if(!(CursesFlags & CFLAG_INITSCR))
X return ERR;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X Scroll(WinPtr, WinStat->ScrollTop, WinStat->ScrollBot, SCROLL_UP);
X return OK;
X}
X
Xstatic Scroll(WinPtr, Top, Bottom, Direction)
X WINDOW *WinPtr;
X int Top, Bottom, Direction;
X{
X int Step, SLine, DLine, Col;
X char *TLine, *TLRLine;
X short *TATTRS, *TLRATTRS;
X struct WindowState *WinStat;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X
X /* Store pointers to line that will be lost */
X if(Direction == SCROLL_UP) {
X Step = +1;
X DLine = Top;
X SLine = Top + Step;
X } else {
X Step = -1;
X DLine = Bottom;
X SLine = Bottom + Step;
X }
X TLine = WinStat->LnArry[DLine].Line;
X TLRLine = WinStat->LnArry[DLine].LRLine;
X TATTRS = WinStat->LnArry[DLine].ATTRS;
X TLRATTRS = WinStat->LnArry[DLine].LRATTRS;
X /* Move the lines */
X for(;;) {
X if((Direction == SCROLL_UP) && (DLine >= Bottom))
X break; /* Done */
X if((Direction == SCROLL_DOWN) && (DLine <= Top))
X break; /* Done */
X WinStat->LnArry[DLine].Line = WinStat->LnArry[SLine].Line;
X WinStat->LnArry[DLine].LRLine = WinStat->LnArry[SLine].LRLine;
X WinStat->LnArry[DLine].ATTRS = WinStat->LnArry[SLine].ATTRS;
X WinStat->LnArry[DLine].LRATTRS = WinStat->LnArry[SLine].LRATTRS;
X for(Col=0; Col <= WinStat->Window._maxx; Col++) {
X WinStat->LnArry[DLine].ATTRS[Col] = WinStat->Window._attrs;
X WinStat->LnArry[DLine].LRATTRS[Col] = 0;
X }
X SLine += Step;
X DLine += Step;
X }
X /* Blank the Temp line */
X memset(TLine, ' ', WinStat->Window._maxx+1);
X memset(TLRLine, 0, WinStat->Window._maxx+1);
X for(Col=0; Col <= WinStat->Window._maxx; Col++) {
X TATTRS[Col] = WinStat->Window._attrs;
X TLRATTRS[Col] = 0;
X }
X /* move in temp line */
X WinStat->LnArry[DLine].Line = TLine;
X WinStat->LnArry[DLine].LRLine = TLRLine;
X WinStat->LnArry[DLine].ATTRS = TATTRS;
X WinStat->LnArry[DLine].LRATTRS = TLRATTRS;
X
X return OK;
X}
X
Xwsetscrreg(WinPtr, top, bottom)
X WINDOW *WinPtr;
X short top, bottom;
X{
X struct WindowState *WinStat;
X
X if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
X return ERR;
X WinStat->ScrollTop = top;
X WinStat->ScrollBot = bottom;
X return OK;
X}
X
Xscrollok(WinPtr, flag)
X WINDOW *WinPtr;
X int flag;
X{
X WinPtr->_scroll = (flag) ? TRUE : FALSE;
X return OK;
X}
X
X/*
X * Simple implementation of wnoutrefresh() and doupdate()
X *
X * Date: 8th Oct 1990
X *
X * Author: SJR
X *
X */
X
Xwnoutrefresh(WinPtr)
X WINDOW *WinPtr;
X{
X struct RefreshElement *NewRefEl;
X
X if(!(NewRefEl = (struct RefreshElement *)
X malloc(sizeof(struct RefreshElement))))
X return ERR;
X
X /* Fill the new element in */
X NewRefEl->Next = (struct RefreshElement *)NULL;
X NewRefEl->WinPtr = WinPtr;
X
X /* Add to start of refresh list */
X if(HeadRefreshList)
X NewRefEl->Next = HeadRefreshList;
X HeadRefreshList = NewRefEl;
X}
X
Xdoupdate()
X{
X struct RefreshElement *ElPtr;
X void ZapRElList();
X
X ElPtr = HeadRefreshList;
X while(ElPtr) {
X if(wrefresh(ElPtr->WinPtr) == ERR)
X return ERR;
X ElPtr = ElPtr->Next;
X }
X ZapRElList(HeadRefreshList);
X HeadRefreshList = (struct RefreshElement *)NULL;
X
X return OK;
X}
X
Xstatic void ZapRElList(ElPtr)
X struct RefreshElement *ElPtr;
X{
X if(!ElPtr)
X return;
X if(ElPtr->Next)
X ZapRElList(ElPtr->Next); /* Recurse my boy */
X free(ElPtr);
X}
X
Xstatic void Optimise(LinePtr)
X struct LineElement *LinePtr;
X{
X int i;
X
X if(!LinePtr->Touched)
X return;
X for(i=LinePtr->StartCol; i<=LinePtr->EndCol; i++) {
X if((LinePtr->Line[i] != LinePtr->LRLine[i]) ||
X (LinePtr->ATTRS[i] != LinePtr->LRATTRS[i]))
X break;
X LinePtr->StartCol++;
X }
X for(i=LinePtr->EndCol; i>=LinePtr->StartCol; i--) {
X if((LinePtr->Line[i] != LinePtr->LRLine[i]) ||
X (LinePtr->ATTRS[i] != LinePtr->LRATTRS[i]))
X break;
X LinePtr->EndCol--;
X }
X if(LinePtr->StartCol > LinePtr->EndCol)
X LinePtr->Touched = FALSE;
X}
END_OF_FILE
if test 44718 -ne `wc -c <'src/curses.c'`; then
echo shar: \"'src/curses.c'\" unpacked with wrong size!
fi
# end of 'src/curses.c'
fi
echo shar: End of archive 5 \(of 8\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 8 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.