PreviousUpNext

15.4.1577  src/lib/x-kit/widget/xkit/theme/widget/default/look/sprite-imp.pkg

# sprite-imp.pkg
#
# For background see comments at top of
#     src/lib/x-kit/widget/gui/guiboss-imp.pkg
#
# This file is like widget_imp, but for   src/lib/x-kit/widget/space/sprite/spritespace-imp.pkg
# instead of                              src/lib/x-kit/widget/space/widget/widgetspace-imp.pkg
#
# Compare to:
#     src/lib/x-kit/widget/xkit/theme/widget/default/look/widget-imp.pkg
#     src/lib/x-kit/widget/xkit/theme/widget/default/look/object-imp.pkg

# Compiled by:
#     src/lib/x-kit/widget/xkit-widget.sublib


stipulate
    include package   threadkit;                                # threadkit                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
    #
#   package ap  =  client_to_atom;                              # client_to_atom                is from   src/lib/x-kit/xclient/src/iccc/client-to-atom.pkg
#   package au  =  authentication;                              # authentication                is from   src/lib/x-kit/xclient/src/stuff/authentication.pkg
#   package cpm =  cs_pixmap;                                   # cs_pixmap                     is from   src/lib/x-kit/xclient/src/window/cs-pixmap.pkg
#   package cpt =  cs_pixmat;                                   # cs_pixmat                     is from   src/lib/x-kit/xclient/src/window/cs-pixmat.pkg
#   package dy  =  display;                                     # display                       is from   src/lib/x-kit/xclient/src/wire/display.pkg
#   package xet =  xevent_types;                                # xevent_types                  is from   src/lib/x-kit/xclient/src/wire/xevent-types.pkg
#   package w2x =  windowsystem_to_xserver;                     # windowsystem_to_xserver       is from   src/lib/x-kit/xclient/src/window/windowsystem-to-xserver.pkg
#   package fil =  file__premicrothread;                        # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
#   package fti =  font_index;                                  # font_index                    is from   src/lib/x-kit/xclient/src/window/font-index.pkg
#   package r2k =  xevent_router_to_keymap;                     # xevent_router_to_keymap       is from   src/lib/x-kit/xclient/src/window/xevent-router-to-keymap.pkg
#   package mtx =  rw_matrix;                                   # rw_matrix                     is from   src/lib/std/src/rw-matrix.pkg
#   package rgb =  rgb;                                         # rgb                           is from   src/lib/x-kit/xclient/src/color/rgb.pkg
#   package rop =  ro_pixmap;                                   # ro_pixmap                     is from   src/lib/x-kit/xclient/src/window/ro-pixmap.pkg
#   package rw  =  root_window;                                 # root_window                   is from   src/lib/x-kit/widget/lib/root-window.pkg
#   package rwv =  rw_vector;                                   # rw_vector                     is from   src/lib/std/src/rw-vector.pkg
#   package sep =  client_to_selection;                         # client_to_selection           is from   src/lib/x-kit/xclient/src/window/client-to-selection.pkg
#   package shp =  shade;                                       # shade                         is from   src/lib/x-kit/widget/lib/shade.pkg
#   package sj  =  socket_junk;                                 # socket_junk                   is from   src/lib/internet/socket-junk.pkg
#   package x2s =  xclient_to_sequencer;                        # xclient_to_sequencer          is from   src/lib/x-kit/xclient/src/wire/xclient-to-sequencer.pkg
#   package tr  =  logger;                                      # logger                        is from   src/lib/src/lib/thread-kit/src/lib/logger.pkg
#   package tsr =  thread_scheduler_is_running;                 # thread_scheduler_is_running   is from   src/lib/src/lib/thread-kit/src/core-thread-kit/thread-scheduler-is-running.pkg
#   package u1  =  one_byte_unt;                                # one_byte_unt                  is from   src/lib/std/one-byte-unt.pkg
#   package v1u =  vector_of_one_byte_unts;                     # vector_of_one_byte_unts       is from   src/lib/std/src/vector-of-one-byte-unts.pkg
#   package v2w =  value_to_wire;                               # value_to_wire                 is from   src/lib/x-kit/xclient/src/wire/value-to-wire.pkg
#   package wg  =  widget;                                      # widget                        is from   src/lib/x-kit/widget/old/basic/widget.pkg
#   package wi  =  window;                                      # window                        is from   src/lib/x-kit/xclient/src/window/window.pkg
#   package wme =  window_map_event_sink;                       # window_map_event_sink         is from   src/lib/x-kit/xclient/src/window/window-map-event-sink.pkg
#   package wpp =  client_to_window_watcher;                    # client_to_window_watcher      is from   src/lib/x-kit/xclient/src/window/client-to-window-watcher.pkg
#   package wy  =  widget_style;                                # widget_style                  is from   src/lib/x-kit/widget/lib/widget-style.pkg
#   package e2s =  xevent_to_string;                            # xevent_to_string              is from   src/lib/x-kit/xclient/src/to-string/xevent-to-string.pkg
#   package xc  =  xclient;                                     # xclient                       is from   src/lib/x-kit/xclient/xclient.pkg
#   package xj  =  xsession_junk;                               # xsession_junk                 is from   src/lib/x-kit/xclient/src/window/xsession-junk.pkg
#   package xt  =  xtypes;                                      # xtypes                        is from   src/lib/x-kit/xclient/src/wire/xtypes.pkg
#   package xtr =  xlogger;                                     # xlogger                       is from   src/lib/x-kit/xclient/src/stuff/xlogger.pkg

    package gtg =  guiboss_to_guishim;                          # guiboss_to_guishim            is from   src/lib/x-kit/widget/theme/guiboss-to-guishim.pkg

    package gd  =  gui_displaylist;                             # gui_displaylist               is from   src/lib/x-kit/widget/theme/gui-displaylist.pkg

    package pp  =  standard_prettyprinter;                      # standard_prettyprinter        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package r8  =  rgb8;                                        # rgb8                          is from   src/lib/x-kit/xclient/src/color/rgb8.pkg
    #
    package w2p =  sprite_to_spritespace;                       # sprite_to_spritespace         is from   src/lib/x-kit/widget/space/sprite/sprite-to-spritespace.pkg
    package p2w =  spritespace_to_sprite;                       # spritespace_to_sprite         is from   src/lib/x-kit/widget/space/sprite/spritespace-to-sprite.pkg
    #
    package g2d =  geometry2d;                                  # geometry2d                    is from   src/lib/std/2d/geometry2d.pkg
    package evt =  gui_event_types;                             # gui_event_types               is from   src/lib/x-kit/widget/gui/gui-event-types.pkg
    package gts =  gui_event_to_string;                         # gui_event_to_string           is from   src/lib/x-kit/widget/gui/gui-event-to-string.pkg

    package gt  =  guiboss_types;                               # guiboss_types                 is from   src/lib/x-kit/widget/gui/guiboss-types.pkg
    package wt  =  widget_theme;                                # widget_theme                  is from   src/lib/x-kit/widget/theme/widget/widget-theme.pkg

    package g2p =  gadget_to_pixmap;                            # gadget_to_pixmap              is from   src/lib/x-kit/widget/theme/gadget-to-pixmap.pkg

    #
    tracefile   =  "widget-unit-test.trace.log";

    nb = log::note_on_stderr;                                   # log                           is from   src/lib/std/src/log.pkg
