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