home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / lib_examples / rawkey.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-21  |  8.2 KB  |  210 lines

  1. ;/* rawkey.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -y -j73 rawkey.c
  3. Blink FROM LIB:c.o,rawkey.o TO rawkey LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. **
  6. ** The following example uses RawKeyConvert() to convert the
  7. ** IDCMP_RAWKEY input stream into an ANSI input stream.  See the
  8. ** "Console Device" chapter in the Amiga ROM Kernel Reference Manual:
  9. ** Devices for more information on RawKeyConvert() and the data it
  10. ** returns.
  11. **
  12. ** rawkey.c - How to correctly convert from RAWKEY to keymapped ASCII
  13. */
  14. #define INTUI_V36_NAMES_ONLY
  15.  
  16. #include <exec/types.h>
  17. #include <exec/memory.h>
  18. #include <intuition/intuition.h>
  19. #include <devices/inputevent.h>
  20. #include <clib/exec_protos.h>
  21. #include <clib/intuition_protos.h>
  22. #include <clib/console_protos.h>
  23. #include <stdio.h>
  24.  
  25. #ifdef LATTICE
  26. int CXBRK(void)    { return(0); }  /* Disable Lattice CTRL/C handling */
  27. int chkabort(void) { return(0); }  /* really */
  28. #endif
  29.  
  30. /* our function prototypes */
  31. LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
  32.                     LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent);
  33. VOID print_qualifiers(ULONG qual);
  34. BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
  35.                     UBYTE **buffer, ULONG *bufsize);
  36. VOID process_window(struct Window *win, struct InputEvent *ievent,
  37.                     UBYTE **buffer, ULONG *bufsize);
  38.  
  39. /* A buffer is created for RawKeyConvert() to put its output. BUFSIZE is the size of
  40. ** the buffer in bytes.  NOTE that this program starts out with a buffer size of 2.
  41. ** This is only to show how the buffer is automatically increased in size  by this
  42. ** example!  In an application, start with a much larger buffer and you will probably
  43. ** never have to increase its size. 128 bytes or so should do the trick, but always
  44. ** be able to change the size if required.
  45. */
  46. #define BUFSIZE (2)
  47.  
  48. struct Library *IntuitionBase, *ConsoleDevice;
  49.  
  50. /* main() - set-up everything used by program. */
  51. VOID main(int argc, char **argv)
  52. {
  53. struct Window *win;
  54. struct IOStdReq ioreq;
  55. struct InputEvent *ievent;
  56. UBYTE *buffer;
  57. ULONG bufsize = BUFSIZE;
  58.  
  59. if(IntuitionBase = OpenLibrary("intuition.library",37)) {
  60.     /* Open the console device just to do keymapping. (unit -1 means any unit) */
  61.     if (0 == OpenDevice("console.device",-1,(struct IORequest *)&ioreq,0)) {
  62.         ConsoleDevice = (struct Library *)ioreq.io_Device;
  63.  
  64.         /* Allocate the initial character buffer used by deadKeyConvert() and RawKeyConvert()
  65.         ** for returning translated characters. If the characters generated by these routines
  66.         ** cannot fit into the buffer, the application must pass a larger buffer.  This is
  67.         ** done in this code by freeing the old buffer and allocating a new one.
  68.         */
  69.         if (buffer = AllocMem(bufsize,MEMF_CLEAR)) {
  70.             if (ievent = AllocMem(sizeof(struct InputEvent),MEMF_CLEAR)) {
  71.                 if (win = OpenWindowTags(NULL,
  72.                         WA_Width, 300,
  73.                         WA_Height, 50,
  74.                         WA_Flags, WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE,
  75.                         WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  76.                         WA_Title, "Raw Key Example",
  77.                         TAG_END)) {
  78.                     printf("Press keyboard keys to see ASCII conversion from rawkey\n");
  79.                     printf("Unprintable characters will be shown as %c\n\n",0x7f);
  80.                     process_window(win,ievent,&buffer,&bufsize);
  81.                     CloseWindow(win);
  82.                     }
  83.                 FreeMem(ievent,sizeof(struct InputEvent));
  84.                 }
  85.             /* Buffer can be freed elsewhere in the program so test first. */
  86.             if (buffer != NULL)
  87.                 FreeMem(buffer,bufsize);
  88.             }
  89.         CloseDevice((struct IORequest *)&ioreq);
  90.         }
  91.     CloseLibrary(IntuitionBase);
  92.     }
  93. }
  94.  
  95. /* Convert RAWKEYs into VANILLAKEYs, also shows special keys like HELP, Cursor Keys,
  96. ** FKeys, etc.  It returns:
  97. **   -2 if not a RAWKEY event.
  98. **   -1 if not enough room in the buffer, try again with a bigger buffer.
  99. **   otherwise, returns the number of characters placed in the buffer.
  100. */
  101. LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
  102.     LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent)
  103. {
  104. if (msg->Class != IDCMP_RAWKEY) return(-2);
  105. ievent->ie_Class = IECLASS_RAWKEY;
  106. ievent->ie_Code = msg->Code;
  107. ievent->ie_Qualifier = msg->Qualifier;
  108. ievent->ie_position.ie_addr = *((APTR*)msg->IAddress);
  109.  
  110. return(RawKeyConvert(ievent,kbuffer,kbsize,kmap));
  111. }
  112.  
  113. /* print_qualifiers() - print out the values found in the qualifier bits of
  114. ** the message. This will print out all of the qualifier bits set.
  115. */
  116. VOID print_qualifiers(ULONG qual)
  117. {
  118. printf("Qual:");
  119. if (qual & IEQUALIFIER_LSHIFT)         printf("LShft,");
  120. if (qual & IEQUALIFIER_RSHIFT)         printf("RShft,");
  121. if (qual & IEQUALIFIER_CAPSLOCK)       printf("CapLok,");
  122. if (qual & IEQUALIFIER_CONTROL)        printf("Ctrl,");
  123. if (qual & IEQUALIFIER_LALT)           printf("LAlt,");
  124. if (qual & IEQUALIFIER_RALT)           printf("RAlt,");
  125. if (qual & IEQUALIFIER_LCOMMAND)       printf("LCmd,");
  126. if (qual & IEQUALIFIER_RCOMMAND)       printf("RCmd,");
  127. if (qual & IEQUALIFIER_NUMERICPAD)     printf("NumPad,");
  128. if (qual & IEQUALIFIER_REPEAT)         printf("Rpt,");
  129. if (qual & IEQUALIFIER_INTERRUPT)      printf("Intrpt,");
  130. if (qual & IEQUALIFIER_MULTIBROADCAST) printf("Multi Broadcast,");
  131. if (qual & IEQUALIFIER_MIDBUTTON)      printf("MidBtn,");
  132. if (qual & IEQUALIFIER_RBUTTON)        printf("RBtn,");
  133. if (qual & IEQUALIFIER_LEFTBUTTON)     printf("LBtn,");
  134. if (qual & IEQUALIFIER_RELATIVEMOUSE)  printf("RelMouse,");
  135. }
  136.  
  137. /* doKeys() - Show what keys were pressed. */
  138. BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
  139.             UBYTE **buffer, ULONG *bufsize)
  140. {
  141. USHORT char_pos;
  142. USHORT numchars;
  143. BOOL   ret_code = TRUE;
  144. UBYTE  realc, c;
  145.  
  146. /* deadKeyConvert() returns -1 if there was not enough space in the buffer to
  147. ** convert the string. Here, the routine increases the size of the buffer on the
  148. ** fly...Set the return code to FALSE on failure.
  149. */
  150. numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
  151. while ((numchars == -1) && (*buffer != NULL)) {
  152.     /* conversion failed, buffer too small. try to double the size of the buffer. */
  153.     FreeMem(*buffer, *bufsize);
  154.     *bufsize = *bufsize << 1;
  155.     printf("Increasing buffer size to %d\n", *bufsize);
  156.  
  157.     if (NULL == (*buffer = AllocMem(*bufsize, MEMF_CLEAR)))  ret_code = FALSE;
  158.     else  numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
  159.     }
  160.  
  161. /* numchars contains the number of characters placed within the buffer.  Key up events and   */
  162. /* key sequences that do not generate any data for the program (like deadkeys) will return   */
  163. /* zero.  Special keys (like HELP, the cursor keys, FKeys, etc.) return multiple characters  */
  164. /* that have to then be parsed by the application.  Allocation failed above if buffer is NULL*/
  165. if (*buffer != NULL) {
  166.     /* if high bit set, then this is a key up otherwise this is a key down */
  167.     if (msg->Code & 0x80)
  168.           printf("Key Up:   ");
  169.     else
  170.           printf("Key Down: ");
  171.  
  172.     print_qualifiers(msg->Qualifier);
  173.     printf(" rawkey #%d maps to %d ASCII character(s)\n", 0x7F & msg->Code, numchars);
  174.     for (char_pos = 0; char_pos < numchars; char_pos++) {
  175.         realc = c = (*buffer)[char_pos];
  176.         if ((c <= 0x1F)||((c >= 0x80)&&(c < 0xa0)))
  177.             c = 0x7f;
  178.         printf("  %3d ($%02x) = %c\n", realc, realc, c);
  179.         }
  180.     }
  181. return(ret_code);
  182. }
  183.  
  184. /* process_window() - simple event loop.  Note that the message is not replied
  185. ** to until the end of the loop so that it may be used in the doKeys() call.
  186. */
  187. VOID process_window(struct Window *win, struct InputEvent *ievent,
  188.     UBYTE **buffer, ULONG *bufsize)
  189. {
  190. struct IntuiMessage *msg;
  191. BOOL done;
  192.  
  193. done = FALSE;
  194. while (done == FALSE) {
  195.     Wait((1L<<win->UserPort->mp_SigBit));
  196.     while ((done == FALSE) && (msg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
  197.         switch (msg->Class) {     /* handle our events */
  198.             case IDCMP_CLOSEWINDOW:
  199.                 done = TRUE;
  200.                 break;
  201.             case IDCMP_RAWKEY:
  202.                 if (FALSE == doKeys(msg,ievent,buffer,bufsize))
  203.                     done = TRUE;
  204.                 break;
  205.             }
  206.         ReplyMsg((struct Message *)msg);
  207.         }
  208.     }
  209. }
  210.