herein

    # This package is referenced in:
    #
    #
    package   sprite_imp
    :         Sprite_Imp                                        # Sprite_Imp                    is from   src/lib/x-kit/widget/xkit/theme/widget/default/look/sprite-imp.api
    {
        Sprite                                                                                          # This turns out not to get used in practice, and probably should be dropped if no use turns up for it.
          =
          { id:                                 Id,                                                     # Unique id to facilitate storing node_state instances in indexed datastructures like red-black trees.
            pass_something:                     Replyqueue -> (Int -> Void) -> Void,
            do_something:                       Int -> Void,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          };

        Startup_Fn
          =
          { 
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          }
          ->
          Void;

        Shutdown_Fn
          =
          Void
          ->
          Void;                                                                                         # 

        Initialize_Gadget_Fn
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            site:                               g2d::Box,                                               # Window rectangle in which to draw.
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme,
            pass_font:                          List(String) -> Replyqueue
                                                             -> (evt::Font -> Void) -> Void,            # Nonblocking version of next, for use in imps.
             get_font:                          List(String) ->  evt::Font,                             # Accepts a list of font names which are tried in order.
            make_rw_pixmap:                     g2d::Size -> g2p::Gadget_To_Rw_Pixmap,                  # Make an Xserver-side rw_pixmap for scratch use by widget.  In general there is no need for the sprite to explicitly free these -- guiboss_imp will do this automatically when the gui is killed.
            #
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          }
          ->
          Void;

        Redraw_Request_Fn
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            frame_number:                       Int,                                                    # 1,2,3,... Purely for convenience of widget, guiboss-imp makes no use of this.
            site:                               g2d::Box,                                               # Window rectangle in which to draw.
            popup_nesting_depth:                Int,                                                    # 0 for gadgets on basewindow, 1 for gadgets on popup on basewindow, 2 for gadgets on popup on popup, etc.
            #
            duration_in_seconds:                Float,                                                  # If state has changed look-imp should call redraw_gadget() before this time is up. Also useful for motionblur.
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            gadget_mode:                        gt::Gadget_Mode,
            #
            theme:                              wt::Widget_Theme,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          }
          ->
          Void;

        Mouse_Click_Fn
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            event:                              gt::Mousebutton_Event,                                  # MOUSEBUTTON_PRESS or MOUSEBUTTON_RELEASE.
            button:                             evt::Mousebutton,
            point:                              g2d::Point,
            site:                               g2d::Box,                                               # Widget's assigned area in window coordinates.
            modifier_keys_state:                evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
            mousebuttons_state:                 evt::Mousebuttons_State,                                # State of mouse buttons as a bool record.
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme
          }
          ->
          Void;

        Mouse_Drag_Fn
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            event_point:                        g2d::Point,
            start_point:                        g2d::Point,
            last_point:                         g2d::Point,
            site:                               g2d::Box,                                               # Widget's assigned area in window coordinates.
            phase:                              gt::Drag_Phase, 
            button:                             evt::Mousebutton,
            modifier_keys_state:                evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
            mousebuttons_state:                 evt::Mousebuttons_State,                                # State of mouse buttons as a bool record.
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          }
          ->
          Void;

        Mouse_Transit_Fn                                                                                # Note that buttons are always all up in a mouse-transit event -- otherwise it is a mouse-drag event.
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            event_point:                        g2d::Point,
            site:                               g2d::Box,                                               # Widget's assigned area in window coordinates.
            transit:                            gt::Gadget_Transit,                                     # Mouse is entering (CAME) or leaving (LEFT) widget, or moving (MOVE) across it.
            modifier_keys_state:                evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          }
          ->
          Void;

        Key_Event_Fn
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            keystroke:                          gt::Keystroke_Info,                                     # Keystring etc for event.
            site:                               g2d::Box,                                               # Widget's assigned area in window coordinates.
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme
          }
          ->
          Void;

        Note_Keyboard_Focus_Fn_Arg
          =
          {
            id:                                 Id,                                                     # Unique id.
            doc:                                String,
            have_keyboard_focus:                Bool,                                                   # 
            gadget_to_guiboss:                  gt::Gadget_To_Guiboss,
            sprite_to_spritespace:              w2p::Sprite_To_Spritespace,
            theme:                              wt::Widget_Theme,
            do:                                 (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
          };
        Note_Keyboard_Focus_Fn = Note_Keyboard_Focus_Fn_Arg -> Void;

        Sprite_Option
            #
            = MICROTHREAD_NAME                  String                                                  # 
            | ID                                Id                                                      # Unique ID for imp, issued by issue_unique_id::issue_unique_id().
            | DOC                               String                                                  # Documentation string for widget, for debugging purposes.
            #
            | WIDGET_CONTROL_CALLBACK           ( p2w::Spritespace_To_Sprite -> Void )                  # Gui boss registers this maildrop to get a port to us once we start up.
            | SPRITE_CALLBACK                   (     Null_Or(Sprite) -> Void )                         # App      registers this maildrop to get (THE sprite_port) from us once we start up, and NULL when we shut down.
            #
            | STARTUP_FN                        Startup_Fn                                              # Application-specific handler for sprite-imp startup.
            | SHUTDOWN_FN                       Shutdown_Fn                                             # Application-specific handler for sprite-imp shutdown -- mainly saving state for possible later sprite restart.
            #                                                                                           # 
            | INITIALIZE_GADGET_FN              Initialize_Gadget_Fn                                    # Typically used to set up widget background.
            | REDRAW_REQUEST_FN                 Redraw_Request_Fn                                       # Application-specific handler for start-of-frame events from guiboss-imp.
            #
            | MOUSE_CLICK_FN                    Mouse_Click_Fn                                          # Application-specific handler for mousebutton clicks.
            #
            | MOUSE_DRAG_FN                     Mouse_Drag_Fn                                           # Application-specific handler for mouse motions.
            | MOUSE_TRANSIT_FN                  Mouse_Transit_Fn                                        # Application-specific handler for mouse motions.
            #
            | KEY_EVENT_FN                      Key_Event_Fn                                            # Application-specific handler for keyboard key-press and key-release events.
            | NOTE_KEYBOARD_FOCUS_FN            Note_Keyboard_Focus_Fn                                  
            ;

        Sprite_Arg        =  List(Sprite_Option);                                                       # No required components at present.



#       pprint_sprite_arg:      pp::Prettyprinter -> Sprite_Arg -> Void;



        Runstate =  {                                                                                   # These values will be statically globally visible throughout the code body for the imp.
                      to:                               Replyqueue,                                     # The name makes   foo::pass_something(imp) to {. ... }   syntax read well.
                      id:                               Id,
                      doc:                              String, 
                      #
                      startup_fn:                       Startup_Fn,                                     # 
                      shutdown_fn:                      Shutdown_Fn,                                    # 
                      #
                      initialize_gadget_fn:             Initialize_Gadget_Fn,
                      redraw_request_fn:                Redraw_Request_Fn,
                      #
                      mouse_click_fn:                   Mouse_Click_Fn,
                      #
                      mouse_drag_fn:                    Mouse_Drag_Fn,
                      mouse_transit_fn:                 Mouse_Transit_Fn,
                      #
                      key_event_fn:                     Key_Event_Fn,
                      note_keyboard_focus_fn:           Note_Keyboard_Focus_Fn,

                      wants_keystrokes:                 Bool,
                      wants_mouseclicks:                Bool,
                                                                                                        # These five provide generic widget connectivity with the guiboss world.
                      gadget_to_guiboss:                gt::Gadget_To_Guiboss,                          # 
                      sprite_to_spritespace:            w2p::Sprite_To_Spritespace,                     # 

                      sprite_callbacks:                 List( Null_Or(Sprite) -> Void ),                # In shut_down_sprite_imp' () we use these to inform app code that our sprite ports are no longer valid.
                      shutdown_oneshot:                 Oneshot_Maildrop ( Void )

# THIS IS NO LONGER NEEDED HERE since Paused_Gui is gone. XXX SUCKO FIXME
#                     sprite_start_fn:                  gt::Sprite_Start_Fn
                    };
 
        Mailq    = Mailqueue( Runstate -> Void );
 
        fun default_startup_fn
              {
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to execute code in main widget microthread.
              }
            =
            (); 

        fun default_shutdown_fn ()
            =
            (); 

        fun default_initialize_gadget_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                site:                           g2d::Box,                                               # Window rectangle in which to draw.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme,
                pass_font:                      List(String) -> Replyqueue
                                                             -> (evt::Font -> Void) -> Void,            # Nonblocking version of next, for use in imps.
                 get_font:                      List(String) ->  evt::Font,                             # Accepts a list of font names which are tried in order.
                make_rw_pixmap:                 g2d::Size -> g2p::Gadget_To_Rw_Pixmap,
                #
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to execute code in main widget microthread.
              }
            =
            {
            };  

        fun default_redraw_request_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                frame_number:                   Int,                                                    # 1,2,3,... Purely for convenience of widget-imp, guiboss-imp makes no use of this.
                site:                           g2d::Box,                                               # Window rectangle in which to draw.
                popup_nesting_depth:            Int,                                                    # 0 for gadgets on basewindow, 1 for gadgets on popup on basewindow, 2 for gadgets on popup on popup, etc.
                #
                duration_in_seconds:            Float,                                                  # If state has changed widget-imp should call redraw_gadget() before this time is up. Also useful for motionblur.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                gadget_mode:                    gt::Gadget_Mode,
                #
                theme:                          wt::Widget_Theme,
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to execute code in main widget microthread.
              }
            =
            {
            };  

        fun default_mouse_click_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                event:                          gt::Mousebutton_Event,                                  # MOUSEBUTTON_PRESS or MOUSEBUTTON_RELEASE.
                button:                         evt::Mousebutton,
                point:                          g2d::Point,
                site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                modifier_keys_state:            evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                mousebuttons_state:             evt::Mousebuttons_State,                                # State of mouse buttons as a bool record.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme
              }
            =
            (); 

        fun default_mouse_drag_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                event_point:                    g2d::Point,
                start_point:                    g2d::Point,
                last_point:                     g2d::Point,
                site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                phase:                          gt::Drag_Phase, 
                button:                         evt::Mousebutton,
                modifier_keys_state:            evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                mousebuttons_state:             evt::Mousebuttons_State,                                # State of mouse buttons as a bool record.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme,
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to execute code in main widget microthread.
              }
            =
            (); 

        fun default_mouse_transit_fn                                                                    # Note that buttons are always all up in a mouse motion -- otherwise it is a mouse-drag event.
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                event_point:                    g2d::Point,
                site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                transit:                        gt::Gadget_Transit,                                     # Mouse is entering (CAME) or leaving (LEFT) widget, or moving (MOVE) across it.
                modifier_keys_state:            evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme,
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to execute code in main widget microthread.
              }
            =
            (); 

        fun default_key_event_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                keystroke:                      gt::Keystroke_Info,                                     # Keystring etc for event.
                site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme
              }
            =
            (); 

        fun default_note_keyboard_focus_fn
              {
                id:                             Id,                                                     # Unique id.
                doc:                            String,
                have_keyboard_focus:            Bool,                                                   # 
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,
                theme:                          wt::Widget_Theme,
                do:                             (Void -> Void) -> Void                                  # Used by widget subthreads to run code in main widget microthread.
              }
            =
            (); 

        fun shut_down_sprite_imp (r: Runstate)
            =
            {   apply   {. #callback  NULL; }   r.sprite_callbacks;                                     # Tell app code that our sprite port is no longer valid.
                #
                put_in_oneshot (r.shutdown_oneshot, ());                                                # Signal guiboss that shutdown is complete.
                                                                                                        # The point here is that we could build and return a new closure locking in updated state if we wished.
                thread_exit { success => TRUE };                                                        # Will not return.      
            };

        fun run (
                  mailq:                        Mailq,                                                  # 
                  #
                  runstate as
                  {                                                                                     # These values will be statically globally visible throughout the code body for the imp.
                    to:                         Replyqueue,                                             # The name makes   foo::pass_something(imp) to {. ... }   syntax read well.
                    id:                         Id,
                    doc:                        String,
                    #
                    startup_fn:                 Startup_Fn,                                             # 
                    shutdown_fn:                Shutdown_Fn,                                            # 
                    #
                    initialize_gadget_fn:       Initialize_Gadget_Fn,
                    redraw_request_fn:          Redraw_Request_Fn,
                    #
                    mouse_click_fn:             Mouse_Click_Fn,
                    #
                    mouse_drag_fn:              Mouse_Drag_Fn,
                    mouse_transit_fn:           Mouse_Transit_Fn,
                    #
                    key_event_fn:               Key_Event_Fn,
                    note_keyboard_focus_fn:     Note_Keyboard_Focus_Fn,
                    #
                    wants_keystrokes:           Bool,
                    wants_mouseclicks:          Bool,
                                                                                                        # These five provide generic widget connectivity with the guiboss world.
                    gadget_to_guiboss:          gt::Gadget_To_Guiboss,                                  # 
                    sprite_to_spritespace:      w2p::Sprite_To_Spritespace,                             # 

                    sprite_callbacks:           List( Null_Or(Sprite) -> Void ),                        # In shut_down_sprite_imp' () we use these to inform app code that our sprite_ports are no longer valid.
                    shutdown_oneshot:           Oneshot_Maildrop ( Void )
#                   sprite_start_fn:            gt::Sprite_Start_Fn
                  }
                )
            =
            {
                loop ();
            }
            where
                fun loop ()                                                                             # Outer loop for the imp.
                    =
                    {   do_one_mailop' to [
                            #
                            (take_from_mailqueue' mailq ==>  do_plea)
                        ];

                        loop ();
                    }   
                    where
                        fun do_plea thunk
                            =
                            thunk runstate;

                        fun shut_down_sprite_imp' ()
                            =
                            shut_down_sprite_imp runstate;
                    end;
            end;        

        fun startup                                                                                             # Root fn of imp microthread.
              { id:                             Id,
                doc:                            String,
                reply_oneshot:                  Oneshot_Maildrop( gt::Sprite_Exports ),
                #
                sprite_callbacks,
                widget_control_callbacks,

                startup_fn:                     Startup_Fn,                                                     # 
                shutdown_fn:                    Shutdown_Fn,                                                    # 
                #
                initialize_gadget_fn:           Initialize_Gadget_Fn,
                redraw_request_fn:              Redraw_Request_Fn,
                #
                mouse_click_fn:                 Mouse_Click_Fn,
                #
                mouse_drag_fn:                  Mouse_Drag_Fn,
                mouse_transit_fn:               Mouse_Transit_Fn,
                #
                key_event_fn:                   Key_Event_Fn,
                note_keyboard_focus_fn:         Note_Keyboard_Focus_Fn,
                #
                wants_keystrokes:               Bool,
                wants_mouseclicks:              Bool,
                                                                                                                # These five provide generic widget connectivity with the guiboss world.
                gadget_to_guiboss:              gt::Gadget_To_Guiboss,                                          # 
                sprite_to_spritespace:          w2p::Sprite_To_Spritespace,                                     # 
                run_gun':                       Run_Gun,
                shutdown_oneshot:               Oneshot_Maildrop ( Void )
#               sprite_start_fn:                gt::Sprite_Start_Fn
              }
              ()                                                                                                # Note currying.
            =
            {   spritespace_to_sprite   = { id, do_something, pass_something, pass_draw_done_flag };

                sprite          = { id, do, do_something, pass_something };

                guiboss_to_gadget       =     { id,
                                                doc,
                                                #
                                                wants_keystrokes,
                                                wants_mouseclicks,
                                                #
                                                initialize_gadget,
                                                redraw_gadget_request,
                                                #
                                                note_keyboard_focus,
                                                note_key_event,
                                                #
                                                note_mousebutton_event,
                                                #
                                                note_mouse_drag_event,
                                                note_mouse_transit,
                                                #
                                                wakeup,
                                                die
                                              };

                exports                 = { guiboss_to_gadget,
                                            spritespace_to_sprite
                                          };

                to                      =  make_replyqueue();   

                put_in_oneshot (reply_oneshot, exports);                                                        # Return value from sprite_start_fn().


                apply   {. #callback  (THE sprite);     }   sprite_callbacks;                                   # Pass our sprite port to everyone who asked for it.
                apply   {. #callback  spritespace_to_sprite;    }   widget_control_callbacks;                   # Pass our port to everyone who asked for it.

                block_until_mailop_fires  run_gun';                                                             # Wait for the starting gun.

                startup_fn                                                                                      # Let application-specific code handle startup however it likes.
                  {                                                                                             # Typically it will set widget foreground and background via
                    gadget_to_guiboss,
                    sprite_to_spritespace,
                    do
                  };

                run (mailq, {                                                                                   # Will not return.
                              to,
                              id,
                              doc,      

                              startup_fn,                                                                       # 
                              shutdown_fn,                                                                      # 
                              #
                              initialize_gadget_fn,
                              redraw_request_fn,
                              #
                              mouse_click_fn,
                              #
                              mouse_drag_fn,
                              mouse_transit_fn,
                              #
                              key_event_fn,
                              note_keyboard_focus_fn,
                              #
                              wants_keystrokes,
                              wants_mouseclicks,
                                                                                                                # These five provide generic widget connectivity with the guiboss world.
                              gadget_to_guiboss,                                                                # 
                              sprite_to_spritespace,                                                            # 
                              sprite_callbacks,                                                                 # In shut_down_sprite_imp' () we use these to inform app code that our sprite ports are no longer valid.
                              shutdown_oneshot
#                             sprite_start_fn
                            }
                    );
            }
            where
                mailq     =  make_mailqueue (get_current_microthread()):  Mailq;

                doc       =  "";                                                                                # Docstring for this sprite. XXX SUCKO FIXME. This is a placeholder, doc functionality need to be coded up per the pattern in  src/lib/x-kit/widget/xkit/theme/widget/default/look/widget-imp.pkg

                fun do (thunk: Void -> Void)                                                                            # PUBLIC.
                    =   
                    put_in_mailqueue  (mailq,
                        #
                        \\ ({ gadget_to_guiboss, ... }: Runstate)
                            =
                            thunk ()
                    );
 
 
                #######################################################################
                # guiboss_to_gadget fns:

                fun initialize_gadget
                      {
                        site:                   g2d::Box,                                                       # Window rectangle in which to draw.
                        theme:                  wt::Widget_Theme,
                         get_font:              List(String) ->  evt::Font,                                     # Accepts a list of font names which are tried in order; returns font 'ascent' and 'descent' in pixels -- sum them to get  font height.
                        pass_font:              List(String) -> Replyqueue                                      #
                                                            -> ( evt::Font -> Void )                            #
                                                            -> Void,                                            # Nonblocking version of next, for use in imps.
                        make_rw_pixmap:         g2d::Size -> g2p::Gadget_To_Rw_Pixmap
                      }
                    =
                    put_in_mailqueue  (mailq,
                        #
                        \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                            =
                            {
                                initialize_gadget_fn                                                            # Let application-specific code handle start-of-frame however it likes.
                                  {
                                    id,
                                    doc,
                                    site,
                                    #
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    theme,
                                     get_font,
                                    pass_font,
                                    make_rw_pixmap,
                                    do
                                  };
                            }
                    );


                fun redraw_gadget_request                                                                       # We get this call at the start of every frame from   src/lib/x-kit/widget/gui/guiboss-imp.pkg
                      {
                        frame_number:           Int,                                                            # 1,2,3,... Purely for convenience of widget, guiboss-imp makes no use of this.
                        site:                   g2d::Box,                                                       # Window rectangle in which to draw.
                        popup_nesting_depth:    Int,                                                            # 0 for gadgets on basewindow, 1 for gadgets on popup on basewindow, 2 for gadgets on popup on popup, etc.
                        duration_in_seconds:    Float,                                                          # If state has changed look-imp should call redraw_gadget() before this time is up. Also useful for motionblur.
                        gadget_mode:            gt::Gadget_Mode,                                                # is_active/has_keyboard_focus/has_mouse_focus flags.
                        theme:                  wt::Widget_Theme
                      }
                    =
                    put_in_mailqueue  (mailq,
                        #
                        \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                            =
                            {
                                redraw_request_fn                                                               # Let application-specific code handle start-of-frame however it likes.
                                  {
                                    id,
                                    doc,
                                    frame_number,
                                    site,
                                    popup_nesting_depth,
                                    duration_in_seconds,
                                    #
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    gadget_mode,
                                    theme,
                                    do
                                  };
                            }
                    );

                fun wakeup                                                                                      # These calls are scheduled via gadget_to_guiboss.wake_me.
                      {
                        wakeup_arg:     gt::Wakeup_Arg,                                                         # 
                        wakeup_fn:      gt::Wakeup_Arg -> Void
                      }
                    =
                    put_in_mailqueue  (mailq,
                        #
                        \\ ({ id, gadget_to_guiboss, ... }: Runstate)
                            =
                            wakeup_fn  wakeup_arg
                    );

                fun die ()
                    =
                    put_in_mailqueue  (mailq,
                        #
                        \\ (runstate: Runstate)
                            =
                            shut_down_sprite_imp  runstate
                    );

                fun note_keyboard_focus
                      (
                        now_have_focus:                 Bool,                                                   # TRUE means we now have keyboard focus, FALSE means we no longer have it.  Allows gadget to visually display focus locus, typically via a black outline and/or dis/abling cursor. See also Gadget_To_Guiboss.request_keyboard_focus
                        theme:                          wt::Widget_Theme
                      )
                    =
                    {
                        put_in_mailqueue  (mailq,
                            #
                            \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                                =
# XXX SUCKO FIXME TBD
                                ()
                        );

                        ();
                    };

                fun note_mouse_transit                                                                          # Note that buttons are always all up in a mouse-transit event -- otherwise it is a mouse-drag event.
                      {
                        transit:                        gt::Gadget_Transit,                                     # Mouse is entering (CAME) or leaving (LEFT) widget, or moving (MOVE) across it.
                        modifier_keys_state:            evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                        event_point:                    g2d::Point,
                        site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                        theme:                          wt::Widget_Theme
                      }                         # Note  keyboard keypress at 'point'.
                    =                           #       ^                                                       # 'point'  ise the click point the window's coordinate system.
                    {                           #       Keyboard key just pressed down.                         #
                        put_in_mailqueue  (mailq,
                            #
                            \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                                =
                                mouse_transit_fn
                                  {
                                    id,
                                    doc,
                                    event_point,
                                    site,
                                    transit,
                                    modifier_keys_state,
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    theme,
                                    do
                                  }
                        );
                    };

                fun note_mouse_drag_event
                      {
                        phase:                          gt::Drag_Phase,                                         # LAUNCH/RESUME/FINISH.
                        button:                         evt::Mousebutton,
                        modifier_keys_state:            evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                        mousebuttons_state:             evt::Mousebuttons_State,                                # State of mouse buttons as a bool record.
                        event_point:                    g2d::Point,
                        start_point:                    g2d::Point,
                        last_point:                     g2d::Point,
                        site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                        theme:                          wt::Widget_Theme
                      }                         # Note  keyboard keypress at 'point'.
                    =                           #       ^                                                       # 'point'  ise the click point the window's coordinate system.
                    {                           #       Keyboard key just pressed down.                         #
                        put_in_mailqueue  (mailq,
                            #
                            \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                                =
                                mouse_drag_fn
                                  {
                                    id,
                                    doc,
                                    event_point,
                                    start_point,
                                    last_point,
                                    site,
                                    phase,
                                    button,
                                    modifier_keys_state,
                                    mousebuttons_state,
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    theme,
                                    do
                                  }
                        );
                    };

                fun note_key_event
                      {
                        keystroke
                          as
                          { key_event:                  gt::Key_Event,                                          # KEY_PRESS or KEY_RELEASE.
                            keycode:                    evt::Keycode,                                           # Keycode of the depressed key.
                            keysym:                     evt::Keysym,                                            # Keysym  of the depressed key.
                            keystring:                  String,                                                 # Ascii  for the depressed key.
                            keychar:                    Char,                                                   # First char of 'string' ('\0' if string-length != 1).
                            modifier_keys_state:        evt::Modifier_Keys_State,                               # State of the modifier keys (shift, ctrl...).
                            mousebuttons_state:         evt::Mousebuttons_State                                 # State of mouse buttons as a bool record.
                        }:                              gt::Keystroke_Info,
                        site:                           g2d::Box,                                               # Widget's assigned area in window coordinates.
                        theme:                          wt::Widget_Theme
                      }                         # Note  keyboard keypress at 'point'.
                    =                           #       ^                                                       # 'point'  ise the click point the window's coordinate system.
                    {                           #       Keyboard key just pressed down.                         #
                        put_in_mailqueue  (mailq,
                            #
                            \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                                =
                                key_event_fn
                                  {
                                    id,
                                    doc,
                                    keystroke,
                                    site,
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    theme
                                  }
                        );
                    };

                fun note_mousebutton_event
                      {
                        mousebutton_event:      gt::Mousebutton_Event,                                          # MOUSEBUTTON_PRESS or MOUSEBUTTON_RELEASE.
                        mouse_button:           evt::Mousebutton,
                        modifier_keys_state:    evt::Modifier_Keys_State,                                       # State of the modifier keys (shift, ctrl...).
                        mousebuttons_state:     evt::Mousebuttons_State,                                        # State of mouse buttons as a bool record.
                        event_point:            g2d::Point,
                        site:                   g2d::Box,                                                       # Widget's assigned area in window coordinates.
                        theme:                  wt::Widget_Theme
                      }                 # Note mousebutton click at 'point'.
                    =                           #       ^                                                       # 'point' is the click point in the window's coordinate system.
                    {                           #       Mouse button just clicked down.                         #
                        put_in_mailqueue  (mailq,
                            #
                            \\ ({ id, gadget_to_guiboss, sprite_to_spritespace, ... }: Runstate)
                                =
                                mouse_click_fn
                                  {
                                    id,
                                    doc,
                                    event  => mousebutton_event,
                                    button => mouse_button,
                                    point  => event_point,
                                    site,
                                    modifier_keys_state,                                                        # State of the modifier keys (shift, ctrl...).
                                    mousebuttons_state,                                                         # State of mouse buttons as a bool record.
                                    gadget_to_guiboss,
                                    sprite_to_spritespace,
                                    theme
                                  }
                        );
                    };



                #######################################################################
                # spritespace_to_sprite fns:


                fun do_something (i: Int)                                                                       # PUBLIC.
                    =   
                    put_in_mailqueue  (mailq,
                        #
                        \\ ({ gadget_to_guiboss, ... }: Runstate)
                            =
                            ()
                    );
 
 
                fun pass_something  (replyqueue: Replyqueue)  (reply_handler: Int -> Void)                      # PUBLIC.
                    =
                    {   reply_oneshot =  make_oneshot_maildrop():  Oneshot_Maildrop( Int );
                        #
                        put_in_mailqueue  (mailq,
                            #
                            \\ (_: Runstate)
                                =
                                put_in_oneshot (reply_oneshot, 0)
                        );
 
                        put_in_replyqueue (replyqueue, (get_from_oneshot' reply_oneshot) ==> reply_handler);
                    };
 
                fun pass_draw_done_flag  (replyqueue: Replyqueue)  (reply_handler: Void -> Void)                # PUBLIC.
                    =
                    {   reply_oneshot =  make_oneshot_maildrop():  Oneshot_Maildrop( Void );
                        #
                        put_in_mailqueue  (mailq,
                            #
                            \\ (_: Runstate)
                                =
                                put_in_oneshot (reply_oneshot, ())
                        );
 
                        put_in_replyqueue (replyqueue, (get_from_oneshot' reply_oneshot) ==> reply_handler);
                    };
            end;


        fun process_options
            ( options: List(Sprite_Option),
              #
              { name,
                id,
                doc,
                #
                sprite_callbacks,
                widget_control_callbacks,
                #
                startup_fn,
                shutdown_fn,
                #
                initialize_gadget_fn,
                redraw_request_fn,
                #
                mouse_click_fn,
                #
                mouse_drag_fn,
                mouse_transit_fn,
                #
                key_event_fn,
                note_keyboard_focus_fn,
                #
                wants_keystrokes,
                wants_mouseclicks
              }
            )
            =
            {   my_name                         =  REF name;
                my_id                           =  REF id;
                my_doc                          =  REF doc;
                #
                my_sprite_callbacks     =  REF  sprite_callbacks;
                my_widget_control_callbacks     =  REF widget_control_callbacks;
                #
                my_startup_fn                   =  REF startup_fn; 
                my_shutdown_fn                  =  REF shutdown_fn; 
                #
                my_initialize_gadget_fn         =  REF initialize_gadget_fn; 
                my_redraw_request_fn            =  REF redraw_request_fn; 
                #
                my_mouse_click_fn               =  REF mouse_click_fn; 
                #
                my_mouse_drag_fn                =  REF mouse_drag_fn; 
                my_mouse_transit_fn             =  REF mouse_transit_fn; 
                #
                my_key_event_fn                 =  REF key_event_fn; 
                my_note_keyboard_focus_fn       =  REF note_keyboard_focus_fn; 
                #
                my_wants_keystrokes             =  REF wants_keystrokes;
                my_wants_mouseclicks            =  REF wants_mouseclicks; 

                apply  do_option  options
                where
                    fun do_option (MICROTHREAD_NAME             n ) =>   my_name                        :=  n;
                        do_option (ID                           i ) =>   my_id                          :=  i;
                        do_option (DOC                           i) =>   my_doc                         :=  i;
                        #
                        do_option (SPRITE_CALLBACK              c ) =>   my_sprite_callbacks            :=  c ! *my_sprite_callbacks;
                        do_option (WIDGET_CONTROL_CALLBACK      c ) =>   my_widget_control_callbacks    :=  c ! *my_widget_control_callbacks;
                        #
                        do_option (STARTUP_FN                   fn) =>   my_startup_fn                  :=  fn;
                        do_option (SHUTDOWN_FN                  fn) =>   my_shutdown_fn                 :=  fn;
                        #
                        do_option (INITIALIZE_GADGET_FN         fn) =>   my_initialize_gadget_fn        :=  fn;
                        do_option (REDRAW_REQUEST_FN            fn) =>   my_redraw_request_fn           :=  fn;
                        #
                        do_option (MOUSE_CLICK_FN               fn) => { my_mouse_click_fn              :=  fn;         my_wants_mouseclicks := TRUE;    };
                        #
                        do_option (MOUSE_DRAG_FN                fn) => { my_mouse_drag_fn               :=  fn;                                          };
                        do_option (MOUSE_TRANSIT_FN             fn) => { my_mouse_transit_fn            :=  fn;                                          };
                        #
                        do_option (KEY_EVENT_FN                 fn) => { my_key_event_fn                :=  fn;         my_wants_keystrokes  := TRUE;    };
                        do_option (NOTE_KEYBOARD_FOCUS_FN       fn) => { my_note_keyboard_focus_fn      :=  fn;                                          };
                    end;
                end;

                { name                      =>  *my_name,
                  id                        =>  *my_id,
                  doc                       =>  *my_doc,
                  #
                  sprite_callbacks          =>  *my_sprite_callbacks,
                  widget_control_callbacks  =>  *my_widget_control_callbacks,
                  #
                  startup_fn                =>  *my_startup_fn,
                  shutdown_fn               =>  *my_shutdown_fn,
                  #
                  initialize_gadget_fn      =>  *my_initialize_gadget_fn,
                  redraw_request_fn         =>  *my_redraw_request_fn,
                  #
                  mouse_click_fn            =>  *my_mouse_click_fn,
                  #
                  mouse_drag_fn             =>  *my_mouse_drag_fn,
                  mouse_transit_fn          =>  *my_mouse_transit_fn,
                  #
                  key_event_fn              =>  *my_key_event_fn,
                  note_keyboard_focus_fn    =>  *my_note_keyboard_focus_fn,
                  #
                  wants_keystrokes          =>  *my_wants_keystrokes,
                  wants_mouseclicks         =>  *my_wants_mouseclicks
                };
            };


        # We do not use our usual Imports/Exports driven
        # imp startup protocol here because we want to
        # keep guiboss_imp from knowing anything about                                                                  # guiboss_imp           is from   src/lib/x-kit/widget/gui/guiboss-imp.pkg
        # the state types of widgets to avoid an explosion
        # of cases in guiboss_imp, one per widget, but we
        # do want guiboss_imp to do the actual widget-imp
        # startup.
        #
        fun make_sprite_start_fn  (widget_options:  List(Sprite_Option))
            =
            {
                (process_options
                  ( widget_options,
                    { name                      =>  "sprite",
                      id                        =>  id_zero,
                      doc                       =>  "",
                      #
                      sprite_callbacks          =>  [],
                      widget_control_callbacks  =>  [],
                      #
                      startup_fn                =>  default_startup_fn,
                      shutdown_fn               =>  default_shutdown_fn,
                      #
                      initialize_gadget_fn      =>  default_initialize_gadget_fn,
                      redraw_request_fn         =>  default_redraw_request_fn,
                      #
                      mouse_click_fn            =>  default_mouse_click_fn,
                      #
                      mouse_drag_fn             =>  default_mouse_drag_fn,
                      mouse_transit_fn          =>  default_mouse_transit_fn,
                      #
                      key_event_fn              =>  default_key_event_fn,
                      note_keyboard_focus_fn    =>  default_note_keyboard_focus_fn,
                      #
                      wants_keystrokes          =>  FALSE,
                      wants_mouseclicks         =>  FALSE
                    }
                ) )
                    ->
                    { name,
                      id,
                      doc,
                      #
                      sprite_callbacks,
                      widget_control_callbacks,
                      #
                      startup_fn,
                      shutdown_fn,
                      #
                      initialize_gadget_fn,
                      redraw_request_fn,
                      #
                      mouse_click_fn,
                      #
                      mouse_drag_fn,
                      mouse_transit_fn,
                      #
                      key_event_fn,
                      note_keyboard_focus_fn,
                      #
                      wants_keystrokes,
                      wants_mouseclicks
                    };

                id  =   if (id_to_int(id) == 0) issue_unique_id();                                              # Allocate unique imp id.
                        else                            id;
                        fi;


                fun sprite_start_fn
                    { gadget_to_guiboss:        gt::Gadget_To_Guiboss,                                                  # 
                      sprite_to_spritespace:    w2p::Sprite_To_Spritespace,                                             # 
                      run_gun':                 Run_Gun,
                      shutdown_oneshot:         Oneshot_Maildrop ( Void )
                    }
                    : gt::Sprite_Exports
                    =
                    {   reply_oneshot =  make_oneshot_maildrop ():      Oneshot_Maildrop( gt::Sprite_Exports );
                        #
                        xlogger::make_thread
                            name
                            (startup  { id,                                                                             # Note that startup() is curried.
                                        doc,
                                        reply_oneshot,
                                        #
                                        sprite_callbacks,
                                        widget_control_callbacks,

                                        startup_fn,                                                                     # Pass in widget-specific args. 
                                        shutdown_fn,                                                                    # Save state for possible widget restart.
                                        #
                                        initialize_gadget_fn,
                                        redraw_request_fn,
                                        #
                                        mouse_click_fn,
                                        #
                                        mouse_drag_fn,
                                        mouse_transit_fn,
                                        #
                                        key_event_fn,
                                        note_keyboard_focus_fn,
                                        #
                                        wants_keystrokes,
                                        wants_mouseclicks,
                                                                                                                        # These five args pass in the ports etc that guiboss-imp gave us.
                                        gadget_to_guiboss,                                                              # 
                                        sprite_to_spritespace,                                                          # 
                                        run_gun',
                                        shutdown_oneshot

#                                       sprite_start_fn =>  gt::SPRITE_START_FN  sprite_start_fn                        # Because we need to put this in shutdown_oneshot at end of run.
                                      }
                            );

                        (get_from_oneshot  reply_oneshot);                                                              # Return gt::Sprite_Exports to guiboss-imp.

                    };

                gt::SPRITE_START_FN  sprite_start_fn;                                                                   # The value-added is that we've locked in the values of *_fn etc, and guiboss-imp can be agnostic about their types.
            };


        fun pprint_sprite_arg
              (pp:              pp::Prettyprinter)
              (sprite_arg:      Sprite_Arg)
            =
            {
                sprite_arg
                  ->
                  ( options:            List(Sprite_Option)
                  );

                pp.box {.
                    pp.txt " [";
                    pp::seqx {. pp.txt ", "; }
                             pprint_option
                             options
                             ;  
                    pp.txt " ]";
                    pp.txt " )";
                };
            }
            where
                fun pprint_option option
                    =
                    case option
                        #
                        MICROTHREAD_NAME name           =>  {  pp.lit (sprintf "MICROTHREAD_NAME \"%s\"" name);         };
                        ID                      id      =>  {  pp.lit (sprintf "ID %d" (id_to_int id)        ); };
                        DOC              docstring      =>  {  pp.lit (sprintf "DOC \"%s\"" docstring             );    };
                        #
                        WIDGET_CONTROL_CALLBACK _       =>  {  pp.lit          "WIDGET_CONTROL_CALLBACK (callback)";    };
                        SPRITE_CALLBACK _               =>  {  pp.lit          "SPRITE_CALLBACK (callback)";            };
                        #
                        STARTUP_FN      _               =>  {  pp.lit          "STARTUP_FN _";                          };
                        SHUTDOWN_FN     _               =>  {  pp.lit          "SHUTDOWN_FN _";                         };
                        #
                        INITIALIZE_GADGET_FN    _       =>  {  pp.lit          "INITIALIZE_GADGET_FN _";                };
                        REDRAW_REQUEST_FN _             =>  {  pp.lit          "REDRAW_REQUEST_FN _";                   };
                        #
                        MOUSE_CLICK_FN  _               =>  {  pp.lit          "MOUSE_CLICK_FN _";                      };
                        #
                        MOUSE_DRAG_FN _                 =>  {  pp.lit          "MOUSE_DRAG_FN _";                       };
                        MOUSE_TRANSIT_FN _              =>  {  pp.lit          "MOUSE_TRANSIT_FN _";                    };
                        #
                        KEY_EVENT_FN    _               =>  {  pp.lit          "KEY_EVENT_FN _";                        };
                        NOTE_KEYBOARD_FOCUS_FN  _       =>  {  pp.lit          "NOTE_KEYBOARD_FOCUS_FN _";              };
                    esac;
            end;
    };

end;




Comments and suggestions to: bugs@mythryl.org

PreviousUpNext