## 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.pkgherein
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;