home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d509 / pckeymap.lha / PCKeyMap / PCKeyMap.c < prev    next >
C/C++ Source or Header  |  1991-06-29  |  18KB  |  582 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *      (C) Copyright 1991 by Peter Vorwerk
  4.  *
  5.  *      Name .....: PCKeyMap.c
  6.  *      Created ..: Saturday 16-Mar-91 10:39
  7.  *      Revision .: 0
  8.  *
  9.  *      Date            Author          Comment
  10.  *      =========       ========        ====================
  11.  *      16-Mar-91       Peter Vorwerk   Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  #define REVISION 0
  15.  
  16. #define VERSION 1
  17.  
  18. #include <stdio.h>
  19. #include <functions.h>
  20. #include <exec/execbase.h>
  21. #include <exec/tasks.h>
  22. #include <exec/types.h>
  23. #include <exec/memory.h>
  24. #include <exec/ports.h>
  25. #include <exec/devices.h>
  26. #include <exec/io.h>
  27. #include <exec/libraries.h>
  28. #include <exec/interrupts.h>
  29. #include <exec/nodes.h>
  30. #include <devices/input.h>
  31. #include <devices/inputevent.h>
  32. #include <intuition/intuitionbase.h>
  33. #include <intuition/intuition.h>
  34. #include <libraries/arpbase.h>
  35. #include <janus/janus.h>
  36.  
  37. void Input_Code(void); /* Predefine the ASM-Handler */
  38.  
  39. struct MsgPort    *IPort = NULL;
  40. struct IOStdReq   *InputRequest = NULL;
  41. struct Interrupt  Input_Handler;
  42. struct Task       *MyTask;
  43.  
  44. ULONG User_Routine;
  45. ULONG Qualifier , Code , MySignal, data , SigNum = 0L;
  46.  
  47. /* These codes are PC RawCodes.
  48.  
  49.    PC_ALT   means press the ALT key
  50.    PC_nALT  means release the ALT key
  51.    
  52.    PC_x     means press the x key of the numeric block */
  53.  
  54. /* Remember, you MUST press and relase control keys as CTRL, ALT
  55.    or SHIFT, while normal keys need only be pressed. */
  56.  
  57. #define PC_ALT    (UBYTE) '\070'
  58. #define PC_nALT   (UBYTE) '\270'
  59. #define PC_0      (UBYTE) '\122'
  60. #define PC_1      (UBYTE) '\117'
  61. #define PC_2      (UBYTE) '\120'
  62. #define PC_3      (UBYTE) '\121'
  63. #define PC_4      (UBYTE) '\113'
  64. #define PC_5      (UBYTE) '\114'
  65. #define PC_6      (UBYTE) '\115'
  66. #define PC_7      (UBYTE) '\107'
  67. #define PC_8      (UBYTE) '\110'
  68. #define PC_9      (UBYTE) '\111'
  69.  
  70. struct IntuitionBase *IntuitionBase;
  71. struct Library       *JanusBase   = NULL;
  72. UBYTE                *KeyB        = NULL;
  73. UBYTE                *IntR        = NULL;
  74.  
  75. /******************************
  76. *                             *
  77. *         PCKeyB()            *
  78. *                             *
  79. ******************************/
  80.  
  81. /* Calculate the address of the keyboard-register (KeyB) and
  82.    the keyboard-interrupt (IntR) of the XT/AT board. By writing
  83.    a value in the KeyB and sending the interrupt, the XT/AT will
  84.    assume we have pressed or released this key on the keyboard. */
  85.  
  86. void PCKeyB(void)
  87. {
  88.     UBYTE *ptr;
  89.     UWORD *offset;
  90.  
  91. /* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */
  92. /* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse
  93.    genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar.
  94.  
  95.    Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm
  96.    PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts,
  97.    so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die
  98.    nähere Umgebung disassemblieren. */
  99.  
  100. /* Keyboard address. Please note 0x7ffff is NOT the correct address in ALL Systems.
  101.    You must calculate it by contents of (JanusBase + 0x72) + 0x7e000 !! */
  102.  
  103. /* I found this by disassembling the file PCWINDOW. */
  104.  
  105.     KeyB    = (UBYTE *) JanusBase;
  106.     KeyB    += 0x72;
  107.     offset  = (UWORD *) KeyB;
  108.     ptr     = (UBYTE *) GetJanusStart();
  109.     KeyB    = ptr + 0x7e000;
  110.     KeyB    += *offset;
  111.     IntR    = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */
  112. }
  113.  
  114. /*******************************
  115. *                              *
  116. *        Handler()             *
  117. *                              *
  118. *******************************/
  119.  
  120. /* This is the C-code of my handler. This function will 
  121.    test, if a key has been pressed or released. If so this
  122.    function test, if the actual window title start with the
  123.    sequence " PC ". If this is true also, send a signal to
  124.    the main process. The main process will determine which
  125.    action should be done. */
  126.  
  127. struct InputEvent *Handler(struct InputEvent *Input, ULONG *Data)
  128. {
  129.     char *s;
  130.     struct InputEvent *Next;
  131.     
  132.     Next = Input;
  133.     while(Next)
  134.     {
  135. /* Is the Event produced of the keyboard ? */
  136.  
  137.         if (Next->ie_Class == IECLASS_RAWKEY)
  138.         {
  139. /* Starts the actual window with the sequence " PC " ? */
  140.  
  141.             s = (char *) IntuitionBase->ActiveWindow->Title;
  142.             if (strncmp(" PC ",s,4) == 0)
  143.             {
  144. /* Save the Code and the Qualifier of the last Event ... */
  145.  
  146.                 Qualifier = Next->ie_Qualifier;
  147.                 Code = Next->ie_Code;
  148. /* ... and send a signal to the main process. */
  149.  
  150.                 Signal(MyTask,MySignal);
  151.             }
  152.         }
  153. /* Search for the next Event. */
  154.  
  155.         Next = Next->ie_NextEvent;
  156.     }
  157. /* Return the Event to the System, so that the other handlers
  158.    can use it too. */
  159.  
  160.     return(Input);
  161. }
  162.  
  163. /***********************
  164. *                      *
  165. *   InitHandler()      *
  166. *                      *
  167. ***********************/
  168.  
  169. /* Start the Handler. */
  170.  
  171. void InitHandler(void)
  172. {
  173.     data = 0L;
  174.     
  175.     User_Routine                  = (ULONG) Handler;
  176.     Input_Handler.is_Data         = (APTR) &data;
  177.     Input_Handler.is_Code         = (void (*)())Input_Code;
  178.     Input_Handler.is_Node.ln_Pri  = 51;
  179.     Input_Handler.is_Node.ln_Name = "PCKeyMap-Handler";
  180.     InputRequest->io_Data         = (APTR) &Input_Handler;
  181.     InputRequest->io_Command      = IND_ADDHANDLER;
  182.     
  183.     DoIO((struct IORequest *) InputRequest);
  184. }
  185.  
  186. /**********************
  187. *                     *
  188. *    Input_Code()     *
  189. *                     *
  190. **********************/
  191.  
  192. /* This is the assembler routine of the handler. We need it,
  193.    because the system will send the parameter in a register.
  194.    But a C-funtion search for the parameter on the stack. */
  195.  
  196. #asm
  197.     public _geta4
  198.     public _Input_Code
  199. _Input_Code:
  200.     move.l   a4,-(sp)
  201.     jsr      _geta4
  202.     movem.l  a0/a1,-(sp)
  203.     move.l   _User_Routine,a0
  204.     jsr      (a0)
  205.     movem.l  (sp)+,a0/a1
  206.     move.l   (sp)+,a4
  207.     rts
  208. #endasm
  209.  
  210. /********************
  211. *                   *
  212. *    CloseAll()     *
  213. *                   *
  214. ********************/
  215.  
  216. /* Normaly this function is not called. Only if an error
  217.    occurs during the setup this function will be called.
  218.    
  219.    Try to close all open stuff. */
  220.  
  221. void CloseAll(void)
  222. {
  223.     if (SigNum)
  224.     {
  225.         FreeSignal(SigNum);
  226.     }
  227.     if (InputRequest->io_Device)
  228.     {
  229.         CloseDevice((struct IORequest *) InputRequest);
  230.     }
  231.     if (InputRequest)
  232.     {
  233.         DeleteStdIO(InputRequest);
  234.     }
  235.     if (IPort)
  236.     {
  237.         DeletePort(IPort);
  238.     }
  239.     exit(10);
  240. }
  241.  
  242. /************************
  243. *                       *
  244. *     OpenAll()         *
  245. *                       *
  246. ************************/
  247.  
  248. /* Open the libraries and the ports. */
  249.  
  250. void OpenAll(void)
  251. {
  252.     if (!(JanusBase = ArpOpenLibrary("janus.library",0L)))
  253.     {
  254.         Printf("\nCan't find JANUS.library\nAborted...\n");
  255.         exit(10);
  256.     }
  257.     if (!(IPort = CreatePort(NULL,0L)))
  258.     {
  259.         CloseAll();
  260.     }
  261.     if (!(InputRequest = CreateStdIO(IPort)))
  262.     {
  263.         CloseAll();
  264.     }
  265.     if (OpenDevice("input.device",0L,(struct IORequest *) InputRequest,0L))
  266.     {
  267.         CloseAll();
  268.     }
  269. /* Get a signal for our own Task */
  270.  
  271.     if ((SigNum = AllocSignal(-1L)) < 0)
  272.     {
  273.         CloseAll();
  274.     }
  275.  
  276.     MySignal = 1 << SigNum;
  277.  
  278. /* Now start the Handler. */
  279.  
  280.     InitHandler();
  281. }    
  282.  
  283. /********************
  284. *                   *
  285. *    SendKey()      *
  286. *                   *
  287. ********************/
  288.  
  289. /* This function will send the values to the keyboard-register and
  290.    send the interrupt. */
  291.  
  292. void SendKey(UBYTE k1, UBYTE k2, UBYTE k3)
  293. {
  294.     *KeyB   = PC_ALT;
  295.     *IntR   = '\377';    /* 0xff */
  296.     Delay(1);
  297.     *KeyB   = k1;
  298.     *IntR   = '\377';    /* 0xff */
  299.     Delay(1);
  300.     *KeyB   = k2;
  301.     *IntR   = '\377';    /* 0xff */
  302.     Delay(1);
  303.     *KeyB   = k3;
  304.     *IntR   = '\377';    /* 0xff */
  305.     Delay(1);
  306.     *KeyB   = PC_nALT;
  307.     *IntR   = '\377';    /* 0xff */
  308.     Delay(1);
  309. }
  310.  
  311. /********************
  312. *                   *
  313. *    CheckKey()     *
  314. *                   *
  315. ********************/
  316.  
  317. /* Check which key has been pressed. */
  318.  
  319. void CheckKey(void)
  320. {
  321.     switch(Code)
  322.     {
  323.         case 0x00: if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  324.                    {
  325.                        SendKey(PC_1,PC_2,PC_6);
  326.                    }
  327.                    else
  328.                    {
  329.                        SendKey(PC_0,PC_9,PC_6);
  330.                    }
  331.                    break;
  332.                    
  333.         case 0x01: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  334.                    {
  335.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  336.                        {
  337.                            SendKey(PC_1,PC_7,PC_3);
  338.                        }
  339.                        else
  340.                        {
  341.                            SendKey(PC_0,PC_4,PC_9);
  342.                        }
  343.                    }
  344.                    break;
  345.                    
  346.         case 0x02: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  347.                    {
  348.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  349.                        {
  350.                            SendKey(PC_0,PC_6,PC_4);
  351.                        }
  352.                        else
  353.                        {
  354.                            SendKey(PC_0,PC_5,PC_0);
  355.                        }
  356.                    }
  357.                    break;
  358.                    
  359.         case 0x03: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  360.                    {
  361.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  362.                        {
  363.                            SendKey(PC_0,PC_3,PC_5);
  364.                        }
  365.                        else
  366.                        {
  367.                            SendKey(PC_0,PC_5,PC_1);
  368.                        }
  369.                    }
  370.                    break;
  371.                    
  372.         case 0x04: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  373.                    {
  374.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  375.                        {
  376.                            SendKey(PC_0,PC_3,PC_6);
  377.                        }
  378.                        else
  379.                        {
  380.                            SendKey(PC_0,PC_5,PC_2);
  381.                        }
  382.                    }
  383.                    break;
  384.                    
  385.         case 0x05: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  386.                    {
  387.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  388.                        {
  389.                            SendKey(PC_0,PC_3,PC_7);
  390.                        }
  391.                        else
  392.                        {
  393.                            SendKey(PC_0,PC_5,PC_3);
  394.                        }
  395.                    }
  396.                    break;
  397.                    
  398.         case 0x06: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  399.                    {
  400.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  401.                        {
  402.                            SendKey(PC_0,PC_9,PC_4);
  403.                        }
  404.                        else
  405.                        {
  406.                            SendKey(PC_0,PC_5,PC_4);
  407.                        }
  408.                    }
  409.                    break;
  410.                    
  411.         case 0x07: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  412.                    {
  413.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  414.                        {
  415.                            SendKey(PC_0,PC_3,PC_8);
  416.                        }
  417.                        else
  418.                        {
  419.                            SendKey(PC_0,PC_5,PC_5);
  420.                        }
  421.                    }
  422.                    break;
  423.                    
  424.         case 0x08: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  425.                    {
  426.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  427.                        {
  428.                            SendKey(PC_0,PC_4,PC_2);
  429.                        }
  430.                        else
  431.                        {
  432.                            SendKey(PC_0,PC_5,PC_6);
  433.                        }
  434.                    }
  435.                    break;
  436.                    
  437.         case 0x09: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  438.                    {
  439.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  440.                        {
  441.                            SendKey(PC_0,PC_4,PC_0);
  442.                        }
  443.                        else
  444.                        {
  445.                            SendKey(PC_0,PC_5,PC_7);
  446.                        }
  447.                    }
  448.                    break;
  449.                    
  450.         case 0x0a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  451.                    {
  452.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  453.                        {
  454.                            SendKey(PC_0,PC_4,PC_1);
  455.                        }
  456.                        else
  457.                        {
  458.                            SendKey(PC_0,PC_4,PC_8);
  459.                        }
  460.                    }
  461.                    break;
  462.                    
  463.         case 0x0b: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  464.                    {
  465.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  466.                        {
  467.                            SendKey(PC_0,PC_9,PC_5);
  468.                        }
  469.                        else
  470.                        {
  471.                            SendKey(PC_0,PC_4,PC_5);
  472.                        }
  473.                    }
  474.                    break;
  475.                    
  476.         case 0x0c: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  477.                    {
  478.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  479.                        {
  480.                            SendKey(PC_0,PC_4,PC_3);
  481.                        }
  482.                        else
  483.                        {
  484.                            SendKey(PC_0,PC_6,PC_1);
  485.                        }
  486.                    }
  487.                    break;
  488.                    
  489.         case 0x0d: if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  490.                    {
  491.                        SendKey(PC_1,PC_2,PC_4);
  492.                    }
  493.                    else
  494.                    {
  495.                        SendKey(PC_0,PC_9,PC_2);
  496.                    }
  497.                    break;
  498.                    
  499.         case 0x1a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  500.                    {
  501.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  502.                        {
  503.                            SendKey(PC_1,PC_2,PC_3);
  504.                        }
  505.                        else
  506.                        {
  507.                            SendKey(PC_0,PC_9,PC_1);
  508.                        }
  509.                    }
  510.                    break;
  511.                    
  512.         case 0x1b: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  513.                    {
  514.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  515.                        {
  516.                            SendKey(PC_1,PC_2,PC_5);
  517.                        }
  518.                        else
  519.                        {
  520.                            SendKey(PC_0,PC_9,PC_3);
  521.                        }
  522.                    }
  523.                    break;
  524.                    
  525.         case 0x29: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  526.                    {
  527.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  528.                        {
  529.                            SendKey(PC_0,PC_5,PC_8);
  530.                        }
  531.                        else
  532.                        {
  533.                            SendKey(PC_0,PC_5,PC_9);
  534.                        }
  535.                    }
  536.                    break;
  537.                    
  538.         case 0x2a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
  539.                    {
  540.                        if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
  541.                        {
  542.                            SendKey(PC_0,PC_3,PC_4);
  543.                        }
  544.                        else
  545.                        {
  546.                            SendKey(PC_0,PC_3,PC_9);
  547.                        }
  548.                    }
  549.                    break;
  550.     }
  551. }
  552.  
  553.  
  554. int main(int argc, char *argv[])
  555. {
  556.     if (MyTask = FindTask("PCKeyMap-Handler"))
  557.     {
  558.         Printf("PCKeyMap is already installed !\n");
  559.         exit(5);
  560.     }
  561.     if (!(MyTask = FindTask(NULL)))
  562.     {
  563.         CloseAll();
  564.     }
  565.     MyTask->tc_Node.ln_Name = "PCKeyMap-Handler";
  566. /* Set own process name, so we can determine if the program is already in memory. */
  567.  
  568.     OpenAll();
  569.     Printf("Installing PCKeyMap V%ld.%ld by Peter Vorwerk\tPUBLIC DOMAIN\n",VERSION,REVISION);    
  570.  
  571.     PCKeyB(); /* Calculate the KeyBoardAddress. */
  572.  
  573. /* Do forever ... */
  574.     for(;;)
  575.     {
  576.         Wait(MySignal);
  577.         CheckKey();
  578.     }
  579. /* We will never reach this statement, but my Compiler needs it. */
  580.     return(0);
  581. }
  582.