PreviousUpNext

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

## draw-types.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 pg =  pen_guts;                                                             # pen_guts                      is from   src/lib/x-kit/xclient/src/window/pen-guts.pkg
    package sn  =  xsession_junk;                                                       # xsession_junk                 is from   src/lib/x-kit/xclient/src/window/xsession-junk.pkg
    package di  =  xserver_ximp;                                                        # xserver_ximp                  is from   src/lib/x-kit/xclient/src/window/xserver-ximp.pkg
    package w2x =  windowsystem_to_xserver;                                             # windowsystem_to_xserver       is from   src/lib/x-kit/xclient/src/window/windowsystem-to-xserver.pkg
herein

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

        #  identity tests 

        same_window = sn::same_window;

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

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

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

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

        fun id_of_window                    ({ window_id => xid, ... }: sn::Window   )  =  xt::xid_to_int  xid;
        fun id_of_rw_pixmap                 ({ pixmap_id => xid, ... }: sn::Rw_Pixmap)  =  xt::xid_to_int  xid;
        fun id_of_ro_pixmap  (sn::RO_PIXMAP ({ pixmap_id => xid, ... }: sn::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, ... }: sn::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 } )
#                           );

                xsession -> { windowsystem_to_xserver, ... }: sn::Xsession;

                reply = block_until_mailop_fires
                            (windowsystem_to_xserver.xclient_to_sequencer.send_xrequest_and_read_reply
#                                                                         ============================  XXX SUCKO FIXME switch to send_xrequest_and_pass_reply
                                (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, ... }: sn::Rw_Pixmap)
            =
            { upperleft => g2d::point::zero,
              size,
              depth,
              border_thickness => 0
            };

        fun shape_of_ro_pixmap (sn::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 (sn::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, ... }: sn::Rw_Pixmap)
            =
            size;


        fun size_of_ro_pixmap (sn::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  sn::Window
              | PIXMAP  sn::Rw_Pixmap
              ;
        };
        #
        Drawable =  DRAWABLE  { root:           r::Window_Or_Pixmap,
                                draw_ops:       List( w2x::Draw_Op ) -> Void
                              };

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


        # Make a drawable from a rw_pixmap 
        #
        fun drawable_of_rw_pixmap (pm as { size, per_depth_imps => { windowsystem_to_xserver, ... }: sn::Per_Depth_Imps, ... }: sn::Rw_Pixmap)
            =
            DRAWABLE { root => r::PIXMAP pm, draw_ops }
            where 
                fun rewrite_ops  ([],  results)
                        =>
                        reverse results;

                    rewrite_ops  ({ to, pen, op => w2x::x::CLEAR_AREA ({ col, row, wide, high } ) } ! rest,  results)
                        =>
                        {   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
                                      };

                            wide   =  clip (col, wide, pm_wide);
                            high   =  clip (row, high, pm_high);

                            to_box =  { col, row, wide, high };

                            op =  { to,
                                    pen =>  pg::default_pen,
                                    op  =>  w2x::x::POLY_FILL_BOX [ to_box ]
                                  };

                            rewrite_ops (rest, op ! results);


                            # The following is needed to
                            # avoid race between updating
                            # the rw_pixmap and using it as
                            # the source of a blt:              # XXX SUCKO FIXME need to dis/confirm this. How does a race condition arise...?
                            #
#                           flush_drawimp  to_screen_drawimp;
                        };

                    rewrite_ops (op ! rest, results)
                        =>
                        rewrite_ops (rest, op ! results);
                end;

                fun draw_ops ops
                    =
                    windowsystem_to_xserver.draw_ops  (rewrite_ops (ops, []));
            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
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext