diff options
Diffstat (limited to 'specs/libX11/AppC.xml')
-rw-r--r-- | specs/libX11/AppC.xml | 3352 |
1 files changed, 3352 insertions, 0 deletions
diff --git a/specs/libX11/AppC.xml b/specs/libX11/AppC.xml new file mode 100644 index 00000000..52fff317 --- /dev/null +++ b/specs/libX11/AppC.xml @@ -0,0 +1,3352 @@ +<appendix id="extensions"> +<title>Extensions</title> +<para> +<!-- .XE --> +Because X can evolve by extensions to the core protocol, +it is important that extensions not be perceived as second-class citizens. +At some point, +your favorite extensions may be adopted as additional parts of the +X Standard. +</para> +<para> +<!-- .LP --> +Therefore, there should be little to distinguish the use of an extension from +that of the core protocol. +To avoid having to initialize extensions explicitly in application programs, +it is also important that extensions perform lazy evaluations, +automatically initializing themselves when called for the first time. +</para> +<para> +<!-- .LP --> +This appendix describes techniques for writing extensions to Xlib that will +run at essentially the same performance as the core protocol requests. +</para> +<!-- .NT --> +<note><para> +It is expected that a given extension to X consists of multiple +requests. +Defining 10 new features as 10 separate extensions is a bad practice. +Rather, they should be packaged into a single extension +and should use minor opcodes to distinguish the requests. +</para></note> +<!-- .NE --> +<para> +<!-- .LP --> +The symbols and macros used for writing stubs to Xlib are listed in +<X11/Xlibint.h> . +<!-- .SH --> +Basic Protocol Support Routines +</para> +<para> +The basic protocol requests for extensions are +<function>XQueryExtension</function> +and +<function>XListExtensions .</function> +</para> +<!-- .IN "XQueryExtension" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>Bool<function> XQueryExtension</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>char<parameter> *name</parameter></paramdef> + <paramdef>int<parameter> *major_opcode_return</parameter></paramdef> + <paramdef>int<parameter> *first_event_return</parameter></paramdef> + <paramdef>int<parameter> *first_error_return</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para>Specifies the connection to the X server.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>name</term> + <listitem> + <para>Specifies the extension name.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>major_opcode_return</term> + <listitem> + <para>Returns the major opcode.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>first_event_return</term> + <listitem> + <para>Returns the first event code, if any.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>first_error_return</term> + <listitem> + <para>Returns the first error code, if any.</para> + </listitem> + </varlistentry> +</variablelist> + +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XQueryExtension</function> +function determines if the named extension is present. +If the extension is not present, +<function>XQueryExtension</function> +returns +<function>False ;</function> +otherwise, it returns +<function>True .</function> +If the extension is present, +<function>XQueryExtension</function> +returns the major opcode for the extension to major_opcode_return; +otherwise, +it returns zero. +Any minor opcode and the request formats are specific to the +extension. +If the extension involves additional event types, +<function>XQueryExtension</function> +returns the base event type code to first_event_return; +otherwise, +it returns zero. +The format of the events is specific to the extension. +If the extension involves additional error codes, +<function>XQueryExtension</function> +returns the base error code to first_error_return; +otherwise, +it returns zero. +The format of additional data in the errors is specific to the extension. +</para> +<para> +<!-- .LP --> +If the extension name is not in the Host Portable Character Encoding +the result is implementation-dependent. +Uppercase and lowercase matter; +the strings ``thing'', ``Thing'', and ``thinG'' +are all considered different names. +<!-- .IN "XListExtensions" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>char<function> **XListExtensions</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> *nextensions_return</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nextensions_return</emphasis> + </term> + <listitem> + <para> +Returns the number of extensions listed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XListExtensions </function> +function returns a list of all extensions supported by the server. +If the data returned by the server is in the Latin Portable Character Encoding, +then the returned strings are in the Host Portable Character Encoding. +Otherwise, the result is implementation-dependent. +<!-- .IN "XFreeExtensionList" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> XFreeExtensionList</function></funcdef> + <paramdef>char<parameter> **list</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>list</emphasis> + </term> + <listitem> + <para> +Specifies the list of extension names. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XFreeExtensionList</function> +function frees the memory allocated by +<function>XListExtensions .</function> +<!-- .SH --> +Hooking into Xlib +</para> +<para> +<!-- .LP --> +These functions allow you to hook into the library. +They are not normally used by application programmers but are used +by people who need to extend the core X protocol and +the X library interface. +The functions, which generate protocol requests for X, are typically +called stubs. +</para> +<para> +<!-- .LP --> +In extensions, stubs first should check to see if they have initialized +themselves on a connection. +If they have not, they then should call +<function>XInitExtension </function> +to attempt to initialize themselves on the connection. +</para> +<para> +<!-- .LP --> +If the extension needs to be informed of GC/font allocation or +deallocation or if the extension defines new event types, +the functions described here allow the extension to be +called when these events occur. +</para> +<para> +<!-- .LP --> +The +<function>XExtCodes</function> +structure returns the information from +<function>XInitExtension </function> +and is defined in +<X11/Xlib.h> : +</para> +<para> +<!-- .LP --> +<!-- .IN "XExtCodes" "" "@DEF@" --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +typedef struct _XExtCodes { /* public to extension, cannot be changed */ + int extension; /* extension number */ + int major_opcode; /* major op-code assigned by server */ + int first_event; /* first event number for the extension */ + int first_error; /* first error number for the extension */ +} XExtCodes; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .IN "XInitExtension" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>XExtCodes<function> *XInitExtension</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>char<parameter> *name</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>name</emphasis> + </term> + <listitem> + <para> +Specifies the extension name. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XInitExtension</function> +function determines if the named extension exists. +Then, it allocates storage for maintaining the +information about the extension on the connection, +chains this onto the extension list for the connection, +and returns the information the stub implementor will need to access +the extension. +If the extension does not exist, +<function>XInitExtension</function> +returns NULL. +</para> +<para> +<!-- .LP --> +If the extension name is not in the Host Portable Character Encoding, +the result is implementation-dependent. +Uppercase and lowercase matter; +the strings ``thing'', ``Thing'', and ``thinG'' +are all considered different names. +</para> +<para> +<!-- .LP --> +The extension number in the +<function>XExtCodes </function> +structure is +needed in the other calls that follow. +This extension number is unique only to a single connection. +</para> +<para> +<!-- .LP --> +<!-- .IN "XAddExtension" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>XExtCodes<function> *XAddExtension</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +For local Xlib extensions, the +<function>XAddExtension</function> +function allocates the +<function>XExtCodes</function> +structure, bumps the extension number count, +and chains the extension onto the extension list. +(This permits extensions to Xlib without requiring server extensions.) +<!-- .SH --> +Hooks into the Library +</para> +<para> +<!-- .LP --> +These functions allow you to define procedures that are to be +called when various circumstances occur. +The procedures include the creation of a new GC for a connection, +the copying of a GC, the freeing of a GC, the creating and freeing of fonts, +the conversion of events defined by extensions to and from wire +format, and the handling of errors. +</para> +<para> +<!-- .LP --> +All of these functions return the previous procedure defined for this +extension. +<!-- .IN "XESetCloseDisplay" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int <function> XESetCloseDisplay</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when the display is closed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetCloseDisplay</function> +function defines a procedure to be called whenever +<function>XCloseDisplay </function> +is called. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When +<function>XCloseDisplay </function> +is called, +your procedure is called +with these arguments: +</para> +<literallayout class="monospaced"> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +<para> +<!-- .IN "XESetCreateGC" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetCreateGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a GC is closed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetCreateGC</function> +function defines a procedure to be called whenever +a new GC is created. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When a GC is created, +your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>gc</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + GC <emphasis remap='I'>gc</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +</para> +<!-- .IN "XESetCopyGC" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetCopyGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when GC components are copied. + </para> + </listitem> + </varlistentry> +</variablelist> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetCopyGC</function> +function defines a procedure to be called whenever +a GC is copied. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When a GC is copied, +your procedure is called with these arguments: +</para> +<literallayout class="monospaced"> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>gc</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + GC <emphasis remap='I'>gc</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +<funcsynopsis> +<funcprototype> + <funcdef>int <function> *XESetFreeGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a GC is freed. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XESetFreeGC</function> +function defines a procedure to be called whenever +a GC is freed. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When a GC is freed, +your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>gc</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + GC <emphasis remap='I'>gc</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .IN "XESetCreateFont" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetCreateFont</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a font is created. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetCreateFont</function> +function defines a procedure to be called whenever +<function>XLoadQueryFont </function> +and +<function>XQueryFont</function> +are called. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When +<function>XLoadQueryFont </function> +or +<function>XQueryFont</function> +is called, +your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>fs</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XFontStruct *<emphasis remap='I'>fs</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .IN "XESetFreeFont" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetFreeFont</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a font is freed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetFreeFont</function> +function defines a procedure to be called whenever +<function>XFreeFont </function> +is called. +It returns any previously defined procedure, usually NULL. +</para> +<para> +<!-- .LP --> +When +<function>XFreeFont </function> +is called, your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>fs</emphasis>, <emphasis remap='I'>codes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XFontStruct *<emphasis remap='I'>fs</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetWireToEvent</function> +and +<function>XESetEventToWire</function> +functions allow you to define new events to the library. +An +<function>XEvent</function> +structure always has a type code (type +<function>int )</function> +as the first component. +This uniquely identifies what kind of event it is. +The second component is always the serial number (type +<function>unsigned</function> +<function>long )</function> +of the last request processed by the server. +The third component is always a Boolean (type +<function>Bool )</function> +indicating whether the event came from a +<function>SendEvent</function> +protocol request. +The fourth component is always a pointer to the display +the event was read from. +The fifth component is always a resource ID of one kind or another, +usually a window, carefully selected to be useful to toolkit dispatchers. +The fifth component should always exist, even if +the event does not have a natural destination; +if there is no value +from the protocol to put in this component, initialize it to zero. +<!-- .NT --> +There is an implementation limit such that your host event +structure size cannot be bigger than the size of the +<function>XEvent </function> +union of structures. +There also is no way to guarantee that more than 24 elements or 96 characters +in the structure will be fully portable between machines. +<!-- .NE --> +<!-- .IN "XESetWireToEvent" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetWireToEvent</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> event_number</parameter></paramdef> + <paramdef>Status<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>event_number</emphasis> + </term> + <listitem> + <para> +Specifies the event code. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when converting an event. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetWireToEvent</function> +function defines a procedure to be called when an event +needs to be converted from wire format +<function>( xEvent )</function> +to host format +<function>( XEvent ).</function> +The event number defines which protocol event number to install a +conversion procedure for. +<function>XESetWireToEvent</function> +returns any previously defined procedure. +<!-- .NT --> +You can replace a core event conversion function with one +of your own, although this is not encouraged. +It would, however, allow you to intercept a core event +and modify it before being placed in the queue or otherwise examined. +<!-- .NE --> +When Xlib needs to convert an event from wire format to host +format, your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +Status (*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>re</emphasis>, <emphasis remap='I'>event</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XEvent *<emphasis remap='I'>re</emphasis>; + xEvent *<emphasis remap='I'>event</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +Your procedure must return status to indicate if the conversion succeeded. +The re argument is a pointer to where the host format event should be stored, +and the event argument is the 32-byte wire event structure. +In the +<function>XEvent </function> +structure you are creating, +you must fill in the five required members of the event structure. +You should fill in the type member with the type specified for the +<function>xEvent </function> +structure. +You should copy all other members from the +<function>xEvent </function> +structure (wire format) to the +<function>XEvent </function> +structure (host format). +Your conversion procedure should return +<function>True</function> +if the event should be placed in the queue or +<function>False</function> +if it should not be placed in the queue. +</para> +<para> +<!-- .LP --> +To initialize the serial number component of the event, call +<function>_XSetLastRequestRead</function> +with the event and use the return value. +</para> +<para> +<!-- .LP --> +<!-- .IN "_XSetLastRequestRead" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>unsigned long<function> _XSetLastRequestRead</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>xGenericReply<parameter> *rep</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>rep</emphasis> + </term> + <listitem> + <para> +Specifies the wire event structure. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XSetLastRequestRead</function> +function computes and returns a complete serial number from the partial +serial number in the event. +<!-- .sp --> +</para> +<para> +<!-- .LP --> +<!-- .IN "XESetEventToWire" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>Status<function> *XESetEventToWire</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> event_number</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>event_number</emphasis> + </term> + <listitem> + <para> +Specifies the event code. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when converting an event. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetEventToWire</function> +function defines a procedure to be called when an event +needs to be converted from host format +<function>( XEvent ) </function> +to wire format +<function>( xEvent )</function> +form. +The event number defines which protocol event number to install a +conversion procedure for. +<function>XESetEventToWire</function> +returns any previously defined procedure. +It returns zero if the conversion fails or nonzero otherwise. +<!-- .NT --> +You can replace a core event conversion function with one +of your own, although this is not encouraged. +It would, however, allow you to intercept a core event +and modify it before being sent to another client. +<!-- .NE --> +When Xlib needs to convert an event from host format to wire format, +your procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>re</emphasis>, <emphasis remap='I'>event</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XEvent *<emphasis remap='I'>re</emphasis>; + xEvent *<emphasis remap='I'>event</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The re argument is a pointer to the host format event, +and the event argument is a pointer to where the 32-byte wire event +structure should be stored. +You should fill in the type with the type from the +<function>XEvent </function> +structure. +All other members then should be copied from the host format to the +<function>xEvent </function> +structure. +<!-- .IN "XESetWireToError" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>Bool<function> *XESetWireToError</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> error_number</parameter></paramdef> + <paramdef>Bool<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>error_number</emphasis> + </term> + <listitem> + <para> +Specifies the error code. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when an error is received. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetWireToError</function> +function defines a procedure to be called when an extension +error needs to be converted from wire format to host format. +The error number defines which protocol error code to install +the conversion procedure for. +<function>XESetWireToError</function> +returns any previously defined procedure. +</para> +<para> +<!-- .LP --> +Use this function for extension errors that contain additional error values +beyond those in a core X error, when multiple wire errors must be combined +into a single Xlib error, or when it is necessary to intercept an +X error before it is otherwise examined. +</para> +<para> +<!-- .LP --> +When Xlib needs to convert an error from wire format to host format, +the procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +Bool (*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>he</emphasis>, <emphasis remap='I'>we</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XErrorEvent *<emphasis remap='I'>he</emphasis>; + xError *<emphasis remap='I'>we</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The he argument is a pointer to where the host format error should be stored. +The structure pointed at by he is guaranteed to be as large as an +<function>XEvent</function> +structure and so can be cast to a type larger than an +<function>XErrorEvent</function> +to store additional values. +If the error is to be completely ignored by Xlib +(for example, several protocol error structures will be combined into +one Xlib error), +then the function should return +<function>False ;</function> +otherwise, it should return +<function>True .</function> +<!-- .IN "XESetError" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetError</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when an error is received. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +Inside Xlib, there are times that you may want to suppress the +calling of the external error handling when an error occurs. +This allows status to be returned on a call at the cost of the call +being synchronous (though most such functions are query operations, in any +case, and are typically programmed to be synchronous). +</para> +<para> +<!-- .LP --> +When Xlib detects a protocol error in +<function>_XReply , </function> +it calls your procedure with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +int (*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>err</emphasis>, <emphasis remap='I'>codes</emphasis>, <emphasis remap='I'>ret_code</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + xError *<emphasis remap='I'>err</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; + int *<emphasis remap='I'>ret_code</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The err argument is a pointer to the 32-byte wire format error. +The codes argument is a pointer to the extension codes structure. +The ret_code argument is the return code you may want +<function>_XReply </function> +returned to. +</para> +<para> +<!-- .LP --> +If your procedure returns a zero value, +the error is not suppressed, and +the client's error handler is called. +(For further information, see section 11.8.2.) +If your procedure returns nonzero, +the error is suppressed, and +<function>_XReply </function> +returns the value of ret_code. +<!-- .IN "XESetErrorString" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>char<function> *XESetErrorString</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>char<parameter> *(*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call to obtain an error string. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XGetErrorText </function> +function returns a string to the user for an error. +<function>XESetErrorString</function> +allows you to define a procedure to be called that +should return a pointer to the error message. +The following is an example. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>code</emphasis>, <emphasis remap='I'>codes</emphasis>, <emphasis remap='I'>buffer</emphasis>, <emphasis remap='I'>nbytes</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + int <emphasis remap='I'>code</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; + char *<emphasis remap='I'>buffer</emphasis>; + int <emphasis remap='I'>nbytes</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +Your procedure is called with the error code for every error detected. +You should copy nbytes of a null-terminated string containing the +error message into buffer. +<!-- .IN "XESetPrintErrorValues" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>void<function> *XESSetPrintErrorValues</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>void<parameter> (*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when an error is printed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetPrintErrorValues</function> +function defines a procedure to be called when an extension +error is printed, to print the error values. +Use this function for extension errors that contain additional error values +beyond those in a core X error. +It returns any previously defined procedure. +</para> +<para> +<!-- .LP --> +When Xlib needs to print an error, +the procedure is called with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +void (*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>ev</emphasis>, <emphasis remap='I'>fp</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XErrorEvent *<emphasis remap='I'>ev</emphasis>; + void *<emphasis remap='I'>fp</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The structure pointed at by ev is guaranteed to be as large as an +<function>XEvent</function> +structure and so can be cast to a type larger than an +<function>XErrorEvent</function> +to obtain additional values set by using +<function>XESetWireToError .</function> +The underlying type of the fp argument is system dependent; +on a POSIX-compliant system, fp should be cast to type FILE*. +<!-- .IN "XESetFlushGC" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetFlushGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> *(*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a GC is flushed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The procedure set by the +<function>XESetFlushGC</function> +function has the same interface as the procedure set by the +<function>XESetCopyGC</function> +function, but is called when a GC cache needs to be updated in the server. +<!-- .IN "XESetBeforeFlush" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>int<function> *XESetCopyGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>int<parameter> extension</parameter></paramdef> + <paramdef>int<parameter> *(*proc)()</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extension</emphasis> + </term> + <listitem> + <para> +Specifies the extension number. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>proc</emphasis> + </term> + <listitem> + <para> +Specifies the procedure to call when a buffer is flushed. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XESetBeforeFlush</function> +function defines a procedure to be called when data is about to be +sent to the server. When data is about to be sent, your procedure is +called one or more times with these arguments: +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +<!-- .R --> +void (*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>codes</emphasis>, <emphasis remap='I'>data</emphasis>, <emphasis remap='I'>len</emphasis>) + Display *<emphasis remap='I'>display</emphasis>; + XExtCodes *<emphasis remap='I'>codes</emphasis>; + char *<emphasis remap='I'>data</emphasis>; + long <emphasis remap='I'>len</emphasis>; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The data argument specifies a portion of the outgoing data buffer, +and its length in bytes is specified by the len argument. +Your procedure must not alter the contents of the data and must not +do additional protocol requests to the same display. +<!-- .SH --> +Hooks onto Xlib Data Structures +</para> +<para> +<!-- .LP --> +Various Xlib data structures have provisions for extension procedures +to chain extension supplied data onto a list. +These structures are +<function>GC , </function> +<function>Visual , </function> +<function>Screen , </function> +<function>ScreenFormat , </function> +<function>Display , </function> +and +<function>XFontStruct .</function> +Because the list pointer is always the first member in the structure, +a single set of procedures can be used to manipulate the data +on these lists. +</para> +<para> +<!-- .LP --> +The following structure is used in the functions in this section +and is defined in +<X11/Xlib.h> +</para> +<para> +<!-- .LP --> +<!-- .IN "XExtData" "" "@DEF@" --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +typedef struct _XExtData { + int number; /* number returned by XInitExtension */ + struct _XExtData *next; /* next item on list of data for structure */ + int (*free_private)(); /* if defined, called to free private */ + XPointer private_data; /* data private to this extension. */ +} XExtData; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +When any of the data structures listed above are freed, +the list is walked, and the structure's free procedure (if any) is called. +If free is NULL, +then the library frees both the data pointed to by the private_data member +and the structure itself. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i --> +<!-- .ta .5i --> +union { Display *display; + GC gc; + Visual *visual; + Screen *screen; + ScreenFormat *pixmap_format; + XFontStruct *font } XEDataObject; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .IN "XEHeadOfExtensionList" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>XExtData<function> **XEHeadOfExtensionList</function></funcdef> + <paramdef>XEDataObject<parameter> object</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>object</emphasis> + </term> + <listitem> + <para> +Specifies the object. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XEHeadOfExtensionList</function> +function returns a pointer to the list of extension structures attached +to the specified object. +In concert with +<function>XAddToExtensionList ,</function> +<function>XEHeadOfExtensionList</function> +allows an extension to attach arbitrary data to any of the structures +of types contained in +<function>XEDataObject .</function> +</para> +<para> +<!-- .LP --> +<!-- .IN "XAddToExtensionList" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> XAddToExtensionList</function></funcdef> + <paramdef>XExtData<parameter> **structure</parameter></paramdef> + <paramdef>XExtData<parameter> *ext_data</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>structure</emphasis> + </term> + <listitem> + <para> +Specifies the extension list. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>ext_data</emphasis> + </term> + <listitem> + <para> +Specifies the extension data structure to add. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The structure argument is a pointer to one of the data structures +enumerated above. +You must initialize ext_data->number with the extension number +before calling this function. +<!-- .IN "XFindOnExtensionList" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>XExtData<function> *XFindOnExtensionList</function></funcdef> + <paramdef>struct_XExtData<parameter> **structure</parameter></paramdef> + <paramdef>int<parameter> number</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>structure</emphasis> + </term> + <listitem> + <para> +Specifies the extension list. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>number</emphasis> + </term> + <listitem> + <para> +Specifies the extension number from +<function>XInitExtension .</function> + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>XFindOnExtensionList</function> +function returns the first extension data structure +for the extension numbered number. +It is expected that an extension will add at most one extension +data structure to any single data structure's extension data list. +There is no way to find additional structures. +</para> +<para> +<!-- .LP --> +The +<function>XAllocID </function> +macro, which allocates and returns a resource ID, is defined in +<X11/Xlib.h>. +<!-- .IN "XAllocID" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> XAllocID</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +This macro is a call through the +<function>Display</function> +structure to an internal resource ID allocator. +It returns a resource ID that you can use when creating new resources. +</para> +<para> +<!-- .LP --> +The +<function>XAllocIDs</function> +macro allocates and returns an array of resource ID. +<!-- .IN "XAllocIDs" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> XAllocIDs</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>XID<parameter> *ids_return</parameter></paramdef> + <paramdef>int<parameter> count</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>ids_return</emphasis> + </term> + <listitem> + <para> +Returns the resource IDs. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>rep</emphasis> + </term> + <listitem> + <para> +Specifies the number of resource IDs requested. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +This macro is a call through the +<function>Display</function> +structure to an internal resource ID allocator. +It returns resource IDs to the array supplied by the caller. +To correctly handle automatic reuse of resource IDs, you must call +<function>XAllocIDs</function> +when requesting multiple resource IDs. This call might generate +protocol requests. +<!-- .SH --> +GC Caching +</para> +<para> +<!-- .LP --> +GCs are cached by the library to allow merging of independent change +requests to the same GC into single protocol requests. +This is typically called a write-back cache. +Any extension procedure whose behavior depends on the contents of a GC +must flush the GC cache to make sure the server has up-to-date contents +in its GC. +</para> +<para> +<!-- .LP --> +The +<function>FlushGC</function> +macro checks the dirty bits in the library's GC structure and calls +<function>_XFlushGCCache </function> +if any elements have changed. +The +<function>FlushGC</function> +macro is defined as follows: +<!-- .IN "FlushGC" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> FlushGC</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>GC<parameter> gc</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>gc</emphasis> + </term> + <listitem> + <para> +Specifies the GC. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +Note that if you extend the GC to add additional resource ID components, +you should ensure that the library stub sends the change request immediately. +This is because a client can free a resource immediately after +using it, so if you only stored the value in the cache without +forcing a protocol request, the resource might be destroyed before being +set into the GC. +You can use the +<function>_XFlushGCCache </function> +procedure +to force the cache to be flushed. +The +<function>_XFlushGCCache </function> +procedure +is defined as follows: +<!-- .IN "_XFlushGCCache" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XFlushGCCache</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>GC<parameter> gc</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>gc</emphasis> + </term> + <listitem> + <para> +Specifies the GC. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .SH --> +Graphics Batching +</para> +<para> +<!-- .LP --> +If you extend X to add more poly graphics primitives, you may be able to +take advantage of facilities in the library to allow back-to-back +single calls to be transformed into poly requests. +This may dramatically improve performance of programs that are not +written using poly requests. +A pointer to an +<function>xReq ,</function> +called last_req in the display structure, is the last request being processed. +By checking that the last request +type, drawable, gc, and other options are the same as the new one +and that there is enough space left in the buffer, you may be able +to just extend the previous graphics request by extending the length +field of the request and appending the data to the buffer. +This can improve performance by five times or more in naive programs. +For example, here is the source for the +<function>XDrawPoint </function> +stub. +(Writing extension stubs is discussed in the next section.) +</para> +<itemizedlist> + <listitem> + <para> +<!-- .sM --> +<!-- .nf --> + +#include <X11/Xlibint.h> + +/* precompute the maximum size of batching request allowed */ + +static int size = sizeof(xPolyPointReq) + EPERBATCH * sizeof(xPoint); + +XDrawPoint(dpy, d, gc, x, y) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ +{ + xPoint *point; + LockDisplay(dpy); + FlushGC(dpy, gc); + { + register xPolyPointReq *req = (xPolyPointReq *) dpy->last_req; + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolyPoint) + && (req->drawable == d) + && (req->gc == gc->gid) + && (req->coordMode == CoordModeOrigin) + && ((dpy->bufptr + sizeof (xPoint)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < size) ) { + point = (xPoint *) dpy->bufptr; + req->length += sizeof (xPoint) >> 2; + dpy->bufptr += sizeof (xPoint); + } + + else { + GetReqExtra(PolyPoint, 4, req); /* 1 point = 4 bytes */ + req->drawable = d; + req->gc = gc->gid; + req->coordMode = CoordModeOrigin; + point = (xPoint *) (req + 1); + } + point->x = x; + point->y = y; + } + UnlockDisplay(dpy); + SyncHandle(); +} +<!-- .fi --> + </para> + </listitem> +</itemizedlist> +<para> +<!-- .LP --> +<!-- .eM --> +To keep clients from generating very long requests that may monopolize the +server, +there is a symbol defined in +<X11/Xlibint.h> +of EPERBATCH on the number of requests batched. +Most of the performance benefit occurs in the first few merged requests. +Note that +<function>FlushGC </function> +is called <emphasis remap='I'>before</emphasis> picking up the value of last_req, +because it may modify this field. +<!-- .SH --> +Writing Extension Stubs +</para> +<para> +<!-- .LP --> +All X requests always contain the length of the request, +expressed as a 16-bit quantity of 32 bits. +This means that a single request can be no more than 256K bytes in +length. +Some servers may not support single requests of such a length. +The value of dpy->max_request_size contains the maximum length as +defined by the server implementation. +For further information, +see ``X Window System Protocol.'' +<!-- .SH --> +Requests, Replies, and Xproto.h +</para> +<para> +<!-- .LP --> +The +<X11/Xproto.h> +file contains three sets of definitions that +are of interest to the stub implementor: +request names, request structures, and reply structures. +</para> +<para> +<!-- .LP --> +You need to generate a file equivalent to +<X11/Xproto.h> +for your extension and need to include it in your stub procedure. +Each stub procedure also must include +<X11/Xlibint.h> . +</para> +<para> +<!-- .LP --> +The identifiers are deliberately chosen in such a way that, if the +request is called X_DoSomething, then its request structure is +xDoSomethingReq, and its reply is xDoSomethingReply. +The GetReq family of macros, defined in +<X11/Xlibint.h> , +takes advantage of this naming scheme. +</para> +<para> +<!-- .LP --> +For each X request, +there is a definition in +<X11/Xproto.h> +that looks similar to this: +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +#define X_DoSomething 42 +</literallayout> +In your extension header file, +this will be a minor opcode, +instead of a major opcode. +<!-- .SH --> +Request Format +</para> +<para> +<!-- .LP --> +Every request contains an 8-bit major opcode and a 16-bit length field +expressed in units of 4 bytes. +Every request consists of 4 bytes of header +(containing the major opcode, the length field, and a data byte) followed by +zero or more additional bytes of data. +The length field defines the total length of the request, including the header. +The length field in a request must equal the minimum length required to contain +the request. +If the specified length is smaller or larger than the required length, +the server should generate a +<function>BadLength </function> +error. +Unused bytes in a request are not required to be zero. +Extensions should be designed in such a way that long protocol requests +can be split up into smaller requests, +if it is possible to exceed the maximum request size of the server. +The protocol guarantees the maximum request size to be no smaller than +4096 units (16384 bytes). +</para> +<para> +<!-- .LP --> +Major opcodes 128 through 255 are reserved for extensions. +Extensions are intended to contain multiple requests, +so extension requests typically have an additional minor opcode encoded +in the second data byte in the request header, +but the placement and interpretation of this minor opcode as well as all +other fields in extension requests are not defined by the core protocol. +Every request is implicitly assigned a sequence number (starting with one) +used in replies, errors, and events. +</para> +<para> +<!-- .LP --> +To help but not cure portability problems to certain machines, the +<function>B16</function> +and +<function>B32</function> +macros have been defined so that they can become bitfield specifications +on some machines. +For example, on a Cray, +these should be used for all 16-bit and 32-bit quantities, as discussed below. +</para> +<para> +<!-- .LP --> +Most protocol requests have a corresponding structure typedef in +<X11/Xproto.h>, +which looks like: +</para> +<para> +<!-- .LP --> +<!-- .IN "xDoSomethingReq" "" "@DEF@" --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +typedef struct _DoSomethingReq { + CARD8 reqType; /* X_DoSomething */ + CARD8 someDatum; /* used differently in different requests */ + CARD16 length B16; /* total # of bytes in request, divided by 4 */ + ... + /* request-specific data */ + ... +} xDoSomethingReq; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +If a core protocol request has a single 32-bit argument, +you need not declare a request structure in your extension header file. +Instead, such requests use the +<function>xResourceReq</function> +structure in +<X11/Xproto.h>. +This structure is used for any request whose single argument is a +<function>Window , </function> +<function>Pixmap ,</function> +<function>Drawable , </function> +<function>GContext , </function> +<function>Font , </function> +<function>Cursor , </function> +<function>Colormap , </function> +<function>Atom , </function> +or +<function>VisualID .</function> +</para> +<para> +<!-- .LP --> +<!-- .IN "xResourceReq" "" "@DEF@" --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +typedef struct _ResourceReq { + CARD8 reqType; /* the request type, e.g. X_DoSomething */ + BYTE pad; /* not used */ + CARD16 length B16; /* 2 (= total # of bytes in request, divided by 4) */ + CARD32 id B32; /* the Window, Drawable, Font, GContext, etc. */ +} xResourceReq; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +If convenient, +you can do something similar in your extension header file. +</para> +<para> +<!-- .LP --> +In both of these structures, +the reqType field identifies the type of the request (for example, +X_MapWindow or X_CreatePixmap). +The length field tells how long the request is +in units of 4-byte longwords. +This length includes both the request structure itself and any +variable-length data, such as strings or lists, that follow the +request structure. +Request structures come in different sizes, +but all requests are padded to be multiples of four bytes long. +</para> +<para> +<!-- .LP --> +A few protocol requests take no arguments at all. +Instead, they use the +<function>xReq </function> +structure in +<X11/Xproto.h>, +which contains only a reqType and a length (and a pad byte). +</para> +<para> +<!-- .LP --> +If the protocol request requires a reply, +then +<X11/Xproto.h> +also contains a reply structure typedef: +</para> +<para> +<!-- .LP --> +<!-- .IN "xDoSomethingReply" "" "@DEF@" --> +<!-- .sM --> +<literallayout class="monospaced"> +<!-- .TA .5i 3i --> +<!-- .ta .5i 3i --> +typedef struct _DoSomethingReply { + BYTE type; /* always X_Reply */ + BYTE someDatum; /* used differently in different requests */ + CARD16 sequenceNumber B16; /* # of requests sent so far */ + CARD32 length B32; /* # of additional bytes, divided by 4 */ + ... + /* request-specific data */ + ... +} xDoSomethingReply; +</literallayout> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +Most of these reply structures are 32 bytes long. +If there are not that many reply values, +then they contain a sufficient number of pad fields +to bring them up to 32 bytes. +The length field is the total number of bytes in the request minus 32, +divided by 4. +This length will be nonzero only if: +</para> +<itemizedlist> + <listitem> + <para> +The reply structure is followed by variable-length data, +such as a list or string. + </para> + </listitem> + <listitem> + <para> +The reply structure is longer than 32 bytes. + </para> + </listitem> +</itemizedlist> +<para> +<!-- .LP --> +Only +<function>GetWindowAttributes , </function> +<function>QueryFont , </function> +<function>QueryKeymap , </function> +and +<function>GetKeyboardControl </function> +have reply structures longer than 32 bytes in the core protocol. +</para> +<para> +<!-- .LP --> +A few protocol requests return replies that contain no data. +<X11/Xproto.h> +does not define reply structures for these. +Instead, they use the +<function>xGenericReply</function> +structure, which contains only a type, length, +and sequence number (and sufficient padding to make it 32 bytes long). +<!-- .SH --> +Starting to Write a Stub Procedure +</para> +<para> +<!-- .LP --> +An Xlib stub procedure should start like this: +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +#include "<X11/Xlibint.h> + +XDoSomething (arguments, ... ) +/* argument declarations */ +{ + +register XDoSomethingReq *req; +... +</literallayout> +If the protocol request has a reply, +then the variable declarations should include the reply structure for the request. +The following is an example: +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +xDoSomethingReply rep; +</literallayout> +<!-- .SH --> +Locking Data Structures +</para> +<para> +<!-- .LP --> +To lock the display structure for systems that +want to support multithreaded access to a single display connection, +each stub will need to lock its critical section. +Generally, this section is the point from just before the appropriate GetReq +call until all arguments to the call have been stored into the buffer. +The precise instructions needed for this locking depend upon the machine +architecture. +Two calls, which are generally implemented as macros, have been provided. +<!-- .IN "LockDisplay" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> LockDisplay</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +</para> +<para> +<!-- .LP --> +<!-- .IN "UnlockDisplay" "" "@DEF@" --> +<funcsynopsis> +<funcprototype> + <funcdef><function> UnlockDisplay</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<!-- .SH --> +Sending the Protocol Request and Arguments +</para> +<para> +<!-- .LP --> +After the variable declarations, +a stub procedure should call one of four macros defined in +<X11/Xlibint.h>: +<function>GetReq , </function> +<function>GetReqExtra , </function> +<function>GetResReq , </function> +or +<function>GetEmptyReq . </function> +All of these macros take, as their first argument, +the name of the protocol request as declared in +<X11/Xproto.h> +except with X_ removed. +Each one declares a +<function>Display </function> +structure pointer, +called dpy, and a pointer to a request structure, called req, +which is of the appropriate type. +The macro then appends the request structure to the output buffer, +fills in its type and length field, and sets req to point to it. +</para> +<para> +<!-- .LP --> +If the protocol request has no arguments (for instance, X_GrabServer), +then use +<function>GetEmptyReq .</function> +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +GetEmptyReq (DoSomething, req); +</literallayout> +If the protocol request has a single 32-bit argument (such as a +<function>Pixmap , </function> +<function>Window , </function> +<function>Drawable , </function> +<function>Atom , </function> +and so on), +then use +<function>GetResReq . </function> +The second argument to the macro is the 32-bit object. +<function>X_MapWindow </function> +is a good example. +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +GetResReq (DoSomething, rid, req); +</literallayout> +The rid argument is the +<function>Pixmap , </function> +<function>Window , </function> +or other resource ID. +</para> +<para> +<!-- .LP --> +If the protocol request takes any other argument list, +then call +<function>GetReq . </function> +After the +<function>GetReq , </function> +you need to set all the other fields in the request structure, +usually from arguments to the stub procedure. +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +GetReq (DoSomething, req); +/* fill in arguments here */ +req->arg1 = arg1; +req->arg2 = arg2; +... +</literallayout> +A few stub procedures (such as +<function>XCreateGC </function> +and +<function>XCreatePixmap ) </function> +return a resource ID to the caller but pass a resource ID as an argument +to the protocol request. +Such procedures use the macro +<function>XAllocID </function> +to allocate a resource ID from the range of IDs +that were assigned to this client when it opened the connection. +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +rid = req->rid = XAllocID(); +... +return (rid); +</literallayout> +Finally, some stub procedures transmit a fixed amount of variable-length +data after the request. +Typically, these procedures (such as +<function>XMoveWindow </function> +and +<function>XSetBackground ) </function> +are special cases of more general functions like +<function>XMoveResizeWindow </function> +and +<function>XChangeGC . </function> +These procedures use +<function>GetReqExtra , </function> +which is the same as +<function>GetReq</function> +except that it takes an additional argument (the number of +extra bytes to allocate in the output buffer after the request structure). +This number should always be a multiple of four. +<!-- .SH --> +Variable Length Arguments +</para> +<para> +<!-- .LP --> +Some protocol requests take additional variable-length data that +follow the +<function>xDoSomethingReq </function> +structure. +The format of this data varies from request to request. +Some requests require a sequence of 8-bit bytes, +others a sequence of 16-bit or 32-bit entities, +and still others a sequence of structures. +</para> +<para> +<!-- .LP --> +It is necessary to add the length of any variable-length data to the +length field of the request structure. +That length field is in units of 32-bit longwords. +If the data is a string or other sequence of 8-bit bytes, +then you must round the length up and shift it before adding: +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +req->length += (nbytes+3)>>2; +</literallayout> +To transmit variable-length data, use the +<function>Data </function> +macros. +If the data fits into the output buffer, +then this macro copies it to the buffer. +If it does not fit, however, +the +<function>Data </function> +macro calls +<function>_XSend , </function> +which transmits first the contents of the buffer and then your data. +The +<function>Data </function> +macros take three arguments: +the display, a pointer to the beginning of the data, +and the number of bytes to be sent. +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> Data</function></funcdef> + <paramdef><parameter> display</parameter></paramdef> + <paramdef>(char<parameter> *</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +<function>Data ,</function> +<function>Data16 ,</function> +and +<function>Data32</function> +are macros that may use their last argument +more than once, so that argument should be a variable rather than +an expression such as ``nitems*sizeof(item)''. +You should do that kind of computation in a separate statement before calling +them. +Use the appropriate macro when sending byte, short, or long data. +</para> +<para> +<!-- .LP --> +If the protocol request requires a reply, +then call the procedure +<function>_XSend </function> +instead of the +<function>Data </function> +macro. +<function>_XSend </function> +takes the same arguments, but because it sends your data immediately instead of +copying it into the output buffer (which would later be flushed +anyway by the following call on +<function>_XReply ), </function> +it is faster. +<!-- .SH --> +Replies +</para> +<para> +<!-- .LP --> +If the protocol request has a reply, +then call +<function>_XReply </function> +after you have finished dealing with +all the fixed-length and variable-length arguments. +<function>_XReply </function> +flushes the output buffer and waits for an +<function>xReply </function> +packet to arrive. +If any events arrive in the meantime, +<function>_XReply </function> +places them in the queue for later use. +<!-- .IN "_XReply" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>Status<function> _XReply</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>xReply<parameter> *rep</parameter></paramdef> + <paramdef>int<parameter> extra</parameter></paramdef> + <paramdef>Bool<parameter> discard</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>rep</emphasis> + </term> + <listitem> + <para> +Specifies the reply structure. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>extra</emphasis> + </term> + <listitem> + <para> +Specifies the number of 32-bit words expected after the replay. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>discard</emphasis> + </term> + <listitem> + <para> +Specifies if any data beyond that specified in the extra argument +should be discarded. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XReply </function> +function waits for a reply packet and copies its contents into the +specified rep. +<function>_XReply </function> +handles error and event packets that occur before the reply is received. +<function>_XReply </function> +takes four arguments: +</para> +<itemizedlist> + <listitem> + <para> +A +<function>Display </function> +* structure + </para> + </listitem> + <listitem> + <para> +A pointer to a reply structure (which must be cast to an +<function>xReply </function> +*) + </para> + </listitem> + <listitem> + <para> +The number of additional 32-bit words (beyond +<function>sizeof( xReply ) </function> += 32 bytes) +in the reply structure + </para> + </listitem> + <listitem> + <para> +A Boolean that indicates whether +<function>_XReply </function> +is to discard any additional bytes +beyond those it was told to read + </para> + </listitem> +</itemizedlist> +<para> +<!-- .LP --> +Because most reply structures are 32 bytes long, +the third argument is usually 0. +The only core protocol exceptions are the replies to +<function>GetWindowAttributes , </function> +<function>QueryFont , </function> +<function>QueryKeymap , </function> +and +<function>GetKeyboardControl ,</function> +which have longer replies. +</para> +<para> +<!-- .LP --> +The last argument should be +<function>False </function> +if the reply structure is followed +by additional variable-length data (such as a list or string). +It should be +<function>True </function> +if there is not any variable-length data. +<!-- .NT --> +This last argument is provided for upward-compatibility reasons +to allow a client to communicate properly with a hypothetical later +version of the server that sends more data than the client expected. +For example, some later version of +<function>GetWindowAttributes </function> +might use a +larger, but compatible, +<function>xGetWindowAttributesReply </function> +that contains additional attribute data at the end. +<!-- .NE --> +<function>_XReply </function> +returns +<function>True</function> +if it received a reply successfully or +<function>False </function> +if it received any sort of error. +</para> +<para> +<!-- .LP --> +For a request with a reply that is not followed by variable-length +data, you write something like: +</para> +<para> +<!-- .LP --> +<literallayout class="monospaced"> +<!-- .R --> +_XReply(display, (xReply *)&rep, 0, True); +*ret1 = rep.ret1; +*ret2 = rep.ret2; +*ret3 = rep.ret3; +... +UnlockDisplay(dpy); +SyncHandle(); +return (rep.ret4); +} +</literallayout> +If there is variable-length data after the reply, +change the +<function>True </function> +to +<function>False , </function> +and use the appropriate +<function>_XRead </function> +function to read the variable-length data. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XRead</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>char<parameter> *data_return</parameter></paramdef> + <paramdef>long<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>data_return</emphasis> + </term> + <listitem> + <para> +Specifies the buffer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XRead</function> +function reads the specified number of bytes into data_return. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XRead16</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>short<parameter> *data_return</parameter></paramdef> + <paramdef>long<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>data_return</emphasis> + </term> + <listitem> + <para> +Specifies the buffer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XRead16</function> +function reads the specified number of bytes, +unpacking them as 16-bit quantities, +into the specified array as shorts. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XRead32</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>long<parameter> *data_return</parameter></paramdef> + <paramdef>long<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>data_return</emphasis> + </term> + <listitem> + <para> +Specifies the buffer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XRead32</function> +function reads the specified number of bytes, +unpacking them as 32-bit quantities, +into the specified array as longs. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XRead16Pad</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>short<parameter> *data_return</parameter></paramdef> + <paramdef>long<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>data_return</emphasis> + </term> + <listitem> + <para> +Specifies the buffer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XRead16Pad</function> +function reads the specified number of bytes, +unpacking them as 16-bit quantities, +into the specified array as shorts. +If the number of bytes is not a multiple of four, +<function>_XRead16Pad</function> +reads and discards up to two additional pad bytes. +</para> +<para> +<!-- .LP --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef><function> _XReadPad</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>char<parameter> *data_return</parameter></paramdef> + <paramdef>long<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>data_return</emphasis> + </term> + <listitem> + <para> +Specifies the buffer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +The +<function>_XReadPad</function> +function reads the specified number of bytes into data_return. +If the number of bytes is not a multiple of four, +<function>_XReadPad</function> +reads and discards up to three additional pad bytes. +</para> +<para> +<!-- .LP --> +Each protocol request is a little different. +For further information, +see the Xlib sources for examples. +<!-- .SH --> +Synchronous Calling +</para> +<para> +<!-- .LP --> +Each procedure should have a call, just before returning to the user, +to a macro called +<function>SyncHandle .</function> +If synchronous mode is enabled (see +<function>XSynchronize ), </function> +the request is sent immediately. +The library, however, waits until any error the procedure could generate +at the server has been handled. +<!-- .SH --> +Allocating and Deallocating Memory +</para> +<para> +<!-- .LP --> +To support the possible reentry of these procedures, +you must observe several conventions when allocating and deallocating memory, +most often done when returning data to the user from the window +system of a size the caller could not know in advance +(for example, a list of fonts or a list of extensions). +The standard C library functions on many systems +are not protected against signals or other multithreaded uses. +The following analogies to standard I/O library functions +have been defined: +</para> +<para> +<!-- .LP --> +These should be used in place of any calls you would make to the normal +C library functions. +</para> +<para> +<!-- .LP --> +If you need a single scratch buffer inside a critical section +(for example, to pack and unpack data to and from the wire protocol), +the general memory allocators may be too expensive to use +(particularly in output functions, which are performance critical). +The following function returns a scratch buffer for use within a +critical section: +<!-- .IN "_XAllocScratch" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>char<function> *_XAllocScratch</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +This storage must only be used inside of a critical section of your +stub. The returned pointer cannot be assumed valid after any call +that might permit another thread to execute inside Xlib. For example, +the pointer cannot be assumed valid after any use of the +<function>GetReq</function> +or +<function>Data</function> +families of macros, +after any use of +<function>_XReply ,</function> +or after any use of the +<function>_XSend</function> +or +<function>_XRead</function> +families of functions. +</para> +<para> +<!-- .LP --> +<!-- .sp --> +The following function returns a scratch buffer for use across +critical sections: +<!-- .IN "_XAllocTemp" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>char<function> *_XAllocTemp</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the number of bytes required. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +This storage can be used across calls that might permit another thread to +execute inside Xlib. The storage must be explicitly returned to Xlib. +The following function returns the storage: +<!-- .IN "_XFreeTemp" "" "@DEF@" --> +<!-- .sM --> +<funcsynopsis> +<funcprototype> + <funcdef>void<function> _XFreeTemp</function></funcdef> + <paramdef>Display<parameter> *display</parameter></paramdef> + <paramdef>char<parameter> *buf</parameter></paramdef> + <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> +</funcprototype> +</funcsynopsis> +<!-- .FN --> +<variablelist> + <varlistentry> + <term> + <emphasis remap='I'>display</emphasis> + </term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>buf</emphasis> + </term> + <listitem> + <para> +Specifies the buffer to return. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis remap='I'>nbytes</emphasis> + </term> + <listitem> + <para> +Specifies the size of the buffer. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> +<para> +<!-- .LP --> +<!-- .eM --> +You must pass back the same pointer and size that were returned by +<function>_XAllocTemp .</function> +<!-- .SH --> +Portability Considerations +</para> +<para> +<!-- .LP --> +Many machine architectures, +including many of the more recent RISC architectures, +do not correctly access data at unaligned locations; +their compilers pad out structures to preserve this characteristic. +Many other machines capable of unaligned references pad inside of structures +as well to preserve alignment, because accessing aligned data is +usually much faster. +Because the library and the server use structures to access data at +arbitrary points in a byte stream, +all data in request and reply packets <emphasis remap='I'>must</emphasis> be naturally aligned; +that is, 16-bit data starts on 16-bit boundaries in the request +and 32-bit data on 32-bit boundaries. +All requests <emphasis remap='I'>must</emphasis> be a multiple of 32 bits in length to preserve +the natural alignment in the data stream. +You must pad structures out to 32-bit boundaries. +Pad information does not have to be zeroed unless you want to +preserve such fields for future use in your protocol requests. +Floating point varies radically between machines and should be +avoided completely if at all possible. +</para> +<para> +<!-- .LP --> +This code may run on machines with 16-bit ints. +So, if any integer argument, variable, or return value either can take +only nonnegative values or is declared as a +<function>CARD16</function> +in the protocol, be sure to declare it as +<function>unsigned</function> +<function>int</function> +and not as +<function>int .</function> +(This, of course, does not apply to Booleans or enumerations.) +</para> +<para> +<!-- .LP --> +Similarly, +if any integer argument or return value is declared +<function>CARD32</function> +in the protocol, +declare it as an +<function>unsigned</function> +<function>long</function> +and not as +<function>int</function> +or +<function>long .</function> +This also goes for any internal variables that may +take on values larger than the maximum 16-bit +<function>unsigned</function> +<function>int .</function> +</para> +<para> +<!-- .LP --> +The library currently assumes that a +<function>char</function> +is 8 bits, a +<function>short</function> +is 16 bits, an +<function>int</function> +is 16 or 32 bits, and a +<function>long</function> +is 32 bits. +The +<function>PackData </function> +macro is a half-hearted attempt to deal with the possibility of 32 bit shorts. +However, much more work is needed to make this work properly. +<!-- .SH --> +Deriving the Correct Extension Opcode +</para> +<para> +<!-- .LP --> +The remaining problem a writer of an extension stub procedure faces that +the core protocol does not face is to map from the call to the proper +major and minor opcodes. +While there are a number of strategies, +the simplest and fastest is outlined below. +</para> +<itemizedlist> + <listitem> + <para> +Declare an array of pointers, _NFILE long (this is normally found +in +<stdio.h> +and is the number of file descriptors supported on the system) +of type +<function>XExtCodes .</function> +Make sure these are all initialized to NULL. + </para> + </listitem> + <listitem> + <para> +When your stub is entered, your initialization test is just to use +the display pointer passed in to access the file descriptor and an index +into the array. +If the entry is NULL, then this is the first time you +are entering the procedure for this display. +Call your initialization procedure and pass to it the display pointer. + </para> + </listitem> + <listitem> + <para> +Once in your initialization procedure, call +<function>XInitExtension ;</function> +if it succeeds, store the pointer returned into this array. +Make sure to establish a close display handler to allow you to zero the entry. +Do whatever other initialization your extension requires. +(For example, install event handlers and so on.) +Your initialization procedure would normally return a pointer to the +<function>XExtCodes </function> +structure for this extension, which is what would normally +be found in your array of pointers. + </para> + </listitem> + <listitem> + <para> +After returning from your initialization procedure, +the stub can now continue normally, because it has its major opcode safely +in its hand in the +<function>XExtCodes </function> +structure. +<!-- .bp --> + </para> + </listitem> +</itemizedlist> +</appendix> |