#ifndef wimp_H
#define wimp_H

/*OSLib---efficient, type-safe, transparent, extensible,\n"
   register-safe A P I coverage of RISC O S*/
/*Copyright  1994 Jonathan Coxhead*/

/*
      OSLib is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 1, or (at your option)
   any later version.

      OSLib is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
   along with this programme; if not, write to the Free Software
   Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, U S A.
*/

#include <swis.h>

#ifndef types_H
   #include "oslib/types.h"
#endif

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

#ifndef osspriteop_H
   #include "oslib/osspriteop.h"
#endif

#define wimp_ERROR_BOX_SHORT_TITLE ((bits) 0x10u)

#define wimp_VERSION_RO3 310

#define wimp_TITLE_LIMIT 12
#define wimp_TASK_NAME_LIMIT 20
#define wimp_MENU_DEPTH_LIMIT 8

/*event types*/
#define wimp_NULL_REASON_CODE          0
#define wimp_REDRAW_WINDOW_REQUEST     1
#define wimp_OPEN_WINDOW_REQUEST       2
#define wimp_CLOSE_WINDOW_REQUEST      3
#define wimp_POINTER_LEAVING_WINDOW    4
#define wimp_POINTER_ENTERING_WINDOW   5
#define wimp_MOUSE_CLICK               6
#define wimp_USER_DRAG_BOX             7
#define wimp_KEY_PRESSED               8
#define wimp_MENU_SELECTION            9
#define wimp_SCROLL_REQUEST           10
#define wimp_LOSE_CARET               11
#define wimp_GAIN_CARET               12
#define wimp_POLLWORD_NON_ZERO        13
#define wimp_USER_MESSAGE             17
#define wimp_USER_MESSAGE_RECORDED    18
#define wimp_USER_MESSAGE_ACKNOWLEDGE 19

#define wimp_EVENTS                   20

/*mask bits for Wimp_Poll*/
#define wimp_MASK_NULL        (1u <<  0)
#define wimp_QUEUE_REDRAW     (1u <<  1)
#define wimp_MASK_LEAVING     (1u <<  4)
#define wimp_MASK_ENTERING    (1u <<  5)
#define wimp_QUEUE_MOUSE      (1u <<  6)
#define wimp_QUEUE_KEY        (1u <<  8)
#define wimp_MASK_LOSE        (1u << 11)
#define wimp_MASK_GAIN        (1u << 12)
#define wimp_MASK_POLLWORD    (1u << 13)
#define wimp_MASK_MESSAGE     (1u << 17)
#define wimp_MASK_RECORDED    (1u << 18)
#define wimp_MASK_ACKNOWLEDGE (1u << 19)
#define wimp_GIVEN_POLLWORD   (1u << 22)
#define wimp_POLL_HIGH        (1u << 23)
#define wimp_SAVE_FP          (1u << 24)

#define wimp_SPRITEOP_AREA ((osspriteop_area *) 1)

#define wimp_BACKGROUND ((wimp_w) -1)
#define wimp_ICONBAR    ((wimp_w) -2)

/*window handles for the icon bar*/
#define wimp_ICONBAR_RIGHT               ((wimp_w) -1)
#define wimp_ICONBAR_LEFT                ((wimp_w) -2)
#define wimp_ICONBAR_LEFT_RELATIVE       ((wimp_w) -3)
#define wimp_ICONBAR_RIGHT_RELATIVE      ((wimp_w) -4)
#define wimp_ICONBAR_LEFT_HIGH_PRIORITY  ((wimp_w) -5)
#define wimp_ICONBAR_LEFT_LOW_PRIORITY   ((wimp_w) -6)
#define wimp_ICONBAR_RIGHT_LOW_PRIORITY  ((wimp_w) -7)
#define wimp_ICONBAR_RIGHT_HIGH_PRIORITY ((wimp_w) -8)

#define wimp_TOP    ((wimp_w) -1)
#define wimp_BOTTOM ((wimp_w) -2)

#define wimp_NO_ICON (wimp_i) -1))

