home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
206.lha
/
Flist_v1.2
/
Sources
/
ttyio.c
< prev
Wrap
C/C++ Source or Header
|
1988-12-28
|
16KB
|
593 lines
/*
This is the I/O stuff for Flist... Inspired by the Mg2a
project.
Written by Stephen W. Berry. 8/19/88
*/
#include <libraries/arpbase.h>
#include "flist.h"
/*
* External Amiga functions.
*/
extern LONG AbortIO();
extern LONG CloseDevice();
extern struct IOStdReq *CreateStdIO();
extern int OpenConsole();
extern struct Window *OpenWindow();
extern LONG RawKeyConvert();
extern top;
/* extern Flist variables */
extern struct NewWindow *winptr;
extern struct Window mywin;
extern struct NewScreen *scrptr;
extern struct Screen scr;
extern struct Menu fmenu;
extern struct Gadget pg;
extern struct RastPort *rp;
extern struct Image cursor_image;
extern struct Image cursor_blank;
extern Enable_Abort;
extern struct FileLock *lock, *olddir;
extern char (*fname[MAXDIR])[FCHARS];
extern long (*finfo[MAXDIR])[4];
extern short remember;
/* Some external functions */
extern void swapdir(), parent();
extern long DoDOS(), spawnproc(), kill(), changedir();
/* Global variables */
struct Device *ConsoleDevice;
struct IOStdReq ConsoleReq;
struct InputEvent RawKeyEvent = {NULL,IECLASS_RAWKEY,0,0,0};
#define BUFSIZ 10
UBYTE KeyBuffer[BUFSIZ];
struct IntuiText input = {
TEXTCOLOR,0, /* Front & Back pen */
JAM2, /* Drawmode */
0,0, /* Left, Top */
NULL, /* Font */
KeyBuffer,
NULL /* Next text */
};
char conline[256];
char titlestr[80];
long row = 0,collum = 0,line = 0,first = 0;
void ttclose(),tthide(),ttshow();
/*
* Iconify Flist's window using tthide(), iconify(), and ttshow().
*/
VOID
tthide(resize)
int resize;
{
if (resize == TRUE) { /* if we're resizing, */
mywin.LeftEdge = winptr->LeftEdge; /* use current window size */
mywin.TopEdge = winptr->TopEdge;
mywin.Width = winptr->Width;
mywin.Height = winptr->Height;
}
ttclose(); /* reset to zero */
}
VOID
ttshow(resize)
int resize;
{
openstuff();
SetMenuStrip(winptr, &fmenu);
Enable_Abort = 1;
}
VOID
ttclose()
{
ClearMenuStrip(winptr);
CloseWindowSafely(winptr,NULL);
CloseScreen(scrptr);
winptr = NULL; scrptr = NULL;
Enable_Abort = 0;
}
extern long numfiles, lastsort;
refresh()
{
char buf[100], buf1[200];
remember = -10;
collum = 0;
if (row+1 > numfiles && row+2 == numfiles) {
row--;
line--;
} else
if (row > numfiles) {
top = 0;
row = 0;
line = 0;
}
sort(lastsort);
first = 0;
scrprt(NUMLINES,top);
PathName(lock, buf1);
sprintf(buf,"%s Files = %ld", buf1, numfiles);
strncpy(titlestr,buf,80L);
SetWindowTitles(winptr, -1L,titlestr);
}
OpenConsole()
{
if (OpenDevice("console.device",-1L,&ConsoleReq,0L)){
DisplayBeep();
Cleanup();
}
ConsoleDevice = ConsoleReq.io_Device; /* Lib base address */
}
/* this little guy takes input from the IDCMP and stuffs it out to the
routines involved... */
getkey(message)
struct IntuiMessage *message;
/* this routine has the potential to grow to enormous */
{ /* size... I'll try to restrain myself */
long keycodes,i,rc;
char buf[1000];
RawKeyEvent.ie_Code = message->Code;
RawKeyEvent.ie_Qualifier = message->Qualifier;
RawKeyEvent.ie_position.ie_addr = *((APTR *)message->IAddress);
keycodes = RawKeyConvert(&RawKeyEvent,KeyBuffer,BUFSIZ,NULL);
ReplyMsg(message);
if (keycodes > 0){ /* we have something */
blankcur();
switch (KeyBuffer[0]) {
case 0x7f: /* here we got a delete */
KeyBuffer[0] = 0;
if (collum == 0)
conline[0] = 0;
for(i=collum;i<254;i++)
conline[i] = conline[i+1];
drawline(collum,TRUE);
break;
case 0x08: /* back space */
KeyBuffer[0] = 0;
if (collum == 0)
conline[0] = 0;
if (collum > 0) {
collum--;
for(i=collum;i<254;i++)
conline[i] = conline[i+1];
}
drawline(collum, TRUE);
break;
case 0x0d:
KeyBuffer[0] = 0;
DoDOS(conline); /* This is the Biggie! */
if ( row == NLMO ) {
if ( top + NUMLINES < numfiles ) {
line++;
scrprt(NUMLINES,++top);
}
else
DisplayBeep(0L);
}
first = 0;
collum = 0;
for(i=0;i<255;i++)
conline[i] = 0;
break;
case 0x9b:
KeyBuffer[0] = 0;
switch (KeyBuffer[1]) {
case 0x3f: /* looking for the Help key */
if (KeyBuffer[2] == 0x7e)
Help();
break;
case 0x41: /* up arrow */
if (collum == 0) {
for(i=0;i<255;i++)
conline[i] = 0;
}
else {
strcpy(buf,conline);
conline[first] = 0;
drawline(collum,TRUE);
strcpy(conline,buf);
}
if (row > 0) {
line--;
row--;
}
else if (row == 0 && top > 0) {
line--;
scrprt(NUMLINES,--top);
}
drawline(collum,TRUE);
break;
case 0x42: /* Down Arrow */
if (collum == 0) {
for(i=0;i<255;i++)
conline[i] = 0;
}
else {
strcpy(buf,conline);
conline[first] = 0;
drawline(collum,TRUE);
strcpy(conline,buf);
}
if (row < NLMO) {
if (line < numfiles - 1){
line++;
row++;
}
}
else if (row == NLMO && line < numfiles - 1) {
line++;
scrprt(NUMLINES,++top);
}
drawline(collum,TRUE);
break;
case 0x44: /* Left Arrow */
if (collum > 0)
collum--;
drawline(collum,TRUE);
break;
case 0x43: /* Right Arrow */
if (collum < 90)
collum++;
else
DisplayBeep(NULL);
drawline(collum,FALSE);
break;
default:
check_for_shift();
break;
}
KeyBuffer[1] = 0;
break;
case 0x1b: /* The File name insertion thing... */
insert_name();
break;
default:
if (KeyBuffer[0] < 0x20)
control_keys(KeyBuffer[0]);
else
enter_char(KeyBuffer[0]);
break;
}
drawcur();
}
}
/* I split up the switch for two reasons... One, I though that the first
was getting a bit big, Two, I think MANX chokes on large switches.
*/
/* Looking for the shift-arrow keys */
check_for_shift()
{
char buf[256];
switch (KeyBuffer[1]) {
case 'T':
if (top > 0) {
if (line < 10)
line = 0;
else
if (top < 10)
line -= top;
else
line -= 10;
if (top < 10)
top = 0;
else
top -= 10;
}
scrprt(NUMLINES,top);
strcpy(buf,conline);
conline[first] = 0;
drawline(collum,TRUE);
strcpy(conline,buf);
drawline(collum,TRUE);
break;
case 'S':
if (numfiles - 11 > line) {
if (numfiles - 11 < line)
line = numfiles - 1;
else
line += 10;
if (top+10 > numfiles - 1)
top = numfiles - 1;
else
top += 10;
}
scrprt(NUMLINES,top);
strcpy(buf,conline);
conline[first] = 0;
drawline(collum,TRUE);
strcpy(conline,buf);
drawline(collum,TRUE);
break;
case ' ':
switch(KeyBuffer[2]) {
case 'A': /* left arrow */
collum = 0;
first = 0;
drawline(collum,TRUE);
break;
case '@': /* right arrow */
collum = strlen(conline);
first = collum > 29 ? collum - 29: 0;
drawline(collum,TRUE);
break;
}
}
}
control_keys(key)
char key;
{
char buf[256];
int i;
switch(key) {
case 0x01: /* ^A - get the Arp file-requestor */
if (Wbargs() == 0){
UnLock(olddir);
refresh();
}
break;
case 0x03: /* user typed ^C */
_abort();
break;
case 0x04: /* ^D - change directory to fname */
/* ***** Hidden SECRET of AmigaDOS !! *****
only found in the RKM includes... You can tell if a file is
really a file or if it is a directory by the value of DirEntryType.
If it is < 0 then it is a file, if > 0 then it is a directory */
if (*finfo[line][0] < 0){
sprintf(buf,"%s Not a directory",fname[line]);
auto_req(buf);
}else {
changedir(fname[line]);
refresh();
}
break;
case 0x07: /* ^G - Re-get the current dir */
getdir();
refresh();
break;
case 0x0b: /* ^K - Delete file */
kill(fname[line]);
refresh();
break;
case 0x0c: /* ^L - refresh the screen */
collum = 0;
row = 0;
line = 0;
first = 0;
top = 0;
refresh(); /* also resets the cursor to zero pos */
break;
case 0x0e: /* ^N - Make directory */
make_dir();
refresh();
break;
case 0x0f: /* ^O - sort by pattern */
sort(3);
refresh();
break;
case 0x10: /* ^P - change directory to Parent */
parent();
refresh();
break;
case 0x12: /* ^R - rename file */
rename_file(fname[line]);
refresh();
break;
case 0x13: /* ^S - sort by names */
sort(0);
refresh();
break;
case 0x14: /* ^T - sort by Time */
sort(2);
refresh();
break;
case 0x15: /* ^U - erase line to start */
for (i=0;i<254;i++)
conline[i] = '\0';
first = 0;
collum = 0;
drawline(collum,TRUE);
break;
case 0x18: /* ^X - Start REXX macro */
dorexx();
break;
case 0x19: /* ^Y - sort by day */
sort(4);
refresh();
break;
case 0x1a: /* ^Z - sort by size */
sort(1);
refresh();
break;
}
}
/* Enter a char into the array and screen */
enter_char(c)
register char c;
{
int i;
for(i=254;i>collum;i--) /* This is for insert mode */
conline[i] = conline[i-1];
KeyBuffer[0] = c;
if (collum < 90) {
conline[collum] = c;
collum++;
drawline(collum,FALSE);
} else
DisplayBeep(NULL);
KeyBuffer[0] = 0;
}
/* Draw the current line from the cursor position, for scrolling */
drawline (curpos,flag)
long curpos,flag;
{
long i,temp1,temp2;
char tbuf[31];
#ifdef DEBUG
char buf[90];
sprintf(buf," Row %ld Collumn %ld Top %ld First %ld line %ld \
numfiles %ld",row,collum,top,first,line,numfiles);
SetWindowTitles(winptr,-1L,buf);
#endif
temp2 = LINEH * row + TOP + 2;
if ((collum >= first+30) || (collum == first)) {
if (flag){
if (first>0)
first--;
}
else {
if (first<89)
first++;
}
}
strncpy(tbuf,&conline[first],30);
temp1 = strlen(tbuf);
for(i=temp1;i<29;i++)
tbuf[i] = ' ';
tbuf[29] = '\0';
input.IText = tbuf;
PrintIText(rp,&input,(LONG)LEFT,temp2);
input.IText = KeyBuffer;
}
long getcol()
{
register long temp1;
if (collum == first + 29)
temp1 = CHARW * 29 + LEFT;
else if (first == collum)
temp1 = LEFT;
else {
temp1 = CHARW * (collum - first) + LEFT;
}
return temp1;
}
/* Draw the cursor at the current row & collum */
drawcur()
{
register long temp1,temp2;
temp1 = getcol();
temp2 = LINEH * row + TOP + 2;
SetDrMd(rp,COMPLEMENT|JAM1);
SetAPen(rp,4);
RectFill(rp,temp1,temp2,temp1+7,temp2+7);
SetAPen(rp,2);
SetDrMd(rp,JAM1);
}
/* Blank the cursur, where-ever it is. */
blankcur()
{
register long temp1,temp2;
temp1 = getcol();
temp2 = LINEH * row + TOP + 2;
SetDrMd(rp,COMPLEMENT|JAM2);
SetAPen(rp,0);
RectFill(rp,temp1,temp2,temp1+7,temp2+7);
SetAPen(rp,2);
SetDrMd(rp,JAM1);
}
/* This is where the File insertion code is (in case you were wondering) */
insert_name()
{
register int i, j;
register char *temp;
j=0;
if(line > numfiles)
return;
for (i=collum;i<89;i++){
temp = fname[line];
if (temp[j] == 0)
break;
enter_char(temp[j++]);
}
}