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