/*window flag bits*/
#define wimp_WINDOW_MOVEABLE       (1u <<  1)
#define wimp_WINDOW_AUTO_REDRAW    (1u <<  4)
#define wimp_WINDOW_PANE           (1u <<  5)
#define wimp_WINDOW_NO_BOUNDS      (1u <<  6)
#define wimp_WINDOW_SCROLL_REPEAT  (1u <<  8)
#define wimp_WINDOW_SCROLL         (1u <<  9)
#define wimp_WINDOW_REAL_COLOURS   (1u << 10)
#define wimp_WINDOW_BACK           (1u << 11)
#define wimp_WINDOW_HOT_KEYS       (1u << 12)
#define wimp_WINDOW_BOUNDED        (1u << 13)
#define wimp_WINDOW_IGNORE_XEXTENT (1u << 14)
#define wimp_WINDOW_IGNORE_YEXTENT (1u << 15)
#define wimp_WINDOW_OPEN           (1u << 16)
#define wimp_WINDOW_NOT_COVERED    (1u << 17)
#define wimp_WINDOW_FULL_SIZE      (1u << 18)
#define wimp_WINDOW_TOGGLED        (1u << 19)
#define wimp_WINDOW_HAS_FOCUS      (1u << 20)
#define wimp_WINDOW_BOUNDED_ONCE   (1u << 21)
#define wimp_WINDOW_BACK_ICON      (1u << 24)
#define wimp_WINDOW_QUIT_ICON      (1u << 25)
#define wimp_WINDOW_TITLE_ICON     (1u << 26)
#define wimp_WINDOW_TOGGLE_ICON    (1u << 27)
#define wimp_WINDOW_VSCROLL        (1u << 28)
#define wimp_WINDOW_SIZE_ICON      (1u << 29)
#define wimp_WINDOW_HSCROLL        (1u << 30)
#define wimp_WINDOW_NEW_FORMAT     (1u << 31)

/*icon flag bits*/
#define wimp_ICON_TEXT            (1u <<  0)
#define wimp_ICON_SPRITE          (1u <<  1)
#define wimp_ICON_BORDER          (1u <<  2)
#define wimp_ICON_HCENTRED        (1u <<  3)
#define wimp_ICON_VCENTRED        (1u <<  4)
#define wimp_ICON_FILLED          (1u <<  5)
#define wimp_ICON_ANTI_ALIASED    (1u <<  6)
#define wimp_ICON_NEEDS_HELP      (1u <<  7)
#define wimp_ICON_INDIRECTED      (1u <<  8)
#define wimp_ICON_RJUSTIFIED      (1u <<  9)
#define wimp_ICON_ALLOW_ADJUST    (1u << 10)
#define wimp_ICON_HALF_SIZE       (1u << 11)
#define wimp_ICON_BUTTON_TYPE(n) ((n) << 12)
#define wimp_ICON_ESG(n)         ((n) << 16)
#define wimp_ICON_SELECTED        (1u << 21)
#define wimp_ICON_SHADED          (1u << 22)
#define wimp_ICON_DELETED         (1u << 23)
#define wimp_ICON_FG_COLOUR(n)   ((n) << 24)
#define wimp_ICON_BG_COLOUR(n)   ((n) << 28)
#define wimp_ICON_FONT_HANDLE(n) ((n) << 24)

/*button types*/
#define wimp_BUTTON_NEVER              0
#define wimp_BUTTON_ALWAYS             1
#define wimp_BUTTON_REPEAT             2
#define wimp_BUTTON_CLICK              3
#define wimp_BUTTON_RELEASE            4
#define wimp_BUTTON_DOUBLE_CLICK       5
#define wimp_BUTTON_CLICK_DRAG         6
#define wimp_BUTTON_RELEASE_DRAG       7
#define wimp_BUTTON_DOUBLE_DRAG        8
#define wimp_BUTTON_MENU_ICON          9
#define wimp_BUTTON_DOUBLE_CLICK_DRAG 10
#define wimp_BUTTON_RADIO             11
#define wimp_BUTTON_WRITE_CLICK_DRAG  14
#define wimp_BUTTON_WRITABLE          15

#define wimp_TEMPLATE_NAME_LIMIT 12

#define wimp_MENU_TICKED              (1u << 0)
#define wimp_MENU_SEPARATE            (1u << 1)
#define wimp_MENU_WRITABLE            (1u << 2)
#define wimp_MENU_WARNING             (1u << 3)
#define wimp_MENU_SUBMENU_WHEN_SHADED (1u << 4)
#define wimp_MENU_LAST                (1u << 7)

#define wimp_CLICK_ADJUST  (1u << 0)
#define wimp_DOUBLE_ADJUST (1u << 0)
#define wimp_CLICK_MENU    (1u << 1)
#define wimp_CLICK_SELECT  (1u << 2)
#define wimp_DOUBLE_SELECT (1u << 2)
#define wimp_DRAG_ADJUST   (1u << 4)
#define wimp_DRAG_SELECT   (1u << 6)
#define wimp_SINGLE_ADJUST (1u << 8)
#define wimp_SINGLE_SELECT (1u << 10)
   /*use CLICK, CLICK/DRAG or SINGLE/DRAG/DOUBLE*/

#define wimp_NO_FONTS ((font_f) -1)

