home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
editors
/
elvis1_5.arj
/
AMITTY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-09
|
8KB
|
335 lines
/* amitty.c */
/*-
* Mike Rieser Dale Rahn
* 2410 Happy Hollow Rd. Apt D-10 540 Vine St.
* West Lafayette, IN 47906 West Lafayette, IN 47906
* riesermc@mentor.cc.purdue.edu rahn@sage.cc.purdue.edu
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/memory.h>
#include <devices/conunit.h>
#include <dos/dos.h>
#include <clib/macros.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#if AZTEC_C
#include <pragmas/exec_lib.h>
#include <pragmas/dos_lib.h>
#else
#include <pragmas/exec.h>
#include <pragmas/dos.h>
#endif
#include "config.h"
/*-
* Defines for amigatty.
*
* Note: Amiga <CSI> Control Sequence Introducer is either:
* 0x9b or <ESC>[ == 0x1b 0x5b.
*
* The Amiga always responds with 0x9b.
*
* For you octal fans: 0x9b == \233, 0x1b == \033.
*/
#define CSI '\233'
#define TIME_FACTOR (100000)/* convert 1/10 sec to microsecs */
/* Amiga Console Control Sequences */
#define ENABLE_SCROLL ((UBYTE *) "\233>1h") /* Amiga default */
#define DISABLE_SCROLL ((UBYTE *) "\233>1l")
#define AUTOWRAP_ON ((UBYTE *) "\233?7h") /* Amiga default */
#define AUTOWRAP_OFF ((UBYTE *) "\233?7l")
#define CURSOR_ON ((UBYTE *) "\233 p") /* Amiga default */
#define CURSOR_OFF ((UBYTE *) "\2330 p")
#define RAW_EVENTS_ON ((UBYTE *) "\23312{") /* Set Window Resize Reports */
#define RAW_EVENTS_OFF ((UBYTE *) "\23312}") /* Reset Window Resize Reports */
/* take out for compiling with elvis */
#ifndef ctrl
#define ctrl(ch) ((ch)&037)
#endif
/* Variables */
static BPTR fh = 0, inputFH, outputFH, oldinputFH, oldoutputFH;
static UBYTE title[]= "RAW:0/0/999/999/Amiga Elvis 1.5/SIMPLE";
static int amigaterm = 0;
/* Function prototypes for amitty.c */
void amiopenwin(char *termtype);
void amiclosewin(void);
void ttysetup(void);
void ttyshutdown(void);
int ttywrite(char *buf, int len);
int ttyread(char *buf, int len, int time);
int CheckforSpecial(char *buf, long len);
LONG setRawCon(LONG toggle);
LONG sendpkt(struct MsgPort *pid, LONG action, LONG args[], LONG nargs);
/*
* amiopenwin - opens a window if we don't already have one.
*/
void
amiopenwin(char *termtype)
{
if (!IsInteractive(Input()))
{
/* open our own window in RAW mode */
if (isOldDOS() || (BPTR) 0 == (fh = Open(title, MODE_READWRITE)))
{
PutStr((UBYTE *) "Couldn't open RAW: window");
clean_exit(1);
} else
{
oldinputFH = SelectInput(fh);
oldoutputFH = SelectOutput(fh);
}
}
inputFH = Input();
outputFH = Output();
if (!strcmp(termtype, TERMTYPE))
{
amigaterm = 1;
Write(outputFH, AUTOWRAP_OFF, sizeof(AUTOWRAP_OFF));
}
return;
}
/*
* amiclosewin - closes a window if we opened one.
*/
void
amiclosewin()
{
if (amigaterm)
{
Write(outputFH, AUTOWRAP_ON, sizeof(AUTOWRAP_ON)); /* Amiga default */
}
if (fh)
{ /* Close down the window */
SelectInput(oldinputFH);
SelectOutput(oldoutputFH);
Close(fh);
}
return;
}
/*
* ttysetup - console initalization routine for Amiga Computers.
*
* Sets raw mode and enables resize notifications.
*/
void
ttysetup()
{
if (isOldDOS())
{
setRawCon(DOSTRUE);
} else
{
SetMode(inputFH, 1); /* Enter RAW mode */
}
if (amigaterm)
{
Write(outputFH, RAW_EVENTS_ON, sizeof(RAW_EVENTS_ON));
}
return;
}
/*
* ttyshutdown - console shutdown routine for Amiga Computers.
*
* Resets raw mode and disables resize notifications.
*/
void
ttyshutdown()
{
if (amigaterm)
{
Write(outputFH, RAW_EVENTS_OFF, sizeof(RAW_EVENTS_OFF));
}
if (isOldDOS())
{
setRawCon(DOSFALSE);
} else
{
SetMode(inputFH, 0); /* Leave RAW mode */
}
return;
}
/*
* ttywrite - amiga version of ttywrite.
*
* This version makes small writes to the console as suggested in the RKM.
* Also turns off the cursor to speed output to the screen.
*/
int
ttywrite(buf, len)
char *buf;
int len;
{
int cursor_off;
register int bytes;
register UBYTE *pc = (UBYTE *) buf;
/* See if turning off the cursor is worthwhile */
if (cursor_off = amigaterm && len > 2 * sizeof(CURSOR_OFF))
{
Write(outputFH, CURSOR_OFF, sizeof(CURSOR_OFF)); /* Turn Cursor OFF */
}
/* The console.device doesn't like large writes */
for (bytes = 0; len; pc += bytes, len -= bytes)
{
bytes = Write(outputFH, pc, MIN((LONG) len, 256L));
}
if (cursor_off)
{
Write(outputFH, CURSOR_ON, sizeof(CURSOR_ON)); /* Turn Cursor ON */
}
return pc - buf;
}
/*
* ttyread - amiga version of ttyread.
*/
int
ttyread(buf, len, time)
char *buf; /* where to store the gotten characters */
int len; /* maximum number of characters to read */
int time; /* maximum time in 1/10 sec for reading */
{
LONG bytes = 0; /* number of bytes actually read */
if (!time || WaitForChar(inputFH, time * TIME_FACTOR))
{ /* Read() if time == 0 or chars waiting */
bytes = Read(inputFH, (UBYTE *) buf, (LONG) len);
bytes = CheckforSpecial(buf, bytes);
}
return bytes; /* the number of bytes read in buf */
}
/*
* CheckforSpecial - crude parser for raw console events.
*/
int
CheckforSpecial(buf, len)
char *buf;
long len;
{
int isnewsize = 0;
char *pb, *peor, *pend;
pb = buf;
pend = &buf[len];
do
{
if (CSI != *pb)
continue;
if (WaitForChar(inputFH, 1))
{
pend += Read(inputFH, pend, 72);
}
if (peor = strchr((char *) pb, '|')) /* Window Resize Event */
{ /* bug == <CSI> seq <CSI> event '|' */
*pb = ctrl('L'); /* force redraw */
isnewsize = 1;
memmove(pb + 1, peor + 1, pend - peor);
pend -= peor - pb;
}
}
while (*pb++);
if (isnewsize)
getsize(0);
return pend - buf;
}
/* INDENT OFF */
/* sendpkt code - A. Finkel, P. Lindsay, C. Scheppner CBM */
LONG setRawCon(toggle)
LONG toggle; /* DOSTRUE (-1L) or DOSFALSE (0L) */
{
struct MsgPort *conid;
struct Process *me;
LONG myargs[8] ,nargs, res1;
me = (struct Process *) FindTask(NULL);
conid = (struct MsgPort *) me->pr_ConsoleTask;
myargs[0]= toggle;
nargs = 1;
res1 = (LONG)sendpkt(conid,ACTION_SCREEN_MODE,myargs,nargs);
return(res1);
}
LONG sendpkt(pid,action,args,nargs)
struct MsgPort *pid; /* process indentifier ... (handlers message port ) */
LONG action, /* packet type ... (what you want handler to do ) */
args[], /* a pointer to a argument list */
nargs; /* number of arguments in list */
{
struct MsgPort *replyport;
struct StandardPacket *packet;
LONG count, *pargs, res1;
replyport = (struct MsgPort *) CreatePort(NULL,0);
if(!replyport) return((LONG)NULL);
packet = (struct StandardPacket *)
AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
if(!packet)
{
DeletePort(replyport);
return((LONG)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);
}