home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / getch.c < prev    next >
C/C++ Source or Header  |  1998-07-24  |  14KB  |  383 lines

  1. /*
  2.  * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe.
  3.  *
  4.  * Permission is hereby granted to copy, distribute or otherwise
  5.  * use any part of this package as long as you do not try to make
  6.  * money from it or pretend that you wrote it.  This copyright
  7.  * notice must be maintained in any copy made.
  8.  *
  9.  * Use of this software constitutes acceptance for use in an AS IS
  10.  * condition. There are NO warranties with regard to this software.
  11.  * In no event shall the author be liable for any damages whatsoever
  12.  * arising out of or in connection with the use or performance of this
  13.  * software.  Any use of this software is at the user's own risk.
  14.  *
  15.  * If you make modifications to this software that you feel
  16.  * increases it usefulness for the rest of the community, please
  17.  * email the changes, enhancements, bug fixes as well as any and
  18.  * all ideas to me. This software is going to be maintained and
  19.  * enhanced as deemed necessary by the community.
  20.  *
  21.  *              Patrick J. Wolfe
  22.  *              uunet!uiucuxc!kailand!pwolfe
  23.  *              pwolfe@kailand.kai.com
  24.  *
  25.  * Additions of Xenix,Sun,DOS,VMS,AIX and OS2 key handling
  26.  * made by Mark Hessling (M.Hessling@qut.edu.au)
  27.  *
  28.  */
  29.  
  30.  
  31. /*
  32. $Id: getch.c 2.1 1995/06/24 16:30:06 MH Rel MH $
  33. */
  34.  
  35. #ifdef HAVE_CONFIG_H
  36. # include <config.h>
  37. #endif
  38.  
  39. #if defined(USE_NCURSES)
  40. #   include <ncurses.h>
  41. #else
  42. #   if defined(USE_EXTCURSES)
  43. #      include <cur00.h>
  44. #   else
  45. #      if defined(USE_XCURSES)
  46. #         define XCURSES
  47. #         include <xcurses.h>
  48. #      else
  49. #         include <curses.h>
  50. #      endif
  51. #   endif
  52. #endif
  53.  
  54. #if !defined(DOS) && !defined(OS2) && !defined(WIN32)
  55. #include <getch.h>
  56.  
  57. #define NORMAL 100
  58. #define ESCAPE 200
  59. #define FKEY   300
  60. #define BRACK  400
  61.  
  62. /***********************************************************************/
  63. #ifdef HAVE_PROTO
  64. #  ifdef MSWIN
  65. int my_getch (WINDOW far *winptr)
  66. #  else
  67. int my_getch (WINDOW *winptr)
  68. #  endif
  69. #else
  70. int my_getch (winptr)
  71. #  ifdef MSWIN
  72. WINDOW far *winptr;
  73. #  else
  74. WINDOW *winptr;
  75. #  endif
  76. #endif
  77. /***********************************************************************/
  78. {
  79. /*-------------------------- external data ----------------------------*/
  80. /*--------------------------- local data ------------------------------*/
  81. int c=0,tmp_c=(-1);
  82. short state = NORMAL;
  83. short fkeycount = 0;
  84. /*--------------------------- processing ------------------------------*/
  85. while (1) {
  86. #ifndef VMS
  87.        c = wgetch(winptr);
  88. #else
  89.        c = keypress();
  90. #endif
  91.        switch (state) {
  92.  
  93.        case BRACK:
  94.                switch (c) {
  95.                /* Linux f1 thru f5 are <esc>[[A <esc>[[B ... <esc>[[E */
  96.                case 'A': case 'B': case 'C': case 'D': case 'E':
  97.                        return KEY_F1 + (c - 'A');
  98.                default:
  99.                        state = NORMAL;
  100.                        break;
  101.                        }
  102.                break;
  103.  
  104.        case FKEY:
  105.                switch (c) {
  106.  
  107.                /* numeric function keys */
  108.                case '0': case '1': case '2': case '3': case '4':
  109.                case '5': case '6': case '7': case '8': case '9':
  110.                        fkeycount = (fkeycount * 10) + (c - '0');
  111.                        break;
  112.  
  113.                case '~':
  114.                        switch (fkeycount) {
  115.  
  116.                        /* Find, Insert Here, Remove, Select, Prev Screen, Next Screen */
  117.                        case 1: return KEY_Find;
  118.                        case 2: return KEY_InsertHere;
  119.                        case 3: return KEY_Remove;
  120.                        case 4: return KEY_Select;
  121.                        case 5: return KEY_PrevScreen;
  122.                        case 6: return KEY_NextScreen;
  123.  
  124.                        /* vt220 function keys F1 to F10 */
  125.                        case 11: case 12: case 13: case 14: case 15:
  126.                                return KEY_F(1) + (fkeycount - 11);
  127.                        case 17: case 18: case 19: case 20: case 21:
  128.                                return KEY_F(6) + (fkeycount - 17);
  129.  
  130.                        /* vt220 function keys F11 to F20 */
  131.                        case 23: case 24:
  132.                                return KEY_F(11) + (fkeycount - 23);
  133.                        case 25: case 26:
  134.                                return KEY_F(49) + (fkeycount - 25);
  135.                        case 28: case 29:
  136.                                return KEY_F(51) + (fkeycount - 28);
  137.                        case 31: case 32: case 33: case 34:
  138.                                return KEY_F(53) + (fkeycount - 31);
  139.  
  140.                        /* vt220 function keys - non-standard */
  141.                        case 37: case 38: case 39: case 40: case 41:
  142.                        case 42: case 43: case 44: case 45: case 46:
  143.                        case 47: case 48: case 49: case 50: case 51:
  144.                        case 52: case 53: case 54: case 55: case 56:
  145.                        case 57: case 58: case 59: case 60:
  146.                                return KEY_F(13) + (fkeycount - 37);
  147.  
  148.                        default:
  149.                                state = NORMAL;
  150.                                }
  151.                        break;
  152.  
  153.                case 0:         return KEY_HOME;
  154.                case 'A':       return KEY_UP;
  155.                case 'B':       return KEY_DOWN;
  156.                case 'C':       return KEY_RIGHT;
  157.                case 'D':       return KEY_LEFT;
  158.                case 'M':       return KEY_NUMENTER;
  159.                case 'Z':       return KEY_BTAB;
  160.  
  161.                /* Xenix default key mappings */
  162.                case 'H':       return KEY_HOME;
  163.                case 'F':       return KEY_END;
  164.                case 'L':       return KEY_InsertHere;
  165.                case 'G':       return KEY_NextScreen;
  166.                case 'I':       return KEY_PrevScreen;
  167.  
  168.                case 'N':       return KEY_F2;
  169.                case 'O':       return KEY_F3;
  170.                case 'T':       return KEY_F8;
  171.                case 'U':       return KEY_F9;
  172.                case 'V':       return KEY_F10;
  173.                case 'W':       return KEY_F11;
  174.                case 'X':       return KEY_F12;
  175.  
  176.                /* VT[12]00 PF keys */
  177.                case 'P': case 'Q': case 'R': case 'S':
  178.                        return KEY_PF1 + (c - 'P');
  179.  
  180.                case 'j':
  181.                        return KEY_PadStar;
  182.                case 'k':
  183.                        return KEY_PadPlus;
  184.                case 'l': 
  185.                        return KEY_PadComma;
  186.                case 'm': 
  187.                        return KEY_PadMinus;
  188.                case 'n': 
  189.                        return KEY_PadPeriod;
  190.                case 'o': 
  191.                        return KEY_PadSlash;
  192.                case 'p': 
  193.                        return KEY_Pad0;
  194.                case 'r':
  195.                        return KEY_C2;
  196.                case 's': 
  197.                        return KEY_C3;
  198.                case 't': 
  199.                        return KEY_B1;
  200.                case 'u': 
  201.                        return KEY_B2;
  202.                case 'v': 
  203.                        return KEY_B3;
  204.                case 'w': 
  205.                        return KEY_A1;
  206.                case 'x': 
  207.                        return KEY_A2;
  208.                case 'y':
  209.                        return KEY_A3;
  210.  
  211.                /* Sun Keyboard Function Keys */
  212.                case 'z':
  213.                        switch (fkeycount) {
  214.                        /* SUN F1-F12 */
  215.                        case 224: case 225: case 226: case 227: case 228:
  216.                        case 229: case 230: case 231: case 232: case 233:
  217.                        case 234: case 235:
  218.                                return KEY_F(1) + (fkeycount - 224);
  219.                        /* SUN S-F1-S-F12 */
  220.                        case 324: case 325: case 326: case 327: case 328:
  221.                        case 329: case 330: case 331: case 332: case 333:
  222.                        case 334: case 335:
  223.                                return KEY_F(13) + (fkeycount - 324);
  224.                        /* SUN C-F1-C-F12 */
  225.                        case 424: case 425: case 426: case 427: case 428:
  226.                        case 429: case 430: case 431: case 432: case 433:
  227.                        case 434: case 435:
  228.                                return KEY_F(25) + (fkeycount - 424);
  229.                        case 192: return KEY_F(49);   /* L1 */
  230.                        case 193: return KEY_F(50);   /* L2 */
  231.                        case 195: return KEY_UNDO;
  232.                        case 292: return KEY_F(57);   /* S-L1 */
  233.                        case 293: return KEY_F(58);   /* S-L2 */
  234.                        case 214: return KEY_HOME;
  235.                        case 414: return CTL_HOME;
  236.                        case 215: return KEY_UP;
  237.                        case 415: return CTL_UP;
  238.                        case 216: return KEY_PrevScreen;
  239.                        case 416: return CTL_PGUP;
  240.                        case 217: return KEY_LEFT;
  241.                        case 417: return CTL_LEFT;
  242.                        case 219: return KEY_RIGHT;
  243.                        case 419: return CTL_RIGHT;
  244.                        case 220: return KEY_END;
  245.                        case 420: return CTL_END;
  246.                        case 221: return KEY_DOWN;
  247.                        case 421: return CTL_DOWN;
  248.                        case 222: return KEY_NextScreen;
  249.                        case 422: return CTL_PGDN;
  250.                        case 1:   return KEY_BTAB;
  251.                        case 2:   return KEY_InsertHere;
  252.                        case 3:   return KEY_HOME;
  253.                        case 4:   return KEY_END;
  254.                        case 5:   return KEY_PrevScreen;
  255.                        case 6:   return KEY_NextScreen;
  256.                        case 423: return KEY_PadComma;
  257.                        default:
  258.                                state = NORMAL;
  259.                                }
  260.                        break;
  261.  
  262.                /* IBM AIX ???????? */
  263.                case 'q':
  264.                        switch (fkeycount) {
  265.                        case 0:  /* VT100/200 keypad */
  266. #ifdef USE_NCURSES
  267.                                return KEY_C1;
  268. #else
  269.                                return KEY_PadComma;
  270. #endif
  271.                        /* AIX F1-F12 */
  272.                        case 1: case 2: case 3: case 4: case 5: 
  273.                        case 6: case 7: case 8: case 9: case 10: 
  274.                        case 11: case 12:
  275.                                return KEY_F(1) + (fkeycount - 1);
  276.                        /* AIX SF1-F12 */
  277.                        case 13: case 14: case 15: case 16: case 17: 
  278.                        case 18: case 19: case 20: case 21: case 22: 
  279.                        case 23: case 24:
  280.                                return KEY_F(13)+ (fkeycount - 13);
  281.                        /* AIX CF1-F12 */
  282.                        case 25: case 26: case 27: case 28: case 29: 
  283.                        case 30: case 31: case 32: case 33: case 34: 
  284.                        case 35: case 36:
  285.                                return KEY_F(25)+ (fkeycount - 25);
  286.                        case 150: return KEY_PrevScreen;
  287.                        case 146: return KEY_END;
  288.                        case 154: return KEY_NextScreen;
  289.                        case 139: return KEY_InsertHere;
  290.                        default:
  291.                                state = NORMAL;
  292.                                }
  293.                        break;
  294.                case '[':
  295.                        state = BRACK;
  296.                        break;
  297.  
  298.                default:
  299.                        state = NORMAL;
  300.                        }
  301.                break;
  302.  
  303.        case ESCAPE:
  304.                switch (c) {
  305.                case 'O':     /* vt100 numeric keypad application codes */
  306.                case '?':     /* vt52  numeric keypad application codes */
  307.                case '[':
  308.                        state = FKEY;
  309.                        fkeycount = 0;
  310.                        break;
  311.                /* VT52 PF keys */
  312.                case 'P': case 'Q': case 'R': case 'S':
  313.                        return KEY_PF1 + (c - 'P');
  314.  
  315.                default:
  316.                        state = NORMAL;
  317.                        }
  318.                break;
  319.  
  320.        default:
  321.                switch (c) {
  322.                case KEY_ESC:
  323. #if defined(HAVE_NODELAY) && defined(HAVE_UNGETCH)
  324. /* this code allows the user to use the ESC key */
  325.                        nodelay(winptr,TRUE);
  326.                        tmp_c = wgetch(winptr);
  327.                        nodelay(winptr,FALSE);
  328.                        if (tmp_c  == ERR)
  329.                           return(c);
  330.                        ungetch(tmp_c);
  331. #endif
  332.                        state = ESCAPE;
  333.                        break;
  334.  
  335.                case CSI:
  336.                        state = FKEY;
  337.                        fkeycount = 0;
  338.                        break;
  339.  
  340.                default:
  341.                        return (c);
  342.                        }
  343.                }
  344.        }
  345. }
  346. #endif
  347.  
  348. #ifdef VMS
  349. #include iodef
  350. #include descrip
  351. /***********************************************************************/
  352. short keypress()
  353. /***********************************************************************/
  354. {
  355. /*--------------------------- local data ------------------------------*/
  356. struct { long length; char *address; } logical_name;
  357. struct { short status; short length; short remainder; } iosb;
  358.  
  359. static char kb[] = { "sys$input" };
  360. static short chan;
  361.  
  362. static char key = 0;
  363. short new_key;
  364. static short first = 1;
  365. short status;
  366. /*--------------------------- processing ------------------------------*/
  367.  
  368.  key = 0;
  369.  logical_name.length = strlen (kb);
  370.  logical_name.address = kb;
  371.  status = sys$assign (&logical_name, &chan, 0, 0);
  372.  if (status != 1)
  373.    return(-1);
  374.  status = SYS$QIOW(0, chan, IO$_READVBLK | IO$M_NOFILTR | IO$M_NOECHO
  375.         | IO$M_TIMED, &iosb, 0, 0, &key, 1,600, 0,0, 0, 0);
  376.  if (!key)
  377.     return (0);
  378.  new_key = (short)(key);
  379.  status = sys$dassgn (chan);
  380.  return (new_key);
  381. }
  382. #endif
  383.