/*System messages*/
#define message_QUIT           0
#define message_DATA_SAVE      1
#define message_DATA_SAVE_ACK  2
#define message_DATA_LOAD      3
#define message_DATA_LOAD_ACK  4
#define message_DATA_OPEN      5
#define message_RAM_FETCH      6
#define message_RAM_TRANSMIT   7
#define message_PREQUIT        8
#define message_PALETTE_CHANGE 9
#define message_SAVE_DESKTOP  10
#define message_DEVICE_CLAIM  11
#define message_DEVICE_IN_USE 12
#define message_DATA_SAVED    13
#define message_SHUTDOWN 14
#define message_CLAIM_ENTITY 15
#define message_DATA_REQUEST 16
#define message_DRAGGING 17
#define message_DRAG_CLAIM 18

/*Filer messages*/
#define message_FILER_OPEN_DIR            0x400
#define message_FILER_CLOSE_DIR           0x401
#define message_FILER_OPEN_DIR_AT         0x402
#define message_FILER_SELECTION_DIRECTORY 0x403
#define message_FILER_ADD_SELECTION       0x404
#define message_FILER_ACTION              0x405
#define message_FILER_CONTROL_ACTION      0x406
#define message_FILER_SELECTION           0x407

/*Alarm messages*/
#define message_ALARM_SET      0x500
#define message_ALARM_GONE_OFF 0x501
#define message_HELP_REQUEST   0x502
#define message_HELP_REPLY     0x503

/*NetFiler message*/
#define message_NOTIFY         0x40040

/*WIMP messages*/
#define message_MENU_WARNING    0x400C0
#define message_MODE_CHANGE     0x400C1
#define message_TASK_INITIALISE 0x400C2
#define message_TASK_CLOSE_DOWN 0x400C3
#define message_SLOT_SIZE       0x400C4
#define message_SET_SLOT        0x400C5
#define message_TASK_NAME_RQ    0x400C6
#define message_TASK_NAME_IS    0x400C7
#define message_TASK_STARTED    0x400C8
#define message_MENUS_DELETED   0x400C9
#define message_ICONISE         0x400CA
#define message_WINDOW_INFO     0x400CB
#define message_WINDOW_CLOSED   0x400CC

/*EMail messages*/
#define message_SEND_MAIL    0x80000
#define message_SEND_MAIL_OK 0x80001
#define message_MAIL_ARRIVED 0x80002
#define message_WANT_MAIL    0x80003
#define message_WANT_MAIL_OK 0x80004
#define message_CHECK_MAIL   0x80005

/*Printer messages*/
#define message_PRINT_FILE              0x80140
#define message_WILL_PRINT              0x80141
#define message_PRINT_SAVE              0x80142
#define message_PRINT_INIT              0x80143
#define message_PRINT_ERROR             0x80144
#define message_PRINT_TYPE_ODD          0x80145
#define message_PRINT_TYPE_KNOWN        0x80146
#define message_SET_PRINTER             0x80147
#define message_PS_PRINTER_QUERY        0x8014c
#define message_PS_PRINTER_ACK          0x8014d
#define message_PS_PRINTER_MODIFIED     0x8014e
#define message_PS_PRINTER_DEFAULTS     0x8014f
#define message_PS_PRINTER_DEFAULTED    0x80150
#define message_PS_PRINTER_NOT_PS       0x80151
#define message_RESET_PRINTER           0x80152
#define message_PS_IS_FONTPRINT_RUNNING 0x80153

/*TaskWindow messages*/
#define message_TASKWINDOW_INPUT    0x808C0
#define message_TASKWINDOW_OUTPUT   0x808C1
#define message_TASKWINDOW_EGO      0x808C2
#define message_TASKWINDOW_MORIO    0x808C3
#define message_TASKWINDOW_MORITE   0x808C4
#define message_TASKWINDOW_NEW_TASK 0x808C5
#define message_TASKWINDOW_SUSPEND  0x808C6
#define message_TASKWINDOW_RESUME   0x808C7

/*Flags for wimp_report_error()*/
#define wimp_ERRORBOX_OK               (1u << 0)
#define wimp_ERRORBOX_CANCEL           (1u << 1)
#define wimp_ERRORBOX_HIGHLIGHT_CANCEL (1u << 2)
#define wimp_ERRORBOX_NO_PROMPT        (1u << 3)
#define wimp_ERRORBOX_SHORT_TITLE      (1u << 4)
#define wimp_ERRORBOX_LEAVE_OPEN       (1u << 5)
#define wimp_ERRORBOX_CLOSE            (1u << 6)
#define wimp_ERRORBOX_NO_BEEP          (1u << 7)

#define wimp_ERRORBOX_NO_CLICK        0
#define wimp_ERRORBOX_OK_SELECTED     1
#define wimp_ERRORBOX_CANCEL_SELECTED 2

