PreviousUpNext

15.3.790  src/lib/x-kit/xclient/src/window/xsession-old.api

## xsession-old.api
#

# Compiled by:
#     src/lib/x-kit/xclient/xclient-internals.sublib


# TODO:
#
#   I think we should recast the X session type as a
# trivial-OOP record of closures.  This will let us write
#
#   session.foo (bar, zot);
#
# in place of
#
#   sn::foo (session, bar, zot);
#
# With the following benefits:
#
#  o It takes better advantage of existing
#    mainstream-hacker OOP (or just C) intuition.
#
#  o Eventually we should be able to tweak the typechecker
#    so that "foo" is resolved in the context of "session"'s
#    type (rather than in the full local context, as currently).
#    At this point we will be dispensing with the irritating
#    "sn::" package qualifier without loss of namespace cleanliness.
#        This does make the relevant code definition less obvious;
#    maybe by then we'll have an IDE where hovering the mouse over
#    an identifier pops up a tooltip-style window with its type.
#
#  o It generalizes to a pervasive concurrent-programming
#    paradigm in which "trampoline" style record-of-closure
#    objects serve as ``capabilities'' granting access to
#    some some im/proper subset of the functionality of an
#    object.
#        If we are to go this route, our OOP support will need
#    to move from the conventional notion of object as
#    state-record with embedded method-table pointer to one
#    which somehow provides support for the trampoline/warthog
#    paradigm of trampoline "capability" objects indirectly
#    referencing the primary warthog object.  Maybe something
#    using one nested subpackage per capability/trampoline:
#
#        class package foo {
#            capability package bar {
#                method fun zot ...
#            }:
#            fun make_bar_capability foo_instance
#                =
#                bar::make foo_instance;
#            ...
#
#    where the bar::make function is autogenerated by the compiler
#    and contains an entry for every method fun declared in 'bar'.

stipulate
    include package   threadkit;                        # threadkit                             is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
    #
    #
    package g2d =  geometry2d;                          # geometry2d                            is from   src/lib/std/2d/geometry2d.pkg
    package cs  =  color_spec;                          # color_spec                            is from   src/lib/x-kit/xclient/src/window/color-spec.pkg
    package xt  =  xtypes;                              # xtypes                                is from   src/lib/x-kit/xclient/src/wire/xtypes.pkg

    package s2t = xsocket_to_hostwindow_router_old;     # xsocket_to_hostwindow_router_old      is from   src/lib/x-kit/xclient/src/window/xsocket-to-hostwindow-router-old.pkg
                                                        # Replaced by                                     src/lib/x-kit/xclient/src/window/xevent-router-ximp.pkg

    package dy  =  display_old;                         # display_old                           is from   src/lib/x-kit/xclient/src/wire/display-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/wire/display.pkg

    package ai  =  atom_imp_old;                        # atom_imp_old                          is from   src/lib/x-kit/xclient/src/iccc/atom-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/iccc/atom-ximp.pkg

    package di  =  draw_imp_old;                        # draw_imp_old                          is from   src/lib/x-kit/xclient/src/window/draw-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/xserver-ximp.pkg

    package fb  =  font_base_old;                       # font_base_old                         is from   src/lib/x-kit/xclient/src/window/font-base-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/font-base.pkg

    package fti =  font_imp_old; # "fi" is taken! :-)   # font_imp_old                          is from   src/lib/x-kit/xclient/src/window/font-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/font-index.pkg

    package ki  =  keymap_imp_old;                      # keymap_imp_old                        is from   src/lib/x-kit/xclient/src/window/keymap-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/keymap-ximp.pkg

    package p2g =  pen_to_gcontext_imp_old;             # pen_to_gcontext_imp_old               is from   src/lib/x-kit/xclient/src/window/pen-to-gcontext-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/pen-cache.pkg

    package si  =  selection_imp_old;                   # selection_imp_old                     is from   src/lib/x-kit/xclient/src/window/selection-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/selection-ximp.pkg

    package wpi =  window_property_imp_old;             # window_property_imp_old               is from   src/lib/x-kit/xclient/src/window/window-property-imp-old.pkg
                                                        # replaced by                                     src/lib/x-kit/xclient/src/window/window-watcher-ximp.pkg
