(* Title:   wimp.h
 * Purpose: C interface to RISC OS Wimp routines.
 *     
 *)

# ifndef __wimp_h
# define __wimp_h

# ifndef __os_h
# include "os.h"
# endif

# ifndef __sprite_h
# include "sprite.h"
# endif

const
  wimp_WMOVEABLE = $00000002;     (* is moveable *)
  wimp_REDRAW_OK = $00000010;     (* can be redrawn entirely by wimp
                                   * ie. no user graphics *)
  wimp_WPANE     = $00000020;     (* window is stuck over tool window *)
  wimp_WTRESPASS = $00000040;     (* window is allowed to go outside
                                   * main area *)
  wimp_WSCROLL_R1= $00000100;     (* scroll request returned when
                                   * scroll button clicked- auto repeat*)
  wimp_SCROLL_R2 = $00000200;     (* as SCROLL_R1, debounced, no auto *)
  wimp_REAL_COLOURS = $000000400; (* use real window colours. *)
  wimp_BACK_WINDOW = $000000800;  (* this window is a background window. *)
  wimp_HOT_KEYS = $000001000;     (* generate events for 'hot keys' *)

  wimp_WOPEN  = $00010000;        (* window is open *)
  wimp_WTOP   = $00020000;        (* window is on top (not covered) *)
  wimp_WFULL  = $00040000;        (* window is full size *)
  wimp_WCLICK_TOGGLE = $00080000; (* open_window_request was due to click
                                   * on toggle-size button *)
  wimp_WFOCUS = $00100000;        (* window has input focus *) 

  wimp_WBACK  = $01000000;        (* window has back button *)
  wimp_WQUIT  = $02000000;        (* has a quit button *)
  wimp_WTITLE = $04000000;        (* has a title bar *)
  wimp_WTOGGLE= $08000000;        (* has a toggle-size button *)
  wimp_WVSCR  = $10000000;        (* has vertical scroll bar *)
  wimp_WSIZE  = $20000000;        (* has size box *)
  wimp_WHSCR  = $40000000;        (* has horizontal scroll bar *)
  wimp_WNEW   = $80000000;        (* use these new flags *)
                                  (* NB! always set the WNEW flag *)

type wimp_wflags_pre = ^wimp_wflags;
     wimp_wflags = integer;

const
  wimp_WCTITLEFORE = 0;
  wimp_WCTITLEBACK = 1;
  wimp_WCWKAREAFORE = 2;
  wimp_WCWKAREABACK = 3;
  wimp_WCSCROLLOUTER = 4;
  wimp_WCSCROLLINNER = 5;
  wimp_WCTITLEHI = 6;
  wimp_WCRESERVED = 7;

type wimp_wcolours_ptr = ^wimp_wcolours;
     wimp_wcolours = integer;

