PreviousUpNext

15.4.1620  src/lib/x-kit/xclient/src/window/draw-types-old.pkg

## draw-types-old.pkg
#
# Types of chunks that can be drawn on (or are pixel sources).

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






###                    "The Universe is a grand book which cannot be read
###                     until one first learns to comprehend the language
###                     and become familiar with the characters in which
###                     it is composed.  It is written in the language of
###                     mathematics..."
###
###                                             -- Galilei Galileo  



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 xt =  xtypes;                       # xtypes                is from   src/lib/x-kit/xclient/src/wire/xtypes.pkg
    package sn =  xsession_old;                 # xsession_old          is from   src/lib/x-kit/xclient/src/window/xsession-old.pkg
    package di =  draw_imp_old;                 # draw_imp_old          is from   src/lib/x-kit/xclient/src/window/draw-imp-old.pkg
    package pg =  pen_guts;                     # pen_guts              is from   src/lib/x-kit/xclient/src/window/pen-guts.pkg
herein

    package   draw_types_old
    : (weak)  Draw_Types_Old                    # Draw_Types_Old        is from   src/lib/x-kit/xclient/src/window/draw-types-old.api
    {
        Window = sn::Window;


        #  An off-screen rectangular pixel array on X server:
        #
        Rw_Pixmap = { pixmap_id:        xt::Pixmap_Id,
                      screen:           sn::Screen,
                      size:             g2d::Size,
                      per_depth_imps:   sn::Per_Depth_Imps
                    };

        # Immutable pixmaps 
        #
        Ro_Pixmap = RO_PIXMAP  Rw_Pixmap;

        #  identity tests 

        same_window = sn::same_window;

        fun same_rw_pixmap
            (
              { pixmap_id=>id1, screen=>s1, ... }: Rw_Pixmap, 
              { pixmap_id=>id2, screen=>s2, ... }: Rw_Pixmap
            )
            =
            (id1 == id2) and sn::same_screen (s1, s2);

        fun same_ro_pixmap
            (  RO_PIXMAP p1,
               RO_PIXMAP p2
            )
            =
            same_rw_pixmap (p1, p2);

        # Sources for bitblt operations:
        #
        Draw_From
          = FROM_WINDOW          Window
          | FROM_RW_PIXMAP    Rw_Pixmap
          | FROM_RO_PIXMAP    Ro_Pixmap
          ;

        fun depth_of_window                   ({ per_depth_imps => { depth, ... }: sn::Per_Depth_Imps, ... }: Window)  = depth;
        fun depth_of_rw_pixmap             ({ per_depth_imps => { depth, ... }: sn::Per_Depth_Imps, ... }: Rw_Pixmap)  = depth;
        fun depth_of_ro_pixmap  (RO_PIXMAP ({ per_depth_imps => { depth, ... }: sn::Per_Depth_Imps, ... }: Rw_Pixmap)) = depth;

        fun id_of_window                   ({ window_id => xid, ... }: Window)  =  xt::xid_to_int  xid;
        fun id_of_rw_pixmap             ({ pixmap_id => xid, ... }: Rw_Pixmap)  =  xt::xid_to_int  xid;
        fun id_of_ro_pixmap  (RO_PIXMAP ({ pixmap_id => xid, ... }: Rw_Pixmap)) =  xt::xid_to_int  xid;

        fun depth_of_draw_src (FROM_WINDOW    w) =>  depth_of_window     w;
            depth_of_draw_src (FROM_RW_PIXMAP w) =>  depth_of_rw_pixmap  w;
            depth_of_draw_src (FROM_RO_PIXMAP w) =>  depth_of_ro_pixmap  w;
        end;

        fun shape_of_window ({ window_id, screen=> { xsession, ... }: sn::Screen, ... }: Window )
            =
            {   include package   value_to_wire;                                        # value_to_wire is from   src/lib/x-kit/xclient/src/wire/value-to-wire.pkg
                include package   wire_to_value;                                        # wire_to_value is from   src/lib/x-kit/xclient/src/wire/wire-to-value.pkg

                reply = block_until_mailop_fires
                            (sn::send_xrequest_and_read_reply
                                xsession
                                (encode_get_geometry { drawable=>window_id } )
                            );

                (decode_get_geometry_reply  reply)
                    ->
                    { depth, geometry=> { upperleft, size, border_thickness }: g2d::Window_Site, ... };

                { upperleft, size, depth, border_thickness };
            };

        fun shape_of_rw_pixmap ({ size, per_depth_imps => { depth, ... }: sn::Per_Depth_Imps, ... }: Rw_Pixmap)
            =
            { upperleft => g2d::point::zero,
              size,
              depth,
              border_thickness => 0
            };

        fun shape_of_ro_pixmap (RO_PIXMAP pm)
            =
            shape_of_rw_pixmap  pm;

        fun shape_of_draw_src (FROM_WINDOW w)                 =>  shape_of_window     w;
            shape_of_draw_src (FROM_RW_PIXMAP pm)             =>  shape_of_rw_pixmap  pm;
            shape_of_draw_src (FROM_RO_PIXMAP (RO_PIXMAP pm)) =>  shape_of_rw_pixmap  pm;
        end;


        fun size_of_window window
            =
            {   (shape_of_window  window) ->  r;
                #
                r.size;
            };


        fun size_of_rw_pixmap ({ size, ... }: Rw_Pixmap)
            =
            size;


        fun size_of_ro_pixmap (RO_PIXMAP pm)
            =
            size_of_rw_pixmap  pm;


        fun flush_drawimp  to_drawimp
            =
            {   done_flush_oneshot = make_oneshot_maildrop ();
                #
                to_drawimp (di::d::FLUSH done_flush_oneshot);
                #
                get_from_oneshot  done_flush_oneshot;
            };  

        fun drawimp_thread_id_of  to_drawimp
            =
            {   thread_id_oneshot = make_oneshot_maildrop ();
                #
                to_drawimp (di::d::THREAD_ID thread_id_oneshot);
                #
                get_from_oneshot  thread_id_oneshot;
            };  

        # drawables **
        #
        # these are abstract views of drawable chunks (e.g., windows or pixmaps).
        #
        package r {
            #
            Window_Or_Pixmap
              #
              = WINDOW  Window
              | PIXMAP  Rw_Pixmap
              ;
        };
        #
        Drawable =  DRAWABLE  { root:           r::Window_Or_Pixmap,
                                to_drawimp:     di::d::Draw_Op -> Void
                              };

        # Make a drawable from a window 
        #
        fun drawable_of_window (w as { to_hostwindow_drawimp => to_drawimp, ... }: Window )
            =
            DRAWABLE { root => r::WINDOW w, to_drawimp };


        # Make a drawable from a rw_pixmap 
        #
        fun drawable_of_rw_pixmap (pm as { size, per_depth_imps => { to_screen_drawimp, ... }: sn::Per_Depth_Imps, ... }: Rw_Pixmap)
            =
            DRAWABLE { root => r::PIXMAP pm, to_drawimp=>draw_command' }
            where 
                fun draw_command' (di::d::DRAW { to, pen, op => di::o::CLEAR_AREA ({ col, row, wide, high } ) } )
                        =>
                        {   fun clip (z, 0, max) =>   max - z;
                                clip (z, w, max) =>   if ((z + w) > max)   max - z;   else   w;   fi;
                            end;

                            size -> { wide => pm_wide,
                                      high => pm_high
                                    };

                            to_box =    { col,
                                          row,
                                          wide => clip (col, wide, pm_wide),
                                          high => clip (row, high, pm_high)
                                        };

                            to_screen_drawimp (di::d::DRAW {
                                  to,
                                  pen => pg::default_pen,
                                  op  => di::o::POLY_FILL_BOX [ to_box ]
                                } );

                            # The following is needed to
                            # avoid race between updating
                            # the rw_pixmap and using it as
                            # the source of a blt:
                            #
                            flush_drawimp  to_screen_drawimp;
                        };

                    draw_command' dmsg
                        =>
                        to_screen_drawimp  dmsg;
                end;
            end;

        fun depth_of_drawable (DRAWABLE { root => r::WINDOW w,  ... } ) =>   depth_of_window      w;
            depth_of_drawable (DRAWABLE { root => r::PIXMAP pm, ... } ) =>   depth_of_rw_pixmap  pm;
        end;

        # An unbuffered drawable is used to provide immediate
        # graphical response to user interaction.  Currently
        # this is implemented by transparently adding a flush
        # command after each draw command. There is probably
        # a better way.
        #
        # This call is used in many of the src/lib/x-kit/tut
        # programs, for an example in:
        #
        #     src/lib/x-kit/widget/old/fancy/graphviz/get-mouse-selection.pkg
        #
        fun make_unbuffered_drawable (DRAWABLE { root as r::WINDOW w, to_drawimp } )
                =>
                DRAWABLE
                  {
                    root,
                    to_drawimp =>   \\ msg =  {   to_drawimp  msg;
                                                  flush_drawimp  to_drawimp;
                                              }
                  };

            make_unbuffered_drawable d
                =>
                d;
        end;

        # The following exception is raised
        # if an attempt is made to use a stale
        # overlay drawable (i.e., one that has been released).
        #
        exception STALE_OVERLAY;

    };  #  draw_types_old 
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext