|
|
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.