------------------------------------------------------------------------------
--                                                                          --
--                           GNAT ncurses Binding                           --
--                                                                          --
--                        Terminal_Interface.Curses                         --
--                                                                          --
--                                 B O D Y                                  --
--                                                                          --
--  Version 00.91                                                           --
--                                                                          --
--  The ncurses Ada95 binding is copyrighted 1996 by                        --
--  Juergen Pfeifer, Email: Juergen.Pfeifer@T-Online.de                     --
--                                                                          --
--  Permission is hereby granted to reproduce and distribute this           --
--  binding by any means and for any fee, whether alone or as part          --
--  of a larger distribution, in source or in binary form, PROVIDED         --
--  this notice is included with any such distribution, and is not          --
--  removed from any of its header files. Mention of ncurses and the        --
--  author of this binding in any applications linked with it is            --
--  highly appreciated.                                                     --
--                                                                          --
--  This binding comes AS IS with no warranty, implied or expressed.        --
------------------------------------------------------------------------------
--  Version Control:
--  $Revision: 1.4 $
------------------------------------------------------------------------------
with System;

with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux;
with Interfaces.C;                  use Interfaces.C;
with Interfaces.C.Strings;          use Interfaces.C.Strings;
with Ada.Characters.Handling;       use Ada.Characters.Handling;
with Unchecked_Conversion;

package body Terminal_Interface.Curses is

   use type System.Bit_Order;

   type chtype_array is array (size_t range <>)
      of aliased Attributed_Character;
   pragma Pack (chtype_array);
   pragma Convention (C, chtype_array);

