home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header * Header built automatically - do not edit! *************
- *
- * (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
- *
- * Name .....: TermBuffer.c
- * Created ..: Monday 21-Jan-91 20:12
- * Revision .: 0
- *
- * Date Author Comment
- * ========= ======== ====================
- * 21-Jan-91 Olsen Created this file!
- *
- * $Revision Header ********************************************************/
-
- #include "TermGlobal.h"
-
- /* Some private data (render info & window). */
-
- STATIC struct Window *BufferWindow;
- STATIC struct Screen *BufferScreen;
-
- struct Gadget *BufferGadget;
-
- STATIC struct RastPort *BPort;
- STATIC APTR BufferVisualInfo;
-
- STATIC LONG BufLine,BufCols;
-
- STATIC BYTE MarkedArea;
-
- STATIC BYTE BufferTerminated;
-
- enum { MEN_SEARCH,MEN_REPEAT,MEN_GOTO,MEN_CLEARBUF,MEN_CLOSEBUF,MEN_QUITBUF };
- enum { MEN_OKAY=1,MEN_CANCEL,MEN_QUITPANEL=4 };
-
- STATIC struct NewMenu BufferMenu[] =
- {
- { NM_TITLE, "Project", 0 , 0, 0, (APTR)0},
- { NM_ITEM, "Search...", "S", 0, 0, (APTR)MEN_SEARCH},
- { NM_ITEM, "Repeat Search", "R", 0, 0, (APTR)MEN_REPEAT},
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
- { NM_ITEM, "Go To Main Screen", "B", 0, 0, (APTR)MEN_GOTO},
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
- { NM_ITEM, "Clear Buffer", "K", 0, 0, (APTR)MEN_CLEARBUF},
- { NM_ITEM, "Close Buffer", "C", 0, 0, (APTR)MEN_CLOSEBUF},
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
- { NM_ITEM, "Quit", "Q", 0, 0, (APTR)MEN_QUITBUF},
- { NM_END, 0, 0 , 0, 0, (APTR)0}
- };
-
- /* AllocString(UBYTE *String,SHORT Len):
- *
- + Allocate space for a string.
- */
-
- STATIC UBYTE *
- AllocString(UBYTE *String,SHORT Len)
- {
- ULONG *Mem;
-
- if(Mem = AllocMem(sizeof(ULONG) + Len,MEMF_PUBLIC))
- {
- *Mem++ = Len;
-
- CopyMem(String,Mem,Len);
-
- String = (UBYTE *)Mem;
-
- return(String);
- }
-
- return(NULL);
- }
-
- /* FreeString(UBYTE *String):
- *
- * Free the space occupied by a string.
- */
-
- STATIC VOID
- FreeString(UBYTE *String)
- {
- FreeMem(&((ULONG *)String)[-1],((ULONG *)String)[-1] + sizeof(ULONG));
- }
-
- /* AddLine(UBYTE *Line,LONG Size):
- *
- * Add a line to the display buffer.
- */
-
- VOID
- AddLine(UBYTE *Line,LONG Size)
- {
- ULONG Signals = 0;
-
- /* Is the buffer array initialized? */
-
- if(BufferLines)
- {
- /* Pick up the global access semaphore
- * (two tasks are sharing the data).
- */
-
- ObtainSemaphore(BufferSemaphore);
-
- /* We've reached the last line in the buffer. */
-
- if(Lines == MaxLines)
- {
- UBYTE **MoreBuffer;
- LONG i;
-
- /* Allocate space for some more lines. */
-
- if(MoreBuffer = (UBYTE **)AllocVec((MaxLines + 100) * sizeof(UBYTE *),MEMF_PUBLIC|MEMF_CLEAR))
- {
- /* Copy the old lines to the new
- * buffer.
- */
-
- for(i = 0 ; i < Lines ; i++)
- MoreBuffer[i] = BufferLines[i];
-
- /* Free the old lines. */
-
- FreeVec(BufferLines);
-
- /* Set the new buffer. */
-
- MaxLines += 100;
-
- BufferLines = MoreBuffer;
- }
- else
- {
- /* We couldn't get enough memory
- * to extend the number of lines
- * in the buffer, so we'll have
- * to wrap the contents of the
- * buffer around.
- */
-
- if(Lines)
- {
- BufferSpace -= ((ULONG *)BufferLines[0])[-1];
-
- FreeString(BufferLines[0]);
-
- for(i = 1 ; i < MaxLines ; i++)
- BufferLines[i - 1] = BufferLines[i];
-
- Lines--;
-
- /* Tell the buffer task to
- * refresh the display.
- */
-
- Signals = SIGBREAKF_CTRL_F;
- }
- }
- }
-
- /* Allocate a new line and copy the buffer contents
- * into it.
- */
-
- if(BufferLines[Lines++] = AllocString(Line,Size))
- BufferSpace += Size;
-
- ReleaseSemaphore(BufferSemaphore);
-
- /* Tell the buffer task to update the display. */
-
- if(!Signals)
- Signals = SIGBREAKF_CTRL_E;
-
- if(BufferProcess)
- Signal(BufferProcess,Signals);
- }
- }
-
- /* ClearBuffer():
- *
- * Clear the current display buffer and flush the contents
- * of the buffered capture file handles.
- */
-
- VOID
- ClearBuffer()
- {
- SHORT i;
-
- if(BufferProcess)
- {
- Signal(BufferProcess,SIGBREAKF_CTRL_C);
-
- Wait(SIGBREAKF_CTRL_C);
- }
-
- if(FileCapture)
- Flush(FileCapture);
-
- if(PrinterCapture)
- Flush(PrinterCapture);
-
- /* Free the contents of the display buffer. */
-
- if(BufferLines)
- {
- for(i = 0 ; i < Lines ; i++)
- {
- if(BufferLines[i])
- FreeString(BufferLines[i]);
- }
-
- FreeVec(BufferLines);
-
- BufferLines = NULL;
-
- Lines = 0;
-
- MaxLines = 100;
-
- BufferLines = (UBYTE **)AllocVec(MaxLines * sizeof(UBYTE *),MEMF_PUBLIC|MEMF_CLEAR);
- }
-
- BufferSpace = 0;
- }
-
- /* StoreBuffer(APTR Buffer,LONG Size):
- *
- * Store data in the display buffer.
- */
-
- VOID
- StoreBuffer(APTR Buffer,LONG Size)
- {
- STATIC UBYTE LineBuffer[200];
- STATIC LONG BufferCount = 0;
-
- UBYTE *CharBuffer = Buffer;
- LONG i;
-
- for(i = 0 ; i < Size ; i++)
- {
- /* Look which char we are to handle. */
-
- switch(CharBuffer[i])
- {
- /* Ignore the following characters. */
-
- case FFD:
- case BEL:
- case DEL:
- case VTB:
- case XON:
- case XOF: continue;
-
- /* Move the cursor to the next tab
- * stop.
- */
-
- case TAB: if(BufferCount + 8 < LastColumn)
- {
- strcpy(&LineBuffer[BufferCount]," ");
-
- BufferCount += 8;
-
- break;
- }
-
- continue;
-
- /* Move the cursor one step back. */
-
- case BKS: if(BufferCount)
- BufferCount--;
-
- continue;
-
- /* Terminate the current line. */
-
- case ENT:
- case RET: AddLine(LineBuffer,BufferCount);
-
- BufferCount = 0;
- continue;
-
- /* Stuff the character into the buffer. */
-
- default: LineBuffer[BufferCount++] = CharBuffer[i];
- break;
- }
-
- /* The line is full, add it to the display buffer. */
-
- if(BufferCount > LastColumn)
- {
- AddLine(LineBuffer,BufferCount);
-
- BufferCount = 0;
- }
- }
- }
-
- /* FlushIMsg(struct Window *Window):
- *
- + Clear the MsgPort of a window.
- */
-
- STATIC VOID
- FlushIMsg(struct Window *Window)
- {
- struct IntuiMessage *Massage;
-
- while(Massage = GT_GetIMsg(Window -> UserPort))
- GT_ReplyIMsg(Massage);
- }
-
- /* CreateAllGadgets():
- *
- * Create all the gadgets required by the
- * buffer screen (i.e. the scroller gadget).
- */
-
- STATIC struct Gadget *
- CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList)
- {
- struct Gadget *Gadget;
- struct NewGadget NewGadget;
-
- if(Gadget = CreateContext(GadgetList))
- {
- memset(&NewGadget,0,sizeof(struct NewGadget));
-
- NewGadget . ng_Width = 16;
- NewGadget . ng_Height = BufferWindow -> Height;
- NewGadget . ng_TextAttr = &DefaultFont;
- NewGadget . ng_VisualInfo = BufferVisualInfo;
- NewGadget . ng_GadgetID = 0;
- NewGadget . ng_LeftEdge = BufferWindow -> Width - 16;
- NewGadget . ng_TopEdge = 0;
-
- GadgetArray[0] = Gadget = CreateGadget(SCROLLER_KIND,Gadget,&NewGadget,
- GTSC_Arrows, (Config . DisplayMode & LACE) ? 16 : 8,
- PGA_Freedom, LORIENT_VERT,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- TAG_DONE);
- }
-
- return(Gadget);
- }
-
- /* GetSearchString(UBYTE *Buffer):
- *
- * Prompt user for a string to search the buffer for.
- */
-
- STATIC BYTE
- GetSearchString(UBYTE *Buffer)
- {
- struct Gadget *GadgetList;
- struct Gadget *GadgetArray[4];
- struct Window *PanelWindow;
- struct Menu *PanelMenu;
- LONG Width;
- UBYTE OtherBuffer[256];
- BYTE Success = FALSE;
-
- strcpy(OtherBuffer,Buffer);
-
- if(CreateAllGetsGadgets(FALSE,OtherBuffer,"Enter Search String",&Width,&GadgetArray[0],&GadgetList,BufferVisualInfo,BufferScreen -> WBorTop + BufferScreen -> Font -> ta_YSize + 1))
- {
- if(PanelMenu = CreateMenus(GetsMenu,
- GTMN_FrontPen, 0,
- TAG_DONE))
- {
- if(LayoutMenus(PanelMenu,VisualInfo,
- GTMN_TextAttr,&DefaultFont,
- TAG_DONE))
- {
- if(PanelWindow = OpenWindowTags(NULL,
- WA_Width, Width,
- WA_Height, 56,
-
- WA_Left, (BufferScreen -> Width - Width) >> 1,
- WA_Top, (BufferScreen -> Height - 56) >> 1,
-
- WA_Activate, TRUE,
- WA_DragBar, TRUE,
- WA_DepthGadget, TRUE,
- WA_CloseGadget, TRUE,
- WA_RMBTrap, TRUE,
- WA_CustomScreen,BufferScreen,
-
- WA_IDCMP, IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_MENUPICK,
-
- WA_Title, "Enter Search String",
- TAG_DONE))
- {
- struct IntuiMessage *Massage;
- ULONG Class,Code;
- struct Gadget *Gadget;
- BYTE Terminated = FALSE;
- struct StringExtend PanelExtend;
- ULONG SignalSet;
-
- CopyMem(&CommandExtend,&PanelExtend,sizeof(struct StringExtend));
-
- PanelExtend . Pens[0] = 1;
- PanelExtend . Pens[1] = 0;
-
- PanelExtend . Pens[2] = 1;
- PanelExtend . Pens[3] = 0;
-
- ((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> Extension = &PanelExtend;
-
- AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
- RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
- GT_RefreshWindow(PanelWindow,NULL);
-
- SetMenuStrip(PanelWindow,PanelMenu);
-
- PanelWindow -> Flags &= ~WFLG_RMBTRAP;
-
- ActiveGadget = GadgetArray[0];
-
- ActivateGadget(GadgetArray[0],PanelWindow,NULL);
-
- while(!Terminated)
- {
- SignalSet = Wait((1 << PanelWindow -> UserPort -> mp_SigBit) | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_C);
-
- if(SignalSet & SIGBREAKF_CTRL_D)
- {
- BumpWindow(PanelWindow);
-
- ActivateGadget(GadgetArray[0],PanelWindow,NULL);
- }
-
- if(SignalSet & SIGBREAKF_CTRL_C)
- {
- BufferTerminated = TRUE;
- Terminated = TRUE;
- }
-
- if(SignalSet & (1 << PanelWindow -> UserPort -> mp_SigBit))
- {
- while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
- {
- Class = Massage -> Class;
- Code = Massage -> Code;
- Gadget = (struct Gadget *)Massage -> IAddress;
-
- GT_ReplyIMsg(Massage);
-
- if(Class == IDCMP_MENUPICK)
- {
- struct MenuItem *MenuItem;
-
- while(Code != MENUNULL)
- {
- MenuItem = ItemAddress(PanelMenu,Code);
-
- switch((ULONG)MENU_USERDATA(MenuItem))
- {
- case MEN_CANCEL:
- case MEN_QUITPANEL: Class = IDCMP_CLOSEWINDOW;
- break;
-
- case MEN_OKAY: strcpy(Buffer,((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> Buffer);
-
- Success = TRUE;
-
- Terminated = TRUE;
- break;
- }
-
- Code = MenuItem -> NextSelect;
- }
-
- if(ActiveGadget)
- ActivateGadget(ActiveGadget,PanelWindow,NULL);
- }
-
- if(Class == IDCMP_ACTIVEWINDOW)
- ActivateGadget(GadgetArray[0],PanelWindow,NULL);
-
- if(Class == IDCMP_CLOSEWINDOW)
- Terminated = TRUE;
-
- if(Class == IDCMP_GADGETUP)
- {
- switch(Gadget -> GadgetID)
- {
- case 0:
- case 1: if(((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> Buffer[0])
- {
- strcpy(Buffer,((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> Buffer);
-
- Success = TRUE;
- }
-
- Terminated = TRUE;
- break;
-
- case 3: Terminated = TRUE;
- break;
- }
- }
- }
- }
- }
-
- PanelWindow -> Flags |= WFLG_RMBTRAP;
-
- ClearMenuStrip(PanelWindow);
-
- RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
-
- CloseWindow(PanelWindow);
- }
-
- FreeGadgets(GadgetList);
- }
-
- FreeMenus(PanelMenu);
- }
- }
-
- return(Success);
- }
-
- /* PrintLine(UBYTE *Buffer,LONG LineNumber):
- *
- * Print a line at a given line number in the displayed area.
- */
-
- STATIC VOID
- PrintLine(UBYTE *Buffer,LONG LineNumber)
- {
- SHORT Length = ((ULONG *)Buffer)[-1];
-
- /* The line doesn't exactly fill the displayed line,
- * so erase the remaining columns.
- */
-
- if(Length < BufCols)
- {
- SetAPen(BPort,0);
-
- RectFill(BPort,Length << 3,LineNumber << 3,(BufCols << 3) - 1,((LineNumber + 1) << 3) - 1);
-
- SetAPen(BPort,1);
- }
-
- /* Print the text. */
-
- if(Length)
- {
- Move(BPort,0,(LineNumber << 3) + 6);
-
- if(Length > BufCols)
- Text(BPort,Buffer,BufCols);
- else
- Text(BPort,Buffer,Length);
- }
- }
-
- /* RedrawScreen(LONG FirstLine):
- *
- * Redraw the contents of the entire screen and return the
- * number of lines actually drawn.
- */
-
- STATIC LONG
- RedrawScreen(LONG FirstLine)
- {
- LONG i,Last,Line = 0;
-
- /* Determine last line to display. */
-
- if((Last = FirstLine + BufLine) >= Lines)
- Last = Lines;
-
- /* Obtain the access semaphore and display the single
- * lines.
- */
-
- ObtainSemaphore(BufferSemaphore);
-
- for(i = FirstLine ; i < Last ; i++)
- PrintLine(BufferLines[i],Line++);
-
- ReleaseSemaphore(BufferSemaphore);
-
- /* We didn't fill the whole screen, so clear the rest. */
-
- if(Line < BufLine)
- {
- SetAPen(BPort,0);
-
- RectFill(BPort,0,Line << 3,BufferWindow -> Width - (1 + 16),BufferWindow -> Height - 1);
-
- SetAPen(BPort,1);
- }
-
- return(Line);
- }
-
- /* MarkArea(SHORT Column,SHORT Line,SHORT Length):
- *
- * Mark an area in the term Buffer window.
- */
-
- STATIC VOID
- MarkArea(SHORT Column,SHORT Line,SHORT Length)
- {
- STATIC SHORT OldColumn = -1,OldLine = -1,OldLength = -1;
-
- if(OldColumn != Column || OldLine != Line || OldLength != Length)
- {
- if(OldColumn != -1)
- ClipBlit(BPort,0,0,BPort,OldColumn << 3,OldLine << 3,OldLength << 3,8,0x50);
-
- MarkedArea = TRUE;
-
- if(Column != -1)
- ClipBlit(BPort,0,0,BPort,Column << 3,Line << 3,Length << 3,8,0x50);
- else
- MarkedArea = FALSE;
- }
-
- OldColumn = Column;
- OldLine = Line;
- OldLength = Length;
- }
-
- /* Search():
- *
- * String search function, based on the Boyer-Moore search
- * algorithm.
- */
-
- STATIC LONG
- Search(UBYTE *Pattern,LONG *FoundX,LONG *FoundY,LONG *SaveX)
- {
- UBYTE Distance[256],NewPattern[256],PatternWidth,SearchWidth;
- LONG LineNumber = -1,i;
- SHORT j,k,l;
-
- /* Determine length of search pattern. */
-
- PatternWidth = strlen(Pattern);
-
- /* Convert search pattern to upper cse. */
-
- for(i = 0 ; i <= PatternWidth ; i++)
- NewPattern[i] = ToUpper(Pattern[i]);
-
- /* Create distance table. */
-
- for(i = 0 ; i < 256 ; i++)
- Distance[i] = PatternWidth;
-
- for(i = 0 ; i < PatternWidth - 1 ; i++)
- Distance[NewPattern[i]] = PatternWidth - i - 1;
-
- /* Run down the buffer. */
-
- for(i = *FoundY ; i < Lines ; i++)
- {
- /* Is there anything to search for? */
-
- if(SearchWidth = ((ULONG *)BufferLines[i])[-1])
- {
- /* Cast the magick spell of
- * Boyer-Moore...
- */
-
- j = PatternWidth;
-
- do
- {
- k = PatternWidth;
- l = j;
-
- do
- {
- k--;
- l--;
- }
- while(k >= 0 && NewPattern[k] == ToUpper(BufferLines[i][l]));
-
- j += Distance[ToUpper(BufferLines[i][j - 1])];
- }
- while(k >= 0 && j <= SearchWidth);
-
- /* Found first occurence, set up the
- * data and quit.
- */
-
- if(k < 0)
- {
- *FoundX = l + 1;
- *FoundY = LineNumber = i;
-
- *SaveX = l + 1;
-
- if(BufferLines[i][*FoundX + 1])
- *FoundX++;
- else
- {
- if(*FoundY - 1 < Lines)
- {
- *FoundX = 0;
- *FoundY++;
- }
- }
-
- return(LineNumber);
- }
- else
- *FoundX = 0;
- }
- }
-
- return(LineNumber);
- }
-
- /* BufferServer():
- *
- * Asynchronous task to display the data stored in the
- * scrollback display buffer.
- */
-
- VOID __saveds
- BufferServer()
- {
- struct ColorSpec ColorSpec[3];
-
- ULONG SignalSet;
-
- struct IntuiMessage *Massage;
- ULONG Class,Code,Qualifier;
- UBYTE Char,LastChar = 0;
-
- LONG CurrentLine,DisplayedLines;
-
- UBYTE PercentBuffer[80];
-
- struct Menu *BufferMenuStrip;
-
- STATIC UBYTE SearchBuffer[256];
- LONG LineNumber,SaveX,FoundX = 0,FoundY = 0;
- ULONG DisplayMode;
-
- struct Rectangle DisplayClip;
-
- UWORD SomeColour;
-
- struct Gadget *GadgetList;
- struct Gadget *GadgetArray[1];
-
- BYTE Scrolling = FALSE;
-
- BufferTerminated = FALSE;
-
- /* Set up the startup colours for our buffer screen. */
-
- ColorSpec[0] . ColorIndex = 0;
- ColorSpec[0] . Red = (Config . Colours[0] >> 8) & 0xF;
- ColorSpec[0] . Green = (Config . Colours[0] >> 4) & 0xF;
- ColorSpec[0] . Blue = (Config . Colours[0] ) & 0xF;
-
- switch(Config . ColourMode)
- {
- case COLOUR_EIGHT: SomeColour = Config . Colours[7];
- break;
-
- case COLOUR_SIXTEEN: SomeColour = Config . Colours[15];
- break;
-
- case COLOUR_AMIGA:
- default: SomeColour = Config . Colours[1];
- break;
- }
-
- ColorSpec[1] . ColorIndex = 1;
- ColorSpec[1] . Red = (SomeColour >> 8) & 0xF;
- ColorSpec[1] . Green = (SomeColour >> 4) & 0xF;
- ColorSpec[1] . Blue = (SomeColour ) & 0xF;
-
- ColorSpec[2] . ColorIndex = -1;
-
- /* We'll use a fixed screen width, only the
- * height is adapted from the main screen.
- */
-
- if(Config . DisplayMode & LACE)
- {
- if(!ModeNotAvailable(VGAPRODUCT_KEY))
- DisplayMode = VGAPRODUCT_KEY;
- else
- DisplayMode = HIRESLACE_KEY;
- }
- else
- DisplayMode = HIRES_KEY;
-
- /* Inquire the text overscan dimensions. */
-
- if(QueryOverscan(DisplayMode,&DisplayClip,OSCAN_TEXT))
- {
- /* Centre the buffer screen. */
-
- if(DisplayClip . MaxX - DisplayClip . MinX + 1 > 640 + 16)
- {
- SHORT Differ = ((DisplayClip . MaxX - DisplayClip . MinX + 1) - (640 + 16)) >> 1;
-
- DisplayClip . MinX += Differ;
- DisplayClip . MaxX -= Differ;
- }
-
- /* Open a single bitplane clone of the main screen. */
-
- if(BufferScreen = (struct Screen *)OpenScreenTags(NULL,
- SA_Title, "term Buffer",
- SA_Depth, 1,
- SA_DClip, &DisplayClip,
- SA_DisplayID, DisplayMode,
- SA_Font, &DefaultFont,
- SA_Behind, TRUE,
- SA_AutoScroll, TRUE,
- SA_Colors, ColorSpec,
- TAG_END))
- {
- if(BufferVisualInfo = GetVisualInfo(BufferScreen,TAG_DONE))
- {
- if(BufferMenuStrip = CreateMenus(BufferMenu,
- GTMN_FrontPen, 0,
- TAG_DONE))
- {
- if(LayoutMenus(BufferMenuStrip,BufferVisualInfo,
- GTMN_TextAttr,&DefaultFont,
- TAG_DONE))
- {
- /* Open a cute window on our buffer screen. */
-
- if(BufferWindow = OpenWindowTags(NULL,
- WA_Top, BufferScreen -> BarHeight + 2,
- WA_Left, 0,
- WA_Width, BufferScreen -> Width,
- WA_Height, BufferScreen -> Height - (Screen -> BarHeight + 2),
- WA_Backdrop, TRUE,
- WA_Borderless, TRUE,
- WA_SmartRefresh,FALSE,
- WA_CustomScreen,BufferScreen,
- WA_RMBTrap, TRUE,
- WA_RptQueue, 1,
- WA_IDCMP, ARROWIDCMP | SCROLLERIDCMP | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK,
- TAG_DONE))
- {
- if(CreateAllGadgets(&GadgetArray[0],&GadgetList))
- {
- /* Signal our father process that
- * we're running.
- */
-
- Signal(ThisProcess,SIGBREAKF_CTRL_C);
-
- SetMenuStrip(BufferWindow,BufferMenuStrip);
-
- BufferGadget = GadgetArray[0];
-
- AddGList(BufferWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
- RefreshGList(GadgetList,BufferWindow,NULL,(UWORD)-1);
- GT_RefreshWindow(BufferWindow,NULL);
-
- Restart: /* Set the IBM font if necessary. */
-
- BPort = BufferWindow -> RPort;
-
- if(Config . Font == FONT_IBM && IBM)
- SetFont(BPort,IBM);
-
- /* Determine maximum dimensions of
- * the buffer screen (in rows and
- * columns).
- */
-
- BufCols = (BufferWindow -> Width - 16) >> 3;
- BufLine = BufferWindow -> Height >> 3;
-
- /* Bring the screen to the front. */
-
- BumpWindow(BufferWindow);
-
- /* Set the drawing pens for the window. */
-
- SetAPen(BPort,1);
- SetBPen(BPort,0);
- SetDrMd(BPort,JAM2);
-
- /* Initial creation of the buffer display. */
-
- DisplayedLines = RedrawScreen(CurrentLine = 0);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, 0,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
-
- BufferWindow -> Flags &= ~WFLG_RMBTRAP;
-
- while(!BufferTerminated)
- {
- /* Show where we are. */
-
- if(Lines)
- {
- SetAPen(BufferScreen -> BarLayer -> rp,0);
- SetBPen(BufferScreen -> BarLayer -> rp,1);
- SetDrMd(BufferScreen -> BarLayer -> rp,JAM2);
-
- SPrintf(PercentBuffer,"%04ld/%04ld (%3ld%%) %ld Bytes Total ",CurrentLine,Lines > BufLine ? Lines - BufLine : 0,(100 * (CurrentLine + DisplayedLines)) / Lines,BufferSpace);
-
- Move(BufferScreen -> BarLayer -> rp,101,7);
- Text(BufferScreen -> BarLayer -> rp,PercentBuffer,strlen(PercentBuffer));
- }
-
- SignalSet = Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F | (1 << BufferWindow -> UserPort -> mp_SigBit));
-
- /* Leave the town? */
-
- if(SignalSet & SIGBREAKF_CTRL_C)
- BufferTerminated = TRUE;
-
- /* Bring our window to the front. */
-
- if(SignalSet & SIGBREAKF_CTRL_D)
- BumpWindow(BufferWindow);
-
- /* We've got one more line in the
- * buffer.
- */
-
- if(SignalSet & SIGBREAKF_CTRL_E)
- {
- if(Lines - CurrentLine > DisplayedLines && DisplayedLines < BufLine)
- PrintLine(BufferLines[CurrentLine + DisplayedLines],DisplayedLines++);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- /* The contents of the buffer have moved
- * up a line.
- */
-
- if(SignalSet & SIGBREAKF_CTRL_F)
- {
- if(DisplayedLines)
- ScrollRaster(BPort,0,-8,0,0,(BufCols << 3) - 1,(DisplayedLines << 3) - 1);
-
- CurrentLine--;
-
- ObtainSemaphore(BufferSemaphore);
-
- PrintLine(BufferLines[CurrentLine],0);
-
- ReleaseSemaphore(BufferSemaphore);
-
- if(DisplayedLines < BufLine)
- DisplayedLines++;
-
- if(FoundY)
- FoundY--;
- }
-
- /* Process the incoming window
- * input.
- */
-
- while(!BufferTerminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(BufferWindow -> UserPort)))
- {
- Class = Massage -> Class;
- Code = Massage -> Code;
- Qualifier = Massage -> Qualifier;
-
- /* This hack is necessary to obtain the
- * character codes generated for the cursor
- * keys. A control or alternate qualifier
- * would spoil the result (i.e. we would
- * not get a valid key code).
- */
-
- Massage -> Qualifier = NULL;
-
- Char = KeyConvert(Massage,NULL);
-
- /* Just in case anybody needs it... */
-
- Massage -> Qualifier = Qualifier;
-
- GT_ReplyIMsg(Massage);
-
- if(Class == IDCMP_GADGETUP)
- Scrolling = FALSE;
-
- if(Class == IDCMP_GADGETDOWN)
- Scrolling = TRUE;
-
- if((Class == IDCMP_MOUSEMOVE && Scrolling) || Class == IDCMP_GADGETDOWN)
- {
- if(Code != CurrentLine)
- {
- if(ABS(CurrentLine - Code) == 1)
- {
- Qualifier = NULL;
- Class = IDCMP_RAWKEY;
-
- if(Code > CurrentLine)
- Code = CDN;
- else
- Code = CUP;
-
- goto UseKey;
- }
- else
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- DisplayedLines = RedrawScreen(CurrentLine = Code);
- }
- }
- }
-
- if(Class == IDCMP_RAWKEY)
- {
- if(LastChar && (Code & IECODE_UP_PREFIX))
- {
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- if(LastChar = Char)
- {
- /* Use the numeric keypad keys to
- * move through the buffer.
- */
-
- UseKey: if(Qualifier & IEQUALIFIER_NUMERICPAD)
- {
- /* Remove the numpad qualifier. */
-
- Qualifier &= ~IEQUALIFIER_NUMERICPAD;
-
- switch(Char - '0')
- {
- /* Jump to bottom. */
-
- case 1: Char = CDN;
- Qualifier |= IEQUALIFIER_CONTROL;
- break;
-
- /* Jump to top. */
-
- case 7: Char = CUP;
- Qualifier |= IEQUALIFIER_CONTROL;
- break;
-
- /* Move one page down. */
-
- case 3: Char = CDN;
- Qualifier |= IEQUALIFIER_LSHIFT;
- break;
-
- /* Move one page up. */
-
- case 9: Char = CUP;
- Qualifier |= IEQUALIFIER_LSHIFT;
- break;
-
- /* Move one line down. */
-
- case 2: Char = CDN;
- break;
-
- /* Move one line up. */
-
- case 8: Char = CUP;
- break;
- }
- }
-
- /* Check cursor keys. */
-
- switch(Char)
- {
- /* Scroll the buffer up. */
-
- case CUP: if(Qualifier & IEQUALIFIER_CONTROL)
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(CurrentLine)
- {
- DisplayedLines = RedrawScreen(CurrentLine = 0);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, 0,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- break;
- }
-
- if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- {
- LONG NewCurrentLine;
-
- if((NewCurrentLine = CurrentLine - BufLine) < 0)
- NewCurrentLine = 0;
-
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(NewCurrentLine != CurrentLine)
- {
- DisplayedLines = RedrawScreen(CurrentLine = NewCurrentLine);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- break;
- }
-
- if(CurrentLine)
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(DisplayedLines)
- ScrollRaster(BPort,0,-8,0,0,(BufCols << 3) - 1,(DisplayedLines << 3) - 1);
-
- CurrentLine--;
-
- ObtainSemaphore(BufferSemaphore);
-
- PrintLine(BufferLines[CurrentLine],0);
-
- ReleaseSemaphore(BufferSemaphore);
-
- if(DisplayedLines < BufLine)
- DisplayedLines++;
- }
-
- break;
-
- /* Scroll the buffer down. */
-
- case CDN: if(Qualifier & IEQUALIFIER_CONTROL)
- {
- LONG NewCurrentLine;
-
- if((NewCurrentLine = Lines - BufLine) < 0)
- NewCurrentLine = 0;
-
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(CurrentLine != NewCurrentLine)
- {
- DisplayedLines = RedrawScreen(CurrentLine = NewCurrentLine);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- break;
- }
-
- if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- {
- LONG NewCurrentLine;
-
- if((NewCurrentLine = CurrentLine + (2 * BufLine)) > Lines)
- NewCurrentLine = Lines;
-
- if((NewCurrentLine = NewCurrentLine - BufLine) < 0)
- NewCurrentLine = 0;
-
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(NewCurrentLine != CurrentLine)
- {
- DisplayedLines = RedrawScreen(CurrentLine = NewCurrentLine);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
-
- break;
- }
-
- if(CurrentLine + BufLine < Lines)
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(DisplayedLines)
- ScrollRaster(BPort,0,8,0,0,(BufCols << 3) - 1,(DisplayedLines << 3) - 1);
-
- ObtainSemaphore(BufferSemaphore);
-
- PrintLine(BufferLines[CurrentLine + BufLine],BufLine - 1);
-
- ReleaseSemaphore(BufferSemaphore);
-
- CurrentLine++;
-
- if(DisplayedLines < BufLine)
- DisplayedLines++;
- }
-
- break;
-
- default: break;
- }
- }
-
- continue;
- }
-
- /* User hit a mouse button. */
-
- if(Class == IDCMP_MOUSEBUTTONS)
- {
- BYTE SkipLoop = FALSE;
- LONG ThisLine,ThisColumn,MyColumn,LastColumn,SomeColumn;
- UBYTE *TheLine;
-
- /* Remember initial mouse position. */
-
- ThisColumn = Massage -> MouseX >> 3;
- ThisLine = Massage -> MouseY >> 3;
-
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- /* Reasonable dimensions? */
-
- if(ThisLine < DisplayedLines)
- {
- /* Find the approriate line and its length. */
-
- TheLine = BufferLines[CurrentLine + ThisLine];
- LastColumn = ((ULONG *)BufferLines[CurrentLine + ThisLine])[-1];
-
- /* Resonable dimensions? */
-
- if(ThisColumn < LastColumn)
- {
- MyColumn = ThisColumn;
-
- ReportMouse(TRUE,BufferWindow);
-
- /* Loop until left mouse button is release. */
-
- while(!SkipLoop)
- {
- SignalSet = Wait(SIGBREAKF_CTRL_F | (1 << BufferWindow -> UserPort -> mp_SigBit));
-
- /* Contents of the buffer has changed! */
-
- if(SignalSet & SIGBREAKF_CTRL_F)
- {
- if(FoundY)
- FoundY--;
-
- DisplayBeep(BufferScreen);
- break;
- }
-
- while(Massage = (struct IntuiMessage *)GetMsg(BufferWindow -> UserPort))
- {
- Class = Massage -> Class;
- Code = Massage -> Code;
-
- ReplyMsg(Massage);
-
- /* We're finished! */
-
- if(Class == IDCMP_MOUSEBUTTONS && Code == SELECTUP)
- {
- SkipLoop = TRUE;
-
- /* Did we get a reasonable mouse
- * position?
- */
-
- if(MyColumn != ThisColumn)
- {
- /* Preserve right order of
- * numbers.
- */
-
- if(MyColumn < ThisColumn)
- {
- LONG Help;
-
- Help = ThisColumn;
- ThisColumn = MyColumn;
- MyColumn = Help;
- }
-
- /* Restore the line. */
-
- if(MyColumn < LastColumn)
- LastColumn = MyColumn;
-
- MarkArea(-1,-1,-1);
-
- /* Clip the contents of the line to
- * the clipboard.
- */
-
- SaveClip(&TheLine[ThisColumn],MyColumn - ThisColumn);
- }
-
- break;
- }
-
- /* The mouse has moved. */
-
- if(Class == IDCMP_MOUSEMOVE)
- {
- STATIC LONG OldColumn = ~0;
-
- /* Determine new mouse position. */
-
- SomeColumn = MyColumn;
-
- MyColumn = Massage -> MouseX >> 3;
-
- if((Massage -> MouseY >> 3) < ThisLine)
- MyColumn = 0;
-
- if((Massage -> MouseY >> 3) > ThisLine)
- MyColumn = LastColumn;
-
- /* Don't redraw the line if nothing
- * has changed.
- */
-
- if(OldColumn != MyColumn)
- {
- OldColumn = MyColumn;
-
- /* Reasonable position? */
-
- if(MyColumn <= LastColumn)
- {
- if(MyColumn >= 0)
- {
- /* Highlight the selected
- * area (invert).
- */
-
- if(MyColumn != ThisColumn)
- {
- if(MyColumn < ThisColumn)
- MarkArea(MyColumn,ThisLine,ThisColumn - MyColumn);
- else
- MarkArea(ThisColumn,ThisLine,MyColumn - ThisColumn);
- }
- }
- }
- else
- MyColumn = SomeColumn;
- }
- }
- }
- }
-
- ReportMouse(FALSE,BufferWindow);
- }
- }
- }
-
- if(Class == IDCMP_MENUPICK)
- {
- struct MenuItem *MenuItem;
-
- while(Code != MENUNULL)
- {
- MenuItem = ItemAddress(BufferMenuStrip,Code);
-
- switch((ULONG)MENU_USERDATA(MenuItem))
- {
- case MEN_SEARCH: BufferWindow -> Flags |= WFLG_RMBTRAP;
- SetWait(BufferWindow);
-
- GetTheString: if(Lines)
- {
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GA_Disabled,TRUE,
- TAG_DONE);
-
- if(GetSearchString(SearchBuffer))
- {
- FoundX = FoundY = 0;
-
- SearchForIt: LineNumber = -1;
-
- if(FoundY == 0 && CurrentLine != 0)
- FoundY = CurrentLine;
-
- ObtainSemaphore(BufferSemaphore);
-
- LineNumber = Search(SearchBuffer,&FoundX,&FoundY,&SaveX);
-
- ReleaseSemaphore(BufferSemaphore);
-
- if(LineNumber == -1)
- {
- BlockWindows();
-
- MyEasyRequest(BufferWindow,"Didn't find \"%s\".","Continue",SearchBuffer);
-
- ReleaseWindows();
-
- FlushIMsg(BufferWindow);
-
- FoundX = FoundY = 0;
-
- if(MarkedArea)
- MarkArea(-1,-1,-1);
- }
- else
- {
- if(LineNumber < CurrentLine)
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- DisplayedLines = RedrawScreen(CurrentLine = 0);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
- else
- {
- if(LineNumber > CurrentLine + DisplayedLines - 1)
- {
- if(MarkedArea)
- MarkArea(-1,-1,-1);
-
- if(LineNumber >= Lines - BufLine)
- {
- LONG NewCurrentLine;
-
- if((NewCurrentLine = Lines - BufLine) < 0)
- NewCurrentLine = 0;
-
- if(CurrentLine != NewCurrentLine)
- {
- DisplayedLines = RedrawScreen(CurrentLine = NewCurrentLine);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
- }
- else
- {
- DisplayedLines = RedrawScreen(CurrentLine = LineNumber);
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GTSC_Top, CurrentLine,
- GTSC_Total, Lines,
- GTSC_Visible, BufLine,
- TAG_DONE);
- }
- }
- }
-
- MarkArea(SaveX,LineNumber - CurrentLine,strlen(SearchBuffer));
- }
-
- FoundY = (FoundY + 1) % Lines;
- }
-
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GA_Disabled,FALSE,
- TAG_DONE);
- }
- else
- MyEasyRequest(BufferWindow,"There isn't anything in the\nbuffer right now.","Continue");
-
- BufferWindow -> Flags &= ~WFLG_RMBTRAP;
- ClearPointer(BufferWindow);
- break;
-
- case MEN_REPEAT: BufferWindow -> Flags |= WFLG_RMBTRAP;
- SetWait(BufferWindow);
-
- if(!SearchBuffer[0])
- goto GetTheString;
- else
- {
- GT_SetGadgetAttrs(BufferGadget,BufferWindow,NULL,
- GA_Disabled,TRUE,
- TAG_DONE);
-
- goto SearchForIt;
- }
-
- case MEN_GOTO: BumpWindow(TopWindow);
- break;
-
- case MEN_QUITBUF:
- case MEN_CLOSEBUF: BufferTerminated = TRUE;
- break;
-
- case MEN_CLEARBUF: if(Lines)
- {
- BlockWindows();
-
- SetWait(BufferWindow);
-
- BufferWindow -> Flags |= WFLG_RMBTRAP;
-
- if(MyEasyRequest(BufferWindow,"The buffer still holds %ld lines,\ndo you wish to discard them?","Yes|No",Lines))
- {
- ClearBuffer();
-
- MarkedArea = FALSE;
-
- ClearPointer(BufferWindow);
-
- BufferWindow -> Flags &= ~WFLG_RMBTRAP;
-
- ReleaseWindows();
-
- FlushIMsg(BufferWindow);
-
- goto Restart;
- }
-
- ClearPointer(BufferWindow);
-
- BufferWindow -> Flags &= ~WFLG_RMBTRAP;
-
- ReleaseWindows();
-
- FlushIMsg(BufferWindow);
- }
-
- break;
-
- default: break;
- }
-
- Code = MenuItem -> NextSelect;
- }
- }
- }
- }
-
- RemoveGList(BufferWindow,GadgetList,(UWORD)-1);
-
- FreeGadgets(GadgetList);
-
- BufferGadget = NULL;
- }
-
- BumpWindow(TopWindow);
-
- MarkArea(-1,-1,-1);
-
- ScreenToBack(BufferScreen);
-
- BufferWindow -> Flags |= WFLG_RMBTRAP;
-
- ClearMenuStrip(BufferWindow);
-
- CloseWindow(BufferWindow);
- }
- }
-
- FreeMenus(BufferMenuStrip);
- }
-
- FreeVisualInfo(BufferVisualInfo);
- }
-
- CloseScreen(BufferScreen);
- }
- }
-
- Forbid();
-
- BufferProcess = NULL;
-
- Signal(ThisProcess,SIGBREAKF_CTRL_C);
- }
-