|
|
1.1 root 1: /* amitty.c */
2:
3: /*-
4: * Mike Rieser Dale Rahn
5: * 2410 Happy Hollow Rd. Apt D-10 540 Vine St.
6: * West Lafayette, IN 47906 West Lafayette, IN 47906
7: * [email protected] [email protected]
8: */
9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <exec/memory.h>
14: #include <devices/conunit.h>
15: #include <dos/dos.h>
16: #include <clib/macros.h>
17: #include <clib/exec_protos.h>
18: #include <clib/dos_protos.h>
19:
20: #if AZTEC_C
21: #include <pragmas/exec_lib.h>
22: #include <pragmas/dos_lib.h>
23: #else
24: #include <pragmas/exec.h>
25: #include <pragmas/dos.h>
26: #endif
27:
28: #include "config.h"
29:
30: /*-
31: * Defines for amigatty.
32: *
33: * Note: Amiga <CSI> Control Sequence Introducer is either:
34: * 0x9b or <ESC>[ == 0x1b 0x5b.
35: *
36: * The Amiga always responds with 0x9b.
37: *
38: * For you octal fans: 0x9b == \233, 0x1b == \033.
39: */
40: #define CSI '\233'
41: #define TIME_FACTOR (100000)/* convert 1/10 sec to microsecs */
42:
43: /* Amiga Console Control Sequences */
44: #define ENABLE_SCROLL ((UBYTE *) "\233>1h") /* Amiga default */
45: #define DISABLE_SCROLL ((UBYTE *) "\233>1l")
46: #define AUTOWRAP_ON ((UBYTE *) "\233?7h") /* Amiga default */
47: #define AUTOWRAP_OFF ((UBYTE *) "\233?7l")
48: #define CURSOR_ON ((UBYTE *) "\233 p") /* Amiga default */
49: #define CURSOR_OFF ((UBYTE *) "\2330 p")
50:
51: #define RAW_EVENTS_ON ((UBYTE *) "\23312{") /* Set Window Resize Reports */
52: #define RAW_EVENTS_OFF ((UBYTE *) "\23312}") /* Reset Window Resize Reports */
53:
54: /* take out for compiling with elvis */
55:
56: #ifndef ctrl
57: #define ctrl(ch) ((ch)&037)
58: #endif
59:
60: /* Variables */
61: static BPTR fh = 0, inputFH, outputFH, oldinputFH, oldoutputFH;
62: static UBYTE title[]= "RAW:0/0/999/999/Amiga Elvis 1.5/SIMPLE";
63: static int amigaterm = 0;
64:
65: /* Function prototypes for amitty.c */
66: void amiopenwin(char *termtype);
67: void amiclosewin(void);
68: void ttysetup(void);
69: void ttyshutdown(void);
70: int ttywrite(char *buf, int len);
71: int ttyread(char *buf, int len, int time);
72: int CheckforSpecial(char *buf, long len);
73: LONG setRawCon(LONG toggle);
74: LONG sendpkt(struct MsgPort *pid, LONG action, LONG args[], LONG nargs);
75:
76: /*
77: * amiopenwin - opens a window if we don't already have one.
78: */
79: void
80: amiopenwin(char *termtype)
81: {
82: if (!IsInteractive(Input()))
83: {
84: /* open our own window in RAW mode */
85: if (isOldDOS() || (BPTR) 0 == (fh = Open(title, MODE_READWRITE)))
86: {
87: PutStr((UBYTE *) "Couldn't open RAW: window");
88: clean_exit(2);
89: } else
90: {
91: oldinputFH = SelectInput(fh);
92: oldoutputFH = SelectOutput(fh);
93: }
94: }
95: inputFH = Input();
96: outputFH = Output();
97:
98: if (!strcmp(termtype, TERMTYPE))
99: {
100: amigaterm = 1;
101: Write(outputFH, AUTOWRAP_OFF, sizeof(AUTOWRAP_OFF));
102: }
103: return;
104: }
105:
106:
107: /*
108: * amiclosewin - closes a window if we opened one.
109: */
110: void
111: amiclosewin()
112: {
113: if (amigaterm)
114: {
115: Write(outputFH, AUTOWRAP_ON, sizeof(AUTOWRAP_ON)); /* Amiga default */
116: }
117: if (fh)
118: { /* Close down the window */
119: SelectInput(oldinputFH);
120: SelectOutput(oldoutputFH);
121: Close(fh);
122: }
123: return;
124: }
125:
126:
127: /*
128: * ttysetup - console initalization routine for Amiga Computers.
129: *
130: * Sets raw mode and enables resize notifications.
131: */
132: void
133: ttysetup()
134: {
135: if (isOldDOS())
136: {
137: setRawCon(DOSTRUE);
138: } else
139: {
140: SetMode(inputFH, 1); /* Enter RAW mode */
141: }
142:
143: if (amigaterm)
144: {
145: Write(outputFH, RAW_EVENTS_ON, sizeof(RAW_EVENTS_ON));
146: }
147: return;
148: }
149:
150:
151: /*
152: * ttyshutdown - console shutdown routine for Amiga Computers.
153: *
154: * Resets raw mode and disables resize notifications.
155: */
156: void
157: ttyshutdown()
158: {
159: if (amigaterm)
160: {
161: Write(outputFH, RAW_EVENTS_OFF, sizeof(RAW_EVENTS_OFF));
162: }
163: if (isOldDOS())
164: {
165: setRawCon(DOSFALSE);
166: } else
167: {
168: SetMode(inputFH, 0); /* Leave RAW mode */
169: }
170:
171: return;
172: }
173:
174:
175: /*
176: * ttywrite - amiga version of ttywrite.
177: *
178: * This version makes small writes to the console as suggested in the RKM.
179: * Also turns off the cursor to speed output to the screen.
180: */
181: int
182: ttywrite(buf, len)
183: char *buf;
184: int len;
185: {
186: int cursor_off;
187: register int bytes;
188: register UBYTE *pc = (UBYTE *) buf;
189:
190: /* See if turning off the cursor is worthwhile */
191: if (cursor_off = amigaterm && len > 2 * sizeof(CURSOR_OFF))
192: {
193: Write(outputFH, CURSOR_OFF, sizeof(CURSOR_OFF)); /* Turn Cursor OFF */
194: }
195:
196: /* The console.device doesn't like large writes */
197: for (bytes = 0; len; pc += bytes, len -= bytes)
198: {
199: bytes = Write(outputFH, pc, MIN((LONG) len, 256L));
200: }
201:
202: if (cursor_off)
203: {
204: Write(outputFH, CURSOR_ON, sizeof(CURSOR_ON)); /* Turn Cursor ON */
205: }
206: return pc - buf;
207: }
208:
209:
210: /*
211: * ttyread - amiga version of ttyread.
212: */
213: int
214: ttyread(buf, len, time)
215: char *buf; /* where to store the gotten characters */
216: int len; /* maximum number of characters to read */
217: int time; /* maximum time in 1/10 sec for reading */
218: {
219: LONG bytes = 0; /* number of bytes actually read */
220:
221: if (!time || WaitForChar(inputFH, time * TIME_FACTOR))
222: { /* Read() if time == 0 or chars waiting */
223: bytes = Read(inputFH, (UBYTE *) buf, (LONG) len);
224: bytes = CheckforSpecial(buf, bytes);
225: }
226: return bytes; /* the number of bytes read in buf */
227: }
228:
229:
230: /*
231: * CheckforSpecial - crude parser for raw console events.
232: */
233: int
234: CheckforSpecial(buf, len)
235: char *buf;
236: long len;
237: {
238: int isnewsize = 0;
239: char *pb, *peor, *pend;
240:
241: pb = buf;
242: pend = &buf[len];
243: do
244: {
245: if (CSI != *pb)
246: continue;
247:
248: if (WaitForChar(inputFH, 1))
249: {
250: pend += Read(inputFH, pend, 72);
251: }
252: if (peor = strchr((char *) pb, '|')) /* Window Resize Event */
253: { /* bug == <CSI> seq <CSI> event '|' */
254: *pb = ctrl('L'); /* force redraw */
255: isnewsize = 1;
256: memmove(pb + 1, peor + 1, pend - peor);
257: pend -= peor - pb;
258: }
259: }
260: while (*pb++);
261:
262: if (isnewsize)
263: getsize(0);
264:
265: return pend - buf;
266: }
267:
268:
269: /* INDENT OFF */
270: /* sendpkt code - A. Finkel, P. Lindsay, C. Scheppner CBM */
271:
272: LONG setRawCon(toggle)
273: LONG toggle; /* DOSTRUE (-1L) or DOSFALSE (0L) */
274: {
275: struct MsgPort *conid;
276: struct Process *me;
277: LONG myargs[8] ,nargs, res1;
278:
279: me = (struct Process *) FindTask(NULL);
280: conid = (struct MsgPort *) me->pr_ConsoleTask;
281:
282: myargs[0]= toggle;
283: nargs = 1;
284: res1 = (LONG)sendpkt(conid,ACTION_SCREEN_MODE,myargs,nargs);
285: return(res1);
286: }
287:
288:
289:
290: LONG sendpkt(pid,action,args,nargs)
291: struct MsgPort *pid; /* process indentifier ... (handlers message port ) */
292: LONG action, /* packet type ... (what you want handler to do ) */
293: args[], /* a pointer to a argument list */
294: nargs; /* number of arguments in list */
295: {
296: struct MsgPort *replyport;
297: struct StandardPacket *packet;
298:
299: LONG count, *pargs, res1;
300:
301: replyport = (struct MsgPort *) CreatePort(NULL,0);
302: if(!replyport) return((LONG)NULL);
303:
304: packet = (struct StandardPacket *)
305: AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
306: if(!packet)
307: {
308: DeletePort(replyport);
309: return((LONG)NULL);
310: }
311:
312: packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
313: packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
314: packet->sp_Pkt.dp_Port = replyport;
315: packet->sp_Pkt.dp_Type = action;
316:
317: /* copy the args into the packet */
318: pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
319: for(count=0;count < nargs;count++)
320: pargs[count]=args[count];
321:
322: PutMsg(pid,(struct Message *)packet); /* send packet */
323:
324: WaitPort(replyport);
325: GetMsg(replyport);
326:
327: res1 = packet->sp_Pkt.dp_Res1;
328:
329: FreeMem(packet,(long)sizeof(struct StandardPacket));
330: DeletePort(replyport);
331:
332: return(res1);
333: }
334:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.