char InvBuf[]= {CSI,'7',0x6d,NULL,CSI,'0',0x6d}; char Inv[]= {CSI,'7',0x6d,NULL}; char Norm[]= {CSI,'0',0x6d,NULL}; struct LineItem *InvItem; MovedMouse(x,y) /*The mouse was moved! Record its new position*/ int x,y; { LastX=PtrX; LastY=PtrY; PtrX=(x/8)+1; PtrY=(y/8)+1; } HandleButton(Seconds,Micros) /*Handle a button press*/ int Seconds,Micros; { int status; static int LastSeconds=1,LastMicros=1,DoubClicked=FALSE; static UBYTE ButtonX,ButtonY; /*If the user double-clicked (the mouse button), start or modify*/ /*a highlighted block*/ if(DoubleClick(LastSeconds,LastMicros,Seconds,Micros) && PtrY==LastY && !DoubClicked) { PtrX=ButtonX; PtrY=ButtonY; DoubClicked=TRUE; HandleInvs(); BLastX=PtrX; BLastY=PtrY; } else /*Otherwise, just move the cursor accordingly*/ if(PtrY > 0 && PtrY <= SCRNHEIGHT) { ButtonX=PtrX; ButtonY=PtrY; DoubClicked=FALSE; if(PtrY != InvY && InvsMode > NOINV) EndLineInvs(); if(PtrY-CurY < 0) status=MoveBack(-(PtrY-CurY)); else status=MoveForward(PtrY-CurY); if(status==FALSE) return(FALSE); if(PtrX > MaxX(CurrentItem)) CurX=MaxX(CurrentItem); else if(PtrX < MinX(CurrentItem)) CurX=MinX(CurrentItem); else CurX=PtrX; PlotCursor(CurX,PtrY); } LastSeconds=Seconds; LastMicros=Micros; } HandleInvs() /*Handle a modification or creation of a highlighted block*/ { if(InvsMode==NOINV) if(PtrX >= MinX(CurrentItem) && PtrX <= MaxX(CurrentItem)) HandleLineInvs(); else HandleBlockInvs(); else if(InvsMode > NOINV) HandleLineInvs(); else HandleBlockInvs(); } HandleBlockInvs() /*Handle the inverse of a block of lines*/ { int X,Y; if(InvsMode==NOINV) { InvY=EndIY=CurY; WriteConsole(Inv,-1); PlotCursor(1,CurY); PrintItem(CurrentItem); WriteConsole(Norm,-1); EndIItem=StartIItem=(struct LineItem *)CurrentItem; PlotCursor(MinX(CurrentItem),CurY); InvsMode=BLOCK_PENDING; return(TRUE); } if(InvsMode==BLOCK_PENDING) { if(PtrY == BLastY) { EndBlockInvs(); return(TRUE); } if(PtrY > BLastY) { EndIItem=(struct LineItem *)CurrentItem; PlotCursor(1,BLastY+1); RvsBlock(StartIItem->NextItem,EndIItem); EndIY=CurY=PtrY; InvsMode=BLOCK_DOWN; PlotCursor(MinX(EndIItem),CurY); } if(PtrY < BLastY) { EndIItem=(struct LineItem *)CurrentItem; EndIY=CurY; RvsBlock(EndIItem,StartIItem->PrevItem); PlotCursor(MinX(EndIItem),EndIY); InvsMode=BLOCK_UP; } return(TRUE); } if(InvsMode == BLOCK_DOWN) { if(PtrY > BLastY) { PlotCursor(1,BLastY+1); RvsBlock(EndIItem->NextItem,CurrentItem); EndIY=CurY=PtrY; EndIItem=(struct LineItem *)CurrentItem; PlotCursor(MinX(EndIItem),CurY); } if(PtrY < BLastY) { if(PtrY <= InvY) { EndBlockInvs(FALSE); return(TRUE); } EndIY=Y=CurY; X=CurX; PlotCursor(CurX,CurY+1); NormBlock(CurrentItem->NextItem,EndIItem); PlotCursor(X,Y); EndIItem=(struct LineItem *)CurrentItem; } } else { if(PtrY < BLastY) { EndIY=Y=CurY; RvsBlock(CurrentItem,EndIItem->PrevItem); PlotCursor(MinX(CurrentItem),Y); EndIItem=(struct LineItem *)CurrentItem; } if(PtrY > BLastY) { if(PtrY >= InvY) { EndBlockInvs(); return(TRUE); } Y=CurY; PlotCursor(CurX,EndIY); NormBlock(EndIItem,CurrentItem->PrevItem); EndIItem=(struct LineItem *)CurrentItem; PlotCursor(MinX(CurrentItem),CurY+1); EndIY=CurY; } } } NormBlock(Start,End) /*Normalize a specified block of highlight*/ struct LineItem *Start,*End; { struct LineItem *CurItem; CurItem=(struct LineItem *)Start; WriteConsole(Norm,-1); CurY--; while(CurItem != End->NextItem) { PlotCursor(1,CurY+1); PrintItem(CurItem); CurItem=(struct LineItem *)CurItem->NextItem; } } RvsBlock(Start,End) /*Reverse a block*/ struct LineItem *Start,*End; { struct LineItem *CurItem; CurItem=(struct LineItem *)Start; WriteConsole(Inv,-1); CurY--; while(CurItem != End->NextItem) { PlotCursor(1,CurY+1); PrintItem(CurItem); CurItem=(struct LineItem *)CurItem->NextItem; } WriteConsole(Norm,-1); } EndBlockInvs() /*End the highlight of a block of lines*/ { int Y=CurY; if(InvY > EndIY) { PlotCursor(1,EndIY); NormBlock(EndIItem,StartIItem); PlotCursor(MinX(CurrentItem),Y); } else { PlotCursor(1,InvY); NormBlock(StartIItem,EndIItem); PlotCursor(MinX(StartIItem),Y); } InvsMode=NOINV; } HandleLineInvs() /*Handle the inverse of individual characters*/ { int NewEnd; if(PtrX < MinX(CurrentItem)) PtrX=MinX(CurrentItem); else if(PtrX > MaxX(CurrentItem)) PtrX=MaxX(CurrentItem); if(InvsMode==NOINV) { InvBuf[3]=CurrentItem->Text[PosInText(CurrentItem->Level)]; WriteConsole(InvBuf,7); StartChar=EndChar=PosInText(CurrentItem->Level); PlotCursor(CurX,CurY); InvsMode=LINE_PENDING; InvY=CurY; InvItem=(struct LineItem *)CurrentItem; return(TRUE); } if(InvsMode==LINE_PENDING) { if(PtrX == BLastX) { EndLineInvs(); return(TRUE); } if(PtrX > BLastX) { if(PtrX > BLastX+1) { EndChar=PosInText(InvItem->Level)-1; PlotCursor(BLastX+1,CurY); RvsText(StartChar+1,EndChar); CurX=CurX+EndChar-StartChar; } InvsMode=LINE_FWD; return(TRUE); } if(PtrX < BLastX) { EndChar=PosInText(InvItem->Level); RvsText(EndChar,StartChar-1); PlotCursor(PtrX,CurY); InvsMode=LINE_BACK; } return(TRUE); } else if(InvsMode==LINE_FWD) { if(PtrX > BLastX) { NewEnd=PtrX-MinX(InvItem)-1; PlotCursor(EndChar+MinX(InvItem),CurY); RvsText(EndChar,NewEnd); CurX=NewEnd+MinX(InvItem); EndChar=NewEnd; } if(PtrX < BLastX) if(PtrX-MinX(InvItem)<=StartChar) EndLineInvs(); else { NewEnd=PtrX-MinX(InvItem); NormText(NewEnd,EndChar); PlotCursor(CurX,CurY); EndChar=NewEnd; } } else { if(PtrX < BLastX) { NewEnd=PtrX-MinX(InvItem); RvsText(NewEnd,EndChar); PlotCursor(CurX,CurY); EndChar=NewEnd; } if(PtrX > BLastX) if(PtrX-MinX(InvItem)>=StartChar) EndLineInvs(); else { NewEnd=PtrX-MinX(InvItem)-1; PlotCursor(EndChar+MinX(InvItem),CurY); NormText(EndChar,NewEnd); CurX=NewEnd+MinX(InvItem); EndChar=NewEnd; PlotCursor(CurX+1,CurY); } } } RvsText(Start,End) /*Highlight a block of text*/ int Start,End; { char Buffer[80]; int c,l; strcpy(Buffer,Inv); l=strlen(Buffer); for(c=l; c-l < End-Start+1 ; c++) { Buffer[c]=InvItem->Text[c+Start-l]; } Buffer[c]=0; strcat(Buffer,Norm); WriteConsole(Inv,-1); WriteConsole(Buffer,c); WriteConsole(Norm,-1); } MoveBack(Number) /*Move back in the item list a specified number of times*/ int Number; { int c; for(c=0;cPrevItem==NULL) return(FALSE); else CurrentItem=(struct LineItem *)CurrentItem->PrevItem; } return(TRUE); } MoveForward(Number) /*Move forward in the item list a specifiecd*/ int Number; /*number of times*/ { int c; struct LineItem *OrigItem; OrigItem=(struct LineItem *)CurrentItem; for(c=0;cNextItem==NULL) { CurrentItem=(struct LineItem *)OrigItem; return(FALSE); } else CurrentItem=(struct LineItem *)CurrentItem->NextItem; } return(TRUE); } EndLineInvs() /*End text inverse*/ { if(StartChar < EndChar) NormText(StartChar,EndChar); else NormText(EndChar,StartChar); InvsMode=NOINV; } NormText(Start,End) /*Un-reverse text*/ int Start,End; { int TempX,c; char Buffer[80]; for(c=Start;c<=End;c++) Buffer[c-Start]=InvItem->Text[c]; Buffer[c-Start]=0; TempX=CurX; PlotCursor(MinX(InvItem)+Start,InvY); WriteConsole(Buffer,-1); PlotCursor(TempX,InvY); } HandleDelBlock() /*Delete a block of lines*/ { InvsMode=NOINV; if((StartIItem->PrevItem==NULL && EndIItem->NextItem==NULL) || (StartIItem->NextItem==NULL && EndIItem->PrevItem==NULL)) { NewAll(); return(TRUE); } if(InvY <= BLastY) DelBlock(StartIItem,EndIItem,InvY,BLastY); else DelBlock(EndIItem,StartIItem,BLastY,InvY); } DelBlock(Start,End,StartY,EndY) /*Delete a block of lines*/ struct LineItem *Start,*End; int StartY,EndY; { int TOS; if(Start==FirstScrnItem) TOS=TRUE; else TOS=FALSE; if(Start->PrevItem == NULL) { CurrentItem=FirstItem=FirstScrnItem= (struct LineItem *)End->NextItem; CurrentItem->PrevItem=NULL; RemItem(CurrentItem); AddItem(CurrentItem); TOS=FALSE; } else if(End->NextItem==NULL) { CurrentItem=LastItem= (struct LineItem *)Start->PrevItem; LastItem->NextItem=NULL; if(Start==FirstScrnItem) { FirstScrnItem=ScrnBtm=(struct LineItem *)CurrentItem; StartY=1; } else StartY--; TOS=FALSE; } else { CurrentItem=Start->PrevItem->NextItem=(struct LineItem *) End->NextItem; End->NextItem->PrevItem= (struct LineItem *)Start->PrevItem; } if(TOS) CurrentItem=FirstScrnItem=(struct LineItem *)End->NextItem; FreeListMem(Start,End); RemItem(CurrentItem); AddItem(CurrentItem); BackSearchRefresh(CurrentItem); PrintItemList(CurrentItem,StartY); PlotCursor(MinX(CurrentItem),StartY); } FreeListMem(Start,End) /*Free several Items at once*/ struct LineItem *Start,*End; { struct LineItem *Item,*Next; Next=(struct LineItem *)Start; do { Item=(struct LineItem *)Next; RemItem(Item); Next=(struct LineItem *)Item->NextItem; FreeMem(Item,sizeof(struct LineItem)); } while(Item != End && Next != NULL); } DelTextBlock() /*Delete the highlighted text*/ { int c,Start,End,len; char Buffer[2]; if(StartChar < EndChar) { Start=StartChar; End=EndChar; } else { Start=EndChar; End=StartChar; } len=strlen(InvItem->Text); for(c=0;c <= len-End; c++) InvItem->Text[c+Start]=InvItem->Text[c+End+1]; PlotCursor(1,InvY); Buffer[0]=CSI; Buffer[1]=0x4b; WriteConsole(Buffer,2); PrintItem(InvItem); PlotCursor(MinX(InvItem)+Start,InvY); InvsMode=NOINV; } CancelInvs() /*Cancel inversed text or lines*/ { if(NOINV == InvsMode) return(FALSE); else if(InvsMode > NOINV) EndLineInvs(); else EndBlockInvs(); return(TRUE); } DelInvs() /*Delete the highlighted block or text*/ { if(InvsMode==NULL) return(FALSE); if(InvsMode > NOINV) DelTextBlock(); else HandleDelBlock(); return(TRUE); } TitleError(string) char *string; { DisplayBeep(Screen); ErrorInTitle = TRUE; SetWindowTitles(Window,-1,string); } TitleErrorCancel() { static char Title[85]; strcpy(Title,ScreenTitle); if(FileName[0]) strncat(Title,FileName,65); else strcat(Title,"Untitled"); if(Modified==TRUE) Title[0]='*'; ErrorInTitle = FALSE; SetWindowTitles(Window,-1,Title); } BackSearchRefresh(Base) /*Do a refresh of ItemNumbers by searching*/ struct LineItem *Base; /*back through the item list*/ { struct LineItem *Work,Dummy; Dummy.PrevItem=(struct LineItem *)Base->PrevItem; Dummy.NextItem=(struct LineItem *)Base->NextItem; for(Dummy.Level=Base->Level;Dummy.Level > 0;Dummy.Level--) if((Work=(struct LineItem *)FindPrev(&Dummy))!=NULL) { RemItem(Work); AddItem(Work); } }