------------------------------------------------------------------------------
   procedure Key_Name (Key  : in  Real_Key_Code;
                       Name : out String)
   is
      function Keyname (K : C_Int) return chars_ptr;
      pragma Import (C, Keyname, "keyname");

      Ch : Character;
   begin
      if Key <= Character'Pos (Character'Last) then
         Ch := Character'Val (Key);
         if Is_Control (Ch) then
            Un_Control (Attributed_Character'(Ch    => Ch,
                                              Color => Color_Pair'First,
                                              Attr  => Normal_Video),
                        Name);
         elsif Is_Graphic (Ch) then
            Fill_String (Null_Ptr, Name);
            Name (Name'First) := Ch;
         else
            Fill_String (Null_Ptr, Name);
         end if;
      else
         Fill_String (Keyname (C_Int (Key)), Name);
      end if;
   end Key_Name;
------------------------------------------------------------------------------
   procedure Init_Screen
   is
      function Initscr return Window;
      pragma Import (C, Initscr, "initscr");

      W : Window;
   begin
      W := Initscr;
      if W = Null_Window then
         raise Curses_Exception;
      end if;
   end Init_Screen;

   procedure End_Windows
   is
      function Endwin return C_Int;
      pragma Import (C, Endwin, "endwin");
   begin
      if Endwin = Curses_Err then
         raise Curses_Exception;
      end if;
   end End_Windows;

   function Is_End_Window return Boolean
   is
      function Isendwin return C_Int;
      pragma Import (C, Isendwin, "isendwin");
   begin
      if Isendwin = Curses_False then
         return False;
      else
         return True;
      end if;
   end Is_End_Window;
------------------------------------------------------------------------------
   procedure Move_Cursor (Win    : in Window := Standard_Window;
                          Line   : in Line_Position;
                          Column : in Column_Position)
   is
      function Wmove (Win    : Window;
                      Line   : C_Int;
                      Column : C_Int
                     ) return C_Int;
      pragma Import (C, Wmove, "wmove");
   begin
      if Wmove (Win, C_Int (Line), C_Int (Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Move_Cursor;
------------------------------------------------------------------------------
   procedure Add (Win : in Window := Standard_Window;
                  Ch  : in Attributed_Character)
   is
      function Waddch (W  : Window;
                       Ch : C_Int) return C_Int;
      pragma Import (C, Waddch, "waddch");
   begin
      if Waddch (Win, Chtype_To_Cint (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add;

   procedure Add (Win : in Window := Standard_Window;
                  Ch  : in Character)
   is
   begin
      Add (Win,
           Attributed_Character'(Ch    => Ch,
                                 Color => Color_Pair'First,
                                 Attr  => Normal_Video));
   end Add;

   procedure Add
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Ch     : in Attributed_Character)
   is
      function mvwaddch (W  : Window;
                         Y  : C_Int;
                         X  : C_Int;
                         Ch : C_Int) return C_Int;
      pragma Import (C, mvwaddch, "mvwaddch");
   begin
      if mvwaddch (Win, C_Int (Line),
                   C_Int (Column),
                   Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add;

   procedure Add
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Ch     : in Character)
   is
   begin
      Add (Win,
           Line,
           Column,
           Attributed_Character'(Ch    => Ch,
                                 Color => Color_Pair'First,
                                 Attr  => Normal_Video));
   end Add;

   procedure Add_With_Immediate_Echo
     (Win : in Window := Standard_Window;
      Ch  : in Attributed_Character)
   is
      function Wechochar (W  : Window;
                          Ch : C_Int) return C_Int;
      pragma Import (C, Wechochar, "wechochar");
   begin
      if Wechochar (Win, Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add_With_Immediate_Echo;

   procedure Add_With_Immediate_Echo
     (Win : in Window := Standard_Window;
      Ch  : in Character)
   is
   begin
      Add_With_Immediate_Echo
        (Win,
         Attributed_Character'(Ch    => Ch,
                               Color => Color_Pair'First,
                               Attr  => Normal_Video));
   end Add_With_Immediate_Echo;
------------------------------------------------------------------------------
   function Create (Number_Of_Lines       : Line_Count;
                    Number_Of_Columns     : Column_Count;
                    First_Line_Position   : Line_Position;
                    First_Column_Position : Column_Position) return Window
   is
      function Newwin (Number_Of_Lines       : C_Int;
                       Number_Of_Columns     : C_Int;
                       First_Line_Position   : C_Int;
                       First_Column_Position : C_Int) return Window;
      pragma Import (C, Newwin, "newwin");

      W : Window;
   begin
      W := Newwin (C_Int (Number_Of_Lines),
                   C_Int (Number_Of_Columns),
                   C_Int (First_Line_Position),
                   C_Int (First_Column_Position));
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end Create;

   procedure Delete (Win : in out Window)
   is
      function Wdelwin (W : Window) return C_Int;
      pragma Import (C, Wdelwin, "delwin");
   begin
      if Wdelwin (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
      Win := Null_Window;
   end Delete;

   function Sub_Window
     (Win                   : Window := Standard_Window;
      Number_Of_Lines       : Line_Count;
      Number_Of_Columns     : Column_Count;
      First_Line_Position   : Line_Position;
      First_Column_Position : Column_Position) return Window
   is
      function Subwin
        (Win                   : Window;
         Number_Of_Lines       : C_Int;
         Number_Of_Columns     : C_Int;
         First_Line_Position   : C_Int;
         First_Column_Position : C_Int) return Window;
      pragma Import (C, Subwin, "subwin");

      W : Window;
   begin
      W := Subwin (Win,
                   C_Int (Number_Of_Lines),
                   C_Int (Number_Of_Columns),
                   C_Int (First_Line_Position),
                   C_Int (First_Column_Position));
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end Sub_Window;

   function Derived_Window
     (Win                   : Window := Standard_Window;
      Number_Of_Lines       : Line_Count;
      Number_Of_Columns     : Column_Count;
      First_Line_Position   : Line_Position;
      First_Column_Position : Column_Position) return Window
   is
      function Derwin
        (Win                   : Window;
         Number_Of_Lines       : C_Int;
         Number_Of_Columns     : C_Int;
         First_Line_Position   : C_Int;
         First_Column_Position : C_Int) return Window;
      pragma Import (C, Derwin, "derwin");

      W : Window;
   begin
      W := Derwin (Win,
                   C_Int (Number_Of_Lines),
                   C_Int (Number_Of_Columns),
                   C_Int (First_Line_Position),
                   C_Int (First_Column_Position));
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end Derived_Window;

   function Duplicate (Win : Window) return Window
   is
      function Dupwin (Win : Window) return Window;
      pragma Import (C, Dupwin, "dupwin");

      W : Window := Dupwin (Win);
   begin
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end Duplicate;

   procedure Move_Window (Win    : in Window;
                          Line   : in Line_Position;
                          Column : in Column_Position)
   is
      function Mvwin (Win    : Window;
                      Line   : C_Int;
                      Column : C_Int) return C_Int;
      pragma Import (C, Mvwin, "mvwin");
   begin
      if Mvwin (Win, C_Int (Line), C_Int (Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Move_Window;

   procedure Move_Derived_Window (Win    : in Window;
                                  Line   : in Line_Position;
                                  Column : in Column_Position)
   is
      function Mvderwin (Win    : Window;
                         Line   : C_Int;
                         Column : C_Int) return C_Int;
      pragma Import (C, Mvderwin, "mvderwin");
   begin
      if Mvderwin (Win, C_Int (Line), C_Int (Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Move_Derived_Window;

   procedure Set_Synch_Mode (Win  : in Window  := Standard_Window;
                             Mode : in Boolean := False)
   is
      function Syncok (Win  : Window;
                       Mode : C_Int) return C_Int;
      pragma Import (C, Syncok, "syncok");
   begin
      if Syncok (Win, Boolean'Pos (Mode)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Synch_Mode;
------------------------------------------------------------------------------
   procedure Add (Win : in Window := Standard_Window;
                  Str : in String;
                  Len : in Integer := -1)
   is
      type Char_Ptr is access all Interfaces.C.Char;
      function Waddnstr (Win : Window;
                         Str : Char_Ptr;
                         Len : Integer := -1) return C_Int;
      pragma Import (C, Waddnstr, "waddnstr");

      Txt    : char_array (0 .. Str'Length);
      Length : size_t;
   begin
      To_C (Str, Txt, Length);
      if Waddnstr (Win, Txt (Txt'First)'Access, Len) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add;

   procedure Add
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Str    : in String;
      Len    : in Integer := -1)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Add (Win, Str, Len);
   end Add;
------------------------------------------------------------------------------
   procedure Add
     (Win : in Window := Standard_Window;
      Str : in Attributed_String;
      Len : in Integer := -1)
   is
      type Chtype_Ptr is access all Attributed_Character;
      function Waddchnstr (Win : Window;
                           Str : Chtype_Ptr;
                           Len : Integer := -1) return C_Int;
      pragma Import (C, Waddchnstr, "waddchnstr");

      Txt : chtype_array (0 .. Str'Length);
   begin
      for Length in 1 .. size_t (Str'Length) loop
         Txt (Length - 1) := Str (Natural (Length));
      end loop;
      Txt (Str'Length) := Default_Character;
      if Waddchnstr (Win, Txt (Txt'First)'Access, Len) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add;

   procedure Add
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Str    : in Attributed_String;
      Len    : in Integer := -1)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Add (Win, Str, Len);
   end Add;
------------------------------------------------------------------------------
   procedure Border
     (Win                       : in Window := Standard_Window;
      Left_Side_Symbol          : in Attributed_Character := Default_Character;
      Right_Side_Symbol         : in Attributed_Character := Default_Character;
      Top_Side_Symbol           : in Attributed_Character := Default_Character;
      Bottom_Side_Symbol        : in Attributed_Character := Default_Character;
      Upper_Left_Corner_Symbol  : in Attributed_Character := Default_Character;
      Upper_Right_Corner_Symbol : in Attributed_Character := Default_Character;
      Lower_Left_Corner_Symbol  : in Attributed_Character := Default_Character;
      Lower_Right_Corner_Symbol : in Attributed_Character := Default_Character)
   is
      function Wborder (W   : Window;
                        LS  : C_Int;
                        RS  : C_Int;
                        TS  : C_Int;
                        BS  : C_Int;
                        ULC : C_Int;
                        URC : C_Int;
                        LLC : C_Int;
                        LRC : C_Int) return C_Int;
      pragma Import (C, Wborder, "wborder");
   begin
      if Wborder (Win,
                  Chtype_To_CInt (Left_Side_Symbol),
                  Chtype_To_CInt (Right_Side_Symbol),
                  Chtype_To_CInt (Top_Side_Symbol),
                  Chtype_To_CInt (Bottom_Side_Symbol),
                  Chtype_To_CInt (Upper_Left_Corner_Symbol),
                  Chtype_To_CInt (Upper_Right_Corner_Symbol),
                  Chtype_To_CInt (Lower_Left_Corner_Symbol),
                  Chtype_To_CInt (Lower_Right_Corner_Symbol)
                  ) = Curses_Err
      then
         raise Curses_Exception;
      end if;
   end Border;

   procedure Box
     (Win               : in Window := Standard_Window;
      Vertical_Symbol   : in Attributed_Character := Default_Character;
      Horizontal_Symbol : in Attributed_Character := Default_Character)
   is
   begin
      Border (Win,
              Vertical_Symbol, Vertical_Symbol,
              Horizontal_Symbol, Horizontal_Symbol);
   end Box;

   procedure Horizontal_Line
     (Win         : in Window := Standard_Window;
      Line_Size   : in Natural;
      Line_Symbol : in Attributed_Character := Default_Character)
   is
      function Whline (W   : Window;
                       Ch  : C_Int;
                       Len : C_Int) return C_Int;
      pragma Import (C, Whline, "whline");
   begin
      if Whline (Win,
                 Chtype_To_CInt (Line_Symbol),
                 C_Int (Line_Size)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Horizontal_Line;

   procedure Vertical_Line
     (Win         : in Window := Standard_Window;
      Line_Size   : in Natural;
      Line_Symbol : in Attributed_Character := Default_Character)
   is
      function Wvline (W   : Window;
                       Ch  : C_Int;
                       Len : C_Int) return C_Int;
      pragma Import (C, Wvline, "wvline");
   begin
      if Wvline (Win,
                 Chtype_To_CInt (Line_Symbol),
                 C_Int (Line_Size)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Vertical_Line;

------------------------------------------------------------------------------
   function Get_Keystroke (Win : Window := Standard_Window)
     return Real_Key_Code
   is
      function Wgetch (W : Window) return C_Int;
      pragma Import (C, Wgetch, "wgetch");

      C : constant C_Int := Wgetch (Win);
   begin
      if C = Curses_Err then
         return Key_None;
      else
         return Real_Key_Code (C);
      end if;
   end Get_Keystroke;

   procedure Undo_Keystroke (Key : in Real_Key_Code)
   is
      function Ungetch (Ch : C_Int) return C_Int;
      pragma Import (C, Ungetch, "ungetch");
   begin
      if Ungetch (C_Int (Key)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Undo_Keystroke;

   function Has_Key (Key : Special_Key_Code) return Boolean
   is
      function Haskey (Key : C_Int) return C_Int;
      pragma Import (C, Haskey, "has_key");
   begin
      if Haskey (C_Int (Key)) = Curses_False then
         return False;
      else
         return True;
      end if;
   end Has_Key;

   function Is_Function_Key (Key : Special_Key_Code) return Boolean
   is
      L : constant Special_Key_Code  := Special_Key_Code (Natural (Key_F0) +
        Natural (Function_Key_Number'Last));
   begin
      if (Key >= Key_F0) and then (Key <= L) then
         return True;
      else
         return False;
      end if;
   end Is_Function_Key;

   function Function_Key (Key : Real_Key_Code)
                          return Function_Key_Number
   is
   begin
      if Is_Function_Key (Key) then
         return Function_Key_Number (Key - Key_F0);
      else
         raise Constraint_Error;
      end if;
   end Function_Key;

   function Function_Key_Code (Key : Function_Key_Number) return Real_Key_Code
   is
   begin
      return Real_Key_Code (Natural (Key_F0) + Natural (Key));
   end Function_Key_Code;
------------------------------------------------------------------------------
   procedure Switch_Character_Attribute
     (Win  : in Window := Standard_Window;
      Attr : in Character_Attribute_Set := Normal_Video;
      On   : in Boolean := True)
   is
      function Wattron (Win    : Window;
                        C_Attr : C_Int) return C_Int;
      pragma Import (C, Wattron, "wattr_on");
      function Wattroff (Win    : Window;
                         C_Attr : C_Int) return C_Int;
      pragma Import (C, Wattroff, "wattr_off");
      --  In Ada we use the On Boolean to control whether or not we want to
      --  switch on or off the attributes in the set.
      Err : C_Int;
      AC  : constant Attributed_Character := (Ch    => Character'First,
                                              Color => Color_Pair'First,
                                              Attr  => Attr);
   begin
      if On then
         Err := Wattron (Win, Chtype_To_CInt (AC));
      else
         Err := Wattroff (Win, Chtype_To_CInt (AC));
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Switch_Character_Attribute;

   procedure Set_Character_Attributes
     (Win   : in Window := Standard_Window;
      Attr  : in Character_Attribute_Set := Normal_Video;
      Color : in Color_Pair := Color_Pair'First)
   is
      function Wattrset (Win    : Window;
                         C_Attr : C_Int) return C_Int;
      pragma Import (C, Wattrset, "wattrset"); -- ??? wattr_set
   begin
      if Wattrset (Win,
                   Chtype_To_CInt (Attributed_Character'
                                   (Ch    => Character'First,
                                    Color => Color,
                                    Attr  => Attr))) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Character_Attributes;

   function Get_Character_Attribute (Win : Window := Standard_Window)
                                     return Character_Attribute_Set
   is
      function Wattrget (Win : Window) return C_Int;
      pragma Import (C, Wattrget, "wattr_get");

      Ch : Attributed_Character := CInt_To_Chtype (Wattrget (Win));
   begin
      return Ch.Attr;
   end Get_Character_Attribute;

   function Get_Character_Attribute (Win : Window := Standard_Window)
                                     return Color_Pair
   is
      function Wattrget (Win : Window) return C_Int;
      pragma Import (C, Wattrget, "wattr_get");

      Ch : Attributed_Character := CInt_To_Chtype (Wattrget (Win));
   begin
      return Ch.Color;
   end Get_Character_Attribute;

   procedure Change_Attributes
     (Win   : in Window := Standard_Window;
      Count : in Integer := -1;
      Attr  : in Character_Attribute_Set := Normal_Video;
      Color : in Color_Pair := Color_Pair'First)
   is
      function Wchgat (Win   : Window;
                       Cnt   : C_Int;
                       Attr  : C_Int;
                       Color : C_Short;
                       Opts  : System.Address := System.Null_Address)
                       return C_Int;
      pragma Import (C, Wchgat, "wchgat");

      Ch : constant Attributed_Character :=
        (Ch => Character'First, Color => Color_Pair'First, Attr => Attr);
   begin
      if Wchgat (Win, C_Int (Count), Chtype_To_CInt (Ch),
                 C_Short (Color)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Change_Attributes;

   procedure Change_Attributes
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position := Line_Position'First;
      Column : in Column_Position := Column_Position'First;
      Count  : in Integer := -1;
      Attr   : in Character_Attribute_Set := Normal_Video;
      Color  : in Color_Pair := Color_Pair'First)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Change_Attributes (Win, Count, Attr, Color);
   end Change_Attributes;
------------------------------------------------------------------------------
   procedure Beep
   is
      function Beeper return C_Int;
      pragma Import (C, Beeper, "beep");
   begin
      if Beeper = Curses_Err then
         raise Curses_Exception;
      end if;
   end Beep;

   procedure Flash_Screen
   is
      function Flash return C_Int;
      pragma Import (C, Flash, "flash");
   begin
      if Flash = Curses_Err then
         raise Curses_Exception;
      end if;
   end Flash_Screen;
------------------------------------------------------------------------------
   procedure Set_Cbreak_Mode (SwitchOn : in Boolean := True)
   is
      function Cbreak return C_Int;
      pragma Import (C, Cbreak, "cbreak");
      function NoCbreak return C_Int;
      pragma Import (C, NoCbreak, "nocbreak");

      Err : C_Int;
   begin
      if SwitchOn then
         Err := Cbreak;
      else
         Err := NoCbreak;
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Cbreak_Mode;

   procedure Set_Raw_Mode (SwitchOn : in Boolean := True)
   is
      function Raw return C_Int;
      pragma Import (C, Raw, "raw");
      function NoRaw return C_Int;
      pragma Import (C, NoRaw, "noraw");

      Err : C_Int;
   begin
      if SwitchOn then
         Err := Raw;
      else
         Err := NoRaw;
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Raw_Mode;

   procedure Set_Echo_Mode (SwitchOn : in Boolean := True)
   is
      function Echo return C_Int;
      pragma Import (C, Echo, "echo");
      function NoEcho return C_Int;
      pragma Import (C, NoEcho, "noecho");

      Err : C_Int;
   begin
      if SwitchOn then
         Err := Echo;
      else
         Err := NoEcho;
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Echo_Mode;

   procedure Set_Meta_Mode (Win      : in Window := Standard_Window;
                            SwitchOn : in Boolean := True)
   is
      function Meta (W : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Meta, "meta");
   begin
      if Meta (Win, Boolean'Pos (SwitchOn)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Meta_Mode;

   procedure Set_KeyPad_Mode (Win      : in Window := Standard_Window;
                              SwitchOn : in Boolean := True)
   is
      function Keypad (W : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Keypad, "keypad");
   begin
      if Keypad (Win, Boolean'Pos (SwitchOn)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_KeyPad_Mode;

   procedure Half_Delay (Amount : in Half_Delay_Amount)
   is
      function Halfdelay (Amount : C_Int) return C_Int;
      pragma Import (C, Halfdelay, "halfdelay");
   begin
      if Halfdelay (C_Int (Amount)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Half_Delay;

   procedure Set_Flush_On_Interrupt_Mode
     (Win  : in Window := Standard_Window;
      Mode : in Boolean := True)
   is
      function Intrflush (Win : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Intrflush, "intrflush");
   begin
      if Intrflush (Win, Boolean'Pos (Mode)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Flush_On_Interrupt_Mode;

   procedure Set_Queue_Interrupt_Mode
     (Win   : in Window := Standard_Window;
      Flush : in Boolean := True)
   is
      procedure Qiflush;
      pragma Import (C, Qiflush, "qiflush");
      procedure No_Qiflush;
      pragma Import (C, No_Qiflush, "noqiflush");
   begin
      if Flush then
         Qiflush;
      else
         No_Qiflush;
      end if;
   end Set_Queue_Interrupt_Mode;

   procedure Set_NoDelay_Mode
     (Win  : in Window := Standard_Window;
      Mode : in Boolean := False)
   is
      function Nodelay (Win : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Nodelay, "nodelay");
   begin
      if Nodelay (Win, Boolean'Pos (Mode)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_NoDelay_Mode;

   procedure Set_Timeout_Mode (Win    : in Window := Standard_Window;
                               Mode   : in Timeout_Mode;
                               Amount : in Natural)
   is
      function Wtimeout (Win : Window; Amount : C_Int) return C_Int;
      pragma Import (C, Wtimeout, "wtimeout");

      Time : C_Int;
   begin
      case Mode is
         when Blocking     => Time := -1;
         when Non_Blocking => Time := 0;
         when Delayed      =>
            if Amount = 0 then
               raise CONSTRAINT_ERROR;
            end if;
            Time := C_Int (Amount);
      end case;
      if Wtimeout (Win, Time) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Timeout_Mode;

   procedure Set_Escape_Timer_Mode
     (Win       : in Window := Standard_Window;
      Timer_Off : in Boolean := False)
   is
      function Notimeout (Win : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Notimeout, "notimeout");
   begin
      if Notimeout (Win, Boolean'Pos (Timer_Off)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Escape_Timer_Mode;

------------------------------------------------------------------------------
   procedure Set_NL_Mode (SwitchOn : in Boolean := True)
   is
      function NL return C_Int;
      pragma Import (C, NL, "nl");
      function NoNL return C_Int;
      pragma Import (C, NoNL, "nonl");

      Err : C_Int;
   begin
      if SwitchOn then
         Err := NL;
      else
         Err := NoNL;
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_NL_Mode;

   procedure Clear_On_Next_Update
     (Win      : in Window := Standard_Window;
      Do_Clear : in Boolean := True)
   is
      function Clear_Ok (W : Window; Flag : C_Int) return C_Int;
      pragma Import (C, Clear_Ok, "clearok");
   begin
      if Clear_Ok (Win, Boolean'Pos (Do_Clear)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Clear_On_Next_Update;

   procedure Use_Insert_Delete_Line
     (Win    : in Window := Standard_Window;
      Do_Idl : in Boolean := True)
   is
      function IDL_Ok (W : Window; Flag : C_Int) return C_Int;
      pragma Import (C, IDL_Ok, "idlok");
   begin
      if IDL_Ok (Win, Boolean'Pos (Do_Idl)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Use_Insert_Delete_Line;

   procedure Use_Insert_Delete_Character
     (Win    : in Window := Standard_Window;
      Do_Idc : in Boolean := True)
   is
      function IDC_Ok (W : Window; Flag : C_Int) return C_Int;
      pragma Import (C, IDC_Ok, "idcok");
   begin
      if IDC_Ok (Win, Boolean'Pos (Do_Idc)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Use_Insert_Delete_Character;

   procedure Leave_Cursor_After_Update
     (Win      : in Window := Standard_Window;
      Do_Leave : in Boolean := True)
   is
      function Leave_Ok (W : Window; Flag : C_Int) return C_Int;
      pragma Import (C, Leave_Ok, "leaveok");
   begin
      if Leave_Ok (Win, Boolean'Pos (Do_Leave)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Leave_Cursor_After_Update;

   procedure Immediate_Update_Mode
     (Win  : in Window := Standard_Window;
      Mode : in Boolean := False)
   is
      function Immedok (Win : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Immedok, "immedok");
   begin
      if Immedok (Win, Boolean'Pos (Mode)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Immediate_Update_Mode;

   procedure Allow_Scrolling
     (Win  : in Window  := Standard_Window;
      Mode : in Boolean := False)
   is
      function Scrollok (Win : Window; Mode : C_Int) return C_Int;
      pragma Import (C, Scrollok, "scrollok");
   begin
      if Scrollok (Win, Boolean'Pos (Mode)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Allow_Scrolling;

   function Scrolling_Allowed (Win : Window := Standard_Window) return Boolean
   is
      function Is_Scroll (Win : Window) return C_Int;
      pragma Import (C, Is_Scroll, "_nc_ada_isscroll");

      Res : constant C_Int := Is_Scroll (Win);
   begin
      case Res is
         when Curses_True  => return True;
         when Curses_False => return False;
         when others       => raise Curses_Exception;
      end case;
   end Scrolling_Allowed;

   procedure Set_Scroll_Region
     (Win         : in Window := Standard_Window;
      Top_Line    : in Line_Position;
      Bottom_Line : in Line_Position)
   is
      function Wsetscrreg (Win : Window;
                           Lin : C_Int;
                           Col : C_Int) return C_Int;
      pragma Import (C, Wsetscrreg, "wsetscrreg");
   begin
      if Wsetscrreg (Win, C_Int (Top_Line), C_Int (Bottom_Line))
        = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Scroll_Region;
------------------------------------------------------------------------------
   procedure Update_Screen
   is
      function Do_Update return C_Int;
      pragma Import (C, Do_Update, "doupdate");
   begin
      if Do_Update = Curses_Err then
         raise Curses_Exception;
      end if;
   end Update_Screen;

   procedure Refresh (Win : in Window := Standard_Window)
   is
      function Wrefresh (W : Window) return C_Int;
      pragma Import (C, Wrefresh, "wrefresh");
   begin
      if Wrefresh (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh;

   procedure Refresh_Without_Update
     (Win : in Window := Standard_Window)
   is
      function Wnoutrefresh (W : Window) return C_Int;
      pragma Import (C, Wnoutrefresh, "wnoutrefresh");
   begin
      if Wnoutrefresh (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh_Without_Update;

   procedure Redraw (Win : in Window := Standard_Window)
   is
      function Redrawwin (Win : Window) return C_Int;
      pragma Import (C, Redrawwin, "redrawwin");
   begin
      if Redrawwin (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Redraw;

   procedure Redraw
     (Win        : in Window := Standard_Window;
      Begin_Line : in Line_Position;
      Line_Count : in Positive)
   is
      function Wredrawln (Win : Window; First : C_Int; Cnt : C_Int)
                          return C_Int;
      pragma Import (C, Wredrawln, "wredrawln");
   begin
      if Wredrawln (Win,
                    C_Int (Begin_Line),
                    C_Int (Line_Count)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Redraw;

------------------------------------------------------------------------------
   procedure Erase (Win : in Window := Standard_Window)
   is
      function Werase (W : Window) return C_Int;
      pragma Import (C, Werase, "werase");
   begin
      if Werase (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Erase;

   procedure Clear (Win : in Window := Standard_Window)
   is
      function Wclear (W : Window) return C_Int;
      pragma Import (C, Wclear, "wclear");
   begin
      if Wclear (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Clear;

   procedure Clear_To_End_Of_Screen (Win : in Window := Standard_Window)
   is
      function Wclearbot (W : Window) return C_Int;
      pragma Import (C, Wclearbot, "wclrtobot");
   begin
      if Wclearbot (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Clear_To_End_Of_Screen;

   procedure Clear_To_End_Of_Line (Win : in Window := Standard_Window)
   is
      function Wcleareol (W : Window) return C_Int;
      pragma Import (C, Wcleareol, "wclrtoeol");
   begin
      if Wcleareol (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Clear_To_End_Of_Line;
------------------------------------------------------------------------------
   procedure Set_Background
     (Win : in Window := Standard_Window;
      Ch  : in Attributed_Character)
   is
      procedure WBackground (W : in Window; Ch : in C_Int);
      pragma Import (C, WBackground, "wbkgdset");
   begin
      WBackground (Win, Chtype_To_CInt (Ch));
   end Set_Background;

   procedure Change_Background
     (Win : in Window := Standard_Window;
      Ch  : in Attributed_Character)
   is
      function WChangeBkgd (W : Window; Ch : C_Int)
                            return C_Int;
      pragma Import (C, WChangeBkgd, "wbkgd");
   begin
      if WChangeBkgd (Win, Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Change_Background;

   function Get_Background (Win : Window := Standard_Window)
     return Attributed_Character
   is
      function Wgetbkgd (Win : Window) return C_Int;
      pragma Import (C, Wgetbkgd, "getbkgd");
   begin
      return CInt_To_Chtype (Wgetbkgd (Win));
   end Get_Background;
------------------------------------------------------------------------------
   procedure Change_Lines_Status (Win   : in Window := Standard_Window;
                                  Start : in Line_Position;
                                  Count : in Positive;
                                  State : in Boolean)
   is
      function Wtouchln (Win : Window;
                         Sta : C_Int;
                         Cnt : C_Int;
                         Chg : C_Int) return C_Int;
      pragma Import (C, Wtouchln, "wtouchln");
   begin
      if Wtouchln (Win, C_Int (Start), C_Int (Count),
                   C_Int (Boolean'Pos (State))) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Change_Lines_Status;

   procedure Touch (Win : in Window := Standard_Window)
   is
      Y : Line_Position;
      X : Column_Position;
   begin
      Get_Size (Win, Y, X);
      Change_Lines_Status (Win, 0, Positive (Y), True);
   end Touch;

   procedure Untouch (Win : in Window := Standard_Window)
   is
      Y : Line_Position;
      X : Column_Position;
   begin
      Get_Size (Win, Y, X);
      Change_Lines_Status (Win, 0, Positive (Y), False);
   end Untouch;

   procedure Touch (Win   : in Window := Standard_Window;
                    Start : in Line_Position;
                    Count : in Positive)
   is
   begin
      Change_Lines_Status (Win, Start, Count, True);
   end Touch;

   function Is_Touched
     (Win  : Window := Standard_Window;
      Line : Line_Position) return Boolean
   is
      function WLineTouched (W : Window; L : C_Int) return C_Int;
      pragma Import (C, WLineTouched, "is_linetouched");
   begin
      if WLineTouched (Win, C_Int (Line)) = Curses_False then
         return False;
      else
         return True;
      end if;
   end Is_Touched;

   function Is_Touched
     (Win : Window := Standard_Window) return Boolean
   is
      function WWinTouched (W : Window) return C_Int;
      pragma Import (C, WWinTouched, "is_wintouched");
   begin
      if WWinTouched (Win) = Curses_False then
         return False;
      else
         return True;
      end if;
   end Is_Touched;
------------------------------------------------------------------------------
   procedure Copy
     (Source_Window            : in Window;
      Destination_Window       : in Window;
      Source_Top_Row           : in Line_Position;
      Source_Left_Column       : in Column_Position;
      Destination_Top_Row      : in Line_Position;
      Destination_Left_Column  : in Column_Position;
      Destination_Bottom_Row   : in Line_Position;
      Destination_Right_Column : in Column_Position;
      Non_Destructive_Mode     : in Boolean := True)
   is
      function Copywin (Src : Window;
                        Dst : Window;
                        Str : C_Int;
                        Slc : C_Int;
                        Dtr : C_Int;
                        Dlc : C_Int;
                        Dbr : C_Int;
                        Drc : C_Int;
                        Ndm : C_Int) return C_Int;
      pragma Import (C, Copywin, "copywin");
   begin
      if Copywin (Source_Window,
                  Destination_Window,
                  C_Int (Source_Top_Row),
                  C_Int (Source_Left_Column),
                  C_Int (Destination_Top_Row),
                  C_Int (Destination_Left_Column),
                  C_Int (Destination_Bottom_Row),
                  C_Int (Destination_Right_Column),
                  Boolean'Pos (Non_Destructive_Mode)
                ) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Copy;

   procedure Overwrite
     (Source_Window      : in Window;
      Destination_Window : in Window)
   is
      function Overwrite (Src : Window; Dst : Window) return C_Int;
      pragma Import (C, Overwrite, "overwrite");
   begin
      if Overwrite (Source_Window, Destination_Window) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Overwrite;

   procedure Overlay
     (Source_Window      : in Window;
      Destination_Window : in Window)
   is
      function Overlay (Src : Window; Dst : Window) return C_Int;
      pragma Import (C, Overlay, "overlay");
   begin
      if Overlay (Source_Window, Destination_Window) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Overlay;

------------------------------------------------------------------------------
   procedure Insert_Delete_Lines
     (Win   : in Window := Standard_Window;
      Lines : in Integer       := 1) -- default is to insert one line above
   is
      function Winsdelln (W : Window; N : C_Int) return C_Int;
      pragma Import (C, Winsdelln, "winsdelln");
   begin
      if Winsdelln (Win, C_Int (Lines)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Insert_Delete_Lines;

   procedure Delete_Line (Win : in Window := Standard_Window)
   is
   begin
      Insert_Delete_Lines (Win, -1);
   end Delete_Line;

   procedure Insert_Line (Win : in Window := Standard_Window)
   is
   begin
      Insert_Delete_Lines (Win, 1);
   end Insert_Line;
------------------------------------------------------------------------------
   procedure Get_Size
     (Win               : in Window := Standard_Window;
      Number_Of_Lines   : out Line_Count;
      Number_Of_Columns : out Column_Count)
   is
      type Int_Access is access all C_Int;
      function Getmaxyx (W : Window; Y, X : Int_Access) return C_Int;
      pragma Import (C, Getmaxyx, "_nc_ada_getmaxyx");

      Y, X : aliased C_Int;
      Err  : constant C_Int := Getmaxyx (Win, Y'Access, X'Access);
   begin
      if Err = Curses_Err then
         raise Curses_Exception;
      else
         Number_Of_Lines   := Line_Count (Y);
         Number_Of_Columns := Column_Count (X);
      end if;
   end Get_Size;

   procedure Get_Window_Position
     (Win             : in Window := Standard_Window;
      Top_Left_Line   : out Line_Position;
      Top_Left_Column : out Column_Position)
   is
      type Int_Access is access all C_Int;
      function Getbegyx (W : Window; Y, X : Int_Access) return C_Int;
      pragma Import (C, Getbegyx, "_nc_ada_getbegyx");

      Y, X : aliased C_Int;
      Err  : constant C_Int := Getbegyx (Win, Y'Access, X'Access);
   begin
      if Err = Curses_Err then
         raise Curses_Exception;
      else
         Top_Left_Line   := Line_Position (Y);
         Top_Left_Column := Column_Position (X);
      end if;
   end Get_Window_Position;

   procedure Get_Cursor_Position
     (Win    : in  Window := Standard_Window;
      Line   : out Line_Position;
      Column : out Column_Position)
   is
      type Int_Access is access all C_Int;
      function Getyx (W : Window; Y, X : Int_Access) return C_Int;
      pragma Import (C, Getyx, "_nc_ada_getyx");

      Y, X : aliased C_Int;
      Err  : constant C_Int := Getyx (Win, Y'Access, X'Access);
   begin
      if Err = Curses_Err then
         raise Curses_Exception;
      else
         Line   := Line_Position (Y);
         Column := Column_Position (X);
      end if;
   end Get_Cursor_Position;

   procedure Get_Origin_Relative_To_Parent
     (Win                : in  Window;
      Top_Left_Line      : out Line_Position;
      Top_Left_Column    : out Column_Position;
      Is_Not_A_Subwindow : out Boolean)
   is
      type Int_Access is access all C_Int;
      function Getparyx (W : Window; Y, X : Int_Access) return C_Int;
      pragma Import (C, Getparyx, "_nc_ada_getparyx");

      Y, X : aliased C_Int;
      Err  : constant C_Int := Getparyx (Win, Y'Access, X'Access);
   begin
      if Err = Curses_Err then
         raise Curses_Exception;
      else
         if Y = -1 then
            Top_Left_Line   := Line_Position'Last;
            Top_Left_Column := Column_Position'Last;
            Is_Not_A_Subwindow := True;
         else
            Top_Left_Line   := Line_Position (Y);
            Top_Left_Column := Column_Position (X);
            Is_Not_A_Subwindow := False;
         end if;
      end if;
   end Get_Origin_Relative_To_Parent;
------------------------------------------------------------------------------
   function New_Pad (Lines   : Line_Count;
                     Columns : Column_Count) return Window
   is
      function Newpad (Lines : C_Int; Columns : C_Int) return Window;
      pragma Import (C, Newpad, "newpad");

      W : Window;
   begin
      W := Newpad (C_Int (Lines), C_Int (Columns));
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end New_Pad;

   function Sub_Pad
     (Pad                   : Window;
      Number_Of_Lines       : Line_Count;
      Number_Of_Columns     : Column_Count;
      First_Line_Position   : Line_Position;
      First_Column_Position : Column_Position) return Window
   is
      function Subpad
        (Pad                   : Window;
         Number_Of_Lines       : C_Int;
         Number_Of_Columns     : C_Int;
         First_Line_Position   : C_Int;
         First_Column_Position : C_Int) return Window;
      pragma Import (C, Subpad, "subpad");

      W : Window;
   begin
      W := Subpad (Pad,
                   C_Int (Number_Of_Lines),
                   C_Int (Number_Of_Columns),
                   C_Int (First_Line_Position),
                   C_Int (First_Column_Position));
      if W = Null_Window then
         raise Curses_Exception;
      end if;
      return W;
   end Sub_Pad;

   procedure Refresh
     (Pad                      : in Window;
      Source_Top_Row           : in Line_Position;
      Source_Left_Column       : in Column_Position;
      Destination_Top_Row      : in Line_Position;
      Destination_Left_Column  : in Column_Position;
      Destination_Bottom_Row   : in Line_Position;
      Destination_Right_Column : in Column_Position)
   is
      function Prefresh
        (Pad                      : Window;
         Source_Top_Row           : C_Int;
         Source_Left_Column       : C_Int;
         Destination_Top_Row      : C_Int;
         Destination_Left_Column  : C_Int;
         Destination_Bottom_Row   : C_Int;
         Destination_Right_Column : C_Int) return C_Int;
      pragma Import (C, Prefresh, "prefresh");
   begin
      if Prefresh (Pad,
                   C_Int (Source_Top_Row),
                   C_Int (Source_Left_Column),
                   C_Int (Destination_Top_Row),
                   C_Int (Destination_Left_Column),
                   C_Int (Destination_Bottom_Row),
                   C_Int (Destination_Right_Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh;

   procedure Refresh_Without_Update
     (Pad                      : in Window;
      Source_Top_Row           : in Line_Position;
      Source_Left_Column       : in Column_Position;
      Destination_Top_Row      : in Line_Position;
      Destination_Left_Column  : in Column_Position;
      Destination_Bottom_Row   : in Line_Position;
      Destination_Right_Column : in Column_Position)
   is
      function Pnoutrefresh
        (Pad                      : Window;
         Source_Top_Row           : C_Int;
         Source_Left_Column       : C_Int;
         Destination_Top_Row      : C_Int;
         Destination_Left_Column  : C_Int;
         Destination_Bottom_Row   : C_Int;
         Destination_Right_Column : C_Int) return C_Int;
      pragma Import (C, Pnoutrefresh, "pnoutrefresh");
   begin
      if Pnoutrefresh (Pad,
                       C_Int (Source_Top_Row),
                       C_Int (Source_Left_Column),
                       C_Int (Destination_Top_Row),
                       C_Int (Destination_Left_Column),
                       C_Int (Destination_Bottom_Row),
                       C_Int (Destination_Right_Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh_Without_Update;

   procedure Add_Character_To_Pad_And_Echo_It
     (Pad : in Window;
      Ch  : in Attributed_Character)
   is
      function Pechochar (Pad : Window; Ch : C_Int)
                          return C_Int;
      pragma Import (C, Pechochar, "pechochar");
   begin
      if Pechochar (Pad, Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Add_Character_To_Pad_And_Echo_It;

   procedure Add_Character_To_Pad_And_Echo_It
     (Pad : in Window;
      Ch  : in Character)
   is
   begin
      Add_Character_To_Pad_And_Echo_It
        (Pad,
         Attributed_Character'(Ch    => Ch,
                               Color => Color_Pair'First,
                               Attr  => Normal_Video));
   end Add_Character_To_Pad_And_Echo_It;
------------------------------------------------------------------------------
   procedure Scroll (Win    : in Window := Standard_Window;
                     Amount : in Integer := 1)
   is
      function Wscrl (Win : Window; N : C_Int) return C_Int;
      pragma Import (C, Wscrl, "wscrl");

   begin
      if Wscrl (Win, C_Int (Amount)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Scroll;

------------------------------------------------------------------------------
   procedure Delete_Character (Win : in Window := Standard_Window)
   is
      function Wdelch (Win : Window) return C_Int;
      pragma Import (C, Wdelch, "wdelch");
   begin
      if Wdelch (Win) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Delete_Character;

   procedure Delete_Character
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position)
   is
      function Mvwdelch (Win : Window;
                         Lin : C_Int;
                         Col : C_Int) return C_Int;
      pragma Import (C, Mvwdelch, "mvwdelch");
   begin
      if Mvwdelch (Win, C_Int (Line), C_Int (Column)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Delete_Character;
------------------------------------------------------------------------------
   function Peek (Win : Window := Standard_Window)
     return Attributed_Character
   is
      function Winch (Win : Window) return C_Int;
      pragma Import (C, Winch, "winch");
   begin
      return CInt_To_Chtype (Winch (Win));
   end Peek;

   function Peek
     (Win    : Window := Standard_Window;
      Line   : Line_Position;
      Column : Column_Position) return Attributed_Character
   is
      function Mvwinch (Win : Window;
                        Lin : C_Int;
                        Col : C_Int) return C_Int;
      pragma Import (C, Mvwinch, "mvwinch");
   begin
      return CInt_To_Chtype (Mvwinch (Win, C_Int (Line), C_Int (Column)));
   end Peek;
------------------------------------------------------------------------------
   procedure Insert (Win : in Window := Standard_Window;
                     Ch  : in Attributed_Character)
   is
      function Winsch (Win : Window; Ch : C_Int) return C_Int;
      pragma Import (C, Winsch, "winsch");
   begin
      if Winsch (Win, Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Insert;

   procedure Insert
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Ch     : in Attributed_Character)
   is
      function Mvwinsch (Win : Window;
                         Lin : C_Int;
                         Col : C_Int;
                         Ch  : C_Int) return C_Int;
      pragma Import (C, Mvwinsch, "mvwinsch");
   begin
      if Mvwinsch (Win,
                   C_Int (Line),
                   C_Int (Column),
                   Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Insert;
------------------------------------------------------------------------------
   procedure Insert (Win : in Window := Standard_Window;
                     Str : in String;
                     Len : in Integer := -1)
   is
      type Char_Ptr is access all Interfaces.C.Char;
      function Winsnstr (Win : Window;
                         Str : Char_Ptr;
                         Len : Integer := -1) return C_Int;
      pragma Import (C, Winsnstr, "winsnstr");

      Txt    : char_array (0 .. Str'Length);
      Length : size_t;
   begin
      To_C (Str, Txt, Length);
      if Winsnstr (Win, Txt (Txt'First)'Access, Len) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Insert;

   procedure Insert
     (Win    : in Window := Standard_Window;
      Line   : in Line_Position;
      Column : in Column_Position;
      Str    : in String;
      Len    : in Integer := -1)
   is
      type Char_Ptr is access all Interfaces.C.Char;
      function Mvwinsnstr (Win    : Window;
                           Line   : C_Int;
                           Column : C_Int;
                           Str    : Char_Ptr;
                           Len    : C_Int) return C_Int;
      pragma Import (C, Mvwinsnstr, "mvwinsnstr");

      Txt    : char_array (0 .. Str'Length);
      Length : size_t;
   begin
      To_C (Str, Txt, Length);
      if Mvwinsnstr (Win, C_Int (Line), C_Int (Column),
                     Txt (Txt'First)'Access, C_Int (Len))
        = Curses_Err then
         raise Curses_Exception;
      end if;
   end Insert;
------------------------------------------------------------------------------
   procedure Peek (Win : in  Window := Standard_Window;
                   Str : out String;
                   Len : in  Integer := -1)
   is
      function Winnstr (Win : Window;
                        Str : char_array;
                        Len : C_Int) return C_Int;
      pragma Import (C, Winnstr, "winnstr");

      N   : Integer := Len;
      Txt : char_array (0 .. Str'Length);
      Cnt : Natural;
   begin
      if N < 0 then
         N := Str'Length;
      end if;
      if N > Str'Length then
         raise Constraint_Error;
      end if;
      Txt (0) := Interfaces.C.char'First;
      if Winnstr (Win, Txt, C_Int (N)) = Curses_Err then
         raise Curses_Exception;
      end if;
      To_Ada (Txt, Str, Cnt, True);
      if Cnt < Str'Length then
         Str ((Str'First + Cnt) .. Str'Last) := (others => ' ');
      end if;
   end Peek;

   procedure Peek
     (Win    : in  Window := Standard_Window;
      Line   : in  Line_Position;
      Column : in  Column_Position;
      Str    : out String;
      Len    : in  Integer := -1)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Peek (Win, Str, Len);
   end Peek;
------------------------------------------------------------------------------
   procedure Peek
     (Win : in  Window := Standard_Window;
      Str : out Attributed_String;
      Len : in  Integer := -1)
   is
      type Chtype_Ptr is access all Attributed_Character;
      function Winchnstr (Win : Window;
                          Str : Chtype_Ptr;
                          Len : C_Int) return C_Int;
      pragma Import (C, Winchnstr, "winchnstr");

      N   : Integer := Len;
      Txt : chtype_array (0 .. Str'Length);
      Cnt : Natural := 0;
   begin
      if N < 0 then
         N := Str'Length;
      end if;
      if N > Str'Length then
         raise Constraint_Error;
      end if;
      if Winchnstr (Win, Txt (Txt'First)'Access, C_Int (N)) = Curses_Err then
         raise Curses_Exception;
      end if;
      for To in Str'Range loop
         exit when Txt (size_t (Cnt)) = Default_Character;
         Str (To) := Txt (size_t (Cnt));
         Cnt := Cnt + 1;
      end loop;
      if Cnt < Str'Length then
         Str ((Str'First + Cnt) .. Str'Last) :=
           (others => (Ch => ' ',
                       Color => Color_Pair'First,
                       Attr => Normal_Video));
      end if;
   end Peek;

   procedure Peek
     (Win    : in  Window := Standard_Window;
      Line   : in  Line_Position;
      Column : in  Column_Position;
      Str    : out Attributed_String;
      Len    : in Integer := -1)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Peek (Win, Str, Len);
   end Peek;
------------------------------------------------------------------------------
   procedure Get (Win : in  Window := Standard_Window;
                  Str : out String;
                  Len : in  Integer := -1)
   is
      function Wgetnstr (Win : Window;
                         Str : char_array;
                         Len : C_Int) return C_Int;
      pragma Import (C, Wgetnstr, "wgetnstr");

      N   : Integer := Len;
      Txt : char_array (0 .. Str'Length);
      Cnt : Natural;
   begin
      if N < 0 then
         N := Str'Length;
      end if;
      if N > Str'Length then
         raise Constraint_Error;
      end if;
      Txt (0) := Interfaces.C.char'First;
      if Wgetnstr (Win, Txt, C_Int (N)) = Curses_Err then
         raise Curses_Exception;
      end if;
      To_Ada (Txt, Str, Cnt, True);
      if Cnt < Str'Length then
         Str ((Str'First + Cnt) .. Str'Last) := (others => ' ');
      end if;
   end Get;

   procedure Get
     (Win    : in  Window := Standard_Window;
      Line   : in  Line_Position;
      Column : in  Column_Position;
      Str    : out String;
      Len    : in  Integer := -1)
   is
   begin
      Move_Cursor (Win, Line, Column);
      Get (Win, Str, Len);
   end Get;
------------------------------------------------------------------------------
   procedure Init_Soft_Label_Keys
     (Format : in Soft_Label_Key_Format := Three_Two_Three)
   is
      function Slk_Init (Fmt : C_Int) return C_Int;
      pragma Import (C, Slk_Init, "slk_init");
   begin
      if Slk_Init (Soft_Label_Key_Format'Pos (Format)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Init_Soft_Label_Keys;

   procedure Set_Soft_Label_Key (Label : in Label_Number;
                                 Text  : in String;
                                 Fmt   : in Label_Justification := Left)
   is
      type Char_Ptr is access all Interfaces.C.Char;
      function Slk_Set (Label : C_Int;
                        Txt   : Char_Ptr;
                        Fmt   : C_Int) return C_Int;
      pragma Import (C, Slk_Set, "slk_set");

      Txt : char_array (0 .. Text'Length);
      Len : size_t;
   begin
      To_C (Text, Txt, Len);
      if Slk_Set (C_Int (Label),
                  Txt (Txt'First)'Access,
                  C_Int (Label_Justification'Pos (Fmt)))
        = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Soft_Label_Key;

   procedure Refresh_Soft_Label_Keys
   is
      function Slk_Refresh return C_Int;
      pragma Import (C, Slk_Refresh, "slk_refresh");
   begin
      if Slk_Refresh = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh_Soft_Label_Keys;

   procedure Refresh_Soft_Label_Keys_Without_Update
   is
      function Slk_Noutrefresh return C_Int;
      pragma Import (C, Slk_Noutrefresh, "slk_noutrefresh");
   begin
      if Slk_Noutrefresh = Curses_Err then
         raise Curses_Exception;
      end if;
   end Refresh_Soft_Label_Keys_Without_Update;

   procedure Get_Soft_Label_Key (Label : in Label_Number;
                                 Text  : out String)
   is
      function Slk_Label (Label : C_Int) return chars_ptr;
      pragma Import (C, Slk_Label, "slk_label");
   begin
      Fill_String (Slk_Label (C_Int (Label)), Text);
   end Get_Soft_Label_Key;

   procedure Clear_Soft_Label_Keys
   is
      function Slk_Clear return C_Int;
      pragma Import (C, Slk_Clear, "slk_clear");
   begin
      if Slk_Clear = Curses_Err then
         raise Curses_Exception;
      end if;
   end Clear_Soft_Label_Keys;

   procedure Restore_Soft_Label_Keys
   is
      function Slk_Restore return C_Int;
      pragma Import (C, Slk_Restore, "slk_restore");
   begin
      if Slk_Restore = Curses_Err then
         raise Curses_Exception;
      end if;
   end Restore_Soft_Label_Keys;

   procedure Touch_Soft_Label_Keys
   is
      function Slk_Touch return C_Int;
      pragma Import (C, Slk_Touch, "slk_touch");
   begin
      if Slk_Touch = Curses_Err then
         raise Curses_Exception;
      end if;
   end Touch_Soft_Label_Keys;

   procedure Switch_Soft_Label_Key_Attributes
     (Attr : in Character_Attribute_Set;
      On   : in Boolean := True)
   is
      function Slk_Attron (Ch : C_Int) return C_Int;
      pragma Import (C, Slk_Attron, "slk_attron");
      function Slk_Attroff (Ch : C_Int) return C_Int;
      pragma Import (C, Slk_Attroff, "slk_attroff");

      Err : C_Int;
      Ch  : constant Attributed_Character := (Ch    => Character'First,
                                              Attr  => Attr,
                                              Color => Color_Pair'First);
   begin
      if On then
         Err := Slk_Attron  (Chtype_To_CInt (Ch));
      else
         Err := Slk_Attroff (Chtype_To_CInt (Ch));
      end if;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Switch_Soft_Label_Key_Attributes;

   procedure Set_Soft_Label_Key_Attributes
     (Attr  : in Character_Attribute_Set := Normal_Video;
      Color : in Color_Pair := Color_Pair'First)
   is
      function Slk_Attrset (Ch : C_Int) return C_Int;
      pragma Import (C, Slk_Attrset, "slk_attrset");

      Ch : constant Attributed_Character := (Ch    => Character'First,
                                             Attr  => Attr,
                                             Color => Color);
   begin
      if Slk_Attrset (Chtype_To_CInt (Ch)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Set_Soft_Label_Key_Attributes;

   function Get_Soft_Label_Key_Attributes return Character_Attribute_Set
   is
      function Slk_Attr return C_Int;
      pragma Import (C, Slk_Attr, "slk_attr");

      Attr : constant C_Int := Slk_Attr;
   begin
      return CInt_To_Chtype (Attr).Attr;
   end Get_Soft_Label_Key_Attributes;

   function Get_Soft_Label_Key_Attributes return Color_Pair
   is
      function Slk_Attr return C_Int;
      pragma Import (C, Slk_Attr, "slk_attr");

      Attr : constant C_Int := Slk_Attr;
   begin
      return CInt_To_Chtype (Attr).Color;
   end Get_Soft_Label_Key_Attributes;
------------------------------------------------------------------------------
   procedure Un_Control (Ch  : in Attributed_Character;
                         Str : out String)
   is
      function Unctrl (Ch : C_Int) return chars_ptr;
      pragma Import (C, Unctrl, "unctrl");
   begin
      Fill_String (Unctrl (Chtype_To_CInt (Ch)), Str);
   end Un_Control;

   procedure Delay_Output (Msecs : in Natural)
   is
      function Delayoutput (Msecs : C_Int) return C_Int;
      pragma Import (C, Delayoutput, "delay_output");
   begin
      if Delayoutput (C_Int (Msecs)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Delay_Output;

   procedure Flush_Input
   is
      function Flushinp return C_Int;
      pragma Import (C, Flushinp, "flushinp");
   begin
      if Flushinp = Curses_Err then  -- docu says that never happens, but...
         raise Curses_Exception;
      end if;
   end Flush_Input;
------------------------------------------------------------------------------
   function Baudrate return Natural
   is
      function Baud return C_Int;
      pragma Import (C, Baud, "baudrate");
   begin
      return Natural (Baud);
   end Baudrate;

   function Erase_Character return Character
   is
      function Erasechar return C_Int;
      pragma Import (C, Erasechar, "erasechar");
   begin
      return Character'Val (Erasechar);
   end Erase_Character;

   function Kill_Character return Character
   is
      function Killchar return C_Int;
      pragma Import (C, Killchar, "killchar");
   begin
      return Character'Val (Killchar);
   end Kill_Character;

   function Has_Insert_Character return Boolean
   is
      function Has_Ic return C_Int;
      pragma Import (C, Has_Ic, "has_ic");
   begin
      if Has_Ic = Curses_False then
         return False;
      else
         return True;
      end if;
   end Has_Insert_Character;

   function Has_Insert_Line return Boolean
   is
      function Has_Il return C_Int;
      pragma Import (C, Has_Il, "has_il");
   begin
      if Has_Il = Curses_False then
         return False;
      else
         return True;
      end if;
   end Has_Insert_Line;

   function Supported_Attributes return Character_Attribute_Set
   is
      function Termattrs return C_Int;
      pragma Import (C, Termattrs, "termattrs");

      Ch : constant Attributed_Character := CInt_To_Chtype (Termattrs);
   begin
      return Ch.Attr;
   end Supported_Attributes;

   procedure Long_Name (Name : out String)
   is
      function Longname return chars_ptr;
      pragma Import (C, Longname, "longname");
   begin
      Fill_String (Longname, Name);
   end Long_Name;

   procedure Terminal_Name (Name : out String)
   is
      function Termname return chars_ptr;
      pragma Import (C, Termname, "termname");
   begin
      Fill_String (Termname, Name);
   end Terminal_Name;
------------------------------------------------------------------------------
   procedure Init_Pair (Pair : in Redefinable_Color_Pair;
                        Fore : in Color_Number;
                        Back : in Color_Number)
   is
      function Initpair (Pair : C_Short;
                         Fore : C_Short;
                         Back : C_Short) return C_Int;
      pragma Import (C, Initpair, "init_pair");
   begin
      if Integer (Pair) >= Number_Of_Color_Pairs then
         raise Constraint_Error;
      end if;
      if Integer (Fore) >= Number_Of_Colors or else
        Integer (Back) >= Number_Of_Colors then raise Constraint_Error;
      end if;
      if Initpair (C_Short (Pair), C_Short (Fore), C_Short (Back))
        = Curses_Err then
         raise Curses_Exception;
      end if;
   end Init_Pair;

   procedure Pair_Content (Pair : in Color_Pair;
                           Fore : out Color_Number;
                           Back : out Color_Number)
   is
      type C_Short_Access is access all C_Short;
      function Paircontent (Pair : C_Short;
                            Fp   : C_Short_Access;
                            Bp   : C_Short_Access) return C_Int;
      pragma Import (C, Paircontent, "pair_content");

      F, B : aliased C_Short;
   begin
      if Paircontent (C_Short (Pair), F'Access, B'Access) = Curses_Err then
         raise Curses_Exception;
      else
         Fore := Color_Number (F);
         Back := Color_Number (B);
      end if;
   end Pair_Content;

   function Has_Colors return Boolean
   is
      function Hascolors return C_Int;
      pragma Import (C, Hascolors, "has_colors");
   begin
      if Hascolors = Curses_False then
         return False;
      else
         return True;
      end if;
   end Has_Colors;

   procedure Init_Color (Color : in Color_Number;
                         Red   : in RGB_Value;
                         Green : in RGB_Value;
                         Blue  : in RGB_Value)
   is
      function Initcolor (Col   : C_Short;
                          Red   : C_Short;
                          Green : C_Short;
                          Blue  : C_Short) return C_Int;
      pragma Import (C, Initcolor, "init_color");
   begin
      if Initcolor (C_Short (Color), C_Short (Red), C_Short (Green),
                    C_Short (Blue)) = Curses_Err then
            raise Curses_Exception;
      end if;
   end Init_Color;

   function Can_Change_Color return Boolean
   is
      function Canchangecolor return C_Int;
      pragma Import (C, Canchangecolor, "can_change_color");
   begin
      if Canchangecolor = Curses_False then
         return False;
      else
         return True;
      end if;
   end Can_Change_Color;

   procedure Color_Content (Color : in  Color_Number;
                            Red   : out RGB_Value;
                            Green : out RGB_Value;
                            Blue  : out RGB_Value)
   is
      type C_Short_Access is access all C_Short;

      function Colorcontent (Color : C_Short; R, G, B : C_Short_Access)
                             return C_Int;
      pragma Import (C, Colorcontent, "color_content");

      R, G, B : aliased C_Short;
   begin
      if Colorcontent (C_Short (Color), R'Access, G'Access, B'Access) =
        Curses_Err then
         raise Curses_Exception;
      else
         Red   := RGB_Value (R);
         Green := RGB_Value (G);
         Blue  := RGB_Value (B);
      end if;
   end Color_Content;

------------------------------------------------------------------------------
   procedure Save_Curses_Mode (Mode : in Curses_Mode)
   is
      function Def_Prog_Mode return C_Int;
      pragma Import (C, Def_Prog_Mode, "def_prog_mode");
      function Def_Shell_Mode return C_Int;
      pragma Import (C, Def_Shell_Mode, "def_shell_mode");

      Err : C_Int;
   begin
      case Mode is
         when Curses => Err := Def_Prog_Mode;
         when Shell  => Err := Def_Shell_Mode;
      end case;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Save_Curses_Mode;

   procedure Reset_Curses_Mode (Mode : in Curses_Mode)
   is
      function Reset_Prog_Mode return C_Int;
      pragma Import (C, Reset_Prog_Mode, "reset_prog_mode");
      function Reset_Shell_Mode return C_Int;
      pragma Import (C, Reset_Shell_Mode, "reset_shell_mode");

      Err : C_Int;
   begin
      case Mode is
         when Curses => Err := Reset_Prog_Mode;
         when Shell  => Err := Reset_Shell_Mode;
      end case;
      if Err = Curses_Err then
         raise Curses_Exception;
      end if;
   end Reset_Curses_Mode;

   procedure Save_Terminal_State
   is
      function Savetty return C_Int;
      pragma Import (C, Savetty, "savetty");
   begin
      if Savetty = Curses_Err then
         raise Curses_Exception;
      end if;
   end Save_Terminal_State;

   procedure Reset_Terminal_State
   is
      function Resetty return C_Int;
      pragma Import (C, Resetty, "resetty");
   begin
      if Resetty = Curses_Err then
         raise Curses_Exception;
      end if;
   end Reset_Terminal_State;

   procedure Rip_Off_Lines (Lines : in Integer;
                            Proc  : in Stdscr_Init_Proc)
   is
      function Ripoffline (Lines : C_Int;
                           Proc  : Stdscr_Init_Proc) return C_Int;
      pragma Import (C, Ripoffline, "_nc_ripoffline");
   begin
      if Ripoffline (C_Int (Lines), Proc) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Rip_Off_Lines;

   procedure Set_Cursor_Visibility (Visibility : in out Cursor_Visibility)
   is
      function Curs_Set (Curs : C_Int) return C_Int;
      pragma Import (C, Curs_Set, "curs_set");

      Res : C_Int;
   begin
      Res := Curs_Set (Cursor_Visibility'Pos (Visibility));
      if Res = Curses_Err then
         raise Curses_Exception;
      else
         Visibility := Cursor_Visibility'Val (Res);
      end if;
   end Set_Cursor_Visibility;

   procedure Nap_Milli_Seconds (Ms : in Natural)
   is
      function Napms (Ms : C_Int) return C_Int;
      pragma Import (C, Napms, "napms");
   begin
      if Napms (C_Int (Ms)) = Curses_Err then
         raise Curses_Exception;
      end if;
   end Nap_Milli_Seconds;
------------------------------------------------------------------------------

   function Standard_Window return Window
   is
      Stdscr : Window;
      pragma Import (C, Stdscr, "stdscr");
   begin
      return Stdscr;
   end Standard_Window;

   function Lines return Line_Count
   is
      C_Lines : C_Int;
      pragma Import (C, C_Lines, "LINES");
   begin
      return Line_Count (C_Lines);
   end Lines;

   function Columns return Column_Count
   is
      C_Columns : C_Int;
      pragma Import (C, C_Columns, "COLS");
   begin
      return Column_Count (C_Columns);
   end Columns;

   function Tab_Size return Natural
   is
      C_Tab_Size : C_Int;
      pragma Import (C, C_Tab_Size, "TABSIZE");
   begin
      return Natural (C_Tab_Size);
   end Tab_Size;

   function Number_Of_Colors return Natural
   is
      C_Number_Of_Colors : C_Int;
      pragma Import (C, C_Number_Of_Colors, "COLORS");
   begin
      return Natural (C_Number_Of_Colors);
   end Number_Of_Colors;

   function Number_Of_Color_Pairs return Natural
   is
      C_Number_Of_Color_Pairs : C_Int;
      pragma Import (C, C_Number_Of_Color_Pairs, "COLOR_PAIRS");
   begin
      return Natural (C_Number_Of_Color_Pairs);
   end Number_Of_Color_Pairs;
------------------------------------------------------------------------------
   subtype Column_Range is Integer range
     Integer (Column_Position'First) .. Integer (Column_Position'Last);
   subtype Line_Range is Integer range
     Integer (Line_Position'First) .. Integer (Line_Position'Last);

   function "+" (Left : Column_Position; Right : Integer)
     return Column_Position
   is
      Res : constant Integer := Integer (Left) + Right;
   begin
      if Res not in Column_Range then
         raise Constraint_Error;
      end if;
      return Column_Position (Res);
   end "+";

   function "+" (Left : Integer; Right : Column_Position)
     return Column_Position
   is
      Res : constant Integer := Left + Integer (Right);
   begin
      if Res not in Column_Range then
         raise Constraint_Error;
      end if;
      return Column_Position (Res);
   end "+";

   function "+" (Left : Line_Position; Right : Integer)
     return Line_Position
   is
      Res : constant Integer := Integer (Left) + Right;
   begin
      if Res not in Line_Range then
         raise Constraint_Error;
      end if;
      return Line_Position (Res);
   end "+";

   function "+" (Left : Integer; Right : Line_Position)
     return Line_Position
   is
      Res : constant Integer := Left + Integer (Right);
   begin
      if Res not in Line_Range then
         raise Constraint_Error;
      end if;
      return Line_Position (Res);
   end "+";

   function "-" (Left : Column_Position; Right : Integer)
     return Column_Position
   is
      Res : constant Integer := Integer (Left) - Right;
   begin
      if Res not in Column_Range then
         raise Constraint_Error;
      end if;
      return Column_Position (Res);
   end "-";

   function "-" (Left : Integer; Right : Column_Position)
     return Column_Position
   is
      Res : constant Integer := Left - Integer (Right);
   begin
      if Res not in Column_Range then
         raise Constraint_Error;
      end if;
      return Column_Position (Res);
   end "-";

   function "-" (Left : Line_Position; Right : Integer)
     return Line_Position
   is
      Res : constant Integer := Integer (Left) - Right;
   begin
      if Res not in Line_Range then
         raise Constraint_Error;
      end if;
      return Line_Position (Res);
   end "-";

   function "-" (Left : Integer; Right : Line_Position)
     return Line_Position
   is
      Res : constant Integer := Left - Integer (Right);
   begin
      if Res not in Line_Range then
         raise Constraint_Error;
      end if;
      return Line_Position (Res);
   end "-";


------------------------------------------------------------------------------
   procedure Transform_Coordinates
     (W      : in Window := Standard_Window;
      Line   : in out Line_Position;
      Column : in out Column_Position;
      Dir    : in Transform_Direction := From_Screen)
   is
      type Int_Access is access all C_Int;
      function Transform (W    : Window;
                          Y, X : Int_Access;
                          Dir  : C_Int) return C_Int;
      pragma Import (C, Transform, "_nc_ada_coord_transform");

      X : aliased C_Int := C_Int (Column);
      Y : aliased C_Int := C_Int (Line);
      D : C_Int := 0;
      R : C_Int;
   begin
      if Dir = To_Screen then
         D := 1;
      end if;
      R := Transform (W, Y'Access, X'Access, D);
      if R = Curses_False then
         raise Curses_Exception;
      else
         Line   := Line_Position (Y);
         Column := Column_Position (X);
      end if;
   end Transform_Coordinates;

begin
   if Generation_Bit_Order /= System.Default_Bit_Order then
      raise Constraint_Error;
   end if;
end Terminal_Interface.Curses;