(* If work area background is 255 then it isn't painted. *)
(* If title foreground is 255 then you get no borders, title etc. at all *)

const
  wimp_ITEXT      = $00000001;     (* icon contains text *)
  wimp_ISPRITE    = $00000002;     (* icon is a sprite *)
  wimp_IBORDER    = $00000004;     (* icon has a border *)
  wimp_IHCENTRE   = $00000008;     (* text is horizontally centred *)
  wimp_IVCENTRE   = $00000010;     (* text is vertically centred *)
  wimp_IFILLED    = $00000020;     (* icon has a filled background *)
  wimp_IFONT      = $00000040;     (* text is an anti-aliased font *)
  wimp_IREDRAW    = $00000080;     (* redraw needs application's help *)
  wimp_INDIRECT   = $00000100;     (* icon data is 'indirected' *)
  wimp_IRJUST     = $00000200;     (* text right justified in box *)
  wimp_IESG_NOC   = $00000400;     (* if selected by right button; don't
                                    * cancel other icons in same ESG *)
  wimp_IHALVESPRITE=$00000800;     (* plot sprites half-size *)
(* Must use #define because of type wimp_ibtype *)
#define wimp_IBTYPE $00001000      (* 4-bit field: button type *)
  wimp_ISELECTED  = $00200000;     (* icon selected by user (inverted) *)
  wimp_INOSELECT  = $00400000;     (* icon cannot be selected (shaded) *)
  wimp_IDELETED   = $00800000;     (* icon has been deleted *)
  wimp_IFORECOL   = $01000000;     (* 4-bit field: foreground colour *)
  wimp_IBACKCOL   = $10000000;     (* 4-bit field: background colour *)

type wimp_iconflags_ptr = ^wimp_iconflags;
     wimp_iconflags = integer;

(* If the icon contains anti-aliased text then the colour fields
give the font handle: *)

const wimp_IFONTH = $01000000;

const
  wimp_BIGNORE = 0;               (* ignore all mouse ops *)
  wimp_BNOTIFY = 1;
  wimp_BCLICKAUTO = 2;
  wimp_BCLICKDEBOUNCE = 3;
  wimp_BSELREL = 4;
  wimp_BSELDOUBLE = 5;
  wimp_BDEBOUNCEDRAG = 6;
  wimp_BRELEASEDRAG = 7;
  wimp_BDOUBLEDRAG = 8;
  wimp_BSELNOTIFY = 9;
  wimp_BCLICKDRAGDOUBLE = 10;
  wimp_BCLICKSEL = 11;            (* useful for on/off and radio buttons *)
  wimp_BWRITABLE = 15;

type wimp_ibtype_ptr = ^wimp_ibtype;
     wimp_ibtype = integer;

const
  wimp_BRIGHT       = $001;
  wimp_BMID         = $002;
  wimp_BLEFT        = $004;
  wimp_BDRAGRIGHT   = $010;
  wimp_BDRAGLEFT    = $040;
  wimp_BCLICKRIGHT  = $100;
  wimp_BCLICKLEFT   = $400;

type wimp_bbits_ptr = ^wimp_bbits;
     wimp_bbits = integer;

const
  wimp_MOVE_WIND = 1;                 (* change position of window *)
  wimp_SIZE_WIND = 2;                 (* change size of window *)
  wimp_DRAG_HBAR = 3;                 (* drag horizontal scroll bar *)
  wimp_DRAG_VBAR = 4;                 (* drag vertical scroll bar *)
  wimp_USER_FIXED = 5;                (* user drag box - fixed size *)
  wimp_USER_RUBBER = 6;               (* user drag box - rubber box *)
  wimp_USER_HIDDEN = 7;               (* user drag box - invisible box *)

type wimp_dragtype_ptr = ^wimp_dragtype;
     wimp_dragtype = integer;

(**************************************************************************)

type wimp_w_ptr = ^wimp_w;
     wimp_w = integer; (* abstract window handle *)
     wimp_i_ptr = ^wimp_i;
     wimp_i = integer; (* abstract icon handle *)
     wimp_t_ptr = ^wimp_t;
     wimp_t = integer; (* abstract task handle *)

type wimp_icondata_tag = 1..4;
     wimp_icondata_ptr = ^wimp_icondata;
     wimp_icondata =
       record
         case wimp_icondata_tag of
           1 : (text : packed array[1..11] of char);
                          (* up to 12 bytes of text *)
           2 : (sprite_name : packed array[1..11] of char);
                          (* up to 12 bytes of sprite name *)
           3 : (indirectsprite :
                  record
                    name : string;
                    spritearea : pointer;
                          (* 0->use the common sprite area *)
                          (* 1->use the wimp sprite area *)
                    nameisname : integer
                          (* if FALSE, name is in fact a sprite pointer. *)
                  end);
           4 : (indirecttext :
                  record
                    buffer : string;
                          (* pointer to text buffer *)
                    validstring : string;
                          (* pointer to validation string *)
                    bufflen : integer
                          (* length of text buffer *)
                  end);
       end;

type wimp_box_ptr = ^wimp_box;
     wimp_box =
       record
         x0, y0, x1, y1 : integer
       end;

type wimp_wind_ptr = ^wimp_wind;
     wimp_wind =
       record
         box : wimp_box;       (* screen coords of work area *)
         scx, scy : integer;   (* scroll bar positions *)
         behind : wimp_w;      (* handle to open window behind, -1 if top *)
         flags : wimp_wflags;  (* word of flag bits defined above *)
         colours : array[0..7] of byte;
                               (* colours: index using wimp_wcolours. *)
         ex : wimp_box;        (* maximum extent of work area *)
         titleflags : wimp_iconflags;  (* icon flags for title bar *)
         workflags : wimp_iconflags;   (* just button type relevant *)
         spritearea : pointer; (* 0->use the common sprite area *)
                               (* 1->use the wimp sprite area *)
         minsize : integer;    (* two 16-bit OS-unit fields, (width/height)
                                  giving min size of window. 0->use title. *)
         title : wimp_icondata;(* title icon data *)
         nicons : integer      (* no. of icons in window *)
       end;
(* If there are any icon definitions, they should follow this record
   immediately in memory. *)

type wimp_winfo_ptr = ^wimp_winfo;
     wimp_winfo =         (* result of get_info call. *)
       record
         w : wimp_w;
         info : wimp_wind;
       end;
(* Space for icons must follow. *)

type wimp_icon_ptr = ^wimp_icon;
     wimp_icon =                  (* icon description structure *)
       record
         box : wimp_box;          (* bounding box - relative to
                                   * window origin (work area top left) *)
         flags : wimp_iconflags;  (* word of flag bits defined above *)
         data : wimp_icondata     (* union of bits & bobs as above *)
       end;

type wimp_icreate_ptr = ^wimp_icreate;
     wimp_icreate =               (* structure for creating icons. *)
       record
         w : wimp_w;
         i : wimp_icon
       end;

type wimp_openstr_ptr = ^wimp_openstr;
     wimp_openstr =
       record
         w : wimp_w;      (* window handle *)
         box : wimp_box;  (* position on screen of visible work area *)
         x, y : integer;  (* 'real' coordinates of visible work area *)
         behind : wimp_w  (* handle of window to go behind (-1 = top,
                           * -2 = bottom) *)
       end;

type wimp_wstate_ptr = ^wimp_wstate;
     wimp_wstate =        (* result for window state enquiry *)
       record
         o : wimp_openstr;
         flags : wimp_wflags
       end;

const                    (* event types *)
  wimp_ENULL = 0;        (* null event *)
  wimp_EREDRAW = 1;      (* redraw event *)
  wimp_EOPEN = 2;
  wimp_ECLOSE = 3;
  wimp_EPTRLEAVE = 4;
  wimp_EPTRENTER = 5;
  wimp_EBUT = 6;         (* mouse button change *)
  wimp_EUSERDRAG = 7;
  wimp_EKEY = 8;
  wimp_EMENU = 9;
  wimp_ESCROLL = 10;
  wimp_ELOSECARET = 11;
  wimp_EGAINCARET = 12;
  wimp_ESEND = 17;       (* send message, don't worry if it doesn't arrive *)
  wimp_ESENDWANTACK = 18;(* send message, return ack if not acknowledged *)
  wimp_EACK = 19;        (* acknowledge receipt of message. *)

type wimp_etype_ptr = ^wimp_etype;
     wimp_etype = integer;

const               (* event type masks *)
  wimp_EMNULL        = shl(1, wimp_ENULL);
  wimp_EMREDRAW      = shl(1, wimp_EREDRAW);
  wimp_EMOPEN        = shl(1, wimp_EOPEN);
  wimp_EMCLOSE       = shl(1, wimp_ECLOSE);
  wimp_EMPTRLEAVE    = shl(1, wimp_EPTRLEAVE);
  wimp_EMPTRENTER    = shl(1, wimp_EPTRENTER);
  wimp_EMBUT         = shl(1, wimp_EBUT);
  wimp_EMUSERDRAG    = shl(1, wimp_EUSERDRAG);
  wimp_EMKEY         = shl(1, wimp_EKEY);
  wimp_EMMENU        = shl(1, wimp_EMENU);
  wimp_EMSCROLL      = shl(1, wimp_ESCROLL);
  wimp_EMLOSECARET   = shl(1, wimp_ELOSECARET);
  wimp_EMGAINCARET   = shl(1, wimp_EGAINCARET);
  wimp_EMSEND        = shl(1, wimp_ESEND);
  wimp_EMSENDWANTACK = shl(1, wimp_ESENDWANTACK);
  wimp_EMACK         = shl(1, wimp_EACK);

type wimp_emask_ptr = ^wimp_emask;
     wimp_emask = integer;

type wimp_redrawstr_ptr = ^wimp_redrawstr;
     wimp_redrawstr =
       record
         w : wimp_w;
         box : wimp_box;     (* work area coordinates *)
         scx, scy : integer; (* scroll bar positions *)
         g : wimp_box        (* current graphics window *)
       end;

type wimp_mousestr_ptr = ^wimp_mousestr;
     wimp_mousestr =
       record
         x, y : integer;     (* mouse x and y *)
         bbits : wimp_bbits; (* button state *)
         w : wimp_w;         (* window handle, or -1 if none *)
         i : wimp_i          (* icon handle, or -1 if none *)
       end;

type wimp_caretstr_ptr = ^wimp_caretstr;
     wimp_caretstr =
       record
         w : wimp_w;
         i : wimp_i;
         x, y : integer;   (* offset relative to window origin *)
         height : integer; (* -1 if calc within icon
                            * bit 24 -> VDU-5 type caret
                            * bit 25 -> caret invisible
                            * bit 26 -> bits 16..23 contain colour
                            * bit 27 -> colour is "real" colour *)
         index : integer   (* position within icon *)
       end;

(* Message action codes are allocated just like SWI codes. *)
const
  wimp_MCLOSEDOWN    = 0; (* Reply if any dialogue with the user is required,
                             and the closedown sequence will be aborted. *)
  wimp_MDATASAVE     = 1; (* request to identify directory *)
  wimp_MDATASAVEOK   = 2; (* reply to message type 1 *)
  wimp_MDATALOAD     = 3; (* request to load/insert dragged icon *)
  wimp_MDATALOADOK   = 4; (* reply that file has been loaded *)
  wimp_MDATAOPEN     = 5; (* warning that an object is to be opened *)
  wimp_MRAMFETCH     = 6; (* transfer data to buffer in my workspace *)
  wimp_MRAMTRANSMIT  = 7; (* I have transferred some data to a buffer in your
                             workspace *)
  wimp_MPREQUIT      = 8;
  wimp_PALETTECHANGE = 9;
  wimp_SAVEDESK      = 10; (* Wimp 3.00 onwards, desktop closedown message *)
  wimp_MDEVICECLAIM  = 11; (* Broadcast before an application can claim
                            * parallel port, RS232 port etc. *)
  wimp_MDEVICEINUSE  = 12; (* Reply if another application is already
                            * using the device *)
  wimp_MDATASAVED    = 13; (* A file previously saved has become 'safe' *)

  wimp_FilerOpenDir  = $0400;
  wimp_FilerCloseDir = $0401;

  wimp_Notify        = $40040;  (* net filer notify broadcast *)

  wimp_MMENUWARN     = $400c0;
  (* menu warning. Sent if wimp_MSUBLINKMSG set. Data sent is:
         submenu field of relevant wimp_menuitem.
         screen x-coord
         screen y-coord
         list of menu selection indices (0..n-1 for each menu)
         terminating -1 word.
     Typical response is to call wimp_create_submenu.
  *)
  wimp_MMODECHANGE   = $400c1;
  wimp_MINITTASK     = $400c2;
  wimp_MCLOSETASK    = $400c3;
  wimp_MSLOTCHANGE   = $400c4;       (* Slot size has altered *)
  wimp_MSETSLOT      = $400c5;       (* Task manager requests application
                                         to change its slot size *)
  wimp_MTASKNAMERQ   = $400c6;       (* Request task name *)
  wimp_MTASKNAMEIS   = $400c7;       (* Reply to task name request *)
  wimp_MTASKSTARTED  = $400c8;       (* Broadcast by task to indicate that
                                      * it has now fully started *)

  wimp_MHELPREQUEST  = $502;         (* interactive help request *)
  wimp_MHELPREPLY    = $503;         (* interactive help message *)

  (* Messages for dialogue with printer applications *)

  wimp_MPrintFile       = $80140;    (* Printer app's first response to *)
                                     (* a DATASAVE *)
  wimp_MWillPrint       = $80141;    (* Acknowledgement of PrintFile *)
  wimp_MPrintTypeOdd    = $80145;    (* Broadcast when strange files *)
                                     (* dropped on the printer *)
  wimp_MPrintTypeKnown  = $80146;    (* Ack to above *)
  wimp_MPrinterChange   = $80147;    (* New printer application installed *)

type wimp_msgaction_ptr = ^wimp_msgaction;
     wimp_msgaction = integer;

type wimp_msghdr_ptr = ^wimp_msghdr;
     wimp_msghdr =           (* message block header. *)
       record
         size : integer;     (* 20<=size<=256, multiple of 4 *)
         task : wimp_t;      (* task handle of sender (filled in by wimp) *)
         my_ref : integer;   (* unique ref number (filled in by wimp) *)
         your_ref : integer; (* (0==>none) if non-zero, acknowledge *)
         action : wimp_msgaction  (* message action code *)
       end;
(* size is the size of the whole msgstr, see below. *)

type wimp_msgdatasave_ptr = ^wimp_msgdatasave;
     wimp_msgdatasave =
       record
         w : wimp_w;  (* window in which save occurs. *)
         i : wimp_i;  (* icon there *)
         x : integer; (* position within window of destination of save. *)
         y : integer;
         estsize : integer;    (* estimated size of data, in bytes *)
         _type : integer;      (* file type of data to save *)
         leaf : packed array[1..11] of char
                      (* proposed leaf-name of file, 0-terminated *)
       end;

type wimp_msgdatasaveok_ptr = ^wimp_msgdatasaveok;
     wimp_msgdatasaveok =
       record
(* w, i, x, y, estsize, type copied unaltered from DataSave message. *)
         w : wimp_w;  (* window in which save occurs. *)
         i : wimp_i;  (* icon there *)
         x : integer; (* position within window of destination of save. *)
         y : integer;
         estsize : integer;    (* estimated size of data, in bytes *)
         _type : integer;      (* file type of data to save *)
         name : packed array[1..211] of char
                      (* the name of the file to save *)
       end;

type wimp_msgdataload_ptr = ^wimp_msgdataload;
     wimp_msgdataload =
       record
         w : wimp_w;      (* target window *)
         i : wimp_i;      (* target icon *)
         x : integer;     (* target coords in target window work area *)
         y : integer;
         size : integer;  (* must be 0 *)
         _type : integer; (* type of file *)
         name : packed array[1..211] of char
                          (* the filename follows. *)
       end;

(* for a data load reply, no arguments are required. *)

type wimp_msgdataopen_ptr = ^wimp_msgdataopen;
     wimp_msgdataopen = wimp_msgdataload;
(* The data provided when opening a file is exactly the same. the
 * window, x, y refer to the bottom lh corner of the icon that represents
 * the file being opened, or w=-1 if there is no such. *)

type wimp_msgramfetch_ptr = ^wimp_msgramfetch;
     wimp_msgramfetch =      (* transfer data in memory *)
       record
         addr : string;      (* address of data to transfer *)
         nbytes : integer    (* number of bytes to transfer *)
       end;

type wimp_msgramtransmit_ptr = ^wimp_msgramtransmit;
     wimp_msgramtransmit =       (* I have transferred some data to a
                                  * buffer in your workspace *)
       record
         addr : string;          (* copy of value sent in RAMfetch *)
         nbyteswritten : integer (* number of bytes written *)
       end;

type wimp_msgsavedesk_ptr = ^wimp_msgsavedesk;
     wimp_msgsavedesk =       (* Save state for restart *)
       record
         filehandle : integer (* RISC OS file handle (not a C one!) *)
       end;

type wimp_msgdevice_ptr = ^wimp_msgdevice;
     wimp_msgdevice =
       record
         major : integer;     (* Major device number *)
         minor : integer;     (* Minor device number *)
         information : packed array[1..227] of char
                              (* Null-terminated information string *)
       end;

type wimp_msghelprequest_ptr = ^wimp_msghelprequest;
     wimp_msghelprequest =
       record
         m : wimp_mousestr    (* where the help is required *)
       end;

type wimp_msghelpreply_ptr = ^wimp_msghelpreply;
     wimp_msghelpreply =
       record
         text : packed array[1..199] of char;  (* the helpful string *)
       end;

type wimp_msgprint_ptr = ^wimp_msgprint;
     wimp_msgprint =     (* structure used in all print messages *)
       record
         filler : array[0..4] of integer;
         _type : integer;                    (* filetype *)
         name : packed array[1..211] of char (* filename *)
       end;

type wimp_msgstr_tag = 0..12;
     wimp_msgstr_ptr = ^wimp_msgstr;
     wimp_msgstr =       (* message block *)
       record
         hdr : wimp_msghdr;
         case wimp_msgstr_tag of
           0 : (chars : array[0..235] of byte);
           1 : (words : array[0..58] of integer); (* max data size. *)
           2 : (datasave : wimp_msgdatasave);
           3 : (datasaveok : wimp_msgdatasaveok);
           4 : (dataload : wimp_msgdataload);
           5 : (dataopen : wimp_msgdataopen);
           6 : (ramfetch : wimp_msgramfetch);
           7 : (ramtransmit : wimp_msgramtransmit);
           8 : (helprequest : wimp_msghelprequest);
           9 : (helpreply : wimp_msghelpreply);
          10 : (print : wimp_msgprint);
          11 : (savedesk : wimp_msgsavedesk);
          12 : (device : wimp_msgdevice)
       end;

type wimp_eventdata_tag = 0..7;
     wimp_eventdata_ptr = ^wimp_eventdata;
     wimp_eventdata =
       record
         case wimp_eventdata_tag of
           0 : (o : wimp_openstr);
                            (* for redraw, close, enter, leave events *)
           1 : (but :
                  record    (* for button change event *)
                    m : wimp_mousestr;
                    b : wimp_bbits
                  end);
           2 : (dragbox : wimp_box); (* for user drag box event *)
           3 : (key :
                  record    (* for key events *)
                    c : wimp_caretstr;
                    chcode : integer
                  end);
           4 : (menu : array[0..9] of integer);
                            (* for menu event: terminated by -1 *)
           5 : (scroll :
                  record    (* for scroll requests *)
                    o : wimp_openstr;
                    x : integer;     (* x=-1 for left, +1 for right *)
                    y : integer      (* y=-1 for down, +1 for up    *)
                  end);     (* scroll by +/-2 -> page scroll request *)
           6 : (c : wimp_caretstr);  (* for caret gain/lose. *)
           7 : (msg : wimp_msgstr)   (* for messages. *)
       end;

type wimp_eventstr_ptr = ^wimp_eventstr;
     wimp_eventstr =           (* wimp event description *)
       record
         e : wimp_etype;       (* event type *)
         data : wimp_eventdata
       end;

type wimp_menuhdr_ptr = ^wimp_menuhdr;
     wimp_menuhdr =
       record
         title : packed array[1..11] of char;  (* menu title (optional) *)
         tit_fcol, tit_bcol, work_fcol, work_bcol : byte;    (* colours *)
         width, height : integer;   (* size of following menu items *)
         gap : integer              (* vertical gap between items *)
       end;

const          (* menu item flag set *)
  wimp_MTICK       = 1;
  wimp_MSEPARATE   = 2;
  wimp_MWRITABLE   = 4;
  wimp_MSUBLINKMSG = 8; (* show a => flag, and inform program when it
                           is activated. *)
  wimp_MLAST = $80;     (* signal last item in the menu *)

type wimp_menuflags_ptr = ^wimp_menuflags;
     wimp_menuflags = integer;
(* use wimp_INOSELECT to shade the item as unselectable,
 * and the button type to mark it as writable. *)

type wimp_menustr_ptr = ^wimp_menustr;
(* Only for the circular reference in menuitem/str. *)

     wimp_menuitem_ptr = ^wimp_menuitem;
     wimp_menuitem =
       record
         flags : wimp_menuflags;     (* menu entry flags *)
         submenu : wimp_menustr_ptr; (* wimp_menustr* pointer to sub menu,
                                      * or wimp_w dialogue box,
                                      * or -1 if no submenu *)
         iconflags : wimp_iconflags; (* icon flags for the entry *)
         data : wimp_icondata        (* icon data for the entry *)
       end;
(* submenu can also be a wimp_w, in which case the window is opened as a
 * dialogue box within the menu tree. *)

     wimp_menustr =
       record
         hdr : wimp_menuhdr
         (* item : array[] of wimp_menuitem *)
         (* Zero or more menu items follow in memory *)
       end;

type wimp_dragstr_ptr = ^wimp_dragstr;
     wimp_dragstr =
       record
         window : wimp_w;
         _type : wimp_dragtype;
         box : wimp_box;          (* initial position for drag box *)
         parent : wimp_box        (* parent box for drag box *)
       end;

type wimp_which_block_ptr = ^wimp_which_block;
     wimp_which_block =
       record
         window : wimp_w;        (* handle *)
         bit_mask : integer;     (* bit set => consider this bit *)
         bit_set : integer       (* desired bit setting *)
       end;

type wimp_pshapestr_ptr = ^wimp_pshapestr;
     wimp_pshapestr =
       record
         shape_num : integer; (* pointer shape number (0 turn off pointer) *)
         shape_data : string; (* shape data, NULL pointer implies existing
                               * shape *)
         width : integer;     (* Width and height in pixels. Width = 4 * n,
         height : integer;     * where n is an integer. *)
         activex : integer;   (* active point (pixels from top left) *)
         activey : integer
       end;

type wimp_font_array_ptr = ^wimp_font_array;
     wimp_font_array =            (* initialise all to zero before using for *)
       record                     (* first load_template, then just use *)
          f : array[0..255] of byte(* repeatedly without altering *)
       end;

type wimp_template_ptr = ^wimp_template;
     wimp_template =          (* template reading structure *)
       record
         reserved : integer;  (* ignore - implementation detail *)
         buf : wimp_wind_ptr; (* pointer to space for putting template in *)
         work_free : ^byte;   (* pointer to start of free wimp workspace -
                               * you have to provide the wimp system with
                               * workspace to store its redirected icons in*)
         work_end : ^byte;    (* end of workspace you are offering to wimp *)
         font : wimp_font_array_ptr;
                              (* points to font reference count array, 0
                               * pointer implies fonts not allowed *)
         name : string;       (* name to match with (can be wildcarded) *)
         index : integer      (* pos. in index to search from (0 = start) *)
       end;

type wimp_paletteword_tag = 0..1;
     wimp_paletteword_ptr = ^wimp_paletteword;
     wimp_paletteword =
       record
         case wimp_paletteword_tag of
           0 : (bytes :
                  record
                    gcol, red, green, blue : byte
                  end);
           1 : (word : integer)
       end;

(* The gcol char (least significant) is a gcol colour except in 8-bpp
 * modes, when bits 0..2 are the tint and bits 3..7 are the gcol colour. *)

type wimp_palettestr_ptr = ^wimp_palettestr;
     wimp_palettestr =
       record
         c : array[0..15] of wimp_paletteword; (* wimp colours 0..15 *)
         screenborder, mouse1, mouse2, mouse3 : wimp_paletteword
       end;

(**************************************************************************)

procedure wimp_initialise(var v : integer) : os_error; extern;
(* Close & delete all windows, return wimp version number. *)

procedure wimp_taskinit(name : string;
                var version : integer;
                var t : wimp_t) : os_error; extern;
(* Name is the name of the program. *)
(* Used instead of wimp_initialise. Returns your task handle. *)
(* Version should be at least 200 on entry, and will return the
 * current wimp version number. *)

procedure wimp_create_wind(w : wimp_wind_ptr;
                var handle : wimp_w) : os_error; extern;
(* define (but not display) window, return window handle *)

procedure wimp_create_icon(ic : wimp_icreate_ptr;
                var result : wimp_i) : os_error; extern;
(* add icon definition to that of window, return icon handle *)

procedure wimp_delete_wind(w : wimp_w) : os_error; extern;

procedure wimp_delete_icon(w : wimp_w; i : wimp_i) : os_error; extern;

procedure wimp_open_wind(o : wimp_openstr_ptr) : os_error; extern;
(* make window appear on screen *)

procedure wimp_close_wind(w : wimp_w) : os_error; extern;
(* Remove from active list the window with handle in integer argument. *)

procedure wimp_poll(make : wimp_emask;
                result : wimp_eventstr_ptr) : os_error; extern;
(* Poll next event from the WIMP *)

procedure wimp_save_fp_state_on_poll; extern;
(* Activates saving of floating point state on calls to wimp_poll
 * and wimp_pollidle; this is needed if you do any floating point at
 * all, as other programs may corrupt the FP status word, which is
 * effectively a global in your program
 *)

procedure wimp_corrupt_fp_state_on_poll; extern;
(* Disables saving of floating point state on calls to wimp_poll
 * and wimp_pollidle; use only if you never use FP at all
 *)

procedure wimp_redraw_wind(r : wimp_redrawstr_ptr;
                var out : integer) : os_error; extern;
(* Draw window outline and icons. Return FALSE if there's nothing to draw. *)

procedure wimp_update_wind(r : wimp_redrawstr_ptr;
                var out : integer) : os_error; extern;
(* Return visible portion of window. Return FALSE if nothing to redraw. *)

procedure wimp_get_rectangle(r : wimp_redrawstr_ptr;
                var out : integer) : os_error; extern;
(* return next rectangle in list, or FALSE if done. *)

procedure wimp_get_wind_state(w : wimp_w;
                result : wimp_wstate_ptr) : os_error; extern;
(* read current window state *)

procedure wimp_get_wind_info(result : wimp_winfo_ptr) : os_error; extern;
(* On entry result->w gives the window in question. Space for any
 * icons must follow *result. *)

procedure wimp_set_icon_state(w : wimp_w; i : wimp_i;
                value, mask : wimp_iconflags) : os_error; extern;
(* Set icon's flags as (old_state & ~mask) ^ value *)

procedure wimp_get_icon_info(w : wimp_w; i : wimp_i;
                result : wimp_icon_ptr) : os_error; extern;
(* Get current state of icon *)

procedure wimp_get_point_info(
                result : wimp_mousestr_ptr) : os_error; extern;
(* Give info regarding the state of the mouse *)

procedure wimp_drag_box(d : wimp_dragstr_ptr) : os_error; extern;
(* start the wimp dragging a box *)

procedure wimp_force_redraw(r : wimp_redrawstr_ptr) : os_error; extern;
(* Mark an area of the screen as invalid.
 * If r->wimp_w == -1 then use screen coordinates. Only the first
 * five fields of r are valid. *)

procedure wimp_set_caret_pos(c : wimp_caretstr_ptr) : os_error; extern;
(* set pos./size of text caret *)

procedure wimp_get_caret_pos(c : wimp_caretstr_ptr) : os_error; extern;
(* get pos./size of text caret *)

procedure wimp_create_menu(m : wimp_menustr_ptr;
                x, y : integer) : os_error; extern;
(* 'pop up' menu structure. Set m==(wimp_menustr_ptr)-1 to clear the
 * menu tree. *)

type wimp_menuselection_ptr = ^wimp_menuselection;
     wimp_menuselection = integer;

procedure wimp_decode_menu(m : wimp_menustr_ptr;
                selections : wimp_menuselection_ptr;
                s : string) : os_error; extern;

procedure wimp_which_icon(b : wimp_which_block_ptr;
                results : wimp_i_ptr) : os_error; extern;
(* The results appear in an array, terminated by a (wimp_i) -1. *)

procedure wimp_set_extent(r : wimp_redrawstr_ptr) : os_error; extern;
(* Alter extent of a window's work area - only handle and 1st set of
 * 4 coordinates are looked at. *)

procedure wimp_set_point_shape(
                p : wimp_pshapestr_ptr) : os_error; extern;
(* set pointer shape on screen *)

procedure wimp_open_template(name : string) : os_error; extern;
(* opens named file to allow load_template to
 * read a template from the file. *)

procedure wimp_close_template : os_error; extern;
(* close currently open template file *)

procedure wimp_load_template(t : wimp_template_ptr) : os_error; extern;
(* load a window template from open file into buffer *)

procedure wimp_processkey(chcode : integer) : os_error; extern;
(* Hand back to the wimp a key that you do not understand. *)

procedure wimp_closedown : os_error; extern;

procedure wimp_taskclose(t : wimp_t) : os_error; extern;
(* Calls closedown in the multi-tasking form. *)

procedure wimp_starttask(clicmd : string) : os_error; extern;
(* Start a new wimp task, with the given CLI command. *)

procedure wimp_getwindowoutline(
                r : wimp_redrawstr_ptr) : os_error; extern;
(* set r->w on entry. On exit, r->box will be the screen coordinates
 * of the window, including border, title, scroll bars. *)

procedure wimp_pollidle(mask : wimp_emask;
                result : wimp_eventstr_ptr;
                earliest : integer) : os_error; extern;
(* Like wimp_poll, but do not return before earliest return time.
 * This is a value produced by OS_ReadMonotonicTime. *)

procedure wimp_ploticon(i : wimp_icon_ptr) : os_error; extern;
(* Called only within update or redraw loop. Just does the plotting,
this need not be a real icon attached to a window. *)

procedure wimp_setmode(mode : integer) : os_error; extern;
(* Set the screen mode. Palette colours are maintained, if possible. *)

procedure wimp_readpalette(p : wimp_palettestr_ptr) : os_error; extern;

procedure wimp_setpalette(p : wimp_palettestr_ptr) : os_error; extern;
(* The bytes.gcol values of each field of the palettestr are ignored,
 * only the absolute colours are taken into account. *)

procedure wimp_setcolour(colour : integer) : os_error; extern;
(* bits 0..3 = wimp colour (translate for current mode)
        4..6 = gcol action
        7    = foreground/background.
*)

procedure wimp_spriteop(reason_code : integer;
                name : string) : os_error; extern;
(* call SWI Wimp_SpriteOp *)

procedure wimp_spriteop_full(regs : os_regset_ptr) : os_error; extern;
(* call SWI Wimp_SpriteOp allowing full information to be passed *)

function wimp_baseofsprites : pointer; extern;
(* Returns a sprite_area*. This may be moved about by mergespritefile. *)

procedure wimp_blockcopy(w : wimp_w;
                source : wimp_box_ptr;
                x, y : integer) : os_error; extern;
(* Copy the source box (defined in window coords) to the given destination
(in window coords). Invalidate any portions of the destination that cannot be
updated using on-screen copy. *)

const
  wimp_EOK       = 1;        (* put in "OK" box *)
  wimp_ECANCEL   = 2;        (* put in "CANCEL" box *)
  wimp_EHICANCEL = 4;        (* highlight CANCEL rather than OK. *)
(* If OK and CANCEL are both 0 you get an OK. *)

type wimp_errflags_ptr = ^wimp_errflags;
     wimp_errflags = integer;

procedure wimp_reporterror(err : os_error;
                flags : wimp_errflags;
                name : string) : os_error; extern;
(* Produces an error window. Uses sprite called "error" in the wimp sprite
 * pool. name should be the program name, appearing after "error in " at the
 * head of the dialogue box. *)

procedure wimp_sendmessage(code : wimp_etype;
                msg : wimp_msgstr_ptr;
                dest : wimp_t) : os_error; extern;
(* dest can also be 0, in which case the message is sent to every task in
 * turn, including the sender. msg can also be any other wimp_eventdata*
 * value. *)

procedure wimp_sendwmessage(code : wimp_etype;
                msg : wimp_msgstr_ptr;
                w : wimp_w;
                i : wimp_i) : os_error; extern;
(* Send a message to the owner of a specific window/icon. msg can also be
 * any other wimp_eventdata* value. *)

procedure wimp_create_submenu(sub : wimp_menustr_ptr;
                x, y : integer) : os_error; extern;
(* sub can also be a wimp_w, in which case it is opened by the wimp
 * as a dialogue box. *)

procedure wimp_slotsize(var currentslot : integer;
                var nextslot : integer;
                var freepool : integer) : os_error; extern;
(* currentslot/nextslot==-1 -> just read setting. *)

procedure wimp_transferblock(sourcetask : wimp_t;
                sourcebuf : pointer;
                desttask : wimp_t;
                destbuf : pointer;
                buflen : integer) : os_error; extern;
(* Transfer memory between domains. *)

procedure wimp_setfontcolours(foreground,
                background : integer) : os_error; extern;
(* Set font manager colours. The wimp handles how many shades etc. to use. *)

procedure wimp_readpixtrans(area : sprite_area_ptr;
                id : sprite_id_ptr;
                factors : sprite_factors_ptr;
                pixtrans : sprite_pixtrans_ptr) : os_error; extern;
(* Tells you how the WIMP will plot a sprite when asked to PutSpriteScaled *)

const
  wimp_command_TITLE = 0;
  wimp_command_ACTIVE = 1;
  wimp_command_CLOSE_PROMPT = 2;
  wimp_command_CLOSE_NOPROMPT = 3;

type wimp_command_tag = integer;

type wimp_commandwind_ptr = ^wimp_commandwind;
     wimp_commandwind =
       record
         tag : wimp_command_tag;
         title : string
       end;

procedure wimp_commandwindow(
                commandwindow : wimp_commandwind) : os_error; extern;
(* Open a text window for normal VDU 4-type output
   Note:  the tag types correspond to the 4 kinds of call to
   SWI wimp_CommandWindow shown in the Programmer's Ref Manual.
   Title is only required if tag == wimp_command_TITLE.
   It is the application's responsibility to set the tag correctly.
 *)

# endif

(* end wimp.h *)
