home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / keyboard / keymacro_436 / keysupport.c < prev    next >
Text File  |  1991-01-15  |  7KB  |  321 lines

  1. /****************************************************************************
  2. *
  3. *    KeySupport.c ----------    Keymacro support routines.
  4. *
  5. *    Author ----------------    Olaf Barthel, MXM
  6. *                Brabeckstrasse 35
  7. *                D-3000 Hannover 71
  8. *
  9. *    KeyMacro  ©  Copyright  1990  by  MXM;  Executable  program,
  10. *    documentation  and  source  code are shareware.  If you like
  11. *    this  program  a  small donation will entitle you to receive
  12. *    updates and new programs from MXM.
  13. *
  14. ****************************************************************************/
  15.  
  16.     /* AllocRem():
  17.      *
  18.      *    Allocate public memory and keep track of its size.
  19.      */
  20.  
  21. VOID *
  22. AllocRem(LONG ByteSize,LONG Requirements)
  23. {
  24.     LONG    *MemoryBlock = NULL;
  25.     LONG     RemSize = ByteSize + sizeof(LONG);
  26.  
  27.     if(ByteSize > 0)
  28.         MemoryBlock = (LONG *)AllocMem(RemSize,Requirements);
  29.  
  30.     if(MemoryBlock)
  31.         *MemoryBlock++ = RemSize;
  32.  
  33.     return((VOID *)MemoryBlock);
  34. }
  35.  
  36.     /* FreeRem():
  37.      *
  38.      *    Free a tracked portion of memory.
  39.      */
  40.  
  41. VOID *
  42. FreeRem(LONG *MemoryBlock)
  43. {
  44.     if(MemoryBlock--)
  45.         FreeMem(MemoryBlock,*MemoryBlock);
  46.  
  47.     return(NULL);
  48. }
  49.  
  50.     /* SendMacroMsg(scm_Msg,scm_Port):
  51.      *
  52.      *    Post a cloned macro message to a MsgPort.
  53.      */
  54.  
  55. VOID *
  56. SendMacroMsg(struct MacroMessage *scm_Msg,struct MsgPort *scm_Port)
  57. {
  58.     struct MacroMessage *scm_TempMsg;
  59.  
  60.     if(scm_TempMsg = (struct MacroMessage *)AllocRem(sizeof(struct MacroMessage),MEMF_PUBLIC | MEMF_CLEAR))
  61.     {
  62.         CopyMem(scm_Msg,scm_TempMsg,sizeof(struct MacroMessage));
  63.  
  64.         scm_TempMsg -> mm_Message . mn_Node . ln_Name    = (char *)scm_TempMsg;
  65.         scm_TempMsg -> mm_Message . mn_ReplyPort    = NULL;
  66.         scm_TempMsg -> mm_Message . mn_Length        = sizeof(struct MacroMessage);
  67.  
  68.         PutMsg(scm_Port,(struct Message *)scm_TempMsg);
  69.     }
  70.  
  71.     return((VOID *)scm_TempMsg);
  72. }
  73.  
  74.     /* PackQualifiers():
  75.      *
  76.      *    Pack a couple of qualifiers indicated by a keymap
  77.      *    qualifier tag (sortof).
  78.      */
  79.  
  80. STATIC UWORD
  81. PackQualifiers(BYTE Bits)
  82. {
  83.     UWORD Qualifier = 0;
  84.  
  85.     if(Bits & KCF_SHIFT)
  86.         Qualifier |= IEQUALIFIER_LSHIFT;
  87.  
  88.     if(Bits & KCF_ALT)
  89.         Qualifier |= IEQUALIFIER_LALT;
  90.  
  91.     if(Bits & KCF_CONTROL)
  92.         Qualifier |= IEQUALIFIER_CONTROL;
  93.  
  94.     return(Qualifier);
  95. }
  96.  
  97.     /* ScanKeyMap():
  98.      *
  99.      *    Scan a given part of the keymap area and handle the
  100.      *    necessary Ansi<->InputEvent conversion.
  101.      */
  102.  
  103. BYTE
  104. ScanKeyMap(UBYTE Hi,UBYTE Offset,UBYTE *KeyTable,UBYTE *KeyTypes,UBYTE AnsiKey,struct InputEvent *Event)
  105. {
  106.         /* This table contains the qualifiers associated with
  107.          * the various KeyType flag bits.
  108.          */
  109.  
  110.     STATIC struct {
  111.         UBYTE    QualBits;
  112.         UWORD    Qualifiers[4];
  113.     } QualType[8] = {
  114.         KC_NOQUAL,        0,                    0,            0,            0,
  115.         KCF_SHIFT,        0,                    0,            IEQUALIFIER_LSHIFT,    0,
  116.         KCF_ALT,        0,                    0,            IEQUALIFIER_LALT,    0,
  117.         KCF_CONTROL,        0,                    0,            IEQUALIFIER_CONTROL,    0,
  118.         KCF_ALT|KCF_SHIFT,    IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT,    IEQUALIFIER_LALT,    IEQUALIFIER_LSHIFT,    0,
  119.         KCF_CONTROL|KCF_ALT,    IEQUALIFIER_CONTROL|IEQUALIFIER_LALT,    IEQUALIFIER_CONTROL,    IEQUALIFIER_LALT,    0,
  120.         KCF_CONTROL|KCF_SHIFT,    IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,    IEQUALIFIER_CONTROL,    IEQUALIFIER_LSHIFT,    0,
  121.         KC_VANILLA,        IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT,    IEQUALIFIER_LALT,    IEQUALIFIER_LSHIFT,    0
  122.     };
  123.  
  124.     BYTE    *String;
  125.     SHORT     i,j,k;
  126.  
  127.         /* Scan the area. */
  128.  
  129.     for(i = 0 ; i < Hi ; i++)
  130.     {
  131.             /* This one's a dead key or dead-key-modifiable. */
  132.  
  133.         if(KeyTypes[i] & KCF_DEAD)
  134.         {
  135.             String = (BYTE *)(((ULONG *)KeyTable)[i]);
  136.  
  137.                 /* There a eight two-byte-pairs. The first
  138.                  * byte indicates the type of the dead
  139.                  * key.
  140.                  */
  141.  
  142.             for(j = 0 ; j < 8 ; j++)
  143.             {
  144.                 switch(String[2 * j])
  145.                 {
  146.                         /* Vanilla key. */
  147.  
  148.                     case 0:        if((UBYTE)String[2 * j + 1] == AnsiKey)
  149.                             {
  150.                                 Event -> ie_Qualifier    = PackQualifiers(j);
  151.                                 Event -> ie_Code    = Offset + i;
  152.  
  153.                                 return(TRUE);
  154.                             }
  155.  
  156.                             break;
  157.  
  158.                         /* Dead key modifiable, let's hope
  159.                          * that the first character in
  160.                          * the table indicates our ansi key.
  161.                          */
  162.  
  163.                     case DPF_MOD:    if((UBYTE)String[String[2 * j + 1]] == AnsiKey)
  164.                             {
  165.                                 Event -> ie_Qualifier    = PackQualifiers(j);
  166.                                 Event -> ie_Code    = Offset + i;
  167.  
  168.                                 return(TRUE);
  169.                             }
  170.  
  171.                             break;
  172.  
  173.                         /* Ignore the rest. */
  174.  
  175.                     default:    break;
  176.                 }
  177.             }
  178.         }
  179.  
  180.             /* Is a string mapped to this key? */
  181.  
  182.         if(KeyTypes[i] & KCF_STRING)
  183.         {
  184.             String = (BYTE *)(((ULONG *)KeyTable)[i]);
  185.  
  186.                 /* We need only 1 character strings. */
  187.  
  188.             if(String[0] == 1)
  189.             {
  190.                 if((UBYTE)String[String[1]] == AnsiKey)
  191.                 {
  192.                     for(k = 0 ; k < 8 ; k++)
  193.                     {
  194.                         if(QualType[k] . QualBits == (KeyTypes[i] & KC_VANILLA))
  195.                         {
  196.                             Event -> ie_Qualifier    = QualType[k] . Qualifiers[j];
  197.                             Event -> ie_Code    = Offset + i;
  198.  
  199.                             return(TRUE);
  200.                         }
  201.                     }
  202.                 }
  203.             }
  204.  
  205.                 /* Find the approriate qualifier. */
  206.  
  207.             for(j = 0 ; j < 3 ; j++)
  208.             {
  209.                 if(KeyTypes[i] & (1 << j))
  210.                 {
  211.                     if(String[2 + (2 * j)] == 1)
  212.                     {
  213.                         if((UBYTE)String[String[3 + (2 * j)]] == AnsiKey)
  214.                         {
  215.                             for(k = 0 ; k < 8 ; k++)
  216.                             {
  217.                                 if(QualType[k] . QualBits == (KeyTypes[i] & KC_VANILLA))
  218.                                 {
  219.                                     Event -> ie_Qualifier    = QualType[k] . Qualifiers[j];
  220.                                     Event -> ie_Code    = Offset + i;
  221.  
  222.                                     return(TRUE);
  223.                                 }
  224.                             }
  225.                         }
  226.                     }
  227.                 }
  228.             }
  229.         }
  230.         else
  231.         {
  232.                 /* It's a fair vanilla key. */
  233.  
  234.             for(j = 0 ; j < 4 ; j++)
  235.             {
  236.                 if(AnsiKey == KeyTable[4 * i + j])
  237.                 {
  238.                     for(k = 0 ; k < 8 ; k++)
  239.                     {
  240.                         if(QualType[k] . QualBits == KeyTypes[i])
  241.                         {
  242.                             Event -> ie_Qualifier    = QualType[k] . Qualifiers[j];
  243.                             Event -> ie_Code    = Offset + i;
  244.  
  245.                             return(TRUE);
  246.                         }
  247.                     }
  248.                 }
  249.             }
  250.         }
  251.     }
  252.  
  253.     return(FALSE);
  254. }
  255.  
  256. STATIC VOID
  257. PutKey(struct InputEvent *Event,UBYTE RawKey)
  258. {
  259.     Event -> ie_Qualifier    = 0;
  260.     Event -> ie_Code    = RawKey;
  261. }
  262.  
  263.     /* KeyInvert():
  264.      *
  265.      *    Find the qualifier & code which generate the Ansi
  266.      *    character passed to this routine.
  267.      */
  268.  
  269. BYTE
  270. KeyInvert(UBYTE AnsiKey,struct InputEvent *Event,struct KeyMap *KeyMap)
  271. {
  272.         /* Careful: if this is actually a control character
  273.          *          (return, escape, etc.) we will check the
  274.          *          high keymap table first, else the low
  275.          *          keymap table.
  276.          */
  277.  
  278.     switch(AnsiKey)
  279.     {
  280.         case ' ':    PutKey(Event,0x40);
  281.                 return(TRUE);
  282.  
  283.         case '\b':    PutKey(Event,0x41);
  284.                 return(TRUE);
  285.  
  286.         case '\t':    PutKey(Event,0x42);
  287.                 return(TRUE);
  288.  
  289.         case '\n':
  290.         case '\r':    PutKey(Event,0x44);
  291.                 return(TRUE);
  292.  
  293.         case '\33':    PutKey(Event,0x45);
  294.                 return(TRUE);
  295.  
  296.         case '\177':    PutKey(Event,0x46);
  297.                 return(TRUE);
  298. /*
  299.         This does - strange enough - not work correctly. Can you
  300.         discover why?
  301.  
  302.         case ' ':
  303.         case '\b':
  304.         case '\t':
  305.         case '\n':
  306.         case '\r':
  307.         case '\33':
  308.         case '\177':    if(!ScanKeyMap(0x28,0x40,KeyMap -> km_HiKeyMap,KeyMap -> km_HiKeyMapTypes,AnsiKey,Event))
  309.                     return(ScanKeyMap(0x40,0x00,KeyMap -> km_LoKeyMap,KeyMap -> km_LoKeyMapTypes,AnsiKey,Event));
  310.                 else
  311.                     return(TRUE);
  312. */
  313.                     /* Check the low keymap table first. */
  314.  
  315.         default:    if(!ScanKeyMap(0x40,0x00,KeyMap -> km_LoKeyMap,KeyMap -> km_LoKeyMapTypes,AnsiKey,Event))
  316.                     return(ScanKeyMap(0x28,0x40,KeyMap -> km_HiKeyMap,KeyMap -> km_HiKeyMapTypes,AnsiKey,Event));
  317.                 else
  318.                     return(TRUE);
  319.     }
  320. }
  321.