home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
104.lha
/
textreader.c
< prev
next >
Wrap
C/C++ Source or Header
|
1980-07-10
|
16KB
|
750 lines
/* TextReader by Oren Peli, Copyright (c) 1987 BazboSOFT! */
/*
* Introduction:
*
* TextReader is, I believe, the most useful program I've written on
* the Amiga and I am very proud of it.
*
* TextReader's purpose is to make editing within the CLI much easier,
* and as far as I know, there isn't any other program of that kind
* for the Amiga.
*
* Examples of where could TextReader make you life easier:
*
* 1) Right after finishing writing TextReader, I wanted to copy it
* to my browsing/debugging/working CLI disk, only that
* it was completely full.
*
* I dir'ed the C subdirectory and saw many files I never
* use (lab, if, endif, else, etc.). So I wrote (from csh):
* % rm
* and with TextReader copied all the files names I wanted
* to delete.
*
* 2) While looking at several Fish disks to see how useful and
* debugged TextReader was, I've encounterred STEmualtor:
* I cd'ed into it's directory (with TextReader, of
* course) and 'Type'ed 'README'. Fish wrote in that file
* that in order to run the STEmulator, it is necessary to
* write something like:
* "assign STEmulator: AmigaLibDisk43:STEmulator",
* so, with TextReader, I simply copied those instructions
* instead of retyping then.
*
* Usage:
*
* It's very simple: run it (using the run command) and press the
* left mouse button within the CLI window on a text, drag the
* mouse and watch the results.
*
* To quit: You have a menu: just press the right mouse button
* and pick the Quit (and only) menu.
*
*
* Note: The menu will appear ONLY if the pointer is positioned
* above the window's title bar.
*
*
* If the right mouse button is pressed:
*
* If the pointer is positioned left of the cursor (but in the
* same line) the program will generate BACKSPACE events.
*
* If the pointer is positioned right of the cursor (but in the
* same line) the program will generate DEL keys events.
*
* If the pointer is positioned exactly over the cursor, the
* program will echo your arguments.
*
* If the pointer is positioned under the current cursor line,
* the program will generate a RETURN key event.
*
* Syntax:
* RUN TextReader [string...]
*
* Note: For generating Return key event, use '\n'
*
* Examples:
*
* RUN TextReader
* RUN TextReader "Cd df1:\nDir opt a\n"
* RUN TextReader sys:
* RUN TextReader NewCLI\n
*
* Problems list:
* 1) The program won't recognize alt characters.
* 2) The program won't recognize any text written with foreground
* color other then 1 and/or background color other then 0.
* 3) The program won't recognize any text written in any other
* style then normal.
* 4) The program won't recognize any text written with font
* which its size is not 8x8 (the font must also be
* a fixed with font (e.g. not proportional) ).
* 5) After changing the font (using 'font' for example) of the cli,
* you MUST quit from TextReader and re-run it.
*
* All in all, TextReader is an extremely useful utility and should be called
* from everyone's startup-sequence.
*
* Bug reports, suggestions, etc. can be sent to me at the following address:
*
* Oren Peli
* Shkediya 13
* Ramat-Gan 52-546
* ISRAEL
*
* ..or, if you want to chat with me over the phone, you can call: 03-7514475.
*
*
* You may not immediately realize how powerful TextReader really is,
* after doing so, please consider sending me a donation
* ($20 seems like a nice round number), although TextReader is NOT
* a Sharewere program but a public domain.
*
* For every $100 dollars I receive, I will fix a problem from
* the above list.
*
* ENJOY!
*/
#include <intuition/intuitionbase.h> /* Added by Adams Douglas */
#include <devices/conunit.h>
#include <devices/input.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <libraries/dosextens.h>
extern void *AllocMem();
extern PLANEPTR AllocRaster();
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
extern void *OpenLibrary();
extern void *CreateStdIO();
extern long findWindow();
struct ConUnit *conUnit = NULL;
struct Window *conWindow = NULL;
void *CreatePort() , *FindPort();
struct Process *FindTask();
struct IntuiMessage *GetMsg();
struct RastPort dummy_rastport , *trp = &dummy_rastport;
struct BitMap dummy_bitmap , *tbm = &dummy_bitmap;
struct RastPort dummy_rastport2 , *crp = &dummy_rastport2;
struct BitMap dummy_bitmap2 , *cbm = &dummy_bitmap2;
struct IntuiText ItemText = { 3 , 1 , JAM1 , 1 , 1 , NULL , (STRPTR) "Quit TextReader"
, NULL };
struct MenuItem MenuItem = { NULL , 0 , 0 , 121 , 10 , ITEMTEXT | ITEMENABLED |
HIGHCOMP, 0, (APTR) &ItemText , NULL , NULL , NULL , 0xFFFF };
struct Menu Menu = { NULL , 0 , 0 , 121 , 0 , MENUENABLED , " Quit" , &MenuItem };
struct chr_data
{
char chr;
char raw_data;
char is_shifted;
PLANEPTR pln;
};
struct chr_data chrs[] =
{
{ ' ' , 0x40 , 0 } ,
{ 'a' , 0x20 , 0 } ,
{ 'b' , 0x35 , 0 } ,
{ 'c' , 0x33 , 0 } ,
{ 'd' , 0x22 , 0 } ,
{ 'e' , 0x12 , 0 } ,
{ 'f' , 0x23 , 0 } ,
{ 'g' , 0x24 , 0 } ,
{ 'h' , 0x25 , 0 } ,
{ 'i' , 0x17 , 0 } ,
{ 'j' , 0x26 , 0 } ,
{ 'k' , 0x27 , 0 } ,
{ 'l' , 0x28 , 0 } ,
{ 'm' , 0x37 , 0 } ,
{ 'n' , 0x36 , 0 } ,
{ 'o' , 0x18 , 0 } ,
{ 'p' , 0x19 , 0 } ,
{ 'q' , 0x10 , 0 } ,
{ 'r' , 0x13 , 0 } ,
{ 's' , 0x21 , 0 } ,
{ 't' , 0x14 , 0 } ,
{ 'u' , 0x16 , 0 } ,
{ 'v' , 0x34 , 0 } ,
{ 'w' , 0x11 , 0 } ,
{ 'x' , 0x32 , 0 } ,
{ 'y' , 0x15 , 0 } ,
{ 'z' , 0x31 , 0 } ,
{ '0' , 0x0a , 0 } ,
{ '1' , 0x01 , 0 } ,
{ '2' , 0x02 , 0 } ,
{ '3' , 0x03 , 0 } ,
{ '4' , 0x04 , 0 } ,
{ '5' , 0x05 , 0 } ,
{ '6' , 0x06 , 0 } ,
{ '7' , 0x07 , 0 } ,
{ '8' , 0x08 , 0 } ,
{ '9' , 0x09 , 0 } ,
{ '-' , 0x0b , 0 } ,
{ '=' , 0x0c , 0 } ,
{ '\\' , 0x0d , 0 } ,
{ '[' , 0x1a , 0 } ,
{ ']' , 0x1b , 0 } ,
{ ';' , 0x29 , 0 } ,
{ '\'' , 0x2a , 0 } ,
{ ',' , 0x38 , 0 } ,
{ '.' , 0x39 , 0 } ,
{ '/' , 0x3a , 0 } ,
{ '`' , 0x00 , 0 } ,
{ 'A' , 0x20 , 1 } ,
{ 'B' , 0x35 , 1 } ,
{ 'C' , 0x33 , 1 } ,
{ 'D' , 0x22 , 1 } ,
{ 'E' , 0x12 , 1 } ,
{ 'F' , 0x23 , 1 } ,
{ 'G' , 0x24 , 1 } ,
{ 'H' , 0x25 , 1 } ,
{ 'I' , 0x17 , 1 } ,
{ 'J' , 0x26 , 1 } ,
{ 'K' , 0x27 , 1 } ,
{ 'L' , 0x28 , 1 } ,
{ 'M' , 0x37 , 1 } ,
{ 'N' , 0x36 , 1 } ,
{ 'O' , 0x18 , 1 } ,
{ 'P' , 0x19 , 1 } ,
{ 'Q' , 0x10 , 1 } ,
{ 'R' , 0x13 , 1 } ,
{ 'S' , 0x21 , 1 } ,
{ 'T' , 0x14 , 1 } ,
{ 'U' , 0x16 , 1 } ,
{ 'V' , 0x34 , 1 } ,
{ 'W' , 0x11 , 1 } ,
{ 'X' , 0x32 , 1 } ,
{ 'Y' , 0x15 , 1 } ,
{ 'Z' , 0x31 , 1 } ,
{ '!' , 0x01 , 1 } ,
{ '@' , 0x02 , 1 } ,
{ '#' , 0x03 , 1 } ,
{ '$' , 0x04 , 1 } ,
{ '%' , 0x05 , 1 } ,
{ '^' , 0x06 , 1 } ,
{ '&' , 0x07 , 1 } ,
{ '*' , 0x08 , 1 } ,
{ '(' , 0x09 , 1 } ,
{ ')' , 0x0a , 1 } ,
{ '_' , 0x0b , 1 } ,
{ '+' , 0x0c , 1 } ,
{ '|' , 0x0d , 1 } ,
{ '{' , 0x1a , 1 } ,
{ '}' , 0x1b , 1 } ,
{ ':' , 0x29 , 1 } ,
{ '"' , 0x2a , 1 } ,
{ '<' , 0x38 , 1 } ,
{ '>' , 0x39 , 1 } ,
{ '?' , 0x3a , 1 } ,
{ '~' , 0x00 , 1 } ,
{ -1 , -1 , -1 }
};
struct MsgPort *port = NULL;
struct IOStdReq *req = NULL;
long errdev = 0;
int num_of_chrs;
struct InputEvent ie;
int really_open_window = 0;
do_args(c , v)
register int c;
register char *v[];
{
register int i , j , k , s;
register char chr;
for (i = 1 ; i < c ; i++)
{
s = strlen(v[i]);
for (j = 0 ; j < s ; j++)
{
if (v[i][j] == '\\' && v[i][j + 1] == 'n')
{
ie.ie_Qualifier = NULL;
ie.ie_Code = 0x44;
DoIO(req);
ie.ie_Code = 0x44 | 0x80;
DoIO(req);
j += 2;
}
chr = v[i][j];
for (k = 0 ; k != num_of_chrs ; k++)
if (chrs[k].chr == chr)
{
fake_raw_key_event(k);
break;
}
}
}
}
fake_raw_key_event(c)
register char c;
{
ie.ie_Qualifier = chrs[c].is_shifted ? IEQUALIFIER_LSHIFT : NULL;
ie.ie_Code = chrs[c].raw_data;
DoIO(req);
ie.ie_Code |= 0x80;
DoIO(req);
}
the_same()
{
register int i;
register PLANEPTR ptr1 , ptr2;
ptr1 = cbm->Planes[0];
ptr2 = tbm->Planes[0];
for (i = 0 ; i != 16 ; i += 2)
if (ptr1[i] != ptr2[i])
return(0);
return(1);
}
identify_char()
{
register int c;
for (c = 0 ; c != num_of_chrs ; c++)
{
cbm->Planes[0] = chrs[c].pln;
if (the_same() )
return(c);
}
return(-1);
}
convert_char(x , y)
register int x , y;
{
register int rx , ry;
register int c;
rx = x - conUnit->cu_XROrigin;
ry = y - conUnit->cu_YROrigin;
rx &= ~7;
ry &= ~7;
rx += conUnit->cu_XROrigin;
ry += conUnit->cu_YROrigin;
ClipBlit(conWindow->RPort , (long) rx , (long) ry , trp , 0L , 0L , 8L , 8L ,
0xC0L);
if ( (c = identify_char() ) != -1)
fake_raw_key_event(c);
}
main(argc , argv)
int argc;
char *argv[];
{
register struct Window *win;
register struct IntuiMessage *msg;
register int x , y , code , qua;
register long class;
register int pressed = 0;
register int rx , ry;
register int prx = -1111 , fy , px = -1111 , maxx = -1111;
register int i;
register char buf[2];
register long bl;
register char string_buffer[50];
puts("TextReader, by Oren Peli, Copyright (C) 1987 BazboSOFT!");
for (i = 0 ; chrs[i].raw_data != -1 ; i++)
chrs[i].pln = NULL;
num_of_chrs = i - 1;
if (NOT (IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library" , 33L) ) )
bye();
if (NOT findWindow() )
bye();
win = conWindow;
sprintf(string_buffer , "TextReader's port (win:%lx)" , win);
if (FindPort(string_buffer) )
{
puts("But you have already ran TextReader from this window!");
bye();
}
if (NOT (port = CreatePort(string_buffer , 0L) ) )
bye();
if (NOT (req = CreateStdIO(port) ) )
bye();
if (errdev = OpenDevice("input.device" , 0L , req , 0L) )
bye();
if (NOT (GfxBase = (struct GfxBase *) OpenLibrary("graphics.library" , 33L) ) )
bye();
InitRastPort(trp);
InitRastPort(crp);
InitBitMap(tbm , 1L , 8L , 8L);
InitBitMap(cbm , 1L , 8L , 8L);
trp->BitMap = tbm;
crp->BitMap = cbm;
if (NOT (tbm->Planes[0] = AllocRaster(8L , 8L) ) )
bye();
SetAPen(trp , 0L);
RectFill(trp , 0L , 0L , 8L , 8L);
buf[1] = 0;
SetAPen(crp , 1L);
SetDrMd(crp , JAM2);
bl = GfxBase->DefaultFont->tf_Baseline;
for (i = 0 ; i != num_of_chrs ; i++)
{
cbm->Planes[0] = chrs[i].pln = AllocRaster(8L , 8L);
if (NOT chrs[i].pln)
bye();
Move(crp , 0L , bl);
buf[0] = chrs[i].chr;
Text(crp , buf , 1L);
}
req->io_Command = IND_WRITEEVENT;
req->io_Flags = 0;
req->io_Length = (long) sizeof(struct InputEvent);
req->io_Data = (void *) &ie;
ie.ie_NextEvent = NULL;
ie.ie_Class = IECLASS_RAWKEY;
ie.ie_TimeStamp.tv_secs = 0;
ie.ie_TimeStamp.tv_micro = 0;
ie.ie_X = 0;
ie.ie_Y = 0;
ModifyIDCMP(win , MOUSEBUTTONS | MOUSEMOVE | MENUPICK);
ReportMouse(TRUE , win);
SetMenuStrip(win , &Menu);
while (msg = GetMsg(win->UserPort) )
ReplyMsg(msg);
really_open_window = 1;
loop:
WaitPort(win->UserPort);
msg = GetMsg(win->UserPort);
class = msg->Class;
code = msg->Code;
x = msg->MouseX;
y = msg->MouseY;
ReplyMsg(msg);
Forbid();
if (y < 10)
win->Flags &= ~RMBTRAP;
else
win->Flags |= RMBTRAP;
Permit();
if (class == MENUPICK && code != MENUNULL)
bye();
else if (class == MOUSEBUTTONS)
{
if (code == SELECTDOWN)
{
ry = ( (fy = y) - conUnit->cu_YROrigin) / 8;
pressed = 1;
}
else if (code == SELECTUP)
{
prx = -1111;
px = -1111;
maxx = -1111;
pressed = 0;
}
else if (code == MENUDOWN)
{
rx = (x - conUnit->cu_XROrigin) / 8;
ry = (y - conUnit->cu_YROrigin) / 8;
ie.ie_Qualifier = NULL;
if (ry > conUnit->cu_YCCP)
{
ie.ie_Code = 0x44;
DoIO(req);
ie.ie_Code = 0x44 | 0x80;
DoIO(req);
}
else if (ry == conUnit->cu_YCCP)
{
if (rx > conUnit->cu_XCCP)
{
for (i = rx - conUnit->cu_XCCP + 1 ; i ; i--)
{
ie.ie_Code = 0x46;
DoIO(req);
ie.ie_Code = 0x46 | 0x80;
DoIO(req);
}
}
else if (rx < conUnit->cu_XCCP)
{
for (i = conUnit->cu_XCCP - rx ; i ; i--)
{
ie.ie_Code = 0x41;
DoIO(req);
ie.ie_Code = 0x41 | 0x80;
DoIO(req);
}
}
else if (rx == conUnit->cu_XCCP)
do_args(argc , argv);
}
prx = -1111;
px = -1111;
maxx = -1111;
pressed = 0;
}
}
if (pressed && x >= conUnit->cu_XROrigin && y >= conUnit->cu_YROrigin && x <
conUnit->cu_XRExtant && y < conUnit->cu_YRExtant)
{
rx = (x - conUnit->cu_XROrigin) / 8;
if (rx != prx && rx > maxx)
{
maxx = rx;
if (rx > prx && rx - prx > 1 && prx != -1111)
{
for (i = rx - prx + 1 , x = px + 8 ; i && x <
conUnit->cu_XRExtant ; x += 8 , i--)
convert_char(x , fy);
x -= 8;
}
else
convert_char(x , fy);
rx = (x - conUnit->cu_XROrigin) / 8;
if (rx > maxx)
maxx = rx;
prx = rx;
px = x;
}
}
goto loop;
bye();
}
bye()
{
register int i;
for (i = 0 ; i != num_of_chrs ; i++)
if (chrs[i].pln)
FreeRaster(chrs[i].pln , 8L , 8L);
if (tbm->Planes[0])
FreeRaster(tbm->Planes[0] , 8L , 8L);
if (conWindow && really_open_window)
{
Forbid();
conWindow->Flags &= ~RMBTRAP;
Permit();
ClearMenuStrip(conWindow);
ReportMouse(FALSE , conWindow);
ModifyIDCMP(conWindow , NULL);
}
if (IntuitionBase)
CloseLibrary(IntuitionBase);
if (GfxBase)
CloseLibrary(GfxBase);
if (NOT errdev && req)
CloseDevice(req);
if (req)
DeleteStdIO(req);
if (port)
DeletePort(port);
exit(0);
}
extern long sendpkt();
LONG findWindow() /* inits conWindow and conUnit (global vars) */
{
register struct InfoData *id;
register struct MsgPort *conid;
register struct Process *me;
register LONG myargs[8] ,nargs, res1;
/* Alloc to insure longword alignment */
id = (struct InfoData *)AllocMem( (long) sizeof(struct InfoData),
MEMF_PUBLIC|MEMF_CLEAR);
if(! id) return(0);
me = (struct Process *) FindTask(NULL);
conid = (struct MsgPort *) me->pr_ConsoleTask;
myargs[0]=((ULONG)id) >> 2;
nargs = 1;
res1 = (LONG)sendpkt(conid,ACTION_DISK_INFO,myargs,nargs);
conWindow = (struct Window *)id->id_VolumeNode;
conUnit = (struct ConUnit *)
((struct IOStdReq *)id->id_InUse)->io_Unit;
FreeMem(id, (long) sizeof(struct InfoData));
return(res1);
}
LONG sendpkt(pid,action,args,nargs)
register struct MsgPort *pid; /* process indentifier ... (handlers message port ) */
register LONG action, /* packet type ... (what you want handler to do ) */
args[], /* a pointer to a argument list */
nargs; /* number of arguments in list */
{
register struct MsgPort *replyport;
struct StandardPacket *packet;
register LONG count, *pargs, res1;
replyport = (struct MsgPort *) CreatePort( (long) NULL, (long) 0);
if(!replyport) return( (long) NULL);
packet = (struct StandardPacket *)
AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
if(!packet)
{
DeletePort(replyport);
return(NULL);
}
packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
packet->sp_Pkt.dp_Port = replyport;
packet->sp_Pkt.dp_Type = action;
/* copy the args into the packet */
pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
for(count=0;count < nargs;count++)
pargs[count]=args[count];
PutMsg(pid,packet); /* send packet */
WaitPort(replyport);
GetMsg(replyport);
res1 = packet->sp_Pkt.dp_Res1;
FreeMem(packet,(long)sizeof(struct StandardPacket));
DeletePort(replyport);
return(res1);
}