#----------------------------------------------------------------#

	Ruby X11 Client Library (RXCL)
	Copyright 2001 by Mathieu Bouchard

	$Id: Documentation,v 1.13 2001/07/02 23:01:11 matju Exp $

#----------------------------------------------------------------#

See ./Overview for general info about purpose and features.

#----------------------------------------------------------------#
ENVIRONMENT VARIABLES

X11_LOG

	-1: does not show anything. does not perform type-checking.
	(in theory)

	0: (default) with type-checking.

	1: adds some debugging messages.

	2: shows every packet passing through the socket, in hexadecimal,
	in color.

	3: also pauses whenever an error packet is received.

#----------------------------------------------------------------#
NAMESPACES

1. Files

	The current file organisation is quite arbitrary. The only two
	files that you should require directly are:

		X11/Display.rb
		X11/Keysyms.rb (includes the cursors)

2. X11 module

	All definitions in RXCL are grouped in this module.
	Byte-ordering, versions, classes, etc.

	The only exceptions are some slight additions you find at the
	beginning of X11/Type.

3. Structure

	Most of the code is in X11/Type.

	Most of the rest is data built around that code, declaring every
	type and request to be found in X11.

4. Name Conflicts

Because of name conflicts, some renamings have been done:

	type -> tipe
	class -> qlass
	display -> xdisplay

#----------------------------------------------------------------#
CALLING CONVENTIONS

1. Remote classes and methods

	Some classes define remote methods. Those are: Drawable, Window,
	Pixmap, Font, Graphics, GraphicsOnDrawable, and Display.

	On those classes you may call #rem_methods to get a hash of method
	descriptors. example:

	# get a list of Window's remote methods names.
	X11::Window.rem_methods.keys

2. Remote methods without reply

	Those are the ones that return nil. You may get
	a list of arguments to pass like this:

	# get the argument list for X11::Window#copy_area
	X11::Window.rem_methods[:reparent].in.fields

	# returns this
	[
		X11::TupleField[:parent, X11::Window],
		X11::TupleField[:point, X11::Point]]

	each TupleField gives you the name and type of an argument.
	Therefore a sample call to that #reparent method would be:

	my_window.reparent(another_window, X11::Point[200,150])

3. Remote methods with reply

	You may get the list of return values like this:

	# get the return list for X11::Window#get_geometry
	X11::Window.rem_methods[:get_geometry].out.fields

	# returns this
	
	[
		X11::TupleField[:depth, X11::Uint8, :in_header],
		X11::TupleField[:root, X11::Window],
		X11::TupleField[:rectangle, X11::Rectangle],
		X11::TupleField[:border_width, X11::Uint16]]

	which means when you do this:

	reply = my_window.get_geometry()

	you get a reply object with four attributes named as above;
	and when you do this:

	*reply = my_window.get_geometry()

	you get an reply array with four values in the same order as above;
	and when you do this:

	depth,root,rect,bord = my_window.get_geometry()

	you get four local variables with the names you prefer.

4. Sync methods with delayed reply

	You can delay a reply (that is, avoid waiting for it)
	by passing a code block:

	my_window.get_geometry() {|reply| ... }
	my_window.get_geometry() {|*reply| ... }
	my_window.get_geometry() {|depth,root,rect,bord| ... }

	which accept respectively reply-object, reply-array, and reply-locals,
	as described in the previous section.

	reception has to be triggered explicitly by X11::Display#xreceive,
	but if you want to ensure that a set of replies gets not delayed
	further than a certain point in your program, wrap them in a
	X11::Display#wait_for block like this:

	my_replies = {}
	$display.wait_for {
		my_windows.each {|a_window|
			a_window.get_geometry() {|reply|
				my_replies[a_window] = reply
			}
		}
	}
	p my_replies

5. creating remote objects

	This is still a two-step process for now.

		1. Call .new on the desired class
		2. Call initializer method (name varies from class to class)

6. destroying remote objects

	It is done through a method usually called #free or #close.
	You must not call remote methods of a freed object
	(but there is nothing to stop you yet; you will receive an
	XError for that)

#----------------------------------------------------------------#
META-TYPES

	This is the most important part of this software. Meta-types are
	types of types, from which actual X11 types are defined. They
	define the most general aspects of the X11 protocol: sets of valid
	values for every parameter, and the way they are encoded, decoded.
	The meta-types themselves are not actual X11 types though, because
	they are never sent over the wire.

