Xserver-spec.xml revision 1b5d61b8
135c4bbdfSmrg<?xml version="1.0" encoding="ISO-8859-1"?>
235c4bbdfSmrg<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
335c4bbdfSmrg "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
435c4bbdfSmrg <!ENTITY % xorg-defs SYSTEM "defs.ent"> %xorg-defs;
535c4bbdfSmrg <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs;
635c4bbdfSmrg]>
735c4bbdfSmrg
835c4bbdfSmrg<article>
935c4bbdfSmrg  <articleinfo>
1035c4bbdfSmrg    <title>Definition of the Porting Layer for the X v11 Sample Server</title>
1135c4bbdfSmrg    <titleabbrev>X Porting Layer</titleabbrev>
1235c4bbdfSmrg    <author>
1335c4bbdfSmrg      <firstname>Susan</firstname><surname>Angebranndt</surname>
1435c4bbdfSmrg      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
1535c4bbdfSmrg    </author>
1635c4bbdfSmrg    <author>
1735c4bbdfSmrg      <firstname>Raymond</firstname><surname>Drewry</surname>
1835c4bbdfSmrg      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
1935c4bbdfSmrg    </author>
2035c4bbdfSmrg    <author>
2135c4bbdfSmrg      <firstname>Philip</firstname><surname>Karlton</surname>
2235c4bbdfSmrg      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
2335c4bbdfSmrg    </author>
2435c4bbdfSmrg    <author>
2535c4bbdfSmrg      <firstname>Todd</firstname><surname>Newman</surname>
2635c4bbdfSmrg      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
2735c4bbdfSmrg    </author>
2835c4bbdfSmrg    <author>
2935c4bbdfSmrg      <firstname>Bob</firstname><surname>Scheifler</surname>
3035c4bbdfSmrg      <affiliation><orgname>Massachusetts Institute of Technology</orgname></affiliation>
3135c4bbdfSmrg    </author>
3235c4bbdfSmrg    <author>
3335c4bbdfSmrg      <firstname>Keith</firstname><surname>Packard</surname>
3435c4bbdfSmrg      <affiliation><orgname>MIT X Consortium</orgname></affiliation>
3535c4bbdfSmrg    </author>
3635c4bbdfSmrg    <author>
3735c4bbdfSmrg      <firstname>David</firstname><othername>P.</othername><surname>Wiggins</surname>
3835c4bbdfSmrg      <affiliation><orgname>X Consortium</orgname></affiliation>
3935c4bbdfSmrg    </author>
4035c4bbdfSmrg    <author>
4135c4bbdfSmrg      <firstname>Jim</firstname><surname>Gettys</surname>
4235c4bbdfSmrg      <affiliation><orgname>X.org Foundation and Hewlett Packard</orgname></affiliation>
4335c4bbdfSmrg    </author>
4435c4bbdfSmrg    <publisher><publishername>The X.Org Foundation</publishername></publisher>
4535c4bbdfSmrg    <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
4635c4bbdfSmrg    <releaseinfo>X Server Version &xserver.version;</releaseinfo>
4735c4bbdfSmrg    <copyright><year>1994</year><holder>X Consortium, Inc.</holder></copyright>
4835c4bbdfSmrg    <copyright><year>2004</year><holder>X.org Foundation, Inc.</holder></copyright>
4935c4bbdfSmrg    <legalnotice>
5035c4bbdfSmrg      <para>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</para>
5135c4bbdfSmrg      <para>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</para>
5235c4bbdfSmrg      <para>THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</para>
5335c4bbdfSmrg      <para>LK201 and DEC are trademarks of Digital Equipment Corporation.  Macintosh and Apple are trademarks of Apple Computer, Inc.  PostScript is a trademark of Adobe Systems, Inc.  Ethernet is a trademark of Xerox Corporation.  X Window System is a trademark of the X.org Foundation, Inc.  Cray is a trademark of Cray Research, Inc.</para>
5435c4bbdfSmrg    </legalnotice>
5535c4bbdfSmrg    <pubdate>&xserver.reldate;</pubdate>
5635c4bbdfSmrg    <revhistory>
5735c4bbdfSmrg      <revision>
5835c4bbdfSmrg	<revnumber>1.0</revnumber>
5935c4bbdfSmrg	<date>27 Oct 2004</date>
6035c4bbdfSmrg	<authorinitials>sa</authorinitials>
6135c4bbdfSmrg	<revremark>Initial Version</revremark>
6235c4bbdfSmrg      </revision>
6335c4bbdfSmrg      <revision>
6435c4bbdfSmrg	<revnumber>1.1</revnumber>
6535c4bbdfSmrg	<date>27 Oct 2004</date>
6635c4bbdfSmrg	<authorinitials>bs</authorinitials>
6735c4bbdfSmrg	<revremark>Minor Revisions</revremark>
6835c4bbdfSmrg      </revision>
6935c4bbdfSmrg      <revision>
7035c4bbdfSmrg	<revnumber>2.0</revnumber>
7135c4bbdfSmrg	<date>27 Oct 2004</date>
7235c4bbdfSmrg	<authorinitials>kp</authorinitials>
7335c4bbdfSmrg	<revremark>Revised for Release 4 and 5</revremark>
7435c4bbdfSmrg      </revision>
7535c4bbdfSmrg      <revision>
7635c4bbdfSmrg	<revnumber>3.0</revnumber>
7735c4bbdfSmrg	<date>27 Oct 2004</date>
7835c4bbdfSmrg	<authorinitials>dpw</authorinitials>
7935c4bbdfSmrg	<revremark>Revised for Release 6</revremark>
8035c4bbdfSmrg      </revision>
8135c4bbdfSmrg      <revision>
8235c4bbdfSmrg	<revnumber>3.1</revnumber>
8335c4bbdfSmrg	<date>27 Oct 2004</date>
8435c4bbdfSmrg	<authorinitials>jg</authorinitials>
8535c4bbdfSmrg	<revremark>Revised for Release 6.8.2</revremark>
8635c4bbdfSmrg      </revision>
8735c4bbdfSmrg      <revision>
8835c4bbdfSmrg	<revnumber>3.2</revnumber>
8935c4bbdfSmrg	<date>17 Dec 2006</date>
9035c4bbdfSmrg	<authorinitials>efw</authorinitials>
9135c4bbdfSmrg	<revremark>DocBook conversion</revremark>
9235c4bbdfSmrg      </revision>
9335c4bbdfSmrg      <revision>
9435c4bbdfSmrg	<revnumber>3.3</revnumber>
9535c4bbdfSmrg	<date>17 Feb 2008</date>
9635c4bbdfSmrg	<authorinitials>aj</authorinitials>
9735c4bbdfSmrg	<revremark>Revised for backing store changes</revremark>
9835c4bbdfSmrg      </revision>
9935c4bbdfSmrg      <revision>
10035c4bbdfSmrg	<revnumber>3.4</revnumber>
10135c4bbdfSmrg	<date>31 Mar 2008</date>
10235c4bbdfSmrg	<authorinitials>efw</authorinitials>
10335c4bbdfSmrg	<revremark>Revised for devPrivates changes</revremark>
10435c4bbdfSmrg      </revision>
10535c4bbdfSmrg      <revision>
10635c4bbdfSmrg	<revnumber>3.5</revnumber>
10735c4bbdfSmrg	<date>July 2010</date>
10835c4bbdfSmrg	<authorinitials>ac</authorinitials>
10935c4bbdfSmrg	<revremark>Revised for Xorg 1.9 devPrivates changes
11035c4bbdfSmrg	  and 1.8 CreateNewResourceType changes</revremark>
11135c4bbdfSmrg      </revision>
11235c4bbdfSmrg      <revision>
11335c4bbdfSmrg	<revnumber>3.6</revnumber>
11435c4bbdfSmrg	<date>July 2012</date>
11535c4bbdfSmrg	<authorinitials>kp</authorinitials>
11635c4bbdfSmrg	<revremark>Revised for X server 1.13 screen-specific devPrivates changes</revremark>
11735c4bbdfSmrg      </revision>
11835c4bbdfSmrg    </revhistory>
11935c4bbdfSmrg    <abstract>
12035c4bbdfSmrg      <para>The following document explains the structure of the X Window System display server and the interfaces among the larger pieces.  It is intended as a reference for programmers who are implementing an X Display Server on their workstation hardware.  It is included with the X Window System source tape, along with the document "Strategies for Porting the X v11 Sample Server."  The order in which you should read these documents is:
12135c4bbdfSmrg      <orderedlist>
12235c4bbdfSmrg	<listitem><para>Read the first section of the "Strategies for Porting" document (Overview of Porting Process).</para></listitem>
12335c4bbdfSmrg	<listitem><para>Skim over this document (the Definition document).</para></listitem>
12435c4bbdfSmrg	<listitem><para>Skim over the remainder of the Strategies document.</para></listitem>
12535c4bbdfSmrg	<listitem><para>Start planning and working, referring to the Strategies and Definition documents.</para></listitem>
12635c4bbdfSmrg      </orderedlist>
12735c4bbdfSmrg      You may also want to look at the following documents:
12835c4bbdfSmrg      <itemizedlist>
12935c4bbdfSmrg	<listitem><para>"The X Window System" for an overview of X.</para></listitem>
13035c4bbdfSmrg	<listitem><para>"Xlib - C Language X Interface" for a view of what the client programmer sees.</para></listitem>
13135c4bbdfSmrg	<listitem><para>"X Window System Protocol" for a terse description of the byte stream protocol between the client and server.</para></listitem>
13235c4bbdfSmrg      </itemizedlist>
13335c4bbdfSmrg      </para>
13435c4bbdfSmrg      <para>To understand this document and the accompanying source code, you should know the C language.  You should be familiar with 2D graphics and windowing concepts such as clipping, bitmaps, fonts, etc.  You should have a general knowledge of the X Window System.  To implement the server code on your hardware, you need to know a lot about your hardware, its graphic display device(s), and (possibly) its networking and multitasking facilities.  This document depends a lot on the source code, so you should have a listing of the code handy.</para>
13535c4bbdfSmrg      <para>Some source in the distribution is directly compilable on your machine.  Some of it will require modification.  Other parts may have to be completely written from scratch.  The distribution also includes source for a sample implementation of a display server which runs on a very wide variety of color and monochrome displays on Linux and *BSD which you will find useful for implementing any type of X server.</para>
13635c4bbdfSmrg      <para>Note to the 2008 edition: at this time this document must be considered incomplete, though improved over the 2004 edition.  In particular, the new Render extension is still lacking good documentation, and has become vital to high performance X implementations.  Modern applications and desktop environments are now much more sensitive to good implementation of the Render extension than in most operations of the old X graphics model.  The shadow frame buffer implementation is also very useful in many circumstances, and also needs documentation.  We hope to rectify these shortcomings in our documentation in the future.  Help would be greatly appreciated.</para>
13735c4bbdfSmrg    </abstract>
13835c4bbdfSmrg  </articleinfo>
13935c4bbdfSmrg
14035c4bbdfSmrg<!-- Original authorship information:
14135c4bbdfSmrg
14235c4bbdfSmrg.OF 'Porting Layer Definition'- % -'October 27, 2004'
14335c4bbdfSmrgDefinition of the Porting Layer
14435c4bbdfSmrgfor the X v11 Sample Server
14535c4bbdfSmrgSusan Angebranndt
14635c4bbdfSmrgRaymond Drewry
14735c4bbdfSmrgPhilip Karlton
14835c4bbdfSmrgTodd Newman
14935c4bbdfSmrgDigital Equipment Corporation
15035c4bbdfSmrg
15135c4bbdfSmrgminor revisions by
15235c4bbdfSmrgBob Scheifler
15335c4bbdfSmrgMassachusetts Institute of Technology
15435c4bbdfSmrg
15535c4bbdfSmrgRevised for Release 4 and Release 5 by
15635c4bbdfSmrgKeith Packard
15735c4bbdfSmrgMIT X Consortium
15835c4bbdfSmrg
15935c4bbdfSmrgRevised for Release 6 by
16035c4bbdfSmrgDavid P. Wiggins
16135c4bbdfSmrgX Consortium
16235c4bbdfSmrg
16335c4bbdfSmrgMinor Revisions for Release 6.8.2 by
16435c4bbdfSmrgJim Gettys
16535c4bbdfSmrgX.org Foundation and Hewlett Packard
16635c4bbdfSmrg-->
16735c4bbdfSmrg
16835c4bbdfSmrg<section>
16935c4bbdfSmrg  <title>The X Window System</title>
17035c4bbdfSmrg<para>
17135c4bbdfSmrgThe X Window System, or simply "X," is a
17235c4bbdfSmrgwindowing system that provides high-performance, high-level,
17335c4bbdfSmrgdevice-independent graphics.
17435c4bbdfSmrg</para>
17535c4bbdfSmrg<para>
17635c4bbdfSmrgX is a windowing system designed for bitmapped graphic displays.
17735c4bbdfSmrgThe display can have a
17835c4bbdfSmrgsimple, monochrome display or it can have a color display with up to 32 bits
17935c4bbdfSmrgper pixel with a special graphics processor doing the work.  (In this
18035c4bbdfSmrgdocument, monochrome means a black and white display with one bit per pixel.
18135c4bbdfSmrgEven though the usual meaning of monochrome is more general, this special
18235c4bbdfSmrgcase is so common that we decided to reserve the word for this purpose.)
18335c4bbdfSmrgIn practice, monochrome displays are now almost unheard of, with 4 bit
18435c4bbdfSmrggray scale displays being the low end.
18535c4bbdfSmrg</para>
18635c4bbdfSmrg<para>
18735c4bbdfSmrgX is designed for a networking environment where
18835c4bbdfSmrgusers can run applications on machines other than their own workstations.
18935c4bbdfSmrgSometimes, the connection is over an Ethernet network with a protocol such as TCP/IP;
19035c4bbdfSmrgbut, any "reliable" byte stream is allowable.
19135c4bbdfSmrgA high-bandwidth byte stream is preferable; RS-232 at
19235c4bbdfSmrg9600 baud would be slow without compression techniques.
19335c4bbdfSmrg</para>
19435c4bbdfSmrg<para>
19535c4bbdfSmrgX by itself allows great freedom of design.
19635c4bbdfSmrgFor instance, it does not include any user interface standard.
19735c4bbdfSmrgIts intent is to "provide mechanism, not policy."
19835c4bbdfSmrgBy making it general, it can be the foundation for a wide
19935c4bbdfSmrgvariety of interactive software.
20035c4bbdfSmrg</para>
20135c4bbdfSmrg<para>
20235c4bbdfSmrgFor a more detailed overview, see the document "The X Window System."
20335c4bbdfSmrgFor details on the byte stream protocol, see "X Window System protocol."
20435c4bbdfSmrg</para>
20535c4bbdfSmrg</section>
20635c4bbdfSmrg<section>
20735c4bbdfSmrg<title>Overview of the Server</title>
20835c4bbdfSmrg<para>
20935c4bbdfSmrgThe display server
21035c4bbdfSmrgmanages windows and simple graphics requests
21135c4bbdfSmrgfor the user on behalf of different client applications.
21235c4bbdfSmrgThe client applications can be running on any machine on the network.
21335c4bbdfSmrgThe server mainly does three things:
21435c4bbdfSmrg<itemizedlist>
21535c4bbdfSmrg  <listitem><para>Responds to protocol requests from existing clients (mostly graphic and text drawing commands)</para></listitem>
21635c4bbdfSmrg  <listitem><para>Sends device input (keystrokes and mouse actions) and other events to existing clients</para></listitem>
21735c4bbdfSmrg  <listitem><para>Maintains client connections</para></listitem>
21835c4bbdfSmrg</itemizedlist>
21935c4bbdfSmrg</para>
22035c4bbdfSmrg<para>
22135c4bbdfSmrgThe server code is organized into four major pieces:
22235c4bbdfSmrg<itemizedlist>
22335c4bbdfSmrg  <listitem><para>Device Independent (DIX) layer - code shared among all implementations</para></listitem>
22435c4bbdfSmrg  <listitem><para>Operating System (OS) layer - code that is different for each operating system but is shared among all graphic devices for this operating system</para></listitem>
22535c4bbdfSmrg  <listitem><para>Device Dependent (DDX) layer - code that is (potentially) different for each combination of operating system and graphic device</para></listitem>
22635c4bbdfSmrg  <listitem><para>Extension Interface - a standard way to add features to the X server</para></listitem>
22735c4bbdfSmrg</itemizedlist>
22835c4bbdfSmrg</para>
22935c4bbdfSmrg<para>
23035c4bbdfSmrgThe "porting layer" consists of the OS and DDX layers; these are
23135c4bbdfSmrgactually parallel and neither one is on top of the other.
23235c4bbdfSmrgThe DIX layer is intended to be portable
23335c4bbdfSmrgwithout change to target systems and is not
23435c4bbdfSmrgdetailed here, although several routines
23535c4bbdfSmrgin DIX that are called by DDX are
23635c4bbdfSmrgdocumented.
23735c4bbdfSmrgExtensions incorporate new functionality into the server; and require
23835c4bbdfSmrgadditional functionality over a simple DDX.
23935c4bbdfSmrg</para>
24035c4bbdfSmrg<para>
24135c4bbdfSmrgThe following sections outline the functions of the layers.
24235c4bbdfSmrgSection 3 briefly tells what you need to know about the DIX layer.
24335c4bbdfSmrgThe OS layer is explained in Section 4.
24435c4bbdfSmrgSection 5 gives the theory of operation and procedural interface for the
24535c4bbdfSmrgDDX layer.
24635c4bbdfSmrgSection 6 describes the functions which exist for the extension writer.
24735c4bbdfSmrg</para>
24835c4bbdfSmrg</section>
24935c4bbdfSmrg
25035c4bbdfSmrg<section>
25135c4bbdfSmrg  <title>DIX Layer</title>
25235c4bbdfSmrg<para>
25335c4bbdfSmrgThe DIX layer is the machine and device independent part of X.
25435c4bbdfSmrgThe source should be common to all operating systems and devices.
25535c4bbdfSmrgThe port process should not include changes to this part, therefore internal interfaces to DIX
25635c4bbdfSmrgmodules are not discussed, except for public interfaces to the DDX and the OS layers.
25735c4bbdfSmrgThe functions described in this section are available for extension writers to use.
25835c4bbdfSmrg</para>
25935c4bbdfSmrg<para>
26035c4bbdfSmrgIn the process of getting your server to work, if
26135c4bbdfSmrgyou think that DIX must be modified for purposes other than bug fixes,
26235c4bbdfSmrgyou may be doing something wrong.
26335c4bbdfSmrgKeep looking for a more compatible solution.
26435c4bbdfSmrgWhen the next release of the X server code is available,
26535c4bbdfSmrgyou should be able to just drop in the new DIX code and compile it.
26635c4bbdfSmrgIf you change DIX,
26735c4bbdfSmrgyou will have to remember what changes you made and will have
26835c4bbdfSmrgto change the new sources before you can update to the new version.
26935c4bbdfSmrg</para>
27035c4bbdfSmrg<para>
27135c4bbdfSmrgThe heart of the DIX code is a loop called the dispatch loop.
27235c4bbdfSmrgEach time the processor goes around the loop, it sends off accumulated input events
27335c4bbdfSmrgfrom the input devices to the clients, and it processes requests from the clients.
27435c4bbdfSmrgThis loop is the most organized way for the server to
27535c4bbdfSmrgprocess the asynchronous requests that
27635c4bbdfSmrgit needs to process.
27735c4bbdfSmrgMost of these operations are performed by OS and DDX routines that you must supply.
27835c4bbdfSmrg</para>
27935c4bbdfSmrg<section>
28035c4bbdfSmrg  <title>Server Resource System</title>
28135c4bbdfSmrg<para>
28235c4bbdfSmrgX resources are C structs inside the server.
28335c4bbdfSmrgClient applications create and manipulate these objects
28435c4bbdfSmrgaccording to the rules of the X byte stream protocol.
28535c4bbdfSmrgClient applications refer to resources with resource IDs,
28635c4bbdfSmrgwhich are 32-bit integers that are sent over the network.
28735c4bbdfSmrgWithin the server, of course, they are just C structs, and we refer to them
28835c4bbdfSmrgby pointers.
28935c4bbdfSmrg</para>
29035c4bbdfSmrg<section>
29135c4bbdfSmrg  <title>Pre-Defined Resource Types</title>
29235c4bbdfSmrg<para>
29335c4bbdfSmrgThe DDX layer has several kinds of resources:
29435c4bbdfSmrg<itemizedlist>
29535c4bbdfSmrg<listitem><para>Window</para></listitem>
29635c4bbdfSmrg<listitem><para>Pixmap</para></listitem>
29735c4bbdfSmrg<listitem><para>Screen</para></listitem>
29835c4bbdfSmrg<listitem><para>Device</para></listitem>
29935c4bbdfSmrg<listitem><para>Colormap</para></listitem>
30035c4bbdfSmrg<listitem><para>Font</para></listitem>
30135c4bbdfSmrg<listitem><para>Cursor</para></listitem>
30235c4bbdfSmrg<listitem><para>Graphics Contexts</para></listitem>
30335c4bbdfSmrg</itemizedlist>
30435c4bbdfSmrg</para>
30535c4bbdfSmrg<para>
30635c4bbdfSmrgThe type names of the more
30735c4bbdfSmrgimportant server
30835c4bbdfSmrgstructs usually end in "Rec," such as "DeviceRec;"
30935c4bbdfSmrgthe pointer types usually end in "Ptr," such as "DevicePtr."
31035c4bbdfSmrg</para>
31135c4bbdfSmrg<para>
31235c4bbdfSmrgThe structs and
31335c4bbdfSmrgimportant defined constants are declared
31435c4bbdfSmrgin .h files that have names that suggest the name of the object.
31535c4bbdfSmrgFor instance, there are two .h files for windows,
31635c4bbdfSmrgwindow.h and windowstr.h.
31735c4bbdfSmrgwindow.h defines only what needs to be defined in order to use windows
31835c4bbdfSmrgwithout peeking inside of them;
31935c4bbdfSmrgwindowstr.h defines the structs with all of their components in great detail
32035c4bbdfSmrgfor those who need it.
32135c4bbdfSmrg</para>
32235c4bbdfSmrg<para>
32335c4bbdfSmrgThree kinds of fields are in these structs:
32435c4bbdfSmrg<itemizedlist>
32535c4bbdfSmrg<listitem><para>Attribute fields - struct fields that contain values like normal structs</para></listitem>
32635c4bbdfSmrg<listitem><para>Pointers to procedures, or structures of procedures, that operate on the object</para></listitem>
32735c4bbdfSmrg<listitem><para>A single private field or a devPrivates list (see <xref linkend="wrappers_and_privates"/>)
32835c4bbdfSmrgused by your DDX code to store private data.</para></listitem>
32935c4bbdfSmrg</itemizedlist>
33035c4bbdfSmrg</para>
33135c4bbdfSmrg<para>
33235c4bbdfSmrgDIX calls through
33335c4bbdfSmrgthe struct's procedure pointers to do its tasks.
33435c4bbdfSmrgThese procedures are set either directly or indirectly by DDX procedures.
33535c4bbdfSmrgMost of
33635c4bbdfSmrgthe procedures described in the remainder of this
33735c4bbdfSmrgdocument are accessed through one of these structs.
33835c4bbdfSmrgFor example, the procedure to create a pixmap
33935c4bbdfSmrgis attached to a ScreenRec and might be called by using the expression
34035c4bbdfSmrg</para>
34135c4bbdfSmrg<para>
34235c4bbdfSmrg<blockquote>
34335c4bbdfSmrg<programlisting>(* pScreen->CreatePixmap)(pScreen, width, height, depth).</programlisting>
34435c4bbdfSmrg</blockquote>
34535c4bbdfSmrg</para>
34635c4bbdfSmrg<para>
34735c4bbdfSmrgAll procedure pointers must be set to some routine unless noted otherwise;
34835c4bbdfSmrga null pointer will have unfortunate consequences.
34935c4bbdfSmrg</para>
35035c4bbdfSmrg<para>
35135c4bbdfSmrgProcedure routines will be indicated in the documentation by this convention:
35235c4bbdfSmrg<blockquote>
35335c4bbdfSmrg<programlisting>void pScreen->MyScreenRoutine(arg, arg, ...)</programlisting>
35435c4bbdfSmrg</blockquote>
35535c4bbdfSmrgas opposed to a free routine, not in a data structure:
35635c4bbdfSmrg<blockquote>
35735c4bbdfSmrg<programlisting>void MyFreeRoutine(arg, arg, ...)</programlisting>
35835c4bbdfSmrg</blockquote>
35935c4bbdfSmrg</para>
36035c4bbdfSmrg<para>
36135c4bbdfSmrgThe attribute fields are mostly set by DIX; DDX should not modify them
36235c4bbdfSmrgunless noted otherwise.
36335c4bbdfSmrg</para>
36435c4bbdfSmrg</section>
36535c4bbdfSmrg<section>
36635c4bbdfSmrg  <title>Creating Resources and Resource Types</title>
36735c4bbdfSmrg<para>
36835c4bbdfSmrgThese functions should also be called from your extensionInitProc to
36935c4bbdfSmrgallocate all of the various resource classes and types required for
37035c4bbdfSmrgthe extension.  Each time the server resets, these types must be reallocated
37135c4bbdfSmrgas the old allocations will have been discarded.
37235c4bbdfSmrgResource types are integer values starting at 1.  Get
37335c4bbdfSmrga resource type by calling
37435c4bbdfSmrg<blockquote><programlisting>
37535c4bbdfSmrg
37635c4bbdfSmrg    RESTYPE CreateNewResourceType(deleteFunc, char *name)
37735c4bbdfSmrg
37835c4bbdfSmrg</programlisting></blockquote>
37935c4bbdfSmrgdeleteFunc will be called to destroy all resources with this
38035c4bbdfSmrgtype.   name will be used to identify this type of resource
38135c4bbdfSmrgto clients using the X-Resource extension, to security
38235c4bbdfSmrgextensions such as SELinux, and to tracing frameworks such as DTrace.
38335c4bbdfSmrg[The name argument was added in xorg-server 1.8.]
38435c4bbdfSmrg</para>
38535c4bbdfSmrg<para>
38635c4bbdfSmrgResource classes are masks starting at 1 &lt;&lt; 31 which can
38735c4bbdfSmrgbe or'ed with any resource type to provide attributes for the
38835c4bbdfSmrgtype.  To allocate a new class bit, call
38935c4bbdfSmrg<blockquote><programlisting>
39035c4bbdfSmrg
39135c4bbdfSmrg    RESTYPE CreateNewResourceClass()
39235c4bbdfSmrg
39335c4bbdfSmrg</programlisting></blockquote>
39435c4bbdfSmrg</para>
39535c4bbdfSmrg<para>
39635c4bbdfSmrgThere are two ways of looking up resources, by type or
39735c4bbdfSmrgby class.  Classes are non-exclusive subsets of the space of
39835c4bbdfSmrgall resources, so you can lookup the union of multiple classes.
39935c4bbdfSmrg(RC_ANY is the union of all classes).</para>
40035c4bbdfSmrg<para>
40135c4bbdfSmrgNote that the appropriate class bits must be or'ed into the value returned
40235c4bbdfSmrgby CreateNewResourceType when calling resource lookup functions.</para>
40335c4bbdfSmrg<para>
40435c4bbdfSmrgIf you need to create a ``private'' resource ID for internal use, you
40535c4bbdfSmrgcan call FakeClientID.
40635c4bbdfSmrg<blockquote><programlisting>
40735c4bbdfSmrg
40835c4bbdfSmrg	XID FakeClientID(client)
40935c4bbdfSmrg	    int client;
41035c4bbdfSmrg
41135c4bbdfSmrg</programlisting></blockquote>
41235c4bbdfSmrgThis allocates from ID space reserved for the server.</para>
41335c4bbdfSmrg<para>
41435c4bbdfSmrgTo associate a resource value with an ID, use AddResource.
41535c4bbdfSmrg<blockquote><programlisting>
41635c4bbdfSmrg
41735c4bbdfSmrg	Bool AddResource(id, type, value)
41835c4bbdfSmrg	    XID id;
41935c4bbdfSmrg	    RESTYPE type;
42035c4bbdfSmrg	    pointer value;
42135c4bbdfSmrg
42235c4bbdfSmrg</programlisting></blockquote>
42335c4bbdfSmrgThe type should be the full type of the resource, including any class
42435c4bbdfSmrgbits.  If AddResource fails to allocate memory to store the resource,
42535c4bbdfSmrgit will call the deleteFunc for the type, and then return False.</para>
42635c4bbdfSmrg<para>
42735c4bbdfSmrgTo free a resource, use one of the following.
42835c4bbdfSmrg<blockquote><programlisting>
42935c4bbdfSmrg
43035c4bbdfSmrg	void FreeResource(id, skipDeleteFuncType)
43135c4bbdfSmrg	    XID id;
43235c4bbdfSmrg	    RESTYPE skipDeleteFuncType;
43335c4bbdfSmrg
43435c4bbdfSmrg	void FreeResourceByType(id, type, skipFree)
43535c4bbdfSmrg	    XID id;
43635c4bbdfSmrg	    RESTYPE type;
43735c4bbdfSmrg	    Bool    skipFree;
43835c4bbdfSmrg
43935c4bbdfSmrg</programlisting></blockquote>
44035c4bbdfSmrgFreeResource frees all resources matching the given id, regardless of
44135c4bbdfSmrgtype; the type's deleteFunc will be called on each matching resource,
44235c4bbdfSmrgexcept that skipDeleteFuncType can be set to a single type for which
44335c4bbdfSmrgthe deleteFunc should not be called (otherwise pass RT_NONE).
44435c4bbdfSmrgFreeResourceByType frees a specific resource matching a given id
44535c4bbdfSmrgand type; if skipFree is true, then the deleteFunc is not called.
44635c4bbdfSmrg</para>
44735c4bbdfSmrg</section>
44835c4bbdfSmrg<section>
44935c4bbdfSmrg  <title>Looking Up Resources</title>
45035c4bbdfSmrg<para>
45135c4bbdfSmrgTo look up a resource, use one of the following.
45235c4bbdfSmrg<blockquote><programlisting>
45335c4bbdfSmrg
45435c4bbdfSmrg	int dixLookupResourceByType(
45535c4bbdfSmrg	    pointer *result,
45635c4bbdfSmrg	    XID id,
45735c4bbdfSmrg	    RESTYPE rtype,
45835c4bbdfSmrg	    ClientPtr client,
45935c4bbdfSmrg	    Mask access_mode);
46035c4bbdfSmrg
46135c4bbdfSmrg	int dixLookupResourceByClass(
46235c4bbdfSmrg	    pointer *result,
46335c4bbdfSmrg	    XID id,
46435c4bbdfSmrg	    RESTYPE rclass,
46535c4bbdfSmrg	    ClientPtr client,
46635c4bbdfSmrg	    Mask access_mode);
46735c4bbdfSmrg
46835c4bbdfSmrg</programlisting></blockquote>
46935c4bbdfSmrgdixLookupResourceByType finds a resource with the given id and exact type.
47035c4bbdfSmrgdixLookupResourceByClass finds a resource with the given id whose type is
47135c4bbdfSmrgincluded in any one of the specified classes.
47235c4bbdfSmrgThe client and access_mode must be provided to allow security extensions to
47335c4bbdfSmrgcheck if the client has the right privileges for the requested access.
47435c4bbdfSmrgThe bitmask values defined in the dixaccess.h header are or'ed together
47535c4bbdfSmrgto define the requested access_mode.
47635c4bbdfSmrg</para>
47735c4bbdfSmrg</section>
47835c4bbdfSmrg</section>
47935c4bbdfSmrg<section>
48035c4bbdfSmrg  <title>Callback Manager</title>
48135c4bbdfSmrg<para>
48235c4bbdfSmrgTo satisfy a growing number of requests for the introduction of ad hoc
48335c4bbdfSmrgnotification style hooks in the server, a generic callback manager was
48435c4bbdfSmrgintroduced in R6.  A callback list object can be introduced for each
48535c4bbdfSmrgnew hook that is desired, and other modules in the server can register
48635c4bbdfSmrginterest in the new callback list.  The following functions support
48735c4bbdfSmrgthese operations.</para>
48835c4bbdfSmrg<para>
48935c4bbdfSmrgBefore getting bogged down in the interface details, an typical usage
49035c4bbdfSmrgexample should establish the framework.  Let's look at the
49135c4bbdfSmrgClientStateCallback in dix/dispatch.c.  The purpose of this particular
49235c4bbdfSmrgcallback is to notify interested parties when a client's state
49335c4bbdfSmrg(initial, running, gone) changes.  The callback is "created" in this
49435c4bbdfSmrgcase by simply declaring a variable:
49535c4bbdfSmrg<blockquote><programlisting>
49635c4bbdfSmrg	CallbackListPtr ClientStateCallback;
49735c4bbdfSmrg</programlisting></blockquote>
49835c4bbdfSmrg</para>
49935c4bbdfSmrg<para>
50035c4bbdfSmrgWhenever the client's state changes, the following code appears, which notifies
50135c4bbdfSmrgall interested parties of the change:
50235c4bbdfSmrg<blockquote><programlisting>
50335c4bbdfSmrg	if (ClientStateCallback) CallCallbacks(&amp;ClientStateCallback, (pointer)client);
50435c4bbdfSmrg</programlisting></blockquote>
50535c4bbdfSmrg</para>
50635c4bbdfSmrg<para>
50735c4bbdfSmrgInterested parties subscribe to the ClientStateCallback list by saying:
50835c4bbdfSmrg<blockquote><programlisting>
50935c4bbdfSmrg	AddCallback(&amp;ClientStateCallback, func, data);
51035c4bbdfSmrg</programlisting></blockquote>
51135c4bbdfSmrg</para>
51235c4bbdfSmrg<para>
51335c4bbdfSmrgWhen CallCallbacks is invoked on the list, func will be called thusly:
51435c4bbdfSmrg<blockquote><programlisting>
51535c4bbdfSmrg	(*func)(&amp;ClientStateCallback, data, client)
51635c4bbdfSmrg</programlisting></blockquote>
51735c4bbdfSmrg</para>
51835c4bbdfSmrg<para>
51935c4bbdfSmrgNow for the details.
52035c4bbdfSmrg<blockquote><programlisting>
52135c4bbdfSmrg
52235c4bbdfSmrg	Bool AddCallback(pcbl, callback, subscriber_data)
52335c4bbdfSmrg	    CallbackListPtr *pcbl;
52435c4bbdfSmrg	    CallbackProcPtr callback;
52535c4bbdfSmrg	    pointer         subscriber_data;
52635c4bbdfSmrg
52735c4bbdfSmrg</programlisting></blockquote>
52835c4bbdfSmrgAdds the (callback, subscriber_data) pair to the given callback list.  Creates the callback
52935c4bbdfSmrglist if it doesn't exist.  Returns TRUE if successful.</para>
53035c4bbdfSmrg<para>
53135c4bbdfSmrg<blockquote><programlisting>
53235c4bbdfSmrg
53335c4bbdfSmrg	Bool DeleteCallback(pcbl, callback, subscriber_data)
53435c4bbdfSmrg	    CallbackListPtr *pcbl;
53535c4bbdfSmrg	    CallbackProcPtr callback;
53635c4bbdfSmrg	    pointer         subscriber_data;
53735c4bbdfSmrg
53835c4bbdfSmrg</programlisting></blockquote>
53935c4bbdfSmrgRemoves the (callback, data) pair to the given callback list if present.
54035c4bbdfSmrgReturns TRUE if (callback, data) was found.</para>
54135c4bbdfSmrg<para>
54235c4bbdfSmrg<blockquote><programlisting>
54335c4bbdfSmrg
54435c4bbdfSmrg	void CallCallbacks(pcbl, call_data)
54535c4bbdfSmrg	    CallbackListPtr    *pcbl;
54635c4bbdfSmrg	    pointer	    call_data;
54735c4bbdfSmrg
54835c4bbdfSmrg</programlisting></blockquote>
54935c4bbdfSmrgFor each callback currently registered on the given callback list, call
55035c4bbdfSmrgit as follows:
55135c4bbdfSmrg<blockquote><programlisting>
55235c4bbdfSmrg
55335c4bbdfSmrg	(*callback)(pcbl, subscriber_data, call_data);
55435c4bbdfSmrg</programlisting></blockquote>
55535c4bbdfSmrg</para>
55635c4bbdfSmrg<para>
55735c4bbdfSmrg<blockquote><programlisting>
55835c4bbdfSmrg	void DeleteCallbackList(pcbl)
55935c4bbdfSmrg	    CallbackListPtr    *pcbl;
56035c4bbdfSmrg
56135c4bbdfSmrg</programlisting></blockquote>
56235c4bbdfSmrgDestroys the given callback list.</para>
56335c4bbdfSmrg</section>
56435c4bbdfSmrg<section>
56535c4bbdfSmrg  <title>Extension Interfaces</title>
56635c4bbdfSmrg<para>
56735c4bbdfSmrgThis function should be called from your extensionInitProc which
56835c4bbdfSmrgshould be called by InitExtensions.
56935c4bbdfSmrg<blockquote><programlisting>
57035c4bbdfSmrg
57135c4bbdfSmrg	ExtensionEntry *AddExtension(name, NumEvents,NumErrors,
57235c4bbdfSmrg		MainProc, SwappedMainProc, CloseDownProc, MinorOpcodeProc)
57335c4bbdfSmrg
57435c4bbdfSmrg		const char *name;  /*Null terminate string; case matters*/
57535c4bbdfSmrg		int NumEvents;
57635c4bbdfSmrg		int NumErrors;
57735c4bbdfSmrg		int (* MainProc)(ClientPtr);/*Called if client matches server order*/
57835c4bbdfSmrg		int (* SwappedMainProc)(ClientPtr);/*Called if client differs from server*/
57935c4bbdfSmrg		void (* CloseDownProc)(ExtensionEntry *);
58035c4bbdfSmrg		unsigned short (*MinorOpcodeProc)(ClientPtr);
58135c4bbdfSmrg
58235c4bbdfSmrg</programlisting></blockquote>
58335c4bbdfSmrgname is the name used by clients to refer to the extension.  NumEvents is the
58435c4bbdfSmrgnumber of event types used by the extension, NumErrors is the number of
58535c4bbdfSmrgerror codes needed by the extension.  MainProc is called whenever a client
58635c4bbdfSmrgaccesses the major opcode assigned to the extension.  SwappedMainProc is
58735c4bbdfSmrgidentical, except the client using the extension has reversed byte-sex.
58835c4bbdfSmrgCloseDownProc is called at server reset time to deallocate any private
58935c4bbdfSmrgstorage used by the extension.  MinorOpcodeProc is used by DIX to place the
59035c4bbdfSmrgappropriate value into errors.  The DIX routine StandardMinorOpcode can be
59135c4bbdfSmrgused here which takes the minor opcode from the normal place in the request
59235c4bbdfSmrg(i.e. just after the major opcode).</para>
59335c4bbdfSmrg</section>
59435c4bbdfSmrg<section>
59535c4bbdfSmrg  <title>Macros and Other Helpers</title>
59635c4bbdfSmrg<para>
59735c4bbdfSmrgThere are a number of macros in Xserver/include/dix.h which
59835c4bbdfSmrgare useful to the extension writer.  Ones of particular interest
59935c4bbdfSmrgare: REQUEST, REQUEST_SIZE_MATCH, REQUEST_AT_LEAST_SIZE,
60035c4bbdfSmrgREQUEST_FIXED_SIZE, LEGAL_NEW_RESOURCE, and
60135c4bbdfSmrgVALIDATE_DRAWABLE_AND_GC. Useful byte swapping macros can be found
60235c4bbdfSmrgin Xserver/include/dix.h: WriteReplyToClient and WriteSwappedDataToClient; and
6031b5d61b8Smrgin Xserver/include/misc.h: bswap_64, bswap_32, bswap_16, LengthRestB, LengthRestS,
60435c4bbdfSmrgLengthRestL, SwapRestS, SwapRestL, swapl, swaps, cpswapl, and cpswaps.</para>
60535c4bbdfSmrg</section>
60635c4bbdfSmrg</section>
60735c4bbdfSmrg
60835c4bbdfSmrg<section>
60935c4bbdfSmrg  <title>OS Layer</title>
61035c4bbdfSmrg<para>
61135c4bbdfSmrgThis part of the source consists of a few routines that you have to rewrite
61235c4bbdfSmrgfor each operating system.
61335c4bbdfSmrgThese OS functions maintain the client connections and schedule work
61435c4bbdfSmrgto be done for clients.
61535c4bbdfSmrgThey also provide an interface to font files,
61635c4bbdfSmrgfont name to file name translation, and
61735c4bbdfSmrglow level memory management.
61835c4bbdfSmrg<blockquote>
61935c4bbdfSmrg<programlisting>void OsInit()</programlisting>
62035c4bbdfSmrg</blockquote>
62135c4bbdfSmrgOsInit initializes your OS code, performing whatever tasks need to be done.
62235c4bbdfSmrgFrequently there is not much to be done.
62335c4bbdfSmrgThe sample server implementation is in Xserver/os/osinit.c.
62435c4bbdfSmrg</para>
62535c4bbdfSmrg<section>
62635c4bbdfSmrg  <title>Scheduling and Request Delivery</title>
62735c4bbdfSmrg<para>
62835c4bbdfSmrgThe main dispatch loop in DIX creates the illusion of multitasking between
62935c4bbdfSmrgdifferent windows, while the server is itself but a single process.
63035c4bbdfSmrgThe dispatch loop breaks up the work for each client into small digestible parts.
63135c4bbdfSmrgSome parts are requests from a client, such as individual graphic commands.
63235c4bbdfSmrgSome parts are events delivered to the client, such as keystrokes from the user.
63335c4bbdfSmrgThe processing of events and requests for different
63435c4bbdfSmrgclients can be interleaved with one another so true multitasking
63535c4bbdfSmrgis not needed in the server.
63635c4bbdfSmrg</para>
63735c4bbdfSmrg<para>
63835c4bbdfSmrgYou must supply some of the pieces for proper scheduling between clients.
63935c4bbdfSmrg<blockquote>
64035c4bbdfSmrg<programlisting>
64135c4bbdfSmrg	int WaitForSomething(pClientReady)
64235c4bbdfSmrg		int *pClientReady;
64335c4bbdfSmrg</programlisting>
64435c4bbdfSmrg</blockquote>
64535c4bbdfSmrg</para>
64635c4bbdfSmrg<para>
64735c4bbdfSmrgWaitForSomething is the scheduler procedure you must write that will
64835c4bbdfSmrgsuspend your server process until something needs to be done.
64935c4bbdfSmrgThis call should
65035c4bbdfSmrgmake the server suspend until one or more of the following occurs:
65135c4bbdfSmrg<itemizedlist>
65235c4bbdfSmrg<listitem><para>There is an input event from the user or hardware (see SetInputCheck())</para></listitem>
65335c4bbdfSmrg<listitem><para>There are requests waiting from known clients, in which case you should return a count of clients stored in pClientReady</para></listitem>
65435c4bbdfSmrg<listitem><para>A new client tries to connect, in which case you should create the client and then continue waiting</para></listitem>
65535c4bbdfSmrg</itemizedlist>
65635c4bbdfSmrg</para>
65735c4bbdfSmrg<para>
65835c4bbdfSmrgBefore WaitForSomething() computes the masks to pass to select, poll or
65935c4bbdfSmrgsimilar operating system interface, it needs to
66035c4bbdfSmrgsee if there is anything to do on the work queue; if so, it must call a DIX
66135c4bbdfSmrgroutine called ProcessWorkQueue.
66235c4bbdfSmrg<blockquote>
66335c4bbdfSmrg<programlisting>
66435c4bbdfSmrg	extern WorkQueuePtr	workQueue;
66535c4bbdfSmrg
66635c4bbdfSmrg	if (workQueue)
66735c4bbdfSmrg		ProcessWorkQueue ();
66835c4bbdfSmrg</programlisting>
66935c4bbdfSmrg</blockquote>
67035c4bbdfSmrg</para>
67135c4bbdfSmrg<para>
67235c4bbdfSmrgIf WaitForSomething() decides it is about to do something that might block
67335c4bbdfSmrg(in the sample server,  before it calls select() or poll) it must call a DIX
67435c4bbdfSmrgroutine called BlockHandler().
67535c4bbdfSmrg<blockquote>
67635c4bbdfSmrg<programlisting>
6771b5d61b8Smrg	void BlockHandler(void *pTimeout)
67835c4bbdfSmrg</programlisting>
67935c4bbdfSmrg</blockquote>
68035c4bbdfSmrgThe types of the arguments are for agreement between the OS and DDX
68135c4bbdfSmrgimplementations,  but the pTimeout is a pointer to the information
6821b5d61b8Smrgdetermining how long the block is allowed to last.
68335c4bbdfSmrg</para>
68435c4bbdfSmrg<para>
6851b5d61b8SmrgIn the sample server,  pTimeout is a pointer.
68635c4bbdfSmrg</para>
68735c4bbdfSmrg<para>
68835c4bbdfSmrgThe DIX BlockHandler() iterates through the Screens,  for each one calling
68935c4bbdfSmrgits BlockHandler.  A BlockHandler is declared thus:
69035c4bbdfSmrg<blockquote>
69135c4bbdfSmrg<programlisting>
6921b5d61b8Smrg	void xxxBlockHandler(ScreenPtr pScreen, void *pTimeout)
69335c4bbdfSmrg</programlisting>
69435c4bbdfSmrg</blockquote>
69535c4bbdfSmrgThe arguments are a pointer to the Screen, and the arguments to the
69635c4bbdfSmrgDIX BlockHandler().
69735c4bbdfSmrg</para>
69835c4bbdfSmrg<para>
69935c4bbdfSmrgImmediately after WaitForSomething returns from the
70035c4bbdfSmrgblock,  even if it didn't actually block,  it must call the DIX routine
70135c4bbdfSmrgWakeupHandler().
70235c4bbdfSmrg<blockquote>
70335c4bbdfSmrg<programlisting>
7041b5d61b8Smrg	void WakeupHandler(int result)
70535c4bbdfSmrg</programlisting>
70635c4bbdfSmrg</blockquote>
70735c4bbdfSmrgOnce again,  the types are not specified by DIX.  The result is the
7081b5d61b8Smrgsuccess indicator for the thing that (may have) blocked.
7091b5d61b8SmrgIn the sample server, result is the result from select() (or equivalent
7101b5d61b8Smrgoperating system function).
71135c4bbdfSmrg</para>
71235c4bbdfSmrg<para>
71335c4bbdfSmrgThe DIX WakeupHandler() calls each Screen's
71435c4bbdfSmrgWakeupHandler.  A WakeupHandler is declared thus:
71535c4bbdfSmrg<blockquote>
71635c4bbdfSmrg<programlisting>
7171b5d61b8Smrg	void xxxWakeupHandler(ScreenPtr pScreen, int result)
71835c4bbdfSmrg</programlisting>
71935c4bbdfSmrg</blockquote>
72035c4bbdfSmrgThe arguments are the Screen, of the Screen, and the arguments to
72135c4bbdfSmrgthe DIX WakeupHandler().
72235c4bbdfSmrg</para>
72335c4bbdfSmrg<para>
72435c4bbdfSmrgIn addition to the per-screen BlockHandlers, any module may register
72535c4bbdfSmrgblock and wakeup handlers (only together) using:
72635c4bbdfSmrg<blockquote>
72735c4bbdfSmrg<programlisting>
72835c4bbdfSmrg	Bool RegisterBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
7291b5d61b8Smrg		ServerBlockHandlerProcPtr    blockHandler;
7301b5d61b8Smrg		ServerWakeupHandlerProcPtr   wakeupHandler;
73135c4bbdfSmrg		pointer blockData;
73235c4bbdfSmrg</programlisting>
73335c4bbdfSmrg</blockquote>
73435c4bbdfSmrgA FALSE return code indicates that the registration failed for lack of
73535c4bbdfSmrgmemory.  To remove a registered Block handler at other than server reset time
73635c4bbdfSmrg(when they are all removed automatically), use:
73735c4bbdfSmrg<blockquote>
73835c4bbdfSmrg<programlisting>
73935c4bbdfSmrg	RemoveBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
7401b5d61b8Smrg		ServerBlockHandlerProcPtr   blockHandler;
7411b5d61b8Smrg		ServerWakeupHandlerProcPtr  wakeupHandler;
74235c4bbdfSmrg		pointer blockData;
74335c4bbdfSmrg</programlisting>
74435c4bbdfSmrg</blockquote>
74535c4bbdfSmrgAll three arguments must match the values passed to
74635c4bbdfSmrgRegisterBlockAndWakeupHandlers.
74735c4bbdfSmrg</para>
74835c4bbdfSmrg<para>
7491b5d61b8SmrgThese registered block handlers are called before the per-screen handlers:
75035c4bbdfSmrg<blockquote>
75135c4bbdfSmrg<programlisting>
7521b5d61b8Smrg	void (*ServerBlockHandler) (void *blockData, void *pTimeout)
75335c4bbdfSmrg</programlisting>
75435c4bbdfSmrg</blockquote>
75535c4bbdfSmrg</para>
75635c4bbdfSmrg<para>
7571b5d61b8SmrgSometimes block handlers need to adjust the time referenced by pTimeout,
75835c4bbdfSmrgwhich on UNIX family systems is generally represented by a struct timeval
75935c4bbdfSmrgconsisting of seconds and microseconds in 32 bit values.
76035c4bbdfSmrgAs a convenience to reduce error prone struct timeval computations which
76135c4bbdfSmrgrequire modulus arithmetic and correct overflow behavior in the face of
76235c4bbdfSmrgmillisecond wrapping through 32 bits,
76335c4bbdfSmrg<blockquote><programlisting>
76435c4bbdfSmrg
7651b5d61b8Smrg	void AdjustWaitForDelay(void *pTimeout, unsigned long newdelay)
76635c4bbdfSmrg
76735c4bbdfSmrg</programlisting></blockquote>
76835c4bbdfSmrghas been provided.
76935c4bbdfSmrg</para>
77035c4bbdfSmrg<para>
77135c4bbdfSmrgAny wakeup handlers registered with RegisterBlockAndWakeupHandlers will
7721b5d61b8Smrgbe called after the Screen handlers:
77335c4bbdfSmrg<blockquote><programlisting>
77435c4bbdfSmrg
7751b5d61b8Smrg	void (*ServerWakeupHandler) (void *blockData, int result)
77635c4bbdfSmrg</programlisting></blockquote>
77735c4bbdfSmrg</para>
77835c4bbdfSmrg<para>
77935c4bbdfSmrgThe WaitForSomething on the sample server also has a built
78035c4bbdfSmrgin screen saver that darkens the screen if no input happens for a period of time.
78135c4bbdfSmrgThe sample server implementation is in Xserver/os/WaitFor.c.
78235c4bbdfSmrg</para>
78335c4bbdfSmrg<para>
78435c4bbdfSmrgNote that WaitForSomething() may be called when you already have several
78535c4bbdfSmrgoutstanding things (events, requests, or new clients) queued up.
78635c4bbdfSmrgFor instance, your server may have just done a large graphics request,
78735c4bbdfSmrgand it may have been a long time since WaitForSomething() was last called.
78835c4bbdfSmrgIf many clients have lots of requests queued up, DIX will only service
78935c4bbdfSmrgsome of them for a given client
79035c4bbdfSmrgbefore going on to the next client (see isItTimeToYield, below).
79135c4bbdfSmrgTherefore, WaitForSomething() will have to report that these same clients
79235c4bbdfSmrgstill have requests queued up the next time around.
79335c4bbdfSmrg</para>
79435c4bbdfSmrg<para>
79535c4bbdfSmrgAn implementation should return information on as
79635c4bbdfSmrgmany outstanding things as it can.
79735c4bbdfSmrgFor instance, if your implementation always checks for client data first and does not
79835c4bbdfSmrgreport any input events until there is no client data left,
79935c4bbdfSmrgyour mouse and keyboard might get locked out by an application that constantly
80035c4bbdfSmrgbarrages the server with graphics drawing requests.
80135c4bbdfSmrgTherefore, as a general rule, input devices should always have priority over graphics
80235c4bbdfSmrgdevices.
80335c4bbdfSmrg</para>
80435c4bbdfSmrg<para>
80535c4bbdfSmrgA list of indexes (client->index) for clients with data ready to be read or
80635c4bbdfSmrgprocessed should be returned in pClientReady, and the count of indexes
80735c4bbdfSmrgreturned as the result value of the call.
80835c4bbdfSmrgThese are not clients that have full requests ready, but any clients who have
80935c4bbdfSmrgany data ready to be read or processed.
81035c4bbdfSmrgThe DIX dispatcher
81135c4bbdfSmrgwill process requests from each client in turn by calling
81235c4bbdfSmrgReadRequestFromClient(), below.
81335c4bbdfSmrg</para>
81435c4bbdfSmrg<para>
81535c4bbdfSmrgWaitForSomething() must create new clients as they are requested (by
81635c4bbdfSmrgwhatever mechanism at the transport level).  A new client is created
81735c4bbdfSmrgby calling the DIX routine:
81835c4bbdfSmrg<blockquote><programlisting>
81935c4bbdfSmrg
82035c4bbdfSmrg	ClientPtr NextAvailableClient(ospriv)
82135c4bbdfSmrg		pointer ospriv;
82235c4bbdfSmrg</programlisting></blockquote>
82335c4bbdfSmrgThis routine returns NULL if a new client cannot be allocated (e.g. maximum
82435c4bbdfSmrgnumber of clients reached).  The ospriv argument will be stored into the OS
82535c4bbdfSmrgprivate field (pClient->osPrivate), to store OS private information about the
82635c4bbdfSmrgclient.  In the sample server, the osPrivate field contains the
82735c4bbdfSmrgnumber of the socket for this client. See also "New Client Connections."
82835c4bbdfSmrgNextAvailableClient() will call InsertFakeRequest(), so you must be
82935c4bbdfSmrgprepared for this.
83035c4bbdfSmrg</para>
83135c4bbdfSmrg<para>
83235c4bbdfSmrgIf there are outstanding input events,
83335c4bbdfSmrgyou should make sure that the two SetInputCheck() locations are unequal.
83435c4bbdfSmrgThe DIX dispatcher will call your implementation of ProcessInputEvents()
83535c4bbdfSmrguntil the SetInputCheck() locations are equal.
83635c4bbdfSmrg</para>
83735c4bbdfSmrg<para>
83835c4bbdfSmrgThe sample server contains an implementation of WaitForSomething().
83935c4bbdfSmrgThe
84035c4bbdfSmrgfollowing two routines indicate to WaitForSomething() what devices should
84135c4bbdfSmrgbe waited for.   fd is an OS dependent type; in the sample server
84235c4bbdfSmrgit is an open file descriptor.
84335c4bbdfSmrg<blockquote><programlisting>
84435c4bbdfSmrg
84535c4bbdfSmrg	int AddEnabledDevice(fd)
84635c4bbdfSmrg		int fd;
84735c4bbdfSmrg
84835c4bbdfSmrg	int RemoveEnabledDevice(fd)
84935c4bbdfSmrg		int fd;
85035c4bbdfSmrg</programlisting></blockquote>
85135c4bbdfSmrgThese two routines are
85235c4bbdfSmrgusually called by DDX from the initialize cases of the
85335c4bbdfSmrgInput Procedures that are stored in the DeviceRec (the
85435c4bbdfSmrgroutine passed to AddInputDevice()).
85535c4bbdfSmrgThe sample server implementation of AddEnabledDevice
85635c4bbdfSmrgand RemoveEnabledDevice are in Xserver/os/connection.c.
85735c4bbdfSmrg</para>
85835c4bbdfSmrg<section>
85935c4bbdfSmrg  <title>Timer Facilities</title>
86035c4bbdfSmrg<para>
86135c4bbdfSmrgSimilarly, the X server or an extension may need to wait for some timeout.
86235c4bbdfSmrgEarly X releases implemented this functionality using block and wakeup handlers,
86335c4bbdfSmrgbut this has been rewritten to use a general timer facilty, and the
86435c4bbdfSmrginternal screen saver facilities reimplemented to use Timers.
86535c4bbdfSmrgThese functions are TimerInit, TimerForce, TimerSet, TimerCheck, TimerCancel,
86635c4bbdfSmrgand TimerFree, as defined in Xserver/include/os.h. A callback function will be called
86735c4bbdfSmrgwhen the timer fires, along with the current time, and a user provided argument.
86835c4bbdfSmrg<blockquote><programlisting>
86935c4bbdfSmrg	typedef	struct _OsTimerRec *OsTimerPtr;
87035c4bbdfSmrg
87135c4bbdfSmrg	typedef CARD32 (*OsTimerCallback)(
87235c4bbdfSmrg		OsTimerPtr /* timer */,
87335c4bbdfSmrg		CARD32 /* time */,
87435c4bbdfSmrg		pointer /* arg */);
87535c4bbdfSmrg
87635c4bbdfSmrg	 OsTimerPtr TimerSet( OsTimerPtr /* timer */,
87735c4bbdfSmrg		int /* flags */,
87835c4bbdfSmrg		CARD32 /* millis */,
87935c4bbdfSmrg		OsTimerCallback /* func */,
88035c4bbdfSmrg		pointer /* arg */);
88135c4bbdfSmrg
88235c4bbdfSmrg</programlisting></blockquote>
88335c4bbdfSmrg</para>
88435c4bbdfSmrg<para>
88535c4bbdfSmrgTimerSet returns a pointer to a timer structure and sets a timer to the specified time
88635c4bbdfSmrgwith the specified argument.  The flags can be TimerAbsolute and TimerForceOld.
88735c4bbdfSmrgThe TimerSetOld flag controls whether if the timer is reset and the timer is pending, the
88835c4bbdfSmrgwhether the callback function will get called.
88935c4bbdfSmrgThe TimerAbsolute flag sets the callback time to an absolute time in the future rather
89035c4bbdfSmrgthan a time relative to when TimerSet is called.
89135c4bbdfSmrgTimerFree should be called to free the memory allocated
89235c4bbdfSmrgfor the timer entry.
89335c4bbdfSmrg<blockquote><programlisting>
89435c4bbdfSmrg	void TimerInit(void)
89535c4bbdfSmrg
89635c4bbdfSmrg	Bool TimerForce(OsTimerPtr /* pTimer */)
89735c4bbdfSmrg
89835c4bbdfSmrg	void TimerCheck(void);
89935c4bbdfSmrg
90035c4bbdfSmrg	void TimerCancel(OsTimerPtr /* pTimer */)
90135c4bbdfSmrg
90235c4bbdfSmrg	void TimerFree(OsTimerPtr /* pTimer */)
90335c4bbdfSmrg</programlisting></blockquote>
90435c4bbdfSmrg</para>
90535c4bbdfSmrg<para>
90635c4bbdfSmrgTimerInit frees any existing timer entries. TimerForce forces a call to the timer's
90735c4bbdfSmrgcallback function and returns true if the timer entry existed, else it returns false and
90835c4bbdfSmrgdoes not call the callback function. TimerCancel will cancel the specified timer.
90935c4bbdfSmrgTimerFree calls TimerCancel and frees the specified timer.
91035c4bbdfSmrgCalling TimerCheck will force the server to see if any timer callbacks should be called.
91135c4bbdfSmrg</para>
91235c4bbdfSmrg</section>
91335c4bbdfSmrg</section>
91435c4bbdfSmrg<section>
91535c4bbdfSmrg  <title>New Client Connections</title>
91635c4bbdfSmrg<para>
91735c4bbdfSmrgThe process whereby a new client-server connection starts up is
91835c4bbdfSmrgvery dependent upon what your byte stream mechanism.
91935c4bbdfSmrgThis section describes byte stream initiation using examples from the TCP/IP
92035c4bbdfSmrgimplementation on the sample server.
92135c4bbdfSmrg</para>
92235c4bbdfSmrg<para>
92335c4bbdfSmrgThe first thing that happens is a client initiates a connection with the server.
92435c4bbdfSmrgHow a client knows to do this depends upon your network facilities and the
92535c4bbdfSmrgXlib implementation.
92635c4bbdfSmrgIn a typical scenario, a user named Fred
92735c4bbdfSmrgon his X workstation is logged onto a Cray
92835c4bbdfSmrgsupercomputer running a command shell in an X window.  Fred can type shell
92935c4bbdfSmrgcommands and have the Cray respond as though the X server were a dumb terminal.
93035c4bbdfSmrgFred types in a command to run an X client application that was linked with Xlib.
93135c4bbdfSmrgXlib looks at the shell environment variable DISPLAY, which has the
93235c4bbdfSmrgvalue "fredsbittube:0.0."
93335c4bbdfSmrgThe host name of Fred's workstation is "fredsbittube," and the 0s are
93435c4bbdfSmrgfor multiple screens and multiple X server processes.
93535c4bbdfSmrg(Precisely what
93635c4bbdfSmrghappens on your system depends upon how X and Xlib are implemented.)
93735c4bbdfSmrg</para>
93835c4bbdfSmrg<para>
93935c4bbdfSmrgThe client application calls a TCP routine on the
94035c4bbdfSmrgCray to open a TCP connection for X
94135c4bbdfSmrgto communicate with the network node "fredsbittube."
94235c4bbdfSmrgThe TCP software on the Cray does this by looking up the TCP
94335c4bbdfSmrgaddress of "fredsbittube" and sending an open request to TCP port 6000
94435c4bbdfSmrgon fredsbittube.
94535c4bbdfSmrg</para>
94635c4bbdfSmrg<para>
94735c4bbdfSmrgAll X servers on TCP listen for new clients on port 6000 by default;
94835c4bbdfSmrgthis is known as a "well-known port" in IP terminology.
94935c4bbdfSmrg</para>
95035c4bbdfSmrg<para>
95135c4bbdfSmrgThe server receives this request from its port 6000
95235c4bbdfSmrgand checks where it came from to see if it is on the server's list
95335c4bbdfSmrgof "trustworthy" hosts to talk to.
95435c4bbdfSmrgThen, it opens another port for communications with the client.
95535c4bbdfSmrgThis is the byte stream that all X communications will go over.
95635c4bbdfSmrg</para>
95735c4bbdfSmrg<para>
95835c4bbdfSmrgActually, it is a bit more complicated than that.
95935c4bbdfSmrgEach X server process running on the host machine is called a "display."
96035c4bbdfSmrgEach display can have more than one screen that it manages.
96135c4bbdfSmrg"corporatehydra:3.2" represents screen 2 on display 3 on
96235c4bbdfSmrgthe multi-screened network node corporatehydra.
96335c4bbdfSmrgThe open request would be sent on well-known port number 6003.
96435c4bbdfSmrg</para>
96535c4bbdfSmrg<para>
96635c4bbdfSmrgOnce the byte stream is set up, what goes on does not depend very much
96735c4bbdfSmrgupon whether or not it is TCP.
96835c4bbdfSmrgThe client sends an xConnClientPrefix struct (see Xproto.h) that has the
96935c4bbdfSmrgversion numbers for the version of Xlib it is running, some byte-ordering information,
97035c4bbdfSmrgand two character strings used for authorization.
97135c4bbdfSmrgIf the server does not like the authorization strings
97235c4bbdfSmrgor the version numbers do not match within the rules,
97335c4bbdfSmrgor if anything else is wrong, it sends a failure
97435c4bbdfSmrgresponse with a reason string.
97535c4bbdfSmrg</para>
97635c4bbdfSmrg<para>
97735c4bbdfSmrgIf the information never comes, or comes much too slowly, the connection
97835c4bbdfSmrgshould be broken off.  You must implement the connection timeout.  The
97935c4bbdfSmrgsample server implements this by keeping a timestamp for each still-connecting
98035c4bbdfSmrgclient and, each time just before it attempts to accept new connections, it
98135c4bbdfSmrgcloses any connection that are too old.
98235c4bbdfSmrgThe connection timeout can be set from the command line.
98335c4bbdfSmrg</para>
98435c4bbdfSmrg<para>
98535c4bbdfSmrgYou must implement whatever authorization schemes you want to support.
98635c4bbdfSmrgThe sample server on the distribution tape supports a simple authorization
98735c4bbdfSmrgscheme.  The only interface seen by DIX is:
98835c4bbdfSmrg<blockquote><programlisting>
98935c4bbdfSmrg
99035c4bbdfSmrg	char *
99135c4bbdfSmrg	ClientAuthorized(client, proto_n, auth_proto, string_n, auth_string)
99235c4bbdfSmrg	    ClientPtr client;
99335c4bbdfSmrg	    unsigned int proto_n;
99435c4bbdfSmrg	    char *auth_proto;
99535c4bbdfSmrg	    unsigned int string_n;
99635c4bbdfSmrg	    char *auth_string;
99735c4bbdfSmrg</programlisting></blockquote>
99835c4bbdfSmrgDIX will only call this once per client, once it has read the full initial
99935c4bbdfSmrgconnection data from the client.  If the connection should be
100035c4bbdfSmrgaccepted ClientAuthorized() should return NULL, and otherwise should
100135c4bbdfSmrgreturn an error message string.
100235c4bbdfSmrg</para>
100335c4bbdfSmrg<para>
100435c4bbdfSmrgAccepting new connections happens internally to WaitForSomething().
100535c4bbdfSmrgWaitForSomething() must call the DIX routine NextAvailableClient()
100635c4bbdfSmrgto create a client object.
100735c4bbdfSmrgProcessing of the initial connection data will be handled by DIX.
100835c4bbdfSmrgYour OS layer must be able to map from a client
100935c4bbdfSmrgto whatever information your OS code needs to communicate
101035c4bbdfSmrgon the given byte stream to the client.
101135c4bbdfSmrgDIX uses this ClientPtr to refer to
101235c4bbdfSmrgthe client from now on.   The sample server uses the osPrivate field in
101335c4bbdfSmrgthe ClientPtr to store the file descriptor for the socket, the
101435c4bbdfSmrginput and output buffers, and authorization information.
101535c4bbdfSmrg</para>
101635c4bbdfSmrg<para>
101735c4bbdfSmrgTo initialize the methods you choose to allow clients to connect to
101835c4bbdfSmrgyour server, main() calls the routine
101935c4bbdfSmrg<blockquote><programlisting>
102035c4bbdfSmrg
102135c4bbdfSmrg	void CreateWellKnownSockets()
102235c4bbdfSmrg</programlisting></blockquote>
102335c4bbdfSmrgThis routine is called only once, and not called when the server
102435c4bbdfSmrgis reset.  To recreate any sockets during server resets, the following
102535c4bbdfSmrgroutine is called from the main loop:
102635c4bbdfSmrg<blockquote><programlisting>
102735c4bbdfSmrg
102835c4bbdfSmrg	void ResetWellKnownSockets()
102935c4bbdfSmrg</programlisting></blockquote>
103035c4bbdfSmrgSample implementations of both of these routines are found in
103135c4bbdfSmrgXserver/os/connection.c.
103235c4bbdfSmrg</para>
103335c4bbdfSmrg<para>
103435c4bbdfSmrgFor more details, see the section called "Connection Setup" in the X protocol specification.
103535c4bbdfSmrg</para>
103635c4bbdfSmrg</section>
103735c4bbdfSmrg<section>
103835c4bbdfSmrg  <title>Reading Data from Clients</title>
103935c4bbdfSmrg<para>
104035c4bbdfSmrgRequests from the client are read in as a byte stream by the OS layer.
104135c4bbdfSmrgThey may be in the form of several blocks of bytes delivered in sequence; requests may
104235c4bbdfSmrgbe broken up over block boundaries or there may be many requests per block.
104335c4bbdfSmrgEach request carries with it length information.
104435c4bbdfSmrgIt is the responsibility of the following routine to break it up into request blocks.
104535c4bbdfSmrg<blockquote><programlisting>
104635c4bbdfSmrg
104735c4bbdfSmrg	int ReadRequestFromClient(who)
104835c4bbdfSmrg		ClientPtr who;
104935c4bbdfSmrg</programlisting></blockquote>
105035c4bbdfSmrg</para>
105135c4bbdfSmrg<para>
105235c4bbdfSmrgYou must write
105335c4bbdfSmrgthe routine ReadRequestFromClient() to get one request from the byte stream
105435c4bbdfSmrgbelonging to client "who."
105535c4bbdfSmrgYou must swap the third and fourth bytes (the second 16-bit word) according to the
105635c4bbdfSmrgbyte-swap rules of
105735c4bbdfSmrgthe protocol to determine the length of the
105835c4bbdfSmrgrequest.
105935c4bbdfSmrgThis length is measured in 32-bit words, not in bytes.  Therefore, the
106035c4bbdfSmrgtheoretical maximum request is 256K.
106135c4bbdfSmrg(However, the maximum length allowed is dependent upon the server's input
106235c4bbdfSmrgbuffer.  This size is sent to the client upon connection.  The maximum
106335c4bbdfSmrgsize is the constant MAX_REQUEST_SIZE in Xserver/include/os.h)
106435c4bbdfSmrgThe rest of the request you return is
106535c4bbdfSmrgassumed NOT to be correctly swapped for internal
106635c4bbdfSmrguse, because that is the responsibility of DIX.
106735c4bbdfSmrg</para>
106835c4bbdfSmrg<para>
106935c4bbdfSmrgThe 'who' argument is the ClientPtr returned from WaitForSomething.
107035c4bbdfSmrgThe return value indicating status should be set to the (positive) byte count if the read is successful,
107135c4bbdfSmrg0 if the read was blocked, or a negative error code if an error happened.
107235c4bbdfSmrg</para>
107335c4bbdfSmrg<para>
107435c4bbdfSmrgYou must then store a pointer to
107535c4bbdfSmrgthe bytes of the request in the client request buffer field;
107635c4bbdfSmrgwho->requestBuffer.  This can simply be a pointer into your buffer;
107735c4bbdfSmrgDIX may modify it in place but will not otherwise cause damage.
107835c4bbdfSmrgOf course, the request must be contiguous; you must
107935c4bbdfSmrgshuffle it around in your buffers if not.
108035c4bbdfSmrg</para>
108135c4bbdfSmrg<para>
108235c4bbdfSmrgThe sample server implementation is in Xserver/os/io.c.
108335c4bbdfSmrg</para>
108435c4bbdfSmrg<section><title>Inserting Data for Clients</title>
108535c4bbdfSmrg<para>
108635c4bbdfSmrgDIX can insert data into the client stream, and can cause a "replay" of
108735c4bbdfSmrgthe current request.
108835c4bbdfSmrg<blockquote><programlisting>
108935c4bbdfSmrg
109035c4bbdfSmrg	Bool InsertFakeRequest(client, data, count)
109135c4bbdfSmrg	    ClientPtr client;
109235c4bbdfSmrg	    char *data;
109335c4bbdfSmrg	    int count;
109435c4bbdfSmrg
109535c4bbdfSmrg	int ResetCurrentRequest(client)
109635c4bbdfSmrg	    ClientPtr client;
109735c4bbdfSmrg</programlisting></blockquote>
109835c4bbdfSmrg</para>
109935c4bbdfSmrg<para>
110035c4bbdfSmrgInsertFakeRequest() must insert the specified number of bytes of data
110135c4bbdfSmrginto the head of the input buffer for the client.  This may be a
110235c4bbdfSmrgcomplete request, or it might be a partial request.  For example,
110335c4bbdfSmrgNextAvailableCient() will insert a partial request in order to read
110435c4bbdfSmrgthe initial connection data sent by the client.  The routine returns FALSE
110535c4bbdfSmrgif memory could not be allocated.  ResetCurrentRequest()
110635c4bbdfSmrgshould "back up" the input buffer so that the currently executing request
110735c4bbdfSmrgwill be reexecuted.  DIX may have altered some values (e.g. the overall
110835c4bbdfSmrgrequest length), so you must recheck to see if you still have a complete
110935c4bbdfSmrgrequest.  ResetCurrentRequest() should always cause a yield (isItTimeToYield).
111035c4bbdfSmrg</para>
111135c4bbdfSmrg</section>
111235c4bbdfSmrg</section>
111335c4bbdfSmrg
111435c4bbdfSmrg<section>
111535c4bbdfSmrg  <title>Sending Events, Errors And Replies To Clients</title>
111635c4bbdfSmrg<para>
111735c4bbdfSmrg<blockquote><programlisting>
111835c4bbdfSmrg
111935c4bbdfSmrg	int WriteToClient(who, n, buf)
112035c4bbdfSmrg		ClientPtr who;
112135c4bbdfSmrg		int n;
112235c4bbdfSmrg		char *buf;
112335c4bbdfSmrg</programlisting></blockquote>
112435c4bbdfSmrgWriteToClient should write n bytes starting at buf to the
112535c4bbdfSmrgClientPtr "who".
112635c4bbdfSmrgIt returns the number of bytes written, but for simplicity,
112735c4bbdfSmrgthe number returned must be either the same value as the number
112835c4bbdfSmrgrequested, or -1, signaling an error.
112935c4bbdfSmrgThe sample server implementation is in Xserver/os/io.c.
113035c4bbdfSmrg</para>
113135c4bbdfSmrg<para>
113235c4bbdfSmrg<blockquote><programlisting>
113335c4bbdfSmrg	void SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
113435c4bbdfSmrg	    ClientPtr client;
113535c4bbdfSmrg	    unsigned int majorCode;
113635c4bbdfSmrg	    unsigned int minorCode;
113735c4bbdfSmrg	    XID resId;
113835c4bbdfSmrg	    int errorCode;
113935c4bbdfSmrg</programlisting></blockquote>
114035c4bbdfSmrgSendErrorToClient can be used to send errors back to clients,
114135c4bbdfSmrgalthough in most cases your request function should simply return
114235c4bbdfSmrgthe error code, having set client->errorValue to the appropriate
114335c4bbdfSmrgerror value to return to the client, and DIX will call this
114435c4bbdfSmrgfunction with the correct opcodes for you.
114535c4bbdfSmrg</para>
114635c4bbdfSmrg<para>
114735c4bbdfSmrg<blockquote><programlisting>
114835c4bbdfSmrg
114935c4bbdfSmrg	void FlushAllOutput()
115035c4bbdfSmrg
115135c4bbdfSmrg	void FlushIfCriticalOutputPending()
115235c4bbdfSmrg
115335c4bbdfSmrg	void SetCriticalOutputPending()
115435c4bbdfSmrg</programlisting></blockquote>
115535c4bbdfSmrgThese three routines may be implemented to support buffered or delayed
115635c4bbdfSmrgwrites to clients, but at the very least, the stubs must exist.
115735c4bbdfSmrgFlushAllOutput() unconditionally flushes all output to clients;
115835c4bbdfSmrgFlushIfCriticalOutputPending() flushes output only if
115935c4bbdfSmrgSetCriticalOutputPending() has be called since the last time output
116035c4bbdfSmrgwas flushed.
116135c4bbdfSmrgThe sample server implementation is in Xserver/os/io.c and
116235c4bbdfSmrgactually ignores requests to flush output on a per-client basis
116335c4bbdfSmrgif it knows that there
116435c4bbdfSmrgare requests in that client's input queue.
116535c4bbdfSmrg</para>
116635c4bbdfSmrg</section>
116735c4bbdfSmrg<section>
116835c4bbdfSmrg  <title>Font Support</title>
116935c4bbdfSmrg<para>
117035c4bbdfSmrgIn the sample server, fonts are encoded in disk files or fetched from the
117135c4bbdfSmrgfont server.   The two fonts required by the server, <quote>fixed</quote>
117235c4bbdfSmrgand <quote>cursor</quote> are commonly compiled into the font library.
117335c4bbdfSmrgFor disk fonts, there is one file per font, with a file name like
117435c4bbdfSmrg"fixed.pcf".  Font server fonts are read over the network using the
117535c4bbdfSmrgX Font Server Protocol.  The disk directories containing disk fonts and
117635c4bbdfSmrgthe names of the font servers are listed together in the current "font path."
117735c4bbdfSmrg</para>
117835c4bbdfSmrg<para>
117935c4bbdfSmrgIn principle, you can put all your fonts in ROM or in RAM in your server.
118035c4bbdfSmrgYou can put them all in one library file on disk.
118135c4bbdfSmrgYou could generate them on the fly from stroke descriptions.  By placing the
118235c4bbdfSmrgappropriate code in the Font Library, you will automatically export fonts in
118335c4bbdfSmrgthat format both through the X server and the Font server.
118435c4bbdfSmrg</para>
118535c4bbdfSmrg<para>
118635c4bbdfSmrgThe code for processing fonts in different formats, as well as handling the
118735c4bbdfSmrgmetadata files for them on disk (such as <filename>fonts.dir</filename>) is
118835c4bbdfSmrglocated in the libXfont library, which is provided as a separately compiled
118935c4bbdfSmrgmodule.  These routines are
119035c4bbdfSmrgshared between the X server and the Font server, so instead of this document
119135c4bbdfSmrgspecifying what you must implement, simply refer to the font
119235c4bbdfSmrglibrary interface specification for the details.  All of the interface code to the Font
119335c4bbdfSmrglibrary is contained in dix/dixfonts.c
119435c4bbdfSmrg</para>
119535c4bbdfSmrg</section>
119635c4bbdfSmrg<section>
119735c4bbdfSmrg  <title>Memory Management</title>
119835c4bbdfSmrg<para>
119935c4bbdfSmrgMemory management is based on functions in the C runtime library, malloc(),
120035c4bbdfSmrgrealloc(), and free(), and you should simply call the C library functions
120135c4bbdfSmrgdirectly.  Consult a C runtime library reference manual for more details.
120235c4bbdfSmrg</para>
120335c4bbdfSmrg<para>
120435c4bbdfSmrgTreat memory allocation carefully in your implementation.  Memory
120535c4bbdfSmrgleaks can be very hard to find and are frustrating to a user.  An X
120635c4bbdfSmrgserver could be running for days or weeks without being reset, just
120735c4bbdfSmrglike a regular terminal.  If you leak a few dozen k per day, that will
120835c4bbdfSmrgadd up and will cause problems for users that leave their workstations
120935c4bbdfSmrgon.
121035c4bbdfSmrg</para>
121135c4bbdfSmrg</section>
121235c4bbdfSmrg<section>
121335c4bbdfSmrg  <title>Client Scheduling</title>
121435c4bbdfSmrg<para>
121535c4bbdfSmrgThe X server
121635c4bbdfSmrghas the ability to schedule clients much like an operating system would,
121735c4bbdfSmrgsuspending and restarting them without regard for the state of their input
121835c4bbdfSmrgbuffers.  This functionality allows the X server to suspend one client and
121935c4bbdfSmrgcontinue processing requests from other clients while waiting for a
122035c4bbdfSmrglong-term network activity (like loading a font) before continuing with the
122135c4bbdfSmrgfirst client.
122235c4bbdfSmrg<blockquote><programlisting>
122335c4bbdfSmrg	Bool isItTimeToYield;
122435c4bbdfSmrg</programlisting></blockquote>
122535c4bbdfSmrgisItTimeToYield is a global variable you can set
122635c4bbdfSmrgif you want to tell
122735c4bbdfSmrgDIX to end the client's "time slice" and start paying attention to the next client.
122835c4bbdfSmrgAfter the current request is finished, DIX will move to the next client.
122935c4bbdfSmrg</para>
123035c4bbdfSmrg<para>
123135c4bbdfSmrgIn the sample
123235c4bbdfSmrgserver, ReadRequestFromClient() sets isItTimeToYield after
123335c4bbdfSmrg10 requests packets in a row are read from the same client.
123435c4bbdfSmrg</para>
123535c4bbdfSmrg<para>
123635c4bbdfSmrgThis scheduling algorithm can have a serious effect upon performance when two
123735c4bbdfSmrgclients are drawing into their windows simultaneously.
123835c4bbdfSmrgIf it allows one client to run until its request
123935c4bbdfSmrgqueue is empty by ignoring isItTimeToYield, the client's queue may
124035c4bbdfSmrgin fact never empty and other clients will be blocked out.
124135c4bbdfSmrgOn the other hand, if it switchs between different clients too quickly,
124235c4bbdfSmrgperformance may suffer due to too much switching between contexts.
124335c4bbdfSmrgFor example, if a graphics processor needs to be set up with drawing modes
124435c4bbdfSmrgbefore drawing, and two different clients are drawing with
124535c4bbdfSmrgdifferent modes into two different windows, you may
124635c4bbdfSmrgswitch your graphics processor modes so often that performance is impacted.
124735c4bbdfSmrg</para>
124835c4bbdfSmrg<para>
124935c4bbdfSmrgSee the Strategies document for
125035c4bbdfSmrgheuristics on setting isItTimeToYield.
125135c4bbdfSmrg</para>
125235c4bbdfSmrg<para>
125335c4bbdfSmrgThe following functions provide the ability to suspend request
125435c4bbdfSmrgprocessing on a particular client, resuming it at some later time:
125535c4bbdfSmrg<blockquote><programlisting>
125635c4bbdfSmrg
125735c4bbdfSmrg	int IgnoreClient (who)
125835c4bbdfSmrg		ClientPtr who;
125935c4bbdfSmrg
126035c4bbdfSmrg	int AttendClient (who)
126135c4bbdfSmrg		ClientPtr who;
126235c4bbdfSmrg</programlisting></blockquote>
126335c4bbdfSmrgIgnore client is responsible for pretending that the given client doesn't
126435c4bbdfSmrgexist.  WaitForSomething should not return this client as ready for reading
126535c4bbdfSmrgand should not return if only this client is ready.  AttendClient undoes
126635c4bbdfSmrgwhatever IgnoreClient did, setting it up for input again.
126735c4bbdfSmrg</para>
126835c4bbdfSmrg<para>
126935c4bbdfSmrgThree functions support "process control" for X clients:
127035c4bbdfSmrg<blockquote><programlisting>
127135c4bbdfSmrg
127235c4bbdfSmrg	Bool ClientSleep (client, function, closure)
127335c4bbdfSmrg		ClientPtr	client;
127435c4bbdfSmrg		Bool		(*function)();
127535c4bbdfSmrg		pointer		closure;
127635c4bbdfSmrg
127735c4bbdfSmrg</programlisting></blockquote>
127835c4bbdfSmrgThis suspends the current client (the calling routine is responsible for
127935c4bbdfSmrgmaking its way back to Dispatch()).  No more X requests will be processed
128035c4bbdfSmrgfor this client until ClientWakeup is called.
128135c4bbdfSmrg<blockquote><programlisting>
128235c4bbdfSmrg
128335c4bbdfSmrg	Bool ClientSignal (client)
128435c4bbdfSmrg		ClientPtr	client;
128535c4bbdfSmrg
128635c4bbdfSmrg</programlisting></blockquote>
128735c4bbdfSmrgThis function causes a call to the (*function) parameter passed to
128835c4bbdfSmrgClientSleep to be queued on the work queue.  This does not automatically
128935c4bbdfSmrg"wakeup" the client, but the function called is free to do so by calling:
129035c4bbdfSmrg<blockquote><programlisting>
129135c4bbdfSmrg
129235c4bbdfSmrg	ClientWakeup (client)
129335c4bbdfSmrg		ClientPtr	client;
129435c4bbdfSmrg
129535c4bbdfSmrg</programlisting></blockquote>
129635c4bbdfSmrgThis re-enables X request processing for the specified client.
129735c4bbdfSmrg</para>
129835c4bbdfSmrg</section>
129935c4bbdfSmrg<section>
130035c4bbdfSmrg  <title>Other OS Functions</title>
130135c4bbdfSmrg<para>
130235c4bbdfSmrg<blockquote><programlisting>
130335c4bbdfSmrg	void
130435c4bbdfSmrg	ErrorF(char *f, ...)
130535c4bbdfSmrg
130635c4bbdfSmrg	void
130735c4bbdfSmrg	FatalError(char *f, ...)
130835c4bbdfSmrg</programlisting></blockquote>
130935c4bbdfSmrgYou should write these three routines to provide for diagnostic output
131035c4bbdfSmrgfrom the dix and ddx layers, although implementing them to produce no
131135c4bbdfSmrgoutput will not affect the correctness of your server.  ErrorF() and
131235c4bbdfSmrgFatalError() take a printf() type of format specification in the first
131335c4bbdfSmrgargument and an implementation-dependent number of arguments following
131435c4bbdfSmrgthat.  Normally, the formats passed to ErrorF() and FatalError()
131535c4bbdfSmrgshould be terminated with a newline.
131635c4bbdfSmrg</para>
131735c4bbdfSmrg<para>
131835c4bbdfSmrgAfter printing the message arguments, FatalError() must be implemented
131935c4bbdfSmrgsuch that the server will call AbortDDX() to give the ddx layer
132035c4bbdfSmrga chance to reset the hardware, and then
132135c4bbdfSmrgterminate the server; it must not return.
132235c4bbdfSmrg</para>
132335c4bbdfSmrg<para>
132435c4bbdfSmrgThe sample server implementation for these routines
132535c4bbdfSmrgis in Xserver/os/log.c along with other routines for logging messages.
132635c4bbdfSmrg</para>
132735c4bbdfSmrg</section>
132835c4bbdfSmrg</section>
132935c4bbdfSmrg
133035c4bbdfSmrg<section>
133135c4bbdfSmrg  <title>DDX Layer</title>
133235c4bbdfSmrg<para>
133335c4bbdfSmrgThis section describes the
133435c4bbdfSmrginterface between DIX and DDX.
133535c4bbdfSmrgWhile there may be an OS-dependent driver interface between DDX
133635c4bbdfSmrgand the physical device, that interface is left to the DDX
133735c4bbdfSmrgimplementor and is not specified here.
133835c4bbdfSmrg</para>
133935c4bbdfSmrg<para>
134035c4bbdfSmrgThe DDX layer does most of its work through procedures that are
134135c4bbdfSmrgpointed to by different structs.
134235c4bbdfSmrgAs previously described, the behavior of these resources is largely determined by
134335c4bbdfSmrgthese procedure pointers.
134435c4bbdfSmrgMost of these routines are for graphic display on the screen or support functions thereof.
134535c4bbdfSmrgThe rest are for user input from input devices.
134635c4bbdfSmrg</para>
134735c4bbdfSmrg<section>
134835c4bbdfSmrg  <title>Input</title>
134935c4bbdfSmrg<para>
135035c4bbdfSmrgIn this document "input" refers to input from the user,
135135c4bbdfSmrgsuch as mouse, keyboard, and
135235c4bbdfSmrgbar code readers.
135335c4bbdfSmrgX input devices are of several types: keyboard, pointing device, and
135435c4bbdfSmrgmany others.  The core server has support for extension devices as
135535c4bbdfSmrgdescribed by the X Input Extension document; the interfaces used by
135635c4bbdfSmrgthat extension are described elsewhere.  The core devices are actually
135735c4bbdfSmrgimplemented as two collections of devices, the mouse is a ButtonDevice,
135835c4bbdfSmrga ValuatorDevice and a PtrFeedbackDevice while the keyboard is a KeyDevice,
135935c4bbdfSmrga FocusDevice and a KbdFeedbackDevice.  Each part implements a portion of
136035c4bbdfSmrgthe functionality of the device.  This abstraction is hidden from view for
136135c4bbdfSmrgcore devices by DIX.
136235c4bbdfSmrg</para>
136335c4bbdfSmrg<para>
136435c4bbdfSmrgYou, the DDX programmer, are
136535c4bbdfSmrgresponsible for some of the routines in this section.
136635c4bbdfSmrgOthers are DIX routines that you should call to do the things you need to do in these DDX routines.
136735c4bbdfSmrgPay attention to which is which.
136835c4bbdfSmrg</para>
136935c4bbdfSmrg<section>
137035c4bbdfSmrg  <title>Input Device Data Structures</title>
137135c4bbdfSmrg<para>
137235c4bbdfSmrgDIX keeps a global directory of devices in a central data structure
137335c4bbdfSmrgcalled InputInfo.
137435c4bbdfSmrgFor each device there is a device structure called a DeviceRec.
137535c4bbdfSmrgDIX can locate any DeviceRec through InputInfo.
137635c4bbdfSmrgIn addition, it has a special pointer to identify the main pointing device
137735c4bbdfSmrgand a special pointer to identify the main keyboard.
137835c4bbdfSmrg</para>
137935c4bbdfSmrg<para>
138035c4bbdfSmrgThe DeviceRec (Xserver/include/input.h) is a device-independent
138135c4bbdfSmrgstructure that contains the state of an input device.
138235c4bbdfSmrgA DevicePtr is simply a pointer to a DeviceRec.
138335c4bbdfSmrg</para>
138435c4bbdfSmrg<para>
138535c4bbdfSmrgAn xEvent describes an event the server reports to a client.
138635c4bbdfSmrgDefined in Xproto.h, it is a huge struct of union of structs that have fields for
138735c4bbdfSmrgall kinds of events.
138835c4bbdfSmrgAll of the variants overlap, so that the struct is actually very small in memory.
138935c4bbdfSmrg</para>
139035c4bbdfSmrg</section>
139135c4bbdfSmrg<section>
139235c4bbdfSmrg  <title>Processing Events</title>
139335c4bbdfSmrg<para>
139435c4bbdfSmrgThe main DDX input interface is the following routine:
139535c4bbdfSmrg<blockquote><programlisting>
139635c4bbdfSmrg
139735c4bbdfSmrg	void ProcessInputEvents()
139835c4bbdfSmrg</programlisting></blockquote>
139935c4bbdfSmrgYou must write this routine to deliver input events from the user.
140035c4bbdfSmrgDIX calls it when input is pending (see next section), and possibly
140135c4bbdfSmrgeven when it is not.
140235c4bbdfSmrgYou should write it to get events from each device and deliver
140335c4bbdfSmrgthe events to DIX.
140435c4bbdfSmrgTo deliver the events to DIX, DDX should call the following
140535c4bbdfSmrgroutine:
140635c4bbdfSmrg<blockquote><programlisting>
140735c4bbdfSmrg
140835c4bbdfSmrg	void DevicePtr->processInputProc(pEvent, device, count)
140935c4bbdfSmrg		    xEventPtr events;
141035c4bbdfSmrg		    DeviceIntPtr device;
141135c4bbdfSmrg		    int count;
141235c4bbdfSmrg</programlisting></blockquote>
141335c4bbdfSmrgThis is the "input proc" for the device, a DIX procedure.
141435c4bbdfSmrgDIX will fill in this procedure pointer to one of its own routines by
141535c4bbdfSmrgthe time ProcessInputEvents() is called the first time.
141635c4bbdfSmrgCall this input proc routine as many times as needed to
141735c4bbdfSmrgdeliver as many events as should be delivered.
141835c4bbdfSmrgDIX will buffer them up and send them out as needed.  Count is set
141935c4bbdfSmrgto the number of event records which make up one atomic device event and
142035c4bbdfSmrgis always 1 for the core devices (see the X Input Extension for descriptions
142135c4bbdfSmrgof devices which may use count &#x3E; 1).
142235c4bbdfSmrg</para>
142335c4bbdfSmrg<para>
142435c4bbdfSmrgFor example, your ProcessInputEvents() routine might check the mouse and the
142535c4bbdfSmrgkeyboard.
142635c4bbdfSmrgIf the keyboard had several keystrokes queued up, it could just call
142735c4bbdfSmrgthe keyboard's processInputProc as many times as needed to flush its internal queue.
142835c4bbdfSmrg</para>
142935c4bbdfSmrg<para>
143035c4bbdfSmrgevent is an xEvent struct you pass to the input proc.
143135c4bbdfSmrgWhen the input proc returns, it is finished with the event rec, and you can fill
143235c4bbdfSmrgin new values and call the input proc again with it.
143335c4bbdfSmrg</para>
143435c4bbdfSmrg<para>
143535c4bbdfSmrgYou should deliver the events in the same order that they were generated.
143635c4bbdfSmrg</para>
143735c4bbdfSmrg<para>
143835c4bbdfSmrgFor keyboard and pointing devices the xEvent variant should be keyButtonPointer.
143935c4bbdfSmrgFill in the following fields in the xEvent record:
144035c4bbdfSmrg<itemizedlist>
144135c4bbdfSmrg
144235c4bbdfSmrg<listitem><para>type - is one of the following: KeyPress, KeyRelease, ButtonPress,
144335c4bbdfSmrg					ButtonRelease, or MotionNotify</para></listitem>
144435c4bbdfSmrg<listitem><para>detail - for KeyPress or KeyRelease fields, this should be the
144535c4bbdfSmrg					key number (not the ASCII code); otherwise unused</para></listitem>
144635c4bbdfSmrg<listitem><para>time - is the time that the event happened (32-bits, in milliseconds, arbitrary origin)</para></listitem>
144735c4bbdfSmrg<listitem><para>rootX - is the x coordinate of cursor</para></listitem>
144835c4bbdfSmrg<listitem><para>rootY - is the y coordinate of cursor</para></listitem>
144935c4bbdfSmrg
145035c4bbdfSmrg</itemizedlist>
145135c4bbdfSmrgThe rest of the fields are filled in by DIX.
145235c4bbdfSmrg</para>
145335c4bbdfSmrg<para>
145435c4bbdfSmrgThe time stamp is maintained by your code in the DDX layer, and it is your responsibility to
145535c4bbdfSmrgstamp all events correctly.
145635c4bbdfSmrg</para>
145735c4bbdfSmrg<para>
145835c4bbdfSmrgThe x and y coordinates of the pointing device and the time must be filled in for all event types
145935c4bbdfSmrgincluding keyboard events.
146035c4bbdfSmrg</para>
146135c4bbdfSmrg<para>
146235c4bbdfSmrgThe pointing device must report all button press and release events.
146335c4bbdfSmrgIn addition, it should report a MotionNotify event every time it gets called
146435c4bbdfSmrgif the pointing device has moved since the last notify.
146535c4bbdfSmrgIntermediate pointing device moves are stored in a special GetMotionEvents buffer,
146635c4bbdfSmrgbecause most client programs are not interested in them.
146735c4bbdfSmrg</para>
146835c4bbdfSmrg<para>
146935c4bbdfSmrgThere are quite a collection of sample implementations of this routine,
147035c4bbdfSmrgone for each supported device.
147135c4bbdfSmrg</para>
147235c4bbdfSmrg</section>
147335c4bbdfSmrg<section>
147435c4bbdfSmrg<title>Telling DIX When Input is Pending</title>
147535c4bbdfSmrg<para>
147635c4bbdfSmrgIn the server's dispatch loop, DIX checks to see
147735c4bbdfSmrgif there is any device input pending whenever WaitForSomething() returns.
147835c4bbdfSmrgIf the check says that input is pending, DIX calls the
147935c4bbdfSmrgDDX routine ProcessInputEvents().
148035c4bbdfSmrg</para>
148135c4bbdfSmrg<para>
148235c4bbdfSmrgThis check for pending input must be very quick; a procedure call
148335c4bbdfSmrgis too slow.
148435c4bbdfSmrgThe code that does the check is a hardwired IF
148535c4bbdfSmrgstatement in DIX code that simply compares the values
148635c4bbdfSmrgpointed to by two pointers.
148735c4bbdfSmrgIf the values are different, then it assumes that input is pending and
148835c4bbdfSmrgProcessInputEvents() is called by DIX.
148935c4bbdfSmrg</para>
149035c4bbdfSmrg<para>
149135c4bbdfSmrgYou must pass pointers to DIX to tell it what values to compare.
149235c4bbdfSmrgThe following procedure
149335c4bbdfSmrgis used to set these pointers:
149435c4bbdfSmrg<blockquote><programlisting>
149535c4bbdfSmrg
149635c4bbdfSmrg	void SetInputCheck(p1, p2)
149735c4bbdfSmrg		long *p1, *p2;
149835c4bbdfSmrg</programlisting></blockquote>
149935c4bbdfSmrgYou should call it sometime during initialization to indicate to DIX the
150035c4bbdfSmrgcorrect locations to check.
150135c4bbdfSmrgYou should
150235c4bbdfSmrgpay special attention to the size of what they actually point to,
150335c4bbdfSmrgbecause the locations are assumed to be longs.
150435c4bbdfSmrg</para>
150535c4bbdfSmrg<para>
150635c4bbdfSmrgThese two pointers are initialized by DIX
150735c4bbdfSmrgto point to arbitrary values that
150835c4bbdfSmrgare different.
150935c4bbdfSmrgIn other words, if you forget to call this routine during initialization,
151035c4bbdfSmrgthe worst thing that will happen is that
151135c4bbdfSmrgProcessInputEvents will be called when
151235c4bbdfSmrgthere are no events to process.
151335c4bbdfSmrg</para>
151435c4bbdfSmrg<para>
151535c4bbdfSmrgp1 and p2 might
151635c4bbdfSmrgpoint at the head and tail of some shared
151735c4bbdfSmrgmemory queue.
151835c4bbdfSmrgAnother use would be to have one point at a constant 0, with the
151935c4bbdfSmrgother pointing at some mask containing 1s
152035c4bbdfSmrgfor each input device that has
152135c4bbdfSmrgsomething pending.
152235c4bbdfSmrg</para>
152335c4bbdfSmrg<para>
152435c4bbdfSmrgThe DDX layer of the sample server calls SetInputCheck()
152535c4bbdfSmrgonce when the
152635c4bbdfSmrgserver's private internal queue is initialized.
152735c4bbdfSmrgIt passes pointers to the queue's head and tail.  See Xserver/mi/mieq.c.
152835c4bbdfSmrg</para>
152935c4bbdfSmrg<para>
153035c4bbdfSmrg<blockquote><programlisting>
153135c4bbdfSmrg	int TimeSinceLastInputEvent()
153235c4bbdfSmrg</programlisting></blockquote>
153335c4bbdfSmrgDDX must time stamp all hardware input
153435c4bbdfSmrgevents.  But DIX sometimes needs to know the
153535c4bbdfSmrgtime and the OS layer needs to know the time since the last hardware
153635c4bbdfSmrginput event in
153735c4bbdfSmrgorder for the screen saver to work.   TimeSinceLastInputEvent() returns
153835c4bbdfSmrgthe this time in milliseconds.
153935c4bbdfSmrg</para>
154035c4bbdfSmrg</section>
154135c4bbdfSmrg<section>
154235c4bbdfSmrg  <title>Controlling Input Devices</title>
154335c4bbdfSmrg<para>
154435c4bbdfSmrgYou must write four routines to do various device-specific
154535c4bbdfSmrgthings with the keyboard and pointing device.
154635c4bbdfSmrgThey can have any name you wish because
154735c4bbdfSmrgyou pass the procedure pointers to DIX routines.
154835c4bbdfSmrg</para>
154935c4bbdfSmrg<para>
155035c4bbdfSmrg<blockquote><programlisting>
155135c4bbdfSmrg
155235c4bbdfSmrg	int pInternalDevice->valuator->GetMotionProc(pdevice, coords, start, stop, pScreen)
155335c4bbdfSmrg		DeviceIntPtr pdevice;
155435c4bbdfSmrg		xTimecoord * coords;
155535c4bbdfSmrg		unsigned long start;
155635c4bbdfSmrg		unsigned long stop;
155735c4bbdfSmrg		ScreenPtr pScreen;
155835c4bbdfSmrg</programlisting></blockquote>
155935c4bbdfSmrgYou write this DDX routine to fill in coords with all the motion
156035c4bbdfSmrgevents that have times (32-bit count of milliseconds) between time
156135c4bbdfSmrgstart and time stop.  It should return the number of motion events
156235c4bbdfSmrgreturned.  If there is no motion events support, this routine should
156335c4bbdfSmrgdo nothing and return zero.  The maximum number of coords to return is
156435c4bbdfSmrgset in InitPointerDeviceStruct(), below.
156535c4bbdfSmrg</para>
156635c4bbdfSmrg<para>
156735c4bbdfSmrgWhen the user drags the pointing device, the cursor position
156835c4bbdfSmrgtheoretically sweeps through an infinite number of points.  Normally,
156935c4bbdfSmrga client that is concerned with points other than the starting and
157035c4bbdfSmrgending points will receive a pointer-move event only as often as the
157135c4bbdfSmrgserver generates them. (Move events do not queue up; each new one
157235c4bbdfSmrgreplaces the last in the queue.)  A server, if desired, can implement
157335c4bbdfSmrga scheme to save these intermediate events in a motion buffer.  A
157435c4bbdfSmrgclient application, like a paint program, may then request that these
157535c4bbdfSmrgevents be delivered to it through the GetMotionProc routine.
157635c4bbdfSmrg</para>
157735c4bbdfSmrg<para>
157835c4bbdfSmrg<blockquote><programlisting>
157935c4bbdfSmrg
158035c4bbdfSmrg	void pInternalDevice->bell->BellProc(percent, pDevice, ctrl, unknown)
158135c4bbdfSmrg		int percent;
158235c4bbdfSmrg		DeviceIntPtr pDevice;
158335c4bbdfSmrg		pointer ctrl;
158435c4bbdfSmrg		int class;
158535c4bbdfSmrg</programlisting></blockquote>
158635c4bbdfSmrgYou need to write this routine to ring the bell on the keyboard.
158735c4bbdfSmrgloud is a number from 0 to 100, with 100 being the loudest.
158835c4bbdfSmrgClass is either BellFeedbackClass or KbdFeedbackClass (from XI.h).
158935c4bbdfSmrg</para>
159035c4bbdfSmrg<para>
159135c4bbdfSmrg<blockquote><programlisting>
159235c4bbdfSmrg
159335c4bbdfSmrg	void pInternalDevice->somedevice->CtrlProc(device, ctrl)
159435c4bbdfSmrg		DevicePtr device;
159535c4bbdfSmrg		SomethingCtrl *ctrl;
159635c4bbdfSmrg
159735c4bbdfSmrg</programlisting></blockquote>
159835c4bbdfSmrgYou write two versions of this procedure, one for the keyboard and one for the pointing device.
159935c4bbdfSmrgDIX calls it to inform DDX when a client has requested changes in the current
160035c4bbdfSmrgsettings for the particular device.
160135c4bbdfSmrgFor a keyboard, this might be the repeat threshold and rate.
160235c4bbdfSmrgFor a pointing device, this might be a scaling factor (coarse or fine) for position reporting.
160335c4bbdfSmrgSee input.h for the ctrl structures.
160435c4bbdfSmrg</para>
160535c4bbdfSmrg</section>
160635c4bbdfSmrg<section>
160735c4bbdfSmrg  <title>Input Initialization</title>
160835c4bbdfSmrg<para>
160935c4bbdfSmrgInput initialization is a bit complicated.
161035c4bbdfSmrgIt all starts with InitInput(), a routine that you write to call
161135c4bbdfSmrgAddInputDevice() twice
161235c4bbdfSmrg(once for pointing device and once for keyboard.)
161335c4bbdfSmrg</para>
161435c4bbdfSmrg<para>
161535c4bbdfSmrgWhen you Add the devices, a routine you supply for each device
161635c4bbdfSmrggets called to initialize them.
161735c4bbdfSmrgYour individual initialize routines must call InitKeyboardDeviceStruct()
161835c4bbdfSmrgor InitPointerDeviceStruct(), depending upon which it is.
161935c4bbdfSmrgIn other words, you indicate twice that the keyboard is the keyboard and
162035c4bbdfSmrgthe pointer is the pointer.
162135c4bbdfSmrg</para>
162235c4bbdfSmrg<para>
162335c4bbdfSmrg<blockquote><programlisting>
162435c4bbdfSmrg
162535c4bbdfSmrg	void InitInput(argc, argv)
162635c4bbdfSmrg	    int argc;
162735c4bbdfSmrg	    char **argv;
162835c4bbdfSmrg</programlisting></blockquote>
162935c4bbdfSmrgInitInput is a DDX routine you must write to initialize the
163035c4bbdfSmrginput subsystem in DDX.
163135c4bbdfSmrgIt must call AddInputDevice() for each device that might generate events.
163235c4bbdfSmrg</para>
163335c4bbdfSmrg<para>
163435c4bbdfSmrg<blockquote><programlisting>
163535c4bbdfSmrg
163635c4bbdfSmrg	DevicePtr AddInputDevice(deviceProc, autoStart)
163735c4bbdfSmrg		DeviceProc deviceProc;
163835c4bbdfSmrg		Bool autoStart;
163935c4bbdfSmrg</programlisting></blockquote>
164035c4bbdfSmrgAddInputDevice is a DIX routine you call to create a device object.
164135c4bbdfSmrgdeviceProc is a DDX routine that is called by DIX to do various operations.
164235c4bbdfSmrgAutoStart should be TRUE for devices that need to be turned on at
164335c4bbdfSmrginitialization time with a special call, as opposed to waiting for some
164435c4bbdfSmrgclient application to
164535c4bbdfSmrgturn them on.
164635c4bbdfSmrgThis routine returns NULL if sufficient memory cannot be allocated to
164735c4bbdfSmrginstall the device.
164835c4bbdfSmrg</para>
164935c4bbdfSmrg<para>
165035c4bbdfSmrgNote also that except for the main keyboard and pointing device,
165135c4bbdfSmrgan extension is needed to provide for a client interface to a device.
165235c4bbdfSmrg</para>
165335c4bbdfSmrg<para>
165435c4bbdfSmrgThe following DIX
165535c4bbdfSmrgprocedures return the specified DevicePtr. They may or may not be useful
165635c4bbdfSmrgto DDX implementors.
165735c4bbdfSmrg</para>
165835c4bbdfSmrg<para>
165935c4bbdfSmrg<blockquote><programlisting>
166035c4bbdfSmrg
166135c4bbdfSmrg	DevicePtr LookupKeyboardDevice()
166235c4bbdfSmrg</programlisting></blockquote>
166335c4bbdfSmrgLookupKeyboardDevice returns pointer for current main keyboard device.
166435c4bbdfSmrg</para>
166535c4bbdfSmrg<para>
166635c4bbdfSmrg<blockquote><programlisting>
166735c4bbdfSmrg
166835c4bbdfSmrg	DevicePtr LookupPointerDevice()
166935c4bbdfSmrg</programlisting></blockquote>
167035c4bbdfSmrgLookupPointerDevice returns pointer for current main pointing device.
167135c4bbdfSmrg</para>
167235c4bbdfSmrg<para>
167335c4bbdfSmrgA DeviceProc (the kind passed to AddInputDevice()) in the following form:
167435c4bbdfSmrg<blockquote><programlisting>
167535c4bbdfSmrg
167635c4bbdfSmrg	Bool pInternalDevice->DeviceProc(device, action);
167735c4bbdfSmrg		DeviceIntPtr device;
167835c4bbdfSmrg		int action;
167935c4bbdfSmrg</programlisting></blockquote>
168035c4bbdfSmrgYou must write a DeviceProc for each device.
168135c4bbdfSmrgdevice points to the device record.
168235c4bbdfSmrgaction tells what action to take;
168335c4bbdfSmrgit will be one of  these defined constants  (defined in input.h):
168435c4bbdfSmrg<itemizedlist>
168535c4bbdfSmrg<listitem><para>
168635c4bbdfSmrgDEVICE_INIT -
168735c4bbdfSmrgAt DEVICE_INIT time, the device should initialize itself by calling
168835c4bbdfSmrgInitPointerDeviceStruct(), InitKeyboardDeviceStruct(), or a similar
168935c4bbdfSmrgroutine (see below)
169035c4bbdfSmrgand "opening" the device if necessary.
169135c4bbdfSmrgIf you return a non-zero (i.e., != Success) value from the DEVICE_INIT
169235c4bbdfSmrgcall, that device will be considered unavailable. If either the main keyboard
169335c4bbdfSmrgor main pointing device cannot be initialized, the DIX code will refuse
169435c4bbdfSmrgto continue booting up.</para></listitem>
169535c4bbdfSmrg<listitem><para>
169635c4bbdfSmrgDEVICE_ON - If the DeviceProc is called with DEVICE_ON, then it is
169735c4bbdfSmrgallowed to start
169835c4bbdfSmrgputting events into the client stream by calling through the ProcessInputProc
169935c4bbdfSmrgin the device.</para></listitem>
170035c4bbdfSmrg<listitem><para>
170135c4bbdfSmrgDEVICE_OFF - If the DeviceProc is called with DEVICE_OFF, no further
170235c4bbdfSmrgevents from that
170335c4bbdfSmrgdevice should be given to the DIX layer.
170435c4bbdfSmrgThe device will appear to be dead to the user.</para></listitem>
170535c4bbdfSmrg<listitem><para>
170635c4bbdfSmrgDEVICE_CLOSE - At DEVICE_CLOSE (terminate or reset) time, the device should
170735c4bbdfSmrgbe totally closed down.</para></listitem>
170835c4bbdfSmrg</itemizedlist>
170935c4bbdfSmrg</para>
171035c4bbdfSmrg<para>
171135c4bbdfSmrg<blockquote><programlisting>
171235c4bbdfSmrg
171335c4bbdfSmrg	void InitPointerDeviceStruct(device, map, mapLength,
171435c4bbdfSmrg			GetMotionEvents, ControlProc, numMotionEvents)
171535c4bbdfSmrg		DevicePtr device;
171635c4bbdfSmrg		CARD8 *map;
171735c4bbdfSmrg		int mapLength;
171835c4bbdfSmrg		ValuatorMotionProcPtr ControlProc;
171935c4bbdfSmrg		PtrCtrlProcPtr GetMotionEvents;
172035c4bbdfSmrg		int numMotionEvents;
172135c4bbdfSmrg</programlisting></blockquote>
172235c4bbdfSmrgInitPointerDeviceStruct is a DIX routine you call at DEVICE_INIT time to declare
172335c4bbdfSmrgsome operating routines and data structures for a pointing device.
172435c4bbdfSmrgmap and mapLength are as described in the X Window
172535c4bbdfSmrgSystem protocol specification.
172635c4bbdfSmrgControlProc and GetMotionEvents are DDX routines, see above.
172735c4bbdfSmrg</para>
172835c4bbdfSmrg<para>
172935c4bbdfSmrgnumMotionEvents is for the motion-buffer-size for the GetMotionEvents
173035c4bbdfSmrgrequest.
173135c4bbdfSmrgA typical length for a motion buffer would be 100 events.
173235c4bbdfSmrgA server that does not implement this capability should set
173335c4bbdfSmrgnumMotionEvents to zero.
173435c4bbdfSmrg</para>
173535c4bbdfSmrg<para>
173635c4bbdfSmrg<blockquote><programlisting>
173735c4bbdfSmrg
173835c4bbdfSmrg	void InitKeyboardDeviceStruct(device, pKeySyms, pModifiers, Bell, ControlProc)
173935c4bbdfSmrg		DevicePtr device;
174035c4bbdfSmrg		KeySymsPtr pKeySyms;
174135c4bbdfSmrg		CARD8 *pModifiers;
174235c4bbdfSmrg		BellProcPtr Bell;
174335c4bbdfSmrg		KbdCtrlProcPtr ControlProc;
174435c4bbdfSmrg
174535c4bbdfSmrg</programlisting></blockquote>
174635c4bbdfSmrgYou call this DIX routine when a keyboard device is initialized and
174735c4bbdfSmrgits device procedure is called with
174835c4bbdfSmrgDEVICE_INIT.
174935c4bbdfSmrgThe formats of the keysyms and modifier maps are defined in
175035c4bbdfSmrgXserver/include/input.h.
175135c4bbdfSmrgThey describe the layout of keys on the keyboards, and the glyphs
175235c4bbdfSmrgassociated with them.  ( See the next section for information on
175335c4bbdfSmrgsetting up the modifier map and the keysym map.)
175435c4bbdfSmrgControlProc and Bell are DDX routines, see above.
175535c4bbdfSmrg</para>
175635c4bbdfSmrg</section>
175735c4bbdfSmrg<section>
175835c4bbdfSmrg  <title>Keyboard Mapping and Keycodes</title>
175935c4bbdfSmrg<para>
176035c4bbdfSmrgWhen you send a keyboard event, you send a report that a given key has
176135c4bbdfSmrgeither been pressed or has been released.  There must be a keycode for
176235c4bbdfSmrgeach key that identifies the key; the keycode-to-key mapping can be
176335c4bbdfSmrgany mapping you desire, because you specify the mapping in a table you
176435c4bbdfSmrgset up for DIX.  However, you are restricted by the protocol
176535c4bbdfSmrgspecification to keycode values in the range 8 to 255 inclusive.
176635c4bbdfSmrg</para>
176735c4bbdfSmrg<para>
176835c4bbdfSmrgThe keycode mapping information that you set up consists of the following:
176935c4bbdfSmrg<itemizedlist>
177035c4bbdfSmrg<listitem><para>
177135c4bbdfSmrgA minimum and maximum keycode number</para></listitem>
177235c4bbdfSmrg<listitem><para>
177335c4bbdfSmrgAn array of sets of keysyms for each key, that is of length
177435c4bbdfSmrgmaxkeycode - minkeycode + 1.
177535c4bbdfSmrgEach element of this array is a list of codes for symbols that are on that key.
177635c4bbdfSmrgThere is no limit to the number of symbols that can be on a key.</para></listitem>
177735c4bbdfSmrg</itemizedlist>
177835c4bbdfSmrgOnce the map is set up, DIX keeps and
177935c4bbdfSmrgmaintains the client's changes to it.
178035c4bbdfSmrg</para>
178135c4bbdfSmrg<para>
178235c4bbdfSmrgThe X protocol defines standard names to indicate the symbol(s)
178335c4bbdfSmrgprinted on each keycap. (See X11/keysym.h)
178435c4bbdfSmrg</para>
178535c4bbdfSmrg<para>
178635c4bbdfSmrgLegal modifier keys must generate both up and down transitions.  When
178735c4bbdfSmrga client tries to change a modifier key (for instance, to make "A" the
178835c4bbdfSmrg"Control" key), DIX calls the following routine, which should return
178935c4bbdfSmrgTRUE if the key can be used as a modifier on the given device:
179035c4bbdfSmrg<blockquote><programlisting>
179135c4bbdfSmrg
179235c4bbdfSmrg	Bool LegalModifier(key, pDev)
179335c4bbdfSmrg	    unsigned int key;
179435c4bbdfSmrg	    DevicePtr pDev;
179535c4bbdfSmrg</programlisting></blockquote>
179635c4bbdfSmrg</para>
179735c4bbdfSmrg</section>
179835c4bbdfSmrg</section>
179935c4bbdfSmrg<section>
180035c4bbdfSmrg<title>Screens</title>
180135c4bbdfSmrg<para>
180235c4bbdfSmrgDifferent computer graphics
180335c4bbdfSmrgdisplays have different capabilities.
180435c4bbdfSmrgSome are simple monochrome
180535c4bbdfSmrgframe buffers that are just lying
180635c4bbdfSmrgthere in memory, waiting to be written into.
180735c4bbdfSmrgOthers are color displays with many bits per pixel using some color lookup table.
180835c4bbdfSmrgStill others have high-speed graphic processors that prefer to do all of the work
180935c4bbdfSmrgthemselves,
181035c4bbdfSmrgincluding maintaining their own high-level, graphic data structures.
181135c4bbdfSmrg</para>
181235c4bbdfSmrg<section>
181335c4bbdfSmrg  <title>Screen Hardware Requirements</title>
181435c4bbdfSmrg<para>
181535c4bbdfSmrgThe only requirement on screens is that you be able to both read
181635c4bbdfSmrgand write locations in the frame buffer.
181735c4bbdfSmrgAll screens must have a depth of 32 or less (unless you use
181835c4bbdfSmrgan X extension to allow a greater depth).
181935c4bbdfSmrgAll screens must fit into one of the classes listed in the section
182035c4bbdfSmrgin this document on Visuals and Depths.
182135c4bbdfSmrg</para>
182235c4bbdfSmrg<para>
182335c4bbdfSmrgX uses the pixel as its fundamental unit of distance on the screen.
182435c4bbdfSmrgTherefore, most programs will measure everything in pixels.</para>
182535c4bbdfSmrg<para>
182635c4bbdfSmrgThe sample server assumes square pixels.
182735c4bbdfSmrgSerious WYSIWYG (what you see is what you get) applications for
182835c4bbdfSmrgpublishing and drawing programs will adjust for
182935c4bbdfSmrgdifferent screen resolutions automatically.
183035c4bbdfSmrgConsiderable work
183135c4bbdfSmrgis involved in compensating for non-square pixels (a bit in the DDX
183235c4bbdfSmrgcode for the sample server but quite a bit in the client applications).</para>
183335c4bbdfSmrg</section>
183435c4bbdfSmrg<section>
183535c4bbdfSmrg  <title>Data Structures</title>
183635c4bbdfSmrg<para>
183735c4bbdfSmrgX supports multiple screens that are connected to the same
183835c4bbdfSmrgserver.  Therefore, all the per-screen information is bundled into one data
183935c4bbdfSmrgstructure of attributes and procedures, which is the ScreenRec (see
184035c4bbdfSmrgXserver/include/scrnintstr.h).
184135c4bbdfSmrgThe procedure entry points in a ScreenRec operate on
184235c4bbdfSmrgregions, colormaps, cursors, and fonts, because these resources
184335c4bbdfSmrgcan differ in format from one screen to another.</para>
184435c4bbdfSmrg<para>
184535c4bbdfSmrgWindows are areas on the screen that can be drawn into by graphic
184635c4bbdfSmrgroutines.  "Pixmaps" are off-screen graphic areas that can be drawn
184735c4bbdfSmrginto.  They are both considered drawables and are described in the
184835c4bbdfSmrgsection on Drawables.  All graphic operations work on drawables, and
184935c4bbdfSmrgoperations are available to copy patches from one drawable to another.</para>
185035c4bbdfSmrg<para>
185135c4bbdfSmrgThe pixel image data in all drawables is in a format that is private
185235c4bbdfSmrgto DDX.  In fact, each instance of a drawable is associated with a
185335c4bbdfSmrggiven screen.  Presumably, the pixel image data for pixmaps is chosen
185435c4bbdfSmrgto be conveniently understood by the hardware.  All screens in a
185535c4bbdfSmrgsingle server must be able to handle all pixmaps depths declared in
185635c4bbdfSmrgthe connection setup information.</para>
185735c4bbdfSmrg<para>
185835c4bbdfSmrgPixmap images are transferred to the server in one of two ways:
185935c4bbdfSmrgXYPixmap or ZPimap.  XYPixmaps are a series of bitmaps, one for each
186035c4bbdfSmrgbit plane of the image, using the bitmap padding rules from the
186135c4bbdfSmrgconnection setup.  ZPixmaps are a series of bits, nibbles, bytes or
186235c4bbdfSmrgwords, one for each pixel, using the format rules (padding and so on)
186335c4bbdfSmrgfor the appropriate depth.</para>
186435c4bbdfSmrg<para>
186535c4bbdfSmrgAll screens in a given server must agree on a set of pixmap image
186635c4bbdfSmrgformats (PixmapFormat) to support (depth, number of bits per pixel,
186735c4bbdfSmrgetc.).</para>
186835c4bbdfSmrg<para>
186935c4bbdfSmrgThere is no color interpretation of bits in the pixmap.  Pixmaps
187035c4bbdfSmrgdo not contain pixel values.  The interpretation is made only when
187135c4bbdfSmrgthe bits are transferred onto the screen.</para>
187235c4bbdfSmrg<para>
187335c4bbdfSmrgThe screenInfo structure (in scrnintstr.h) is a global data structure
187435c4bbdfSmrgthat has a pointer to an array of ScreenRecs, one for each screen on
187535c4bbdfSmrgthe server.  (These constitute the one and only description of each
187635c4bbdfSmrgscreen in the server.)  Each screen has an identifying index (0, 1, 2, ...).
187735c4bbdfSmrgIn addition, the screenInfo struct contains global server-wide
187835c4bbdfSmrgdetails, such as the bit- and byte- order in all bit images, and the
187935c4bbdfSmrglist of pixmap image formats that are supported.  The X protocol
188035c4bbdfSmrginsists that these must be the same for all screens on the server.</para>
188135c4bbdfSmrg</section>
188235c4bbdfSmrg<section>
188335c4bbdfSmrg  <title>Output Initialization</title>
188435c4bbdfSmrg<para>
188535c4bbdfSmrg<blockquote><programlisting>
188635c4bbdfSmrg
188735c4bbdfSmrg	InitOutput(pScreenInfo, argc, argv)
188835c4bbdfSmrg		ScreenInfo *pScreenInfo;
188935c4bbdfSmrg		int argc;
189035c4bbdfSmrg		char **argv;
189135c4bbdfSmrg</programlisting></blockquote>
189235c4bbdfSmrgUpon initialization, your DDX routine InitOutput() is called by DIX.
189335c4bbdfSmrgIt is passed a pointer to screenInfo to initialize.  It is also passed
189435c4bbdfSmrgthe argc and argv from main() for your server for the command-line
189535c4bbdfSmrgarguments.  These arguments may indicate what or how many screen
189635c4bbdfSmrgdevice(s) to use or in what way to use them.  For instance, your
189735c4bbdfSmrgserver command line may allow a "-D" flag followed by the name of the
189835c4bbdfSmrgscreen device to use.</para>
189935c4bbdfSmrg<para>
190035c4bbdfSmrgYour InitOutput() routine should initialize each screen you wish to
190135c4bbdfSmrguse by calling AddScreen(), and then it should initialize the pixmap
190235c4bbdfSmrgformats that you support by storing values directly into the
190335c4bbdfSmrgscreenInfo data structure.  You should also set certain
190435c4bbdfSmrgimplementation-dependent numbers and procedures in your screenInfo,
190535c4bbdfSmrgwhich determines the pixmap and scanline padding rules for all screens
190635c4bbdfSmrgin the server.</para>
190735c4bbdfSmrg<para>
190835c4bbdfSmrg<blockquote><programlisting>
190935c4bbdfSmrg
191035c4bbdfSmrg	int AddScreen(scrInitProc, argc, argv)
191135c4bbdfSmrg		Bool (*scrInitProc)();
191235c4bbdfSmrg		int argc;
191335c4bbdfSmrg		char **argv;
191435c4bbdfSmrg</programlisting></blockquote>
191535c4bbdfSmrgYou should call AddScreen(), a DIX procedure, in InitOutput() once for
191635c4bbdfSmrgeach screen to add it to the screenInfo database.  The first argument
191735c4bbdfSmrgis an initialization procedure for the screen that you supply.  The
191835c4bbdfSmrgsecond and third are the argc and argv from main().  It returns the
191935c4bbdfSmrgscreen number of the screen installed, or -1 if there is either
192035c4bbdfSmrginsufficient memory to add the screen, or (*scrInitProc) returned
192135c4bbdfSmrgFALSE.</para>
192235c4bbdfSmrg<para>
192335c4bbdfSmrgThe scrInitProc should be of the following form:
192435c4bbdfSmrg<blockquote><programlisting>
192535c4bbdfSmrg
192635c4bbdfSmrg	Bool scrInitProc(pScreen, argc, argv)
192735c4bbdfSmrg		ScreenPtr pScreen;
192835c4bbdfSmrg		int argc;
192935c4bbdfSmrg		char **argv;
193035c4bbdfSmrg</programlisting></blockquote>
193135c4bbdfSmrgpScreen is the pointer to the screen's new ScreenRec. argc and argv
193235c4bbdfSmrgare as before.  Your screen initialize procedure should return TRUE
193335c4bbdfSmrgupon success or FALSE if the screen cannot be initialized (for
193435c4bbdfSmrg instance, if the screen hardware does not exist on this machine).</para>
193535c4bbdfSmrg<para>
193635c4bbdfSmrgThis procedure must determine what actual device it is supposed to initialize.
193735c4bbdfSmrgIf you have a different procedure for each screen, then it is no problem.
193835c4bbdfSmrgIf you have the same procedure for multiple screens, it may have trouble
193935c4bbdfSmrgfiguring out which screen to initialize each time around, especially if
194035c4bbdfSmrgInitOutput() does not initialize all of the screens.
194135c4bbdfSmrgIt is probably easiest to have one procedure for each screen.</para>
194235c4bbdfSmrg<para>
194335c4bbdfSmrgThe initialization procedure should fill in all the screen procedures
194435c4bbdfSmrgfor that screen (windowing functions, region functions, etc.) and certain
194535c4bbdfSmrgscreen attributes for that screen.</para>
194635c4bbdfSmrg</section>
194735c4bbdfSmrg<section>
194835c4bbdfSmrg  <title>Region Routines in the ScreenRec</title>
194935c4bbdfSmrg<para>
195035c4bbdfSmrgA region is a dynamically allocated data structure that describes an
195135c4bbdfSmrgirregularly shaped piece of real estate in XY pixel space.  You can
195235c4bbdfSmrgthink of it as a set of pixels on the screen to be operated upon with
195335c4bbdfSmrgset operations such as AND and OR.</para>
195435c4bbdfSmrg<para>
195535c4bbdfSmrgA region is frequently implemented as a list of rectangles or bitmaps
195635c4bbdfSmrgthat enclose the selected pixels.  Region operators control the
195735c4bbdfSmrg"clipping policy," or the operations that work on regions.  (The
195835c4bbdfSmrgsample server uses YX-banded rectangles.  Unless you have something
195935c4bbdfSmrgalready implemented for your graphics system, you should keep that
196035c4bbdfSmrgimplementation.)  The procedure pointers to the region operators are
196135c4bbdfSmrglocated in the ScreenRec data structure.  The definition of a region
196235c4bbdfSmrgcan be found in the file Xserver/include/regionstr.h.  The region code
196335c4bbdfSmrgis found in Xserver/mi/miregion.c.  DDX implementations using other
196435c4bbdfSmrgregion formats will need to supply different versions of the region
196535c4bbdfSmrgoperators.</para>
196635c4bbdfSmrg<para>
196735c4bbdfSmrgSince the list of rectangles is unbounded in size, part of the region
196835c4bbdfSmrgdata structure is usually a large, dynamically allocated chunk of
196935c4bbdfSmrgmemory.  As your region operators calculate logical combinations of
197035c4bbdfSmrgregions, these blocks may need to be reallocated by your region
197135c4bbdfSmrgsoftware.  For instance, in the sample server, a RegionRec has some
197235c4bbdfSmrgheader information and a pointer to a dynamically allocated rectangle
197335c4bbdfSmrglist.  Periodically, the rectangle list needs to be expanded with
197435c4bbdfSmrgrealloc(), whereupon the new pointer is remembered in the RegionRec.</para>
197535c4bbdfSmrg<para>
197635c4bbdfSmrgMost of the region operations come in two forms: a function pointer in
197735c4bbdfSmrgthe Screen structure, and a macro.  The server can be compiled so that
197835c4bbdfSmrgthe macros make direct calls to the appropriate functions (instead of
197935c4bbdfSmrgindirecting through a screen function pointer), or it can be compiled
198035c4bbdfSmrgso that the macros are identical to the function pointer forms.
198135c4bbdfSmrgMaking direct calls is faster on many architectures.</para>
198235c4bbdfSmrg<para>
198335c4bbdfSmrg<blockquote><programlisting>
198435c4bbdfSmrg
198535c4bbdfSmrg	RegionPtr pScreen->RegionCreate( rect, size)
198635c4bbdfSmrg		BoxPtr rect;
198735c4bbdfSmrg		int size;
198835c4bbdfSmrg
198935c4bbdfSmrg	macro: RegionPtr RegionCreate(rect, size)
199035c4bbdfSmrg
199135c4bbdfSmrg</programlisting></blockquote>
199235c4bbdfSmrgRegionCreate creates a region that describes ONE rectangle.  The
199335c4bbdfSmrgcaller can avoid unnecessary reallocation and copying by declaring the
199435c4bbdfSmrgprobable maximum number of rectangles that this region will need to
199535c4bbdfSmrgdescribe itself.  Your region routines, though, cannot fail just
199635c4bbdfSmrgbecause the region grows beyond this size.  The caller of this routine
199735c4bbdfSmrgcan pass almost anything as the size; the value is merely a good guess
199835c4bbdfSmrgas to the maximum size until it is proven wrong by subsequent use.
199935c4bbdfSmrgYour region procedures are then on their own in estimating how big the
200035c4bbdfSmrgregion will get.  Your implementation might ignore size, if
200135c4bbdfSmrgapplicable.</para>
200235c4bbdfSmrg<para>
200335c4bbdfSmrg<blockquote><programlisting>
200435c4bbdfSmrg
200535c4bbdfSmrg	void pScreen->RegionInit (pRegion, rect, size)
200635c4bbdfSmrg		RegionPtr	pRegion;
200735c4bbdfSmrg		BoxPtr		rect;
200835c4bbdfSmrg		int		size;
200935c4bbdfSmrg
201035c4bbdfSmrg	macro: RegionInit(pRegion, rect, size)
201135c4bbdfSmrg
201235c4bbdfSmrg</programlisting></blockquote>
201335c4bbdfSmrgGiven an existing raw region structure (such as an local variable), this
201435c4bbdfSmrgroutine fills in the appropriate fields to make this region as usable as
201535c4bbdfSmrgone returned from RegionCreate.  This avoids the additional dynamic memory
201635c4bbdfSmrgallocation overhead for the region structure itself.
201735c4bbdfSmrg</para>
201835c4bbdfSmrg<para>
201935c4bbdfSmrg<blockquote><programlisting>
202035c4bbdfSmrg
202135c4bbdfSmrg	Bool pScreen->RegionCopy(dstrgn, srcrgn)
202235c4bbdfSmrg		RegionPtr dstrgn, srcrgn;
202335c4bbdfSmrg
202435c4bbdfSmrg	macro: Bool RegionCopy(dstrgn, srcrgn)
202535c4bbdfSmrg
202635c4bbdfSmrg</programlisting></blockquote>
202735c4bbdfSmrgRegionCopy copies the description of one region, srcrgn, to another
202835c4bbdfSmrgalready-created region,
202935c4bbdfSmrgdstrgn; returning TRUE if the copy succeeded, and FALSE otherwise.</para>
203035c4bbdfSmrg<para>
203135c4bbdfSmrg<blockquote><programlisting>
203235c4bbdfSmrg
203335c4bbdfSmrg	void pScreen->RegionDestroy( pRegion)
203435c4bbdfSmrg		RegionPtr pRegion;
203535c4bbdfSmrg
203635c4bbdfSmrg	macro: RegionDestroy(pRegion)
203735c4bbdfSmrg
203835c4bbdfSmrg</programlisting></blockquote>
203935c4bbdfSmrgRegionDestroy destroys a region and frees all allocated memory.</para>
204035c4bbdfSmrg<para>
204135c4bbdfSmrg<blockquote><programlisting>
204235c4bbdfSmrg
204335c4bbdfSmrg	void pScreen->RegionUninit (pRegion)
204435c4bbdfSmrg		RegionPtr pRegion;
204535c4bbdfSmrg
204635c4bbdfSmrg	macro: RegionUninit(pRegion)
204735c4bbdfSmrg
204835c4bbdfSmrg</programlisting></blockquote>
204935c4bbdfSmrgFrees everything except the region structure itself, useful when the
205035c4bbdfSmrgregion was originally passed to RegionInit instead of received from
205135c4bbdfSmrgRegionCreate.  When this call returns, pRegion must not be reused until
205235c4bbdfSmrgit has been RegionInit'ed again.</para>
205335c4bbdfSmrg<para>
205435c4bbdfSmrg<blockquote><programlisting>
205535c4bbdfSmrg
205635c4bbdfSmrg	Bool pScreen->Intersect(newReg, reg1, reg2)
205735c4bbdfSmrg		RegionPtr newReg, reg1, reg2;
205835c4bbdfSmrg
205935c4bbdfSmrg	macro: Bool RegionIntersect(newReg, reg1, reg2)
206035c4bbdfSmrg
206135c4bbdfSmrg	Bool  pScreen->Union(newReg, reg1, reg2)
206235c4bbdfSmrg		RegionPtr newReg, reg1, reg2;
206335c4bbdfSmrg
206435c4bbdfSmrg	macro: Bool RegionUnion(newReg, reg1, reg2)
206535c4bbdfSmrg
206635c4bbdfSmrg	Bool  pScreen->Subtract(newReg, regMinuend, regSubtrahend)
206735c4bbdfSmrg		RegionPtr newReg, regMinuend, regSubtrahend;
206835c4bbdfSmrg
206935c4bbdfSmrg	macro: Bool RegionUnion(newReg, regMinuend, regSubtrahend)
207035c4bbdfSmrg
207135c4bbdfSmrg	Bool pScreen->Inverse(newReg, pReg,  pBox)
207235c4bbdfSmrg		RegionPtr newReg, pReg;
207335c4bbdfSmrg		BoxPtr pBox;
207435c4bbdfSmrg
207535c4bbdfSmrg	macro: Bool RegionInverse(newReg, pReg,  pBox)
207635c4bbdfSmrg
207735c4bbdfSmrg</programlisting></blockquote>
207835c4bbdfSmrgThe above four calls all do basic logical operations on regions.  They
207935c4bbdfSmrgset the new region (which already exists) to describe the logical
208035c4bbdfSmrgintersection, union, set difference, or inverse of the region(s) that
208135c4bbdfSmrgwere passed in.  Your routines must be able to handle a situation
208235c4bbdfSmrgwhere the newReg is the same region as one of the other region
208335c4bbdfSmrgarguments.</para>
208435c4bbdfSmrg<para>
208535c4bbdfSmrgThe subtract function removes the Subtrahend from the Minuend and
208635c4bbdfSmrgputs the result in newReg.</para>
208735c4bbdfSmrg<para>
208835c4bbdfSmrgThe inverse function returns a region that is the pBox minus the
208935c4bbdfSmrgregion passed in.  (A true "inverse" would make a region that extends
209035c4bbdfSmrgto infinity in all directions but has holes in the middle.)  It is
209135c4bbdfSmrgundefined for situations where the region extends beyond the box.</para>
209235c4bbdfSmrg<para>
209335c4bbdfSmrgEach routine must return the value TRUE for success.</para>
209435c4bbdfSmrg<para>
209535c4bbdfSmrg<blockquote><programlisting>
209635c4bbdfSmrg
209735c4bbdfSmrg	void pScreen->RegionReset(pRegion, pBox)
209835c4bbdfSmrg		RegionPtr pRegion;
209935c4bbdfSmrg		BoxPtr pBox;
210035c4bbdfSmrg
210135c4bbdfSmrg	macro: RegionReset(pRegion, pBox)
210235c4bbdfSmrg
210335c4bbdfSmrg</programlisting></blockquote>
210435c4bbdfSmrgRegionReset sets the region to describe
210535c4bbdfSmrgone rectangle and reallocates it to a size of one rectangle, if applicable.</para>
210635c4bbdfSmrg<para>
210735c4bbdfSmrg<blockquote><programlisting>
210835c4bbdfSmrg
210935c4bbdfSmrg	void  pScreen->TranslateRegion(pRegion, x, y)
211035c4bbdfSmrg		RegionPtr pRegion;
211135c4bbdfSmrg		int x, y;
211235c4bbdfSmrg
211335c4bbdfSmrg	macro: RegionTranslate(pRegion, x, y)
211435c4bbdfSmrg
211535c4bbdfSmrg</programlisting></blockquote>
211635c4bbdfSmrgTranslateRegion simply moves a region +x in the x direction and +y in the y
211735c4bbdfSmrgdirection.</para>
211835c4bbdfSmrg<para>
211935c4bbdfSmrg<blockquote><programlisting>
212035c4bbdfSmrg
212135c4bbdfSmrg	int  pScreen->RectIn(pRegion, pBox)
212235c4bbdfSmrg		RegionPtr pRegion;
212335c4bbdfSmrg		BoxPtr pBox;
212435c4bbdfSmrg
212535c4bbdfSmrg	macro: int RegionContainsRect(pRegion, pBox)
212635c4bbdfSmrg
212735c4bbdfSmrg</programlisting></blockquote>
212835c4bbdfSmrgRectIn returns one of the defined constants rgnIN, rgnOUT, or rgnPART,
212935c4bbdfSmrgdepending upon whether the box is entirely inside the region, entirely
213035c4bbdfSmrgoutside of the region, or partly in and partly out of the region.
213135c4bbdfSmrgThese constants are defined in Xserver/include/region.h.</para>
213235c4bbdfSmrg<para>
213335c4bbdfSmrg<blockquote><programlisting>
213435c4bbdfSmrg
213535c4bbdfSmrg	Bool pScreen->PointInRegion(pRegion, x, y, pBox)
213635c4bbdfSmrg		RegionPtr pRegion;
213735c4bbdfSmrg		int x, y;
213835c4bbdfSmrg		BoxPtr pBox;
213935c4bbdfSmrg
214035c4bbdfSmrg	macro: Bool RegionContainsPoint(pRegion, x, y, pBox)
214135c4bbdfSmrg
214235c4bbdfSmrg</programlisting></blockquote>
214335c4bbdfSmrgPointInRegion returns true if the point x, y is in the region.  In
214435c4bbdfSmrgaddition, it fills the rectangle pBox with coordinates of a rectangle
214535c4bbdfSmrgthat is entirely inside of pRegion and encloses the point.  In the mi
214635c4bbdfSmrgimplementation, it is the largest such rectangle.  (Due to the sample
214735c4bbdfSmrgserver implementation, this comes cheaply.)</para>
214835c4bbdfSmrg<para>
214935c4bbdfSmrgThis routine used by DIX when tracking the pointing device and
215035c4bbdfSmrgdeciding whether to report mouse events or change the cursor.  For
215135c4bbdfSmrginstance, DIX needs to change the cursor when it moves from one window
215235c4bbdfSmrgto another.  Due to overlapping windows, the shape to check may be
215335c4bbdfSmrgirregular.  A PointInRegion() call for every pointing device movement
215435c4bbdfSmrgmay be too expensive.  The pBox is a kind of wake-up box; DIX need not
215535c4bbdfSmrgcall PointInRegion() again until the cursor wanders outside of the
215635c4bbdfSmrgreturned box.</para>
215735c4bbdfSmrg<para>
215835c4bbdfSmrg<blockquote><programlisting>
215935c4bbdfSmrg
216035c4bbdfSmrg	Bool pScreen->RegionNotEmpty(pRegion)
216135c4bbdfSmrg		RegionPtr pRegion;
216235c4bbdfSmrg
216335c4bbdfSmrg	macro: Bool RegionNotEmpty(pRegion)
216435c4bbdfSmrg
216535c4bbdfSmrg</programlisting></blockquote>
216635c4bbdfSmrgRegionNotEmpty is a boolean function that returns
216735c4bbdfSmrgtrue or false depending upon whether the region encloses any pixels.</para>
216835c4bbdfSmrg<para>
216935c4bbdfSmrg<blockquote><programlisting>
217035c4bbdfSmrg
217135c4bbdfSmrg	void pScreen->RegionEmpty(pRegion)
217235c4bbdfSmrg		RegionPtr pRegion;
217335c4bbdfSmrg
217435c4bbdfSmrg	macro: RegionEmpty(pRegion)
217535c4bbdfSmrg
217635c4bbdfSmrg</programlisting></blockquote>
217735c4bbdfSmrgRegionEmpty sets the region to be empty.</para>
217835c4bbdfSmrg<para>
217935c4bbdfSmrg<blockquote><programlisting>
218035c4bbdfSmrg
218135c4bbdfSmrg	BoxPtr pScreen->RegionExtents(pRegion)
218235c4bbdfSmrg		RegionPtr pRegion;
218335c4bbdfSmrg
218435c4bbdfSmrg	macro: RegionExtents(pRegion)
218535c4bbdfSmrg
218635c4bbdfSmrg</programlisting></blockquote>
218735c4bbdfSmrgRegionExtents returns a rectangle that is the smallest
218835c4bbdfSmrgpossible superset of the entire region.
218935c4bbdfSmrgThe caller will not modify this rectangle, so it can be the one
219035c4bbdfSmrgin your region struct.</para>
219135c4bbdfSmrg<para>
219235c4bbdfSmrg<blockquote><programlisting>
219335c4bbdfSmrg
219435c4bbdfSmrg	Bool pScreen->RegionAppend (pDstRgn, pRegion)
219535c4bbdfSmrg		RegionPtr pDstRgn;
219635c4bbdfSmrg		RegionPtr pRegion;
219735c4bbdfSmrg
219835c4bbdfSmrg	macro: Bool RegionAppend(pDstRgn, pRegion)
219935c4bbdfSmrg
220035c4bbdfSmrg	Bool pScreen->RegionValidate (pRegion, pOverlap)
220135c4bbdfSmrg		RegionPtr pRegion;
220235c4bbdfSmrg		Bool *pOverlap;
220335c4bbdfSmrg
220435c4bbdfSmrg	macro: Bool RegionValidate(pRegion, pOverlap)
220535c4bbdfSmrg
220635c4bbdfSmrg</programlisting></blockquote>
220735c4bbdfSmrgThese functions provide an optimization for clip list generation and
220835c4bbdfSmrgmust be used in conjunction.  The combined effect is to produce the
220935c4bbdfSmrgunion of a collection of regions, by using RegionAppend several times,
221035c4bbdfSmrgand finally calling RegionValidate which takes the intermediate
221135c4bbdfSmrgrepresentation (which needn't be a valid region) and produces the
221235c4bbdfSmrgdesired union.  pOverlap is set to TRUE if any of the original
221335c4bbdfSmrgregions overlap; FALSE otherwise.</para>
221435c4bbdfSmrg<para>
221535c4bbdfSmrg<blockquote><programlisting>
221635c4bbdfSmrg
221735c4bbdfSmrg	RegionPtr pScreen->BitmapToRegion (pPixmap)
221835c4bbdfSmrg		PixmapPtr pPixmap;
221935c4bbdfSmrg
222035c4bbdfSmrg	macro: RegionPtr BitmapToRegion(pScreen, pPixmap)
222135c4bbdfSmrg
222235c4bbdfSmrg</programlisting></blockquote>
222335c4bbdfSmrgGiven a depth-1 pixmap, this routine must create a valid region which
222435c4bbdfSmrgincludes all the areas of the pixmap filled with 1's and excludes the
222535c4bbdfSmrgareas filled with 0's.  This routine returns NULL if out of memory.</para>
222635c4bbdfSmrg<para>
222735c4bbdfSmrg<blockquote><programlisting>
222835c4bbdfSmrg
222935c4bbdfSmrg	RegionPtr pScreen->RectsToRegion (nrects, pRects, ordering)
223035c4bbdfSmrg		int nrects;
223135c4bbdfSmrg		xRectangle *pRects;
223235c4bbdfSmrg		int ordering;
223335c4bbdfSmrg
223435c4bbdfSmrg	macro: RegionPtr RegionFromRects(nrects, pRects, ordering)
223535c4bbdfSmrg
223635c4bbdfSmrg</programlisting></blockquote>
223735c4bbdfSmrgGiven a client-supplied list of rectangles, produces a region which includes
223835c4bbdfSmrgthe union of all the rectangles.  Ordering may be used as a hint which
223935c4bbdfSmrgdescribes how the rectangles are sorted.  As the hint is provided by a
224035c4bbdfSmrgclient, it must not be required to be correct, but the results when it is
224135c4bbdfSmrgnot correct are not defined (core dump is not an option here).</para>
224235c4bbdfSmrg<para>
224335c4bbdfSmrg<blockquote><programlisting>
224435c4bbdfSmrg
224535c4bbdfSmrg	void pScreen->SendGraphicsExpose(client,pRegion,drawable,major,minor)
224635c4bbdfSmrg		ClientPtr client;
224735c4bbdfSmrg		RegionPtr pRegion;
224835c4bbdfSmrg		XID drawable;
224935c4bbdfSmrg		int major;
225035c4bbdfSmrg		int minor;
225135c4bbdfSmrg
225235c4bbdfSmrg</programlisting></blockquote>
225335c4bbdfSmrgSendGraphicsExpose dispatches a list of GraphicsExposure events which
225435c4bbdfSmrgspan the region to the specified client.  If the region is empty, or
225535c4bbdfSmrga NULL pointer, a NoExpose event is sent instead.</para>
225635c4bbdfSmrg</section>
225735c4bbdfSmrg<section>
225835c4bbdfSmrg  <title>Cursor Routines for a Screen</title>
225935c4bbdfSmrg<para>
226035c4bbdfSmrgA cursor is the visual form tied to the pointing device.  The default
226135c4bbdfSmrgcursor is an "X" shape, but the cursor can have any shape.  When a
226235c4bbdfSmrgclient creates a window, it declares what shape the cursor will be
226335c4bbdfSmrgwhen it strays into that window on the screen.</para>
226435c4bbdfSmrg<para>
226535c4bbdfSmrgFor each possible shape the cursor assumes, there is a CursorRec data
226635c4bbdfSmrgstructure.  This data structure contains a pointer to a CursorBits
226735c4bbdfSmrgdata structure which contains a bitmap for the image of the cursor and
226835c4bbdfSmrga bitmap for a mask behind the cursor, in addition, the CursorRec data
226935c4bbdfSmrgstructure contains foreground and background colors for the cursor.
227035c4bbdfSmrgThe CursorBits data structure is shared among multiple CursorRec
227135c4bbdfSmrgstructures which use the same font and glyph to describe both source
227235c4bbdfSmrgand mask.  The cursor image is applied to the screen by applying the
227335c4bbdfSmrgmask first, clearing 1 bits in its form to the background color, and
227435c4bbdfSmrgthen overwriting on the source image, in the foreground color.  (One
227535c4bbdfSmrgbits of the source image that fall on top of zero bits of the mask
227635c4bbdfSmrgimage are undefined.)  This way, a cursor can have transparent parts,
227735c4bbdfSmrgand opaque parts in two colors.  X allows any cursor size, but some
227835c4bbdfSmrghardware cursor schemes allow a maximum of N pixels by M pixels.
227935c4bbdfSmrgTherefore, you are allowed to transform the cursor to a smaller size,
228035c4bbdfSmrgbut be sure to include the hot-spot.</para>
228135c4bbdfSmrg<para>
228235c4bbdfSmrgCursorBits in Xserver/include/cursorstr.h is a device-independent
228335c4bbdfSmrgstructure containing a device-independent representation of the bits
228435c4bbdfSmrgfor the source and mask.  (This is possible because the bitmap
228535c4bbdfSmrgrepresentation is the same for all screens.)</para>
228635c4bbdfSmrg<para>
228735c4bbdfSmrgWhen a cursor is created, it is "realized" for each screen.  At
228835c4bbdfSmrgrealization time, each screen has the chance to convert the bits into
228935c4bbdfSmrgsome other representation that may be more convenient (for instance,
229035c4bbdfSmrgputting the cursor into off-screen memory) and set up its
229135c4bbdfSmrgdevice-private area in either the CursorRec data structure or
229235c4bbdfSmrgCursorBits data structure as appropriate to possibly point to whatever
229335c4bbdfSmrgdata structures are needed.  It is more memory-conservative to share
229435c4bbdfSmrgrealizations by using the CursorBits private field, but this makes the
229535c4bbdfSmrgassumption that the realization is independent of the colors used
229635c4bbdfSmrg(which is typically true).  For instance, the following are the device
229735c4bbdfSmrgprivate entries for a particular screen and cursor:
229835c4bbdfSmrg<blockquote><programlisting>
229935c4bbdfSmrg
230035c4bbdfSmrg	pCursor->devPriv[pScreen->myNum]
230135c4bbdfSmrg	pCursor->bits->devPriv[pScreen->myNum]
230235c4bbdfSmrg
230335c4bbdfSmrg</programlisting></blockquote>
230435c4bbdfSmrgThis is done because the change from one cursor shape to another must
230535c4bbdfSmrgbe fast and responsive; the cursor image should be able to flutter as
230635c4bbdfSmrgfast as the user moves it across the screen.</para>
230735c4bbdfSmrg<para>
230835c4bbdfSmrgYou must implement the following routines for your hardware:
230935c4bbdfSmrg<blockquote><programlisting>
231035c4bbdfSmrg
231135c4bbdfSmrg	Bool pScreen->RealizeCursor( pScr, pCurs)
231235c4bbdfSmrg		ScreenPtr pScr;
231335c4bbdfSmrg		CursorPtr pCurs;
231435c4bbdfSmrg
231535c4bbdfSmrg	Bool pScreen->UnrealizeCursor( pScr, pCurs)
231635c4bbdfSmrg		ScreenPtr pScr;
231735c4bbdfSmrg		CursorPtr pCurs;
231835c4bbdfSmrg
231935c4bbdfSmrg</programlisting></blockquote>
232035c4bbdfSmrg</para>
232135c4bbdfSmrg<para>
232235c4bbdfSmrgRealizeCursor and UnrealizeCursor should realize (allocate and
232335c4bbdfSmrgcalculate all data needed) and unrealize (free the dynamically
232435c4bbdfSmrgallocated data) a given cursor when DIX needs them.  They are called
232535c4bbdfSmrgwhenever a device-independent cursor is created or destroyed.  The
232635c4bbdfSmrgsource and mask bits pointed to by fields in pCurs are undefined for
232735c4bbdfSmrgbits beyond the right edge of the cursor.  This is so because the bits
232835c4bbdfSmrgare in Bitmap format, which may have pad bits on the right edge.  You
232935c4bbdfSmrgshould inhibit UnrealizeCursor() if the cursor is currently in use;
233035c4bbdfSmrgthis happens when the system is reset.</para>
233135c4bbdfSmrg<para>
233235c4bbdfSmrg<blockquote><programlisting>
233335c4bbdfSmrg
233435c4bbdfSmrg	Bool pScreen->DisplayCursor( pScr, pCurs)
233535c4bbdfSmrg		ScreenPtr pScr;
233635c4bbdfSmrg		CursorPtr pCurs;
233735c4bbdfSmrg
233835c4bbdfSmrg</programlisting></blockquote>
233935c4bbdfSmrgDisplayCursor should change the cursor on the given screen to the one
234035c4bbdfSmrgpassed in.  It is called by DIX when the user moves the pointing
234135c4bbdfSmrgdevice into a different window with a different cursor.  The hotspot
234235c4bbdfSmrgin the cursor should be aligned with the current cursor position.</para>
234335c4bbdfSmrg<para>
234435c4bbdfSmrg<blockquote><programlisting>
234535c4bbdfSmrg
234635c4bbdfSmrg	void pScreen->RecolorCursor( pScr, pCurs, displayed)
234735c4bbdfSmrg		ScreenPtr pScr;
234835c4bbdfSmrg		CursorPtr pCurs;
234935c4bbdfSmrg		Bool displayed;
235035c4bbdfSmrg</programlisting></blockquote>
235135c4bbdfSmrgRecolorCursor notifies DDX that the colors in pCurs have changed and
235235c4bbdfSmrgindicates whether this is the cursor currently being displayed.  If it
235335c4bbdfSmrgis, the cursor hardware state may have to be updated.  Whether
235435c4bbdfSmrgdisplayed or not, state created at RealizeCursor time may have to be
235535c4bbdfSmrgupdated.  A generic version, miRecolorCursor, may be used that
235635c4bbdfSmrgdoes an unrealize, a realize, and possibly a display (in micursor.c);
235735c4bbdfSmrghowever this constrains UnrealizeCursor and RealizeCursor to always return
235835c4bbdfSmrgTRUE as no error indication is returned here.</para>
235935c4bbdfSmrg<para>
236035c4bbdfSmrg<blockquote><programlisting>
236135c4bbdfSmrg
236235c4bbdfSmrg	void pScreen->ConstrainCursor( pScr, pBox)
236335c4bbdfSmrg		ScreenPtr pScr;
236435c4bbdfSmrg		BoxPtr pBox;
236535c4bbdfSmrg
236635c4bbdfSmrg</programlisting></blockquote>
236735c4bbdfSmrgConstrainCursor should cause the cursor to restrict its motion to the
236835c4bbdfSmrgrectangle pBox.  DIX code is capable of enforcing this constraint by
236935c4bbdfSmrgforcefully moving the cursor if it strays out of the rectangle, but
237035c4bbdfSmrgConstrainCursor offers a way to send a hint to the driver or hardware
237135c4bbdfSmrgif such support is available.  This can prevent the cursor from
237235c4bbdfSmrgwandering out of the box, then jumping back, as DIX forces it back.</para>
237335c4bbdfSmrg<para>
237435c4bbdfSmrg<blockquote><programlisting>
237535c4bbdfSmrg
237635c4bbdfSmrg	void pScreen->PointerNonInterestBox( pScr, pBox)
237735c4bbdfSmrg		ScreenPtr pScr;
237835c4bbdfSmrg		BoxPtr pBox;
237935c4bbdfSmrg
238035c4bbdfSmrg</programlisting></blockquote>
238135c4bbdfSmrgPointerNonInterestBox is DIX's way of telling the pointing device code
238235c4bbdfSmrgnot to report motion events while the cursor is inside a given
238335c4bbdfSmrgrectangle on the given screen.  It is optional and, if not
238435c4bbdfSmrgimplemented, it should do nothing.  This routine is called only when
238535c4bbdfSmrgthe client has declared that it is not interested in motion events in
238635c4bbdfSmrga given window.  The rectangle you get may be a subset of that window.
238735c4bbdfSmrgIt saves DIX code the time required to discard uninteresting mouse
238835c4bbdfSmrgmotion events.  This is only a hint, which may speed performance.
238935c4bbdfSmrgNothing in DIX currently calls PointerNonInterestBox.</para>
239035c4bbdfSmrg<para>
239135c4bbdfSmrg<blockquote><programlisting>
239235c4bbdfSmrg
239335c4bbdfSmrg	void pScreen->CursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
239435c4bbdfSmrg		ScreenPtr pScr;
239535c4bbdfSmrg		CursorPtr pCurs;
239635c4bbdfSmrg		BoxPtr pHotBox;
239735c4bbdfSmrg		BoxPtr pTopLeftBox;	/* return value */
239835c4bbdfSmrg
239935c4bbdfSmrg</programlisting></blockquote>
240035c4bbdfSmrgCursorLimits should calculate the box that the cursor hot spot is
240135c4bbdfSmrgphysically capable of moving within, as a function of the screen pScr,
240235c4bbdfSmrgthe device-independent cursor pCurs, and a box that DIX hypothetically
240335c4bbdfSmrgwould want the hot spot confined within, pHotBox.  This routine is for
240435c4bbdfSmrginforming DIX only; it alters no state within DDX.</para>
240535c4bbdfSmrg<para>
240635c4bbdfSmrg<blockquote><programlisting>
240735c4bbdfSmrg
240835c4bbdfSmrg	Bool pScreen->SetCursorPosition( pScr, newx, newy, generateEvent)
240935c4bbdfSmrg		ScreenPtr pScr;
241035c4bbdfSmrg		int newx;
241135c4bbdfSmrg		int newy;
241235c4bbdfSmrg		Bool generateEvent;
241335c4bbdfSmrg
241435c4bbdfSmrg</programlisting></blockquote>
241535c4bbdfSmrgSetCursorPosition should artificially move the cursor as though the
241635c4bbdfSmrguser had jerked the pointing device very quickly.  This is called in
241735c4bbdfSmrgresponse to the WarpPointer request from the client, and at other
241835c4bbdfSmrgtimes.  If generateEvent is True, the device should decide whether or
241935c4bbdfSmrgnot to call ProcessInputEvents() and then it must call
242035c4bbdfSmrgDevicePtr->processInputProc.  Its effects are, of course, limited in
242135c4bbdfSmrgvalue for absolute pointing devices such as a tablet.</para>
242235c4bbdfSmrg<para>
242335c4bbdfSmrg<blockquote><programlisting>
242435c4bbdfSmrg
242535c4bbdfSmrg	void NewCurrentScreen(newScreen, x, y)
242635c4bbdfSmrg	    ScreenPtr newScreen;
242735c4bbdfSmrg	    int x,y;
242835c4bbdfSmrg
242935c4bbdfSmrg</programlisting></blockquote>
243035c4bbdfSmrgIf your ddx provides some mechanism for the user to magically move the
243135c4bbdfSmrgpointer between multiple screens, you need to inform DIX when this
243235c4bbdfSmrgoccurs.  You should call NewCurrentScreen to accomplish this, specifying
243335c4bbdfSmrgthe new screen and the new x and y coordinates of the pointer on that screen.</para>
243435c4bbdfSmrg</section>
243535c4bbdfSmrg<section>
243635c4bbdfSmrg  <title>Visuals, Depths and Pixmap Formats for Screens</title>
243735c4bbdfSmrg<para>
243835c4bbdfSmrgThe "depth" of a image is the number of bits that are used per pixel to display it.</para>
243935c4bbdfSmrg<para>
244035c4bbdfSmrgThe "bits per pixel" of a pixmap image that is sent over the client
244135c4bbdfSmrgbyte stream is a number that is either 4, 8, 16, 24 or 32.  It is the
244235c4bbdfSmrgnumber of bits used per pixel in Z format.  For instance, a pixmap
244335c4bbdfSmrgimage that has a depth of six is best sent in Z format as 8 bits per
244435c4bbdfSmrgpixel.</para>
244535c4bbdfSmrg<para>
244635c4bbdfSmrgA "pixmap image format" or a "pixmap format" is a description of the
244735c4bbdfSmrgformat of a pixmap image as it is sent over the byte stream.  For each
244835c4bbdfSmrgdepth available on a server, there is one and only one pixmap format.
244935c4bbdfSmrgThis pixmap image format gives the bits per pixel and the scanline
245035c4bbdfSmrgpadding unit. (For instance, are pixel rows padded to bytes, 16-bit
245135c4bbdfSmrgwords, or 32-bit words?)</para>
245235c4bbdfSmrg<para>
245335c4bbdfSmrgFor each screen, you must decide upon what depth(s) it supports.  You
245435c4bbdfSmrgshould only count the number of bits used for the actual image.  Some
245535c4bbdfSmrgdisplays store additional bits to indicate what window this pixel is
245635c4bbdfSmrgin, how close this object is to a viewer, transparency, and other
245735c4bbdfSmrgdata; do not count these bits.</para>
245835c4bbdfSmrg<para>
245935c4bbdfSmrgA "display class" tells whether the display is monochrome or color,
246035c4bbdfSmrgwhether there is a lookup table, and how the lookup table works.</para>
246135c4bbdfSmrg<para>
246235c4bbdfSmrgA "visual" is a combination of depth, display class, and a description
246335c4bbdfSmrgof how the pixel values result in a color on the screen.  Each visual
246435c4bbdfSmrghas a set of masks and offsets that are used to separate a pixel value
246535c4bbdfSmrginto its red, green, and blue components and a count of the number of
246635c4bbdfSmrgcolormap entries.  Some of these fields are only meaningful when the
246735c4bbdfSmrgclass dictates so.  Each visual also has a screen ID telling which
246835c4bbdfSmrgscreen it is usable on.  Note that the depth does not imply the number
246935c4bbdfSmrgof map_entries; for instance, a display can have 8 bits per pixel but
247035c4bbdfSmrgonly 254 colormap entries for use by applications (the other two being
247135c4bbdfSmrgreserved by hardware for the cursor).</para>
247235c4bbdfSmrg<para>
247335c4bbdfSmrgEach visual is identified by a 32-bit visual ID which the client uses
247435c4bbdfSmrgto choose what visual is desired on a given window.  Clients can be
247535c4bbdfSmrgusing more than one visual on the same screen at the same time.</para>
247635c4bbdfSmrg<para>
247735c4bbdfSmrgThe class of a display describes how this translation takes place.
247835c4bbdfSmrgThere are three ways to do the translation.
247935c4bbdfSmrg<itemizedlist>
248035c4bbdfSmrg<listitem><para>
248135c4bbdfSmrgPseudo - The pixel value, as a whole, is looked up
248235c4bbdfSmrgin a table of length map_entries to
248335c4bbdfSmrgdetermine the color to display.</para></listitem>
248435c4bbdfSmrg<listitem><para>
248535c4bbdfSmrgTrue - The
248635c4bbdfSmrgpixel value is broken up into red, green, and blue fields, each of which
248735c4bbdfSmrgare looked up in separate red, green, and blue lookup tables,
248835c4bbdfSmrgeach of length map_entries.</para></listitem>
248935c4bbdfSmrg<listitem><para>
249035c4bbdfSmrgGray - The pixel value is looked up in a table of length map_entries to
249135c4bbdfSmrgdetermine a gray level to display.</para></listitem>
249235c4bbdfSmrg</itemizedlist>
249335c4bbdfSmrg</para>
249435c4bbdfSmrg<para>
249535c4bbdfSmrgIn addition, the lookup table can be static (resulting colors are fixed for each
249635c4bbdfSmrgpixel value)
249735c4bbdfSmrgor dynamic (lookup entries are under control of the client program).
249835c4bbdfSmrgThis leads to a total of six classes:
249935c4bbdfSmrg<itemizedlist>
250035c4bbdfSmrg<listitem><para>
250135c4bbdfSmrgStatic Gray - The pixel value (of however many bits) determines directly the
250235c4bbdfSmrglevel of gray
250335c4bbdfSmrgthat the pixel assumes.</para></listitem>
250435c4bbdfSmrg<listitem><para>
250535c4bbdfSmrgGray Scale - The pixel value is fed through a lookup table to arrive at the level
250635c4bbdfSmrgof gray to display
250735c4bbdfSmrgfor the given pixel.</para></listitem>
250835c4bbdfSmrg<listitem><para>
250935c4bbdfSmrgStatic Color - The pixel value is fed through a fixed lookup table that yields the
251035c4bbdfSmrgcolor to display
251135c4bbdfSmrgfor that pixel.</para></listitem>
251235c4bbdfSmrg<listitem><para>
251335c4bbdfSmrgPseudoColor - The whole pixel value is fed through a programmable lookup
251435c4bbdfSmrgtable that has one
251535c4bbdfSmrgcolor (including red, green, and blue intensities) for each possible pixel value,
251635c4bbdfSmrgand that color is displayed.</para></listitem>
251735c4bbdfSmrg<listitem><para>
251835c4bbdfSmrgTrue Color - Each pixel value consists of one or more bits
251935c4bbdfSmrgthat directly determine each primary color intensity after being fed through
252035c4bbdfSmrga fixed table.</para></listitem>
252135c4bbdfSmrg<listitem><para>
252235c4bbdfSmrgDirect Color - Each pixel value consists of one or more bits for each primary color.
252335c4bbdfSmrgEach primary color value is individually looked up in a table for that primary
252435c4bbdfSmrgcolor, yielding
252535c4bbdfSmrgan intensity for that primary color.
252635c4bbdfSmrgFor each pixel, the red value is looked up in the
252735c4bbdfSmrgred table, the green value in the green table, and
252835c4bbdfSmrgthe blue value in the blue table.</para></listitem>
252935c4bbdfSmrg</itemizedlist>
253035c4bbdfSmrg</para>
253135c4bbdfSmrg<para>
253235c4bbdfSmrgHere are some examples:
253335c4bbdfSmrg<itemizedlist>
253435c4bbdfSmrg<listitem><para>
253535c4bbdfSmrgA simple monochrome 1 bit per pixel display is Static Gray.</para></listitem>
253635c4bbdfSmrg<listitem><para>
253735c4bbdfSmrgA display that has 2 bits per pixel for a choice
253835c4bbdfSmrgbetween the colors of black, white, green and violet is Static Color.</para></listitem>
253935c4bbdfSmrg<listitem><para>
254035c4bbdfSmrgA display that has three bits per pixel, where
254135c4bbdfSmrgeach bit turns on or off one of the red, green or
254235c4bbdfSmrgblue guns, is in the True Color class.</para></listitem>
254335c4bbdfSmrg<listitem><para>
254435c4bbdfSmrgIf you take the last example and scramble the
254535c4bbdfSmrgcorrespondence between pixel values and colors
254635c4bbdfSmrgit becomes a Static Color display.</para></listitem>
254735c4bbdfSmrg</itemizedlist></para>
254835c4bbdfSmrg<para>
254935c4bbdfSmrgA display has 8 bits per pixel.  The 8 bits select one entry out of 256 entries
255035c4bbdfSmrgin a lookup table, each entry consisting of 24 bits (8bits each for red, green,
255135c4bbdfSmrgand blue).
255235c4bbdfSmrgThe display can show any 256 of 16 million colors on the screen at once.
255335c4bbdfSmrgThis is a pseudocolor display.
255435c4bbdfSmrgThe client application gets to fill the lookup table in this class of display.</para>
255535c4bbdfSmrg<para>
255635c4bbdfSmrgImagine the same hardware from the last example.
255735c4bbdfSmrgYour server software allows the user, on the
255835c4bbdfSmrgcommand line that starts up the server
255935c4bbdfSmrgprogram,
256035c4bbdfSmrgto fill the lookup table to his liking once and for all.
256135c4bbdfSmrgFrom then on, the server software would not change the lookup table
256235c4bbdfSmrguntil it exits.
256335c4bbdfSmrgFor instance, the default might be a lookup table with a reasonable sample of
256435c4bbdfSmrgcolors from throughout the color space.
256535c4bbdfSmrgBut the user could specify that the table be filled with 256 steps of gray scale
256635c4bbdfSmrgbecause he knew ahead of time he would be manipulating a lot of black-and-white
256735c4bbdfSmrgscanned photographs
256835c4bbdfSmrgand not very many color things.
256935c4bbdfSmrgClients would be presented with this unchangeable lookup table.
257035c4bbdfSmrgAlthough the hardware qualifies as a PseudoColor display,
257135c4bbdfSmrgthe facade presented to the X client is that this is a Static Color display.</para>
257235c4bbdfSmrg<para>
257335c4bbdfSmrgYou have to decide what kind of display you have or want
257435c4bbdfSmrgto pretend you have.
257535c4bbdfSmrgWhen you initialize the screen(s), this class value must be set in the
257635c4bbdfSmrgVisualRec data structure along with other display characteristics like the
257735c4bbdfSmrgdepth and other numbers.</para>
257835c4bbdfSmrg<para>
257935c4bbdfSmrgThe allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec.
258035c4bbdfSmrgThese are set up when InitOutput() is called; you should malloc() appropriate blocks
258135c4bbdfSmrgor use static variables initialized to the correct values.</para>
258235c4bbdfSmrg</section>
258335c4bbdfSmrg<section>
258435c4bbdfSmrg<title>Colormaps for Screens</title>
258535c4bbdfSmrg<para>
258635c4bbdfSmrgA colormap is a device-independent
258735c4bbdfSmrgmapping between pixel values and colors displayed on the screen.</para>
258835c4bbdfSmrg<para>
258935c4bbdfSmrgDifferent windows on the same screen can have different
259035c4bbdfSmrgcolormaps at the same time.
259135c4bbdfSmrgAt any given time, the most recently installed
259235c4bbdfSmrgcolormap(s) will be in use in the server
259335c4bbdfSmrgso that its (their) windows' colors will be guaranteed to be correct.
259435c4bbdfSmrgOther windows may be off-color.
259535c4bbdfSmrgAlthough this may seem to be chaotic, in practice most clients
259635c4bbdfSmrguse the default colormap for the screen.</para>
259735c4bbdfSmrg<para>
259835c4bbdfSmrgThe default colormap for a screen is initialized when the screen is initialized.
259935c4bbdfSmrgIt always remains in existence and is not owned by any regular client.  It
260035c4bbdfSmrgis owned by client 0 (the server itself).
260135c4bbdfSmrgMany clients will simply use this default colormap for their drawing.
260235c4bbdfSmrgDepending upon the class of the screen, the entries in this colormap may
260335c4bbdfSmrgbe modifiable by client applications.</para>
260435c4bbdfSmrg</section>
260535c4bbdfSmrg<section>
260635c4bbdfSmrg  <title>Colormap Routines</title>
260735c4bbdfSmrg<para>
260835c4bbdfSmrgYou need to implement the following routines to handle the device-dependent
260935c4bbdfSmrgaspects of color maps.  You will end up placing pointers to these procedures
261035c4bbdfSmrgin your ScreenRec data structure(s).  The sample server implementations of
261135c4bbdfSmrgmany of these routines are in fbcmap.c.</para>
261235c4bbdfSmrg<para>
261335c4bbdfSmrg<blockquote><programlisting>
261435c4bbdfSmrg
261535c4bbdfSmrg	Bool pScreen->CreateColormap(pColormap)
261635c4bbdfSmrg		ColormapPtr pColormap;
261735c4bbdfSmrg
261835c4bbdfSmrg</programlisting></blockquote>
261935c4bbdfSmrgThis routine is called by the DIX CreateColormap routine after it has allocated
262035c4bbdfSmrgall the data for the new colormap and just before it returns to the dispatcher.
262135c4bbdfSmrgIt is the DDX layer's chance to initialize the colormap, particularly if it is
262235c4bbdfSmrga static map.  See the following
262335c4bbdfSmrgsection for more details on initializing colormaps.
262435c4bbdfSmrgThe routine returns FALSE if creation failed, such as due to memory
262535c4bbdfSmrglimitations.
262635c4bbdfSmrgNotice that the colormap has a devPriv field from which you can hang any
262735c4bbdfSmrgcolormap specific storage you need.  Since each colormap might need special
262835c4bbdfSmrginformation, we attached the field to the colormap and not the visual.</para>
262935c4bbdfSmrg<para>
263035c4bbdfSmrg<blockquote><programlisting>
263135c4bbdfSmrg
263235c4bbdfSmrg	void pScreen->DestroyColormap(pColormap)
263335c4bbdfSmrg		ColormapPtr pColormap;
263435c4bbdfSmrg
263535c4bbdfSmrg</programlisting></blockquote>
263635c4bbdfSmrgThis routine is called by the DIX FreeColormap routine after it has uninstalled
263735c4bbdfSmrgthe colormap and notified all interested parties, and before it has freed
263835c4bbdfSmrgany of the colormap storage.
263935c4bbdfSmrgIt is the DDX layer's chance to free any data it added to the colormap.</para>
264035c4bbdfSmrg<para>
264135c4bbdfSmrg<blockquote><programlisting>
264235c4bbdfSmrg
264335c4bbdfSmrg	void pScreen->InstallColormap(pColormap)
264435c4bbdfSmrg		ColormapPtr pColormap;
264535c4bbdfSmrg
264635c4bbdfSmrg</programlisting></blockquote>
264735c4bbdfSmrgInstallColormap should
264835c4bbdfSmrgfill a lookup table on the screen with which the colormap is associated with
264935c4bbdfSmrgthe colors in pColormap.
265035c4bbdfSmrgIf there is only one hardware lookup table for the screen, then all colors on
265135c4bbdfSmrgthe screen may change simultaneously.</para>
265235c4bbdfSmrg<para>
265335c4bbdfSmrgIn the more general case of multiple hardware lookup tables,
265435c4bbdfSmrgthis may cause some other colormap to be
265535c4bbdfSmrguninstalled, meaning that windows that subscribed to the colormap
265635c4bbdfSmrgthat was uninstalled may end up being off-color.
265735c4bbdfSmrgSee the note, below, about uninstalling maps.</para>
265835c4bbdfSmrg<para>
265935c4bbdfSmrg<blockquote><programlisting>
266035c4bbdfSmrg
266135c4bbdfSmrg	void pScreen->UninstallColormap(pColormap)
266235c4bbdfSmrg		ColormapPtr pColormap;
266335c4bbdfSmrg
266435c4bbdfSmrg</programlisting></blockquote>
266535c4bbdfSmrgUninstallColormap should
266635c4bbdfSmrgremove pColormap from screen pColormap->pScreen.
266735c4bbdfSmrgSome other map, such as the default map if possible,
266835c4bbdfSmrgshould be installed in place of pColormap if applicable.
266935c4bbdfSmrgIf
267035c4bbdfSmrgpColormap is the default map, do nothing.
267135c4bbdfSmrgIf any client has requested ColormapNotify events, the DDX layer must notify the client.
267235c4bbdfSmrg(The routine WalkTree() is
267335c4bbdfSmrgbe used to find such windows.  The DIX routines TellNoMap(),
267435c4bbdfSmrgTellNewMap()  and TellGainedMap() are provided to be used as
267535c4bbdfSmrgthe procedure parameter to WalkTree.  These procedures are in
267635c4bbdfSmrgXserver/dix/colormap.c.)</para>
267735c4bbdfSmrg<para>
267835c4bbdfSmrg<blockquote><programlisting>
267935c4bbdfSmrg
268035c4bbdfSmrg	int pScreen->ListInstalledColormaps(pScreen, pCmapList)
268135c4bbdfSmrg		ScreenPtr pScreen;
268235c4bbdfSmrg		XID *pCmapList;
268335c4bbdfSmrg
268435c4bbdfSmrg
268535c4bbdfSmrg</programlisting></blockquote>
268635c4bbdfSmrgListInstalledColormaps fills the pCmapList in with the resource ids
268735c4bbdfSmrgof the installed maps and returns a count of installed maps.
268835c4bbdfSmrgpCmapList will point to an array of size MaxInstalledMaps that was allocated
268935c4bbdfSmrgby the caller.</para>
269035c4bbdfSmrg<para>
269135c4bbdfSmrg<blockquote><programlisting>
269235c4bbdfSmrg
269335c4bbdfSmrg	void pScreen->StoreColors (pmap, ndef, pdefs)
269435c4bbdfSmrg		ColormapPtr pmap;
269535c4bbdfSmrg		int ndef;
269635c4bbdfSmrg		xColorItem *pdefs;
269735c4bbdfSmrg
269835c4bbdfSmrg</programlisting></blockquote>
269935c4bbdfSmrgStoreColors changes some of the entries in the colormap pmap.
270035c4bbdfSmrgThe number of entries to change are ndef, and pdefs points to the information
270135c4bbdfSmrgdescribing what to change.
270235c4bbdfSmrgNote that partial changes of entries in the colormap are allowed.
270335c4bbdfSmrgOnly the colors
270435c4bbdfSmrgindicated in the flags field of each xColorItem need to be changed.
270535c4bbdfSmrgHowever, all three color fields will be sent with the proper value for the
270635c4bbdfSmrgbenefit of screens that may not be able to set part of a colormap value.
270735c4bbdfSmrgIf the screen is a static class, this routine does nothing.
270835c4bbdfSmrgThe structure of colormap entries is nontrivial; see colormapst.h
270935c4bbdfSmrgand the definition of xColorItem in Xproto.h for
271035c4bbdfSmrgmore details.</para>
271135c4bbdfSmrg<para>
271235c4bbdfSmrg<blockquote><programlisting>
271335c4bbdfSmrg
271435c4bbdfSmrg	void pScreen->ResolveColor(pRed, pGreen, pBlue, pVisual)
271535c4bbdfSmrg		unsigned short *pRed, *pGreen, *pBlue;
271635c4bbdfSmrg		VisualPtr pVisual;
271735c4bbdfSmrg
271835c4bbdfSmrg
271935c4bbdfSmrg</programlisting></blockquote>
272035c4bbdfSmrgGiven a requested color, ResolveColor returns the nearest color that this hardware is
272135c4bbdfSmrgcapable of displaying on this visual.
272235c4bbdfSmrgIn other words, this rounds off each value, in place, to the number of bits
272335c4bbdfSmrgper primary color that your screen can use.
272435c4bbdfSmrgRemember that each screen has one of these routines.
272535c4bbdfSmrgThe level of roundoff should be what you would expect from the value
272635c4bbdfSmrgyou put in the bits_per_rgb field of the pVisual.</para>
272735c4bbdfSmrg<para>
272835c4bbdfSmrgEach value is an unsigned value ranging from 0 to 65535.
272935c4bbdfSmrgThe bits least likely to be used are the lowest ones.</para>
273035c4bbdfSmrg<para>
273135c4bbdfSmrgFor example, if you had a pseudocolor display
273235c4bbdfSmrgwith any number of bits per pixel
273335c4bbdfSmrgthat had a lookup table supplying 6 bits for each color gun
273435c4bbdfSmrg(a total of 256K different colors), you would
273535c4bbdfSmrground off each value to 6 bits.  Please don't simply truncate these values
273635c4bbdfSmrgto the upper 6 bits, scale the result so that the maximum value seen
273735c4bbdfSmrgby the client will be 65535 for each primary.  This makes color values
273835c4bbdfSmrgmore portable between different depth displays (a 6-bit truncated white
273935c4bbdfSmrgwill not look white on an 8-bit display).</para>
274035c4bbdfSmrg<section>
274135c4bbdfSmrg<title>Initializing a Colormap</title>
274235c4bbdfSmrg<para>
274335c4bbdfSmrgWhen a client requests a new colormap and when the server creates the default
274435c4bbdfSmrgcolormap, the procedure CreateColormap in the DIX layer is invoked.
274535c4bbdfSmrgThat procedure allocates memory for the colormap and related storage such as
274635c4bbdfSmrgthe lists of which client owns which pixels.
274735c4bbdfSmrgIt then sets a bit, BeingCreated, in the flags field of the ColormapRec
274835c4bbdfSmrgand calls the DDX layer's CreateColormap routine.
274935c4bbdfSmrgThis is your chance to initialize the colormap.
275035c4bbdfSmrgIf the colormap is static, which you can tell by looking at the class field,
275135c4bbdfSmrgyou will want to fill in each color cell to match the hardwares notion of the
275235c4bbdfSmrgcolor for that pixel.
275335c4bbdfSmrgIf the colormap is the default for the screen, which you can tell by looking
275435c4bbdfSmrgat the IsDefault bit in the flags field, you should allocate BlackPixel
275535c4bbdfSmrgand WhitePixel to match the values you set in the pScreen structure.
275635c4bbdfSmrg(Of course, you picked those values to begin with.)</para>
275735c4bbdfSmrg<para>
275835c4bbdfSmrgYou can also wait and use AllocColor() to allocate blackPixel
275935c4bbdfSmrgand whitePixel after the default colormap has been created.
276035c4bbdfSmrgIf the default colormap is static and you initialized it in
276135c4bbdfSmrgpScreen->CreateColormap, then use can use AllocColor afterwards
276235c4bbdfSmrgto choose pixel values with the closest rgb values to those
276335c4bbdfSmrgdesired for blackPixel and whitePixel.
276435c4bbdfSmrgIf the default colormap is dynamic and uninitialized, then
276535c4bbdfSmrgthe rgb values you request will be obeyed, and AllocColor will
276635c4bbdfSmrgagain choose pixel values for you.
276735c4bbdfSmrgThese pixel values can then be stored into the screen.</para>
276835c4bbdfSmrg<para>
276935c4bbdfSmrgThere are two ways to fill in the colormap.
277035c4bbdfSmrgThe simplest way is to use the DIX function AllocColor.
277135c4bbdfSmrg<blockquote><programlisting>
277235c4bbdfSmrg
277335c4bbdfSmrgint AllocColor (pmap, pred, pgreen, pblue, pPix, client)
277435c4bbdfSmrg    ColormapPtr         pmap;
277535c4bbdfSmrg    unsigned short      *pred, *pgreen, *pblue;
277635c4bbdfSmrg    Pixel               *pPix;
277735c4bbdfSmrg    int                 client;
277835c4bbdfSmrg
277935c4bbdfSmrg</programlisting></blockquote>
278035c4bbdfSmrgThis takes three pointers to 16 bit color values and a pointer to a suggested
278135c4bbdfSmrgpixel value.  The pixel value is either an index into one colormap or a
278235c4bbdfSmrgcombination of three indices depending on the type of pmap.
278335c4bbdfSmrgIf your colormap starts out empty, and you don't deliberately pick the same
278435c4bbdfSmrgvalue twice, you will always get your suggested pixel.
278535c4bbdfSmrgThe truly nervous could check that the value returned in *pPix is the one
278635c4bbdfSmrgAllocColor was called with.
278735c4bbdfSmrgIf you don't care which pixel is used, or would like them sequentially
278835c4bbdfSmrgallocated from entry 0, set *pPix to 0.  This will find the first free
278935c4bbdfSmrgpixel and use that.</para>
279035c4bbdfSmrg<para>
279135c4bbdfSmrgAllocColor will take care of all the  bookkeeping  and  will
279235c4bbdfSmrgcall StoreColors to get the colormap rgb values initialized.
279335c4bbdfSmrgThe hardware colormap will be changed whenever this colormap
279435c4bbdfSmrgis installed.</para>
279535c4bbdfSmrg<para>
279635c4bbdfSmrgIf for some reason AllocColor doesn't do what you want, you can do your
279735c4bbdfSmrgown bookkeeping and call StoreColors yourself.  This is much more difficult
279835c4bbdfSmrgand shouldn't be necessary for most devices.</para>
279935c4bbdfSmrg</section>
280035c4bbdfSmrg</section>
280135c4bbdfSmrg<section>
280235c4bbdfSmrg  <title>Fonts for Screens</title>
280335c4bbdfSmrg<para>
280435c4bbdfSmrgA font is a set of bitmaps that depict the symbols in a character set.
280535c4bbdfSmrgEach font is for only one typeface in a given size, in other words,
280635c4bbdfSmrgjust one bitmap for each character.  Parallel fonts may be available
280735c4bbdfSmrgin a variety of sizes and variations, including "bold" and "italic."
280835c4bbdfSmrgX supports fonts for 8-bit and 16-bit character codes (for oriental
280935c4bbdfSmrglanguages that have more than 256 characters in the font).  Glyphs are
281035c4bbdfSmrgbitmaps for individual characters.</para>
281135c4bbdfSmrg<para>
281235c4bbdfSmrgThe source comes with some useful font files in an ASCII, plain-text
281335c4bbdfSmrgformat that should be comprehensible on a wide variety of operating
281435c4bbdfSmrgsystems.  The text format, referred to as BDF, is a slight extension
281535c4bbdfSmrgof the current Adobe 2.1 Bitmap Distribution Format (Adobe Systems,
281635c4bbdfSmrgInc.).</para>
281735c4bbdfSmrg<para>
281835c4bbdfSmrgA short paper in PostScript format is included with the sample server
281935c4bbdfSmrgthat defines BDF.  It includes helpful pictures, which is why it is
282035c4bbdfSmrgdone in PostScript and is not included in this document.</para>
282135c4bbdfSmrg<para>
282235c4bbdfSmrgYour implementation should include some sort of font compiler to read
282335c4bbdfSmrgthese files and generate binary files that are directly usable by your
282435c4bbdfSmrgserver implementation.  The sample server comes with the source for a
282535c4bbdfSmrgfont compiler.</para>
282635c4bbdfSmrg<para>
282735c4bbdfSmrgIt is important the font properties contained in the BDF files are
282835c4bbdfSmrgpreserved across any font compilation. In particular, copyright
282935c4bbdfSmrginformation cannot be casually tossed aside without legal
283035c4bbdfSmrgramifications. Other properties will be important to some
283135c4bbdfSmrgsophisticated applications.</para>
283235c4bbdfSmrg<para>
283335c4bbdfSmrgAll clients get font information from the server.  Therefore, your
283435c4bbdfSmrgserver can support any fonts it wants to.  It should probably support
283535c4bbdfSmrgat least the fonts supplied with the X11 tape.  In principle, you can
283635c4bbdfSmrgconvert fonts from other sources or dream up your own fonts for use on
283735c4bbdfSmrgyour server.</para>
283835c4bbdfSmrg<section>
283935c4bbdfSmrg<title>Portable Compiled Format</title>
284035c4bbdfSmrg<para>
284135c4bbdfSmrgA font compiler is supplied with the sample server.  It has
284235c4bbdfSmrgcompile-time switches to convert the BDF files into a portable binary
284335c4bbdfSmrgform, called Portable Compiled Format or PCF.  This allows for an
284435c4bbdfSmrgarbitrary data format inside the file, and by describing the details
284535c4bbdfSmrgof the format in the header of the file, any PCF file can be read by
284635c4bbdfSmrgany PCF reading client.  By selecting the format which matches the
284735c4bbdfSmrgrequired internal format for your renderer, the PCF reader can avoid
284835c4bbdfSmrgreformatting the data each time it is read in.  The font compiler
284935c4bbdfSmrgshould be quite portable.</para>
285035c4bbdfSmrg<para>
285135c4bbdfSmrgThe fonts included with the tape are stored in fonts/bdf.  The
285235c4bbdfSmrgfont compiler is found in fonts/tools/bdftopcf.</para>
285335c4bbdfSmrg</section>
285435c4bbdfSmrg<section>
285535c4bbdfSmrg  <title>Font Realization</title>
285635c4bbdfSmrg<para>
285735c4bbdfSmrgEach screen configured into the server
285835c4bbdfSmrghas an opportunity at font-load time
285935c4bbdfSmrgto "realize" a font into some internal format if necessary.
286035c4bbdfSmrgThis happens every time the font is loaded into memory.</para>
286135c4bbdfSmrg<para>
286235c4bbdfSmrgA font (FontRec in Xserver/include/dixfontstr.h) is
286335c4bbdfSmrga device-independent structure containing a device-independent
286435c4bbdfSmrgrepresentation of the font.  When a font is created, it is "realized"
286535c4bbdfSmrgfor each screen.  At this point, the screen has the chance to convert
286635c4bbdfSmrgthe font into some other format.  The DDX layer can also put information
286735c4bbdfSmrgin the devPrivate storage.</para>
286835c4bbdfSmrg<para>
286935c4bbdfSmrg<blockquote><programlisting>
287035c4bbdfSmrg
287135c4bbdfSmrg	Bool pScreen->RealizeFont(pScr, pFont)
287235c4bbdfSmrg		ScreenPtr pScr;
287335c4bbdfSmrg		FontPtr pFont;
287435c4bbdfSmrg
287535c4bbdfSmrg	Bool pScreen->UnrealizeFont(pScr, pFont)
287635c4bbdfSmrg		ScreenPtr pScr;
287735c4bbdfSmrg		FontPtr pFont;
287835c4bbdfSmrg
287935c4bbdfSmrg</programlisting></blockquote>
288035c4bbdfSmrgRealizeFont and UnrealizeFont should calculate and allocate these extra data structures and
288135c4bbdfSmrgdispose of them when no longer needed.
288235c4bbdfSmrgThese are called in response to OpenFont and CloseFont requests from
288335c4bbdfSmrgthe client.
288435c4bbdfSmrgThe sample server implementation is in fbscreen.c (which does very little).</para>
288535c4bbdfSmrg</section>
288635c4bbdfSmrg</section>
288735c4bbdfSmrg<section>
288835c4bbdfSmrg  <title>Other Screen Routines</title>
288935c4bbdfSmrg<para>
289035c4bbdfSmrgYou must supply several other screen-specific routines for
289135c4bbdfSmrgyour X server implementation.
289235c4bbdfSmrgSome of these are described in other sections:
289335c4bbdfSmrg<itemizedlist>
289435c4bbdfSmrg<listitem><para>
289535c4bbdfSmrgGetImage() is described in the Drawing Primitives section.</para></listitem>
289635c4bbdfSmrg<listitem><para>
289735c4bbdfSmrgGetSpans() is described in the Pixblit routine section.</para></listitem>
289835c4bbdfSmrg<listitem><para>
289935c4bbdfSmrgSeveral window and pixmap manipulation procedures are
290035c4bbdfSmrgdescribed in the Window section under Drawables.</para></listitem>
290135c4bbdfSmrg<listitem><para>
290235c4bbdfSmrgThe CreateGC() routine is described under Graphics Contexts.</para></listitem>
290335c4bbdfSmrg</itemizedlist>
290435c4bbdfSmrg</para>
290535c4bbdfSmrg<para>
290635c4bbdfSmrg<blockquote><programlisting>
290735c4bbdfSmrg
290835c4bbdfSmrg	void pScreen->QueryBestSize(kind, pWidth, pHeight)
290935c4bbdfSmrg		int kind;
291035c4bbdfSmrg		unsigned short *pWidth, *pHeight;
291135c4bbdfSmrg		ScreenPtr pScreen;
291235c4bbdfSmrg
291335c4bbdfSmrg</programlisting></blockquote>
291435c4bbdfSmrgQueryBestSize() returns the best sizes for cursors, tiles, and stipples
291535c4bbdfSmrgin response to client requests.
291635c4bbdfSmrgkind is one of the defined constants CursorShape, TileShape, or StippleShape
291735c4bbdfSmrg(defined in X.h).
291835c4bbdfSmrgFor CursorShape, return the maximum width and
291935c4bbdfSmrgheight for cursors that you can handle.
292035c4bbdfSmrgFor TileShape and StippleShape, start with the suggested values in pWidth
292135c4bbdfSmrgand pHeight and modify them in place to be optimal values that are
292235c4bbdfSmrggreater than or equal to the suggested values.
292335c4bbdfSmrgThe sample server implementation is in Xserver/fb/fbscreen.c.</para>
292435c4bbdfSmrg<para>
292535c4bbdfSmrg<blockquote><programlisting>
292635c4bbdfSmrg
292735c4bbdfSmrg	pScreen->SourceValidate(pDrawable, x, y, width, height)
292835c4bbdfSmrg		DrawablePtr pDrawable;
292935c4bbdfSmrg		int x, y, width, height;
293035c4bbdfSmrg		unsigned int subWindowMode;
293135c4bbdfSmrg
293235c4bbdfSmrg</programlisting></blockquote>
293335c4bbdfSmrgSourceValidate should be called by CopyArea/CopyPlane primitives when
293435c4bbdfSmrgthe SourceValidate function pointer in the screen is non-null.  If you know that
293535c4bbdfSmrgyou will never need SourceValidate, you can avoid this check.  Currently,
293635c4bbdfSmrgSourceValidate is used by the mi software cursor code to remove the cursor
293735c4bbdfSmrgfrom the screen when the source rectangle overlaps the cursor position.
293835c4bbdfSmrgx,y,width,height describe the source rectangle (source relative, that is)
293935c4bbdfSmrgfor the copy operation.  subWindowMode comes from the GC or source Picture.
294035c4bbdfSmrg</para>
294135c4bbdfSmrg<para>
294235c4bbdfSmrg<blockquote><programlisting>
294335c4bbdfSmrg
294435c4bbdfSmrg	Bool pScreen->SaveScreen(pScreen, on)
294535c4bbdfSmrg		ScreenPtr pScreen;
294635c4bbdfSmrg		int on;
294735c4bbdfSmrg
294835c4bbdfSmrg</programlisting></blockquote>
294935c4bbdfSmrgSaveScreen() is used for Screen Saver support (see WaitForSomething()).
295035c4bbdfSmrgpScreen is the screen to save.</para>
295135c4bbdfSmrg<para>
295235c4bbdfSmrg<blockquote><programlisting>
295335c4bbdfSmrg
295435c4bbdfSmrg	Bool pScreen->CloseScreen(pScreen)
295535c4bbdfSmrg	    ScreenPtr pScreen;
295635c4bbdfSmrg
295735c4bbdfSmrg</programlisting></blockquote>
295835c4bbdfSmrgWhen the server is reset, it calls this routine for each screen.</para>
295935c4bbdfSmrg<para>
296035c4bbdfSmrg<blockquote><programlisting>
296135c4bbdfSmrg
296235c4bbdfSmrg	Bool pScreen->CreateScreenResources(pScreen)
296335c4bbdfSmrg	    ScreenPtr pScreen;
296435c4bbdfSmrg
296535c4bbdfSmrg</programlisting></blockquote>
296635c4bbdfSmrgIf this routine is not NULL, it will be called once per screen per
296735c4bbdfSmrgserver initialization/reset after all modules have had a chance to
296835c4bbdfSmrgrequest private space on all structures that support them (see
296935c4bbdfSmrg<xref linkend="wrappers_and_privates"/> below).  You may create resources
297035c4bbdfSmrgin this function instead of in the
297135c4bbdfSmrgscreen init function passed to AddScreen in order to guarantee that
297235c4bbdfSmrgall pre-allocated space requests have been registered first.  With the
297335c4bbdfSmrgnew devPrivates mechanism, this is not strictly necessary, however.
297435c4bbdfSmrgThis routine returns TRUE if successful.</para>
297535c4bbdfSmrg</section>
297635c4bbdfSmrg</section>
297735c4bbdfSmrg<section>
297835c4bbdfSmrg<title>Drawables</title>
297935c4bbdfSmrg<para>
298035c4bbdfSmrgA drawable is a descriptor of a surface that graphics are drawn into, either
298135c4bbdfSmrga window on the screen or a pixmap in memory.</para>
298235c4bbdfSmrg<para>
298335c4bbdfSmrgEach drawable has a type, class,
298435c4bbdfSmrgScreenPtr for the screen it is associated with, depth, position, size,
298535c4bbdfSmrgand serial number.
298635c4bbdfSmrgThe type is one of the defined constants DRAWABLE_PIXMAP,
298735c4bbdfSmrgDRAWABLE_WINDOW and UNDRAWABLE_WINDOW.
298835c4bbdfSmrg(An undrawable window is used for window class InputOnly.)
298935c4bbdfSmrgThe serial number is guaranteed to be unique across drawables, and
299035c4bbdfSmrgis used in determining
299135c4bbdfSmrgthe validity of the clipping information in a GC.
299235c4bbdfSmrgThe screen selects the set of procedures used to manipulate and draw into the
299335c4bbdfSmrgdrawable.  Position is used (currently) only by windows; pixmaps must
299435c4bbdfSmrgset these fields to 0,0 as this reduces the amount of conditional code
299535c4bbdfSmrgexecuted throughout the mi code.  Size indicates the actual client-specified
299635c4bbdfSmrgsize of the drawable.
299735c4bbdfSmrgThere are, in fact, no other fields that a window drawable and pixmap
299835c4bbdfSmrgdrawable have in common besides those mentioned here.</para>
299935c4bbdfSmrg<para>
300035c4bbdfSmrgBoth PixmapRecs and WindowRecs are structs that start with a drawable
300135c4bbdfSmrgand continue on with more fields.  Pixmaps have a single pointer field
300235c4bbdfSmrgnamed devPrivate which usually points to the pixmap data but could conceivably be
300335c4bbdfSmrgused for anything that DDX wants.  Both windows and pixmaps also have a
300435c4bbdfSmrgdevPrivates field which can be used for DDX specific data (see <xref linkend="wrappers_and_privates"/>
300535c4bbdfSmrgbelow).  This is done because different graphics hardware has
300635c4bbdfSmrgdifferent requirements for management; if the graphics is always
300735c4bbdfSmrghandled by a processor with an independent address space, there is no
300835c4bbdfSmrgpoint having a pointer to the bit image itself.</para>
300935c4bbdfSmrg<para>
301035c4bbdfSmrgThe definition of a drawable and a pixmap can be found in the file
301135c4bbdfSmrgXserver/include/pixmapstr.h.
301235c4bbdfSmrgThe definition of a window can be found in the file Xserver/include/windowstr.h.</para>
301335c4bbdfSmrg<section>
301435c4bbdfSmrg  <title>Pixmaps</title>
301535c4bbdfSmrg<para>
301635c4bbdfSmrgA pixmap is a three-dimensional array of bits stored somewhere offscreen,
301735c4bbdfSmrgrather than in the visible portion of the screen's display frame buffer.  It
301835c4bbdfSmrgcan be used as a source or destination in graphics operations.  There is no
301935c4bbdfSmrgimplied interpretation of the pixel values in a pixmap, because it has no
302035c4bbdfSmrgassociated visual or colormap.  There is only a depth that indicates the
302135c4bbdfSmrgnumber of significant bits per pixel.  Also, there is no implied physical
302235c4bbdfSmrgsize for each pixel; all graphic units are in numbers of pixels.  Therefore,
302335c4bbdfSmrga pixmap alone does not constitute a complete image; it represents only a
302435c4bbdfSmrgrectangular array of pixel values.</para>
302535c4bbdfSmrg<para>
302635c4bbdfSmrgNote that the pixmap data structure is reference-counted.</para>
302735c4bbdfSmrg<para>
302835c4bbdfSmrgThe server implementation is free to put the pixmap data
302935c4bbdfSmrganywhere it sees fit, according to its graphics hardware setup.  Many
303035c4bbdfSmrgimplementations will simply have the data dynamically allocated in the
303135c4bbdfSmrgserver's address space.  More sophisticated implementations may put the
303235c4bbdfSmrgdata in undisplayed framebuffer storage.</para>
303335c4bbdfSmrg<para>
303435c4bbdfSmrgIn addition to dynamic devPrivates (see <xref linkend="wrappers_and_privates"/>
303535c4bbdfSmrgbelow), the pixmap data structure has two fields that are private to
303635c4bbdfSmrgthe device.  Although you can use them for anything you want, they
303735c4bbdfSmrghave intended purposes.  devKind is intended to be a device specific
303835c4bbdfSmrgindication of the pixmap location (host memory, off-screen, etc.).  In
303935c4bbdfSmrgthe sample server, since all pixmaps are in memory, devKind stores the
304035c4bbdfSmrgwidth of the pixmap in bitmap scanline units.  devPrivate is usually
304135c4bbdfSmrga pointer to the bits in the pixmap.</para>
304235c4bbdfSmrg<para>
304335c4bbdfSmrgA bitmap is a pixmap that is one bit deep.</para>
304435c4bbdfSmrg<para>
304535c4bbdfSmrg<blockquote><programlisting>
304635c4bbdfSmrg
304735c4bbdfSmrg	PixmapPtr pScreen->CreatePixmap(pScreen, width, height, depth)
304835c4bbdfSmrg		ScreenPtr pScreen;
304935c4bbdfSmrg		int width, height, depth;
305035c4bbdfSmrg
305135c4bbdfSmrg</programlisting></blockquote>
305235c4bbdfSmrgThis ScreenRec procedure must create a pixmap of the size
305335c4bbdfSmrgrequested.
305435c4bbdfSmrgIt must allocate a PixmapRec and fill in all of the fields.
305535c4bbdfSmrgThe reference count field must be set to 1.
305635c4bbdfSmrgIf width or height are zero, no space should be allocated
305735c4bbdfSmrgfor the pixmap data, and if the implementation is using the
305835c4bbdfSmrgdevPrivate field as a pointer to the pixmap data, it should be
305935c4bbdfSmrgset to NULL.
306035c4bbdfSmrgIf successful, it returns a pointer to the new pixmap; if not, it returns NULL.
306135c4bbdfSmrgSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
306235c4bbdfSmrg<para>
306335c4bbdfSmrg<blockquote><programlisting>
306435c4bbdfSmrg
306535c4bbdfSmrg	Bool pScreen->DestroyPixmap(pPixmap)
306635c4bbdfSmrg		PixmapPtr pPixmap;
306735c4bbdfSmrg
306835c4bbdfSmrg</programlisting></blockquote>
306935c4bbdfSmrgThis ScreenRec procedure must "destroy" a pixmap.
307035c4bbdfSmrgIt should decrement the reference count and, if zero, it
307135c4bbdfSmrgmust deallocate the PixmapRec and all attached devPrivate blocks.
307235c4bbdfSmrgIf successful, it returns TRUE.
307335c4bbdfSmrgSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
307435c4bbdfSmrg<para>
307535c4bbdfSmrg<blockquote><programlisting>
307635c4bbdfSmrg
307735c4bbdfSmrg	Bool
307835c4bbdfSmrg	pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData)
307935c4bbdfSmrg		PixmapPtr   pPixmap;
308035c4bbdfSmrg		int	    width;
308135c4bbdfSmrg		int	    height;
308235c4bbdfSmrg		int	    depth;
308335c4bbdfSmrg		int	    bitsPerPixel;
308435c4bbdfSmrg		int	    devKind;
308535c4bbdfSmrg		pointer     pPixData;
308635c4bbdfSmrg
308735c4bbdfSmrg</programlisting></blockquote>
308835c4bbdfSmrgThis routine takes a pixmap header and initializes the fields of the PixmapRec to the
308935c4bbdfSmrgparameters of the same name.  pPixmap must have been created via
309035c4bbdfSmrgpScreen->CreatePixmap with a zero width or height to avoid
309135c4bbdfSmrgallocating space for the pixmap data.  pPixData is assumed to be the
309235c4bbdfSmrgpixmap data; it will be stored in an implementation-dependent place
309335c4bbdfSmrg(usually pPixmap->devPrivate.ptr).  This routine returns
309435c4bbdfSmrgTRUE if successful.  See Xserver/mi/miscrinit.c for the sample
309535c4bbdfSmrgserver implementation.</para>
309635c4bbdfSmrg<para>
309735c4bbdfSmrg<blockquote><programlisting>
309835c4bbdfSmrg
309935c4bbdfSmrg	PixmapPtr
310035c4bbdfSmrg	GetScratchPixmapHeader(pScreen, width, height, depth, bitsPerPixel, devKind, pPixData)
310135c4bbdfSmrg		ScreenPtr   pScreen;
310235c4bbdfSmrg		int	    width;
310335c4bbdfSmrg		int	    height;
310435c4bbdfSmrg		int	    depth;
310535c4bbdfSmrg		int	    bitsPerPixel;
310635c4bbdfSmrg		int	    devKind;
310735c4bbdfSmrg		pointer     pPixData;
310835c4bbdfSmrg
310935c4bbdfSmrg	void FreeScratchPixmapHeader(pPixmap)
311035c4bbdfSmrg		PixmapPtr pPixmap;
311135c4bbdfSmrg
311235c4bbdfSmrg</programlisting></blockquote>
311335c4bbdfSmrgDDX should use these two DIX routines when it has a buffer of raw
311435c4bbdfSmrgimage data that it wants to manipulate as a pixmap temporarily,
311535c4bbdfSmrgusually so that some other part of the server can be leveraged to
311635c4bbdfSmrgperform some operation on the data.  The data should be passed in
311735c4bbdfSmrgpPixData, and will be stored in an implementation-dependent place
311835c4bbdfSmrg(usually pPixmap->devPrivate.ptr). The other
311935c4bbdfSmrgfields go into the corresponding PixmapRec fields.
312035c4bbdfSmrgIf successful, GetScratchPixmapHeader returns a valid PixmapPtr which can
312135c4bbdfSmrgbe used anywhere the server expects a pixmap, else
312235c4bbdfSmrgit returns NULL.  The pixmap should be released when no longer needed
312335c4bbdfSmrg(usually within the same function that allocated it)
312435c4bbdfSmrgwith FreeScratchPixmapHeader.</para>
312535c4bbdfSmrg</section>
312635c4bbdfSmrg<section>
312735c4bbdfSmrg  <title>Windows</title>
312835c4bbdfSmrg<para>
312935c4bbdfSmrgA window is a visible, or potentially visible, rectangle on the screen.
313035c4bbdfSmrgDIX windowing functions maintain an internal n-ary tree data structure, which
313135c4bbdfSmrgrepresents the current relationships of the mapped windows.
313235c4bbdfSmrgWindows that are contained in another window are children of that window and
313335c4bbdfSmrgare clipped to the boundaries of the parent.
313435c4bbdfSmrgThe root window in the tree is the window for the entire screen.
313535c4bbdfSmrgSibling windows constitute a doubly-linked list; the parent window has a pointer
313635c4bbdfSmrgto the head and tail of this list.
313735c4bbdfSmrgEach child also has a pointer to its parent.</para>
313835c4bbdfSmrg<para>
313935c4bbdfSmrgThe border of a window is drawn by a DDX procedure when DIX requests that it
314035c4bbdfSmrgbe drawn.  The contents of the window is drawn by the client through
314135c4bbdfSmrgrequests to the server.</para>
314235c4bbdfSmrg<para>
314335c4bbdfSmrgWindow painting is orchestrated through an expose event system.
314435c4bbdfSmrgWhen a region is exposed,
314535c4bbdfSmrgDIX generates an expose event, telling the client to repaint the window and
314635c4bbdfSmrgpassing the region that is the minimal area needed to be repainted.</para>
314735c4bbdfSmrg<para>
314835c4bbdfSmrgAs a favor to clients, the server may retain
314935c4bbdfSmrgthe output to the hidden parts of windows
315035c4bbdfSmrgin off-screen memory; this is called "backing store".
315135c4bbdfSmrgWhen a part of such a window becomes exposed, it
315235c4bbdfSmrgcan quickly move pixels into place instead of
315335c4bbdfSmrgtriggering an expose event and waiting for a client on the other
315435c4bbdfSmrgend of the network to respond.
315535c4bbdfSmrgEven if the network response is insignificant, the time to
315635c4bbdfSmrgintelligently paint a section of a window is usually more than
315735c4bbdfSmrgthe time to just copy already-painted sections.
315835c4bbdfSmrgAt best, the repainting involves blanking out the area to a background color,
315935c4bbdfSmrgwhich will take about the
316035c4bbdfSmrgsame amount of time.
316135c4bbdfSmrgIn this way, backing store can dramatically increase the
316235c4bbdfSmrgperformance of window moves.</para>
316335c4bbdfSmrg<para>
316435c4bbdfSmrgOn the other hand, backing store can be quite complex, because
316535c4bbdfSmrgall graphics drawn to hidden areas must be intercepted and redirected
316635c4bbdfSmrgto the off-screen window sections.
316735c4bbdfSmrgNot only can this be complicated for the server programmer,
316835c4bbdfSmrgbut it can also impact window painting performance.
316935c4bbdfSmrgThe backing store implementation can choose, at any time, to
317035c4bbdfSmrgforget pieces of backing that are written into, relying instead upon
317135c4bbdfSmrgexpose events to repaint for simplicity.</para>
317235c4bbdfSmrg<para>
317335c4bbdfSmrgIn X, the decision to use the backing-store scheme is made
317435c4bbdfSmrgby you, the server implementor.  The sample server implements
317535c4bbdfSmrgbacking store "for free" by reusing the infrastructure for the Composite
317635c4bbdfSmrgextension.  As a side effect, it treats the WhenMapped and Always hints
317735c4bbdfSmrgas equivalent.  However, it will never forget pixel contents when the
317835c4bbdfSmrgwindow is mapped.</para>
317935c4bbdfSmrg<para>
318035c4bbdfSmrgWhen a window operation is requested by the client,
318135c4bbdfSmrgsuch as a window being created or moved,
318235c4bbdfSmrga new state is computed.
318335c4bbdfSmrgDuring this transition, DIX informs DDX what rectangles in what windows are about to
318435c4bbdfSmrgbecome obscured and what rectangles in what windows have become exposed.
318535c4bbdfSmrgThis provides a hook for the implementation of backing store.
318635c4bbdfSmrgIf DDX is unable to restore exposed regions, DIX generates expose
318735c4bbdfSmrgevents to the client.
318835c4bbdfSmrgIt is then the client's responsibility to paint the
318935c4bbdfSmrgwindow parts that were exposed but not restored.</para>
319035c4bbdfSmrg<para>
319135c4bbdfSmrgIf a window is resized, pixels sometimes need to be
319235c4bbdfSmrgmoved, depending upon
319335c4bbdfSmrgthe application.
319435c4bbdfSmrgThe client can request "Gravity" so that
319535c4bbdfSmrgcertain blocks of the window are
319635c4bbdfSmrgmoved as a result of a resize.
319735c4bbdfSmrgFor instance, if the window has controls or other items
319835c4bbdfSmrgthat always hang on the edge of the
319935c4bbdfSmrgwindow, and that edge is moved as a result of the resize,
320035c4bbdfSmrgthen those pixels should be moved
320135c4bbdfSmrgto avoid having the client repaint it.
320235c4bbdfSmrgIf the client needs to repaint it anyway, such an operation takes
320335c4bbdfSmrgtime, so it is desirable
320435c4bbdfSmrgfor the server to approximate the appearance of the window as best
320535c4bbdfSmrgit can while waiting for the client
320635c4bbdfSmrgto do it perfectly.
320735c4bbdfSmrgGravity is used for that, also.</para>
320835c4bbdfSmrg<para>
320935c4bbdfSmrgThe window has several fields used in drawing
321035c4bbdfSmrgoperations:
321135c4bbdfSmrg<itemizedlist>
321235c4bbdfSmrg<listitem><para>
321335c4bbdfSmrgclipList - This region, in conjunction with
321435c4bbdfSmrgthe client clip region in the gc, is used to clip output.
321535c4bbdfSmrgclipList has the window's children subtracted from it, in addition to pieces of sibling windows
321635c4bbdfSmrgthat overlap this window.  To get the list with the
321735c4bbdfSmrgchildren included (subwindow-mode is IncludeInferiors),
321835c4bbdfSmrgthe routine NotClippedByChildren(pWin) returns the unclipped region.</para></listitem>
321935c4bbdfSmrg<listitem><para>
322035c4bbdfSmrgborderClip is the region used by CopyWindow and
322135c4bbdfSmrgincludes the area of the window, its children, and the border, but with the
322235c4bbdfSmrgoverlapping areas of sibling children removed.</para></listitem>
322335c4bbdfSmrg</itemizedlist>
322435c4bbdfSmrgMost of the other fields are for DIX use only.</para>
322535c4bbdfSmrg<section>
322635c4bbdfSmrg<title>Window Procedures in the ScreenRec</title>
322735c4bbdfSmrg<para>
322835c4bbdfSmrgYou should implement
322935c4bbdfSmrgall of the following procedures and store pointers to them in the screen record.</para>
323035c4bbdfSmrg<para>
323135c4bbdfSmrgThe device-independent portion of the server "owns" the window tree.
323235c4bbdfSmrgHowever, clever hardware might want to know the relationship of
323335c4bbdfSmrgmapped windows.  There are pointers to procedures
323435c4bbdfSmrgin the ScreenRec data structure that are called to give the hardware
323535c4bbdfSmrga chance to update its internal state.  These are helpers and
323635c4bbdfSmrghints to DDX only;
323735c4bbdfSmrgthey do not change the window tree, which is only changed by DIX.</para>
323835c4bbdfSmrg<para>
323935c4bbdfSmrg<blockquote><programlisting>
324035c4bbdfSmrg
324135c4bbdfSmrg	Bool pScreen->CreateWindow(pWin)
324235c4bbdfSmrg		WindowPtr pWin;
324335c4bbdfSmrg
324435c4bbdfSmrg</programlisting></blockquote>
324535c4bbdfSmrgThis routine is a hook for when DIX creates a window.
324635c4bbdfSmrgIt should fill in the "Window Procedures in the WindowRec" below
324735c4bbdfSmrgand also allocate the devPrivate block for it.</para>
324835c4bbdfSmrg<para>
324935c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
325035c4bbdfSmrg<para>
325135c4bbdfSmrg<blockquote><programlisting>
325235c4bbdfSmrg
325335c4bbdfSmrg	Bool pScreen->DestroyWindow(pWin);
325435c4bbdfSmrg		WindowPtr pWin;
325535c4bbdfSmrg
325635c4bbdfSmrg</programlisting></blockquote>
325735c4bbdfSmrgThis routine is a hook for when DIX destroys a window.
325835c4bbdfSmrgIt should deallocate the devPrivate block for it and any other blocks that need
325935c4bbdfSmrgto be freed, besides doing other cleanup actions.</para>
326035c4bbdfSmrg<para>
326135c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
326235c4bbdfSmrg<para>
326335c4bbdfSmrg<blockquote><programlisting>
326435c4bbdfSmrg
326535c4bbdfSmrg	Bool pScreen->PositionWindow(pWin, x, y);
326635c4bbdfSmrg		WindowPtr pWin;
326735c4bbdfSmrg		int x, y;
326835c4bbdfSmrg
326935c4bbdfSmrg</programlisting></blockquote>
327035c4bbdfSmrgThis routine is a hook for when DIX moves or resizes a window.
327135c4bbdfSmrgIt should do whatever private operations need to be done when a window is moved or resized.
327235c4bbdfSmrgFor instance, if DDX keeps a pixmap tile used for drawing the background
327335c4bbdfSmrgor border, and it keeps the tile rotated such that it is longword
327435c4bbdfSmrgaligned to longword locations in the frame buffer, then you should rotate your tiles here.
327535c4bbdfSmrgThe actual graphics involved in moving the pixels on the screen and drawing the
327635c4bbdfSmrgborder are handled by CopyWindow(), below.</para>
327735c4bbdfSmrg<para>
327835c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
327935c4bbdfSmrg<para>
328035c4bbdfSmrg<blockquote><programlisting>
328135c4bbdfSmrg
328235c4bbdfSmrg	Bool pScreen->RealizeWindow(pWin);
328335c4bbdfSmrg		WindowPtr pWin;
328435c4bbdfSmrg
328535c4bbdfSmrg	Bool  pScreen->UnrealizeWindow(pWin);
328635c4bbdfSmrg		WindowPtr pWin;
328735c4bbdfSmrg
328835c4bbdfSmrg</programlisting></blockquote>
328935c4bbdfSmrgThese routines are hooks for when DIX maps (makes visible) and unmaps
329035c4bbdfSmrg(makes invisible) a window.  It should do whatever private operations
329135c4bbdfSmrgneed to be done when these happen, such as allocating or deallocating
329235c4bbdfSmrgstructures that are only needed for visible windows.  RealizeWindow
329335c4bbdfSmrgdoes NOT draw the window border, background or contents;
329435c4bbdfSmrgUnrealizeWindow does NOT erase the window or generate exposure events
329535c4bbdfSmrgfor underlying windows; this is taken care of by DIX.  DIX does,
329635c4bbdfSmrghowever, call PaintWindowBackground() and PaintWindowBorder() to
329735c4bbdfSmrgperform some of these.</para>
329835c4bbdfSmrg<para>
329935c4bbdfSmrg<blockquote><programlisting>
330035c4bbdfSmrg
330135c4bbdfSmrg	Bool pScreen->ChangeWindowAttributes(pWin, vmask)
330235c4bbdfSmrg		WindowPtr pWin;
330335c4bbdfSmrg		unsigned long vmask;
330435c4bbdfSmrg
330535c4bbdfSmrg</programlisting></blockquote>
330635c4bbdfSmrgChangeWindowAttributes is called whenever DIX changes window
330735c4bbdfSmrgattributes, such as the size, front-to-back ordering, title, or
330835c4bbdfSmrganything of lesser severity that affects the window itself.  The
330935c4bbdfSmrgsample server implements this routine.  It computes accelerators for
331035c4bbdfSmrgquickly putting up background and border tiles.  (See description of
331135c4bbdfSmrgthe set of routines stored in the WindowRec.)</para>
331235c4bbdfSmrg<para>
331335c4bbdfSmrg<blockquote><programlisting>
331435c4bbdfSmrg
331535c4bbdfSmrg	int pScreen->ValidateTree(pParent,  pChild, kind)
331635c4bbdfSmrg		WindowPtr pParent, pChild;
331735c4bbdfSmrg		VTKind kind;
331835c4bbdfSmrg
331935c4bbdfSmrg</programlisting></blockquote>
332035c4bbdfSmrgValidateTree calculates the clipping region for the parent window and
332135c4bbdfSmrgall of its children.  This routine must be provided. The sample server
332235c4bbdfSmrghas a machine-independent version in Xserver/mi/mivaltree.c.  This is
332335c4bbdfSmrga very difficult routine to replace.</para>
332435c4bbdfSmrg<para>
332535c4bbdfSmrg<blockquote><programlisting>
332635c4bbdfSmrg
332735c4bbdfSmrg	void pScreen->PostValidateTree(pParent,  pChild, kind)
332835c4bbdfSmrg		WindowPtr pParent, pChild;
332935c4bbdfSmrg		VTKind kind;
333035c4bbdfSmrg
333135c4bbdfSmrg</programlisting></blockquote>
333235c4bbdfSmrgIf this routine is not NULL, DIX calls it shortly after calling
333335c4bbdfSmrgValidateTree, passing it the same arguments.  This is useful for
333435c4bbdfSmrgmanaging multi-layered framebuffers.
333535c4bbdfSmrgThe sample server sets this to NULL.</para>
333635c4bbdfSmrg<para>
333735c4bbdfSmrg<blockquote><programlisting>
333835c4bbdfSmrg
333935c4bbdfSmrg	void pScreen->WindowExposures(pWin, pRegion, pBSRegion)
334035c4bbdfSmrg		WindowPtr pWin;
334135c4bbdfSmrg		RegionPtr pRegion;
334235c4bbdfSmrg		RegionPtr pBSRegion;
334335c4bbdfSmrg
334435c4bbdfSmrg</programlisting></blockquote>
334535c4bbdfSmrgThe WindowExposures() routine
334635c4bbdfSmrgpaints the border and generates exposure events for the window.
334735c4bbdfSmrgpRegion is an unoccluded region of the window, and pBSRegion is an
334835c4bbdfSmrgoccluded region that has backing store.
334935c4bbdfSmrgSince exposure events include a rectangle describing what was exposed,
335035c4bbdfSmrgthis routine may have to send back a series of exposure events, one for
335135c4bbdfSmrgeach rectangle of the region.
335235c4bbdfSmrgThe count field in the expose event is a hint to the
335335c4bbdfSmrgclient as to the number of
335435c4bbdfSmrgregions that are after this one.
335535c4bbdfSmrgThis routine must be provided. The sample
335635c4bbdfSmrgserver has a machine-independent version in Xserver/mi/miexpose.c.</para>
335735c4bbdfSmrg<para>
335835c4bbdfSmrg<blockquote><programlisting>
335935c4bbdfSmrg
336035c4bbdfSmrg	void pScreen->ClipNotify (pWin, dx, dy)
336135c4bbdfSmrg		WindowPtr pWin;
336235c4bbdfSmrg		int dx, dy;
336335c4bbdfSmrg
336435c4bbdfSmrg</programlisting></blockquote>
336535c4bbdfSmrgWhenever the cliplist for a window is changed, this function is called to
336635c4bbdfSmrgperform whatever hardware manipulations might be necessary.  When called,
336735c4bbdfSmrgthe clip list and border clip regions in the window are set to the new
336835c4bbdfSmrgvalues.  dx,dy are the distance that the window has been moved (if at all).</para>
336935c4bbdfSmrg</section>
337035c4bbdfSmrg<section>
337135c4bbdfSmrg  <title>Window Painting Procedures</title>
337235c4bbdfSmrg<para>
337335c4bbdfSmrgIn addition to the procedures listed above, there are two routines which
337435c4bbdfSmrgmanipulate the actual window image directly.
337535c4bbdfSmrgIn the sample server, mi implementations will work for
337635c4bbdfSmrgmost purposes and fb routines speed up situations, such
337735c4bbdfSmrgas solid backgrounds/borders or tiles that are 8, 16 or 32 pixels square.</para>
337835c4bbdfSmrg<para>
337935c4bbdfSmrg<blockquote><programlisting>
338035c4bbdfSmrg
338135c4bbdfSmrg	void pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
338235c4bbdfSmrg		WindowPtr pWin;
338335c4bbdfSmrg		int x, y, w, h;
338435c4bbdfSmrg		Bool generateExposures;
338535c4bbdfSmrg
338635c4bbdfSmrg</programlisting></blockquote>
338735c4bbdfSmrgThis routine is called on a window in response to a ClearToBackground request
338835c4bbdfSmrgfrom the client.
338935c4bbdfSmrgThis request has two different but related functions, depending upon generateExposures.</para>
339035c4bbdfSmrg<para>
339135c4bbdfSmrgIf generateExposures is true, the client is declaring that the given rectangle
339235c4bbdfSmrgon the window is incorrectly painted and needs to be repainted.
339335c4bbdfSmrgThe sample server implementation calculates the exposure region
339435c4bbdfSmrgand hands it to the DIX procedure HandleExposures(), which
339535c4bbdfSmrgcalls the WindowExposures() routine, below, for the window
339635c4bbdfSmrgand all of its child windows.</para>
339735c4bbdfSmrg<para>
339835c4bbdfSmrgIf generateExposures is false, the client is trying to simply erase part
339935c4bbdfSmrgof the window to the background fill style.
340035c4bbdfSmrgClearToBackground should write the background color or tile to the
340135c4bbdfSmrgrectangle in question (probably using PaintWindowBackground).
340235c4bbdfSmrgIf w or h is zero, it clears all the way to the right or lower edge of the window.</para>
340335c4bbdfSmrg<para>
340435c4bbdfSmrgThe sample server implementation is in Xserver/mi/miwindow.c.</para>
340535c4bbdfSmrg<para>
340635c4bbdfSmrg<blockquote><programlisting>
340735c4bbdfSmrg
340835c4bbdfSmrg	void pScreen->CopyWindow(pWin, oldpt, oldRegion);
340935c4bbdfSmrg		WindowPtr pWin;
341035c4bbdfSmrg		DDXPointRec oldpt;
341135c4bbdfSmrg		RegionPtr oldRegion;
341235c4bbdfSmrg
341335c4bbdfSmrg</programlisting></blockquote>
341435c4bbdfSmrgCopyWindow is called when a window is moved, and graphically moves to
341535c4bbdfSmrgpixels of a window on the screen.  It should not change any other
341635c4bbdfSmrgstate within DDX (see PositionWindow(), above).</para>
341735c4bbdfSmrg<para>
341835c4bbdfSmrgoldpt is the old location of the upper-left corner.  oldRegion is the
341935c4bbdfSmrgold region it is coming from.  The new location and new region is
342035c4bbdfSmrgstored in the WindowRec.  oldRegion might modified in place by this
342135c4bbdfSmrgroutine (the sample implementation does this).</para>
342235c4bbdfSmrg<para>
342335c4bbdfSmrgCopyArea could be used, except that this operation has more
342435c4bbdfSmrgcomplications.  First of all, you do not want to copy a rectangle onto
342535c4bbdfSmrga rectangle.  The original window may be obscured by other windows,
342635c4bbdfSmrgand the new window location may be similarly obscured.  Second, some
342735c4bbdfSmrghardware supports multiple windows with multiple depths, and your
342835c4bbdfSmrgroutine needs to take care of that.</para>
342935c4bbdfSmrg<para>
343035c4bbdfSmrgThe pixels in oldRegion (with reference point oldpt) are copied to the
343135c4bbdfSmrgwindow's new region (pWin->borderClip).  pWin->borderClip is gotten
343235c4bbdfSmrgdirectly from the window, rather than passing it as a parameter.</para>
343335c4bbdfSmrg<para>
343435c4bbdfSmrgThe sample server implementation is in Xserver/fb/fbwindow.c.</para>
343535c4bbdfSmrg</section>
343635c4bbdfSmrg<section>
343735c4bbdfSmrg<title>Screen Operations for Multi-Layered Framebuffers</title>
343835c4bbdfSmrg<para>
343935c4bbdfSmrgThe following screen functions are useful if you have a framebuffer with
344035c4bbdfSmrgmultiple sets of independent bit planes, e.g. overlays or underlays in
344135c4bbdfSmrgaddition to the "main" planes.  If you have a simple single-layer
344235c4bbdfSmrgframebuffer, you should probably use the mi versions of these routines
344335c4bbdfSmrgin mi/miwindow.c.  This can be easily accomplished by calling miScreenInit.</para>
344435c4bbdfSmrg<para>
344535c4bbdfSmrg<blockquote><programlisting>
344635c4bbdfSmrg
344735c4bbdfSmrg    void pScreen->MarkWindow(pWin)
344835c4bbdfSmrg	WindowPtr pWin;
344935c4bbdfSmrg
345035c4bbdfSmrg</programlisting></blockquote>
345135c4bbdfSmrgThis formerly dix function MarkWindow has moved to ddx and is accessed
345235c4bbdfSmrgvia this screen function.  This function should store something,
345335c4bbdfSmrgusually a pointer to a device-dependent structure, in pWin->valdata so
345435c4bbdfSmrgthat ValidateTree has the information it needs to validate the window.</para>
345535c4bbdfSmrg<para>
345635c4bbdfSmrg<blockquote><programlisting>
345735c4bbdfSmrg
345835c4bbdfSmrg    Bool pScreen->MarkOverlappedWindows(parent, firstChild, ppLayerWin)
345935c4bbdfSmrg	WindowPtr parent;
346035c4bbdfSmrg	WindowPtr firstChild;
346135c4bbdfSmrg	WindowPtr * ppLayerWin;
346235c4bbdfSmrg
346335c4bbdfSmrg</programlisting></blockquote>
346435c4bbdfSmrgThis formerly dix function MarkWindow has moved to ddx and is accessed
346535c4bbdfSmrgvia this screen function.  In the process, it has grown another
346635c4bbdfSmrgparameter: ppLayerWin, which is filled in with a pointer to the window
346735c4bbdfSmrgat which save under marking and ValidateTree should begin.  In the
346835c4bbdfSmrgsingle-layered framebuffer case, pLayerWin == pWin.</para>
346935c4bbdfSmrg<para>
347035c4bbdfSmrg<blockquote><programlisting>
347135c4bbdfSmrg
347235c4bbdfSmrg    Bool pScreen->ChangeSaveUnder(pLayerWin, firstChild)
347335c4bbdfSmrg	WindowPtr pLayerWin;
347435c4bbdfSmrg	WindowPtr firstChild;
347535c4bbdfSmrg
347635c4bbdfSmrg</programlisting></blockquote>
347735c4bbdfSmrgThe dix functions ChangeSaveUnder and CheckSaveUnder have moved to ddx and
347835c4bbdfSmrgare accessed via this screen function.  pLayerWin should be the window
347935c4bbdfSmrgreturned in the ppLayerWin parameter of MarkOverlappedWindows.  The function
348035c4bbdfSmrgmay turn on backing store for windows that might be covered, and may partially
348135c4bbdfSmrgturn off backing store for windows.  It returns TRUE if PostChangeSaveUnder
348235c4bbdfSmrgneeds to be called to finish turning off backing store.</para>
348335c4bbdfSmrg<para>
348435c4bbdfSmrg<blockquote><programlisting>
348535c4bbdfSmrg
348635c4bbdfSmrg    void pScreen->PostChangeSaveUnder(pLayerWin, firstChild)
348735c4bbdfSmrg	WindowPtr pLayerWin;
348835c4bbdfSmrg	WindowPtr firstChild;
348935c4bbdfSmrg
349035c4bbdfSmrg</programlisting></blockquote>
349135c4bbdfSmrgThe dix function DoChangeSaveUnder has moved to ddx and is accessed via
349235c4bbdfSmrgthis screen function.  This function completes the job of turning off
349335c4bbdfSmrgbacking store that was started by ChangeSaveUnder.</para>
349435c4bbdfSmrg<para>
349535c4bbdfSmrg<blockquote><programlisting>
349635c4bbdfSmrg
349735c4bbdfSmrg    void pScreen->MoveWindow(pWin, x, y, pSib, kind)
349835c4bbdfSmrg	WindowPtr pWin;
349935c4bbdfSmrg	int x;
350035c4bbdfSmrg	int y;
350135c4bbdfSmrg	WindowPtr pSib;
350235c4bbdfSmrg	VTKind kind;
350335c4bbdfSmrg
350435c4bbdfSmrg</programlisting></blockquote>
350535c4bbdfSmrgThe formerly dix function MoveWindow has moved to ddx and is accessed via
350635c4bbdfSmrgthis screen function.  The new position of the window is given by
350735c4bbdfSmrgx,y.  kind is VTMove if the window is only moving, or VTOther if
350835c4bbdfSmrgthe border is also changing.</para>
350935c4bbdfSmrg<para>
351035c4bbdfSmrg<blockquote><programlisting>
351135c4bbdfSmrg
351235c4bbdfSmrg    void pScreen->ResizeWindow(pWin, x, y, w, h, pSib)
351335c4bbdfSmrg	WindowPtr pWin;
351435c4bbdfSmrg	int x;
351535c4bbdfSmrg	int y;
351635c4bbdfSmrg	unsigned int w;
351735c4bbdfSmrg	unsigned int h;
351835c4bbdfSmrg	WindowPtr pSib;
351935c4bbdfSmrg
352035c4bbdfSmrg</programlisting></blockquote>
352135c4bbdfSmrgThe formerly dix function SlideAndSizeWindow has moved to ddx and is accessed via
352235c4bbdfSmrgthis screen function.  The new position is given by x,y.  The new size
352335c4bbdfSmrgis given by w,h.</para>
352435c4bbdfSmrg<para>
352535c4bbdfSmrg<blockquote><programlisting>
352635c4bbdfSmrg
352735c4bbdfSmrg    WindowPtr pScreen->GetLayerWindow(pWin)
352835c4bbdfSmrg	WindowPtr pWin
352935c4bbdfSmrg
353035c4bbdfSmrg</programlisting></blockquote>
353135c4bbdfSmrgThis is a new function which returns a child of the layer parent of pWin.</para>
353235c4bbdfSmrg<para>
353335c4bbdfSmrg<blockquote><programlisting>
353435c4bbdfSmrg
353535c4bbdfSmrg    void pScreen->HandleExposures(pWin)
353635c4bbdfSmrg	WindowPtr pWin;
353735c4bbdfSmrg
353835c4bbdfSmrg</programlisting></blockquote>
353935c4bbdfSmrgThe formerly dix function HandleExposures has moved to ddx and is accessed via
354035c4bbdfSmrgthis screen function.  This function is called after ValidateTree and
354135c4bbdfSmrguses the information contained in valdata to send exposures to windows.</para>
354235c4bbdfSmrg<para>
354335c4bbdfSmrg<blockquote><programlisting>
354435c4bbdfSmrg
354535c4bbdfSmrg    void pScreen->ReparentWindow(pWin, pPriorParent)
354635c4bbdfSmrg	WindowPtr pWin;
354735c4bbdfSmrg	WindowPtr pPriorParent;
354835c4bbdfSmrg
354935c4bbdfSmrg</programlisting></blockquote>
355035c4bbdfSmrgThis function will be called when a window is reparented.  At the time of
355135c4bbdfSmrgthe call, pWin will already be spliced into its new position in the
355235c4bbdfSmrgwindow tree, and pPriorParent is its previous parent.  This function
355335c4bbdfSmrgcan be NULL.</para>
355435c4bbdfSmrg<para>
355535c4bbdfSmrg<blockquote><programlisting>
355635c4bbdfSmrg
355735c4bbdfSmrg    void pScreen->SetShape(pWin)
355835c4bbdfSmrg	WindowPtr pWin;
355935c4bbdfSmrg
356035c4bbdfSmrg</programlisting></blockquote>
356135c4bbdfSmrgThe formerly dix function SetShape has moved to ddx and is accessed via
356235c4bbdfSmrgthis screen function.  The window's new shape will have already been
356335c4bbdfSmrgstored in the window when this function is called.</para>
356435c4bbdfSmrg<para>
356535c4bbdfSmrg<blockquote><programlisting>
356635c4bbdfSmrg
356735c4bbdfSmrg    void pScreen->ChangeBorderWidth(pWin, width)
356835c4bbdfSmrg	WindowPtr pWin;
356935c4bbdfSmrg	unsigned int width;
357035c4bbdfSmrg
357135c4bbdfSmrg</programlisting></blockquote>
357235c4bbdfSmrgThe formerly dix function ChangeBorderWidth has moved to ddx and is accessed via
357335c4bbdfSmrgthis screen function.  The new border width is given by width.</para>
357435c4bbdfSmrg<para>
357535c4bbdfSmrg<blockquote><programlisting>
357635c4bbdfSmrg
357735c4bbdfSmrg    void pScreen->MarkUnrealizedWindow(pChild, pWin, fromConfigure)
357835c4bbdfSmrg	WindowPtr pChild;
357935c4bbdfSmrg	WindowPtr pWin;
358035c4bbdfSmrg	Bool fromConfigure;
358135c4bbdfSmrg
358235c4bbdfSmrg</programlisting></blockquote>
358335c4bbdfSmrgThis function is called for windows that are being unrealized as part of
358435c4bbdfSmrgan UnrealizeTree.  pChild is the window being unrealized, pWin is an
358535c4bbdfSmrgancestor, and the fromConfigure value is simply propagated from UnrealizeTree.</para>
358635c4bbdfSmrg</section>
358735c4bbdfSmrg</section>
358835c4bbdfSmrg</section>
358935c4bbdfSmrg<section>
359035c4bbdfSmrg<title>Graphics Contexts and Validation</title>
359135c4bbdfSmrg<para>
359235c4bbdfSmrgThis graphics context (GC) contains state variables such as foreground and
359335c4bbdfSmrgbackground pixel value (color), the current line style and width,
359435c4bbdfSmrgthe current tile or stipple for pattern generation, the current font for text
359535c4bbdfSmrggeneration, and other similar attributes.</para>
359635c4bbdfSmrg<para>
359735c4bbdfSmrgIn many graphics systems, the equivalent of the graphics context and the
359835c4bbdfSmrgdrawable are combined as one entity.
359935c4bbdfSmrgThe main distinction between the two kinds of status is that a drawable
360035c4bbdfSmrgdescribes a writing surface and the writings that may have already been done
360135c4bbdfSmrgon it, whereas a graphics context describes the drawing process.
360235c4bbdfSmrgA drawable is like a chalkboard.
360335c4bbdfSmrgA GC is like a piece of chalk.</para>
360435c4bbdfSmrg<para>
360535c4bbdfSmrgUnlike many similar systems, there is no "current pen location."
360635c4bbdfSmrgEvery graphic operation is accompanied by the coordinates where it is to happen.</para>
360735c4bbdfSmrg<para>
360835c4bbdfSmrgThe GC also includes two vectors of procedure pointers, the first
360935c4bbdfSmrgoperate on the GC itself and are called GC funcs.  The second, called
361035c4bbdfSmrgGC ops,
361135c4bbdfSmrgcontains the functions that carry out the fundamental graphic operations
361235c4bbdfSmrgsuch as drawing lines, polygons, arcs, text, and copying bitmaps.
361335c4bbdfSmrgThe DDX graphic software can, if it
361435c4bbdfSmrgwants to be smart, change these two vectors of procedure pointers
361535c4bbdfSmrgto take advantage of hardware/firmware in the server machine, which can do
361635c4bbdfSmrga better job under certain circumstances.  To reduce the amount of memory
361735c4bbdfSmrgconsumed by each GC, it is wise to create a few "boilerplate" GC ops vectors
361835c4bbdfSmrgwhich can be shared by every GC which matches the constraints for that set.
361935c4bbdfSmrgAlso, it is usually reasonable to have every GC created by a particular
362035c4bbdfSmrgmodule to share a common set of GC funcs.  Samples of this sort of
362135c4bbdfSmrgsharing can be seen in fb/fbgc.c.</para>
362235c4bbdfSmrg<para>
362335c4bbdfSmrgThe DDX software is notified any time the client (or DIX) uses a changed GC.
362435c4bbdfSmrgFor instance, if the hardware has special support for drawing fixed-width
362535c4bbdfSmrgfonts, DDX can intercept changes to the current font in a GC just before
362635c4bbdfSmrgdrawing is done.  It can plug into either a fixed-width procedure that makes
362735c4bbdfSmrgthe hardware draw characters, or a variable-width procedure that carefully
362835c4bbdfSmrglays out glyphs by hand in software, depending upon the new font that is
362935c4bbdfSmrgselected.</para>
363035c4bbdfSmrg<para>
363135c4bbdfSmrgA definition of these structures can be found in the file
363235c4bbdfSmrgXserver/include/gcstruct.h.</para>
363335c4bbdfSmrg<para>
363435c4bbdfSmrgAlso included in each GC is support for dynamic devPrivates, which the
363535c4bbdfSmrgDDX can use for any purpose (see <xref linkend="wrappers_and_privates"/> below).</para>
363635c4bbdfSmrg<para>
363735c4bbdfSmrgThe DIX routines available for manipulating GCs are
363835c4bbdfSmrgCreateGC, ChangeGC, ChangeGCXIDs, CopyGC, SetClipRects, SetDashes, and FreeGC.
363935c4bbdfSmrg<blockquote><programlisting>
364035c4bbdfSmrg
364135c4bbdfSmrg	GCPtr CreateGC(pDrawable, mask, pval, pStatus)
364235c4bbdfSmrg	    DrawablePtr pDrawable;
364335c4bbdfSmrg	    BITS32 mask;
364435c4bbdfSmrg	    XID *pval;
364535c4bbdfSmrg	    int *pStatus;
364635c4bbdfSmrg
364735c4bbdfSmrg	int ChangeGC(client, pGC, mask, pUnion)
364835c4bbdfSmrg	    ClientPtr client;
364935c4bbdfSmrg	    GCPtr pGC;
365035c4bbdfSmrg	    BITS32 mask;
365135c4bbdfSmrg	    ChangeGCValPtr pUnion;
365235c4bbdfSmrg
365335c4bbdfSmrg	int ChangeGCXIDs(client, pGC, mask, pC32)
365435c4bbdfSmrg	    ClientPtr client;
365535c4bbdfSmrg	    GCPtr pGC;
365635c4bbdfSmrg	    BITS32 mask;
365735c4bbdfSmrg	    CARD32 *pC32;
365835c4bbdfSmrg
365935c4bbdfSmrg	int CopyGC(pgcSrc, pgcDst, mask)
366035c4bbdfSmrg	    GCPtr pgcSrc;
366135c4bbdfSmrg	    GCPtr pgcDst;
366235c4bbdfSmrg	    BITS32 mask;
366335c4bbdfSmrg
366435c4bbdfSmrg	int SetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering)
366535c4bbdfSmrg	    GCPtr pGC;
366635c4bbdfSmrg	    int xOrigin, yOrigin;
366735c4bbdfSmrg	    int nrects;
366835c4bbdfSmrg	    xRectangle *prects;
366935c4bbdfSmrg	    int ordering;
367035c4bbdfSmrg
367135c4bbdfSmrg	SetDashes(pGC, offset, ndash, pdash)
367235c4bbdfSmrg	    GCPtr pGC;
367335c4bbdfSmrg	    unsigned offset;
367435c4bbdfSmrg	    unsigned ndash;
367535c4bbdfSmrg	    unsigned char *pdash;
367635c4bbdfSmrg
367735c4bbdfSmrg	int FreeGC(pGC, gid)
367835c4bbdfSmrg	    GCPtr pGC;
367935c4bbdfSmrg	    GContext gid;
368035c4bbdfSmrg
368135c4bbdfSmrg</programlisting></blockquote>
368235c4bbdfSmrg</para>
368335c4bbdfSmrg<para>
368435c4bbdfSmrgAs a convenience, each Screen structure contains an array of
368535c4bbdfSmrgGCs that are preallocated, one at each depth the screen supports.
368635c4bbdfSmrgThese are particularly useful in the mi code.  Two DIX routines
368735c4bbdfSmrgmust be used to get these GCs:
368835c4bbdfSmrg<blockquote><programlisting>
368935c4bbdfSmrg
369035c4bbdfSmrg	GCPtr GetScratchGC(depth, pScreen)
369135c4bbdfSmrg	    int depth;
369235c4bbdfSmrg	    ScreenPtr pScreen;
369335c4bbdfSmrg
369435c4bbdfSmrg	FreeScratchGC(pGC)
369535c4bbdfSmrg	    GCPtr pGC;
369635c4bbdfSmrg
369735c4bbdfSmrg</programlisting></blockquote>
369835c4bbdfSmrgAlways use these two routines, don't try to extract the scratch
369935c4bbdfSmrgGC yourself -- someone else might be using it, so a new one must
370035c4bbdfSmrgbe created on the fly.</para>
370135c4bbdfSmrg<para>
370235c4bbdfSmrgIf you need a GC for a very long time, say until the server is restarted,
370335c4bbdfSmrgyou should not take one from the pool used by GetScratchGC, but should
370435c4bbdfSmrgget your own using CreateGC or CreateScratchGC.
370535c4bbdfSmrgThis leaves the ones in the pool free for routines that only need it for
370635c4bbdfSmrga little while and don't want to pay a heavy cost to get it.
370735c4bbdfSmrg<blockquote><programlisting>
370835c4bbdfSmrg
370935c4bbdfSmrg	GCPtr CreateScratchGC(pScreen, depth)
371035c4bbdfSmrg	    ScreenPtr pScreen;
371135c4bbdfSmrg	    int depth;
371235c4bbdfSmrg
371335c4bbdfSmrg</programlisting></blockquote>
371435c4bbdfSmrgNULL is returned if the GC cannot be created.
371535c4bbdfSmrgThe GC returned can be freed with FreeScratchGC.</para>
371635c4bbdfSmrg<section>
371735c4bbdfSmrg  <title>Details of Operation</title>
371835c4bbdfSmrg<para>
371935c4bbdfSmrgAt screen initialization, a screen must supply a GC creation procedure.
372035c4bbdfSmrgAt GC creation, the screen must fill in GC funcs and GC ops vectors
372135c4bbdfSmrg(Xserver/include/gcstruct.h).  For any particular GC, the func vector
372235c4bbdfSmrgmust remain constant, while the op vector may vary.  This invariant is to
372335c4bbdfSmrgensure that Wrappers work correctly.</para>
372435c4bbdfSmrg<para>
372535c4bbdfSmrgWhen a client request is processed that results in a change
372635c4bbdfSmrgto the GC, the device-independent state of the GC is updated.
372735c4bbdfSmrgThis includes a record of the state that changed.
372835c4bbdfSmrgThen the ChangeGC GC func is called.
372935c4bbdfSmrgThis is useful for graphics subsystems that are able to process
373035c4bbdfSmrgstate changes in parallel with the server CPU.
373135c4bbdfSmrgDDX may opt not to take any action at GC-modify time.
373235c4bbdfSmrgThis is more efficient if multiple GC-modify requests occur
373335c4bbdfSmrgbetween draws using a given GC.</para>
373435c4bbdfSmrg<para>
373535c4bbdfSmrgValidation occurs at the first draw operation that specifies the GC after
373635c4bbdfSmrgthat GC was modified.  DIX calls then the ValidateGC GC func.  DDX should
373735c4bbdfSmrgthen update its internal state.  DDX internal state may be stored as one or
373835c4bbdfSmrgmore of the following:  1) device private block on the GC; 2) hardware
373935c4bbdfSmrgstate; 3) changes to the GC ops.</para>
374035c4bbdfSmrg<para>
374135c4bbdfSmrgThe GC contains a serial number, which is loaded with a number fetched from
374235c4bbdfSmrgthe window that was drawn into the last time the GC was used.  The serial
374335c4bbdfSmrgnumber in the drawable is changed when the drawable's
374435c4bbdfSmrgclipList or absCorner changes.  Thus, by
374535c4bbdfSmrgcomparing the GC serial number with the drawable serial number, DIX can
374635c4bbdfSmrgforce a validate if the drawable has been changed since the last time it
374735c4bbdfSmrgwas used with this GC.</para>
374835c4bbdfSmrg<para>
374935c4bbdfSmrgIn addition, the drawable serial number is always guaranteed to have the
375035c4bbdfSmrgmost significant bit set to 0.  Thus, the DDX layer can set the most
375135c4bbdfSmrgsignificant bit of the serial number to 1 in a GC to force a validate the next time
375235c4bbdfSmrgthe GC is used.  DIX also uses this technique to indicate that a change has
375335c4bbdfSmrgbeen made to the GC by way of a SetGC, a SetDashes or a SetClip request.</para>
375435c4bbdfSmrg</section>
375535c4bbdfSmrg<section>
375635c4bbdfSmrg  <title>GC Handling Routines</title>
375735c4bbdfSmrg<para>
375835c4bbdfSmrgThe ScreenRec data structure has a pointer for
375935c4bbdfSmrgCreateGC().
376035c4bbdfSmrg<blockquote><programlisting>
376135c4bbdfSmrg
376235c4bbdfSmrg	Bool pScreen->CreateGC(pGC)
376335c4bbdfSmrg		GCPtr pGC;
376435c4bbdfSmrg</programlisting></blockquote>
376535c4bbdfSmrgThis routine must fill in the fields of
376635c4bbdfSmrga dynamically allocated GC that is passed in.
376735c4bbdfSmrgIt does NOT allocate the GC record itself or fill
376835c4bbdfSmrgin the defaults; DIX does that.</para>
376935c4bbdfSmrg<para>
377035c4bbdfSmrgThis must fill in both the GC funcs and ops; none of the drawing
377135c4bbdfSmrgfunctions will be called before the GC has been validated,
377235c4bbdfSmrgbut the others (dealing with allocating of clip regions,
377335c4bbdfSmrgchanging and destroying the GC, etc.) might be.</para>
377435c4bbdfSmrg<para>
377535c4bbdfSmrgThe GC funcs vector contains pointers to 7
377635c4bbdfSmrgroutines and a devPrivate field:
377735c4bbdfSmrg<blockquote><programlisting>
377835c4bbdfSmrg
377935c4bbdfSmrg	pGC->funcs->ChangeGC(pGC, changes)
378035c4bbdfSmrg		GCPtr pGC;
378135c4bbdfSmrg		unsigned long changes;
378235c4bbdfSmrg
378335c4bbdfSmrg</programlisting></blockquote>
378435c4bbdfSmrgThis GC func is called immediately after a field in the GC is changed.
378535c4bbdfSmrgchanges is a bit mask indicating the changed fields of the GC in this
378635c4bbdfSmrgrequest.</para>
378735c4bbdfSmrg<para>
378835c4bbdfSmrgThe ChangeGC routine is useful if you have a system where
378935c4bbdfSmrgstate-changes to the GC can be swallowed immediately by your graphics
379035c4bbdfSmrgsystem, and a validate is not necessary.</para>
379135c4bbdfSmrg<para>
379235c4bbdfSmrg<blockquote><programlisting>
379335c4bbdfSmrg
379435c4bbdfSmrg	pGC->funcs->ValidateGC(pGC, changes, pDraw)
379535c4bbdfSmrg		GCPtr pGC;
379635c4bbdfSmrg		unsigned long changes;
379735c4bbdfSmrg		DrawablePtr pDraw;
379835c4bbdfSmrg
379935c4bbdfSmrg</programlisting></blockquote>
380035c4bbdfSmrgValidateGC is called by DIX just before the GC will be used when one
380135c4bbdfSmrgof many possible changes to the GC or the graphics system has
380235c4bbdfSmrghappened.  It can modify devPrivates data attached to the GC,
380335c4bbdfSmrgchange the op vector, or change hardware according to the
380435c4bbdfSmrgvalues in the GC.  It may not change the device-independent portion of
380535c4bbdfSmrgthe GC itself.</para>
380635c4bbdfSmrg<para>
380735c4bbdfSmrgIn almost all cases, your ValidateGC() procedure should take the
380835c4bbdfSmrgregions that drawing needs to be clipped to and combine them into a
380935c4bbdfSmrgcomposite clip region, which you keep a pointer to in the private part
381035c4bbdfSmrgof the GC.  In this way, your drawing primitive routines (and whatever
381135c4bbdfSmrgis below them) can easily determine what to clip and where.  You
381235c4bbdfSmrgshould combine the regions clientClip (the region that the client
381335c4bbdfSmrgdesires to clip output to) and the region returned by
381435c4bbdfSmrgNotClippedByChildren(), in DIX.  An example is in Xserver/fb/fbgc.c.</para>
381535c4bbdfSmrg<para>
381635c4bbdfSmrgSome kinds of extension software may cause this routine to be called
381735c4bbdfSmrgmore than originally intended; you should not rely on algorithms that
381835c4bbdfSmrgwill break under such circumstances.</para>
381935c4bbdfSmrg<para>
382035c4bbdfSmrgSee the Strategies document for more information on creatively using
382135c4bbdfSmrgthis routine.</para>
382235c4bbdfSmrg<para>
382335c4bbdfSmrg<blockquote><programlisting>
382435c4bbdfSmrg
382535c4bbdfSmrg	pGC->funcs->CopyGC(pGCSrc, mask, pGCDst)
382635c4bbdfSmrg		GCPtr pGCSrc;
382735c4bbdfSmrg		unsigned long mask;
382835c4bbdfSmrg		GCPtr pGCDst;
382935c4bbdfSmrg
383035c4bbdfSmrg</programlisting></blockquote>
383135c4bbdfSmrgThis routine is called by DIX when a GC is being copied to another GC.
383235c4bbdfSmrgThis is for situations where dynamically allocated chunks of memory
383335c4bbdfSmrgare stored in the GC's dynamic devPrivates and need to be transferred to
383435c4bbdfSmrgthe destination GC.</para>
383535c4bbdfSmrg<para>
383635c4bbdfSmrg<blockquote><programlisting>
383735c4bbdfSmrg
383835c4bbdfSmrg	pGC->funcs->DestroyGC(pGC)
383935c4bbdfSmrg		GCPtr pGC;
384035c4bbdfSmrg
384135c4bbdfSmrg</programlisting></blockquote>
384235c4bbdfSmrgThis routine is called before the GC is destroyed for the
384335c4bbdfSmrgentity interested in this GC to clean up after itself.
384435c4bbdfSmrgThis routine is responsible for freeing any auxiliary storage allocated.</para>
384535c4bbdfSmrg</section>
384635c4bbdfSmrg<section>
384735c4bbdfSmrg  <title>GC Clip Region Routines</title>
384835c4bbdfSmrg<para>
384935c4bbdfSmrgThe GC clientClip field requires three procedures to manage it.  These
385035c4bbdfSmrgprocedures are in the GC funcs vector.  The underlying principle is that dix
385135c4bbdfSmrgknows nothing about the internals of the clipping information, (except when
385235c4bbdfSmrgit has come from the client), and so calls ddX whenever it needs to copy,
385335c4bbdfSmrgset, or destroy such information.  It could have been possible for dix not
385435c4bbdfSmrgto allow ddX to touch the field in the GC, and require it to keep its own
385535c4bbdfSmrgcopy in devPriv, but since clip masks can be very large, this seems like a
385635c4bbdfSmrgbad idea.  Thus, the server allows ddX to do whatever it wants to the
385735c4bbdfSmrgclientClip field of the GC, but requires it to do all manipulation itself.</para>
385835c4bbdfSmrg<para>
385935c4bbdfSmrg<blockquote><programlisting>
386035c4bbdfSmrg
386135c4bbdfSmrg	void pGC->funcs->ChangeClip(pGC, type, pValue, nrects)
386235c4bbdfSmrg		GCPtr pGC;
386335c4bbdfSmrg		int type;
386435c4bbdfSmrg		char *pValue;
386535c4bbdfSmrg		int nrects;
386635c4bbdfSmrg
386735c4bbdfSmrg</programlisting></blockquote>
386835c4bbdfSmrgThis routine is called whenever the client changes the client clip
386935c4bbdfSmrgregion.  The pGC points to the GC involved, the type tells what form
387035c4bbdfSmrgthe region has been sent in.  If type is CT_NONE, then there is no
387135c4bbdfSmrgclient clip.  If type is CT_UNSORTED, CT_YBANDED or CT_YXBANDED, then
387235c4bbdfSmrgpValue pointer to a list of rectangles, nrects long.  If type is
387335c4bbdfSmrgCT_REGION, then pValue pointer to a RegionRec from the mi region code.
387435c4bbdfSmrgIf type is CT_PIXMAP pValue is a pointer to a pixmap.  (The defines
387535c4bbdfSmrgfor CT_NONE, etc. are in Xserver/include/gc.h.)  This routine is
387635c4bbdfSmrgresponsible for incrementing any necessary reference counts (e.g. for
387735c4bbdfSmrga pixmap clip mask) for the new clipmask and freeing anything that
387835c4bbdfSmrgused to be in the GC's clipMask field.  The lists of rectangles passed
387935c4bbdfSmrgin can be freed with free(), the regions can be destroyed with the
388035c4bbdfSmrgRegionDestroy field in the screen, and pixmaps can be destroyed by
388135c4bbdfSmrgcalling the screen's DestroyPixmap function.  DIX and MI code expect
388235c4bbdfSmrgwhat they pass in to this to be freed or otherwise inaccessible, and
388335c4bbdfSmrgwill never look inside what's been put in the GC.  This is a good
388435c4bbdfSmrgplace to be wary of storage leaks.</para>
388535c4bbdfSmrg<para>
388635c4bbdfSmrgIn the sample server, this routine transforms either the bitmap or the
388735c4bbdfSmrgrectangle list into a region, so that future routines will have a more
388835c4bbdfSmrgpredictable starting point to work from.  (The validate routine must
388935c4bbdfSmrgtake this client clip region and merge it with other regions to arrive
389035c4bbdfSmrgat a composite clip region before any drawing is done.)</para>
389135c4bbdfSmrg<para>
389235c4bbdfSmrg<blockquote><programlisting>
389335c4bbdfSmrg
389435c4bbdfSmrg	void pGC->funcs->DestroyClip(pGC)
389535c4bbdfSmrg		GCPtr pGC;
389635c4bbdfSmrg
389735c4bbdfSmrg</programlisting></blockquote>
389835c4bbdfSmrgThis routine is called whenever the client clip region must be destroyed.
389935c4bbdfSmrgThe pGC points to the GC involved.  This call should set the clipType
390035c4bbdfSmrgfield of the GC to CT_NONE.
390135c4bbdfSmrgIn the sample server, the pointer to the client clip region is set to NULL
390235c4bbdfSmrgby this routine after destroying the region, so that other software
390335c4bbdfSmrg(including ChangeClip() above) will recognize that there is no client clip region.</para>
390435c4bbdfSmrg<para>
390535c4bbdfSmrg<blockquote><programlisting>
390635c4bbdfSmrg
390735c4bbdfSmrg	void pGC->funcs->CopyClip(pgcDst, pgcSrc)
390835c4bbdfSmrg		GCPtr pgcDst, pgcSrc;
390935c4bbdfSmrg
391035c4bbdfSmrg</programlisting></blockquote>
391135c4bbdfSmrgThis routine makes a copy of the clipMask and clipType from pgcSrc
391235c4bbdfSmrginto pgcDst.  It is responsible for destroying any previous clipMask
391335c4bbdfSmrgin pgcDst.  The clip mask in the source can be the same as the
391435c4bbdfSmrgclip mask in the dst (clients do the strangest things), so care must
391535c4bbdfSmrgbe taken when destroying things.  This call is required because dix
391635c4bbdfSmrgdoes not know how to copy the clip mask from pgcSrc.</para>
391735c4bbdfSmrg</section>
391835c4bbdfSmrg</section>
391935c4bbdfSmrg<section>
392035c4bbdfSmrg  <title>Drawing Primitives</title>
392135c4bbdfSmrg<para>
392235c4bbdfSmrgThe X protocol (rules for the byte stream that goes between client and server)
392335c4bbdfSmrgdoes all graphics using primitive
392435c4bbdfSmrgoperations, which are called Drawing Primitives.
392535c4bbdfSmrgThese include line drawing, area filling, arcs, and text drawing.
392635c4bbdfSmrgYour implementation must supply 16 routines
392735c4bbdfSmrgto perform these on your hardware.
392835c4bbdfSmrg(The number 16 is arbitrary.)</para>
392935c4bbdfSmrg<para>
393035c4bbdfSmrgMore specifically, 16 procedure pointers are in each
393135c4bbdfSmrgGC op vector.
393235c4bbdfSmrgAt any given time, ALL of them MUST point to a valid procedure that
393335c4bbdfSmrgattempts to do the operation assigned, although
393435c4bbdfSmrgthe procedure pointers may change and may
393535c4bbdfSmrgpoint to different procedures to carry out the same operation.
393635c4bbdfSmrgA simple server will leave them all pointing to the same 16 routines, while
393735c4bbdfSmrga more optimized implementation will switch each from one
393835c4bbdfSmrgprocedure to another, depending upon what is most optimal
393935c4bbdfSmrgfor the current GC and drawable.</para>
394035c4bbdfSmrg<para>
394135c4bbdfSmrgThe sample server contains a considerable chunk of code called the
394235c4bbdfSmrgmi (machine independent)
394335c4bbdfSmrgroutines, which serve as drawing primitive routines.
394435c4bbdfSmrgMany server implementations will be able to use these as-is,
394535c4bbdfSmrgbecause they work for arbitrary depths.
394635c4bbdfSmrgThey make no assumptions about the formats of pixmaps
394735c4bbdfSmrgand frame buffers, since they call a set of routines
394835c4bbdfSmrgknown as the "Pixblit Routines" (see next section).
394935c4bbdfSmrgThey do assume that the way to draw is
395035c4bbdfSmrgthrough these low-level routines that apply pixel values rows at a time.
395135c4bbdfSmrgIf your hardware or firmware gives more performance when
395235c4bbdfSmrgthings are done differently, you will want to take this fact into account
395335c4bbdfSmrgand rewrite some or all of the drawing primitives to fit your needs.</para>
395435c4bbdfSmrg<section>
395535c4bbdfSmrg  <title>GC Components</title>
395635c4bbdfSmrg<para>
395735c4bbdfSmrgThis section describes the fields in the GC that affect each drawing primitive.
395835c4bbdfSmrgThe only primitive that is not affected is GetImage, which does not use a GC
395935c4bbdfSmrgbecause its destination is a protocol-style bit image.
396035c4bbdfSmrgSince each drawing primitive mirrors exactly the X protocol request of the
396135c4bbdfSmrgsame name, you should refer to the X protocol specification document
396235c4bbdfSmrgfor more details.</para>
396335c4bbdfSmrg<para>
396435c4bbdfSmrgALL of these routines MUST CLIP to the
396535c4bbdfSmrgappropriate regions in the drawable.
396635c4bbdfSmrgSince there are many regions to clip to simultaneously,
396735c4bbdfSmrgyour ValidateGC routine should combine these into a unified
396835c4bbdfSmrgclip region to which your drawing routines can quickly refer.
396935c4bbdfSmrgThis is exactly what the fb routines supplied with the sample server
397035c4bbdfSmrgdo.
397135c4bbdfSmrgThe mi implementation passes responsibility for clipping while drawing
397235c4bbdfSmrgdown to the Pixblit routines.</para>
397335c4bbdfSmrg<para>
397435c4bbdfSmrgAlso, all of them must adhere to the current plane mask.
397535c4bbdfSmrgThe plane mask has one bit for every bit plane in the drawable;
397635c4bbdfSmrgonly planes with 1 bits in the mask are affected by any drawing operation.</para>
397735c4bbdfSmrg<para>
397835c4bbdfSmrgAll functions except for ImageText calls must obey the alu function.
397935c4bbdfSmrgThis is usually Copy, but could be any of the allowable 16 raster-ops.</para>
398035c4bbdfSmrg<para>
398135c4bbdfSmrgAll of the functions, except for CopyArea, might use the current
398235c4bbdfSmrgforeground and background pixel values.
398335c4bbdfSmrgEach pixel value is 32 bits.
398435c4bbdfSmrgThese correspond to foreground and background colors, but you have
398535c4bbdfSmrgto run them through the colormap to find out what color the pixel values
398635c4bbdfSmrgrepresent.  Do not worry about the color, just apply the pixel value.</para>
398735c4bbdfSmrg<para>
398835c4bbdfSmrgThe routines that draw lines (PolyLine, PolySegment, PolyRect, and PolyArc)
398935c4bbdfSmrguse the line width, line style, cap style, and join style.
399035c4bbdfSmrgLine width is in pixels.
399135c4bbdfSmrgThe line style specifies whether it is solid or dashed, and what kind of dash.
399235c4bbdfSmrgThe cap style specifies whether Rounded, Butt, etc.
399335c4bbdfSmrgThe join style specifies whether joins between joined lines are Miter, Round or Beveled.
399435c4bbdfSmrgWhen lines cross as part of the same polyline, they are assumed to be drawn once.
399535c4bbdfSmrg(See the X protocol specification for more details.)</para>
399635c4bbdfSmrg<para>
399735c4bbdfSmrgZero-width lines are NOT meant to be really zero width; this is the client's way
399835c4bbdfSmrgof telling you that you can optimize line drawing with little regard to
399935c4bbdfSmrgthe end caps and joins.
400035c4bbdfSmrgThey are called "thin" lines and are meant to be one pixel wide.
400135c4bbdfSmrgThese are frequently done in hardware or in a streamlined assembly language
400235c4bbdfSmrgroutine.</para>
400335c4bbdfSmrg<para>
400435c4bbdfSmrgLines with widths greater than zero, though, must all be drawn with the same
400535c4bbdfSmrgalgorithm, because client software assumes that every jag on every
400635c4bbdfSmrgline at an angle will come at the same place.
400735c4bbdfSmrgTwo lines that should have
400835c4bbdfSmrgone pixel in the space between them
400935c4bbdfSmrg(because of their distance apart and their widths) should have such a one-pixel line
401035c4bbdfSmrgof space between them if drawn, regardless of angle.</para>
401135c4bbdfSmrg<para>
401235c4bbdfSmrgThe solid area fill routines (FillPolygon, PolyFillRect, PolyFillArc)
401335c4bbdfSmrgall use the fill rule, which specifies subtle interpretations of
401435c4bbdfSmrgwhat points are inside and what are outside of a given polygon.
401535c4bbdfSmrgThe PolyFillArc routine also uses the arc mode, which specifies
401635c4bbdfSmrgwhether to fill pie segments or single-edge slices of an ellipse.</para>
401735c4bbdfSmrg<para>
401835c4bbdfSmrgThe line drawing, area fill, and PolyText routines must all
401935c4bbdfSmrgapply the correct "fill style."
402035c4bbdfSmrgThis can be either a solid foreground color, a transparent stipple,
402135c4bbdfSmrgan opaque stipple, or a tile.
402235c4bbdfSmrgStipples are bitmaps where the 1 bits represent that the foreground color is written,
402335c4bbdfSmrgand 0 bits represent that either the pixel is left alone (transparent) or that
402435c4bbdfSmrgthe background color is written (opaque).
402535c4bbdfSmrgA tile is a pixmap of the full depth of the GC that is applied in its full glory to all areas.
402635c4bbdfSmrgThe stipple and tile patterns can be any rectangular size, although some implementations
402735c4bbdfSmrgwill be faster for certain sizes such as 8x8 or 32x32.
402835c4bbdfSmrgThe mi implementation passes this responsibility down to the Pixblit routines.</para>
402935c4bbdfSmrg<para>
403035c4bbdfSmrgSee the X protocol document for full details.
403135c4bbdfSmrgThe description of the CreateGC request has a very good, detailed description of these
403235c4bbdfSmrgattributes.</para>
403335c4bbdfSmrg</section>
403435c4bbdfSmrg<section>
403535c4bbdfSmrg<title>The Primitives</title>
403635c4bbdfSmrg<para>
403735c4bbdfSmrgThe Drawing Primitives are as follows:
403835c4bbdfSmrg
403935c4bbdfSmrg<blockquote><programlisting>
404035c4bbdfSmrg
404135c4bbdfSmrg	RegionPtr pGC->ops->CopyArea(src, dst, pGC, srcx, srcy, w, h, dstx, dsty)
404235c4bbdfSmrg		DrawablePtr dst, src;
404335c4bbdfSmrg		GCPtr pGC;
404435c4bbdfSmrg		int srcx, srcy, w, h, dstx, dsty;
404535c4bbdfSmrg
404635c4bbdfSmrg</programlisting></blockquote>
404735c4bbdfSmrgCopyArea copies a rectangle of pixels from one drawable to another of
404835c4bbdfSmrgthe same depth.  To effect scrolling, this must be able to copy from
404935c4bbdfSmrgany drawable to itself, overlapped.  No squeezing or stretching is done
405035c4bbdfSmrgbecause the source and destination are the same size.  However,
405135c4bbdfSmrgeverything is still clipped to the clip regions of the destination
405235c4bbdfSmrgdrawable.</para>
405335c4bbdfSmrg<para>
405435c4bbdfSmrgIf pGC->graphicsExposures is True, any portions of the destination which
405535c4bbdfSmrgwere not valid in the source (either occluded by covering windows, or
405635c4bbdfSmrgoutside the bounds of the drawable) should be collected together and
405735c4bbdfSmrgreturned as a region (if this resultant region is empty, NULL can be
405835c4bbdfSmrgreturned instead).  Furthermore, the invalid bits of the source are
405935c4bbdfSmrgnot copied to the destination and (when the destination is a window)
406035c4bbdfSmrgare filled with the background tile.  The sample routine
406135c4bbdfSmrgmiHandleExposures generates the appropriate return value and fills the
406235c4bbdfSmrginvalid area using pScreen->PaintWindowBackground.</para>
406335c4bbdfSmrg<para>
406435c4bbdfSmrgFor instance, imagine a window that is partially obscured by other
406535c4bbdfSmrgwindows in front of it.  As text is scrolled on your window, the pixels
406635c4bbdfSmrgthat are scrolled out from under obscuring windows will not be
406735c4bbdfSmrgavailable on the screen to copy to the right places, and so an exposure
406835c4bbdfSmrgevent must be sent for the client to correctly repaint them.  Of
406935c4bbdfSmrgcourse, if you implement backing store, you could do this without resorting
407035c4bbdfSmrgto exposure events.</para>
407135c4bbdfSmrg<para>
407235c4bbdfSmrgAn example implementation is fbCopyArea() in Xserver/fb/fbcopy.c.</para>
407335c4bbdfSmrg<para>
407435c4bbdfSmrg<blockquote><programlisting>
407535c4bbdfSmrg
407635c4bbdfSmrg	RegionPtr pGC->ops->CopyPlane(src, dst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
407735c4bbdfSmrg		DrawablePtr dst, src;
407835c4bbdfSmrg		GCPtr pGC;
407935c4bbdfSmrg		int srcx, srcy, w, h, dstx, dsty;
408035c4bbdfSmrg		unsigned long plane;
408135c4bbdfSmrg
408235c4bbdfSmrg</programlisting></blockquote>
408335c4bbdfSmrgCopyPlane must copy one plane of a rectangle from the source drawable
408435c4bbdfSmrgonto the destination drawable.  Because this routine only copies one
408535c4bbdfSmrgbit out of each pixel, it can copy between drawables of different
408635c4bbdfSmrgdepths.  This is the only way of copying between drawables of
408735c4bbdfSmrgdifferent depths, except for copying bitmaps to pixmaps and applying
408835c4bbdfSmrgforeground and background colors to it.  All other conditions of
408935c4bbdfSmrgCopyArea apply to CopyPlane too.</para>
409035c4bbdfSmrg<para>
409135c4bbdfSmrgAn example implementation is fbCopyPlane() in
409235c4bbdfSmrgXserver/fb/fbcopy.c.</para>
409335c4bbdfSmrg<para>
409435c4bbdfSmrg<blockquote><programlisting>
409535c4bbdfSmrg
409635c4bbdfSmrg	void pGC->ops->PolyPoint(dst, pGC, mode, n, pPoint)
409735c4bbdfSmrg		DrawablePtr dst;
409835c4bbdfSmrg		GCPtr pGC;
409935c4bbdfSmrg		int mode;
410035c4bbdfSmrg		int n;
410135c4bbdfSmrg		DDXPointPtr pPoint;
410235c4bbdfSmrg
410335c4bbdfSmrg</programlisting></blockquote>
410435c4bbdfSmrgPolyPoint draws a set of one-pixel dots (foreground color)
410535c4bbdfSmrgat the locations given in the array.
410635c4bbdfSmrgmode is one of the defined constants Origin (absolute coordinates) or Previous
410735c4bbdfSmrg(each coordinate is relative to the last).
410835c4bbdfSmrgNote that this does not use the background color or any tiles or stipples.</para>
410935c4bbdfSmrg<para>
411035c4bbdfSmrgExample implementations are fbPolyPoint() in Xserver/fb/fbpoint.c and
411135c4bbdfSmrgmiPolyPoint in Xserver/mi/mipolypnt.c.</para>
411235c4bbdfSmrg<para>
411335c4bbdfSmrg<blockquote><programlisting>
411435c4bbdfSmrg
411535c4bbdfSmrg	void pGC->ops->Polylines(dst, pGC, mode, n, pPoint)
411635c4bbdfSmrg		DrawablePtr dst;
411735c4bbdfSmrg		GCPtr pGC;
411835c4bbdfSmrg		int mode;
411935c4bbdfSmrg		int n;
412035c4bbdfSmrg		DDXPointPtr pPoint;
412135c4bbdfSmrg
412235c4bbdfSmrg</programlisting></blockquote>
412335c4bbdfSmrgSimilar to PolyPoint, Polylines draws lines between the locations given in the array.
412435c4bbdfSmrgZero-width lines are NOT meant to be really zero width; this is the client's way of
412535c4bbdfSmrgtelling you that you can maximally optimize line drawing with little regard to
412635c4bbdfSmrgthe end caps and joins.
412735c4bbdfSmrgmode is one of the defined constants Previous or Origin, depending upon
412835c4bbdfSmrgwhether the points are each relative to the last or are absolute.</para>
412935c4bbdfSmrg<para>
413035c4bbdfSmrgExample implementations are miWideLine() and miWideDash() in
413135c4bbdfSmrgmi/miwideline.c and miZeroLine() in mi/mizerline.c.</para>
413235c4bbdfSmrg<para>
413335c4bbdfSmrg<blockquote><programlisting>
413435c4bbdfSmrg
413535c4bbdfSmrg	void pGC->ops->PolySegment(dst, pGC, n, pPoint)
413635c4bbdfSmrg		DrawablePtr dst;
413735c4bbdfSmrg		GCPtr pGC;
413835c4bbdfSmrg		int n;
413935c4bbdfSmrg		xSegment *pSegments;
414035c4bbdfSmrg
414135c4bbdfSmrg</programlisting></blockquote>
414235c4bbdfSmrgPolySegments draws unconnected
414335c4bbdfSmrglines between pairs of points in the array; the array must be of
414435c4bbdfSmrgeven size; no interconnecting lines are drawn.</para>
414535c4bbdfSmrg<para>
414635c4bbdfSmrgAn example implementation is miPolySegment() in mipolyseg.c.</para>
414735c4bbdfSmrg<para>
414835c4bbdfSmrg<blockquote><programlisting>
414935c4bbdfSmrg
415035c4bbdfSmrg	void pGC->ops->PolyRectangle(dst, pGC, n, pRect)
415135c4bbdfSmrg		DrawablePtr dst;
415235c4bbdfSmrg		GCPtr pGC;
415335c4bbdfSmrg		int n;
415435c4bbdfSmrg		xRectangle *pRect;
415535c4bbdfSmrg
415635c4bbdfSmrg</programlisting></blockquote>
415735c4bbdfSmrgPolyRectangle draws outlines of rectangles for each rectangle in the array.</para>
415835c4bbdfSmrg<para>
415935c4bbdfSmrgAn example implementation is miPolyRectangle() in Xserver/mi/mipolyrect.c.</para>
416035c4bbdfSmrg<para>
416135c4bbdfSmrg<blockquote><programlisting>
416235c4bbdfSmrg
416335c4bbdfSmrg	void pGC->ops->PolyArc(dst, pGC, n, pArc)
416435c4bbdfSmrg		DrawablePtr dst;
416535c4bbdfSmrg		GCPtr pGC;
416635c4bbdfSmrg		int n;
416735c4bbdfSmrg		xArc*pArc;
416835c4bbdfSmrg
416935c4bbdfSmrg</programlisting></blockquote>
417035c4bbdfSmrgPolyArc draws connected conic arcs according to the descriptions in the array.
417135c4bbdfSmrgSee the protocol specification for more details.</para>
417235c4bbdfSmrg<para>
417335c4bbdfSmrgExample implementations are miZeroPolyArc in Xserver/mi/mizerarc. and
417435c4bbdfSmrgmiPolyArc() in Xserver/mi/miarc.c.</para>
417535c4bbdfSmrg<para>
417635c4bbdfSmrg<blockquote><programlisting>
417735c4bbdfSmrg
417835c4bbdfSmrg	void pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pPoint)
417935c4bbdfSmrg		DrawablePtr dst;
418035c4bbdfSmrg		GCPtr pGC;
418135c4bbdfSmrg		int shape;
418235c4bbdfSmrg		int mode;
418335c4bbdfSmrg		int count;
418435c4bbdfSmrg		DDXPointPtr pPoint;
418535c4bbdfSmrg
418635c4bbdfSmrg</programlisting></blockquote>
418735c4bbdfSmrgFillPolygon fills a polygon specified by the points in the array
418835c4bbdfSmrgwith the appropriate fill style.
418935c4bbdfSmrgIf necessary, an extra border line is assumed between the starting and ending lines.
419035c4bbdfSmrgThe shape can be used as a hint
419135c4bbdfSmrgto optimize filling; it indicates whether it is convex (all interior angles
419235c4bbdfSmrgless than 180), nonconvex (some interior angles greater than 180 but
419335c4bbdfSmrgborder does not cross itself), or complex (border crosses itself).
419435c4bbdfSmrgYou can choose appropriate algorithms or hardware based upon mode.
419535c4bbdfSmrgmode is one of the defined constants Previous or Origin, depending upon
419635c4bbdfSmrgwhether the points are each relative to the last or are absolute.</para>
419735c4bbdfSmrg<para>
419835c4bbdfSmrgAn example implementation is miFillPolygon() in Xserver/mi/mipoly.c.</para>
419935c4bbdfSmrg<para>
420035c4bbdfSmrg<blockquote><programlisting>
420135c4bbdfSmrg
420235c4bbdfSmrg	void pGC->ops->PolyFillRect(dst, pGC, n, pRect)
420335c4bbdfSmrg		DrawablePtr dst;
420435c4bbdfSmrg		GCPtr pGC;
420535c4bbdfSmrg		int n;
420635c4bbdfSmrg		xRectangle *pRect;
420735c4bbdfSmrg
420835c4bbdfSmrg</programlisting></blockquote>
420935c4bbdfSmrgPolyFillRect fills multiple rectangles.</para>
421035c4bbdfSmrg<para>
421135c4bbdfSmrgExample implementations are fbPolyFillRect() in Xserver/fb/fbfillrect.c and
421235c4bbdfSmrgmiPolyFillRect() in Xserver/mi/mifillrct.c.</para>
421335c4bbdfSmrg<para>
421435c4bbdfSmrg<blockquote><programlisting>
421535c4bbdfSmrg
421635c4bbdfSmrg	void pGC->ops->PolyFillArc(dst, pGC, n, pArc)
421735c4bbdfSmrg		DrawablePtr dst;
421835c4bbdfSmrg		GCPtr pGC;
421935c4bbdfSmrg		int n;
422035c4bbdfSmrg		xArc *pArc;
422135c4bbdfSmrg
422235c4bbdfSmrg</programlisting></blockquote>
422335c4bbdfSmrgPolyFillArc fills a shape for each arc in the
422435c4bbdfSmrglist that is bounded by the arc and one or two
422535c4bbdfSmrgline segments with the current fill style.</para>
422635c4bbdfSmrg<para>
422735c4bbdfSmrgAn example implementation is miPolyFillArc() in Xserver/mi/mifillarc.c.</para>
422835c4bbdfSmrg<para>
422935c4bbdfSmrg<blockquote><programlisting>
423035c4bbdfSmrg
423135c4bbdfSmrg	void pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBinImage)
423235c4bbdfSmrg		DrawablePtr dst;
423335c4bbdfSmrg		GCPtr pGC;
423435c4bbdfSmrg		int x, y, w, h;
423535c4bbdfSmrg		int format;
423635c4bbdfSmrg		char *pBinImage;
423735c4bbdfSmrg
423835c4bbdfSmrg</programlisting></blockquote>
423935c4bbdfSmrgPutImage copies a pixmap image into the drawable.  The pixmap image
424035c4bbdfSmrgmust be in X protocol format (either Bitmap, XYPixmap, or ZPixmap),
424135c4bbdfSmrgand format tells the format.  (See the X protocol specification for
424235c4bbdfSmrgdetails on these formats).  You must be able to accept all three
424335c4bbdfSmrgformats, because the client gets to decide which format to send.
424435c4bbdfSmrgEither the drawable and the pixmap image have the same depth, or the
424535c4bbdfSmrgsource pixmap image must be a Bitmap.  If a Bitmap, the foreground and
424635c4bbdfSmrgbackground colors will be applied to the destination.</para>
424735c4bbdfSmrg<para>
424835c4bbdfSmrgAn example implementation is fbPutImage() in Xserver/fb/fbimage.c.</para>
424935c4bbdfSmrg<para>
425035c4bbdfSmrg<blockquote><programlisting>
425135c4bbdfSmrg
425235c4bbdfSmrg	void pScreen->GetImage(src, x, y, w, h, format, planeMask, pBinImage)
425335c4bbdfSmrg		 DrawablePtr src;
425435c4bbdfSmrg		 int x, y, w, h;
425535c4bbdfSmrg		 unsigned int format;
425635c4bbdfSmrg		 unsigned long planeMask;
425735c4bbdfSmrg		 char *pBinImage;
425835c4bbdfSmrg
425935c4bbdfSmrg</programlisting></blockquote>
426035c4bbdfSmrgGetImage copies the bits from the source drawable into
426135c4bbdfSmrgthe destination pointer.  The bits are written into the buffer
426235c4bbdfSmrgaccording to the server-defined pixmap padding rules.
426335c4bbdfSmrgpBinImage is guaranteed to be big enough to hold all
426435c4bbdfSmrgthe bits that must be written.</para>
426535c4bbdfSmrg<para>
426635c4bbdfSmrgThis routine does not correspond exactly to the X protocol GetImage
426735c4bbdfSmrgrequest, since DIX has to break the reply up into buffers of a size
426835c4bbdfSmrgrequested by the transport layer.  If format is ZPixmap, the bits are
426935c4bbdfSmrgwritten in the ZFormat for the depth of the drawable; if there is a 0
427035c4bbdfSmrgbit in the planeMask for a particular plane, all pixels must have the
427135c4bbdfSmrgbit in that plane equal to 0.  If format is XYPixmap, planemask is
427235c4bbdfSmrgguaranteed to have a single bit set; the bits should be written in
427335c4bbdfSmrgBitmap format, which is the format for a single plane of an XYPixmap.</para>
427435c4bbdfSmrg<para>
427535c4bbdfSmrgAn example implementation is miGetImage() in Xserver/mi/mibitblt.c.
427635c4bbdfSmrg<blockquote><programlisting>
427735c4bbdfSmrg
427835c4bbdfSmrg	void pGC->ops->ImageText8(pDraw, pGC, x, y, count, chars)
427935c4bbdfSmrg		DrawablePtr pDraw;
428035c4bbdfSmrg		GCPtr pGC;
428135c4bbdfSmrg		int x, y;
428235c4bbdfSmrg		int count;
428335c4bbdfSmrg		char *chars;
428435c4bbdfSmrg
428535c4bbdfSmrg</programlisting></blockquote>
428635c4bbdfSmrgImageText8 draws text.  The text is drawn in the foreground color; the
428735c4bbdfSmrgbackground color fills the remainder of the character rectangles.  The
428835c4bbdfSmrgcoordinates specify the baseline and start of the text.</para>
428935c4bbdfSmrg<para>
429035c4bbdfSmrgAn example implementation is miImageText8() in Xserver/mi/mipolytext.c.</para>
429135c4bbdfSmrg<para>
429235c4bbdfSmrg<blockquote><programlisting>
429335c4bbdfSmrg
429435c4bbdfSmrg	int pGC->ops->PolyText8(pDraw, pGC, x, y, count, chars)
429535c4bbdfSmrg		DrawablePtr pDraw;
429635c4bbdfSmrg		GCPtr pGC;
429735c4bbdfSmrg		int x, y;
429835c4bbdfSmrg		int count;
429935c4bbdfSmrg		char *chars;
430035c4bbdfSmrg
430135c4bbdfSmrg</programlisting></blockquote>
430235c4bbdfSmrgPolyText8 works like ImageText8, except it draws with
430335c4bbdfSmrgthe current fill style for special effects such as
430435c4bbdfSmrgshaded text.
430535c4bbdfSmrgSee the X protocol specification for more details.</para>
430635c4bbdfSmrg<para>
430735c4bbdfSmrgAn example implementation is miPolyText8() in Xserver/mi/mipolytext.c.</para>
430835c4bbdfSmrg<para>
430935c4bbdfSmrg<blockquote><programlisting>
431035c4bbdfSmrg
431135c4bbdfSmrg	int pGC->ops->PolyText16(pDraw, pGC, x, y, count, chars)
431235c4bbdfSmrg		DrawablePtr pDraw;
431335c4bbdfSmrg		GCPtr pGC;
431435c4bbdfSmrg		int x, y;
431535c4bbdfSmrg		int count;
431635c4bbdfSmrg		unsigned short *chars;
431735c4bbdfSmrg
431835c4bbdfSmrg	void pGC->ops->ImageText16(pDraw, pGC, x, y, count, chars)
431935c4bbdfSmrg		DrawablePtr pDraw;
432035c4bbdfSmrg		GCPtr pGC;
432135c4bbdfSmrg		int x, y;
432235c4bbdfSmrg		int count;
432335c4bbdfSmrg		unsigned short *chars;
432435c4bbdfSmrg
432535c4bbdfSmrg</programlisting></blockquote>
432635c4bbdfSmrgThese two routines are the same as the "8" versions,
432735c4bbdfSmrgexcept that they are for 16-bit character codes (useful
432835c4bbdfSmrgfor oriental writing systems).</para>
432935c4bbdfSmrg<para>
433035c4bbdfSmrgThe primary difference is in the way the character information is
433135c4bbdfSmrglooked up.  The 8-bit and the 16-bit versions obviously have different
433235c4bbdfSmrgkinds of character values to look up; the main goal of the lookup is
433335c4bbdfSmrgto provide a pointer to the CharInfo structs for the characters to
433435c4bbdfSmrgdraw and to pass these pointers to the Glyph routines.  Given a
433535c4bbdfSmrgCharInfo struct, lower-level software can draw the glyph desired with
433635c4bbdfSmrglittle concern for other characteristics of the font.</para>
433735c4bbdfSmrg<para>
433835c4bbdfSmrg16-bit character fonts have a row-and-column scheme, where the 2bytes
433935c4bbdfSmrgof the character code constitute the row and column in a square matrix
434035c4bbdfSmrgof CharInfo structs.  Each font has row and column minimum and maximum
434135c4bbdfSmrgvalues; the CharInfo structures form a two-dimensional matrix.</para>
434235c4bbdfSmrg<para>
434335c4bbdfSmrgExample implementations are miPolyText16() and
434435c4bbdfSmrgmiImageText16() in Xserver/mi/mipolytext.c.</para>
434535c4bbdfSmrg<para>
434635c4bbdfSmrgSee the X protocol specification for more details on these graphic operations.</para>
434735c4bbdfSmrg<para>
434835c4bbdfSmrgThere is a hook in the GC ops, called LineHelper, that used to be used in the
434935c4bbdfSmrgsample implementation by the code for wide lines.  It no longer servers any
435035c4bbdfSmrgpurpose in the sample servers, but still exists, #ifdef'ed by NEED_LINEHELPER,
435135c4bbdfSmrgin case someone needs it.</para>
435235c4bbdfSmrg</section>
435335c4bbdfSmrg</section>
435435c4bbdfSmrg<section>
435535c4bbdfSmrg  <title>Pixblit Procedures</title>
435635c4bbdfSmrg<para>
435735c4bbdfSmrgThe Drawing Primitive functions must be defined for your server.
435835c4bbdfSmrgOne possible way to do this is to use the mi routines from the sample server.
435935c4bbdfSmrgIf you choose to use the mi routines (even part of them!) you must implement
436035c4bbdfSmrgthese Pixblit routines.
436135c4bbdfSmrgThese routines read and write pixel values
436235c4bbdfSmrgand deal directly with the image data.</para>
436335c4bbdfSmrg<para>
436435c4bbdfSmrgThe Pixblit routines for the sample server are part of the "fb"
436535c4bbdfSmrgroutines.  As with the mi routines, the fb routines are
436635c4bbdfSmrgportable but are not as portable as the mi routines.</para>
436735c4bbdfSmrg<para>
436835c4bbdfSmrgThe fb subsystem is a depth-independent framebuffer core, capable of
436935c4bbdfSmrgoperating at any depth from 1 to 32, based on the depth of the window
437035c4bbdfSmrgor pixmap it is currently operating on.  In particular, this means it
437135c4bbdfSmrgcan support pixmaps of multiple depths on the same screen.  It supplies
437235c4bbdfSmrgboth Pixblit routines and higher-level optimized implementations of the
437335c4bbdfSmrgDrawing Primitive routines.  It does make the assumption that the pixel
437435c4bbdfSmrgdata it touches is available in the server's address space.</para>
437535c4bbdfSmrg<para>
437635c4bbdfSmrgIn other words, if you have a "normal" frame buffer type display, you
437735c4bbdfSmrgcan probably use the fb code, and the mi code.  If you
437835c4bbdfSmrghave a stranger hardware, you will have to supply your own Pixblit
437935c4bbdfSmrgroutines, but you can use the mi routines on top of them.  If you have
438035c4bbdfSmrgbetter ways of doing some of the Drawing Primitive functions, then you
438135c4bbdfSmrgmay want to supply some of your own Drawing Primitive routines.  (Even
438235c4bbdfSmrgpeople who write their own Drawing Primitives save at least some of
438335c4bbdfSmrgthe mi code for certain special cases that their hardware or library
438435c4bbdfSmrgor fancy algorithm does not handle.)</para>
438535c4bbdfSmrg<para>
438635c4bbdfSmrgThe client, DIX, and the machine-independent routines do not carry the
438735c4bbdfSmrgfinal responsibility of clipping.  They all depend upon the Pixblit
438835c4bbdfSmrgroutines to do their clipping for them.  The rule is, if you touch the
438935c4bbdfSmrgframe buffer, you clip.</para>
439035c4bbdfSmrg<para>
439135c4bbdfSmrg(The higher level routines may decide to clip at a high level, but
439235c4bbdfSmrgthis is only for increased performance and cannot substitute for
439335c4bbdfSmrgbottom-level clipping.  For instance, the mi routines, DIX, or the
439435c4bbdfSmrgclient may decide to check all character strings to be drawn and chop
439535c4bbdfSmrgoff all characters that would not be displayed.  If so, it must retain
439635c4bbdfSmrgthe character on the edge that is partly displayed so that the Pixblit
439735c4bbdfSmrgroutines can clip off precisely at the right place.)</para>
439835c4bbdfSmrg<para>
439935c4bbdfSmrgTo make this easier, all of the reasons to clip can be combined into
440035c4bbdfSmrgone region in your ValidateGC procedure.  You take this composite clip
440135c4bbdfSmrgregion with you into the Pixblit routines.  (The sample server does
440235c4bbdfSmrgthis.)</para>
440335c4bbdfSmrg<para>
440435c4bbdfSmrgAlso, FillSpans() has to apply tile and stipple patterns.  The
440535c4bbdfSmrgpatterns are all aligned to the window origin so that when two people
440635c4bbdfSmrgwrite patches that are contiguous, they will merge nicely.  (Really,
440735c4bbdfSmrgthey are aligned to the patOrg point in the GC.  This defaults to (0,
440835c4bbdfSmrg0) but can be set by the client to anything.)</para>
440935c4bbdfSmrg<para>
441035c4bbdfSmrgHowever, the mi routines can translate (relocate) the points from
441135c4bbdfSmrgwindow-relative to screen-relative if desired.  If you set the
441235c4bbdfSmrgmiTranslate field in the GC (set it in the CreateGC or ValidateGC
441335c4bbdfSmrgroutine), then the mi output routines will translate all coordinates.
441435c4bbdfSmrgIf it is false, then the coordinates will be passed window-relative.
441535c4bbdfSmrgScreens with no hardware translation will probably set miTranslate to
441635c4bbdfSmrgTRUE, so that geometry (e.g. polygons, rectangles) can be translated,
441735c4bbdfSmrgrather than having the resulting list of scanlines translated; this is
441835c4bbdfSmrggood because the list vertices in a drawing request will generally be
441935c4bbdfSmrgmuch smaller than the list of scanlines it produces.  Similarly,
442035c4bbdfSmrghardware that does translation can set miTranslate to FALSE, and avoid
442135c4bbdfSmrgthe extra addition per vertex, which can be (but is not always)
442235c4bbdfSmrgimportant for getting the highest possible performance.  (Contrast the
442335c4bbdfSmrgbehavior of GetSpans, which is not expected to be called as often, and
442435c4bbdfSmrgso has different constraints.)  The miTranslate field is settable in
442535c4bbdfSmrgeach GC, if , for example, you are mixing several kinds of
442635c4bbdfSmrgdestinations (offscreen pixmaps, main memory pixmaps, backing store,
442735c4bbdfSmrgand windows), all of which have different requirements, on one screen.</para>
442835c4bbdfSmrg<para>
442935c4bbdfSmrgAs with other drawing routines, there are fields in the GC to direct
443035c4bbdfSmrghigher code to the correct routine to execute for each function.  In
443135c4bbdfSmrgthis way, you can optimize for special cases, for example, drawing
443235c4bbdfSmrgsolids versus drawing stipples.</para>
443335c4bbdfSmrg<para>
443435c4bbdfSmrgThe Pixblit routines are broken up into three sets.  The Span routines
443535c4bbdfSmrgsimply fill in rows of pixels.  The Glyph routines fill in character
443635c4bbdfSmrgglyphs.  The PushPixels routine is a three-input bitblt for more
443735c4bbdfSmrgsophisticated image creation.</para>
443835c4bbdfSmrg<para>
443935c4bbdfSmrgIt turns out that the Glyph and PushPixels routines actually have a
444035c4bbdfSmrgmachine-independent implementation that depends upon the Span
444135c4bbdfSmrgroutines.  If you are really pressed for time, you can use these
444235c4bbdfSmrgversions, although they are quite slow.</para>
444335c4bbdfSmrg<section>
444435c4bbdfSmrg<title>Span Routines</title>
444535c4bbdfSmrg<para>
444635c4bbdfSmrgFor these routines, all graphic operations have been reduced to "spans."
444735c4bbdfSmrgA span is a horizontal row of pixels.
444835c4bbdfSmrgIf you can design these routines which write into and read from
444935c4bbdfSmrgrows of pixels at a time, you can use the mi routines.</para>
445035c4bbdfSmrg<para>
445135c4bbdfSmrgEach routine takes
445235c4bbdfSmrga destination drawable to draw into, a GC to use while drawing,
445335c4bbdfSmrgthe number of spans to do, and two pointers to arrays that indicate the list
445435c4bbdfSmrgof starting points and the list of widths of spans.</para>
445535c4bbdfSmrg<para>
445635c4bbdfSmrg<blockquote><programlisting>
445735c4bbdfSmrg
445835c4bbdfSmrg	void pGC->ops->FillSpans(dst, pGC, nSpans, pPoints, pWidths, sorted)
445935c4bbdfSmrg		DrawablePtr dst;
446035c4bbdfSmrg		GCPtr pGC;
446135c4bbdfSmrg		int nSpans;
446235c4bbdfSmrg		DDXPointPtr pPoints;
446335c4bbdfSmrg		int *pWidths;
446435c4bbdfSmrg		int sorted;
446535c4bbdfSmrg
446635c4bbdfSmrg</programlisting></blockquote>
446735c4bbdfSmrgFillSpans should fill horizontal rows of pixels with
446835c4bbdfSmrgthe appropriate patterns, stipples, etc.,
446935c4bbdfSmrgbased on the values in the GC.
447035c4bbdfSmrgThe starting points are in the array at pPoints; the widths are in pWidths.
447135c4bbdfSmrgIf sorted is true, the scan lines are in increasing y order, in which case
447235c4bbdfSmrgyou may be able to make assumptions and optimizations.</para>
447335c4bbdfSmrg<para>
447435c4bbdfSmrgGC components: alu, clipOrg, clientClip, and fillStyle.</para>
447535c4bbdfSmrg<para>
447635c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
447735c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
447835c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
447935c4bbdfSmrg<para>
448035c4bbdfSmrg<blockquote><programlisting>
448135c4bbdfSmrg
448235c4bbdfSmrg	void pGC->ops->SetSpans(pDrawable, pGC, pSrc, ppt, pWidths, nSpans, sorted)
448335c4bbdfSmrg		DrawablePtr pDrawable;
448435c4bbdfSmrg		GCPtr pGC;
448535c4bbdfSmrg		char *pSrc;
448635c4bbdfSmrg		DDXPointPtr pPoints;
448735c4bbdfSmrg		int *pWidths;
448835c4bbdfSmrg		int nSpans;
448935c4bbdfSmrg		int sorted;
449035c4bbdfSmrg
449135c4bbdfSmrg</programlisting></blockquote>
449235c4bbdfSmrgFor each span, this routine should copy pWidths bits from pSrc to
449335c4bbdfSmrgpDrawable at pPoints using the raster-op from the GC.
449435c4bbdfSmrgIf sorted is true, the scan lines are in increasing y order.
449535c4bbdfSmrgThe pixels in pSrc are
449635c4bbdfSmrgpadded according to the screen's padding rules.
449735c4bbdfSmrgThese
449835c4bbdfSmrgcan be used to support
449935c4bbdfSmrginteresting extension libraries, for example, shaded primitives.   It does not
450035c4bbdfSmrguse the tile and stipple.</para>
450135c4bbdfSmrg<para>
450235c4bbdfSmrgGC components: alu, clipOrg, and clientClip</para>
450335c4bbdfSmrg<para>
450435c4bbdfSmrgThe above functions are expected to handle all modifiers in the current
450535c4bbdfSmrgGC.  Therefore, it is expedient to have
450635c4bbdfSmrgdifferent routines to quickly handle common special cases
450735c4bbdfSmrgand reload the procedure pointers
450835c4bbdfSmrgat validate time, as with the other output functions.</para>
450935c4bbdfSmrg<para>
451035c4bbdfSmrg<blockquote><programlisting>
451135c4bbdfSmrg
451235c4bbdfSmrg	void pScreen->GetSpans(pDrawable, wMax, pPoints, pWidths, nSpans)
451335c4bbdfSmrg		DrawablePtr pDrawable;
451435c4bbdfSmrg		int wMax;
451535c4bbdfSmrg		DDXPointPtr pPoints;
451635c4bbdfSmrg		int *pWidths;
451735c4bbdfSmrg		int nSpans;
451835c4bbdfSmrg		char *pDst;
451935c4bbdfSmrg
452035c4bbdfSmrg</programlisting></blockquote>
452135c4bbdfSmrgFor each span, GetSpans gets bits from the drawable starting at pPoints
452235c4bbdfSmrgand continuing for pWidths bits.
452335c4bbdfSmrgEach scanline returned will be server-scanline padded.
452435c4bbdfSmrgThe routine can return NULL if memory cannot be allocated to hold the
452535c4bbdfSmrgresult.</para>
452635c4bbdfSmrg<para>
452735c4bbdfSmrgGetSpans never translates -- for a window, the coordinates are already
452835c4bbdfSmrgscreen-relative.  Consider the case of hardware that doesn't do
452935c4bbdfSmrgtranslation: the mi code that calls ddX will translate each shape
453035c4bbdfSmrg(rectangle, polygon,. etc.) before scan-converting it, which requires
453135c4bbdfSmrgmany fewer additions that having GetSpans translate each span does.
453235c4bbdfSmrgConversely, consider hardware that does translate: it can set its
453335c4bbdfSmrgtranslation point to (0, 0) and get each span, and the only penalty is
453435c4bbdfSmrgthe small number of additions required to translate each shape being
453535c4bbdfSmrgscan-converted by the calling code.  Contrast the behavior of
453635c4bbdfSmrgFillSpans and SetSpans (discussed above under miTranslate), which are
453735c4bbdfSmrgexpected to be used more often.</para>
453835c4bbdfSmrg<para>
453935c4bbdfSmrgThus, the penalty to hardware that does hardware translation is
454035c4bbdfSmrgnegligible, and code that wants to call GetSpans() is greatly
454135c4bbdfSmrgsimplified, both for extensions and the machine-independent core
454235c4bbdfSmrgimplementation.</para>
454335c4bbdfSmrg<section>
454435c4bbdfSmrg  <title>Glyph Routines</title>
454535c4bbdfSmrg<para>
454635c4bbdfSmrgThe Glyph routines draw individual character glyphs for text drawing requests.</para>
454735c4bbdfSmrg<para>
454835c4bbdfSmrgYou have a choice in implementing these routines.  You can use the mi
454935c4bbdfSmrgversions; they depend ultimately upon the span routines.  Although
455035c4bbdfSmrgtext drawing will work, it will be very slow.</para>
455135c4bbdfSmrg<para>
455235c4bbdfSmrg<blockquote><programlisting>
455335c4bbdfSmrg
455435c4bbdfSmrg	void pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
455535c4bbdfSmrg		DrawablePtr pDrawable;
455635c4bbdfSmrg		GCPtr pGC;
455735c4bbdfSmrg		int x , y;
455835c4bbdfSmrg		unsigned int nglyph;
455935c4bbdfSmrg		CharInfoRec **ppci;		/* array of character info */
456035c4bbdfSmrg		pointer unused;			/* unused since R5 */
456135c4bbdfSmrg
456235c4bbdfSmrg</programlisting></blockquote>
456335c4bbdfSmrgGC components: alu, clipOrg, clientClip, font, and fillStyle.</para>
456435c4bbdfSmrg<para>
456535c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
456635c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
456735c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
456835c4bbdfSmrg<para>
456935c4bbdfSmrg<blockquote><programlisting>
457035c4bbdfSmrg
457135c4bbdfSmrg	void pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
457235c4bbdfSmrg		DrawablePtr pDrawable;
457335c4bbdfSmrg		GCPtr pGC;
457435c4bbdfSmrg		int x , y;
457535c4bbdfSmrg		unsigned int nglyph;
457635c4bbdfSmrg		CharInfoRec **ppci;	/* array of character info */
457735c4bbdfSmrg		pointer unused;		/* unused since R5 */
457835c4bbdfSmrg
457935c4bbdfSmrg</programlisting></blockquote>
458035c4bbdfSmrgGC components: clipOrg, clientClip, font, fgPixel, bgPixel</para>
458135c4bbdfSmrg<para>
458235c4bbdfSmrgThese routines must copy the glyphs defined by the bitmaps in
458335c4bbdfSmrgpglyphBase and the font metrics in ppci to the DrawablePtr, pDrawable.
458435c4bbdfSmrgThe poly routine follows all fill, stipple, and tile rules.  The image
458535c4bbdfSmrgroutine simply blasts the glyph onto the glyph's rectangle, in
458635c4bbdfSmrgforeground and background colors.</para>
458735c4bbdfSmrg<para>
458835c4bbdfSmrgMore precisely, the Image routine fills the character rectangle with
458935c4bbdfSmrgthe background color, and then the glyph is applied in the foreground
459035c4bbdfSmrgcolor.  The glyph can extend outside of the character rectangle.
459135c4bbdfSmrgImageGlyph() is used for terminal emulators and informal text purposes
459235c4bbdfSmrgsuch as button labels.</para>
459335c4bbdfSmrg<para>
459435c4bbdfSmrgThe exact specification for the Poly routine is that the glyph is
459535c4bbdfSmrgpainted with the current fill style.  The character rectangle is
459635c4bbdfSmrgirrelevant for this operation.  PolyText, at a higher level, includes
459735c4bbdfSmrgfacilities for font changes within strings and such; it is to be used
459835c4bbdfSmrgfor WYSIWYG word processing and similar systems.</para>
459935c4bbdfSmrg<para>
460035c4bbdfSmrgBoth of these routines must clip themselves to the overall clipping region.</para>
460135c4bbdfSmrg<para>
460235c4bbdfSmrgExample implementations in mi are miPolyGlyphBlt() and
460335c4bbdfSmrgmiImageGlyphBlt() in Xserver/mi/miglblt.c.</para>
460435c4bbdfSmrg</section>
460535c4bbdfSmrg<section>
460635c4bbdfSmrg<title>PushPixels routine</title>
460735c4bbdfSmrg<para>
460835c4bbdfSmrgThe PushPixels routine writes the current fill style onto the drawable
460935c4bbdfSmrgin a certain shape defined by a bitmap.  PushPixels is equivalent to
461035c4bbdfSmrgusing a second stipple.  You can thing of it as pushing the fillStyle
461135c4bbdfSmrgthrough a stencil.  PushPixels is not used by any of the mi rendering code,
461235c4bbdfSmrgbut is used by the mi software cursor code.
461335c4bbdfSmrg<blockquote><para>
461435c4bbdfSmrg	Suppose the stencil is:	00111100
461535c4bbdfSmrg	and the stipple is:	10101010
461635c4bbdfSmrg	PushPixels result:	00101000
461735c4bbdfSmrg</para></blockquote>
461835c4bbdfSmrg</para>
461935c4bbdfSmrg<para>
462035c4bbdfSmrgYou have a choice in implementing this routine.
462135c4bbdfSmrgYou can use the mi version which depends ultimately upon FillSpans().
462235c4bbdfSmrgAlthough it will work, it will be slow.</para>
462335c4bbdfSmrg<para>
462435c4bbdfSmrg<blockquote><programlisting>
462535c4bbdfSmrg
462635c4bbdfSmrg	void pGC->ops->PushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
462735c4bbdfSmrg		GCPtr pGC;
462835c4bbdfSmrg		PixmapPtr pBitMap;
462935c4bbdfSmrg		DrawablePtr pDrawable;
463035c4bbdfSmrg		int dx, dy, xOrg, yOrg;
463135c4bbdfSmrg
463235c4bbdfSmrg</programlisting></blockquote>
463335c4bbdfSmrgGC components: alu, clipOrg, clientClip, and fillStyle.</para>
463435c4bbdfSmrg<para>
463535c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
463635c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
463735c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
463835c4bbdfSmrg<para>
463935c4bbdfSmrgPushPixels applys the foreground color, tile, or stipple from the pGC
464035c4bbdfSmrgthrough a stencil onto pDrawable.  pBitMap points to a stencil (of
464135c4bbdfSmrgwhich we use an area dx wide by dy high), which is oriented over the
464235c4bbdfSmrgdrawable at xOrg, yOrg.  Where there is a 1 bit in the bitmap, the
464335c4bbdfSmrgdestination is set according to the current fill style.  Where there
464435c4bbdfSmrgis a 0 bit in the bitmap, the destination is left the way it is.</para>
464535c4bbdfSmrg<para>
464635c4bbdfSmrgThis routine must clip to the overall clipping region.</para>
464735c4bbdfSmrg<para>
464835c4bbdfSmrgAn Example implementation is miPushPixels() in Xserver/mi/mipushpxl.c.</para>
464935c4bbdfSmrg</section>
465035c4bbdfSmrg</section>
465135c4bbdfSmrg</section>
465235c4bbdfSmrg<section>
465335c4bbdfSmrg  <title>Shutdown Procedures</title>
465435c4bbdfSmrg<para>
465535c4bbdfSmrg<blockquote><programlisting>
465635c4bbdfSmrg	void AbortDDX(enum ExitCode error)
465735c4bbdfSmrg	void ddxGiveUp(enum ExitCode error)
465835c4bbdfSmrg</programlisting></blockquote>
465935c4bbdfSmrgSome hardware may require special work to be done before the server
466035c4bbdfSmrgexits so that it is not left in an intermediate state.  As explained
466135c4bbdfSmrgin the OS layer, FatalError() will call AbortDDX() just before
466235c4bbdfSmrgterminating the server.  In addition, ddxGiveUp() will be called just
466335c4bbdfSmrgbefore terminating the server on a "clean" death.  What AbortDDX() and
466435c4bbdfSmrgddxGiveUP do is left unspecified, only that stubs must exist in the
466535c4bbdfSmrgddx layer.  It is up to local implementors as to what they should
466635c4bbdfSmrgaccomplish before termination.</para>
466735c4bbdfSmrg<section>
466835c4bbdfSmrg  <title>Command Line Procedures</title>
466935c4bbdfSmrg<para>
467035c4bbdfSmrg<blockquote><programlisting>
467135c4bbdfSmrg	int ddxProcessArgument(argc, argv, i)
467235c4bbdfSmrg	    int argc;
467335c4bbdfSmrg	    char *argv[];
467435c4bbdfSmrg	    int i;
467535c4bbdfSmrg
467635c4bbdfSmrg	void
467735c4bbdfSmrg	ddxUseMsg()
467835c4bbdfSmrg
467935c4bbdfSmrg</programlisting></blockquote>
468035c4bbdfSmrgYou should write these routines to deal with device-dependent command line
468135c4bbdfSmrgarguments.  The routine ddxProcessArgument() is called with the command line,
468235c4bbdfSmrgand the current index into argv; you should return zero if the argument
468335c4bbdfSmrgis not a device-dependent one, and otherwise return a count of the number
468435c4bbdfSmrgof elements of argv that are part of this one argument.  For a typical
468535c4bbdfSmrgoption (e.g., "-realtime"), you should return the value one.  This
468635c4bbdfSmrgroutine gets called before checks are made against device-independent
468735c4bbdfSmrgarguments, so it is possible to peek at all arguments or to override
468835c4bbdfSmrgdevice-independent argument processing.  You can document the
468935c4bbdfSmrgdevice-dependent arguments in ddxUseMsg(), which will be
469035c4bbdfSmrgcalled from UseMsg() after printing out the device-independent arguments.</para>
469135c4bbdfSmrg</section>
469235c4bbdfSmrg</section>
469335c4bbdfSmrg<section id="wrappers_and_privates">
469435c4bbdfSmrg  <title>Wrappers and Privates</title>
469535c4bbdfSmrg<para>
469635c4bbdfSmrgTwo new extensibility concepts have been developed for release 4, Wrappers
469735c4bbdfSmrgand devPrivates.  These replace the R3 GCInterest queues, which were not a
469835c4bbdfSmrggeneral enough mechanism for many extensions and only provided hooks into a
469935c4bbdfSmrgsingle data structure.  devPrivates have been revised substantially for
470035c4bbdfSmrgX.Org X server release 1.5, updated again for the 1.9 release and extended
470135c4bbdfSmrgagain for the 1.13 relealse.</para>
470235c4bbdfSmrg<section>
470335c4bbdfSmrg  <title>devPrivates</title>
470435c4bbdfSmrg<para>
470535c4bbdfSmrgdevPrivates provides a way to attach arbitrary private data to various server structures.
470635c4bbdfSmrgAny structure which contains a <structfield>devPrivates</structfield> field of
470735c4bbdfSmrgtype <type>PrivateRec</type> supports this mechanism.  Some structures allow
470835c4bbdfSmrgallocating space for private data after some objects have been created, others
470935c4bbdfSmrgrequire all space allocations be registered before any objects of that type
471035c4bbdfSmrgare created.  <filename class="headerfile">Xserver/include/privates.h</filename>
471135c4bbdfSmrglists which of these cases applies to each structure containing
471235c4bbdfSmrg<structfield>devPrivates</structfield>.</para>
471335c4bbdfSmrg
471435c4bbdfSmrg<para>
471535c4bbdfSmrgTo request private space, use
471635c4bbdfSmrg<blockquote><programlisting>
471735c4bbdfSmrg	Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
471835c4bbdfSmrg</programlisting></blockquote>
471935c4bbdfSmrgThe first argument is a pointer to a <type>DevPrivateKeyRec</type> which
472035c4bbdfSmrgwill serve as the unique identifier for the private data.  Typically this is
472135c4bbdfSmrgthe address of a static <type>DevPrivateKeyRec</type> in your code.
472235c4bbdfSmrgThe second argument is the class of objects for which this key will apply.
472335c4bbdfSmrgThe third argument is the size of the space being requested, or
472435c4bbdfSmrg<constant>0</constant> to only allocate a pointer that the caller will manage.
472535c4bbdfSmrgIf space is requested, this space will be automatically freed when the object
472635c4bbdfSmrgis destroyed.  Note that a call to <function>dixSetPrivate</function>
472735c4bbdfSmrgthat changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
472835c4bbdfSmrgThe function returns <literal>TRUE</literal> unless memory allocation fails.
472935c4bbdfSmrgIf the function is called more than once on the same key, all calls must use
473035c4bbdfSmrgthe same value for <type>size</type> or the server will abort.</para>
473135c4bbdfSmrg
473235c4bbdfSmrg<para>
473335c4bbdfSmrgTo request per-screen private space in an object, use
473435c4bbdfSmrg<blockquote><programlisting>
473535c4bbdfSmrg	Bool dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
473635c4bbdfSmrg</programlisting></blockquote>
473735c4bbdfSmrgThe <parameter>type</parameter> and <parameter>size</parameter> arguments are
473835c4bbdfSmrgthe same as those to <function>dixRegisterPrivateKey</function> but this
473935c4bbdfSmrgfunction ensures the given <parameter>key</parameter> exists on objects of
474035c4bbdfSmrgthe specified type with distinct storage for the given
474135c4bbdfSmrg<parameter>pScreen</parameter>. The key is usable on ScreenPrivate variants
474235c4bbdfSmrgthat are otherwise equivalent to the following Private functions.</para>
474335c4bbdfSmrg
474435c4bbdfSmrg<para>
474535c4bbdfSmrg  To request private space in objects created for a specific screen, use
474635c4bbdfSmrg  <blockquote><programlisting>
474735c4bbdfSmrg    Bool dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, DevPrivateType type, unsigned size);
474835c4bbdfSmrg  </programlisting></blockquote>
474935c4bbdfSmrg  The <parameter>type</parameter> and <parameter>size</parameter> arguments are
475035c4bbdfSmrg  the same as those to <function>dixRegisterPrivateKey</function> but this
475135c4bbdfSmrg  function ensures only that the given <parameter>key</parameter> exists on objects of
475235c4bbdfSmrg  the specified type that are allocated with reference to the specified
475335c4bbdfSmrg  <parameter>pScreen</parameter>. Using the key on objects allocated for
475435c4bbdfSmrg  other screens will result in incorrect results; there is no check made to
475535c4bbdfSmrg  ensure that the caller's screen matches the private's screen. The key is
475635c4bbdfSmrg  usable in any of the following functions. Screen-specific private storage is available
475735c4bbdfSmrg  only for Windows, GCs, Pixmaps and Pictures. Attempts to allocate screen-specific
475835c4bbdfSmrg  privates on other objects will result in a call to FatalError.
475935c4bbdfSmrg</para>
476035c4bbdfSmrg
476135c4bbdfSmrg<para>
476235c4bbdfSmrgTo attach a piece of private data to an object, use:
476335c4bbdfSmrg<blockquote><programlisting>
476435c4bbdfSmrg	void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
476535c4bbdfSmrg</programlisting></blockquote>
476635c4bbdfSmrgThe first argument is the address of the <structfield>devPrivates</structfield>
476735c4bbdfSmrgfield in the target structure.  This field is managed privately by the DIX
476835c4bbdfSmrglayer and should not be directly modified.  The second argument is a pointer
476935c4bbdfSmrgto the <type>DevPrivateKeyRec</type> which you registered with
477035c4bbdfSmrg<function>dixRegisterPrivateKey</function> or allocated with
477135c4bbdfSmrg<function>dixCreatePrivateKey</function>.  Only one
477235c4bbdfSmrgpiece of data with a given key can be attached to an object, and in most cases
477335c4bbdfSmrgeach key is specific to the type of object it was registered for.   (An
477435c4bbdfSmrgexception is the PRIVATE_XSELINUX class which applies to multiple object types.)
477535c4bbdfSmrgThe third argument is the value to store.</para>
477635c4bbdfSmrg<para>
477735c4bbdfSmrgIf private data with the given key is already associated with the object,
477835c4bbdfSmrg<function>dixSetPrivate</function> will overwrite the old value with the
477935c4bbdfSmrgnew one.</para>
478035c4bbdfSmrg
478135c4bbdfSmrg<para>
478235c4bbdfSmrgTo look up a piece of private data, use one of:
478335c4bbdfSmrg<blockquote><programlisting>
478435c4bbdfSmrg	pointer dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
478535c4bbdfSmrg	pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
478635c4bbdfSmrg</programlisting></blockquote>
478735c4bbdfSmrgThe first argument is the address of the <structfield>devPrivates</structfield> field
478835c4bbdfSmrgin the target structure.  The second argument is the key to look up.
478935c4bbdfSmrgIf a non-zero size was given when the key was registered, or if private data
479035c4bbdfSmrgwith the given key is already associated with the object, then
479135c4bbdfSmrg<function>dixLookupPrivate</function> will return the pointer value
479235c4bbdfSmrgwhile <function>dixLookupPrivateAddr</function>
479335c4bbdfSmrgwill return the address of the pointer.</para>
479435c4bbdfSmrg
479535c4bbdfSmrg<para>
479635c4bbdfSmrgWhen implementing new server resource objects that support devPrivates, there
479735c4bbdfSmrgare four steps to perform:
479835c4bbdfSmrgAdd a type value to the <type>DevPrivateType</type> enum in
479935c4bbdfSmrg<filename class="headerfile">Xserver/include/privates.h</filename>,
480035c4bbdfSmrgdeclare a field of type <type>PrivateRec *</type> in your structure;
480135c4bbdfSmrginitialize this field to <literal>NULL</literal> when creating any objects; and
480235c4bbdfSmrgwhen freeing any objects call the <function>dixFreePrivates</function> or
480335c4bbdfSmrg<function>dixFreeObjectWithPrivates</function> function.</para>
480435c4bbdfSmrg</section>
480535c4bbdfSmrg<section>
480635c4bbdfSmrg  <title>Wrappers</title>
480735c4bbdfSmrg<para>
480835c4bbdfSmrgWrappers are not a body of code, nor an interface spec.  They are, instead,
480935c4bbdfSmrga technique for hooking a new module into an existing calling sequence.
481035c4bbdfSmrgThere are limitations on other portions of the server implementation which
481135c4bbdfSmrgmake using wrappers possible; limits on when specific fields of data
481235c4bbdfSmrgstructures may be modified.  They are intended as a replacement for
481335c4bbdfSmrgGCInterest queues, which were not general enough to support existing
481435c4bbdfSmrgmodules; in particular software cursors needed more
481535c4bbdfSmrgcontrol over the activity.  The general mechanism for using wrappers is:
481635c4bbdfSmrg<blockquote><programlisting>
481735c4bbdfSmrgprivateWrapperFunction (object, ...)
481835c4bbdfSmrg	ObjectPtr	object;
481935c4bbdfSmrg{
482035c4bbdfSmrg	pre-wrapped-function-stuff ...
482135c4bbdfSmrg
482235c4bbdfSmrg	object->functionVector = dixLookupPrivate(&amp;object->devPrivates, privateKey);
482335c4bbdfSmrg	(*object->functionVector) (object, ...);
482435c4bbdfSmrg	/*
482535c4bbdfSmrg	 * this next line is occasionally required by the rules governing
482635c4bbdfSmrg	 * wrapper functions.  Always using it will not cause problems.
482735c4bbdfSmrg	 * Not using it when necessary can cause severe troubles.
482835c4bbdfSmrg	 */
482935c4bbdfSmrg	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
483035c4bbdfSmrg	object->functionVector = privateWrapperFunction;
483135c4bbdfSmrg
483235c4bbdfSmrg	post-wrapped-function-stuff ...
483335c4bbdfSmrg}
483435c4bbdfSmrg
483535c4bbdfSmrgprivateInitialize (object)
483635c4bbdfSmrg	ObjectPtr	object;
483735c4bbdfSmrg{
483835c4bbdfSmrg	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
483935c4bbdfSmrg	object->functionVector = privateWrapperFunction;
484035c4bbdfSmrg}
484135c4bbdfSmrg</programlisting></blockquote>
484235c4bbdfSmrg</para>
484335c4bbdfSmrg<para>
484435c4bbdfSmrgThus the privateWrapperFunction provides hooks for performing work both
484535c4bbdfSmrgbefore and after the wrapped function has been called; the process of
484635c4bbdfSmrgresetting the functionVector is called "unwrapping" while the process of
484735c4bbdfSmrgfetching the wrapped function and replacing it with the wrapping function
484835c4bbdfSmrgis called "wrapping".  It should be clear that GCInterest queues could
484935c4bbdfSmrgbe emulated using wrappers.  In general, any function vectors contained in
485035c4bbdfSmrgobjects can be wrapped, but only vectors in GCs and Screens have been tested.</para>
485135c4bbdfSmrg<para>
485235c4bbdfSmrgWrapping screen functions is quite easy; each vector is individually
485335c4bbdfSmrgwrapped.  Screen functions are not supposed to change after initialization,
485435c4bbdfSmrgso rewrapping is technically not necessary, but causes no problems.</para>
485535c4bbdfSmrg<para>
485635c4bbdfSmrgWrapping GC functions is a bit more complicated.  GC's have two tables of
485735c4bbdfSmrgfunction vectors, one hanging from gc->ops and the other from gc->funcs, which
485835c4bbdfSmrgshould be initially wrapped from a CreateGC wrapper.  Wrappers should modify
485935c4bbdfSmrgonly table pointers, not the contents of the tables, as they
486035c4bbdfSmrgmay be shared by more than one GC (and, in the case of funcs, are probably
486135c4bbdfSmrgshared by all gcs).  Your func wrappers may change the GC funcs or ops
486235c4bbdfSmrgpointers, and op wrappers may change the GC op pointers but not the funcs.</para>
486335c4bbdfSmrg<para>
486435c4bbdfSmrgThus, the rule for GC wrappings is: wrap the funcs from CreateGC and, in each
486535c4bbdfSmrgfunc wrapper, unwrap the ops and funcs, call down, and re-wrap.  In each op
486635c4bbdfSmrgwrapper, unwrap the ops, call down, and rewrap afterwards.  Note that in
486735c4bbdfSmrgre-wrapping you must save out the pointer you're replacing again.  This way the
486835c4bbdfSmrgchain will be maintained when wrappers adjust the funcs/ops tables they use.</para>
486935c4bbdfSmrg</section>
487035c4bbdfSmrg</section>
487135c4bbdfSmrg<section>
487235c4bbdfSmrg    <title>Work Queue</title>
487335c4bbdfSmrg<para>
487435c4bbdfSmrgTo queue work for execution when all clients are in a stable state (i.e.
487535c4bbdfSmrgjust before calling select() in WaitForSomething), call:
487635c4bbdfSmrg<blockquote><programlisting>
487735c4bbdfSmrg	Bool QueueWorkProc(function,client,closure)
487835c4bbdfSmrg		Bool		(*function)();
487935c4bbdfSmrg		ClientPtr	client;
488035c4bbdfSmrg		pointer		closure;
488135c4bbdfSmrg</programlisting></blockquote>
488235c4bbdfSmrg</para>
488335c4bbdfSmrg<para>
488435c4bbdfSmrgWhen the server is about to suspend itself, the given function will be
488535c4bbdfSmrgexecuted:
488635c4bbdfSmrg<blockquote><programlisting>
488735c4bbdfSmrg	(*function) (client, closure)
488835c4bbdfSmrg</programlisting></blockquote>
488935c4bbdfSmrg</para>
489035c4bbdfSmrg<para>
489135c4bbdfSmrgNeither client nor closure are actually used inside the work queue routines.</para>
489235c4bbdfSmrg</section>
489335c4bbdfSmrg</section>
489435c4bbdfSmrg<section>
489535c4bbdfSmrg  <title>Summary of Routines</title>
489635c4bbdfSmrg<para>
489735c4bbdfSmrgThis is a summary of the routines discussed in this document.
489835c4bbdfSmrgThe procedure names are in alphabetical order.
489935c4bbdfSmrgThe Struct is the structure it is attached to; if blank, this
490035c4bbdfSmrgprocedure is not attached to a struct and must be named as shown.
490135c4bbdfSmrgThe sample server provides implementations in the following
490235c4bbdfSmrgcategories.  Notice that many of the graphics routines have both
490335c4bbdfSmrgmi and fb implementations.</para>
490435c4bbdfSmrg<para>
490535c4bbdfSmrg<itemizedlist>
490635c4bbdfSmrg<listitem><para>dix	portable to all systems; do not attempt to rewrite (Xserver/dix)</para></listitem>
490735c4bbdfSmrg<listitem><para>os	routine provided in Xserver/os or Xserver/include/os.h</para></listitem>
490835c4bbdfSmrg<listitem><para>ddx	frame buffer dependent (examples in Xserver/fb)</para></listitem>
490935c4bbdfSmrg<listitem><para>mi	routine provided in Xserver/mi</para></listitem>
491035c4bbdfSmrg<listitem><para>hd	hardware dependent (examples in many Xserver/hw directories)</para></listitem>
491135c4bbdfSmrg<listitem><para>none	not implemented in sample implementation</para></listitem>
491235c4bbdfSmrg</itemizedlist>
491335c4bbdfSmrg</para>
491435c4bbdfSmrg	<table frame="all" id="routines-1">
491535c4bbdfSmrg	  <title>Server Routines (Page 1)</title>
491635c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
491735c4bbdfSmrg	    <thead>
491835c4bbdfSmrg	      <row>
491935c4bbdfSmrg		<entry>Procedure</entry>
492035c4bbdfSmrg		<entry>Port</entry>
492135c4bbdfSmrg		<entry>Struct</entry>
492235c4bbdfSmrg	      </row>
492335c4bbdfSmrg	    </thead>
492435c4bbdfSmrg	    <tbody>
492535c4bbdfSmrg<row><entry><function>ALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
492635c4bbdfSmrg<row><entry><function>AbortDDX</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
492735c4bbdfSmrg<row><entry><function>AddCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
492835c4bbdfSmrg<row><entry><function>AddEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
492935c4bbdfSmrg<row><entry><function>AddInputDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
493035c4bbdfSmrg<row><entry><function>AddScreen</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
493135c4bbdfSmrg<row><entry><function>AdjustWaitForDelay</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
493235c4bbdfSmrg<row><entry><function>Bell</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
493335c4bbdfSmrg<row><entry><function>ChangeClip</function></entry><entry><literal>mi</literal></entry><entry><para>GC func</para></entry></row>
493435c4bbdfSmrg<row><entry><function>ChangeGC</function></entry><entry><literal></literal></entry><entry><para>GC func</para></entry></row>
493535c4bbdfSmrg<row><entry><function>ChangeWindowAttributes</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
493635c4bbdfSmrg<row><entry><function>ClearToBackground</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
493735c4bbdfSmrg<row><entry><function>ClientAuthorized</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
493835c4bbdfSmrg<row><entry><function>ClientSignal</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
493935c4bbdfSmrg<row><entry><function>ClientSleep</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
494035c4bbdfSmrg<row><entry><function>ClientWakeup</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
494135c4bbdfSmrg<row><entry><function>ClipNotify</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
494235c4bbdfSmrg<row><entry><function>CloseScreen</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
494335c4bbdfSmrg<row><entry><function>ConstrainCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
494435c4bbdfSmrg<row><entry><function>CopyArea</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
494535c4bbdfSmrg<row><entry><function>CopyGCDest</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
494635c4bbdfSmrg<row><entry><function>CopyGCSource</function></entry><entry><literal>none</literal></entry><entry><para>GC func</para></entry></row>
494735c4bbdfSmrg<row><entry><function>CopyPlane</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
494835c4bbdfSmrg<row><entry><function>CopyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
494935c4bbdfSmrg<row><entry><function>CreateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
495035c4bbdfSmrg<row><entry><function>CreateCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
495135c4bbdfSmrg<row><entry><function>CreatePixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
495235c4bbdfSmrg<row><entry><function>CreateScreenResources</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
495335c4bbdfSmrg<row><entry><function>CreateWellKnowSockets</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495435c4bbdfSmrg<row><entry><function>CreateWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
495535c4bbdfSmrg<row><entry><function>CursorLimits</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
495635c4bbdfSmrg<row><entry><function>DEALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495735c4bbdfSmrg<row><entry><function>DeleteCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
495835c4bbdfSmrg<row><entry><function>DeleteCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
495935c4bbdfSmrg<row><entry><function>DestroyClip</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
496035c4bbdfSmrg<row><entry><function>DestroyGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
496135c4bbdfSmrg<row><entry><function>DestroyPixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
496235c4bbdfSmrg<row><entry><function>DestroyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
496335c4bbdfSmrg<row><entry><function>DisplayCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
496435c4bbdfSmrg<row><entry><function>Error</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
496535c4bbdfSmrg<row><entry><function>ErrorF</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
496635c4bbdfSmrg<row><entry><function>FatalError</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
496735c4bbdfSmrg<row><entry><function>FillPolygon</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
496835c4bbdfSmrg<row><entry><function>FillSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
496935c4bbdfSmrg<row><entry><function>FlushAllOutput</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
497035c4bbdfSmrg<row><entry><function>FlushIfCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
497135c4bbdfSmrg<row><entry><function>FreeScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
497235c4bbdfSmrg<row><entry><function>GetImage</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
497335c4bbdfSmrg<row><entry><function>GetMotionEvents</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
497435c4bbdfSmrg<row><entry><function>GetScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
497535c4bbdfSmrg<row><entry><function>GetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
497635c4bbdfSmrg<row><entry><function>GetStaticColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
497735c4bbdfSmrg	    </tbody>
497835c4bbdfSmrg	  </tgroup>
497935c4bbdfSmrg	</table>
498035c4bbdfSmrg
498135c4bbdfSmrg	<table frame="all" id="routines-2">
498235c4bbdfSmrg	  <title>Server Routines (Page 2)</title>
498335c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
498435c4bbdfSmrg	    <thead>
498535c4bbdfSmrg	      <row>
498635c4bbdfSmrg		<entry>Procedure</entry>
498735c4bbdfSmrg		<entry>Port</entry>
498835c4bbdfSmrg		<entry>Struct</entry>
498935c4bbdfSmrg	      </row>
499035c4bbdfSmrg	    </thead>
499135c4bbdfSmrg	    <tbody>
499235c4bbdfSmrg<row><entry><function>ImageGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
499335c4bbdfSmrg<row><entry><function>ImageText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
499435c4bbdfSmrg<row><entry><function>ImageText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
499535c4bbdfSmrg<row><entry><function>InitInput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
499635c4bbdfSmrg<row><entry><function>InitKeyboardDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
499735c4bbdfSmrg<row><entry><function>InitOutput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
499835c4bbdfSmrg<row><entry><function>InitPointerDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
499935c4bbdfSmrg<row><entry><function>InsertFakeRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
500035c4bbdfSmrg<row><entry><function>InstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
500135c4bbdfSmrg<row><entry><function>Intersect</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
500235c4bbdfSmrg<row><entry><function>Inverse</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
500335c4bbdfSmrg<row><entry><function>LegalModifier</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
500435c4bbdfSmrg<row><entry><function>LineHelper</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500535c4bbdfSmrg<row><entry><function>ListInstalledColormaps</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
500635c4bbdfSmrg<row><entry><function>LookupKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
500735c4bbdfSmrg<row><entry><function>LookupPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
500835c4bbdfSmrg<row><entry><function>ModifyPixmapHeader</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
500935c4bbdfSmrg<row><entry><function>NextAvailableClient</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
501035c4bbdfSmrg<row><entry><function>OsInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
501135c4bbdfSmrg<row><entry><function>PaintWindowBackground</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
501235c4bbdfSmrg<row><entry><function>PaintWindowBorder</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
501335c4bbdfSmrg<row><entry><function>PointerNonInterestBox</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
501435c4bbdfSmrg<row><entry><function>PointInRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
501535c4bbdfSmrg<row><entry><function>PolyArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501635c4bbdfSmrg<row><entry><function>PolyFillArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501735c4bbdfSmrg<row><entry><function>PolyFillRect</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501835c4bbdfSmrg<row><entry><function>PolyGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501935c4bbdfSmrg<row><entry><function>Polylines</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502035c4bbdfSmrg<row><entry><function>PolyPoint</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502135c4bbdfSmrg<row><entry><function>PolyRectangle</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502235c4bbdfSmrg<row><entry><function>PolySegment</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502335c4bbdfSmrg<row><entry><function>PolyText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502435c4bbdfSmrg<row><entry><function>PolyText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502535c4bbdfSmrg<row><entry><function>PositionWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
502635c4bbdfSmrg<row><entry><function>ProcessInputEvents</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
502735c4bbdfSmrg<row><entry><function>PushPixels</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502835c4bbdfSmrg<row><entry><function>PutImage</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
502935c4bbdfSmrg<row><entry><function>QueryBestSize</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
503035c4bbdfSmrg<row><entry><function>ReadRequestFromClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
503135c4bbdfSmrg<row><entry><function>RealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
503235c4bbdfSmrg<row><entry><function>RealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
503335c4bbdfSmrg<row><entry><function>RealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
503435c4bbdfSmrg<row><entry><function>RecolorCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
503535c4bbdfSmrg<row><entry><function>RectIn</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
503635c4bbdfSmrg<row><entry><function>RegionCopy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
503735c4bbdfSmrg<row><entry><function>RegionCreate</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
503835c4bbdfSmrg<row><entry><function>RegionDestroy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
503935c4bbdfSmrg<row><entry><function>RegionEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
504035c4bbdfSmrg<row><entry><function>RegionExtents</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
504135c4bbdfSmrg<row><entry><function>RegionNotEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
504235c4bbdfSmrg<row><entry><function>RegionReset</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
504335c4bbdfSmrg<row><entry><function>ResolveColor</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
504435c4bbdfSmrg	    </tbody>
504535c4bbdfSmrg	  </tgroup>
504635c4bbdfSmrg	</table>
504735c4bbdfSmrg
504835c4bbdfSmrg	<table frame="all" id="routines-3">
504935c4bbdfSmrg	  <title>Server Routines (Page 3)</title>
505035c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
505135c4bbdfSmrg	    <thead>
505235c4bbdfSmrg	      <row>
505335c4bbdfSmrg		<entry>Procedure</entry>
505435c4bbdfSmrg		<entry>Port</entry>
505535c4bbdfSmrg		<entry>Struct</entry>
505635c4bbdfSmrg	      </row>
505735c4bbdfSmrg	    </thead>
505835c4bbdfSmrg	    <tbody>
505935c4bbdfSmrg<row><entry><function>RemoveEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
506035c4bbdfSmrg<row><entry><function>ResetCurrentRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
506135c4bbdfSmrg<row><entry><function>SaveScreen</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
506235c4bbdfSmrg<row><entry><function>SetCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
506335c4bbdfSmrg<row><entry><function>SetCursorPosition</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
506435c4bbdfSmrg<row><entry><function>SetInputCheck</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
506535c4bbdfSmrg<row><entry><function>SetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
506635c4bbdfSmrg<row><entry><function>StoreColors</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
506735c4bbdfSmrg<row><entry><function>Subtract</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
506835c4bbdfSmrg<row><entry><function>TimerCancel</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
506935c4bbdfSmrg<row><entry><function>TimerCheck</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507035c4bbdfSmrg<row><entry><function>TimerForce</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507135c4bbdfSmrg<row><entry><function>TimerFree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507235c4bbdfSmrg<row><entry><function>TimerInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507335c4bbdfSmrg<row><entry><function>TimerSet</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507435c4bbdfSmrg<row><entry><function>TimeSinceLastInputEvent</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
507535c4bbdfSmrg<row><entry><function>TranslateRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
507635c4bbdfSmrg<row><entry><function>UninstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
507735c4bbdfSmrg<row><entry><function>Union</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
507835c4bbdfSmrg<row><entry><function>UnrealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
507935c4bbdfSmrg<row><entry><function>UnrealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
508035c4bbdfSmrg<row><entry><function>UnrealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
508135c4bbdfSmrg<row><entry><function>ValidateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
508235c4bbdfSmrg<row><entry><function>ValidateTree</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
508335c4bbdfSmrg<row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
508435c4bbdfSmrg<row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
508535c4bbdfSmrg<row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
508635c4bbdfSmrg	    </tbody>
508735c4bbdfSmrg	  </tgroup>
508835c4bbdfSmrg	</table>
508935c4bbdfSmrg</section>
509035c4bbdfSmrg</article>
5091