#define wimp_COLOUR_WHITE           0
#define wimp_COLOUR_VERT_LIGHT_GREY 1
#define wimp_COLOUR_LIGHT_GREY      2
#define wimp_COLOUR_MID_LIGHT_GREY  3
#define wimp_COLOUR_MID_DARK_GREY   4
#define wimp_COLOUR_DARK_GREY       5
#define wimp_COLOUR_VERY_DARK_GREY  6
#define wimp_COLOUR_BLACK           7
#define wimp_COLOUR_DARK_BLUE       8
#define wimp_COLOUR_YELLOW          9
#define wimp_COLOUR_LIGHT_GREEN    10
#define wimp_COLOUR_RED            11
#define wimp_COLOUR_CREAM          12
#define wimp_COLOUR_DARK_GREEN     13
#define wimp_COLOUR_ORANGE         14
#define wimp_COLOUR_LIGHT_BLUE     15

typedef int wimp_w, wimp_i, wimp_t;

typedef union wimp_ptr {int size; void *ptr;} wimp_ptr;

typedef struct wimp_message_list {int (messages) [UNKNOWN];} wimp_message_list;

typedef
   union wimp_icon_data
   {  char text [wimp_TITLE_LIMIT],
         sprite [wimp_TITLE_LIMIT],
         text_and_sprite [wimp_TITLE_LIMIT];
      struct {char *text, *validation; int len;} indirected_text,
         indirected_text_and_sprite;
      struct {void *ptr; osspriteop_area *area; int len;} indirected_sprite;
   }
   wimp_icon_data;

typedef
   struct wimp_icon
   {  os_box visible;
      int flags;
      wimp_icon_data data;
   }
   wimp_icon;

typedef
   struct wimp_icon_create
   {  wimp_w w;
      wimp_icon icon;
   }
   wimp_icon_create;

typedef
   struct wimp_window
   {  os_box visible;
      int xscroll, yscroll;
      wimp_w behind;
      int flags;
      char title_fg, title_bg;
      char work_fg, work_bg;
      char scroll_outer, scroll_inner;
      char highlight_bg;
      char reserved;
      os_box work;
      int title_flags;
      int work_flags;
      osspriteop_area *sprite_area;
      short xmin, ymin;
      wimp_icon_data title_data;
      int icon_count;
      wimp_icon icons [UNKNOWN];
   }
   wimp_window;

#define wimp_window(n) \
   struct \
   {  os_box visible; \
      int xscroll, yscroll; \
      wimp_w behind; \
      int flags; \
      char title_fg, title_bg; \
      char work_fg, work_bg; \
      char scroll_outer, scroll_inner; \
      char highlight_bg; \
      char reserved; \
      os_box work; \
      int title_flags; \
      int work_flags; \
      osspriteop_area *sprite_area; \
      short xmin, ymin; \
      wimp_icon_data title; \
      int no_icons; \
      wimp_icon icons [n]; \
   }

#define wimp_SIZEOF_WINDOW(N) \
      (offsetof (wimp_window, icons) + (N)*sizeof ((wimp_window *) NULL)->icons)

typedef
   struct wimp_window_state
   {  wimp_w w;
      os_box visible;
      int xscroll, yscroll;
      wimp_w in_front;
      int flags;
   }
   wimp_window_state;

typedef
   struct wimp_icon_state
   {  wimp_w w;
      wimp_i i;
      wimp_icon icon;
   }
   wimp_icon_state;

typedef
   struct wimp_info
   {  wimp_w w;
      wimp_window window;
   }
   wimp_info;

typedef
   struct wimp_update
   {  wimp_w w;
      os_box extent;
   }
   wimp_update;

typedef
   struct wimp_outline
   {  wimp_w w;
      os_box outline;
   }
   wimp_outline;

typedef
   struct wimp_redraw
   {  wimp_w w;
      os_box visible;
      int xscroll, yscroll;
      os_box clip;
   }
   wimp_redraw;

typedef
   struct wimp_open
   {  wimp_w w;
      os_box visible;
      int xscroll, yscroll;
      wimp_w behind;
   }
   wimp_open;

typedef struct wimp_close {wimp_w w;} wimp_close;

typedef struct wimp_leaving {wimp_w w;} wimp_leaving;

typedef struct wimp_entering {wimp_w w;} wimp_entering;

typedef
   struct wimp_pointer
   {  os_coord pos;
      int buttons;
      wimp_w w;
      wimp_i i;
   }
   wimp_pointer;

typedef struct wimp_drag {os_box box;} wimp_drag;

typedef
   struct wimp_key
   {  wimp_w w;
      wimp_i i;
      os_coord pos;
      int height;
      int index;
      int c;
   }
   wimp_key;

