Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 334 lines (280 sloc) 7.741 kb
63353867 »
2011-12-10 Import Elvis 1.8 (written by Steve Kirkendall)
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 * riesermc@mentor.cc.purdue.edu rahn@sage.cc.purdue.edu
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
Something went wrong with that request. Please try again.