home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Module : curses.c
- *
- * Description : AMIGA CURSES package.
- *
- * Author : Simon Raybould (sie@fulcrum.bt.co.uk)
- *
- * Date V1.00a : 16th February 1990
- * V1.10 : 30th July 1990
- * V1.20a : 4th October 1990
- * V1.20 : 7th November 1990
- * V1.21 : 2nd December 1990 minor fixes
- * V1.22 : 7th January 1991 bug fixes
- *
- */
-
-
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/screens.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/audio.h>
-
- #include "acurses.h"
-
-
- /* Main background screen */
- static struct NewScreen NewScreen = {
- 0, /* LeftEdge */
- 0, /* TopEdge */
- 0, /* Width */
- 0, /* Height */
- 4, /* No. Bitplanes */
- 0, 1, /* DetailPen, BlockPen */
- HIRES, /* ViewModes */
- CUSTOMSCREEN, /* Screen type */
- (struct TextAttr *)NULL, /* default font */
- "Curses screen", /* Screen Title */
- (struct Gadget *)NULL, /* Gadget list */
- (struct BitMap *)NULL /* custom bitmap */
- };
-
- /* Main background window */
- static struct NewWindow NewWindow = {
- 0, /* Left edge */
- 0, /* Top edge */
- 0, /* Width */
- 0, /* Height */
- -1, -1, /* Pens */
- RAWKEY, /* IDCMP flags */
- ACTIVATE | BORDERLESS, /* Window flags */
- NULL, /* First gadget */
- NULL, /* Image data */
- NULL, /* Title */
- NULL, /* Pointer to screen structure */
- NULL, /* Super BitMap ? */
- 0,0,0,0, /* MIN/MAX sizing */
- CUSTOMSCREEN /* Type of screen */
- };
-
- /*
- * Make author appear when right mouse button is pressed.
- */
-
- static struct Menu _CursesMenu = {
- NULL, 0, 0, 0, 0, 0,
- " AMIGA CURSES by Simon J Raybould (sie@fulcrum.bt.co.uk) V1.22 07.Jan.1991",
- NULL, 0, 0, 0, 0
- };
-
- /*
- * Should initialise all of these to NULL to be certain that
- * CleanExit() will function correctly. Most compilers will do this
- * anyway, but better safe than GURUed.
- */
-
- struct IntuitionBase *IntuitionBase = NULL;
- struct GfxBase *GfxBase = NULL;
-
- struct ConsoleDevice *ConsoleDevice = NULL;
- static struct IOStdReq ioreq;
- static struct Screen *CursesScreen = NULL;
- static struct Window *CursesWindow = NULL;
-
- static struct RastPort *RPort;
- static struct ViewPort *VPort;
-
- static unsigned char CursesFlags; /* Global flags */
- static short CursorCol = 0,CursorLine = 0,LCursorLine = -1,LCursorCol = -1;
- static struct WindowState *HeadWindowList = (struct WindowState *)NULL;
- static struct RefreshElement *HeadRefreshList=(struct RefreshElement *)NULL;
- static struct IOAudio *AIOptr;
- static struct MsgPort *port;
- static ULONG device;
- static BYTE *sound_data;
- static UBYTE whichannel[] = { 1, 2, 4, 8 };
-
- /*
- * void internal functions
- */
-
- static void CleanExit(), CleanUp(), DoEcho();
- static void ZapCursor(), DrawCursor();
-
- /* Define a blank mouse pointer */
- static USHORT __chip MyMsPtr[] = { 0, 0, 0, 0 };
-
- #define NCOLOURS 32
-
- static UWORD ColourTable[] = {
- 0x000, 0xfff, 0xff0, 0xf80, 0x00f, 0xf0f, 0x0ff, 0xfff,
- 0x620, 0xe50, 0x9f1, 0xeb0, 0x55f, 0x92f, 0x0f8, 0xccc,
- 0x000, 0xd22, 0x000, 0xabc, 0x444, 0x555, 0x666, 0x777,
- 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff
- };
-
- WINDOW *stdscr = (WINDOW *)NULL, *curscr = (WINDOW *)NULL;
- int LINES=24, COLS=80; /* Defaults */
-
- /*
- * Need to be global so that flushinp() can reset them !
- */
- static unsigned char GetchRPos = 0, GetchWPos = 0;
-
- /*
- * Start of code.
- */
-
- initscr()
- {
- ULONG IBaseLock;
- char *Ptr, *getenv();
- int Tmp;
-
- /*
- * It would be devestating if someone called initscr() twice
- * so make the second call fail.
- */
- if(CursesFlags & CFLAG_INITSCR)
- return ERR;
-
- CursesFlags |= CFLAG_INITSCR; /* Mark that we have called initscr() */
-
- if((IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 0)) == NULL) {
- fprintf(stderr, "Failed to open Intuition library");
- CleanExit(10);
- }
- IBaseLock = LockIBase(0L);
- NewScreen.Height = NewWindow.Height = IntuitionBase->ActiveScreen->Height;
- NewScreen.Width = NewWindow.Width = IntuitionBase->ActiveScreen->Width;
- UnlockIBase(IBaseLock);
- /* Set interlace if height >= 400 */
- if(NewScreen.Height>=400)
- NewScreen.ViewModes |= LACE;
- LINES = NewScreen.Height/8;
- COLS = NewScreen.Width/8;
- /* if LINES and/or COLS set as environment variables then use them */
- if((Ptr = getenv("LINES"))) {
- Tmp = atoi(Ptr);
- if(Tmp>0 && Tmp<=LINES)
- LINES = Tmp;
- }
- if((Ptr = getenv("COLS"))) {
- Tmp = atoi(Ptr);
- if(Tmp>0 && Tmp<=COLS)
- COLS = Tmp;
- }
- /* Open graphics library */
- if((GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library", 0))==NULL) {
- fprintf(stderr, "Failed to open Graphics library");
- CleanExit(10);
- }
- /*
- * must have the console.device opened to use RawKeyConvert()
- */
-
- if(OpenDevice("console.device",-1L,(struct IORequest *)&ioreq,0L))
- CleanExit(10);
- ConsoleDevice=(struct ConsoleDevice *)ioreq.io_Device;
-
- if((CursesScreen=(struct Screen *)OpenScreen(&NewScreen)) == NULL) {
- fprintf(stderr, "Failed to open Screen");
- CleanExit(10);
- }
- RPort = &(CursesScreen->RastPort);
- VPort = &(CursesScreen->ViewPort);
- LoadRGB4(VPort, ColourTable, NCOLOURS);
- SetDrMd(RPort, JAM2);
- SetAPen(RPort, 1);
- NewWindow.Screen = CursesScreen; /* Must do this !! */
- if((CursesWindow=(struct Window *)OpenWindow(&NewWindow)) == NULL) {
- fprintf(stderr, "Failed to open Window\n");
- CleanExit(10);
- }
- SetMenuStrip(CursesWindow, &_CursesMenu);
- SetPointer(CursesWindow, MyMsPtr, 0, 0, 0, 0); /*Remove mouse pointer*/
- /* Create stdscr and curscr */
- stdscr = newwin(LINES, COLS, 0, 0);
- curscr = newwin(LINES, COLS, 0, 0); /* used for redraws */
- clearok(curscr, TRUE); /* Clear curscr on every refresh */
-
- CursesFlags = CFLAG_ECHO | CFLAG_NLCR | CFLAG_CURSOR | CFLAG_INITSCR;
- return OK;
- }
-
- /*
- * Close the screen and libraries.
- */
-
- endwin() /* called from main prior to exit. */
- {
- void ZapWindows();
-
- if(!(CursesFlags & CFLAG_INITSCR)) { /* haven't called initscr() */
- return ERR;
- }
- ZapWindows(HeadWindowList);
- CleanUp();
- CursesFlags &= ~CFLAG_INITSCR; /* Mark that we have called endwin() */
- return OK;
- }
-
- /* Recursive routine to zap all windows and release data structures */
- static void ZapWindows(WinStat)
- struct WindowState *WinStat;
- {
- if(!WinStat)
- return;
- if(WinStat->Next)
- ZapWindows(WinStat->Next); /* Recurse */
- delwin(&WinStat->Window);
- }
-
- static void CleanExit(RetCode)
- int RetCode;
- {
- CleanUp();
- exit(RetCode);
- }
-
- static void CleanUp()
- {
- if(CursesWindow)
- CloseWindow(CursesWindow);
- if(CursesScreen)
- CloseScreen(CursesScreen);
- if(GfxBase)
- CloseLibrary((struct Library *)GfxBase);
- if(IntuitionBase)
- CloseLibrary((struct Library *)IntuitionBase);
- }
-
- init_color(n, r, g, b)
- short n;
- unsigned char r, g, b;
- {
- if(n<0 || n>15 || r>1000 || g>1000 || b>1000)
- return ERR;
- /* If 0 then leave, else subtract 1 */
- if(r) r--;
- if(g) g--;
- if(g) g--;
-
- SetRGB4(VPort, n, r*16/1000, g*16/1000, b*16/1000);
- return OK;
- }
-
- start_color()
- {
- return OK; /* No initialisation required to get colours going */
- }
-
- has_colors()
- {
- return TRUE; /* Yes baby we have colours on this bitch */
- }
-
- /*
- * static because not implemented yet.
- */
- static color_content(color, r, g, b)
- short color, *r, *g, *b;
- {
- return OK;
- }
-
- waddstr(WinPtr, Str)
- WINDOW *WinPtr;
- char *Str;
- {
- struct WindowState *WinStat, *PWinStat = NULL;
- short TmpAttrs;
-
- if(!*Str)
- return OK;
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
- if(WinStat->ParentWin)
- if(!(PWinStat = (struct WindowState *)WinStat->ParentWin->_WinStat))
- return ERR;
-
- WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
- WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
- if(PWinStat) {
- PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].Touched = TRUE;
- PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury + WinPtr->_begy].StartCol, WinPtr->_curx + WinPtr->_begx);
- }
- while(*Str) {
- switch(*Str) {
- case '\t':
- do {
- WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx] = ' ';
- WinStat->LnArry[WinPtr->_cury].ATTRS[WinPtr->_curx++] = WinPtr->_attrs;
- } while(WinPtr->_curx % 8);
- break;
- case '\n':
- WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
- TmpAttrs = WinPtr->_attrs;
- wattrset(WinPtr, 0); /* better to call wattrset in case I change attrs */
- wclrtoeol(WinPtr);
- wattrset(WinPtr, TmpAttrs);
- if(PWinStat)
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol=max(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol,WinPtr->_curx+WinPtr->_begx-1);
- WinPtr->_curx = 0;
- WinPtr->_cury++;
- if(WinPtr->_cury > WinStat->ScrollBot) {
- if(WinPtr->_scroll)
- scroll(WinPtr);
- WinPtr->_cury = WinStat->ScrollBot;
- }
- if(*(Str + 1)) { /* If there is more then touch this line too */
- WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
- WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
- if(PWinStat) {
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].Touched = TRUE;
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol, WinPtr->_curx+WinPtr->_begx);
- }
- }
- break;
- default:
- WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx] = *Str;
- WinStat->LnArry[WinPtr->_cury].ATTRS[WinPtr->_curx] = WinPtr->_attrs;
- WinPtr->_curx++;
- break;
- }
- /* If hit right edge of window then increment _cury */
- if(WinPtr->_curx > WinPtr-> _maxx) {
- WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
- WinPtr->_curx = 0;
- WinPtr->_cury++;
- if(WinPtr->_cury > WinStat->ScrollBot) {
- if(WinPtr->_scroll)
- scroll(WinPtr);
- WinPtr->_cury = WinStat->ScrollBot;
- }
- if(WinPtr->_cury > WinPtr->_maxy)
- WinPtr->_cury = WinPtr->_maxy;
- if(*(Str + 1)) { /* If there is more then touch this line too */
- WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
- WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
- if(PWinStat) {
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].Touched = TRUE;
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol = min(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].StartCol, WinPtr->_curx+WinPtr->_begx);
- }
- }
- }
- Str++;
- }
- WinStat->LnArry[WinPtr->_cury].EndCol = max(WinStat->LnArry[WinPtr->_cury].EndCol, WinPtr->_curx - 1);
- if(PWinStat)
- PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol = max(PWinStat->LnArry[WinPtr->_cury+WinPtr->_begy].EndCol, WinPtr->_curx+WinPtr->_begx-1);
- return OK;
- }
-
- waddch(WinPtr, c)
- WINDOW *WinPtr;
- char c;
- {
- char *str = " ";
-
- *str = c;
- return waddstr(WinPtr, str);
- }
-
- winsch(WinPtr, c)
- WINDOW *WinPtr;
- char c;
- {
- int i;
- struct WindowState *WinStat;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- /* shuffle line along to the right */
- for (i = WinPtr->_maxx; i > WinPtr->_curx; i--)
- WinStat->LnArry[WinPtr->_cury].Line[i] = WinStat->LnArry[WinPtr->_cury].Line[i-1];
- WinStat->LnArry[WinPtr->_cury].Line[i] = c;
- WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
- WinStat->LnArry[WinPtr->_cury].EndCol = WinPtr->_maxx;
- WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
-
- return OK;
- }
-
- wdelch(WinPtr)
- WINDOW *WinPtr;
- {
- int i;
- struct WindowState *WinStat;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- /* shuffle line along to the left */
- for (i = WinPtr->_curx; i < WinPtr->_maxx; i++)
- WinStat->LnArry[WinPtr->_cury].Line[i] = WinStat->LnArry[WinPtr->_cury].Line[i+1];
- WinStat->LnArry[WinPtr->_cury].Line[i] = ' '; /* Blank last char */
- WinStat->LnArry[WinPtr->_cury].StartCol = min(WinStat->LnArry[WinPtr->_cury].StartCol, WinPtr->_curx);
- WinStat->LnArry[WinPtr->_cury].EndCol = WinPtr->_maxx;
- WinStat->LnArry[WinPtr->_cury].Touched = TRUE;
-
- return OK;
- }
-
- wclear(WinPtr)
- WINDOW *WinPtr;
- {
- int Line, Col;
- struct WindowState *WinStat;
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- for(Line=0; Line<WinStat->NLines; Line++) {
- memset(WinStat->LnArry[Line].Line, ' ', WinPtr->_maxx + 1);
- memset(WinStat->LnArry[Line].LRLine, ' ', WinPtr->_maxx + 1);
- for(Col = 0; Col <= WinPtr->_maxx; Col++) {
- WinStat->LnArry[Line].ATTRS[Col] = WinPtr->_attrs;
- WinStat->LnArry[Line].LRATTRS[Col] = WinPtr->_attrs;
- }
- WinStat->LnArry[Line].Touched = FALSE;
- WinStat->LnArry[Line].StartCol = WinPtr->_maxx;
- WinStat->LnArry[Line].EndCol = 0;
- }
- WinPtr->_curx = 0;
- WinPtr->_cury = 0;
- WinPtr->_cls = TRUE;
- return OK;
- }
-
- werase(WinPtr)
- WINDOW *WinPtr;
- {
- int Line, Col;
- struct WindowState *WinStat;
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- /* Blank screen image */
- for(Line=0; Line<WinStat->NLines; Line++) {
- memset(WinStat->LnArry[Line].Line, ' ', WinPtr->_maxx + 1);
- for(Col = 0; Col <= WinPtr->_maxx; Col++)
- WinStat->LnArry[Line].ATTRS[Col] = WinPtr->_attrs;
- WinStat->LnArry[Line].Touched = TRUE;
- WinStat->LnArry[Line].StartCol = 0;
- WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
- }
- WinPtr->_curx = 0;
- WinPtr->_cury = 0;
- return OK;
- }
-
- clearok(WinPtr, flag)
- WINDOW *WinPtr;
- int flag;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_clear = (flag) ? TRUE : FALSE;
-
- return OK;
- }
-
- wclrtoeol(WinPtr)
- WINDOW *WinPtr;
- {
- short x, y;
- int len;
- char Buffer[100];
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
- x = WinPtr->_curx;
- y = WinPtr->_cury;
-
- len = WinPtr->_maxx - WinPtr->_curx + 1;
- memset(Buffer, ' ', len);
- Buffer[len] = '\0';
-
- waddstr(WinPtr, Buffer);
- wmove(WinPtr, y, x);
-
- return OK;
- }
-
- wclrtobot(WinPtr)
- WINDOW *WinPtr;
- {
- short x, y;
- int i;
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
- x = WinPtr->_curx;
- y = WinPtr->_cury;
-
- wclrtoeol(WinPtr);
- for(i = WinPtr->_cury + 1; i <= WinPtr->_maxy; i++) {
- wmove(WinPtr, i, 0);
- wclrtoeol(WinPtr);
- }
- wmove(WinPtr, y, x);
-
- return OK;
- }
-
- static int GetNextChar(WinPtr)
- WINDOW *WinPtr;
- {
- static unsigned char buffer[RAWBUFSIZ], BufPos = 0, NumChars = 0;
- int Class, i;
- struct IntuiMessage *Message;
- static struct InputEvent ievent = { NULL, IECLASS_RAWKEY, 0, 0, 0 };
-
- if(BufPos < NumChars) /* If we still hav some chars then return next */
- return (int)buffer[BufPos++];
-
- while (BufPos == NumChars) {
- /* Get message if there is one allready queued */
- Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
- if(!Message) {
- /* Nuffin yet */
- if(WinPtr->_nodelay) /* If non-blocking return ERR */
- return ERR;
- else { /* Wait for character */
- Wait(1<<CursesWindow->UserPort->mp_SigBit);
- Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
- }
- }
- if(!Message) /* Try again */
- continue;
-
- Class = Message->Class;
- switch(Class) {
- case RAWKEY:
- BufPos = 0;
- ievent.ie_Code = Message->Code;
- ievent.ie_Qualifier = Message->Qualifier;
- ievent.ie_position.ie_addr = *((APTR*)Message->IAddress);
- NumChars = RawKeyConvert(&ievent, buffer, RAWBUFSIZ, 0L);
- ReplyMsg((struct Message *)Message);
- if(!NumChars) /* If no characters then try again */
- break;
- if(CursesFlags & CFLAG_ECHO)
- for(i=0; i<NumChars; i++)
- DoEcho(WinPtr, buffer[i]);
- /* Translate id keypad set to TRUE */
- if(WinPtr->_use_keypad) {
- switch(NumChars) {
- case 1:
- NumChars = 0; /* Translation will use up all chars */
- return (int)buffer[0];
- case 2: /* ARROW KEY */
- NumChars = 0; /* Translation will use up all chars */
- if(buffer[0] != 155)
- return -1;
- switch(buffer[1]) {
- case 65: return KEY_UP;
- case 66: return KEY_DOWN;
- case 67: return KEY_RIGHT;
- case 68: return KEY_LEFT;
- default: return -1;
- }
- case 3: /* FUNCTION KEY */
- NumChars = 0; /* Translation will use up all chars */
- if(buffer[0] != 155)
- return -1;
- if(buffer[2] != 126)
- return -1;
- if(buffer[1] == 63)
- return KEY_HELP;
- return KEY_F0 + (buffer[1] - 48); /* KEY_F0 = F1 */
- default:
- NumChars = 0; /* Translation will use up all chars */
- return -1;
- }
- }
- break;
- default:
- ReplyMsg((struct Message *)Message);
- break;
- }
- }
- return (int)buffer[BufPos++];
- }
-
- flushinp()
- {
- GetchRPos = 0;
- GetchWPos = 0;
- return OK;
- }
-
- wgetch(WinPtr)
- WINDOW *WinPtr;
- {
- static int buffer[256]; /* Cyclic buffer */
- static unsigned char forward = FALSE;
- int Ret;
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- while(GetchRPos == GetchWPos || (!(CursesFlags & CFLAG_CBREAK) && !forward)) {
- if(WinPtr->_nodelay)
- return GetNextChar(WinPtr);
- if((Ret = GetNextChar(WinPtr)) >= 0)
- buffer[GetchWPos++] = Ret;
- if(Ret == (int)'\r')
- forward = TRUE;
- }
- if(buffer[GetchRPos] == '\r') {
- buffer[GetchRPos] = '\n';
- forward = FALSE;
- }
- return((int)buffer[GetchRPos++]);
- }
-
- wgetstr(WinPtr, ptr)
- WINDOW *WinPtr;
- char *ptr;
- {
- char done = FALSE, *BuffStart;
- unsigned char TempFlag; /* Used to restore flags after */
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- BuffStart = ptr;
-
- /* Will need to be in CBREAK mode for this */
- TempFlag = CursesFlags;
- CursesFlags |= CFLAG_CBREAK;
- while(!done) {
- switch(*ptr = wgetch(WinPtr)) {
- case -1: /* wgetch() returned ERROR */
- *ptr = '\0';
- CursesFlags = TempFlag;
- return -1;
- case '\n':
- case '\r':
- *ptr = '\0';
- done = TRUE;
- break;
- case '\b':
- if(--ptr < BuffStart) /* Don't move before start */
- ptr = BuffStart;
- else if(CursesFlags & CFLAG_ECHO) {
- /* Do BS SP BS processing */
- mvcur(CursorLine, CursorCol, CursorLine, CursorCol - 1); /* BS */
- DoEcho(WinPtr, ' '); /* SP */
- mvcur(CursorLine, CursorCol, CursorLine, CursorCol - 1); /* BS */
- }
- break;
- default:
- ptr++;
- break;
- }
- }
- CursesFlags = TempFlag;
- return 0;
- }
-
- winch(WinPtr)
- WINDOW *WinPtr;
- {
- struct WindowState *WinStat;
-
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- return (int)WinStat->LnArry[WinPtr->_cury].Line[WinPtr->_curx];
- }
-
- static void DoEcho(WinPtr, c)
- WINDOW *WinPtr;
- char c;
- {
- short x, y;
- struct WindowState *WinStat;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return;
-
- if(c == BS || c == CR) /* Don't echo Backspace or Return */
- return;
-
- x = CursorCol * 8;
- y = 6 + CursorLine * 8;
- ZapCursor();
- SetDrMd(RPort, JAM2);
- SetAPen(RPort, WinPtr->_attrs & 0x0f);
- Move(RPort, x, y);
- Text(RPort, &c, 1);
- DrawCursor();
- /* Update curscr */
- if(WinPtr != curscr) {
- wmove(curscr, CursorLine, CursorCol);
- waddch(curscr, c);
- }
- /* Update Line structure */
- WinStat->LnArry[CursorLine-WinPtr->_begy].Line[CursorCol-WinPtr->_begx] = c;
- WinStat->LnArry[CursorLine-WinPtr->_begy].LRLine[CursorCol-WinPtr->_begx] = c;
- WinStat->LnArry[CursorLine-WinPtr->_begy].ATTRS[CursorCol-WinPtr->_begx] = WinPtr->_attrs;
- WinStat->LnArry[CursorLine-WinPtr->_begy].LRATTRS[CursorCol-WinPtr->_begx] = WinPtr->_attrs;
- /* Move current position one to the right */
- if(++WinPtr->_curx > WinPtr->_maxx)
- WinPtr->_curx = WinPtr->_maxx;
- mvcur(CursorLine, CursorCol, CursorLine, CursorCol + 1);
- }
-
- wmove(WinPtr, Line, Col)
- WINDOW *WinPtr;
- short Line, Col;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- if(Line<0 || Line>WinPtr->_maxy)
- return ERR;
- if(Col<0 || Col>WinPtr->_maxx)
- return ERR;
- WinPtr -> _cury = Line;
- WinPtr -> _curx = Col;
- WinPtr -> _flags |= CWF_MOVED;
- return OK;
- }
-
- mvcur(CurLine, CurCol, NewLine, NewCol)
- int CurLine, CurCol, NewLine, NewCol;
- {
- /* Could check CurLine and CurCol but this would make it fail too often */
- ZapCursor();
- CursorLine = NewLine;
- CursorCol = NewCol;
- DrawCursor();
- return OK;
- }
-
- printw(fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- char *fmt;
- double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- int Ret;
- char buffer[BUFSIZ];
-
- Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- waddstr(stdscr, buffer);
- return Ret;
- }
-
- wprintw(WinPtr, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- WINDOW *WinPtr;
- char *fmt;
- double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- int Ret;
- char buffer[BUFSIZ];
-
- Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- waddstr(WinPtr, buffer);
- return Ret;
- }
-
- mvprintw(Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- short Line, Col;
- char *fmt;
- double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- int Ret;
- char buffer[BUFSIZ];
-
- Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- wmove(stdscr, Line, Col);
- waddstr(stdscr, buffer);
- return Ret;
- }
-
- mvwprintw(WinPtr, Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- WINDOW *WinPtr;
- short Line, Col;
- char *fmt;
- double A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- int Ret;
- char buffer[BUFSIZ];
-
- Ret = sprintf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- wmove(WinPtr, Line, Col);
- waddstr(WinPtr, buffer);
- return Ret;
- }
-
- wrefresh(WinPtr)
- WINDOW *WinPtr;
- {
- int i, j;
- unsigned long style;
- short Line;
- struct WindowState *WinStat;
- char Buffer[BUFSIZ];
- void Optimise();
-
- if(WinPtr == curscr)
- touchwin(WinPtr);
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
- ZapCursor();
- /*
- * It is possible for no printing since last refresh, but for
- * a move to have been done...
- */
- if(WinPtr->_flags & CWF_MOVED) {
- WinPtr->_flags &= ~CWF_MOVED;
- CursorLine = WinPtr->_cury + WinPtr->_begy;
- CursorCol = WinPtr->_curx + WinPtr->_begx;
- }
- /*
- * If clearok has been called, then clear on every refresh.
- */
- if(WinPtr->_clear || WinPtr->_cls) {
- WinPtr->_cls = FALSE;
- SetAPen(RPort, 0);
- SetDrMd(RPort, JAM2);
- RectFill(RPort, (WinPtr->_begx * 8), (WinPtr->_begy * 8),
- ((WinPtr->_begx + WinPtr->_maxx) * 8) + 7,
- ((WinPtr->_begy + WinPtr->_maxy) * 8 + 7));
- }
- if(CursesFlags & CFLAG_CURSOR) {
- CursorLine = WinPtr->_cury + WinPtr->_begy;
- CursorCol = WinPtr->_curx + WinPtr->_begx;
- }
- for(Line=0; Line<WinStat->NLines; Line++) {
- /* if clearok set then must refresh everything */
- if(WinPtr->_clear) {
- memset(WinStat->LnArry[Line].LRLine, ' ', WinPtr->_maxx+1);
- WinStat->LnArry[Line].Touched = TRUE;
- WinStat->LnArry[Line].StartCol = 0;
- WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
- }
- Optimise(&WinStat->LnArry[Line]);
- if(WinStat->LnArry[Line].Touched) {
- j = WinStat->LnArry[Line].StartCol;
- for(i=WinStat->LnArry[Line].StartCol + 1; i<=WinStat->LnArry[Line].EndCol; i++) {
- if(WinStat->LnArry[Line].ATTRS[i] != WinStat->LnArry[Line].ATTRS[j]) {
- /* Print what we've got */
- SetAPen(RPort, WinStat->LnArry[Line].ATTRS[j] & 017);
- if(WinStat->LnArry[Line].ATTRS[j] & (A_REVERSE | A_STANDOUT))
- SetDrMd(RPort, JAM2|INVERSVID);
- else
- SetDrMd(RPort, JAM2);
- style = FS_NORMAL;
- if(WinStat->LnArry[Line].ATTRS[j] & A_BOLD)
- style |= FSF_BOLD;
- if(WinStat->LnArry[Line].ATTRS[j] & A_UNDERLINE)
- style |= FSF_UNDERLINED;
- SetSoftStyle(RPort, style, ~0L);
- Move(RPort, (j+WinPtr->_begx) * 8, 6 + (Line+WinPtr->_begy) * 8);
- Text(RPort, &WinStat->LnArry[Line].Line[j], i-j);
- /*
- * Update the record of the current screen state.
- */
- if(WinPtr != curscr) {
- wmove(curscr, Line+WinPtr->_begy, j+WinPtr->_begx);
- memcpy(Buffer, &WinStat->LnArry[Line].Line[j], i-j);
- Buffer[i-j] = '\0';
- waddstr(curscr, Buffer);
- }
- j = i;
- }
- }
- if(j < i) {
- SetAPen(RPort, WinStat->LnArry[Line].ATTRS[j] & 017);
- if(WinStat->LnArry[Line].ATTRS[j] & (A_STANDOUT | A_REVERSE))
- SetDrMd(RPort, JAM2|INVERSVID);
- else
- SetDrMd(RPort, JAM2);
- style = FS_NORMAL;
- if(WinStat->LnArry[Line].ATTRS[j] & A_BOLD)
- style |= FSF_BOLD;
- if(WinStat->LnArry[Line].ATTRS[j] & A_UNDERLINE)
- style |= FSF_UNDERLINED;
- SetSoftStyle(RPort, style, ~0L);
- Move(RPort, (j+WinPtr->_begx) * 8, 6 + (Line+WinPtr->_begy) * 8);
- Text(RPort, &(WinStat->LnArry[Line].Line[j]), i-j);
- /*
- * Update the record of the current screen state.
- */
- if(WinPtr != curscr) {
- wmove(curscr, Line+WinPtr->_begy, j+WinPtr->_begx);
- memcpy(Buffer, &WinStat->LnArry[Line].Line[j], i-j);
- Buffer[i-j] = '\0';
- waddstr(curscr, Buffer);
- }
- }
- WinStat->LnArry[Line].Touched = FALSE;
- WinStat->LnArry[Line].StartCol = WinPtr->_maxx;
- WinStat->LnArry[Line].EndCol = 0;
- }
- /*
- * Copy line and attrs to LR for Optimise code
- */
- memcpy(WinStat->LnArry[Line].LRLine, WinStat->LnArry[Line].Line, WinPtr->_maxx+1);
- memcpy(WinStat->LnArry[Line].LRATTRS, WinStat->LnArry[Line].ATTRS, sizeof(short) * (WinPtr->_maxx+1));
- }
- DrawCursor();
- return OK;
- }
-
- static void ToggleCursor(Line, Col)
- {
- SetDrMd(RPort, JAM2 | INVERSVID | COMPLEMENT);
- Move(RPort, Col*8, 6 + Line*8);
- Text(RPort, " ", 1);
- }
-
- static void
- ZapCursor()
- {
- /* If there was a cursor then blank it */
- if(LCursorCol >= 0 && LCursorLine >= 0)
- ToggleCursor(LCursorLine, LCursorCol);
-
- LCursorCol = LCursorLine = -1;
- }
-
- static void DrawCursor()
- {
- /* Draw cursor */
- if(CursesFlags & CFLAG_CURSOR)
- ToggleCursor(CursorLine, CursorCol);
-
- if(CursesFlags & CFLAG_CURSOR) {
- LCursorCol = CursorCol;
- LCursorLine = CursorLine;
- } else {
- LCursorCol = -1;
- LCursorLine = -1;
- }
- }
-
- scanw(fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- char *fmt;
- long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- char buffer[BUFSIZ];
-
- wgetstr(stdscr, buffer);
- return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- }
-
- wscanw(WinPtr, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- WINDOW *WinPtr;
- char *fmt;
- long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- char buffer[BUFSIZ];
-
- wgetstr(WinPtr, buffer);
- return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- }
-
- mvscanw(Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- short Line, Col;
- char *fmt;
- long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- char buffer[BUFSIZ];
-
- wmove(stdscr, Line, Col);
- wgetstr(stdscr, buffer);
- return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- }
-
- mvwscanw(WinPtr, Line, Col, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
- WINDOW *WinPtr;
- short Line, Col;
- char *fmt;
- long A0, A1, A2, A3, A4, A5, A6, A7, A8, A9;
- {
- char buffer[BUFSIZ];
-
- wmove(WinPtr, Line, Col);
- wgetstr(WinPtr, buffer);
- return sscanf(buffer, fmt, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9);
- }
-
- wstandout(WinPtr)
- WINDOW *WinPtr;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_attrs |= A_STANDOUT;
- }
-
- wstandend(WinPtr)
- WINDOW *WinPtr;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_attrs &= ~A_STANDOUT;
- }
-
- wattrset(WinPtr, attr)
- WINDOW *WinPtr;
- short attr;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- /*
- * Older code may inadvertently reset the attributes and set the
- * forground colour to 0, in this case, set it to white.
- */
- if(!(attr & 017))
- attr |= COLOR_WHITE;
-
- WinPtr->_attrs = attr;
- return OK;
- }
-
- wattron(WinPtr, attr)
- WINDOW *WinPtr;
- short attr;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- /* If attributes contain a colour change then mask off old colour */
- if(attr & 017)
- WinPtr->_attrs &= ~017;
-
- WinPtr->_attrs |= attr;
- return OK;
- }
-
- wattroff(WinPtr, attr)
- WINDOW *WinPtr;
- short attr;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_attrs &= ~attr;
- return OK;
- }
-
- cbreak()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags |= CFLAG_CBREAK;
- return OK;
- }
-
- nocbreak()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags &= ~CFLAG_CBREAK;
- return OK;
- }
-
- raw()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags |= CFLAG_CBREAK;
- return OK;
- }
-
- noraw()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags &= ~CFLAG_CBREAK;
- return OK;
- }
-
- idlok(WinPtr, flag)
- WINDOW *WinPtr;
- int flag;
- {
- /* This function is to enable hardware insert/delete line */
- return OK;
- }
-
- winsertln(WinPtr)
- WINDOW *WinPtr;
- {
- Scroll(WinPtr, WinPtr->_cury, WinPtr->_maxy, SCROLL_DOWN);
- return OK;
- }
-
- wdeleteln(WinPtr)
- WINDOW *WinPtr;
- {
- Scroll(WinPtr, WinPtr->_cury, WinPtr->_maxy, SCROLL_UP);
- return OK;
- }
-
- nodelay(WinPtr, flag)
- WINDOW *WinPtr;
- int flag;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_nodelay = flag;
- return OK;
- }
-
- echo()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags |= CFLAG_ECHO;
- return OK;
- }
-
- noecho()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- CursesFlags &= ~CFLAG_ECHO;
- return OK;
- }
-
- keypad(WinPtr, flag)
- WINDOW *WinPtr;
- char flag;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- WinPtr->_use_keypad = flag?TRUE:FALSE;
-
- return OK;
- }
-
- beep()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- AIOptr = (struct IOAudio *) AllocMem(sizeof(struct IOAudio), MEMF_CHIP|MEMF_PUBLIC);
- if(!AIOptr)
- exit(1);
-
- port = (struct MsgPort *)CreatePort(0, 0);
- if(!port) {
- FreeMem(AIOptr, sizeof(struct IOAudio));
- return ERR;
- }
-
- AIOptr->ioa_Request.io_Message.mn_ReplyPort = port;
- AIOptr->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
- AIOptr->ioa_Request.io_Command = ADCMD_ALLOCATE;
- AIOptr->ioa_Request.io_Flags = ADIOF_NOWAIT;
- AIOptr->ioa_AllocKey = 0;
- AIOptr->ioa_Data = whichannel;
- AIOptr->ioa_Length = sizeof(whichannel);
-
- device = OpenDevice("audio.device", 0L, (struct IORequest *)AIOptr, 0L);
- if(device) {
- printf("Curses beep() - Can't open Audio Device\n");
- FreeMem(AIOptr, sizeof(struct IOAudio));
- return ERR;
- }
-
- sound_data = (UBYTE *) AllocMem(SOUNDLENGTH, MEMF_CHIP|MEMF_PUBLIC);
- if(!sound_data) {
- FreeMem(AIOptr, sizeof(struct IOAudio));
- return ERR;
- }
-
- sound_data[0]=127;
- sound_data[1]=-127;
-
- AIOptr->ioa_Request.io_Message.mn_ReplyPort = port;
- AIOptr->ioa_Request.io_Command = CMD_WRITE;
- AIOptr->ioa_Request.io_Flags = ADIOF_PERVOL;
- AIOptr->ioa_Data = sound_data;
- AIOptr->ioa_Cycles = 200;
- AIOptr->ioa_Length = SOUNDLENGTH;
- AIOptr->ioa_Period = 2000;
- AIOptr->ioa_Volume = 64;
-
- BeginIO((struct IORequest *)AIOptr);
- WaitIO((struct IORequest *)AIOptr);
-
- FreeMem(sound_data, SOUNDLENGTH);
- DeletePort(port);
- CloseDevice((struct IORequest *)AIOptr);
- FreeMem(AIOptr, sizeof(struct IOAudio));
- }
-
- flash()
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- DisplayBeep(CursesScreen);
- }
-
- leaveok(WinPtr, flag)
- WINDOW *WinPtr;
- int flag;
- {
- if(!(CursesFlags & CFLAG_INITSCR)) /* Haven't called initscr() */
- return ERR;
-
- if(flag) {
- CursorCol = CursorLine = -1;
- CursesFlags &= ~CFLAG_CURSOR;
- } else {
- CursesFlags |= CFLAG_CURSOR;
- }
- return OK;
- }
-
- resetty()
- {
- return OK;
- }
-
- savetty()
- {
- return OK;
- }
-
- resetterm()
- {
- return OK;
- }
-
- fixterm()
- {
- return OK;
- }
-
- saveterm()
- {
- return OK;
- }
-
- baudrate()
- {
- return 9600;
- }
-
- nl()
- {
- CursesFlags |= CFLAG_NLCR;
- return OK;
- }
-
- nonl()
- {
- CursesFlags &= ~CFLAG_NLCR;
- return OK;
- }
-
- crmode()
- {
- return (cbreak());
- }
-
- nocrmode()
- {
- return (nocbreak());
- }
-
- box(WinPtr, vert, hor)
- WINDOW *WinPtr;
- char vert, hor;
- {
- int i;
- short CurY, CurX;
-
- CurY = WinPtr->_cury;
- CurX = WinPtr->_curx;
-
- if(vert < 32 || vert > 126)
- vert = '|';
- if(hor < 32 || hor > 126)
- hor = '-';
-
- for(i=0; i<=WinPtr->_maxx; i++) {
- mvwaddch(WinPtr, 0, i, hor); /* Top horizontal */
- mvwaddch(WinPtr, WinPtr->_maxy, i, hor); /* Bottom horizontal */
- }
- for(i=1; i<WinPtr->_maxy; i++) {
- mvwaddch(WinPtr, i, 0, vert); /* Left vertical */
- mvwaddch(WinPtr, i, WinPtr->_maxx, vert); /* Right vertical */
- }
- WinPtr -> _cury = CurY;
- WinPtr -> _curx = CurX;
- return OK;
- }
-
- WINDOW *subwin(Orig, NLines, NCols, StartLine, StartCol)
- WINDOW *Orig;
- unsigned int NLines, NCols, StartLine, StartCol;
- {
- WINDOW *WinPtr, *CreatWindow();
-
- if(!(WinPtr = CreatWindow(NLines, NCols, StartLine, StartCol, Orig))) {
- printf("WARNING - subwin() failed, returning stdscr !!\n");
- return stdscr; /* Failed */
- }
- return WinPtr;
- }
-
- WINDOW *newwin(NLines, NCols, StartLine, StartCol)
- unsigned int NLines, NCols, StartLine, StartCol;
- {
- WINDOW *WinPtr, *CreatWindow();
-
- if(!(WinPtr = CreatWindow(NLines, NCols, StartLine, StartCol, NULL))) {
- printf("WARNING - newwin() failed, returning stdscr !!\n");
- return stdscr; /* Failed */
- }
- wclear(WinPtr);
- return WinPtr;
- }
-
- /* Orig is NULL and StartCol/Line are not used for newwin() calls */
- static WINDOW *CreatWindow(NLines, NCols, StartLine, StartCol, Orig)
- int NLines, NCols, StartLine, StartCol;
- WINDOW *Orig;
- {
- int Line, j;
- struct WindowState *NewWinStat, *TmpWinPtr, *OrgWinStat = NULL;
- char *malloc();
-
- /* If either are zero then make them max */
- if(!NLines)
- NLines = LINES - StartLine;
- if(!NCols)
- NCols = COLS - StartCol;
-
- if(NLines>LINES || NCols>COLS || StartLine>LINES || StartCol>COLS)
- return (struct WINDOW *)NULL;
-
- if(StartLine < 0)
- StartLine = 0;
- if(StartCol < 0)
- StartCol = 0;
- if(Orig)
- OrgWinStat = (struct WindowState *)Orig->_WinStat;
-
- /* Create a new WinStat structure */
- if((NewWinStat=(struct WindowState *)malloc(sizeof(struct WindowState)))
- == (struct WindowState *)NULL) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- NewWinStat->ParentWin = Orig;
- NewWinStat->Next = (struct WindowState *)NULL;
- NewWinStat->Prev = (struct WindowState *)NULL;
- NewWinStat->ScrollTop = 0;
- NewWinStat->ScrollBot = NLines - 1;
- NewWinStat->NLines = NLines;
- /* Allocate space for LnArry[] */
- if(!(NewWinStat->LnArry = (struct LineElement *)malloc(sizeof(struct LineElement)*LINES))) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- /* Allocate space for Line, LRLine e.t.c */
- for(Line = 0; Line < NLines; Line++) {
- if(OrgWinStat) { /* If this is a subwindow */
- /* Set up pointers into parent window */
- NewWinStat->LnArry[Line].Line =
- &OrgWinStat->LnArry[Line+StartLine].Line[StartCol];
- NewWinStat->LnArry[Line].LRLine =
- &OrgWinStat->LnArry[Line+StartLine].LRLine[StartCol];
- NewWinStat->LnArry[Line].ATTRS =
- &OrgWinStat->LnArry[Line+StartLine].ATTRS[StartCol];
- NewWinStat->LnArry[Line].LRATTRS =
- &OrgWinStat->LnArry[Line+StartLine].LRATTRS[StartCol];
- } else { /* New window, allocate space for lines */
- /* malloc lines and ATTRS */
- if((NewWinStat->LnArry[Line].Line = malloc(NCols)) == NULL) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- if((NewWinStat->LnArry[Line].LRLine = malloc(NCols)) == NULL) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- if((NewWinStat->LnArry[Line].ATTRS =
- (short *)malloc(NCols*sizeof(short))) == NULL) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- if((NewWinStat->LnArry[Line].LRATTRS =
- (short *)malloc(NCols*sizeof(short))) == NULL) {
- fprintf(stderr, "CreatWindow() - Not enough memory\n");
- return (struct WINDOW *)NULL;
- }
- /* The optimiser will untouch any lines not used */
- memset(NewWinStat->LnArry[Line].LRLine, ' ', NCols);
- for(j=0; j<NCols; j++)
- NewWinStat->LnArry[Line].LRATTRS[j] = A_NORMAL | COLOR_WHITE;
- }
- NewWinStat->LnArry[Line].Touched = FALSE;
- NewWinStat->LnArry[Line].StartCol = NCols;
- NewWinStat->LnArry[Line].EndCol = 0;
- }
- /* Add to Window Stat list */
- if(HeadWindowList) {
- TmpWinPtr = HeadWindowList;
- while(TmpWinPtr->Next)
- TmpWinPtr = TmpWinPtr->Next;
- TmpWinPtr->Next = NewWinStat;
- NewWinStat->Prev = TmpWinPtr;
- } else {
- /* This is the first window i.e. stdscr */
- HeadWindowList = NewWinStat;
- }
- /* Initialise state of the window structure */
- NewWinStat->Window._cury = 0;
- NewWinStat->Window._curx = 0;
- NewWinStat->Window._maxy = NLines - 1;
- NewWinStat->Window._maxx = NCols - 1;
- NewWinStat->Window._begy = StartLine;
- NewWinStat->Window._begx = StartCol;
- NewWinStat->Window._flags = 0;
- NewWinStat->Window._attrs = A_NORMAL | COLOR_WHITE;
- NewWinStat->Window._clear = FALSE;
- NewWinStat->Window._cls = TRUE;
- NewWinStat->Window._scroll = FALSE;
- NewWinStat->Window._use_keypad = 0;
- NewWinStat->Window._use_meta = 0;
- NewWinStat->Window._nodelay = 0;
- NewWinStat->Window._WinStat = (char *)NewWinStat;
-
- return &NewWinStat->Window;
- }
-
- touchwin(WinPtr)
- WINDOW *WinPtr;
- {
- struct WindowState *WinStat;
- int Line;
-
- if(!(CursesFlags & CFLAG_INITSCR))
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- for(Line=0; Line<WinStat->NLines; Line++) {
- WinStat->LnArry[Line].Touched = TRUE;
- /* Mark whole line as refreshable */
- WinStat->LnArry[Line].StartCol = 0;
- WinStat->LnArry[Line].EndCol = WinPtr->_maxx;
- /* Dump optimisation */
- memset(WinStat->LnArry[Line].LRLine, 0, WinPtr->_maxx+1);
- }
- return OK;
- }
-
- delwin(WinPtr)
- WINDOW *WinPtr;
- {
- struct WindowState *WinStat;
- int LineNo;
-
- if(!(CursesFlags & CFLAG_INITSCR))
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- if(!WinStat->ParentWin) {
- /* If it's a real window, free up Line, LRLine, ATTRS, LRATTRS */
- for(LineNo=0; LineNo<WinStat->NLines; LineNo++) {
- free(WinStat->LnArry[LineNo].Line);
- free(WinStat->LnArry[LineNo].LRLine);
- free(WinStat->LnArry[LineNo].ATTRS);
- free(WinStat->LnArry[LineNo].LRATTRS);
- }
- }
- /* Free up LnArry[] */
- free(WinStat->LnArry);
- /* Remove the winstat from the list */
- if(WinStat == HeadWindowList) { /* if this is first window (stdscr) */
- HeadWindowList = WinStat->Next;
- if(HeadWindowList)
- HeadWindowList->Prev = (struct WindowState *)NULL;
- } else {
- if(WinStat->Next)
- WinStat->Next->Prev = WinStat->Prev;
- if(WinStat->Prev)
- WinStat->Prev->Next = WinStat->Next;
- }
- /* Free the winstat */
- free(WinStat);
- return OK;
- }
-
-
- mvwin(WinPtr, NewLine, NewCol)
- WINDOW *WinPtr;
- short NewLine, NewCol;
- {
- if(!(CursesFlags & CFLAG_INITSCR))
- return ERR;
-
- WinPtr->_begx = NewCol;
- WinPtr->_begy = NewLine;
- if(touchwin(WinPtr) == ERR)
- return ERR;
- return OK;
- }
-
- scroll(WinPtr)
- WINDOW *WinPtr;
- {
- struct WindowState *WinStat;
-
- if(!(CursesFlags & CFLAG_INITSCR))
- return ERR;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- Scroll(WinPtr, WinStat->ScrollTop, WinStat->ScrollBot, SCROLL_UP);
- return OK;
- }
-
- static Scroll(WinPtr, Top, Bottom, Direction)
- WINDOW *WinPtr;
- int Top, Bottom, Direction;
- {
- int Step, SLine, DLine, Col;
- char *TLine, *TLRLine;
- short *TATTRS, *TLRATTRS;
- struct WindowState *WinStat;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
-
- /* Store pointers to line that will be lost */
- if(Direction == SCROLL_UP) {
- Step = +1;
- DLine = Top;
- SLine = Top + Step;
- } else {
- Step = -1;
- DLine = Bottom;
- SLine = Bottom + Step;
- }
- TLine = WinStat->LnArry[DLine].Line;
- TLRLine = WinStat->LnArry[DLine].LRLine;
- TATTRS = WinStat->LnArry[DLine].ATTRS;
- TLRATTRS = WinStat->LnArry[DLine].LRATTRS;
- /* Move the lines */
- for(;;) {
- if((Direction == SCROLL_UP) && (DLine >= Bottom))
- break; /* Done */
- if((Direction == SCROLL_DOWN) && (DLine <= Top))
- break; /* Done */
- WinStat->LnArry[DLine].Line = WinStat->LnArry[SLine].Line;
- WinStat->LnArry[DLine].LRLine = WinStat->LnArry[SLine].LRLine;
- WinStat->LnArry[DLine].ATTRS = WinStat->LnArry[SLine].ATTRS;
- WinStat->LnArry[DLine].LRATTRS = WinStat->LnArry[SLine].LRATTRS;
- for(Col=0; Col <= WinStat->Window._maxx; Col++) {
- WinStat->LnArry[DLine].ATTRS[Col] = WinStat->Window._attrs;
- WinStat->LnArry[DLine].LRATTRS[Col] = 0;
- }
- SLine += Step;
- DLine += Step;
- }
- /* Blank the Temp line */
- memset(TLine, ' ', WinStat->Window._maxx+1);
- memset(TLRLine, 0, WinStat->Window._maxx+1);
- for(Col=0; Col <= WinStat->Window._maxx; Col++) {
- TATTRS[Col] = WinStat->Window._attrs;
- TLRATTRS[Col] = 0;
- }
- /* move in temp line */
- WinStat->LnArry[DLine].Line = TLine;
- WinStat->LnArry[DLine].LRLine = TLRLine;
- WinStat->LnArry[DLine].ATTRS = TATTRS;
- WinStat->LnArry[DLine].LRATTRS = TLRATTRS;
-
- return OK;
- }
-
- wsetscrreg(WinPtr, top, bottom)
- WINDOW *WinPtr;
- short top, bottom;
- {
- struct WindowState *WinStat;
-
- if(!(WinStat = (struct WindowState *)WinPtr->_WinStat))
- return ERR;
- WinStat->ScrollTop = top;
- WinStat->ScrollBot = bottom;
- return OK;
- }
-
- scrollok(WinPtr, flag)
- WINDOW *WinPtr;
- int flag;
- {
- WinPtr->_scroll = (flag) ? TRUE : FALSE;
- return OK;
- }
-
- /*
- * Simple implementation of wnoutrefresh() and doupdate()
- *
- * Date: 8th Oct 1990
- *
- * Author: SJR
- *
- */
-
- wnoutrefresh(WinPtr)
- WINDOW *WinPtr;
- {
- struct RefreshElement *NewRefEl;
-
- if(!(NewRefEl = (struct RefreshElement *)
- malloc(sizeof(struct RefreshElement))))
- return ERR;
-
- /* Fill the new element in */
- NewRefEl->Next = (struct RefreshElement *)NULL;
- NewRefEl->WinPtr = WinPtr;
-
- /* Add to start of refresh list */
- if(HeadRefreshList)
- NewRefEl->Next = HeadRefreshList;
- HeadRefreshList = NewRefEl;
- }
-
- doupdate()
- {
- struct RefreshElement *ElPtr;
- void ZapRElList();
-
- ElPtr = HeadRefreshList;
- while(ElPtr) {
- if(wrefresh(ElPtr->WinPtr) == ERR)
- return ERR;
- ElPtr = ElPtr->Next;
- }
- ZapRElList(HeadRefreshList);
- HeadRefreshList = (struct RefreshElement *)NULL;
-
- return OK;
- }
-
- static void ZapRElList(ElPtr)
- struct RefreshElement *ElPtr;
- {
- if(!ElPtr)
- return;
- if(ElPtr->Next)
- ZapRElList(ElPtr->Next); /* Recurse my boy */
- free(ElPtr);
- }
-
- static void Optimise(LinePtr)
- struct LineElement *LinePtr;
- {
- int i;
-
- if(!LinePtr->Touched)
- return;
- for(i=LinePtr->StartCol; i<=LinePtr->EndCol; i++) {
- if((LinePtr->Line[i] != LinePtr->LRLine[i]) ||
- (LinePtr->ATTRS[i] != LinePtr->LRATTRS[i]))
- break;
- LinePtr->StartCol++;
- }
- for(i=LinePtr->EndCol; i>=LinePtr->StartCol; i--) {
- if((LinePtr->Line[i] != LinePtr->LRLine[i]) ||
- (LinePtr->ATTRS[i] != LinePtr->LRATTRS[i]))
- break;
- LinePtr->EndCol--;
- }
- if(LinePtr->StartCol > LinePtr->EndCol)
- LinePtr->Touched = FALSE;
- }
-