% ***************************************************************
%                                                               *
%     Definition of single character keyboard input             *
%     Conforms to release 109.2.2 of PC Simula                  *
%                                                               *
% ***************************************************************
/*
   keyboard.ins                           V0.1  (Cim 3.29 / Win32)  

   simula functions and def. for managing console input (key, mouse)

   ported by Petr Novak 1999
*/
  
/************************************************************************* 
  Comment for ifkey, inkey:

  Attributes of lastKey for KEYBOARD event:

    map - mapped key !!!  (some constants are defined below)
    chr - scan code       (exact key on the keyboard)
    fkey - function key   (some constants are defined below) 
    c0, c1 - control keys (each bit signs some control key)
    c2 - key release      (if enabled by listenReleaseKeys)
   
  Attributes of lastKey for MOUSE event: (also see further)

    map == 1 && chr == 0
      (you can recognize mouse acording this atributes, or use wasMouse)
    fkey - action: click, double click, move
    c0, c2 - control keys (each bit signs some control key) (like key events)
    c2 - button press (leftmost, rightmost, button2, button3, ...)
         (if the bit is set, the button is pressed)
    x, y - mouse position (pos == x, lin == y)

  !!! Use method isSet (atribut, constant) for test bits !!!
  (as for buttons, controll keys ... - c0, c1, c2) (constants see further)
  
  - you can test the behaviour of control keys using listenControllKeys
  - I suggest to do some tests before programming nontrivial key-combination
  - You can use simple test program keyin.sim found in the package with cim
*/

%  ************************************************************************
%  1. Named constants for special key mapped character (lastkey.map)
%     ************************************************

   character
    Inskey    = '!03!',  Rightkey = '!04!', Leftkey   = '!05!',
    Rubout    = '!08!',  Tabkey   = '!09!', Lfkey     = '!10!', 
    Downkey   = '!14!',  Homekey  = '!15!', Delkey    ='!127!',
    Endkey    = '!26!',  Esckey   = '!27!', Upkey     = '!28!',
    Backtab   = '!29!',  PgUpkey  = '!30!', PgDnkey   = '!31!',
    Crkey     = '!13!',  /* Crkey is Enter. */

    Funckey   = '!01!';  !value for all other special keys;

%  ************************************************************************
%  2. Function key definitions (lastkey.fkey)
%     ************************

   integer
    F1  =  112, 
    F2  =  113, 
    F3  =  114, 
    F4  =  115, 
    F5  =  116, 
    F6  =  117, 
    F7  =  118, 
    F8  =  119, 
    F9  =  120, 
    F10 =  121, 
    F11 =  122, 
    F12 =  123, 

    fkHome     = 36,    fkUp       = 38,   fkDel       = 46,
    fkLeft     = 37,    fkPgUp     = 33,   fkRight     = 39, 
    fkEnd      = 35,    fkDown     = 40,   fkPgDn      = 34,
    fkIns      = 45;

%  ************************************************************************
%  2. Controll keys (lastkey.c0 lastkey.c1)
%     *************            

   /* use method: eg.: isSet (lastKey.c0, LEFT_CTRL_PRESSED) */

   integer /* lastkey.c0 */
    CAPSLOCK_ON         = (128),
    LEFT_ALT_PRESSED	= (2)  ,
    LEFT_CTRL_PRESSED	= (8)  ,
    NUMLOCK_ON	        = (32) ,
    RIGHT_ALT_PRESSED	= (1)  ,
    RIGHT_CTRL_PRESSED	= (4)  ,
    SCROLLLOCK_ON	= (64) ,
    SHIFT_PRESSED	= (16) ;

   integer /* lastkey.c1 */
    ENHANCED_KEY	= (1);

%  ************************************************************************
%  3. Input facilities
%     ****************
 
   class keyPkt; begin
      character map;         ! mapped input character;
      character chr;         ! unmapped character;
      short integer fKey;    ! function key code;
      character c0, c1, c2;  ! OS-dependent contents;
      integer x, y;          ! mouse position (for mouse event);
   end;

   ref(keyPkt) lastKey;

%  ************************************************************************
%  3. Mouse methods
%     *************
   /* Initiate mouse using setMouse (true)                   */
   /* You can read mouse events using methods inchar, ifchar */
   /* and recognize mouse event using the method wasMouse    */

   boolean procedure wasMouse;
     wasMouse := (lastKey.chr = '!0!' and lastKey.map = '!1!');

   integer  /* lastkey.fkey */
     mouseClick       = 256, /* press or release button */
     mouseMove        = 257, /* mouse move */
     mouseDoubleClick = 258; /* second click was recognized as double click */

   integer /* lastkey.c2    */ 
     /* if the bit is set, the button is pressed */
     /* I suggest to use terminal-method: isSet (lastKey.c2, XXXXXX_BUTTON) */

     FROM_LEFT_1ST_BUTTON = 1,
     RIGHTMOST_BUTTON     = 2,
     FROM_LEFT_2ND_BUTTON = 4,
     FROM_LEFT_3RD_BUTTON = 8,
     FROM_LEFT_4TH_BUTTON = 16;
   /*...                  = ... */

   /* this method initiate and hide mouse */
   external C procedure setMouse is    
   procedure setMouse (on); boolean on;;
  
%  ************************************************************************
%  3. library procedures
%     ******************

      character procedure ifchar;
      begin KEYIN(false,lastKey); ifchar:= lastKey.map end;

      character procedure inchar;
      begin KEYIN(true, lastKey); inchar:= lastKey.map end;

      character procedure inchar_;
      begin KEYIN(true, lastKey); inchar_:= lastKey.map end;

      external C procedure KEYIN is
      procedure KEYIN(wait, pkt); value wait; 
                                  boolean wait; ref(keyPkt) pkt;;
      !*** KEYIN should be specified hidden protected ***;

      external C procedure flushInput = "EFlushInput" is
      procedure flushInput;;

      external C procedure listenControllKeys="ElistenControllKeys" is
      procedure listenControllKeys (enable); boolean enable;;

      external C procedure listenReleaseKeys="ElistenReleaseKeys" is
      procedure listenReleaseKeys (enable); boolean enable;;

      external C procedure setInsert is
      procedure setInsert (on); boolean on;;

%  end of KEYBOARD.INS
