home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff285.lzh
/
'Liner
/
Source
/
'Liner.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-28
|
35KB
|
1,156 lines
/*'Liner Version 1.32. Written by Dave Schreiber */
/*©1988, 1989 Dave Schreiber. All Rights Reserved. */
/*1.32 completed Monday, October 31, 1989 */
/*1.31 completed Friday, October 6, 1989 */
/*1.3 completed Saturday, February 25, 1989 */
/*1.2 completed Friday, November 11, 1988 */
/*1.1 completed Friday, October 14, 1988 */
/*1.0 completed Friday, September 9, 1988 */
/*Compiled with Lattice C V5.02 */
/*To compile: 1> lc -cw -j30 -L+YAFR:YAFR.o 'Liner */
/*You must assign YAFR: to the directory where YAFR.o is stored. */
/*You must also assign LINER: to the directory where the 'Liner source */
/*is located. */
/*'Liner is an outliner, with up to six levels of depth, and up to */
/*26 items per level (each isolated section). It has both clipboard and */
/*non-clipboard support of CUT, COPY, and PASTE. It can output files */
/*in its own format, or in ASCII (to disk or printer). It can read files*/
/*in its own format only. It uses dynamic memory allocation to allow */
/*an infinite number of items (memory providing).*/
/*Amiga features of note that are used: */
/*console device, disk i/o, printer i/o, clipboard i/o */
/*Intuition objects (screen, windows, gadgets, menus, etc.) generated by */
/*PowerWindows Version 2.0*/
/*V1.1 corrects some bugs, doubles the number of characters available */
/*for filenames, and improves PrintItemList() so that it doesn't always */
/*print the entire item list*/
/*1.2 allows the toggling between 640x200 & 640x400 screens and the */
/*choice of the order that levels appear in, has a completely reworked */
/*About... window, lets the user change the level of all the items */
/*in a highlighted block, and now displays the current filename */
/*in the title bar.*/
/*1.3 adds support for user-selected keymaps, and now prints an asterisk */
/*in the title bar if an outline has been edited but not saved. It also */
/*includes my very own file requester, YAFR (Yet Another File Requester) */
/*based in principal upon Charlie Heath's, but with a lot more buttons. */
/*1.31 changes the default device where files are located from DF0: to */
/*the current directory */
/*1.32 fixed a bug that kept the screen from updating properly after a */
/*paste. Also uses YAFR V1.1 */
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <devices/console.h>
#include <devices/clipboard.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <devices/inputevent.h>
#include <devices/keymap.h>
#include <math.h>
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
ULONG DosBase;
struct IOStdReq *consoleWriteMsg,*consoleReadMsg;
struct Port *consoleWritePort,*consoleReadPort;
struct IOClipReq ClipboardIO;
struct MsgPort clipboardMsgPort;
struct Process *ThisProc;
struct LineItem /*'Liner structure definition*/
{
struct LineItem *NextItem,*PrevItem;
UBYTE Level,ItemNumber;
char Text[80];
};
extern struct LineItem *InsertItem(),*FindNext(),*FindPrev();
struct Screen *Screen;
struct Window *Window,*AboutWindow;
struct KeyMap keymap;
#define Rp Window->RPort;
#define CSI 0x09b
#define SEMI 0x03b
#define NEWPAGE 0x0c
#define CLOSECHAR 0x05c
#define SCRNHEIGHT RowsInScreen
#define REQUESTERCHARS 57
APTR ConsoleDevice;
struct LineItem *CharItem,*StartIItem,*EndIItem,*ClipStart,*ClipEnd;
int ButtonState,PtrX,PtrY,LastX,LastY,InvsMode,StartChar,EndChar,InvY,EndIY;
int BLastX,BLastY,ClipMode,ErrorInTitle=FALSE;
UBYTE Laced,RowsInScreen,StartingLevel,Modified;
char Indent=0;
char DoubleSpc=FALSE;
char FileName[150+33],SDirName[150],SFileName[33],SExt[18];
char PDName[150+33],PDirName[150],PFileName[33],PExt[18];
char ScreenTitle[] = {" 'Liner V1.32: "};
#define UP 0
#define DOWN 1
#define NOINV 0
#define LINE_PENDING 1
#define LINE_FWD 2
#define LINE_BACK 3
#define BLOCK_PENDING -1
#define BLOCK_DOWN -2
#define BLOCK_UP -3
UBYTE OLCPos[6][6]=
{
{9,13,17,21,25,29},
{6,10,14,18,22,26},
{6,10,14,18,22,26},
{6,10,14,18,22,26},
{6,10,14,18,22,26},
{6,10,14,18,22,26}
};
/*Some macros*/
#define PERPOS(x) OLCPos[StartingLevel][x]-3
#define MinX(LI) OLCPos[StartingLevel][(LI->Level)-1]
#define MaxX(LI) OLCPos[StartingLevel][(LI->Level)-1]+strlen(LI->Text)
#define MaxLen(Level) 79-OLCPos[StartingLevel][Level-1]
#define PosInText(Level) CurX-OLCPos[StartingLevel][Level-1]
#define RealLevel(LI) (LI->Level+StartingLevel > 6) ? (LI->Level+StartingLevel-7) : (LI->Level+StartingLevel)
/* ^^^ == get level when StartingLevel != 0 */
/*Pointers to various LineItems*/
struct LineItem *FirstItem,*LastItem,*CurrentItem,*FirstScrnItem,*ScrnBtm;
int CurX,CurY,DispRows;
/*Outline characters*/
char *OutLineChars[6][26]=
{
{
{"I."},{"II."},{"III."},{"IV."},{"V."},{"VI."},{"VII."},{"VIII."},
{"IX."},{"X."},{"XI."},{"XII."},{"XIII."},{"XIV."},{"XV."},{"XVI."},
{"XVII."},{"XVIII."},{"XIX."},{"XX."},{"XXI."},{"XXII."},{"XXIII."},
{"XXIV."},{"XXV."},{"XXVI."}
},
{
{"A."},{"B."},{"C."},{"D."},{"E."},{"F."},{"G."},{"H."},{"I."},
{"J."},{"K."},{"L."},{"M."},{"N."},{"O."},{"P."},{"Q."},{"R."},
{"S."},{"T."},{"U."},{"V."},{"W."},{"X."},{"Y."},{"Z."}
},
{
{"1."},{"2."},{"3."},{"4."},{"5."},{"6."},{"7."},{"8."},{"9."},
{"10."},{"11."},{"12."},{"13."},{"14."},{"15."},{"16."},{"17."},
{"18."},{"19."},{"20."},{"21."},{"22."},{"23."},{"24."},{"25."},
{"26."}
},
{
{"a."},{"b."},{"c."},{"d."},{"e."},{"f."},{"g."},{"h."},{"i."},
{"j."},{"k."},{"l."},{"m."},{"n."},{"o."},{"p."},{"q."},{"r."},
{"s."},{"t."},{"u."},{"v."},{"w."},{"x."},{"y."},{"z."}
},
{
{"1)"},{"2)"},{"3)"},{"4)"},{"5)"},{"6)"},{"7)"},{"8)"},{"9)"},
{"10)"},{"11)"},{"12)"},{"13)"},{"14)"},{"15)"},{"16)"},{"17)"},
{"18)"},{"19)"},{"20)"},{"21)"},{"22)"},{"23)"},{"24)"},{"25)"},
{"26)"}
},
{
{"a)"},{"b)"},{"c)"},{"d)"},{"e)"},{"f)"},{"g)"},{"h)"},{"i)"},
{"j)"},{"k)"},{"l)"},{"m)"},{"n)"},{"o)"},{"p)"},{"q)"},{"r)"},
{"s)"},{"t)"},{"u)"},{"v)"},{"w)"},{"x)"},{"y)"},{"z)"}
},
};
/*The position of each special character in the array below*/
int SCPos[]=
{0,1,4,5,9,13,14,16,17,18,19,20,21,23,25,27,29};
/*Special characters (TAB, RETURN, etc.)*/
char SpecChars[]=
{
32,
8,CSI,'P',
0,
0x0D,0x0A,CSI,'L',
0x0D,0x0A,CSI,'L',
0,
CSI,'P',
0,
0,
0,
0,
0,
CSI,'A',
CSI,'B',
CSI,'C',
CSI,'D'
};
/*All the other little components of 'Liner*/
#include <liner:mouse.h>
#include <liner:Windows.h>
#include <liner:menu.h>
#include <liner:disk.h>
#include <liner:sure.h>
#include <liner:clip.h>
_main()
{
ULONG Class;
USHORT Code,Qualifier;
APTR IAddress;
SHORT MouseX,MouseY;
int Seconds,Micros;
struct IntuiMessage *Message;
char Buffer[200];
Buffer[0]=NULL;
FileName[0]=SFileName[0]=SExt[0]=NULL;
strcpy(SDirName,"");
strcpy(PDirName,"");
PDName[0]=PFileName[0]=PExt[0]=NULL;
Laced=FALSE; /*Not interlaced*/
Modified=FALSE; /*No modifications, yet*/
StartingLevel=0;
/*Open all the libraries*/
IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",1);
if(IntuitionBase==NULL)
exit(10);
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",1);
if(GfxBase==NULL)
exit(20);
DosBase=OpenLibrary("dos.library",1);
if(DosBase==NULL)
exit(30);
RowsInScreen=23;
ThisProc=(struct Process *)FindTask(NULL); /*Get 'Liner's process structure*/
OpenGraphics(); /*Open screen, window, etc.*/
SetupClipboard(); /*Open the clipboard*/
/*Setup various system variable*/
DispRows=1;
PtrX=PtrY=LastX=LastY=1;
ButtonState=UP;
InvsMode=ClipMode=NOINV;
FirstItem=LastItem=FirstScrnItem=CurrentItem=(struct LineItem *)
InsertItem(NULL,NULL);
FirstItem->Level=1;
FirstItem->ItemNumber=0;
PrintItemList(FirstItem,1);
PlotCursor(MinX(CurrentItem),1);
FileName[0]=PDName[0]=NULL;
for(;;) /*The main loop!*/
{
Wait(1<<Window->UserPort->mp_SigBit); /*Wait for an event*/
while((Message=(struct IntuiMessage *) /*Get the message*/
GetMsg(Window->UserPort))!=NULL)
{ /*Get the message's information*/
Class=Message->Class;
Code=Message->Code;
Qualifier=Message->Qualifier;
MouseX=Message->MouseX;
MouseY=Message->MouseY;
Seconds=Message->Seconds;
Micros=Message->Micros;
IAddress=(APTR)Message->IAddress;
ReplyMsg(Message); /*Reply to the message*/
/*Decode the message*/
if(HandleIDCMP(Class,Code,Qualifier,MouseX,MouseY,IAddress,
Buffer,Seconds,Micros))
{ /*If the message was a keypress*/
InsertChar(CurrentItem->Text,Buffer[2], /*Print the letter*/
PosInText(CurrentItem->Level)); /*onto the screen*/
CurX++;
WriteConsole(Buffer,-1);
}
}
}
}
WriteConsole(Buffer,Length) /*Write a string to the console*/
char *Buffer;
int Length;
{
consoleWriteMsg->io_Command=CMD_WRITE;
consoleWriteMsg->io_Data=(char *)Buffer;
consoleWriteMsg->io_Length=Length;
DoIO(consoleWriteMsg);
}
/*Decode an IDCMP message*/
HandleIDCMP(Class,Code,Qualifier,MouseX,MouseY,IAddress,Buffer,Secs,Micros)
ULONG Class;
USHORT Code,Qualifier;
APTR IAddress;
SHORT MouseX,MouseY;
int Secs,Micros;
char *Buffer;
{
struct MenuItem *item;
struct InputEvent KeyEvent;
struct LineItem *WorkingItem;
int TempX,TempY;
Buffer[0]=CSI;
Buffer[1]=0x40;
Buffer[2]=NULL;
switch(Class)
{
case MENUPICK: /*There was a menu selection*/
if(ErrorInTitle)
TitleErrorCancel();
while(Code != MENUNULL)
{
item=(struct MenuItem *)ItemAddress(&Menu1,Code);
HandleEvent(item);
Code=item->NextSelect;
}
case MOUSEBUTTONS: /*The left mouse button was pushed*/
if(Code==SELECTDOWN)
HandleButton(Secs,Micros);
break;
case MOUSEMOVE: /*The mouse was moved*/
MovedMouse(MouseX,MouseY);
break;
/*A key was pressed*/
case RAWKEY: /*By using IDCMP RAWKEY as input, and the*/
if(Code & 0x80) /*console for output, we can both get input*/
return(FALSE); /*and IDCMP messsages without having to try*/
if(ErrorInTitle) /*and decode ASCII console messages*/
TitleErrorCancel(); /*(IDCMP structures are MUCH easier)*/
if((Code < 0x41) || (0x5a <= Code && Code <= 0x5e) ||
(Code==0x4a))
{ /*^^^==All the RAWKEY codes that represent ASCII symbols*/
CheckModified();
KeyEvent.ie_NextEvent=NULL; /*Create a fake input event*/
KeyEvent.ie_Class=IECLASS_RAWKEY; /*for RawKeyConvert() to */
KeyEvent.ie_SubClass=NULL; /*munch on. Using RawKeyConvert()*/
KeyEvent.ie_Code=Code; /*insures that the current keymap*/
KeyEvent.ie_Qualifier=Qualifier; /*is used*/
RawKeyConvert(&KeyEvent,&Buffer[2],200,&keymap),ConsoleDevice;
Buffer[3]=NULL; /* ^^^ == RAWKEY to ASCII*/
if(InvsMode < NOINV) /*If a block of lines was highlighted*/
{ /*when a key was pressed, cancel the*/
EndBlockInvs(); /*highlight*/
return(FALSE);
}
/*If a key was pressed when TEXT was*/
if(InvsMode) /*highlighted, delete the text & replace*/
DelTextBlock(); /*it with the letter pressed*/
/*If the current line isn't full*/
if(strlen(CurrentItem->Text)<MaxLen(CurrentItem->Level))
return(TRUE); /*OK to print the character*/
else
return(FALSE); /*Otherwise not*/
}
else
switch(Code) /*Handle all the "special" characters*/
{
case 0x4d: /*Move cursor down one*/
CancelInvs();
if(Qualifier & 3) /*Handle SHIFT-DOWN*/
WholeScreenDown();
else if(Qualifier & 8) /*Handle CTRL-DOWN*/
JumpToBottom();
else
CursorDown();
break;
case 0x4c: /*Move cursor up one*/
CancelInvs();
if(Qualifier & 3) /*Check for shift*/
WholeScreenUp();
else if(Qualifier & 8) /*Check for control*/
JumpToTop();
else
CursorUp();
break;
case 0x4e: /*Move cursor one to the right*/
CancelInvs();
if(CurX >= MaxX(CurrentItem))
{
TempX=CurX;
CurX=1;
if(!CursorDown())
CurX=TempX;
}
else
if(Qualifier & 3) /*Handle SHIFT-cursor-right*/
PlotCursor(MaxX(CurrentItem),CurY);
else
PlotCursor(CurX+1,CurY);
break;
case 0x4f: /*Move cursor one to the left*/
CancelInvs();
if(CurX <= MinX(CurrentItem))
{
TempX=CurX;
CurX=100;
if(!CursorUp())
CurX=TempX;
}
else
if(Qualifier & 3) /*Handle SHIFT-cursor-left*/
PlotCursor(MinX(CurrentItem),CurY);
else
PlotCursor(CurX-1,CurY);
break;
case 0x41: /*Backspace over a character*/
CheckModified();
if(DelInvs()) /*If something is highlighted*/
break; /*delete it*/
/*Delete the character, if not at the beginning of the line...*/
if(CurX>MinX(CurrentItem))
{
strcpy(Buffer,&SpecChars[SCPos[1]]);
Buffer[SCPos[2]-SCPos[1]]=NULL;
DeleteChar(CurrentItem->Text,
PosInText(CurrentItem->Level)-1);
WriteConsole(Buffer,-1);
CurX--;
}
else /*otherwise, delete the line*/
if(CurrentItem->PrevItem != NULL &&
strlen(CurrentItem->Text)==0)
{
DelBlock(CurrentItem,CurrentItem,CurY,CurY);
if(CurrentItem != LastItem)
CursorUp();
PlotCursor(MaxX(CurrentItem),CurY);
}
break;
case 0x46: /*Delete a character*/
CheckModified();
if(DelInvs())
break;
if(CurX<MaxX(CurrentItem))
{
strcpy(Buffer,&SpecChars[SCPos[6]]);
Buffer[SCPos[7]-SCPos[6]]=NULL;
DeleteChar(CurrentItem->Text,
PosInText(CurrentItem->Level));
WriteConsole(Buffer,-1);
}
break;
case 0x42: /*TAB (in or out)*/
CheckModified();
if(InvsMode < NOINV) /*Block highlighted*/
if(Qualifier & 3)
if(InvsMode==BLOCK_DOWN)
PullOutBlock(StartIItem,EndIItem,InvY);
else
PullOutBlock(EndIItem,StartIItem,EndIY);
else
if(InvsMode==BLOCK_DOWN)
PushInBlock(StartIItem,EndIItem,InvY);
else
PushInBlock(EndIItem,StartIItem,EndIY);
else
{
if(CancelInvs())
return(FALSE);
TempY=CurY;
PlotCursor(1,TempY);
if(Qualifier & 3) /*TAB out (shift pressed)*/
PullOut(CurrentItem);
else
PushIn(CurrentItem); /*TAB in*/
PlotCursor(MinX(CurrentItem),TempY);
}
break;
case 0x43: /*Return & Enter */
case 0x44: /*Insert a line*/
CheckModified();
if(CancelInvs())
return(FALSE);
if(CurX < MaxX(CurrentItem))
if(!CursorUp())
{
InsertLineAtTop();
return(FALSE);
}
strcpy(Buffer,&SpecChars[SCPos[4]]);
WriteConsole(Buffer,4);
WorkingItem=(struct LineItem *)
InsertItem(CurrentItem->NextItem,CurrentItem);
WorkingItem->Level=CurrentItem->Level;
if(CurrentItem->ItemNumber==25)
WorkingItem->ItemNumber=0;
else
WorkingItem->ItemNumber=CurrentItem->ItemNumber+1;
if(CurY==SCRNHEIGHT)
{
ScrnBtm=(struct LineItem *)WorkingItem;
FirstScrnItem=(struct LineItem *)
FirstScrnItem->NextItem;
}
else
{
CurY++;
if(DispRows==SCRNHEIGHT)
ScrnBtm=(struct LineItem *)ScrnBtm->PrevItem;
else
++DispRows;
}
if(WorkingItem->NextItem==NULL)
ScrnBtm=LastItem=(struct LineItem *)
WorkingItem;
AddItem(WorkingItem);
TempY=CurY;
RedrawOutlineChars(WorkingItem,WorkingItem->Level,0);
CurrentItem=(struct LineItem *)WorkingItem;
PlotCursor(MinX(CurrentItem),TempY);
break;
}
return(FALSE);
}
return(FALSE);
}
/*Close everything*/
CloseStuff()
{
FreeListMem(FirstItem,LastItem);
if(ClipMode < NOINV)
FreeListMem(ClipStart,ClipEnd);
ShutDownClipboard();
CloseGraphics();
CloseLibrary(DosBase);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(0);
}
Leave(err,why) /*If an error occured, tell user, close window & screen*/
int err; /*& exit*/
char *why;
{
TitleError(why);
Delay(500); /*Give user 5 seconds to read error message*/
exit(err);
}
PushIn(Item) /*Increase and redraw the level of an item*/
struct LineItem *Item;
{
if(Push(Item))
{
RedrawOutlineChars(Item,Item->Level-1,Item->Level);
return(TRUE);
}
else
return(FALSE);
}
Push(Item) /*Increase the level of an item (I. to A., etc.)*/
struct LineItem *Item;
{
if(Item->Level==6)
return(FALSE);
RemItem(Item);
Item->Level++; /*Increase the level and chop off excess text if it*/
Item->Text[MaxLen(Item->Level)]=NULL; /*would go off the line*/
AddItem(Item);
PrintItem(Item);
return(TRUE);
}
PullOut(Item) /*Decrease the level of an item and redraw*/
struct LineItem *Item;
{
if(Pull(Item))
{
RedrawOutlineChars(Item,Item->Level+1,Item->Level);
return(TRUE);
}
else
return(FALSE);
}
Pull(Item) /*Decrease the level of an item (a. to 1., etc.)*/
struct LineItem *Item;
{
if(Item->Level==1)
return(FALSE);
RemItem(Item);
Item->Level--;
AddItem(Item);
AddItem(Item->NextItem);
PrintItem(Item);
return(TRUE);
}
PushInBlock(Start,End,YStart) /*Indent a reversed block*/
struct LineItem *Start,*End;
UBYTE YStart;
{
struct LineItem *Item;
UBYTE OldX=CurX;
UBYTE OldY=CurY;
UBYTE Y=YStart;
Item=(struct LineItem *)Start; /*Check to see if any items are as*/
while(Item != End) /*pushed in as possible*/
{
if(Item->Level == 6)
return(FALSE);
Item=(struct LineItem *)Item->NextItem;
}
PlotCursor(1,Y);
Item=(struct LineItem *)Start; /*Do first one*/
Push(Item);
while(Item != End) /*Loop until all pushed in*/
{
Item=(struct LineItem *)Item->NextItem;
PlotCursor(1,++Y);
Push(Item);
}
PlotCursor(1,++Y); /*Redraw outline characters*/
RedrawOutlineChars(End->NextItem,6,5);
PlotCursor(1,Y);
RedrawOutlineChars(End->NextItem,4,3);
PlotCursor(1,Y);
RedrawOutlineChars(End->NextItem,2,1);
PlotCursor(1,YStart);
RvsBlock(Start,End);
if(OldX < MinX(CurrentItem)) /*OldX might no longer be possible if*/
PlotCursor(MinX(CurrentItem),OldY); /*CurrentItem was one pushed in*/
else
PlotCursor(OldX,OldY);
}
PullOutBlock(Start,End,YStart) /*Indent a reversed block*/
struct LineItem *Start,*End;
UBYTE YStart;
{
struct LineItem *Item;
UBYTE OldX=CurX;
UBYTE OldY=CurY;
UBYTE Y=YStart;
Item=(struct LineItem *)Start; /*Check to see if any items are as*/
while(Item != End) /*pushed in as possible*/
{
if(Item->Level == 1)
return(FALSE);
Item=(struct LineItem *)Item->NextItem;
}
PlotCursor(1,Y);
Item=(struct LineItem *)Start; /*Do first one*/
Pull(Item);
while(Item != End) /*Loop until all pushed in*/
{
Item=(struct LineItem *)Item->NextItem;
PlotCursor(1,++Y);
Pull(Item);
}
PlotCursor(1,++Y); /*Redraw outline characters*/
RedrawOutlineChars(End->NextItem,6,5);
PlotCursor(1,Y);
RedrawOutlineChars(End->NextItem,4,3);
PlotCursor(1,Y);
RedrawOutlineChars(End->NextItem,2,1);
PlotCursor(1,YStart);
RvsBlock(Start,End);
if(OldX > MaxX(CurrentItem)) /*OldX might no longer be possible if*/
PlotCursor(MaxX(CurrentItem),OldY); /*CurrentItem was one pushed in*/
else
PlotCursor(OldX,OldY);
}
JumpToTop() /*Jump to top of outline*/
{
FirstScrnItem=CurrentItem=(struct LineItem *)FirstItem;
PrintItemList(CurrentItem,1);
PlotCursor(MinX(CurrentItem),1);
}
JumpToBottom() /*Jump to bottom of outline*/
{
struct LineItem *Item;
int c;
CurrentItem=(struct LineItem *)LastItem;
for(c=0,Item=(struct LineItem *)LastItem;Item!=FirstItem &&
c < SCRNHEIGHT-1;Item=(struct LineItem *)Item->PrevItem,c++);
FirstScrnItem=(struct LineItem *)Item;
PrintItemList(FirstScrnItem,1);
PlotCursor(MinX(CurrentItem),DispRows);
}
PrintItemList(FrstItem,StartY) /*Prints a specified number of items*/
struct LineItem *FrstItem;
int StartY;
{
struct LineItem *CrntItem;
int y;
char Buffer[3];
PlotCursor(1,StartY);
CrntItem=(struct LineItem *)FrstItem;
Buffer[0]=0x9b;
Buffer[1]=0x4a;
WriteConsole(Buffer,2);
for(y=StartY;y<=SCRNHEIGHT && CrntItem!=NULL;y++)
{
PlotCursor(1,y);
PrintItem(CrntItem);
ScrnBtm=(struct LineItem *)CrntItem;
CrntItem=(struct LineItem *)CrntItem->NextItem;
}
DispRows=y-1;
}
PrintItem(Item) /*Print an item at the current Y location*/
struct LineItem *Item;
{
char ConsoleBuffer[100];
ConsoleBuffer[0]=CSI;
ConsoleBuffer[1]=0x4b;
ConsoleBuffer[2]=NULL;
GetOutlineChars(Item,ConsoleBuffer);
strcat(ConsoleBuffer," ");
strcat(ConsoleBuffer,Item->Text);
WriteConsole(ConsoleBuffer,-1);
}
GetOutlineChars(Item,ConsoleBuffer) /*Get the outline chars (IX.,B.,etc.)*/
struct LineItem *Item; /*for an item*/
char *ConsoleBuffer;
{
int Level,StrLen,InsLen,c;
Level=RealLevel(Item)-1;
StrLen=strlen(OutLineChars[Level][(Item->ItemNumber)]);
InsLen=PERPOS((Item->Level)-1)-StrLen;
for(c=0;c<InsLen;c++)
strcat(ConsoleBuffer," ");
strcat(ConsoleBuffer,OutLineChars[Level][(Item->ItemNumber)]);
}
RedrawOutlineChars(Item,Hi,Lo) /*Redraw the outline characters */
struct LineItem *Item; /*(Lo <= Changed level <= Hi)*/
int Hi,Lo;
{
char Buffer[60];
int x=1;
int y,Level;
Level=Item->Level;
for(y=CurY;y<=SCRNHEIGHT & Item != NULL ;y++)
{
if(Lo == Item->Level || Hi == Item->Level)
{
PlotCursor(x,y);
strcpy(Buffer,"");
GetOutlineChars(Item,Buffer);
WriteConsole(Buffer,-1);
}
Item=(struct LineItem *)Item->NextItem;
}
}
PlotCursor(x,y) /*Plot the console cursor on the screen*/
int x,y;
{
char Buffer[10];
int len=1;
Buffer[0]=CSI;
len+=stci_d(&Buffer[1],y,9);
Buffer[len]=0x3b;
len+=stci_d(&Buffer[len+1],x,6);
Buffer[len+1]=0x48;
Buffer[len+2]=NULL;
WriteConsole(Buffer,-1);
CurX=x;
CurY=y;
}
CursorUp() /*Move the cursor up (scroll screen, etc.)*/
{
char Buffer[20];
int TempX;
if(CurrentItem->PrevItem !=NULL)
{
if(CurrentItem==FirstScrnItem && CurrentItem != FirstItem)
{
strcpy(Buffer,&SpecChars[SCPos[0x0c]]);
WriteConsole(Buffer,2);
TempX=CurX;
PlotCursor(1,1);
PrintItem(CurrentItem->PrevItem);
++CurY;
if(ScrnBtm==LastItem && DispRows < SCRNHEIGHT)
++DispRows;
else
ScrnBtm=(struct LineItem *)ScrnBtm->PrevItem;
FirstScrnItem=(struct LineItem *)FirstScrnItem->PrevItem;
CurX=TempX;
InvY++;
}
if(CurX < MinX(CurrentItem->PrevItem))
CurX=MinX(CurrentItem->PrevItem);
else
if(CurX > MaxX(CurrentItem->PrevItem))
CurX=MaxX(CurrentItem->PrevItem);
PlotCursor(CurX,CurY-1);
CurrentItem=(struct LineItem *) CurrentItem->PrevItem;
return(TRUE);
}
return(FALSE);
}
CursorDown() /*Move the cursor down (scroll screen, etc.)*/
{
char Buffer[20];
int TempX;
if(CurrentItem->NextItem != NULL)
{
if(CurrentItem==ScrnBtm && (CurrentItem->NextItem != NULL))
{
strcpy(Buffer,&SpecChars[SCPos[0x0d]]);
WriteConsole(Buffer,2);
TempX=CurX;
PlotCursor(1,CurY);
PrintItem(CurrentItem->NextItem);
PlotCursor(TempX,CurY-1);
ScrnBtm=(struct LineItem *)ScrnBtm->NextItem;
FirstScrnItem=(struct LineItem *)FirstScrnItem->NextItem;
InvY--;
}
if(CurX < MinX(CurrentItem->NextItem))
CurX=MinX(CurrentItem->NextItem);
else
if(CurX > MaxX(CurrentItem->NextItem))
CurX=MaxX(CurrentItem->NextItem);
PlotCursor(CurX,CurY+1);
CurrentItem=(struct LineItem *)CurrentItem->NextItem;
return(TRUE);
}
return(FALSE);
}
InsertChar(Text,Character,Pos) /*Insert a char into an item*/
char *Text,Character;
int Pos;
{
int c;
for(c=strlen(Text);c>=Pos;c--)
Text[c+1]=Text[c];
Text[Pos]=Character;
}
DeleteChar(Text,Pos) /*Delete a char in an item*/
char *Text;
int Pos;
{
int lim;
for(lim=strlen(Text);Pos<lim;Pos++)
Text[Pos]=Text[Pos+1];
}
/*Insert an item into the item list*/
extern struct LineItem *InsertItem(NextItem,PrevItem)
struct LineItem *NextItem,*PrevItem;
{
struct LineItem *Item;
Item=(struct LineItem *)AllocMem(sizeof(struct LineItem),MEMF_CLEAR);
if(Item==NULL)
return(NULL);
if(NextItem != NULL)
{
NextItem->PrevItem=(struct LineItem *)Item;
Item->NextItem=(struct LineItem *)NextItem;
}
if(PrevItem != NULL)
{
PrevItem->NextItem=(struct LineItem *)Item;
Item->PrevItem=(struct LineItem *)PrevItem;
}
return(Item);
}
RemItem(Item) /*Adjust the ItemNumbers for items after one is removed*/
struct LineItem *Item;
{
int ItemNumber;
struct LineItem *WorkingItem;
if(Item==NULL)
return(FALSE);
if((WorkingItem=(struct LineItem *)FindPrev(Item))==NULL)
ItemNumber=0;
else
ItemNumber=Item->ItemNumber;
while((Item=(struct LineItem *)FindNext(Item))!=NULL)
{
if(ItemNumber==25)
ItemNumber=0;
Item->ItemNumber=ItemNumber++;
}
}
AddItem(Item) /*Adjust the ItemNumbers after adding an item*/
struct LineItem *Item;
{
int ItemNumber;
struct LineItem *CrntItem;
if((CrntItem=(struct LineItem *)FindPrev(Item))==NULL)
ItemNumber=0;
else
ItemNumber=CrntItem->ItemNumber+1;
do
{
if(ItemNumber==25)
ItemNumber=0;
Item->ItemNumber=ItemNumber++;
Item=(struct LineItem *)FindNext(Item);
}
while(Item != NULL && Item->PrevItem->Level >= Item->Level);
}
extern struct LineItem *FindPrev(Item) /*Find the previous item of*/
struct LineItem *Item; /*the same Level as Item*/
{
int Level;
Level=Item->Level;
Item=(struct LineItem *)Item->PrevItem;
while(Item->Level > Level && Item !=NULL)
Item=(struct LineItem *)Item->PrevItem;
if(Item->Level < Level || Item == NULL)
return(NULL);
else
return(Item);
}
extern struct LineItem *FindNext(Item) /*Find the next item of the same*/
struct LineItem *Item; /*Level as Item*/
{
int Level;
Level=Item->Level;
Item=(struct LineItem *)Item->NextItem;
while(Item->Level > Level && Item != NULL)
Item=(struct LineItem *)Item->NextItem;
if(Item->Level < Level)
return(NULL);
else
return(Item);
}
InsertLineAtTop() /*Insert a line at the top of the list*/
{
struct LineItem *WorkingItem;
WorkingItem=(struct LineItem *)
InsertItem(FirstItem,NULL);
WorkingItem->Level=1;
FirstItem=(struct LineItem *)WorkingItem;
AddItem(FirstItem);
PlotCursor(1,1);
RedrawOutlineChars(WorkingItem->NextItem,1,1);
PlotCursor(MinX(CurrentItem),1);
CursorUp();
}
WholeScreenDown() /*Scrolls down by an entire screen*/
{
struct LineItem *item;
UBYTE c,X,Y;
item=(struct LineItem *)ScrnBtm;
if(item->NextItem == NULL) /*No lines after screen bottom?*/
{ /*Move to last line*/
CurrentItem=(struct LineItem *)LastItem;
PlotCursor(MinX(CurrentItem),DispRows);
return(FALSE);
}
/*Get the first screen item*/
item=FirstScrnItem=(struct LineItem *)item->NextItem;
for(c=1;(c < CurY) && (item->NextItem != NULL);c++)
item=(struct LineItem *)item->NextItem; /*Get item at old Y*/
CurrentItem=(struct LineItem *)item; /*It is now the CurrentItem*/
Y=c; /*In case CurY is no longer possible (23 lines down)*/
/*If CurX's old position is no longer possible*/
/*move the cursor to the nearest possible position*/
if(CurX < MinX(CurrentItem))
X=MinX(CurrentItem);
else
if(CurX > MaxX(CurrentItem))
X=MaxX(CurrentItem);
else
X=CurX;
for(c=1;(c < SCRNHEIGHT-CurY) && (item->NextItem != NULL);c++)
item=(struct LineItem *)item->NextItem; /*Find screen bottom*/
ScrnBtm=(struct LineItem *)item; /*Got it!*/
DispRows=c; /*Get the number of lines*/
PrintItemList(FirstScrnItem,1); /*Refresh the display*/
PlotCursor(X,Y);
return(TRUE); /*Done!*/
}
WholeScreenUp() /*Move up one screenfull of lines*/
{
struct LineItem *item;
UBYTE c,X,Y;
Y=CurY;
item=(struct LineItem *)FirstScrnItem;
if(item->PrevItem == NULL) /*At the top?*/
{ /*Move cursor to first line*/
CurrentItem=(struct LineItem *)FirstItem;
PlotCursor(MinX(CurrentItem),1);
return(FALSE);
}
for(c=0;(c<SCRNHEIGHT) & (item->PrevItem != NULL);c++)
item=(struct LineItem *)item->PrevItem;
FirstScrnItem=(struct LineItem *)item;
for(c=1;(c<CurY) && (item->NextItem != NULL);c++) /*Get new CurrentItem*/
item=(struct LineItem *)item->NextItem;
CurrentItem=(struct LineItem *)item;
if(CurX < MinX(CurrentItem)) /*If CurX is no longer possible*/
X=MinX(CurrentItem); /*get closest possible X*/
else
if(CurX > MaxX(CurrentItem))
X=MaxX(CurrentItem);
else
X=CurX;
for(;(c<SCRNHEIGHT) & (item->NextItem != NULL);c++)
item=(struct LineItem *)item->NextItem; /*Get ScrnBtm*/
ScrnBtm=(struct LineItem *)item;
DispRows=c; /*Number of lines*/
PrintItemList(FirstScrnItem,1); /*Refresh display*/
PlotCursor(X,Y);
return(TRUE); /*Done!*/
}
OpenGraphics() /*Open screen, window, etc.*/
{
/*Open screen (640x200x2)*/
NewWindow.Screen=Screen=(struct Screen *)OpenScreen(&NewScreen);
if(Screen==NULL)
exit(40);
/*Open backdrop window & make requestors open onto it*/
if((ThisProc->pr_WindowPtr=Window=
(struct Window *)OpenWindow(&NewWindow))==NULL)
{
CloseScreen(Screen);
exit(50);
}
/*Install menus*/
SetMenuStrip(Window,&Menu1);
/*Setup the console.device*/
consoleWritePort=(struct Port *)CreatePort("mycon.write",0);
if(consoleWritePort==NULL)
Leave(60,"Couldn't open console.device!");
consoleWriteMsg=(struct IOStdReq *)CreateStdIO(consoleWritePort);
if(consoleWriteMsg==NULL)
Leave(70,"Couldn't open console.device!");
consoleReadPort=(struct Port *)CreatePort("mycon.read",0);
if(consoleReadPort==NULL)
exit(60);
consoleReadMsg=(struct IOStdReq *)CreateStdIO(consoleReadPort);
if(consoleReadMsg==NULL)
exit(70);
consoleWriteMsg->io_Data=(struct Window *)Window; /*Attach console*/
consoleWriteMsg->io_Length=sizeof(struct Window); /*device to window...*/
OpenDevice("console.device",0,consoleWriteMsg,0); /*& open it*/
ConsoleDevice=consoleReadMsg->io_Device=(APTR)consoleWriteMsg->io_Device;
consoleReadMsg->io_Unit=consoleWriteMsg->io_Unit;
consoleReadMsg->io_Command=CD_ASKKEYMAP;
consoleReadMsg->io_Length=sizeof(struct KeyMap);
consoleReadMsg->io_Data=&keymap;
DoIO(consoleReadMsg);
TitleErrorCancel();
}
CloseGraphics() /*Close the window, screen, etc.*/
{
CloseDevice(consoleWriteMsg);
DeleteStdIO(consoleWriteMsg);
DeleteStdIO(consoleReadMsg);
DeletePort(consoleWritePort);
DeletePort(consoleReadPort);
ClearMenuStrip(Window);
CloseWindow(Window);
CloseScreen(Screen);
}