home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / c / curses / src / wgetch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-30  |  5.5 KB  |  198 lines

  1. /* -*-C-*-
  2.  *
  3.  *
  4.  * Filename : wgetch.c
  5.  *
  6.  * Author   : Simon J Raybould.    (sie@fulcrum.bt.co.uk).
  7.  *
  8.  * Date     : Friday 23rd August 1991.
  9.  *
  10.  * Desc     : Read a character.
  11.  *
  12.  *
  13.  * THIS CODE IS NOT PUBLIC DOMAIN
  14.  * ==============================
  15.  * 
  16.  * This code is copyright Simon J Raybould 1991, all rights are reserved.
  17.  * All code, ideas, data structures and algorithms remain the property of the
  18.  * author. Neither the whole nor sections of this code may be used as part
  19.  * of other code without the authors consent. If you wish to use some of this
  20.  * code then please email me at (sie@fulcrum.bt.co.uk).
  21.  *
  22.  * This source is not public domain, so you do not have any right to alter it
  23.  * or sell it for personal gain. The source is provided purely for reference
  24.  * purposes. You may re-compile the source with any compiler you choose.
  25.  * You must not distribute altered copies without the authors consent. My
  26.  * intention is that the source will help people isolate any bugs much more
  27.  * effectivly.
  28.  *
  29.  * Disclaimer
  30.  * ==========
  31.  *
  32.  * No implication is made as to this code being fit for any purpose at all.
  33.  * I (the author) shall not be held responsible for any loss of data or damage 
  34.  * to property that may result from its use or misuse.
  35.  *
  36.  *
  37.  * Revision History
  38.  * ================
  39.  *
  40.  * $Log:    wgetch.c,v $
  41.  * Revision 1.4  92/06/10  23:44:59  sie
  42.  * Added serial support.
  43.  * 
  44.  * Revision 1.3  91/12/28  22:45:46  sie
  45.  * changed attrs to UBYTE from short + some tidying up.
  46.  * 
  47.  * Revision 1.2  91/12/27  10:02:38  sie
  48.  * Attempted to speed up wgetch a bit.
  49.  * 
  50.  * Revision 1.1  91/09/07  11:50:10  sie
  51.  * Initial revision
  52.  * 
  53.  *
  54.  */
  55.  
  56. static char *rcsid = "$Header: SRC:lib/curses/src/RCS/wgetch.c,v 1.4 92/06/10 23:44:59 sie Exp $";
  57.  
  58. #include <fcntl.h>
  59. #include "acurses.h"
  60.  
  61. wgetch(WINDOW *WinPtr)
  62. {
  63.   static unsigned char buffer[RAWBUFSIZ];
  64.   int Class, i;
  65.   struct IntuiMessage *Message;
  66.   static struct InputEvent ievent = { NULL, IECLASS_RAWKEY, 0, 0, 0 };
  67.   char c;
  68.   
  69.   if(!(CursesFlags & CFLAG_INITSCR))  /* Haven't called initscr() */
  70.     return ERR;
  71.   
  72.   if(CursesType == CUST_CURSES) {
  73.     if(GetchBufPos < GetchNChars)  /* If we still have some chars then return next */
  74.       return (int)buffer[GetchBufPos++];
  75.  
  76.     /* Else read a new buffer */
  77.     GetchBufPos = GetchNChars = 0;
  78.     while(!GetchNChars) {
  79.       chkabort(); /* Check if INTR */
  80.       /* Get message if there is one already queued */
  81.       Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
  82.       if(!Message) {
  83.     /* Nuffin yet */
  84.     if(WinPtr->_nodelay)  /* If non-blocking return ERR */
  85.       return ERR;
  86.     else {    /* Wait for character */
  87.       Wait(1<<CursesWindow->UserPort->mp_SigBit);
  88.       Message = (struct IntuiMessage *)GetMsg(CursesWindow->UserPort);
  89.     }
  90.       }
  91.       if(!Message)  /* Try again */
  92.     continue;
  93.       
  94.       Class = Message->Class;
  95.       switch(Class) {
  96.       case RAWKEY:
  97.     GetchBufPos = 0;
  98.     ievent.ie_Code = Message->Code;
  99.     ievent.ie_Qualifier = Message->Qualifier;
  100.     ievent.ie_position.ie_addr = *((APTR*)Message->IAddress);
  101.     ReplyMsg((struct Message *)Message);
  102.     GetchNChars = RawKeyConvert(&ievent, buffer, RAWBUFSIZ, 0L);
  103.     if(!GetchNChars)  /* If no characters then try again */
  104.       break;
  105.     if(CursesFlags & CFLAG_ECHO)
  106.       for(i=0; i<GetchNChars; i++)
  107.         DoEcho(WinPtr, buffer[i]);
  108.     /* Translate ANSI sequence if keypad set to TRUE */
  109.     if(CursesFlags & CFLAG_KEYPAD) {
  110.       switch(GetchNChars) {
  111.       case 1:
  112.         GetchNChars = 0;  /* Translation will use up all chars */
  113.         if((CursesFlags & CFLAG_NLCR) && (buffer[0] == '\r'))
  114.           return (int)'\n';
  115.         return (int)*buffer;
  116.       case 2:    /* ARROW KEY */
  117.         GetchNChars = 0;  /* Translation will use up all chars */
  118.         if(buffer[0] != 155)
  119.           return -1;
  120.         switch(buffer[1]) {
  121.         case 'A':
  122.           return KEY_UP;
  123.         case 'B':
  124.           return KEY_DOWN;
  125.         case 'C':
  126.           return KEY_RIGHT;
  127.         case 'D':
  128.           return KEY_LEFT;
  129.         default:
  130.           return -1;
  131.         }
  132.       case 3:    /* FUNCTION KEY */
  133.         GetchNChars = 0;  /* Translation will use up all chars */
  134.         if(buffer[0] != 155)
  135.           return -1;
  136.         if(buffer[2] != 126)
  137.           return -1;
  138.         if(buffer[1] == 63)
  139.           return KEY_HELP;
  140.         return KEY_F0 + (buffer[1] - 47);  /* KEY_F(1) = F1 */
  141.       default:
  142.         GetchNChars = 0;  /* Translation will use up all chars */
  143.         return -1;
  144.       }
  145.     }
  146.     break;
  147.       default:
  148.     ReplyMsg((struct Message *)Message);
  149.     break;
  150.       }
  151.     }
  152.     if((CursesFlags & CFLAG_NLCR) && (buffer[GetchBufPos] == '\r')) {
  153.       GetchBufPos++;
  154.       return (int)'\n';
  155.     }
  156.     return (int)buffer[GetchBufPos++];
  157.   } else if(CursesType == ANSI_CURSES) {
  158.     if((WinPtr->_nodelay) && (!WaitForChar(ifh, 10000L)))
  159.       return ERR;        /* if nodelay and no char ready */
  160.     read(0, &c, 1);
  161.     if(CursesFlags & CFLAG_ECHO)
  162.       DoEcho(WinPtr, c);
  163.     if((CursesFlags & CFLAG_NLCR) && (c == '\r'))
  164.       return (int)'\n';
  165.  
  166.     if(c == ESC && WaitForChar(ifh, 10000L)) { /* if ESC wait for [ */
  167.       read(0, &c, 1);
  168.       if(CursesFlags & CFLAG_ECHO)
  169.     DoEcho(WinPtr, c);
  170.       if(c != '[')
  171.     return -1;
  172.     } else if((unsigned char)c != 0x9b)    /* if not ESC of 9b then return */
  173.       return (int)c;
  174.  
  175.     /* Got CSI, wait for rest */
  176.     if(!WaitForChar(ifh, 10000L))
  177.       return -1;
  178.     read(0, &c, 1);
  179.     if(CursesFlags & CFLAG_ECHO)
  180.       DoEcho(WinPtr, c);
  181.  
  182.     if(CursesFlags & CFLAG_KEYPAD) {
  183.       switch(c) {
  184.       case 'A':
  185.     return KEY_UP;
  186.       case 'B':
  187.     return KEY_DOWN;
  188.       case 'C':
  189.     return KEY_RIGHT;
  190.       case 'D':
  191.     return KEY_LEFT;
  192.       default:
  193.     return -1;
  194.       }      
  195.     }
  196.   }
  197. }
  198.