typedef
   struct wimp_selection
   {  int items [UNKNOWN];
   }
   wimp_selection;

typedef
   struct wimp_scroll
   {  wimp_w w;
      os_box visible;
      int xscroll, yscroll;
      wimp_w behind;
      int xdir, ydir;
   }
   wimp_scroll;

typedef
   struct wimp_pollword
   {  int addr;
      int word;
   }
   wimp_pollword;

typedef
   struct wimp_user_drag
   {  wimp_w w;
      int type;
      os_box initial;
      os_box parent;
      int handle;
      void *draw, *undraw, *redraw;
   }
   wimp_user_drag;

typedef
   struct wimp_caret
   {  wimp_w w;
      wimp_i i;
      os_coord pos;
      int height;
      int index;
   }
   wimp_caret;

typedef
   struct wimp_menu_entry
   {  int menu_flags;
      struct wimp_menu *submenu;
      int icon_flags;
      wimp_icon_data data;
   }
   wimp_menu_entry;

typedef
   struct wimp_menu
   {  union
      {  char text [wimp_TITLE_LIMIT];
         struct {char *text;} indirected_text;
      }
      title_data;
      char title_fg, title_bg;
      char work_fg, work_bg;
      int width, height, gap;
      wimp_menu_entry entries [UNKNOWN];
   }
   wimp_menu;

#define wimp_menu(n) \
   struct \
   {  union \
      {  char text [wimp_TITLE_LIMIT]; \
         struct {char *text;} indirected_text; \
      } \
      title_data; \
      char title_fg, title_bg; \
      char work_fg, work_bg; \
      int width, height, gap; \
      wimp_menu_entry entries [n]; \
   }

typedef struct wimp_message_menu_warning
   {  wimp_menu *(sub_menu);
      os_coord pos;
      wimp_selection selection;
   } wimp_message_menu_warning;

typedef struct wimp_message_task_initialise
   {  void *(cao);
      int size;
      char (task_name) [UNKNOWN];
   } wimp_message_task_initialise;

typedef struct wimp_message_slot_size
   {  int new_curr;
      int new_mext;
   } wimp_message_slot_size;

typedef struct wimp_message_set_slot
   {  int new_curr;
      wimp_t task;
   } wimp_message_set_slot;

typedef struct wimp_message_task_name_rq
   {  wimp_t task;
   } wimp_message_task_name_rq;

typedef struct wimp_message_task_name_is
   {  wimp_t task;
      int size;
      char (task_name) [UNKNOWN];
   } wimp_message_task_name_is;

typedef struct wimp_message_menus_deleted
   {  wimp_menu *(menu);
   } wimp_message_menus_deleted;

typedef struct wimp_message_iconise
   {  wimp_w w;
      wimp_t task;
      char (title) [20];
   } wimp_message_iconise;

typedef struct wimp_message_window_closed
   {  wimp_w w;
   } wimp_message_window_closed;

typedef struct wimp_message_window_info
   {  wimp_w w;
      int reserved;
      char (sprite_name) [8];
      char (title) [20];
   } wimp_message_window_info;

typedef struct wimp_message_data_xfer wimp_message_data_xfer;
typedef struct wimp_message_ram_xfer wimp_message_ram_xfer;
typedef struct wimp_message_prequit wimp_message_prequit;
typedef struct wimp_message_save_desktop wimp_message_save_desktop;
typedef struct wimp_message_device wimp_message_device;
typedef struct wimp_message_data_saved wimp_message_data_saved;
typedef struct wimp_message_shutdown wimp_message_shutdown;
typedef struct wimp_message_claim_entity wimp_message_claim_entity;
typedef struct wimp_message_data_request wimp_message_data_request;
typedef struct wimp_message_dragging wimp_message_dragging;
typedef struct wimp_message_drag_claim wimp_message_drag_claim;

