home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / unix / emx / test / kbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-25  |  2.9 KB  |  139 lines

  1. /* kbd.c (emx+gcc) */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define INCL_KBD
  7. #include <os2.h>
  8.  
  9.  
  10. /* The header files of "IBM Developer's Toolkit for OS/2 2.0" lack */
  11. /* the definition of KBDTRF_EXTENDED_CODE! */
  12.  
  13. #if !defined (KBDTRF_EXTENDED_CODE)
  14. #define KBDTRF_EXTENDED_CODE 0x02
  15. #endif
  16.  
  17. /* These variables must not cross a 64KB boundary */
  18. /* Making them auto variables is dangerous */
  19.  
  20. static KBDKEYINFO ki;
  21. static STRINGINBUF si;
  22. static CHAR buf[255];
  23.  
  24. #define CHECK_ADDR(v) do { \
  25.   if (((ULONG)&v & ~0xffff) != (((ULONG)&v+sizeof(v)-1) & ~0xffff)) \
  26.     abort(); } while (0)
  27.  
  28. static void test_charin (void)
  29. {
  30.   USHORT rc;
  31.  
  32.   for (;;)
  33.     {
  34.       rc = KbdCharIn (&ki, IO_WAIT, 0);
  35.       if (rc != 0)
  36.         {
  37.           fprintf (stderr, "\nKbdCharIn failed, rc=%u\n", (unsigned)rc);
  38.           exit (1);
  39.         }
  40.       if ((ki.chChar == 0 || ki.chChar == 0xe0)
  41.           && ki.fbStatus & KBDTRF_EXTENDED_CODE)
  42.         fputs ("<ext>", stdout);
  43.       else if (ki.chChar == 0x1b)
  44.         break;
  45.       else
  46.         putchar (ki.chChar);
  47.     }
  48. }
  49.  
  50.  
  51. static void test_stringin (void)
  52. {
  53.   USHORT rc;
  54.  
  55.   si.cchIn = 0;
  56.   for (;;)
  57.     {
  58.       si.cb = sizeof (buf);
  59.       rc = KbdStringIn (buf, &si, IO_WAIT, 0);
  60.       if (rc != 0)
  61.         {
  62.           fprintf (stderr, "\nKbdStringIn failed, rc=%u\n", (unsigned)rc);
  63.           exit (1);
  64.         }
  65.       buf[si.cchIn] = 0;
  66.       putchar ('\n');
  67.       if (buf[0] == 0x1a)
  68.         break;
  69.       puts (buf);
  70.     }
  71. }
  72.  
  73.  
  74. /* Move a structure to an address where it crosses a 64KB boundary. */
  75. /* If the structure is not properly aligned, an exception occurs.   */
  76. /* If the structure is properly aligned, the 16:16 pointer wraps    */
  77. /* around to an address 64KB lower than expected.                   */
  78.  
  79. static void test_bad_example (int trap)
  80. {
  81.   void *buf;
  82.   ULONG addr;
  83.   PKBDINFO pi;
  84.   int i;
  85.  
  86.   buf = malloc (0x30000);
  87.   if (buf == NULL)
  88.     {
  89.       fputs ("malloc() failed\n", stderr);
  90.       exit (2);
  91.     }
  92.   memset (buf, 0, 0x30000);
  93.   addr = (ULONG)buf + 0x10000;
  94.   addr = addr | (trap ? 0xffff : 0xfffe);
  95.   pi = (PKBDINFO)addr;
  96.   pi->cb = sizeof (*pi);
  97.   /* CHECK_ADDR (*pi); */
  98.   if (trap)
  99.     {
  100.       puts ("Exception expected..."); fflush (stdout);
  101.     }
  102.   KbdGetStatus (pi, 0);
  103.   for (i = 0; i < 0x10000; ++i)
  104.     if (((char *)(addr - 0x10000))[i] != 0)
  105.       {
  106.         puts ("Wrap around occured");
  107.         return;
  108.       }
  109. }
  110.  
  111.  
  112. static void usage (void)
  113. {
  114.   puts ("Usage: kbd [-stw]");
  115.   exit (1);
  116. }
  117.  
  118.  
  119.  
  120. int main (int argc, char *argv[])
  121. {
  122.   CHECK_ADDR (ki);
  123.   CHECK_ADDR (si);
  124.   CHECK_ADDR (buf);
  125.   if (argc == 1)
  126.     test_charin ();
  127.   else if (argc != 2)
  128.     usage ();
  129.   else if (strcmp (argv[1], "-t") == 0)
  130.     test_bad_example (TRUE);
  131.   else if (strcmp (argv[1], "-w") == 0)
  132.     test_bad_example (FALSE);
  133.   else if (strcmp (argv[1], "-s") == 0)
  134.     test_stringin ();
  135.   else
  136.     usage ();
  137.   return (0);
  138. }
  139.