1a. COMMON Type module

	This is the tough part, but it's the base for everything else. A
	"type" is not necessarily a "class". A "type" brings together a
	number of arbitrary objects as described by its === method
	(respecting the protocol of Class#===).

	include Type

		this declares a class as a metatype. Instances of that class
		should be types.

	extend Type

		this declares an object as a type.

	#===(object) -> boolean

		The type-checking method. Returns true or false, just like
		Class' idea of ===. A type in this context is not necessarily
		a class that an object is in; a type object may not even be a
		class.

1b. NEW Type module (July 2001)

	#xwrite(output,object)

		writes an object in X11 format
		using one or more calls to output.write(data).

	#xread(input) -> object

		reads an object in X11 format
		using one or more calls to output.read(byte_count).

	#xread(input,length) -> object

		for reading lists only.

1c. OLD Type module (June 2001) (no longer supported)

	#xlength -> Integer

		returns the length of the string that xpack returns
		and that xunpack takes. Some types are variable-length
		and do not support this. those should raise ItDependsError.

	#xlength(count=nil) -> Integer
	(Lists only)

		specifying count gets rid of ItDependsError.

	#xpack(object) -> chunk

		this encodes something à la X11 protocol. Note that this is
		not a method of a type member, like you could expect it to
		be. it's a method of a type, because a member does not 
		necessarily know its types, and could be encoded differently
		under different typings.

	#xpack(object,context=nil) -> chunk

		context is an optional argument that is used only in encoding
		a request tuple. it is omitted when not a request; otherwise
		it is like this:

		{
			:self  => the receiver of the original message,
			:seqid => the request sequence id,
			:reqid => the request id
					(based on receiver selector + type)
			:header => a four byte string to which the header info
					will be written.
		}

		that context should not be passed recursively.

	#xunpack(xdisplay,chunk) -> object

		this is the counterpart of xpack; t.xunpack(t.pack(object))
		should make an equal copy of object.

		the xdisplay argument is now required and is put first.
		it provides an unpacking context from which XID objects
		can be built. it is to be passed recursively.

	#xunpack(xdisplay,chunk,header=nil) -> object
	(Replies and Events only)

		header is normally nil; when unpacking a reply or event,
		it should be a string, so that additional info
		may be read from it. that header should not be passed
		recursively.

	#xunpack(xdisplay,chunk,count=nil) -> object
	(Lists only)

		for variable-length lists, specifies an exact count of the
		objects to be read.

		for fixed-length lists, this causes an error.

		That count should not be passed recursively.

2. Any

	the union of two types, usually one "big" type and a Choice
	among 1-3 possibilities.

3. Tuple

	This is a base class for classes that are principally a sequence of
	N fields, all constant. Those fields are declared using #fields_are.
	Construction of a Tuple is done by passing all the values in order.

	#fields_are gets passed a list of field specifiers. Order is important
	because it is used to convert to/from arrays and X11 chunks. Valid
	specifier formats are:

	[symbol, type]
		An ordinary field named #{symbol} that can only hold values
		of type #{type}.

	[symbol, length_type, :length]
	[symbol, data_type, :data]
		Variable-length data in two parts.

	[nil, Unused[length]]
	length
		a padding of exactly #{length} bytes inside a chunk.

	[:self, type]
		A special field that encodes the receiver in a request.

	[symbol, type, :in_header]
	[symbol, length_type, :length_in_header]
		Encodes a field in the one-byte gap inside a header.

	Tuple#format returns the array of fields as provided by fields_are;
	this includes all the encoding details.

	Tuple#fields returns a possibly smaller array of fields, intended
	for conversion to/from arrays.

4. PartialTuple

	This is a base class for classes that have a sequence of N fields, all
	constant, in which all fields are optional.
	Construction is done by passing a hash of fieldnames-to-values.
	Encoding is variable-length with implicit paddings.
	Otherwise it's much like Tuple except it has less options.

5. IntType

	This is the class of types that are subsets of Integer.

6. ChoiceType

	a ChoiceType object represents a type of value that can be any
	in a given set of symbols.

7. MultiChoiceType

	a MultiChoiceType object represents a type of integer which encodes
	a subset of a given set of symbols.

	in short, you have related flags packed together in a very small space.

8. TupleField

	Described above in the section about Tuple

9. Unused

	Described above in the section about Tuple

#----------------------------------------------------------------#

tupleclass Point, Size, Rectangle, Arc, Segment

	Represent geometry in X11

tupleclass ScreenInfo, VisualInfo, DepthInfo, FormatInfo

	Information that one gets spammed with when connecting to an
	X11 server.

module X11Socket

	Mix into a socket to add buffering and logging capacities.

class Display

	Here goes all the stuff that doesn't fit anywhere else.
	All the stuff that is global to a connection, or to the display
	itself even.

...

#----------------------------------------------------------------#
GLOSSARY

:rid = request id  (a unique number assigned to each def_remote)
:sid = sequence id (a unique number assigned to each remote call)
