home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / lang / lsc30p4u.sit / stdget_console.c < prev    next >
Text File  |  1989-01-15  |  5KB  |  329 lines

  1. /*
  2.     Routines for LightspeedC
  3.  
  4.     (C) Copyright 1985, 1986. THINK Technologies, Inc.  All rights reserved.
  5.  
  6.         This file contains:
  7.  
  8.              ungetch, getch, getche.
  9. */
  10.  
  11. #ifndef _stdioh_
  12. #include "stdio.h"
  13. #endif
  14.  
  15. #ifndef    _EventMgr_
  16. #include "EventMgr.h"
  17. #endif
  18.  
  19. #ifndef    _signalh_
  20. #include "signal.h"
  21. #endif
  22.  
  23. #ifndef _Quickdraw_
  24. #include "QuickDraw.h"
  25. #endif
  26.  
  27. extern Boolean _inited;
  28. extern Boolean _echo;
  29.  
  30. /* signal handling hooks */
  31.  
  32. int (*_key_int_sig_func_)() = 0;
  33.  
  34. /* pdg - 6/18/86 - completely revised command character handling of the
  35.                     following function to allow control characters to be
  36.                     easily generated from the keyboard */
  37.  
  38. #ifdef _STD_PASTE_
  39.  
  40. /*    If _STD_PASTE is defined in stdio.h, then characters from the clipboard
  41.     can be pasted into the input stream, unlike TE which pastes into a
  42.     window.  This allows all of the standard i/o functions to be passed the
  43.     contents of the paste on a character by character basis.  While the
  44.     paste is occurring, the keyboard is constantly monitored for a
  45.     Command-. which will abort the paste. */
  46.  
  47. static
  48. AbortEvent()
  49. {
  50. EventRecord event;
  51.     
  52.     /* swallow key events looking for Command-. */
  53.  
  54.     while (GetNextEvent(keyDownMask, &event))
  55.         if ((char) event.message == '.' && (event.modifiers & cmdKey))
  56.             return(1);
  57.  
  58.     return(0);
  59. }
  60.  
  61. static long paste_offset = 0;
  62. static int paste_length = 0;
  63. static Handle scrap_handle = 0;
  64.  
  65. void _std_setup_paste()
  66. {
  67. long scrap_offset;
  68.  
  69.     if (scrap_handle)
  70.         DisposHandle(scrap_handle);
  71.  
  72.     scrap_handle = NewHandle(0);
  73.         
  74.     paste_length = GetScrap(scrap_handle, 'TEXT', &scrap_offset);
  75.     paste_offset = 0;
  76. }
  77.  
  78. #endif _STD_PASTE_
  79.  
  80.  
  81. #line 0 _get_char_from_keyboard()
  82. int    _get_char_from_keyboard()
  83. {
  84. register int c;
  85. EventRecord the_Event;    /* holds the event record    */
  86.  
  87.     Init_stdio();
  88.  
  89. #ifdef _STD_PASTE_
  90.  
  91.     /* allow getting keystrokes from the clipboard (scrap) if a paste
  92.         operation has been done */
  93.  
  94. dopaste:
  95.     
  96.     if (paste_length > 0)
  97.     {
  98.         /* a paste operation is in progress, check for keyboard aborts */
  99.     
  100.         if (AbortEvent())
  101.             paste_length = 0;
  102.         else
  103.         {
  104.             c = * (*scrap_handle + paste_offset);
  105.             paste_length--;
  106.             paste_offset++;
  107.             
  108.             /* change Mac return to a new line */
  109.             
  110.             if (c == '\r') c = '\n';
  111.             
  112.             return (c);
  113.         }
  114.     }
  115. #endif _STD_PASTE_
  116.  
  117. nextevent:
  118.  
  119.     while(true)
  120.     {
  121.         while (! GetNextEvent(everyEvent, &the_Event))
  122.         {
  123.             HiliteMenu(0);
  124.             SystemTask();
  125.             
  126. #ifdef _STD_PASTE_
  127.             if (paste_length > 0) goto dopaste;
  128. #endif _STD_PASTE_
  129.  
  130.         }
  131.  
  132. #ifdef _STD_PASTE_
  133.             if (paste_length > 0) goto dopaste;
  134. #endif _STD_PASTE_
  135.  
  136.         SetCursor(&arrow);
  137.         
  138.         if (the_Event.what == keyDown || the_Event.what == autoKey)
  139.             break;
  140.  
  141.         StdEvent(&the_Event);
  142.     }
  143.  
  144.     /* pick up the character */
  145.     
  146.     c  = (unsigned char) the_Event.message;
  147.  
  148.     if (the_Event.modifiers & cmdKey)
  149.     {
  150.     
  151.         /* if signal logic is enabled, then call interrupt procedure */
  152.         
  153.         if (_key_int_sig_func_)
  154.         {register int (*_temp_key_int_sig_func_)() = _key_int_sig_func_;
  155.  
  156.             switch (c)
  157.             {
  158.             case 'c':
  159.             case 'C':
  160.             case '.':
  161.                         if ((long)_key_int_sig_func_ == SIG_DFL)
  162.                             abort();
  163.                         
  164.                         _key_int_sig_func_ = (void*) SIG_DFL;
  165.                         (*_temp_key_int_sig_func_)(SIGINT);
  166.                         goto nextevent;
  167.         
  168.             default:    break;
  169.             }
  170.         }
  171.     
  172.         switch (c)
  173.         {
  174.             /* command(fan) D and command Z are considered EOF chars */
  175.             
  176.         case 'd':
  177.         case 'D':
  178.         case 'z':
  179.         case 'Z':
  180.                     return (EOF);
  181.         
  182.             /* the key may therefore be some other control key, convert it
  183.                 if it is, otherwise ignore the command modifier */
  184.                 
  185.             /* NULL is command space, as is command 2 (shift doesn't work
  186.                 on for @ since event manager traps command shift combos */
  187.         
  188.         case ' ':
  189.         case '2':
  190.                     c = 0;
  191.                     break;
  192.                     
  193.             /* map command 6 into control-^ */
  194.         
  195.         case '6':
  196.                     c = 30;
  197.                     break;
  198.         
  199.             /* map command ` into control-~ */
  200.         
  201.         case '`':
  202.                     c = 31;
  203.                     break;
  204.  
  205.             /* map command backspace into DEL */
  206.     
  207.         case 8:
  208.                     c = 0x7F;
  209.                     break;
  210.         
  211.         default:
  212.                     /* check for standard control chars */
  213.         
  214.                     if ((c >= 'A') && (c <= '_')) c-= ('A' - 1);
  215.                     else
  216.                         if ((c >= 'a') && (c <= '~')) c-= ('a' - 1);
  217.         
  218.                     break;
  219.         }
  220.     }
  221.     else
  222.         /* translate any input return to a newline, but not control M! */
  223.         if (c == '\r') c = '\n';
  224.  
  225.     return(c);
  226. }
  227.  
  228.  
  229. #line 0 ungetch()
  230. int ungetch(c)
  231. int c;
  232. {
  233.     if (_console->look_full)
  234.         return(EOF);
  235.  
  236.     _console->look_full = true;
  237.     _console->look_ahead = c;
  238.     return(c);
  239. }
  240.  
  241.  
  242.  
  243. #line 0 getch_common()
  244. static int getch_common()
  245. {
  246.     if (_console->look_full)
  247.         {
  248.         _console->look_full = false;
  249.         return((int)_console->look_ahead);
  250.     }
  251.     return( _get_char_from_keyboard() );
  252. }
  253.  
  254.  
  255.  
  256. #line 0 getch()
  257. int getch()
  258. {
  259.     return( getch_common() );
  260. }
  261.  
  262.  
  263.  
  264. #line 0 getche()
  265. int getche()
  266. {
  267.     register int    c;
  268.  
  269.     c = getch_common();
  270.     if (c != EOF)
  271.         putch(c);
  272.     return(c);
  273. }
  274.  
  275.  
  276.  
  277. #line 0 cgets()
  278. char *cgets(s)
  279. register char *s;
  280. {
  281. register int    c;
  282. register char    *scopy = s;
  283. register Boolean orig_echo = _echo;
  284.  
  285.     /* handle our own echoing */
  286.  
  287.     Init_stdio();
  288.     
  289.     /*loop until EOF or \n    */
  290.  
  291.     while ((c=getch_common())!= EOF)
  292.     {
  293.         if (c == '\b')
  294.         {
  295.             if (scopy != s)
  296.             {
  297.                 if (_echo)
  298.                 {
  299.                     putch('\b');
  300.                     putch(' ');
  301.                     putch('\b');
  302.                 }
  303.  
  304.                 *--scopy = ' ';
  305.             }
  306.         }
  307.         else
  308.         {
  309.             if (_echo) putch(c);
  310.                 
  311.             if ((*scopy++ = c) == '\n')
  312.             {
  313.                 scopy--;
  314.                 break;
  315.             }        
  316.         }
  317.     }
  318.  
  319.     if ((scopy != s) || (c == '\n'))
  320.     {
  321.         *scopy = '\0';
  322.     }
  323.     else
  324.         s = NULL;
  325.  
  326.     return(s);
  327. }
  328.  
  329.