herein

    # This api is implemented in:
    #
    #     src/lib/x-kit/xclient/src/window/xsession-old.pkg

    api Xsession_Old {
        #
        Per_Depth_Imps
            =
            # For each supported combination of
            #
            #     visual + depth + screen
            #
            # we allot a pair of imps, one to draw,
            # one to manage graphics contexts.  This
            # is forced because X requires that each
            # gc and pixmap be associated with a
            # particular screen, visual and depth:
            #
            {                                                                           # The graphics context imp and draw_imp
                #                                                                       # for a given  depth of a screen.
                depth:                  Int,    
                pen_imp:                p2g::Pen_To_Gcontext_Imp,                       # The pen-to-gcontext imp for this depth on this screen.
                to_screen_drawimp:      di::d::Draw_Op -> Void                          # The rootwindow draw-imp for this depth on this screen. 
            };

        Screen_Info = { xscreen:                        dy::Xscreen,                    # Xscreen       def in    src/lib/x-kit/xclient/src/wire/display-old.pkg
                        per_depth_imps:                 List( Per_Depth_Imps ),         # The pen-to-gcontext and draw imps for the supported depths of this screen.
                        rootwindow_per_depth_imps:      Per_Depth_Imps                  # The pen-to-gcontext and draw imps for the root window of this screen.
                      };

        Xsession
            =
            {
              xdisplay:                         dy::Xdisplay,                   #  
              screens:                          List( Screen_Info ),

              default_screen_info:              Screen_Info,

              xsocket_to_hostwindow_router:     s2t::Xsocket_To_Hostwindow_Router,          # Feeds X events to appropriate toplevel window.

              font_imp:                         fti::Font_Imp,
              atom_imp:                         ai::Atom_Imp,

              window_property_imp:              wpi::Window_Property_Imp,
              selection_imp:                    si::Selection_Imp,

              keymap_imp:                       ki::Keymap_Imp
            };

        Screen =  {                                                                     # A screen handle for users.
                    xsession:     Xsession,
                    screen_info:  Screen_Info
                  }; 

        # An on-screen pixmap:
        #
        Window =  { window_id:                  xt::Window_Id,
                    #
                    screen:                             Screen,
                    per_depth_imps:     Per_Depth_Imps,
                    #
                    to_hostwindow_drawimp:              di::d::Draw_Op -> Void
                  };

        # Identity tests:
        #
        same_xsession: (Xsession, Xsession) -> Bool;
        same_screen:   (Screen,   Screen  ) -> Bool;
        same_window:   (Window,   Window  ) -> Bool;

        open_xsession: (/* DISPLAY:*/ String, Null_Or( xt::Xauthentication )) -> Xsession;
            #
            # Start an X session with some X server.
            # 
            # Parameters:
            # 
            #     display_name:  "128.84.254.97:0.0" or such.
            #    
            #         General display_name format is:
            #    
            #             <host>:<display_number><screen_number>.
            #    
            #         display_number:
            #         screen_number:
            #             In practice these are almost always zero,
            #             since most home computers have a single
            #             display subsystem with a single logical
            #             screen, even if using two physical monitors.
            #             (My xserver box has six monitors and three
            #             graphics cards, but still gets addressed
            #             as the single screen 0.0)
            #    
            #         host:
            #             This can be "unix" to open a unix domain
            #             socket instead of the usual internet domain socket.
            #    
            #         Supported display_name abbreviations include:
            #             ""               == "unix:0.0"
            #             ":3"             == "unix:3.0"
            #             ":3.4"           == "unix:3.4"
            #             "128.84.254.97:0 == "128.84.254.97:0.0
            #
            #         Any failure to connect to the given display
            #     results in raising of the exception
            #
            #         display::BAD_ADDRESS "somestring";
            #
            #     xauthentication:
            #     See Xauthentication comments in
            #               src/lib/x-kit/xclient/xclient.api.


        # X-server I/O. 
        #
        # These just forward to the
        # Xsocket embedded in the Xsession:
        #
        send_xrequest:                          Xsession -> vector_of_one_byte_unts::Vector -> Void;
        send_xrequest_and_return_completion_mailop:     Xsession -> vector_of_one_byte_unts::Vector -> Mailop( Void );
        #
        send_xrequest_and_read_reply:           Xsession -> vector_of_one_byte_unts::Vector -> Mailop( vector_of_one_byte_unts::Vector );
        sent_xrequest_and_read_replies:   Xsession -> (vector_of_one_byte_unts::Vector, (vector_of_one_byte_unts::Vector -> Int)) -> Mailop( vector_of_one_byte_unts::Vector );
        #
        flush_out:         Xsession -> Void;
        close_xsession:    Xsession -> Void;


        # The standard X queries:
        #
        # It is possible these should be a separate
        # package, but for now it seems simplest to
        # just fold them into xsession:

        query_font
            :
            Xsession
            ->
            { font:            xt::Xid }
            ->
            {
              all_chars_exist: Bool, 
              default_char:    Int, 
              #
              char_infos:      List(xt::Char_Info), 
              draw_dir:        xt::Font_Drawing_Direction, 
              #
              font_ascent:     Int,
              font_descent:    Int, 
              #
              min_bounds:      xt::Char_Info, 
              max_bounds:      xt::Char_Info,
              #
              max_byte1:       Int, 
              min_byte1:       Int,
              #
              min_char:        Int, 
              max_char:        Int,
              #
              properties:      List(xt::Font_Prop)
            }
            ;

        # Get/set location of mouse pointer
        # relative to root window:
        #
        get_mouse_location:  Xsession -> g2d::Point;    
        set_mouse_location:  Xsession -> g2d::Point -> Void;

        query_colors
            :
            Xsession
            ->
            { cmap:     xt::Xid,
              pixels:   List(rgb8::Rgb8)
            }
            ->
            List(rgb::Rgb)
            ;

        query_best_size
            :   
            Xsession
            ->
            { drawable: xt::Xid,
              ilk:      xt::Best_Size_Ilk, 
              size:     g2d::Size
            }
            ->
            { high:     Int,
              wide:     Int
            }
            ;

        query_text_extents
            :
            Xsession
            ->
            { font:     xt::Xid,
              string:   String
            }
            ->
            { draw_direction:  xt::Font_Drawing_Direction,
              #
              font_ascent:     one_word_unt::Unt,
              font_descent:    one_word_unt::Unt, 
              #
              overall_ascent:  one_word_unt::Unt, 
              overall_descent: one_word_unt::Unt,
              #
              overall_left:    one_word_unt::Unt, 
              overall_right:   one_word_unt::Unt,
              #
              overall_width:   one_word_unt::Unt
            }
            ;

        # See   p23 http://mythryl.org/pub/exene/X-protocol-R6.pdf
        #
        query_tree
            :
            Xsession
            ->
            { window_id:        xt::Xid }
            ->
            { children:         List(xt::Xid), 
              parent:           Null_Or(xt::Xid),
              root:             xt::Xid
            }
            ;


        # NB: Rather than using the following xevent-send calls,
        #     you will often find it more convenient to use the
        #     corresponding call in
        #
        #     src/lib/x-kit/xclient/src/window/window-old.api


        # Make 'window' receive a (faked) keyboard keypress at 'point'.
        # 'window' should be the sub/window actually holding the widget to be activate.
        # 'point'  should be the click point in that window's coordinate system.
        #
        # NOTE! We send the event via the X server to provide full end-to-end testing;
        # the resulting network round trip will be quite slow, making this call
        # generally inappropriate for anything other than unit test code.
        #
        send_fake_key_press_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the keypress event.
              keycode:          xt::Keycode,                    # Keyboard key just pressed down.
              point:            g2d::Point
            }
            ->
            Void
            ;

        # Make 'window' receive a (faked) keyboard key release at 'point'.
        # 'window' should be the sub/window actually holding the widget to be activate.
        # 'point'  should be the click point in that window's coordinate system.
        #
        # NOTE! We send the event via the X server to provide full end-to-end testing;
        # the resulting network round trip will be quite slow, making this call
        # generally inappropriate for anything other than unit test code.
        #
        send_fake_key_release_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the keypress event.
              keycode:          xt::Keycode,                    # Keyboard key just pressed down.
              point:            g2d::Point
            }
            ->
            Void
            ;

        # Make 'window' receive a (faked) mousebutton click at 'point'.
        # 'window' should be the sub/window actually holding the widget to be activate.
        # 'point'  should be the click point in that window's coordinate system.
        #
        # NOTE! We send the event via the X server to provide full end-to-end testing;
        # the resulting network round trip will be quite slow, making this call
        # generally inappropriate for anything other than unit test code.
        #
        send_fake_mousebutton_press_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the mouse-button click event.
              button:           xt::Mousebutton,                # Mouse button just clicked down.
              point:            g2d::Point
            }
            ->
            Void
            ;

        # Counterpart of previous:  make 'window' receive a (faked) mousebutton release at 'point'.
        # 'window' should be the sub/window actually holding the widget to be activate.
        # 'point'  should be the button-release point in that window's coordinate system.
        #
        # NOTE! We send the event via the X server to provide full end-to-end testing;
        # the resulting network round trip will be quite slow, making this call
        # generally inappropriate for anything other than unit test code.
        #
        send_fake_mousebutton_release_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the mouse-button release event.
              button:           xt::Mousebutton,                # Mouse button just released.
              point:            g2d::Point
            }
            ->
            Void
            ;

        # This call may be used to simulate mouse "drag" operations in unit-test code.
        # 'window' should be the sub/window actually holding the widget to be activate.
        # 'point'  should be the supposed mouse-pointer location in that window's coordinate system.
        #
        # NOTE! We send the event via the X server to provide full end-to-end testing;
        # the resulting network round trip will be quite slow, making this call
        # generally inappropriate for anything other than unit test code.
        #
        send_fake_mouse_motion_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the mouse-button release event.
              buttons:          List(xt::Mousebutton),          # Mouse button(s) being dragged.
              point:            g2d::Point
            }
            ->
            Void
            ;

        # The xkit buttons react not just to mouse-up and mouse-down events but also
        # to mouse-enter and mouse-leave events, so to auto-test them propertly we
        # must synthesize those also:
        #
        send_fake_''mouse_enter''_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the event.
              point:            g2d::Point                      # End-of-event coordinate, thus should be just inside window.
            }
            ->
            Void
            ;
        #
        send_fake_''mouse_leave''_xevent
            :
            Xsession
            ->
            { window:           Window,                         # Window handling the event.
              point:            g2d::Point                      # End-of-event coordinate, thus should be just outside window.
            }
            ->
            Void
            ;

        # Return the maximum request size
        # supported by the display. This
        # information comes ultimately from
        # the connect-request reply supplied
        # by the X server:
        #
        max_request_length:  Xsession -> Int;



        # Atom operations:
        #
        # These just forward to the
        # Atom_Imp embedded in the Xsession:
        #
        make_atom:       Xsession -> String -> ai::Atom;
        find_atom:       Xsession -> String -> Null_Or( ai::Atom );
        atom_to_string:  Xsession -> ai::Atom -> String;



        # Font operations:
        #
        # These just forward to the
        # Font_Imp embedded in the Xsession:
        #
        find_else_open_font:        Xsession -> String -> fb::Font;             # Misnomer -- this version actually always opens font via round-trip to X.  But this is old code due to be discarded soon.


        default_screen_of:  Xsession -> Screen;
        screens_of:         Xsession -> List(Screen);

        get_''gui_startup_complete''_oneshot_of_xsession                        # Export to the wider world from src/lib/x-kit/xclient/src/window/xsocket-to-hostwindow-router-old.api
            :
            Xsession -> Oneshot_Maildrop(Void);

        ring_bell:          Xsession -> Int -> Void;


        # Screen functions:
        #
        color_of_screen:          cs::Color_Spec -> rgb::Rgb;

        xsession_of_screen:       Screen -> Xsession;
        root_window_of_screen:    Screen -> xt::Window_Id;

           size_of_screen:        Screen -> g2d::Size;
        mm_size_of_screen:        Screen -> g2d::Size;

        depth_of_screen:          Screen -> Int;

        display_class_of_screen:  Screen -> xt::Display_Class;

        # Extract the pen and draw imps
        # for a given depth:
        #
        per_depth_imps_for_depth:  (Screen, Int) ->  Per_Depth_Imps;

        # Map a point in the window's coordinate system
        # to the screen's coordinate system
        #
        window_point_to_screen_point:  Window -> g2d::Point -> g2d::Point;

        keysym_to_keycode: (Xsession, xt::Keysym) -> Null_Or(xt::Keycode);
    };                                                                  # api Xsession
end;                                                                    # stipulate.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext