## xclient.api
#
# Compiled by:
#
src/lib/x-kit/xclient/xclient.sublib### "You don't understand anything until you learn it more than one way."
###
### -- Marvin Minsky
### "It is the mark of an educated mind to be able
### to entertain a thought without accepting it."
###
### -- Aristotle
### "This ink of the scholar is more sacred than the blood of the martyr."
###
### -- Mohammed
### "Classes struggle,
### some classes triumph,
### others are eliminated."
###
### -- Mao Zedong
### "A good workman is known by his tools."
###
### -- proverb
### "The right word may be effective,
### but no word was ever as effective
### as a rightly timed pause."
###
### -- Mark Twain's Speeches
### "I fear the the new object-oriented systems
### may suffer the fate of LISP, in that they
### can do many things, but the complexity of
### the class hierarchies may cause them to
### collapse under their own weight."
###
### -- Bill Joy
stipulate
include package threadkit;
#
package g2d= geometry2d; # Geometry2d is from
src/lib/std/2d/geometry2d.apiherein
api Xclient {
# Core xkit types and fns.
version: { major: Int,
minor: Int,
reverse: Int,
date: String
};
version_name: String;
# Opaque types:
#
Xsession; # Xsession def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg Screen; # Screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg Window; # Window def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg Font; # Font def in
src/lib/x-kit/xclient/src/window/font-base-old.pkg Rw_Pixmap; # Rw_Pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg Ro_Pixmap; # Ro_Pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg Xcursor; # Xcursor def in
src/lib/x-kit/xclient/src/window/cursors-old.pkg Rgb8; # Rgb8 def in
src/lib/x-kit/xclient/src/color/rgb8.pkg #
eqtype Standard_Xcursor; # Standard_Xcursor def in
src/lib/x-kit/xclient/src/window/cursors-old.pkg eqtype Atom; # Atom def in
src/lib/x-kit/xclient/src/wire/xtypes.pkg exception NO_CHAR_INFO; # NO_CHAR_INFO def in
src/lib/x-kit/xclient/src/window/font-base-old.pkg exception FONT_PROPERTY_NOT_FOUND; # FONT_PROPERTY_NOT_FOUND def in
src/lib/x-kit/xclient/src/window/font-base-old.pkg exception FONT_NOT_FOUND; # FONT_NOT_FOUND def in
src/lib/x-kit/xclient/src/window/font-imp-old.pkg find_else_open_font # find_else_open_font def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg :
Xsession -> String -> Font;
# Font drawing direction:
#
Font_Drawing_Direction
= DRAW_FONT_LEFT_TO_RIGHT
| DRAW_FONT_RIGHT_TO_LEFT
;
# Font properties
#
Font_Prop
=
FONT_PROP
{
name: Atom, # Name of the property.
value: one_word_unt::Unt # Value of the property: interpret according to the property.
};
# Per-character font info:
#
Char_Info
=
CHAR_INFO
{
left_bearing: Int,
right_bearing: Int,
char_width: Int,
ascent: Int,
descent: Int,
attributes: Unt
};
font_property_of: Font -> Atom -> one_word_unt::Unt;
font_info_of
:
Font
->
{ min_bounds: Char_Info,
max_bounds: Char_Info,
#
min_char: Int,
max_char: Int
};
char_info_of: Font -> Int -> Char_Info;
text_width: Font -> String -> Int;
char_width: Font -> Char -> Int;
substr_width: Font -> (String, Int, Int) -> Int;
char_positions: Font -> String -> List(Int);
text_extents
:
Font
->
String
->
{ dir: Font_Drawing_Direction,
#
font_ascent: Int,
font_descent: Int,
#
overall_info: Char_Info
};
font_high
:
Font
->
{ ascent: Int,
descent: Int
};
# Graphics functions -- the sixteen
# possible functions of two boolean inputs:
#
Graphics_Op
= OP_CLR # 0
| OP_AND
# src AND dst
| OP_AND_NOT
# src AND NOT dst
| OP_COPY
# src
| OP_AND_INVERTED
# NOT src AND dst
| OP_NOP
# Dst
| OP_XOR
# src XOR dst
| OP_OR
# src OR dst
| OP_NOR
# NOT src AND NOT dst
| OP_EQUIV
# NOT src XOR dst
| OP_NOT
# NOT dst
| OP_OR_NOT
# src OR NOT dst
| OP_COPY_NOT
# NOT src
| OP_OR_INVERTED
# NOT src OR dst
| OP_NAND
# NOT src OR NOT dst
| OP_SET
# 1
;
Plane_Mask = PLANEMASK Unt; # This may belong elsewhere
Shape = COMPLEX_SHAPE
| NONCONVEX_SHAPE | CONVEX_SHAPE;
# "X attempts to provide a portable model of input devices;
# part of this support includes support for ``modifier keys'';
# i.e., keys that do not have an individual meaning, but which
# modify the meaning of other keys. The following sumtype
# represents the modifier keys."
#
# -- p26 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
#
Modifier_Key
= SHIFT_KEY
| LOCK_KEY | CONTROL_KEY
| MOD1KEY | MOD2KEY | MOD3KEY | MOD4KEY | MOD5KEY
| ANY_MODIFIER
;
# "The state of the modifier buttons (i.e., which are depressed)
# is represented by:"
#
# -- p26 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
eqtype Modifier_Keys_State;
# Keysyms are portable keycap representations:
#
Keysym = KEYSYM Int
| NO_SYMBOL;
# Keycodes
#
Keycode = KEYCODE Int;
# Mouse buttons
#
Mousebutton = MOUSEBUTTON Int;
# Mouse-d button states
#
eqtype Mousebuttons_State;
# Window stacking modes:
#
Stack_Mode = ABOVE
| BELOW
| TOP_IF
| BOTTOM_IF
| OPPOSITE
;
Drawable;
# "The X-protocol provides two operations for copying a rectangle
# from one drawable to another: CopyArea and CopyPlane.
#
# "To further complicate things, these operations can have replies
# in the form of GraphicsExpose and NoExpose X-events. When the
# source drawable is a window, then it is possible that some or
# all of the source rectangle might be obscured; in this case,
# the portions of the destination that did not get updated need
# to be redrawn.
#
# "In [x-kit] we provde three versions of four operations, which
# are fully synchronous."
#
# -- p21 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
# Sources for bitblt operations
#
Draw_From
= FROM_WINDOW Window
| FROM_RW_PIXMAP Rw_Pixmap
| FROM_RO_PIXMAP Ro_Pixmap
;
# Destinations for drawing operations.
# "A drawable [window] is an abstract type that collects
# together windows, [pixmaps] and overlays."
#
# -- p20 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
drawable_of_rw_pixmap: Rw_Pixmap -> Drawable;
drawable_of_window: Window -> Drawable;
depth_of_drawable: Drawable -> Int;
make_unbuffered_drawable: Drawable -> Drawable;
#
# 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.)
#
# This call is used in many of the src/lib/x-kit/tut
# programs, for example:
#
#
src/lib/x-kit/widget/old/fancy/graphviz/get-mouse-selection.pkg # X server timestamps.
#
package xserver_timestamp: api {
Xserver_Timestamp;
to_float: Xserver_Timestamp -> Float;
+ : (Xserver_Timestamp, Xserver_Timestamp) -> Xserver_Timestamp;
- : (Xserver_Timestamp, Xserver_Timestamp) -> Xserver_Timestamp;
# If you use these, remember that X server timestamps
# WRAP AROUND MONTHLY, so you cannot assume that
#
# timestamp1 < timestamp2
# => # DANGER!
# timestamp1 earlier_than timestamp2
#
< : (Xserver_Timestamp, Xserver_Timestamp) -> Bool;
<= : (Xserver_Timestamp, Xserver_Timestamp) -> Bool;
> : (Xserver_Timestamp, Xserver_Timestamp) -> Bool;
>= : (Xserver_Timestamp, Xserver_Timestamp) -> Bool;
};
# Xauthentication information.
# This type actually gets defined in:
#
#
src/lib/x-kit/xclient/src/wire/xtypes.pkg #
# At runtime this information gets extracted from
#
# ~/.Xauthority
#
# by code (e.g. get_xdisplay_string_and_xauthentication) in
#
#
src/lib/x-kit/xclient/src/stuff/authentication.pkg #
# and then passed successively to:
#
# root_window::make_root_window in
src/lib/x-kit/widget/old/basic/root-window-old.pkg # xession::open_xsession in
src/lib/x-kit/xclient/src/window/xsession-old.pkg # display::open_xdisplay in
src/lib/x-kit/xclient/src/wire/display-old.pkg # value_to_wire::encode_xserver_connection_request in
src/lib/x-kit/xclient/src/wire/value-to-wire.pkg #
# and ultimately to the X server.
#
Xauthentication
=
XAUTHENTICATION
{
family: Int, # E.g. xauthentication::family_internet
address: String, # E.g. "127.0.0.1"
display: String, # E.g. "0"
name: String, # E.g. "MIT-MAGIC-COOKIE-1"
data: vector_of_one_byte_unts::Vector # For MIT-MAGIC-COOKIE-1 this is 16 bytes (128 bits) of random data.
};
# This is our preferred vanilla color representation,
# based on a (red, green, blue) float triple representation:
Rgb;
#
# Predefine a few common colors for convenience:
#
black: Rgb;
white: Rgb;
red: Rgb;
green: Rgb;
blue: Rgb;
cyan: Rgb;
magenta: Rgb;
yellow: Rgb;
#
rgb8_color0: Rgb8;
rgb8_color1: Rgb8;
rgb8_white: Rgb8;
rgb8_black: Rgb8;
rgb8_red: Rgb8;
rgb8_green: Rgb8;
rgb8_blue: Rgb8;
rgb8_cyan: Rgb8;
rgb8_magenta: Rgb8;
rgb8_yellow: Rgb8;
#
rgb_normalize: Rgb -> Rgb;
#
rgb_from_unts: (Unt, Unt, Unt) -> Rgb;
rgb_to_unts: Rgb -> (Unt, Unt, Unt);
#
rgb_from_floats: (Float, Float, Float) -> Rgb;
rgb_to_floats: Rgb -> (Float, Float, Float);
rgb8_from_ints: (Int, Int, Int) -> Rgb8;
rgb8_from_int: Int -> Rgb8;
rgb8_from_name: String -> Rgb8;
rgb8_from_rgb: Rgb -> Rgb8;
#
rgb8_to_ints: Rgb8 -> (Int, Int, Int);
rgb8_to_int: Rgb8 -> Int;
# Identity tests:
#
same_xsession: (Xsession, Xsession) -> Bool; # same_xsession def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg same_screen: (Screen, Screen) -> Bool; # same_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg same_window: (Window, Window) -> Bool; # same_window def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg same_font: (Font, Font) -> Bool; # same_font def in
src/lib/x-kit/xclient/src/window/font-base-old.pkg same_cursor: (Xcursor, Xcursor) -> Bool; # same_cursor def in
src/lib/x-kit/xclient/src/window/cursors-old.pkg same_rgb: (Rgb, Rgb) -> Bool; # same_rgb def in
src/lib/x-kit/xclient/src/color/rgb.pkg
same_rgb8: (Rgb8, Rgb8) -> Bool; # same_rgb8 def in
src/lib/x-kit/xclient/src/color/rgb8.pkg #
same_rw_pixmap # same_rw_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg :
( Rw_Pixmap,
Rw_Pixmap
)
->
Bool;
same_ro_pixmap # same_ro_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg :
( Ro_Pixmap,
Ro_Pixmap
)
->
Bool;
# Xsession operations
#
exception XSERVER_CONNECT_ERROR String;
#
open_xsession: (String, Null_Or(Xauthentication)) -> Xsession; # open_xsession def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg close_xsession: Xsession -> Void; # close_xesession def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg default_screen_of: Xsession -> Screen; # default_screen_of def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg screens_of: Xsession -> List( Screen ); # screens_of def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg ring_bell: Xsession -> Int -> Void; # ring_bell def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg max_request_length: Xsession -> Int; # max_request_length def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg get_''gui_startup_complete''_oneshot_of_xsession # get_''gui_startup_complete''_oneshot_of_xsesion def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg :
Xsession -> Oneshot_Maildrop(Void); # See comments in
src/lib/x-kit/xclient/src/window/xsocket-to-hostwindow-router-old.api # Get/set location of mouse pointer
# relative to root window:
#
get_mouse_location: Xsession -> g2d::Point; # get_mouse_location def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg set_mouse_location: Xsession -> g2d::Point -> Void; # set_mouse_location def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg # Screen operations:
#
xsession_of_screen: Screen -> Xsession; # xsession_of_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg size_of_screen: Screen -> g2d::Size; # size_of_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg mm_size_of_screen: Screen -> g2d::Size; # mm_size_of_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg depth_of_screen: Screen -> Int; # depth_of_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg Display_Class
= STATIC_GRAY
| GRAY_SCALE
| STATIC_COLOR
| PSEUDO_COLOR
| TRUE_COLOR
| DIRECT_COLOR
;
display_class_of_screen # display_class_of_screen def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg :
Screen -> Display_Class;
# Window, rw_pixmap and ro_pixmap geometry functions:
#
depth_of_window: Window -> Int; # depth_of_window def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg depth_of_rw_pixmap: Rw_Pixmap -> Int; # depth_of_rw_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg depth_of_ro_pixmap: Ro_Pixmap -> Int; # depth_of_ro_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg #
size_of_window: Window -> g2d::Size; # size_of_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg size_of_rw_pixmap: Rw_Pixmap -> g2d::Size; # size_of_rw_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg size_of_ro_pixmap: Ro_Pixmap -> g2d::Size; # size_of_ro_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg #
shape_of_window: Window -> { upperleft: g2d::Point, size: g2d::Size, depth: Int, border_thickness: Int }; # " "
shape_of_rw_pixmap: Rw_Pixmap -> { upperleft: g2d::Point, size: g2d::Size, depth: Int, border_thickness: Int }; # " "
shape_of_ro_pixmap: Ro_Pixmap -> { upperleft: g2d::Point, size: g2d::Size, depth: Int, border_thickness: Int }; # " "
#
id_of_window: Window -> Int; # id_of_window def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg id_of_rw_pixmap: Rw_Pixmap -> Int; # id_of_rw_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg id_of_ro_pixmap: Ro_Pixmap -> Int; # id_of_ro_pixmap def in
src/lib/x-kit/xclient/src/window/draw-types-old.pkg #
# These give windows etc distinguishing marks
# visible at the application programmer level,
# which is essential for tracelog debugging.
# Client-side windows:
#
Cs_Pixmap_Old
=
CS_PIXMAP
{
size: g2d::Size,
data: List( List( vector_of_one_byte_unts::Vector ))
};
exception BAD_CS_PIXMAP_DATA;
make_clientside_pixmap_from_ascii # make_clientside_pixmap_from_ascii def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg :
(Int, List( List( String ) ))
->
Cs_Pixmap_Old;
# Rw_Pixmap and ro_pixmap operations:
#
exception BAD_PIXMAP_PARAMETER;
make_readwrite_pixmap: Screen -> (g2d::Size, Int) -> Rw_Pixmap; # make_readwrite_pixmap def in
src/lib/x-kit/xclient/src/window/rw-pixmap-old.pkg make_readwrite_pixmap_from_ascii_data: Screen -> (Int, List( List(String))) -> Rw_Pixmap; # make_readwrite_pixmap_from_ascii_data def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg make_readwrite_pixmap_from_clientside_pixmap: Screen -> Cs_Pixmap_Old -> Rw_Pixmap; # make_readwrite_pixmap_from_clientside_pixmap def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg destroy_rw_pixmap: Rw_Pixmap -> Void; # destroy_rw_pixmap def in
src/lib/x-kit/xclient/src/window/rw-pixmap-old.pkg make_readonly_pixmap_from_ascii: Screen -> (Int, List(List(String))) -> Ro_Pixmap; # make_readonly_pixmap_from_ascii def in
src/lib/x-kit/xclient/src/window/ro-pixmap-old.pkg make_readonly_pixmap_from_clientside_pixmap: Screen -> Cs_Pixmap_Old -> Ro_Pixmap; # make_ro_pixmal_from_clientside_pixmap def in
src/lib/x-kit/xclient/src/window/ro-pixmap-old.pkg make_readonly_pixmap_from_readwrite_pixmap: Rw_Pixmap -> Ro_Pixmap; # make_ro_pixmal_from_rw_pixmap def in
src/lib/x-kit/xclient/src/window/ro-pixmap-old.pkg make_clientside_pixmap_from_readwrite_pixmap: Rw_Pixmap -> Cs_Pixmap_Old; # make_clientside_pixmap_from_readwrite_pixmap def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg make_clientside_pixmap_from_readonly_pixmap: Ro_Pixmap -> Cs_Pixmap_Old; # make_clientside_pixmap_from_readonly_pixmap def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg make_clientside_pixmap_from_window: (g2d::Box, Window) -> Cs_Pixmap_Old; # make_clientside_pixmap_from_window def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg same_cs_pixmap: (Cs_Pixmap_Old, Cs_Pixmap_Old) -> Bool; # same_cs_pixmap def in
src/lib/x-kit/xclient/src/window/cs-pixmap-old.pkg # Window hashtables:
Window_Map(X);
exception WINDOW_NOT_FOUND;
make_map: Void -> Window_Map(X);
set: Window_Map(X) -> ((Window, X)) -> Void;
get: Window_Map(X) -> Window -> X;
get_and_drop: Window_Map(X) -> Window -> Null_Or(X); # Remove value by key, returning (THE value) if key is found, else NULL.
drop: Window_Map(X) -> Window -> Void; # Remove value by key. This is a no-op if key is not found.
vals_list: Window_Map(X) -> List(X);
# Colors.
#
# "This release of [x-kit] supports the most basic
# use of color supported by X: read-only access to
# the default colormap using either RGB values or
# names to specify the color. A devide-independent
# mechanism for specifying colors is part of the
# X11R5 standard. We plan to use this as the basis
# for future color support in [x-kit]."
#
# "To determine whether a screen supports color, one
# can use the function display_class_of_screen to determine
# the screen's display class. A monochrome screen,
# for example, will usually have the display class
# StaticGray and a depth of one."
#
# "Colors are specified either by name or RGB value,
# using the Color_Spec sumtype. The values 'black'
# and 'white' specify their respecive colors. A
# Color_Spec is mapped to an abstract Color value
# using the function color_of_screen. The functions
# black_of_screen and white_of_screen return the black
# and white colors for the given screen. The colors
# 'color0' and 'color1' represent the 0 and 1 pixel
# values, and are used to draw on [Pixmap]s."
#
# -- p24 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
#
Color_Spec
= CMS_NAME String
| CMS_RGB { red: Unt, green: Unt, blue: Unt }
;
get_color: Color_Spec -> Rgb;
# Cursors:
get_standard_xcursor: Xsession -> Standard_Xcursor -> Xcursor;
#
# These are currently the only cursors
# supported by x-kit.
recolor_cursor
:
{ cursor: Xcursor,
#
foreground_rgb: Rgb,
background_rgb: Rgb
}
->
Void;
change_active_grab_cursor: Xsession -> Xcursor -> Void;
#
# Change the cursor during an "active grab" of the mouse.
# Gravity (both window and bit):
#
Gravity
= FORGET_GRAVITY # Bit gravity only
| UNMAP_GRAVITY
# window gravity only
| NORTHWEST_GRAVITY
| NORTH_GRAVITY
| NORTHEAST_GRAVITY
| WEST_GRAVITY
| CENTER_GRAVITY
| EAST_GRAVITY
| SOUTHWEST_GRAVITY
| SOUTH_GRAVITY
| SOUTHEAST_GRAVITY
| STATIC_GRAVITY
;
keysym_to_keycode: (Xsession, Keysym) -> Null_Or(Keycode);
################ start of authentication stuff #################
# Motivation
# ----------
#
# When I started programming in the 1970s workstations were shipped
# with X configured to accept all client connections and most people
# left them that way; consequently, in general anyone anywhere on
# the ARPANET could in open up an X window on any other machine
# connected to the ARPANET. Requiring passwords to log onto a machine
# was considered by many people to be anti-social; Stallman used to
# advertise that he used an accountname of "rms" and password also "rms"
# as protest against the imposition of passwords. As late as 1990 muds
# were resisting the use of passwords.
#
# That was a different era; such openness is not very practical on
# today's savage Internet. Consequently some way must be found to
# restrict the set of people/machines allowed to connect to a given
# X server. The typical X authentication scheme used these days is
# MIT-MAGIC-COOKIE-1, which works roughly so:
#
# o When an X server is started, it is given a list of
# 128-bit random numbers ("cookies"); it will accept
# any X client presenting one of those cookies.
#
# o At user login XDM stores the cookie for the machine in the
# user's ~/.Xauthority file, keyed by machine address. This
# file may contain multiple cookies to allow connection to
# multiple X servers.
#
# o When an X client program is run, it looks up the X server
# (typically obtained from the DISPLAY environment variable)
# in ~/.Xauthority, locates the corresponding cookie, and
# forwards it as part of the X connection request message to
# the X server. For X clients written in C this is usually
# handled transparently by xlib.
#
# (xlib and the X server do no encryption themselves, consequently it
# is best to use ssh X forwarding to avoid sending cookies in the clear.)
#
# In this file we define an API to functionality for fetching cookies
# from ~/.Xauthority, plus related functionality for finding the proper
# .Xauthority file and parsing X server addresses obtained from DISPLAY
# environment variables. Typical usage:
#
# my (display, cookie) = get_xdisplay_string_and_xauthentication NULL;
#
# root_window = make_root_window (display, cookie);
#
# or simply
#
# root_window = make_root_window (get_xdisplay_string_and_xauthentication NULL);
#
# See for example the code in:
#
#
src/lib/x-kit/widget/old/lib/run-in-x-window-old.pkg # The different network protocol families:
#
family_internet: Int;
family_decnet: Int;
family_chaos: Int;
family_local: Int;
family_wild: Int;
get_xauthority_filename: Void -> String;
#
# Return the default name of the authentication file (either
# specified by the XAUTHORITY dictionary variable, or the
# file $HOME/.Xauthority. If neither XAUTHORITY or HOME
# are defined, then ".Xauthority" is returned.
get_xauthority_file_entry_by_address
:
{ family: Int, # family_wild, family_local, family_internet ...
address: String, # Identity of our workstation, from gethostname(2) or such.
display: String # E.g. "0" -- from "localhost:0.1" DISPLAY string or such.
}
->
Null_Or( Xauthentication );
#
# Search the default xauthority file for the first entry that
# matches the family, network address and display number. If no
# such match is found, then NULL is returned. The * value family_wild
# matches anything, as do the empty strings when given for address or display.
get_best_xauthority_file_entry_by_address
:
{ family: Int, # family_wild, family_local, family_internet ...
address: String, # Identity of our workstation, from gethostname(2) or such.
display: String, # E.g. "0" -- from "localhost:0.1" DISPLAY string or such.
#
acceptable_authentication_methods: List( String ) # E.g. [ "MIT-MAGIC-COOKIE-1" ]
}
->
Null_Or( Xauthentication );
#
# This is similar to get_xauthority_file_entry_by_address,
# except that a list of acceptable authentication methods
# is specified by the list acceptable_authentication_methods.
# This contains one or more strings like
#
# "MIT-MAGIC-COOKIE-1"
# "XDM-AUTHORIZATION-1"
# "SUN-DES-1"
# "MIT-KERBEROS-5"
#
# to match literally against the contents of ~/.Xauthority entries.
#
# Not all of these are available everywhere; the de facto standard
# method is MIT-MAGIC-COOKIE-1. For more information about the
# various authentication methods see (e.g.):
#
# man 7 Xsecurity
# http://manpages.ubuntu.com/manpages/jaunty/man7/Xsecurity.7.html
#
# We return the matching authentication info that matches the earliest
# name on the list.
#
# We return NULL if no match is found.
get_selected_xauthority_file_entries
:
(Xauthentication -> Bool)
->
String
->
List( Xauthentication );
#
# Read the specified authentication file
# (usually ~/.Xauthority) and return a list
# of the entries that satisfy the given predicate.
# Parse a string specifying an
# X display into its components:
#
parse_xdisplay_string
:
String
->
{ host: String,
display: String,
screen: String
};
# Given an optional display name, return
# the display and authentication information.
#
# If the argument is NULL we use the unix DISPLAY
# environment variable if defined else "".
#
get_xdisplay_string_and_xauthentication
:
Null_Or( String )
->
(String, Null_Or( Xauthentication ));
################ end of authentication stuff #################
# X cursor stuff gets its own subpackage:
#
package cursors_old: api {
# The "names" of the standard cursors supplied by the X server.
#
# Currently these are the only cursors supported by x-kit.
x_cursor: Standard_Xcursor;
arrow: Standard_Xcursor;
based_arrow_down: Standard_Xcursor;
based_arrow_up: Standard_Xcursor;
boat: Standard_Xcursor;
bogosity: Standard_Xcursor;
bottom_left_corner: Standard_Xcursor;
bottom_right_corner: Standard_Xcursor;
bottom_side: Standard_Xcursor;
bottom_tee: Standard_Xcursor;
box_spiral: Standard_Xcursor;
center_ptr: Standard_Xcursor;
circle: Standard_Xcursor;
clock: Standard_Xcursor;
coffee_mug: Standard_Xcursor;
cross: Standard_Xcursor;
cross_reverse: Standard_Xcursor;
crosshair: Standard_Xcursor;
diamond_cross: Standard_Xcursor;
dot: Standard_Xcursor;
dotbox: Standard_Xcursor;
double_arrow: Standard_Xcursor;
draft_large: Standard_Xcursor;
draft_small: Standard_Xcursor;
draped_box: Standard_Xcursor;
exchange: Standard_Xcursor;
fleur: Standard_Xcursor;
gobbler: Standard_Xcursor;
gumby: Standard_Xcursor;
hand1: Standard_Xcursor;
hand2: Standard_Xcursor;
heart: Standard_Xcursor;
icon: Standard_Xcursor;
iron_cross: Standard_Xcursor;
left_ptr: Standard_Xcursor;
left_side: Standard_Xcursor;
left_tee: Standard_Xcursor;
leftbutton: Standard_Xcursor;
ll_angle: Standard_Xcursor;
lr_angle: Standard_Xcursor;
man: Standard_Xcursor;
middlebutton: Standard_Xcursor;
mouse: Standard_Xcursor;
pencil: Standard_Xcursor;
pirate: Standard_Xcursor;
plus: Standard_Xcursor;
question_arrow: Standard_Xcursor;
right_ptr: Standard_Xcursor;
right_side: Standard_Xcursor;
right_tee: Standard_Xcursor;
rightbutton: Standard_Xcursor;
rtl_logo: Standard_Xcursor;
sailboat: Standard_Xcursor;
sb_down_arrow: Standard_Xcursor;
sb_h_double_arrow: Standard_Xcursor;
sb_left_arrow: Standard_Xcursor;
sb_right_arrow: Standard_Xcursor;
sb_up_arrow: Standard_Xcursor;
sb_v_double_arrow: Standard_Xcursor;
shuttle: Standard_Xcursor;
sizing: Standard_Xcursor;
spider: Standard_Xcursor;
spraycan: Standard_Xcursor;
star: Standard_Xcursor;
target: Standard_Xcursor;
tcross: Standard_Xcursor;
top_left_arrow: Standard_Xcursor;
top_left_corner: Standard_Xcursor;
top_right_corner: Standard_Xcursor;
top_side: Standard_Xcursor;
top_tee: Standard_Xcursor;
trek: Standard_Xcursor;
ul_angle: Standard_Xcursor;
umbrella: Standard_Xcursor;
ur_angle: Standard_Xcursor;
watch: Standard_Xcursor;
xterm: Standard_Xcursor;
}; # package cursors
################ start of draw stuff #################
#
package p: api {
#
Pen_Trait
= FUNCTION Graphics_Op
| PLANE_MASK Plane_Mask
| FOREGROUND Rgb8
| BACKGROUND Rgb8
| LINE_WIDTH Int
| LINE_STYLE_SOLID
| LINE_STYLE_ON_OFF_DASH
| LINE_STYLE_DOUBLE_DASH
| CAP_STYLE_NOT_LAST
| CAP_STYLE_BUTT
| CAP_STYLE_ROUND
| CAP_STYLE_PROJECTING
| JOIN_STYLE_MITER
| JOIN_STYLE_ROUND
| JOIN_STYLE_BEVEL
| FILL_STYLE_SOLID
| FILL_STYLE_TILED
| FILL_STYLE_STIPPLED
| FILL_STYLE_OPAQUE_STIPPLED
| FILL_RULE_EVEN_ODD
| FILL_RULE_WINDING
| ARC_MODE_CHORD
| ARC_MODE_PIE_SLICE
| CLIP_BY_CHILDREN
| INCLUDE_INFERIORS
| RO_PIXMAP Ro_Pixmap
| STIPPLE Ro_Pixmap
| STIPPLE_ORIGIN g2d::Point
| CLIP_ORIGIN g2d::Point
| CLIP_MASK_NONE
| CLIP_MASK Ro_Pixmap
| CLIP_MASK_UNSORTED_BOXES List( g2d::Box )
| CLIP_MASK_YSORTED_BOXES List( g2d::Box )
| CLIP_MASK_YXSORTED_BOXES List( g2d::Box )
| CLIP_MASK_YXBANDED_BOXES List( g2d::Box )
| DASH_OFFSET Int
| DASH_FIXED Int
| DASH_LIST List( Int )
;
};
# This api brings together all of the
# drawing-related types and operations.
#
# For Gansner+Reppy's original 1993 drawing docs
# see Chapter 5 (page 16) in their eXene library manual:
#
# http://mythryl.org/pub/exene/1993-lib.ps
#
# This api is implemented in
#
#
src/lib/x-kit/xclient/xclient.pkg #
# with the bulk of the code coming from:
#
#
src/lib/x-kit/xclient/src/window/draw-old.pkg Pen;
exception BAD_PEN_TRAIT;
make_pen: List(p::Pen_Trait) -> Pen;
clone_pen: (Pen, List(p::Pen_Trait)) -> Pen; # Make a copy of given pen, with given differences.
default_pen: Pen;
# Drawing operations.
#
# "The semantics are essentially the same as in xlib,
# although the names are different.
#
# "Functions that draw ``paths'' treat their List(Point)
# argument as a list of relative coordinates. The
# first element specifies an absolute coordinate and
# each successive element specifies an offset relative
# to the previous coordinate.
#
# "All other operations use absolute coordinates..
#
# "The exception BAD_DRAW_PARAMETER is raised if the
# argument to a drawable is invalid."
#
# -- p20 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
exception BAD_DRAW_PARAMETER;
draw_points: Drawable -> Pen -> List( g2d::Point ) -> Void;
draw_point_path: Drawable -> Pen -> List( g2d::Point ) -> Void;
draw_point: Drawable -> Pen -> g2d::Point -> Void;
draw_lines: Drawable -> Pen -> List( g2d::Point ) -> Void;
draw_path: Drawable -> Pen -> List( g2d::Point ) -> Void;
draw_segs: Drawable -> Pen -> List( g2d::Line ) -> Void;
draw_seg: Drawable -> Pen -> g2d::Line -> Void;
fill_polygon: Drawable -> Pen -> { verts: List( g2d::Point ), shape: Shape } -> Void;
fill_path: Drawable -> Pen -> { path: List( g2d::Point ), shape: Shape } -> Void;
draw_boxes: Drawable -> Pen -> List( g2d::Box ) -> Void;
draw_box: Drawable -> Pen -> g2d::Box -> Void;
fill_boxes: Drawable -> Pen -> List( g2d::Box ) -> Void;
fill_box: Drawable -> Pen -> g2d::Box -> Void;
draw_arcs: Drawable -> Pen -> List( g2d::Arc64 ) -> Void;
draw_arc: Drawable -> Pen -> g2d::Arc64 -> Void;
fill_arcs: Drawable -> Pen -> List( g2d::Arc64 ) -> Void;
fill_arc: Drawable -> Pen -> g2d::Arc64 -> Void;
draw_circle: Drawable -> Pen -> { center: g2d::Point, rad: Int } -> Void;
fill_circle: Drawable -> Pen -> { center: g2d::Point, rad: Int } -> Void;
# Polytext drawing.
#
# "There are two styles of text drawing: opaque and transparent.
#
# "Opaque text [...] is drawn by first filling in the bounding box
# with the background color and then drawing the text with the
# foreground color. The function and fill-style of the pen are
# ignored, replaced in effect by OP_COPY and pen::FILL_STYLE_SOLID
#
# "In transparent text [...] the pixels corresponding to bits set in
# a character's glyph are drawn using the foreground color in the
# context of the other relevant pen values, while the other pixels
# are unmodified.
#
# "The [draw_transparent_text] function provides a user-level batching
# mechanism for drawing multiple strings of the same line with possible
# intervening font changes or horizontal shifts."
#
# -- p22-3 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
package t: api {
#
Text = TEXT (Font, List(Text_Item))
#
also
Text_Item = FONT (Font, List(Text_Item))
| STRING String
| BLANK_PIXELS Int
# Skip this many pixels before next STRING.
;
};
draw_opaque_string: Drawable -> Pen -> Font -> (g2d::Point, String ) -> Void;
draw_transparent_string: Drawable -> Pen -> Font -> (g2d::Point, String ) -> Void;
draw_transparent_text: Drawable -> Pen -> (g2d::Point, t::Text) -> Void;
exception DEPTH_MISMATCH;
exception BAD_PLANE;
# *_mailop versions
# =================
#
# The synchronous (non- _mailop) versions of the
# blt operations can be slow because they have
# wait for a reply from the X server. If the
# X server is remote, this can involve a network
# round-trip of tens or even hundreds of milliseconds.
# Even if the X server is local, it can involve two
# or more slow process switches.
#
# We address this problem by providing asynchronous
# _mailop versions of these operations:
#
# pixel_blt_mailop
# bitblt_mailop
# plane_blt_mailop
# copy_blt_mailop
#
# These return mailops which will evaluate to the
# result boxlists when the relevant X events arrive
# from the X server: By doing a block_until_mailop_fires() on them
# in a throwaway thread, or by doing a select() on
# themspinning off
pixel_blt
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point
}
-> List( g2d::Box )
;
# Provides CopyArea semantics.
# Raises DEPTH_MISMATCH if 'to' and 'from'
# drawables do not have same depth.
#
# Return value is list of rectangles on
# 'to' which need to be redrawn because
# the corresponding 'from' areas were
# obscured. (This can only happen when
# 'from' is an onscreen window.)
#
# If 'from' is smaller than the 'to' box,
# the unspecified pixels are zero-filled
# -- color0.
pixel_blt_mailop
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point
}
-> threadkit::Mailop( List( g2d::Box ) )
;
# pixel_blt with asynchronous resultlist
# handling for performance: Do a select()
# or block_until_mailop_fires() on the result to obtain
# and redraw the resulting boxlist. list.
#
# If 'to' is known not to be a Window
# (i.e., if it is an Pixmap
# or Ro_Pixmap) -- or if it is known
# not to be obscured -- then the returned
# mailop can simply be discarded, since
# is the obtained boxlist will always be
# empty.
bitblt
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point
}
-> List( g2d::Box )
;
# Same as plane_blt with 'plane' == 0.
bitblt_mailop
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point
}
-> threadkit::Mailop( List( g2d::Box ) )
;
# bit_blt with asynchronous resultlist
# handling for performance: Do a select()
# or block_until_mailop_fires() on the result to obtain
# and redraw the resulting boxlist. list.
#
# If 'to' is known not to be a Window
# (i.e., if it is a Rw_Pixmap
# or Ro_Pixmap) -- or if it is known
# not to be obscured -- then the returned
# mailop can simply be discarded, since
# is the obtained boxlist will always be
# empty.
plane_blt
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point,
plane: Int
}
-> List( g2d::Box )
; #
# Provides CopyPlane semantics;
# Raises BAD_PLANE if 'plane' is not
# a legal bitplan in 'from'.
#
# Return value is list of rectangles on
# 'to' which need to be redrawn because
# the corresponding 'from' areas were
# obscured. This can only happen when
# 'from' is an onscreen Sindow: if it
# is an Rw_Pixmap or Ro_Pixmap
# the return list will always be empty.
#
# If 'from' is smaller than the 'to' box,
# the unspecified pixels are zero-filled
# -- color0.
plane_blt_mailop
: Drawable
-> Pen
-> { from: Draw_From,
from_box: g2d::Box,
to_pos: g2d::Point,
plane: Int
}
-> threadkit::Mailop( List( g2d::Box ) )
;
# plane_blt with asynchronous resultlist
# handling for performance: Do a select()
# or block_until_mailop_fires() on the result to obtain
# and redraw the resulting boxlist. list.
#
# If 'to' is known not to be a Window
# (i.e., if it is a Rw_Pixmap
# or Ro_Pixmap) -- or if it is known
# not to be obscured -- then the returned
# mailop can simply be discarded, since
# is the obtained boxlist will always be
# empty.
texture_blt: Drawable -> Pen -> { from: Ro_Pixmap, to_pos: g2d::Point } -> Void;
tile_blt: Drawable -> Pen -> { from: Ro_Pixmap, to_pos: g2d::Point } -> Void;
#
# tile_blt is a bitblt where 'from'
# is all of a depth-1 Ro_Pixmap.
copy_blt
: Drawable
-> Pen
-> { to_pos: g2d::Point,
from_box: g2d::Box
}
-> List( g2d::Box )
;
# A pixel_blt where 'to' and 'from'
# are the same drawable.
copy_blt_mailop
: Drawable
-> Pen
-> { to_pos: g2d::Point,
from_box: g2d::Box
}
-> threadkit::Mailop( List( g2d::Box ) )
;
# copy_blt with asynchronous resultlist
# handling for performance: Do a select()
# or block_until_mailop_fires() on the result to obtain
# and redraw the resulting boxlist. list.
#
# If 'to' is known not to be a Window
# (i.e., if it is a Rw_Pixmap
# or Ro_Pixmap) -- or if it is known
# not to be obscured -- then the returned
# mailop can simply be discarded, since
# is the obtained boxlist will always be
# empty.
# "Clear a rectangular region (or all) of a drawable.
#
# "For a window, these functions will with the background color;
# For an offscreen window, they fill with 0.
#
# "If the retangle's width is zero, then the cleared rectangle
# is extended to the right edge of the drawable, and if the
# height is zero, then the cleared rectangle is extended to
# the bottom of the drawable."
#
# -- p21 http://mythryl.org/pub/exene/1993-lib.ps
# (Reppy + Gansner's 1993 eXene library manual.)
#
clear_box: Drawable -> g2d::Box -> Void;
clear_drawable: Drawable -> Void; # Clear entire drawable.
# Flush all queued draw commands to X server.
# Normally the draw imp sends them in batches
# as a network optimization, flushing the
# the buffer every 40ms; this call will flush
# immediately:
#
flush: Drawable -> Void;
drawimp_thread_id_of: Drawable -> Int;
#
# This lets the application programmer tell
# which drawables use which draw imps, which
# is occasionally important when debugging,
# for example to decide if you're flushing
# the right draw imp(s) before doing a GetImage
# request to the X server.
################ end of draw stuff #################
################ start of input stuff #################
#
#
# Types and operations to support user interaction
# and other external X-events.
make_modifier_keys_state: List(Modifier_Key) -> Modifier_Keys_State;
union_of_modifier_keys_states: (Modifier_Keys_State, Modifier_Keys_State) -> Modifier_Keys_State;
intersection_of_modifier_keys_states: (Modifier_Keys_State, Modifier_Keys_State) -> Modifier_Keys_State;
modifier_keys_state_is_empty: Modifier_Keys_State -> Bool;
shift_key_is_set: Modifier_Keys_State -> Bool;
shiftlock_key_is_set: Modifier_Keys_State -> Bool;
control_key_is_set: Modifier_Keys_State -> Bool;
modifier_key_is_set: (Modifier_Keys_State, Int) -> Bool;
# Keysym to ASCII translations:
#
Keysym_To_Ascii_Mapping;
default_keysym_to_ascii_mapping: Keysym_To_Ascii_Mapping;
rebind_keysym: Keysym_To_Ascii_Mapping -> (Keysym, List(Modifier_Key), String) -> Keysym_To_Ascii_Mapping;
translate_keysym_to_ascii: Keysym_To_Ascii_Mapping -> (Keysym, Modifier_Keys_State) -> String;
make_mousebutton_state: List(Mousebutton) -> Mousebuttons_State;
union_of_mousebutton_states: (Mousebuttons_State, Mousebuttons_State) -> Mousebuttons_State;
intersection_of_mousebutton_states: (Mousebuttons_State, Mousebuttons_State) -> Mousebuttons_State;
invert_button_in_mousebutton_state: (Mousebuttons_State, Mousebutton) -> Mousebuttons_State;
no_mousebuttons_set: Mousebuttons_State -> Bool;
some_mousebutton_is_set: Mousebuttons_State -> Bool;
#
mousebutton_1_is_set: Mousebuttons_State -> Bool;
mousebutton_2_is_set: Mousebuttons_State -> Bool;
mousebutton_3_is_set: Mousebuttons_State -> Bool;
mousebutton_4_is_set: Mousebuttons_State -> Bool;
mousebutton_5_is_set: Mousebuttons_State -> Bool;
#
mousebutton_is_set: (Mousebuttons_State, Mousebutton) -> Bool;
# Keyboard messages:
#
Keyboard_Mail
= KEY_PRESS (Keysym, Modifier_Keys_State)
| KEY_RELEASE (Keysym, Modifier_Keys_State)
| KEY_CONFIG_SYNC
;
# Mouse messages:
#
Mouse_Mail
#
= MOUSE_MOTION {
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_FIRST_DOWN {
mouse_button: Mousebutton, # Button that is in transition
window_point: g2d::Point, # Mouse position in window coords
screen_point: g2d::Point, # Mouse position in screen coords
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_LAST_UP {
mouse_button: Mousebutton, # Button that is in transition.
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_DOWN {
mouse_button: Mousebutton, # Button that is in transition.
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
state: Mousebuttons_State, # State of the mouse buttons.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_UP {
mouse_button: Mousebutton, # Button that is in transition.
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
state: Mousebuttons_State, # State of the mouse buttons.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_ENTER {
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_LEAVE {
window_point: g2d::Point, # Mouse position in window coords.
screen_point: g2d::Point, # Mouse position in screen coords.
timestamp: xserver_timestamp::Xserver_Timestamp
}
| MOUSE_CONFIG_SYNC
;
# Command/control messages from parent
#
Other_Mail
= ETC_REDRAW List( g2d::Box )
| ETC_RESIZE g2d::Box
#
| ETC_CHILD_BIRTH Window
| ETC_CHILD_DEATH Window
| ETC_OWN_DEATH
;
# Command/control messages to parent (really requests)
#
Mail_To_Mom
= REQ_RESIZE # Ask mom to resize our window.
| REQ_DESTRUCTION
;
# Envelopes are delivered hop-by-hop down
# the hostwindow's widget hierarchy according
# to the route recorded on the envelope.
# Mail envelopes for hop-by-hop routing.
#
# These also carry sequence numbers so
# the original order of keyboard vs mouse
# events can be recovered when necessary:
#
Envelope X;
# Hop-by-hop envelope routing -- return
# value for route_envelope():
#
Pass_To X
= TO_SELF X # Envelope has reached its target window/widget.
| TO_CHILD Envelope(X)
# Envelope needs to be passed on down the widget hierarchy.
;
route_envelope: Envelope(X) -> Pass_To(X);
#
# Figure out next step in delivering
# an envelope -- either it is for us,
# or else it needs to be passed to
# one of our kids.
to_window: (Envelope(X), Window) -> Bool;
#
# Compare envelope to window and return
# TRUE iff envelope should be routed to
# that window for delivery.
exception NO_MATCH_WINDOW;
next_stop_for_envelope: List( (Window, X) ) -> Envelope(Y) -> X;
#
# Search a list of child windows
# and return the one matching the
# given envelope's delivery route.
#
# Raise NO_MATCH_WINDOW if there
# is no match. (Shouldn't happen.)
#
# This function does a linear sequential
# search which is usually fast enough;
# if a window has too many children for
# this to be sensible, use instead
#
# next_stop_for_envelope_via_hashtable
next_stop_for_envelope_via_hashtable: Window_Map(X) -> Envelope(Y) -> X;
#
# Faster version of above, used in
#
#
src/lib/x-kit/widget/old/basic/xevent-mail-router.pkg envelope_before: (Envelope(X), Envelope(X)) -> Bool;
#
# Compare envelopes by sequence number.
#
# Since keyboard- and mouse-event envelopes
# get routed down separate streams, it is
# possible for them to be delivered out of
# order. Most widgets do not care, but those
# which do can use this function to recover
# the original ordering.
#
# (No code currently uses this. I'm dubious
# about it -- a widget cannot know how long
# to wait for possible out-of-order envelopes
# to arrive before responding, and any waiting
# will increase system response latency, which
# is not where we want to be going.
# I suspect mouse and keyboard streams
# should be combined into one to guarantee
# in-order delivery, with suitable interface
# sugar to make this equally easy for client
# code to use. 2010-01-14 CrT. XXX BUGGO FIXME)
get_contents_of_envelope: Envelope(X) -> X;
# Widget cables:
#
Kidplug
=
KIDPLUG
{
from_keyboard': Mailop( Envelope( Keyboard_Mail) ),
from_mouse': Mailop( Envelope( Mouse_Mail ) ),
from_other': Mailop( Envelope( Other_Mail ) ),
#
to_mom: Mail_To_Mom -> Mailop( Void )
};
Momplug
=
MOMPLUG
{
keyboard_sink: Envelope( Keyboard_Mail ) -> Mailop( Void ),
mouse_sink: Envelope( Mouse_Mail ) -> Mailop( Void ),
other_sink: Envelope( Other_Mail ) -> Mailop( Void ),
#
from_kid': Mailop( Mail_To_Mom )
};
make_widget_cable
:
Void -> { kidplug: Kidplug,
momplug: Momplug
};
# Often a window will want to ignore a given
# input stream, but since communication is
# synchronous it must still read messages to
# avoid locking its parent.
#
# The following operations attach null threads
# to the given input streams, discarding all
# messages on them, and substitute a dummy stream
# that will have no traffic:
#
ignore_mouse: Kidplug -> Kidplug;
ignore_keyboard: Kidplug -> Kidplug;
ignore_mouse_and_keyboard: Kidplug -> Kidplug;
ignore_all: Kidplug -> Kidplug;
# Make a clone of the given kidplug
# in which the given stream has been
# replaced by another:
#
replace_mouse: (Kidplug, Mailop( Envelope( Mouse_Mail ))) -> Kidplug;
replace_keyboard: (Kidplug, Mailop( Envelope( Keyboard_Mail))) -> Kidplug;
replace_other: (Kidplug, Mailop( Envelope( Other_Mail ))) -> Kidplug;
# Sometimes a thread will eat messages
# on one stream while forwarding those
# on the others. A new [plug] with
# a dummy in the intercepted slot can
# be made via the appropriate 'replace'
# function from above with 'null_stream'.
# This stream will never yield a message;
# block_until_mailop_fires() on it will block forever:
#
null_stream: Mailop( Envelope(X) );
# Menus and must wait until the mouse has reached
# a stable state. 'while_mouse_state' eats mouse
# mail until a given predicate such as
#
# some_mousebutton_is_set
#
# is satisfied. For example this fun will read
# from_mouse' until mouse_button is released and
# then call action(), after which it will wait
# until all mouse buttons are up before returning:
#
# fun do_mouseclick_action (from_mouse', mouse_button, action)
# =
# loop ()
# where
# while_some_set = while_mouse_state some_mousebutton_is_set;
#
# fun loop ()
# =
# case (get_contents_of_envelope (block_until_mailop_fires from_mouse'))
# #
# MOUSE_UP { mouse_button => mouse_button', state, ... }
# =>
# if (mouse_button == mouse_button')
# #
# action ();
# while_some_set (state, from_mouse');
# else
# loop ();
# fi;
#
# MOUSE_LAST_UP _
# =>
# action ();
#
# _ => loop ();
# end;
# end;
#
# This idiom is useful for guaranteeing that the
# mouse buttons are in a stable state before handling
# more mouse button transitions.
#
# Credit: Comments and example adapted from p29 of
# http://mythryl.org/pub/exene/1993-lib.ps
#
while_mouse_state
:
(Mousebuttons_State -> Bool)
->
(Mousebuttons_State, Mailop(Mouse_Mail))
->
Void;
################ end of input stuff #################
################ start of selection stuff #################
#
#
#
Selection_Handle;
# Standard X atoms:
#
package atom: api {
#
primary: Atom;
secondary: Atom;
arc: Atom;
atom: Atom;
bitmap: Atom;
cardinal: Atom;
colormap: Atom;
cursor: Atom;
cut_buffer0: Atom;
cut_buffer1: Atom;
cut_buffer2: Atom;
cut_buffer3: Atom;
cut_buffer4: Atom;
cut_buffer5: Atom;
cut_buffer6: Atom;
cut_buffer7: Atom;
drawable: Atom;
font: Atom;
integer: Atom;
pixmap: Atom;
point: Atom;
rectangle: Atom;
resource_manager: Atom;
rgb_color_map: Atom;
rgb_best_map: Atom;
rgb_blue_map: Atom;
rgb_default_map: Atom;
rgb_gray_map: Atom;
rgb_green_map: Atom;
rgb_red_map: Atom;
string: Atom;
visualid: Atom;
window: Atom;
wm_command: Atom;
wm_hints: Atom;
wm_client_machine: Atom;
wm_icon_name: Atom;
wm_icon_size: Atom;
wm_name: Atom;
wm_normal_hints: Atom;
wm_size_hints: Atom;
wm_zoom_hints: Atom;
min_space: Atom;
norm_space: Atom;
max_space: Atom;
end_space: Atom;
superscript_x: Atom;
superscript_y: Atom;
subscript_x: Atom;
subscript_y: Atom;
underline_position: Atom;
underline_thickness: Atom;
strikeout_ascent: Atom;
strikeout_descent: Atom;
italic_angle: Atom;
x_height: Atom;
quad_width: Atom;
weight: Atom;
point_size: Atom;
resolution: Atom;
copyright: Atom;
notice: Atom;
font_name: Atom;
family_name: Atom;
full_name: Atom;
cap_height: Atom;
wm_ilk: Atom;
wm_transient_for: Atom;
};
# Properties.
# Raw data from server (in ClientMessage, property values, ...)
#
Raw_Format = RAW08
| RAW16 | RAW32;
#
Raw_Data
=
RAW_DATA
{
format: Raw_Format,
data: vector_of_one_byte_unts::Vector
};
# X property values.
#
# A property value has a type,
# which is an atom, and a value.
#
# The value is a sequence of
# 8, 16 or 32-bit items, represented
# as a format and a string.
#
Property_Value
=
PROPERTY_VALUE
{
type: Atom,
value: Raw_Data
};
exception PROPERTY_ALLOCATE;
#
# Raised, if there is not enough space to
# store a property value on the server.
# An abstract interface to a property on a window.
#
Property;
property: (Window, Atom) -> Property;
#
# Return the abstract representation of the
# named property on the specified window.
unused_property: Window -> Property;
#
# Generate a property on the specified window
# that is guaranteed to be unused.
#
# Note that once this property has
# been "deleted" its name may be reused.
#
# NOTE: eventually, properties will be finalized,
# but for the time being, programs should delete
# any allocated properties they are not using.
make_property: (Window, Property_Value) -> Property;
#
# Create a new property initialized to the given value
name_of_property: Property -> Atom;
#
# Return the atom that names the given property.
set_property: ((Property, Property_Value)) -> Void;
#
# Set the value of the property.
append_to_property: ((Property, Property_Value)) -> Void;
#
# Append the property value to the property.
# The types and formats must match.
prepend_to_property: ((Property, Property_Value)) -> Void;
#
# Prepend the property value to the property.
# The types and formats must match.
delete_property: Property -> Void;
#
# Delete the named property.
exception ROTATE_PROPERTIES;
rotate_properties: ((List( Property ), Int)) -> Void;
#
# Rotate the list of properties.
#
# Raise ROTATE_PROPERTIES if the
# properties do not belong to
# the same window.
get_property: Property -> Null_Or( Property_Value );
#
# Get the value of the property.
# Return NULL if the property
# has not been set.
# xrdb_of_screen: Return the list of strings contained in the
# XA_RESOURCE_MANAGER property of the root screen of the
# specified screen.
# This should properly belong some other place than in ICCC,
# as it has nothing to do with ICCC, except that it accesses
# data in the screen type, and uses the GetProperty functions
# of ICCC. XXX BUGGO FIXME
#
xrdb_of_screen: Screen -> List( String );
Property_Change
= NEW_VALUE
| DELETED
;
watch_property: Property -> Mailop( (Property_Change, xserver_timestamp::Xserver_Timestamp) );
#
# Return a mailop for monitoring changes
# to a property's state.
#
# Note that once a property has been deleted
# there will be no more mailops unless
# watch_property is called again.
# Hints about the window size:
#
Window_Manager_Size_Hint
= HINT_USPOSITION
| HINT_PPOSITION
| HINT_USSIZE
| HINT_PSIZE
| HINT_PMIN_SIZE g2d::Size
| HINT_PMAX_SIZE g2d::Size
| HINT_PRESIZE_INC g2d::Size
| HINT_PBASE_SIZE g2d::Size
| HINT_PWIN_GRAVITY Gravity
| HINT_PASPECT { min: (Int, Int),
max: (Int, Int)
}
;
# Window manager hints:
#
Window_Manager_Nonsize_Hint
= HINT_INPUT Bool # Does this application rely on the window
# manager to get keyboard input?
# Initial window state (choose one)
| HINT_WITHDRAWN_STATE
# o For windows that are not mapped.
| HINT_NORMAL_STATE
# o Most want to start this way.
| HINT_ICONIC_STATE
# o Application wants to start as an icon.
| HINT_ICON_RO_PIXMAP Ro_Pixmap
# Icon specified as ro_pixmap.
| HINT_ICON_PIXMAP Rw_Pixmap
# Icon specified as pixmap.
| HINT_ICON_WINDOW Window
# Icon specified as plain window.
| HINT_ICON_MASK Rw_Pixmap
# Icon mask bitmap.
| HINT_ICON_POSITION g2d::Point
# Initial position of icon.
| HINT_WINDOW_GROUP Window
# The group leader.
;
# Atom operations:
#
make_atom: Xsession -> String -> Atom;
find_atom: Xsession -> String -> Null_Or( Atom );
atom_to_string: Xsession -> Atom -> String;
# Selection owner operations:
#
acquire_selection
:
(Window, Atom, xserver_timestamp::Xserver_Timestamp)
->
Null_Or( Selection_Handle );
#
# Acquire the named selection.
selection_of: Selection_Handle -> Atom;
timestamp_of: Selection_Handle -> xserver_timestamp::Xserver_Timestamp;
selection_req_mailop
:
Selection_Handle
->
Mailop
{
target: Atom,
timestamp: Null_Or( xserver_timestamp::Xserver_Timestamp ),
reply: Null_Or( Property_Value ) -> Void
};
#
# This mailop is enabled once for each request for the selection.
# The target field is the requested target type;
# the time field is the server-time of the gesture that caused the request, and
# the reply field is a function for sending the reply.
# If the time field is NULL, this means a value of CURRENT_TIME was used.
# Strictly speaking this violates the ICCC specification, but applications
# may choose to accept it.
selection_rel_mailop
:
Selection_Handle -> Mailop( Void );
#
# This mailop becomes enabled when
# the selection is lost, either by
# the owner releasing it, or by
# some other client acquiring ownership.
release_selection: Selection_Handle -> Void;
#
# Release ownership of the selection.
# Selection requestor operations.
request_selection
:
{ window: Window,
selection: Atom,
target: Atom,
property: Atom,
timestamp: xserver_timestamp::Xserver_Timestamp
}
->
Mailop( Null_Or( Property_Value ) );
#
# Request the value of the selection.
# the window field is the requesting window,
# the selection field is the requested selection,
# the target field is the requested target type, and
# the time field is the server-time of the gesture causing the request.
#
# This returns a mailop that will become enabled
# when the reply is received.
################ end of selection stuff #################
################ start of window stuff #################
#
#
# User-level window attributes
#
package a: api {
Window_Attribute
#
= BACKGROUND_NONE
| BACKGROUND_PARENT_RELATIVE
| BACKGROUND_RO_PIXMAP Ro_Pixmap
| BACKGROUND_COLOR Rgb
| BACKGROUND_RW_PIXMAP Rw_Pixmap
#
| BORDER_COPY_FROM_PARENT
| BORDER_RW_PIXMAP Rw_Pixmap
| BORDER_RO_PIXMAP Ro_Pixmap
| BORDER_COLOR Rgb
#
| BIT_GRAVITY Gravity
| WINDOW_GRAVITY Gravity
#
| CURSOR Xcursor
| CURSOR_NONE
;
};
# Window configuration values
#
package c: api {
Window_Config
#
= ORIGIN g2d::Point
| SIZE g2d::Size
#
| BORDER_WID Int
| STACK_MODE Stack_Mode
#
| REL_STACK_MODE (Window, Stack_Mode)
;
};
# Window operations
exception BAD_WINDOW_SITE;
make_simple_top_window
:
Screen
->
{ site: g2d::Window_Site,
border_color: Rgb,
background_color: Rgb8
}
->
( Window,
Kidplug,
Mailslot(Void)
);
make_simple_subwindow
:
Window
->
{ site: g2d::Window_Site,
border_color: Null_Or( Rgb ),
background_color: Null_Or( Rgb8 )
}
->
Window;
make_transient_window
:
Window
->
{ site: g2d::Window_Site,
border_color: Rgb,
background_color: Rgb8
}
->
(Window, Kidplug);
make_simple_popup_window
:
Screen
->
{ site: g2d::Window_Site,
border_color: Rgb,
background_color: Rgb8
}
->
(Window, Kidplug);
make_input_only_window
:
Window -> g2d::Box -> Window;
# We raise this exception on operations
# such as drawing that are illegal for
# Input_Only windows.
#
exception OP_UNSUPPORTED_ON_INPUT_ONLY_WINDOWS;
# commandline is from
src/lib/std/commandline.pkg # Set the properties of a top-level window.
#
# This should be done before showing (mapping)
# the window:
#
set_window_manager_properties
:
Window
->
{
window_name: Null_Or( String ),
icon_name: Null_Or( String ),
#
commandline_arguments: List( String ), # Typically from: commandline::get_arguments ().
size_hints: List( Window_Manager_Size_Hint ),
nonsize_hints: List( Window_Manager_Nonsize_Hint ),
#
class_hints: Null_Or { resource_class: String,
resource_name: String
}
}
->
Void;
# Set the window-manager protocols
# for a window:
#
set_window_manager_protocols: Window -> List( Atom ) -> Bool;
# Various routines to reconfigure window layout:
#
configure_window: Window -> List( c::Window_Config ) -> Void;
move_window: Window -> g2d::Point -> Void;
resize_window: Window -> g2d::Size -> Void;
move_and_resize_window: Window -> g2d::Box -> Void;
# 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;
set_cursor: Window -> Null_Or( Xcursor ) -> Void;
set_background_color: Window -> Null_Or( Rgb ) -> Void;
#
# Set the background color attribute of the window.
#
# This does not immediately affect the window's contents,
# but if it is done before the window is mapped the window
# will come up with the right color.
change_window_attributes: Window -> List( a::Window_Attribute ) -> Void;
#
# Set various window attributes.
show_window: Window -> Void; # Show ("map") window. Won't actually show unless all ancestors show.
hide_window: Window -> Void; # Opposite of show.
withdraw_window: Window -> Void;
destroy_window: Window -> Void;
screen_of_window: Window -> Screen;
xsession_of_window: Window -> Xsession;
grab_keyboard: Window -> Int;
ungrab_keyboard: Window -> Int;
get_window_site: Window -> g2d::Box;
note_''seen_first_expose''_oneshot: Window -> Oneshot_Maildrop(Void) -> Void;
#
# Infrastructure -- see comments in
src/lib/x-kit/xclient/src/window/window-old.pkg get_''seen_first_expose''_oneshot_of: Window -> Null_Or(Oneshot_Maildrop(Void));
#
# This function makes the above oneshot
# available to clients with access to
# the Window but not the Widget. Clients
# with access to the Widget should use the
#
# widget::seen_first_redraw_oneshot_of
#
# call because it is guaranteed to return
# the required oneshot; the above call may
# return NULL, in which case the client thread
# will have to sleep a bit and then retry.
get_''gui_startup_complete''_oneshot_of # get_''gui_startup_complete''_oneshot_of def in
src/lib/x-kit/xclient/src/window/xsession-old.pkg :
Window -> Oneshot_Maildrop(Void); # See comments in
src/lib/x-kit/xclient/src/window/xsocket-to-hostwindow-router-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
:
{ window: Window, # Window handling the mouse-button click event.
keycode: 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
:
{ window: Window, # Window handling the mouse-button click event.
keycode: 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
:
{ window: Window, # Window handling the mouse-button click event.
button: 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
:
{ window: Window, # Window handling the mouse-button release event.
button: 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
:
{ window: Window, # Window handling the mouse-motion event.
buttons: List(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
:
{ 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
:
{ window: Window, # Window handling the event.
point: g2d::Point # End-of-event coordinate, thus should be just outside window.
}
->
Void
;
################ end of window stuff #################
}; # api Xclient
end;