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.