typedef
   struct wimp_message
   {  int size;
      wimp_t sender;
      int my_ref;
      int your_ref;
      int action;

      union
      {  char bytes [256 - 5*sizeof (int)];
         int words [256/sizeof (int) - 5];

         /*Message_Quit*/

         /*Message_Data{{Save,Load}(_Ack)?,Open}*/
         struct wimp_message_data_xfer
         {  wimp_w w;
            wimp_i i;
            os_coord pos;
            int est_size, file_type;
            char file_name [UNKNOWN];
         }
         data_xfer;

         /*Message_RAM{Fetch,Transmit}*/
         struct wimp_message_ram_xfer
         {  void *addr;
            int size;
         }
         ram_xfer;

         /*Message_Prequit*/
         struct wimp_message_prequit
         {  int flags;
         }
         prequit;

         /*PaletteChange*/

         /*Message_SaveDesktop*/
         struct wimp_message_save_desktop
         {  os_f file;
            byte (reserved) [3];
            bits flags;
         }
         save_desktop;

         /*Message_DeviceClaim, Message_DeviceInUse*/
         struct wimp_message_device
         {  int major, minor;
            char info [UNKNOWN];
         }
         device;

         struct wimp_message_data_saved
         {  int ref;
         }
         data_saved;

         struct wimp_message_shutdown
         {  bits flags;
         }
         shutdown;

         struct wimp_message_claim_entity
         {  bits flags;
         }
         claim_entity;

         struct wimp_message_data_request
         {  wimp_w w;
            wimp_i i;
            os_coord pos;
            bits flags;
            int (file_type) [UNKNOWN];
         }
         data_request;

         struct wimp_message_dragging
         {  wimp_w w;
            wimp_i i;
            os_coord pos;
            bits flags;
            os_box box;
            int (file_type) [UNKNOWN];
         }
         dragging;

         struct wimp_message_drag_claim
         {  bits flags;
            int (file_type) [UNKNOWN];
         }
         drag_claim;
      }
      data;
   }
   wimp_message;

typedef
   union
   {  char bytes [256];
      int words [256/sizeof (int)];

      /*Null_Reason_Code*/

      /*Redraw_Window_Request*/
      wimp_redraw redraw;

      /*Open_Window_Request*/
      wimp_open open;

      /*Close_Window_Request*/
      wimp_close close;

      /*Pointer_Leaving_Window*/
      wimp_leaving leaving;

      /*Pointer_Entering_Window*/
      wimp_entering entering;

      /*Mouse_Click*/
      wimp_pointer pointer;

      /*User_Drag_Box*/
      wimp_drag drag;

      /*Key_Pressed*/
      wimp_key key;

      /*Menu_Selection*/
      wimp_selection selection;

      /*Scroll_Request*/
      wimp_scroll scroll;

      /*Lose_Caret, Gain_Caret*/
      wimp_caret caret;

      /*PollWord_NonZero*/
      wimp_pollword pollword;

      /*User_Message*/
      /*User_Message_Recorded*/
      /*User_Message_Acknowledge*/
      wimp_message message, recorded, acknowledge;
   }
   wimp_block;

typedef
   union
   {  struct {char gcol, red, green, blue;} bytes;
      int word;
   }
   wimp_palette_entry;

typedef
   struct
   {  wimp_palette_entry c [16], screenborder, mouse1, mouse2, mouse3;
   }
   wimp_palette;

#define xwimp_initialise(version, name, messages, version_out, t) \
   _swix (Wimp_Initialise, _IN (0) | _IN (1) | _IN (2) | _IN (3) | \
         _OUT (0) | _OUT (1), (int) (version), *(int *) "TASK", \
         (char *) (name), (int *) (messages), (int *) (version_out), \
         (wimp_t *) (t))

#define xwimp_create_window(window, w) \
   _swix (Wimp_CreateWindow, _IN (1) | _OUT (0), \
         (wimp_window *) (window), (wimp_w *) (w))

#define xwimp_create_icon(icon, i) \
   _swix (Wimp_CreateIcon, _IN (1) | _OUT (0), \
         (wimp_icon_create *) (icon), (wimp_i *) (i))

#define xwimp_delete_window(w) \
   _swix (Wimp_DeleteWindow, _BLOCK (1), (wimp_w) (w))

#define xwimp_delete_icon(w, i) \
   _swix (Wimp_DeleteIcon, _BLOCK (1), (wimp_w) (w), (wimp_i) (i))

#define xwimp_open_window(open) \
   _swix (Wimp_OpenWindow, _IN (1), (wimp_open *) (open))

#define xwimp_close_window(w) \
   _swix (Wimp_CloseWindow, _BLOCK (1), (wimp_w) (w))

#define xwimp_poll(mask, block, pollword, event) \
   _swix (Wimp_Poll, _IN (0) | _IN (1) | _IN (3) | _OUT (0), \
         (int) (mask), (wimp_block *) (block), (int *) (pollword), \
         (int *) (event))

#define xwimp_redraw_window(redraw) \
   _swix (Wimp_RedrawWindow, _IN (1), (wimp_redraw *) (redraw))

#define xwimp_update_window(update) \
   _swix (Wimp_UpdateWindow, _IN (1), (wimp_update *) (update))

#define xwimp_get_rectangle(redraw) \
   _swix (Wimp_GetRectangle, _IN (1), (wimp_redraw *) (redraw))

#define xwimp_get_window_state(state) \
   _swix (Wimp_GetWindowState, _IN (1), (wimp_window_state *) (state))

