/* $Revision Header *** Header built automatically - do not edit! *********** * * (C) Copyright 1991 by Peter Vorwerk * * Name .....: PCExecute.c * Created ..: Monday 05-Aug-91 11:03 * Revision .: 2 * * Date Author Comment * ========= ======== ==================== * 03-Sep-91 Peter Vorwerk Added AREXX port * 01-Sep-91 Peter Vorwerk Added Gadgets for F-keys * and some other keys * * 05-Aug-91 Peter Vorwerk Created this file! * * $Revision Header ********************************************************/ #define REVISION 2 #define VERSION 1 #include #include #include #include #include #include #include #include #include extern char *strupr(char *); UBYTE *KeyB; UBYTE *IntR; struct Syscall86 *Ptr; RPTR OldPtr; struct Library *JanusBase; struct ReqLib *ReqBase; struct RexxHostBase *RexxHostBase; struct RexxHost *rexx_host; struct Window *window; struct GadgetBlock *first_row; struct GadgetBlock *second_row; struct GadgetBlock *third_row; UBYTE tab[] = { /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 */ 0x39, 0x82, 0xa8, 0x84, 0x85, 0x86, 0x2b, 0x28, /* 28 */ 0x8a, 0x8b, 0x89, 0x8d, 0x33, 0x0c, 0x34, 0x35, /* 30 */ 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, /* 38 */ 0x09, 0x0a, 0xa7, 0x27, 0xb3, 0x0d, 0xb4, 0xb5, /* 40 */ 0x83, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* 48 */ 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* 50 */ 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* 58 */ 0x2d, 0x15, 0x2c, 0x1a, 0x2b, 0x1b, 0x87, 0x8c }; UBYTE key[] = { /* 00 */ 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, /* 10 */ 0x4b, 0x48, 0x50, 0x4d, 0x47, 0x49, 0x51, 0x4f, 0x01, 0x0f, /* 20 */ 0x45, 0x46, 0x3a, 0x52, 0x37, 0x1d, 0x2a, 0x38, 0x53, 0x0e, 0x39, 0x1c }; void PCKeyB(void) { UBYTE *ptr; UWORD *offset; /* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */ /* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar. Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts, so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die nähere Umgebung disassemblieren. */ /* Keyboard address. Please note 0x7ffff is NOT the correct address in ALL Systems. You must calculate it by contents of (JanusBase + 0x72) + 0x7e000 !! */ /* I found this by disassembling the file PCWINDOW. */ KeyB = (UBYTE *) JanusBase; KeyB += 0x72; offset = (UWORD *) KeyB; ptr = (UBYTE *) GetJanusStart(); KeyB = ptr + 0x7e000; KeyB += *offset; IntR = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */ } void PC_Cmd(char *cmd) { UBYTE wert; if (cmd == NULL || *cmd == 0) return; *KeyB = 0x1d; /* CTRL */ *IntR = 0xff; Delay(1); *KeyB = 0x38; /* ALT */ *IntR = 0xff; Delay(1); *KeyB = 0x3b; /* F1 */ *IntR = 0xff; Delay(1); *KeyB = 0xbb; /* ~F1 */ *IntR = 0xff; Delay(1); *KeyB = 0xb8; /* ~ALT */ *IntR = 0xff; Delay(1); *KeyB = 0x9d; /* ~CTRL */ *IntR = 0xff; Delay(1); while(*cmd != '\0') { wert = tab[*cmd++]; if (wert > 0x80) { wert -= 0x80; *KeyB = (UBYTE) 0x2a; *IntR = (UBYTE) 0xff; Delay(1); *KeyB = wert; *IntR = (UBYTE) 0xff; Delay(1); *KeyB = (UBYTE) 0xaa; *IntR = (UBYTE) 0xff; Delay(1); } else { *KeyB = wert; *IntR = (UBYTE) 0xff; Delay(1); } } *KeyB = 0x1d; /* CTRL */ *IntR = 0xff; Delay(1); *KeyB = 0x38; /* ALT */ *IntR = 0xff; Delay(1); *KeyB = 0x3c; /* F2 */ *IntR = 0xff; Delay(1); *KeyB = 0xbc; /* ~F2 */ *IntR = 0xff; Delay(1); *KeyB = 0xb8; /* ~ALT */ *IntR = 0xff; Delay(1); *KeyB = 0x9d; /* ~CTRL */ *IntR = 0xff; Delay(1); } char text1[10][6] = { " F1 ", " F2 ", " F3 ", " F4 ", " F5 ", " F6 ", " F7 ", " F8 ", " F9 ", " F10 " }; char text2[10][6] = { " <- ", " up ", "down ", " -> ", "Home ", "Pg Up", "Pg Dn", " End ", " ESC ", " TAB " }; char text3[10][6] = { "NumL ", "ScrL ", "CapsL", " Ins ", "PrtSc", "CTRL ", "SHIFT", " ALT ", " Del ", " BS " }; char *cmdlist[] = { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "RIGHT", "UP", "DOWN", "LEFT", "HOME", "PAGE_UP", "PAGE_DOWN", "END", "ESC", "TAB", "NUM_LOCK", "SCROLL_LOCK", "CAPS_LOCK", "INS", "PRINT_SCREEN", "CTRL", "SHIFT", "ALT", "DEL", "BACKSPACE", "SPACE", "ENTER" }; void Press(char *cmd) { int i,j; struct GadgetBlock *gadget; for(i = 0; i < 32; i++) { if (Strcmp(cmd,cmdlist[i]) == 0) { *KeyB = key[i]; *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); if (i > 30) break; else if (i > 20) { i -= 20; gadget = third_row; } else if (i >10) { i -= 10; gadget = second_row; } else gadget = first_row; while(--i >= 0) gadget++; j = RemoveGadget(window,&gadget->Gadget); gadget->Gadget.Flags |= SELECTED; AddGadget(window,&gadget->Gadget,j); RefreshGadgets(&gadget->Gadget,window,NULL); break; } } } void Release(char *cmd) { int i,j; struct GadgetBlock *gadget; for(i = 0; i < 32; i++) { if (Strcmp(cmd,cmdlist[i]) == 0) { *KeyB = key[i] + 0x80; *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); if (i > 30) break; else if (i > 20) { i -= 20; gadget = third_row; } else if (i >10) { i -= 10; gadget = second_row; } else gadget = first_row; while(--i >= 0) gadget++; j = RemoveGadget(window,&gadget->Gadget); gadget->Gadget.Flags &= ~SELECTED; AddGadget(window,&gadget->Gadget,j); RefreshGadgets(&gadget->Gadget,window,NULL); break; } } } void GetCmd(char *Buffer) { char Undobuffer[256]; register short gadgetnum,class,select; register struct IntuiMessage *message; register int i; struct GadgetBlock *ok_block; struct GadgetBlock *cancel_block; struct StringBlock *string_block; struct GadgetBlock *row; struct RexxMsg *rexxmessage; /* incoming rexx messages */ STRPTR Arg; /* Temporary string pointer */ char ArgBuff[40]; /* Temporary argument buffer */ ULONG SignalSet; /* Incoming signals. */ LONG NumResult; /* Return code. */ STRPTR StringResult; /* Result string (error message). */ struct NewWindow nw = { 0,0, /* LeftEdge, TopEdge */ 640,90, /* Width, Height */ -1,-1, /* DetailPen, BlockPen */ GADGETUP | CLOSEWINDOW, /* IDCMPFlags */ SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE, /* Flags */ NULL, /* FirstGadget */ NULL, /* CheckMark */ (UBYTE *) "Enter your PC command", /* Title */ NULL, /* Screen */ NULL, /* BitMap */ 0,0, /* MinWidth, MinHeight */ 0,0, /* MaxWidth, MaxHeight */ WBENCHSCREEN /* Type (of screen) */ }; if ((ok_block = AllocMem(sizeof(struct GadgetBlock),MEMF_CLEAR)) == NULL) return; if ((cancel_block = AllocMem(sizeof(struct GadgetBlock),MEMF_CLEAR)) == NULL) return; if ((string_block = AllocMem(sizeof(struct StringBlock),MEMF_CLEAR)) == NULL) return; if ((first_row = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL) return; if ((second_row = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL) return; if ((third_row = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL) return; LinkGadget(ok_block, "Ok", &nw, 12, 75); LinkGadget(cancel_block, "Cancel", &nw, 628, 75); LinkStringGadget(string_block, Buffer, Undobuffer, &nw, 616, 255, 12, 60); ok_block ->Gadget.GadgetID = 1; cancel_block->Gadget.GadgetID = 2; string_block->Gadget.GadgetID = 3; cancel_block->Gadget.LeftEdge -= cancel_block->Gadget.Width; row = first_row; for(i = 0; i < 10; i++) { LinkGadget(row, text1[i], &nw, 12+i*64, 15); row->Gadget.Activation |= TOGGLESELECT; row->Gadget.GadgetID = i+4; row++; } row = second_row; for(i = 0; i < 10; i++) { LinkGadget(row, text2[i], &nw, 12+i*64, 30); row->Gadget.Activation |= TOGGLESELECT; row->Gadget.GadgetID = i+14; row++; } row = third_row; for(i = 0; i < 10; i++) { LinkGadget(row, text3[i], &nw, 12+i*64, 45); row->Gadget.Activation |= TOGGLESELECT; if (i == 0 && (Ptr->s86_AX & 0x20)) row->Gadget.Flags |= SELECTED; if (i == 1 && (Ptr->s86_AX & 0x10)) row->Gadget.Flags |= SELECTED; if (i == 2 && (Ptr->s86_AX & 0x40)) row->Gadget.Flags |= SELECTED; if (i == 3 && (Ptr->s86_AX & 0x80)) row->Gadget.Flags |= SELECTED; row->Gadget.GadgetID = i+24; row++; } Center(&nw, nw.Width - (cancel_block->Gadget.Width >> 1) - 12, 75 + (cancel_block->Gadget.Height >> 1)); if (!(window = (struct Window *) OpenWindow(&nw))) return; ActivateGadget(&string_block->Gadget,window,NULL); do { SignalSet = Wait(1L << window->UserPort->mp_SigBit | HOSTMASK(rexx_host)); if (SignalSet & (1L << window->UserPort->mp_SigBit)) { message = (struct IntuiMessage *) GetMsg(window->UserPort); gadgetnum = ((struct Gadget *) (message->IAddress))->GadgetID; select = ((struct Gadget *) (message->IAddress))->Flags; class = message->Class; ReplyMsg((struct Message *)message); } if (class != CLOSEWINDOW && gadgetnum != 2) { OldPtr = SetParamOffset(JSERV_PCCALL,JanusMemToOffset(Ptr)); Ptr->s86_AX = 0x0200; Ptr->s86_INT = 0x16; SendJanusInt(JSERV_PCCALL); Delay(10); SetParamOffset(JSERV_PCCALL,OldPtr); } /* did we get something from rexx? */ if (RexxHostBase) { while(rexxmessage = GetRexxMsg(rexx_host,FALSE)) { /* Getting a string pointer means * that we've received a command. */ StringResult = NULL; NumResult = 0; if(Arg = GetRexxCommand(rexxmessage)) { LONG CharCount = 0; /* Need counter, function reentrant. */ /* Now split the command string into arguments. */ GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40); if (Strcmp(ArgBuff,"COMMAND") == 0) { while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40)) { PC_Cmd(strupr(ArgBuff)); Delay(1); *KeyB = (UBYTE) 0x39; /* SPACE */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); } *KeyB = (UBYTE) 0x1c; /* ENTER */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ } else if (Strcmp(ArgBuff,"KEY") == 0) { char dummy[1024]; strcpy(dummy,(char *) Arg); while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40)) Press((char *) ArgBuff); CharCount = 0; GetToken((STRPTR) dummy,&CharCount,(STRPTR) ArgBuff,40); while(GetToken((STRPTR) dummy,&CharCount,(STRPTR) ArgBuff,40)) Release((char *) ArgBuff); } else if (Strcmp(ArgBuff,"PRESS") == 0) { while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40)) Press((char *) ArgBuff); } else if (Strcmp(ArgBuff,"RELEASE") == 0) { while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40)) Release((char *) ArgBuff); } else { char dummy[80]; NumResult = 10; SPrintf(dummy,"ERROR: Command \"%s\" is not supported in this version", ArgBuff); StringResult = (STRPTR) dummy; } } /* Reply the rexx command. */ ReplyRexxCommand(rexxmessage,NumResult,0,StringResult); } } if (gadgetnum >= 4 && gadgetnum <= 34) { if (select & SELECTED) { *KeyB = key[gadgetnum-4]; *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); } else { if (gadgetnum != 26) *KeyB = key[gadgetnum-4] + 0x80; else *KeyB = key[gadgetnum-4]; /* Caps Lock is a (hardware) switch key. So this key must be pressed to send the release code! */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); } } if (gadgetnum == 1 || gadgetnum == 3) { int j; PC_Cmd(strupr(Buffer)); *KeyB = (UBYTE) 0x1c; /* ENTER */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); j = RemoveGadget(window,&string_block->Gadget); *Buffer = 0; AddGadget(window,&string_block->Gadget,j); RefreshGadgets(&string_block->Gadget,window,NULL); ActivateGadget(&string_block->Gadget,window,NULL); } } while((gadgetnum != 2) && (class != CLOSEWINDOW)); CloseWindow(window); FreeMem(ok_block, sizeof(struct GadgetBlock)); FreeMem(cancel_block,sizeof(struct GadgetBlock)); FreeMem(string_block,sizeof(struct StringBlock)); FreeMem(first_row, sizeof(struct GadgetBlock) *10); FreeMem(second_row, sizeof(struct GadgetBlock) *10); FreeMem(third_row, sizeof(struct GadgetBlock) *10); } void main(int argc, char *argv[]) { int i; char buf[256] = 0; if (!(JanusBase = ArpOpenLibrary("janus.library",0L))) { Puts("ERROR: Can't find Janus.library"); exit(10); } if (!(ReqBase = (struct ReqLib *) ArpOpenLibrary("req.library",0L))) { Puts("ERROR: Can't find Req.library"); exit(10); } if (!(RexxHostBase = (struct RexxHostBase *) ArpOpenLibrary(REXXHOSTNAME,REXXHOSTMINIMUM))) { Puts("Sorry, couldn't open rexxhost library."); } if (RexxHostBase) { if (!(rexx_host = CreateRexxHost((STRPTR)"PC_EX"))) { Puts("Sorry, couldn't set up our public rexx port"); } } if (RexxHostBase == NULL | rexx_host == NULL) { Puts("\nSo you can't use the AREXX port.\n"); } if ((Ptr = (struct Syscall86 *) AllocJanusMem(sizeof(struct Syscall86), MEMF_PARAMETER | MEM_WORDACCESS)) != NULL) { OldPtr = SetParamOffset(JSERV_PCCALL,JanusMemToOffset(Ptr)); Ptr->s86_AX = 0x0200; Ptr->s86_INT = 0x16; SendJanusInt(JSERV_PCCALL); Delay(10); SetParamOffset(JSERV_PCCALL,OldPtr); } else { Puts("ERROR: No Janus mem free."); if (rexx_host) rexx_host = DeleteRexxHost(rexx_host); exit(10); } PCKeyB(); Printf("%s V%ld.%ld by Peter Vorwerk\tPUBLIC DOMAIN\n", BaseName(argv[0]),VERSION,REVISION); if (argc < 2) { GetCmd(buf); FreeJanusMem(Ptr,sizeof(struct Syscall86)); if (rexx_host) rexx_host = DeleteRexxHost(rexx_host); exit(0); } for(i = 1; i < argc; i++) { PC_Cmd(strupr(argv[i])); /* Only upper case letters and digits are allowed */ Delay(1); *KeyB = (UBYTE) 0x39; /* SPACE */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ Delay(1); } *KeyB = (UBYTE) 0x1c; /* ENTER */ *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */ FreeJanusMem(Ptr,sizeof(struct Syscall86)); if (rexx_host) rexx_host = DeleteRexxHost(rexx_host); exit(0); }