package Ada_Store.PoST.Device.Keyboard

with Ada_Store.PoST.Input_Queue;

package Ada_Store.PoST.Device.Keyboard is

   type Instance 	is new Device.Instance with private;

   type Lock_Status 	is new Positive range 1 .. 4;
   
   function  Current_Status
     (Keyboard : in Instance)
      return Lock_Status;
    
   procedure Open
     (Keyboard : in out Instance);

   procedure Close
     (Keyboard : in out Instance);

   type Function_Key is new Positive range 1 .. 10;
   type Function_Info is
      record
	 Text_Line1 : String(1 .. 6);
	 Text_Line2 : String(1 .. 6);
	 Action     : Input_Queue.Input_Action;
      end record;
   Null_Function : constant Function_Info := ("      ", "      ", Input_Queue.Cancel);

   type Function_Key_Array is array (Function_Key) of Function_Info;

   procedure Set_Function_Keys
     (Keyboard : in out Instance;
      Keys     : in     Function_Key_Array);

   procedure Flush
     (Keyboard	 : in out Instance;
      Flush_Mode : in     Device_Mode);

   procedure Accept_Input
     (Keyboard : in out Instance;
      Input    : in     Input_Queue.Message_Ptr);
	
   Invalid_Input : exception;

private

   Max_Echo_Key : constant Natural := 20;
   Min_Echo_Key : constant Natural := 0;

   type Instance is new Device.Instance with 
      record
	 Function_Keys : Function_Key_Array        := (others => Null_Function);
	 Echo_Keys     : String(1 .. Max_Echo_Key) := (others => ' ');
	 Last_Echo_Key : Natural                   := 0;
      end record;

   procedure Echo_Char
     (Keyboard   : in out Instance;
      Char       : in     Character);

   procedure End_Echo
     (Keyboard   : in out Instance;
      Char       : in     Character);

end Ada_Store.PoST.Device.Keyboard;

with System;
with Ada.Characters.Handling;
with Ada.Strings;
with Ada.Strings.Fixed;

with Ada_Store.PoST.Device.Alarm;
with Ada_Store.PoST.Configuration;
with Ada_Store.Support.Screen;
with Ada_Store.Post.Device.Display;
package body Ada_Store.PoST.Device.Keyboard is

-- internal

   Key_Enter     : constant Character := Character'Val(13);
   Key_BackSpace : constant Character := Character'Val(8);
   Key_Extended  : constant Character := Character'Val(0);
   Key_F0        : constant Character := Character'Val(58);
   Key_F1        : constant Character := Character'Val(59);
   Key_F10       : constant Character := Character'Val(69);

   task Keyboard_Reader is
      pragma Priority(System.Priority'First);

      entry Start;
   end Keyboard_Reader;

   task body Keyboard_Reader is

      Read_Char  : Character;
      Ext_Char   : Character;
   begin
      accept Start do
	 null;
      end Start;

      loop
	 Read_Char := Support.Screen.Get;
	 case Read_Char is
	    when Key_Extended =>  
	       Ext_Char := Support.Screen.Get;
	       End_Echo(Configuration.Keyboard0, Ext_Char);
	    when Key_Enter => 
	       End_Echo(Configuration.Keyboard0, Read_Char);
	    when others =>
	       Echo_Char(Configuration.Keyboard0, Read_Char);
	 end case;
      end loop;
   end Keyboard_Reader;

-- public

   function  Current_Status
     (Keyboard : in Instance)
      return Lock_Status is
   begin
      return 1;
   end Current_Status;
   
   procedure Open
     (Keyboard : in out Instance) is
   begin
      Keyboard_Reader.Start;
   end Open;

   procedure Close
     (Keyboard : in out Instance) is
   begin
      abort Keyboard_Reader;
   end Close;

   procedure Set_Function_Keys
     (Keyboard : in out Instance;
      Keys     : in     Function_Key_Array) is
     
      Column : Support.Screen.Width;
   begin
      Keyboard.Function_Keys := Keys;

      Support.Screen.Lock_Exclusive;
      for I in Function_Key'Range loop

	 Column := Support.Screen.Width(((I - 1) * 8) + 1);
	 
	 Support.Screen.Set_Cursor((22, Column));
	 Support.Screen.Put("F" & Ada.Strings.Fixed.Trim(Function_Key'Image(I), 
							 Ada.Strings.Left));
	 Support.Screen.Set_Cursor((23, Column));
	 Support.Screen.Put(Keyboard.Function_Keys(I).Text_Line1 & " |");
	 
	 Support.Screen.Set_Cursor((24, Column));
	 Support.Screen.Put(Keyboard.Function_Keys(I).Text_Line2 & " |");
      end loop;
      Support.Screen.Unlock;

   end Set_Function_Keys;

   procedure Flush
     (Keyboard	 : in out Instance;
      Flush_Mode : in     Device_Mode) is
   begin
      null;
   end Flush;

   procedure Accept_Input
     (Keyboard : in out Instance;
      Input    : in     Input_Queue.Message_Ptr) is
   begin
      Input_Queue.Append(Input);
   end Accept_Input;

-- private

   procedure Echo_Char
     (Keyboard   : in out Instance;
      Char       : in     Character) is
   begin
      if Char = Key_BackSpace and then
	 Keyboard.Last_Echo_Key > Min_Echo_Key then

	 Keyboard.Last_Echo_Key := Keyboard.Last_Echo_Key - 1;
      else
	 if Keyboard.Last_Echo_Key = Max_Echo_Key then

	    Alarm.Sound(Configuration.Alarm0, Alarm.Error);
	 else

	    if Ada.Characters.Handling.Is_Alphanumeric(Char) or
	       Char = '-' or Char = '.' then

	       Keyboard.Last_Echo_Key := Keyboard.Last_Echo_Key + 1;
	       Keyboard.Echo_Keys(Keyboard.Last_Echo_Key) := Char;
	    else

	       Alarm.Sound(Configuration.Alarm0, Alarm.Warning);
	    end if;
	 end if;
      end if;

      Ada_Store.Post.Device.Display.Clear(Configuration.Displays(Configuration.Cashier),
		    2);
      Ada_Store.Post.Device.Display.Write(Configuration.Displays(Configuration.Cashier),
		    2,
		    Keyboard.Echo_Keys(1 .. Keyboard.Last_Echo_Key));
   end Echo_Char;
 
   procedure End_Echo
     (Keyboard   : in out Instance;
      Char       : in     Character) is

      Input : Input_Queue.Message_Ptr := new Input_Queue.Message;
      Index : Function_Key;
   begin
      case Char is
	 when Key_Enter =>
	    Input.Action := Input_Queue.Enter;
	 when Key_F1 .. Key_F10 =>
	    Index := Character'Pos(Char) - Character'Pos(Key_F0);
	    Input.Action := Keyboard.Function_Keys(Index).Action;
	 when others =>
	    Alarm.Sound(Configuration.Alarm0, Alarm.Warning);
	    Input.Action := Input_Queue.Unknown;
      end case;

      Input.Input(1 .. Keyboard.Last_Echo_Key) := 
	Keyboard.Echo_Keys(1 .. Keyboard.Last_Echo_Key);
      Input.Length := Keyboard.Last_Echo_Key;

      Accept_Input(Keyboard, Input);

      Keyboard.Last_Echo_Key := Min_Echo_Key;
   end End_Echo;

end Ada_Store.PoST.Device.Keyboard;

Contents Page

Copyright © 1996 Simon Johnston &
Addison Wesley Longman