#define xwimp_get_window_info(info) \
   _swix (Wimp_GetWindowInfo, _IN (1), (wimp_info *) (info))

#define xwimp_set_icon_state(w, i, eor_word, clear_word) \
   _swix (Wimp_SetIconState, _BLOCK (1), (wimp_w) (w), (wimp_i) (i), \
         (int) (eor_word), (int) (clear_word))

#define xwimp_get_icon_state(state) \
   _swix (Wimp_GetIconState, _IN (1), (wimp_icon_state *) (state))

#define xwimp_get_pointer_info(pointer) \
   _swix (Wimp_GetPointerInfo, _IN (1), (wimp_pointer *) (pointer))

#define xwimp_drag_box(drag) \
   _swix (Wimp_DragBox, _IN (1), (wimp_user_drag *) (drag))

#define xwimp_force_redraw(w, x0, y0, x1, y1) \
   _swix (Wimp_ForceRedraw, \
         _IN (0) | _IN (1) | _IN (2) } _IN (3) | _IN (4), \
         (wimp_w) (w), (int) (x0), (int) (y0), (int) (x1), (int) (y1))

#define xwimp_set_caret_position(w, i, x, y, height, index) \
   _swix (Wimp_SetCaretPosition, _IN (0) | _IN (1) | _IN (2) } _IN (3) | \
         _IN (4) | _IN (5), \
         (wimp_w) (w), (wimp_i) (i), (int) (x), (int) (y), (int) (height), \
         (int) (index))

#define xwimp_get_caret_position(caret) \
   _swix (Wimp_GetCaretPosition, _IN (1), (wimp_caret *) (caret))

#define xwimp_create_menu(menu, x, y) \
   _swix (Wimp_CreateMenu, _IN (1) | _IN (2) | _IN (3), \
         (wimp_menu *) (menu), (int) (x), (int) (y))

#define xwimp_decode_menu(menu, selection, buffer) \
   _swix (Wimp_DecodeMenu, _IN (1) | _IN (2) | _IN (3), \
         (wimp_menu *) (menu), (wimp_selection *) (selection), \
         (char *) (buffer))

#define xwimp_which_icon(w, matches, mask, match) \
   _swix (Wimp_WhichIcon, _IN (0) | _IN (1) | _IN (2) | _IN (3), \
         (wimp_w) (w), (wimp_i *) (matches), (int) (mask), (int) (match))

#define xwimp_set_extent(w, extent) \
   _swix (Wimp_SetExtent, _IN (0) | _IN (1), \
         (wimp_w) (w), (os_box *) (extent))

/*wimp_set_pointer_shape() deprecated*/

#define xwimp_open_template(file_name) \
   _swix (Wimp_OpenTemplate, _IN (1), (char *) (file_name))

#define xwimp_close_template() \
   _swix (Wimp_CloseTemplate, 0)

#define xwimp_load_template(window, buffer, end, font_ref, name, context, \
      size_out, data_size_out, context_out) \
   _swix (Wimp_LoadTemplate, \
         _IN (1) | _IN (2) | _IN (3) | _IN (4) | _IN (5) | _IN (6) | \
         _OUT (1) | _OUT (2) | _OUT (6), \
         (wimp_window *) (window), (void *) (buffer), (void *) (end), \
         (font_f *) (font_ref), (char *) (name), (char *) (context), \
         (int *) (size_out), /*(int *) or (char **)*/ data_size_out, \
         (char **) (context_out))

#define xwimp_process_key(c) \
   _swix (Wimp_ProcessKey, _IN (0), (int) (c))

#define xwimp_close_down(t) \
   _swix (Wimp_CloseDown, _IN (0) | _IN (1), \
         (wimp_t) (t), *(int *) "TASK")

#define xwimp_start_task(command, t) \
   _swix (Wimp_StartTask, _IN (0) | _OUT (0), \
         (char *) (command), (wimp_t *) (t))

#define xwimp_report_error(error, flags, name, click) \
   _swix (Wimp_ReportError, _IN (0) | _IN (1) | _IN (2) | _OUT (1), \
         (os_error *) (error), (int) (flags), (char *) (name), \
         (int *) (click))

#define xwimp_get_window_outline(outline) \
   _swix (Wimp_GetWindowOutline, _IN (1), \
         (wimp_outline *) (outline))

#define xwimp_poll_idle(mask, block, timeout, pollword, event) \
   _swix (Wimp_PollIdle, _IN (0) | _IN (1) | _IN (2) | _IN (3) | _OUT (0), \
         (int) (mask), (wimp_block *) (block), (os_time) (timeout), \
         (int *) (pollword), (int *) (event))

#define xwimp_plot_icon(icon) \
   _swix (Wimp_PlotIcon, _IN (1), (wimp_icon *) (icon))

#define xwimp_set_mode(mode) \
   _swix (Wimp_SetMode, _IN (0), (int) (mode))

#define xwimp_set_palette(palette) \
   _swix (Wimp_SetPalette, _IN (1), (wimp_palette *) (palette))

#define xwimp_read_palette(palette) \
   _swix (Wimp_ReadPalette, _IN (1), (wimp_palette *) (palette))

#define xwimp_set_colour(colour) \
   _swix (Wimp_SetColour, _IN (0), (int) (colour))

#define xwimp_send_message(event, message, to) \
   _swix (Wimp_SendMessage, _IN (0) | _IN (1) | _IN (2), \
         (int) (event), (wimp_message *) (message), (wimp_t) (to))

#define xwimp_send_message_to_window(event, message, to_w, to_i, to_t) \
   _swix (Wimp_SendMessage, \
         _IN (0) | _IN (1) | _IN (2) | _IN (3) | _OUT (2), \
         (int) (event), (wimp_message *) (message), (wimp_w) (to_w), \
         (wimp_i) (to_i), (wimp_t) (to_t))

#define xwimp_create_submenu(submenu, x, y) \
   _swix (Wimp_CreateSubMenu, _IN (1) | _IN (2) | _IN (3), \
         (wimp_menu *) (submenu), (int) (x), (int) (y))

/*wimp_sprite_op: see wimp/spriteop.h*/

#define xwimp_base_of_sprites(rom, ram) \
   _swix (Wimp_BaseOfSprites, _OUT (0) | _OUT (1), \
      (osspriteop_area **) (rom), (osspriteop_area **) (ram))

#define xwimp_block_copy(w, x0, y0, x1, y1, X0, Y0) \
   _swix (Wimp_BlockCopy, \
      _IN (0) | _IN (1) | _IN (2) | _IN (3) | _IN (4) | _IN (5) | _IN (6), \
      (wimp_w) (w), (int) (x0), (int) (y0), (int) (x1), (int) (y1), \
      (int) (X0), (int) (Y0))

#define xwimp_slot_size(new_curr, new_next, curr, next, free) \
   _swix (Wimp_SlotSize, \
         _IN (0) | _IN (1) | _OUT (0) | _OUT (1) | _OUT (2), \
         (int) (new_curr), (int) (new_next), \
         (int *) (curr), (int *) (next), (int *) (free))

#define xwimp_read_pix_trans(bits, area, ptr, factors, trans_tab) \
   _swix (Wimp_ReadPixTrans, \
         _IN (0) | _IN (1) | _IN (2) | IN (6) | _IN (7), \
         (int) (bits), (osspriteop_area *) (area), (void *) (ptr), \
         (osspriteop_factors *) (factors), (osspriteop_trans_tab *) (trans_tab))

#define xwimp_claim_free_memory(claim, size, avail, addr) \
   _swix (Wimp_ClaimFreeMemory, _INN (0) | _IN (1) | _OUT (1) | _OUT (2), \
         (osbool) (claim), (int) (size), (int *) (avail), (void **) (addr))

#define xwimp_command_window(op) \
   _swix (Wimp_CommandWindow, _IN (0), op)

#define xwimp_text_colour(colour) \
   _swix (Wimp_TextColour, _IN (0), (int) (colour))

#define xwimp_transfer_block(from_t, from, to_t, to, len) \
   _swix (Wimp_TransferBlock, \
         _IN (0) | _IN (1) | _IN (2) | _IN (3) | _IN (4), \
         (wimp_t) (from_t), (char *) (from), (wimpt_t (to_t), \
         (char *) (to), (int) (len))

/*Wimp_ReadSysInfo: see "wimp/readsysinfo.h"*/

#define xwimp_set_font_colours(bg, fg) \
   _swix (Wimp_SetFontColours, _IN (1) | _IN (2), (int) (fg), (int) (bg))

#define xwimp_get_menu_state(given_icon, buffer, w, i) \
   _swix (Wimp_GetMenuState, _IN (0) | _IN (1) | _IN (2) | _IN (3), \
      (osbool) (given_icon), (char *) (buffer), (wimp_w) (w), (wimp_i) (i))

#define xwimp_register_filter(type, filter, handle) \
   _swix (Wimp_RegisterFilter, _IN (0) | _IN (1) | _IN (2), \
         (int) (type), (void *) (filter), (int) (handle))

#define xwimp_add_messages(messages) \
   _swix (Wimp_AddMessages, _IN (0), (int *) (messages))

#define xwimp_remove_messages(messages) \
   _swix (Wimp_RemoveMessages, _IN (0), (int *) (messages))

#define xwimp_set_colour_mapping() \
   _swix (Wimp_SetColourMapping, )

#endif
