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.
1241ed6184dfSmrgOn the other hand, if it switches 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
1319ed6184dfSmrgsuch that the server will call ddxGiveUp(EXIT_ERR_ABORT) 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</section>
178635c4bbdfSmrg</section>
178735c4bbdfSmrg<section>
178835c4bbdfSmrg<title>Screens</title>
178935c4bbdfSmrg<para>
179035c4bbdfSmrgDifferent computer graphics
179135c4bbdfSmrgdisplays have different capabilities.
179235c4bbdfSmrgSome are simple monochrome
179335c4bbdfSmrgframe buffers that are just lying
179435c4bbdfSmrgthere in memory, waiting to be written into.
179535c4bbdfSmrgOthers are color displays with many bits per pixel using some color lookup table.
179635c4bbdfSmrgStill others have high-speed graphic processors that prefer to do all of the work
179735c4bbdfSmrgthemselves,
179835c4bbdfSmrgincluding maintaining their own high-level, graphic data structures.
179935c4bbdfSmrg</para>
180035c4bbdfSmrg<section>
180135c4bbdfSmrg  <title>Screen Hardware Requirements</title>
180235c4bbdfSmrg<para>
180335c4bbdfSmrgThe only requirement on screens is that you be able to both read
180435c4bbdfSmrgand write locations in the frame buffer.
180535c4bbdfSmrgAll screens must have a depth of 32 or less (unless you use
180635c4bbdfSmrgan X extension to allow a greater depth).
180735c4bbdfSmrgAll screens must fit into one of the classes listed in the section
180835c4bbdfSmrgin this document on Visuals and Depths.
180935c4bbdfSmrg</para>
181035c4bbdfSmrg<para>
181135c4bbdfSmrgX uses the pixel as its fundamental unit of distance on the screen.
181235c4bbdfSmrgTherefore, most programs will measure everything in pixels.</para>
181335c4bbdfSmrg<para>
181435c4bbdfSmrgThe sample server assumes square pixels.
181535c4bbdfSmrgSerious WYSIWYG (what you see is what you get) applications for
181635c4bbdfSmrgpublishing and drawing programs will adjust for
181735c4bbdfSmrgdifferent screen resolutions automatically.
181835c4bbdfSmrgConsiderable work
181935c4bbdfSmrgis involved in compensating for non-square pixels (a bit in the DDX
182035c4bbdfSmrgcode for the sample server but quite a bit in the client applications).</para>
182135c4bbdfSmrg</section>
182235c4bbdfSmrg<section>
182335c4bbdfSmrg  <title>Data Structures</title>
182435c4bbdfSmrg<para>
182535c4bbdfSmrgX supports multiple screens that are connected to the same
182635c4bbdfSmrgserver.  Therefore, all the per-screen information is bundled into one data
182735c4bbdfSmrgstructure of attributes and procedures, which is the ScreenRec (see
182835c4bbdfSmrgXserver/include/scrnintstr.h).
182935c4bbdfSmrgThe procedure entry points in a ScreenRec operate on
183035c4bbdfSmrgregions, colormaps, cursors, and fonts, because these resources
183135c4bbdfSmrgcan differ in format from one screen to another.</para>
183235c4bbdfSmrg<para>
183335c4bbdfSmrgWindows are areas on the screen that can be drawn into by graphic
183435c4bbdfSmrgroutines.  "Pixmaps" are off-screen graphic areas that can be drawn
183535c4bbdfSmrginto.  They are both considered drawables and are described in the
183635c4bbdfSmrgsection on Drawables.  All graphic operations work on drawables, and
183735c4bbdfSmrgoperations are available to copy patches from one drawable to another.</para>
183835c4bbdfSmrg<para>
183935c4bbdfSmrgThe pixel image data in all drawables is in a format that is private
184035c4bbdfSmrgto DDX.  In fact, each instance of a drawable is associated with a
184135c4bbdfSmrggiven screen.  Presumably, the pixel image data for pixmaps is chosen
184235c4bbdfSmrgto be conveniently understood by the hardware.  All screens in a
184335c4bbdfSmrgsingle server must be able to handle all pixmaps depths declared in
184435c4bbdfSmrgthe connection setup information.</para>
184535c4bbdfSmrg<para>
184635c4bbdfSmrgPixmap images are transferred to the server in one of two ways:
184735c4bbdfSmrgXYPixmap or ZPimap.  XYPixmaps are a series of bitmaps, one for each
184835c4bbdfSmrgbit plane of the image, using the bitmap padding rules from the
184935c4bbdfSmrgconnection setup.  ZPixmaps are a series of bits, nibbles, bytes or
185035c4bbdfSmrgwords, one for each pixel, using the format rules (padding and so on)
185135c4bbdfSmrgfor the appropriate depth.</para>
185235c4bbdfSmrg<para>
185335c4bbdfSmrgAll screens in a given server must agree on a set of pixmap image
185435c4bbdfSmrgformats (PixmapFormat) to support (depth, number of bits per pixel,
185535c4bbdfSmrgetc.).</para>
185635c4bbdfSmrg<para>
185735c4bbdfSmrgThere is no color interpretation of bits in the pixmap.  Pixmaps
185835c4bbdfSmrgdo not contain pixel values.  The interpretation is made only when
185935c4bbdfSmrgthe bits are transferred onto the screen.</para>
186035c4bbdfSmrg<para>
186135c4bbdfSmrgThe screenInfo structure (in scrnintstr.h) is a global data structure
186235c4bbdfSmrgthat has a pointer to an array of ScreenRecs, one for each screen on
186335c4bbdfSmrgthe server.  (These constitute the one and only description of each
186435c4bbdfSmrgscreen in the server.)  Each screen has an identifying index (0, 1, 2, ...).
186535c4bbdfSmrgIn addition, the screenInfo struct contains global server-wide
186635c4bbdfSmrgdetails, such as the bit- and byte- order in all bit images, and the
186735c4bbdfSmrglist of pixmap image formats that are supported.  The X protocol
186835c4bbdfSmrginsists that these must be the same for all screens on the server.</para>
186935c4bbdfSmrg</section>
187035c4bbdfSmrg<section>
187135c4bbdfSmrg  <title>Output Initialization</title>
187235c4bbdfSmrg<para>
187335c4bbdfSmrg<blockquote><programlisting>
187435c4bbdfSmrg
187535c4bbdfSmrg	InitOutput(pScreenInfo, argc, argv)
187635c4bbdfSmrg		ScreenInfo *pScreenInfo;
187735c4bbdfSmrg		int argc;
187835c4bbdfSmrg		char **argv;
187935c4bbdfSmrg</programlisting></blockquote>
188035c4bbdfSmrgUpon initialization, your DDX routine InitOutput() is called by DIX.
188135c4bbdfSmrgIt is passed a pointer to screenInfo to initialize.  It is also passed
188235c4bbdfSmrgthe argc and argv from main() for your server for the command-line
188335c4bbdfSmrgarguments.  These arguments may indicate what or how many screen
188435c4bbdfSmrgdevice(s) to use or in what way to use them.  For instance, your
188535c4bbdfSmrgserver command line may allow a "-D" flag followed by the name of the
188635c4bbdfSmrgscreen device to use.</para>
188735c4bbdfSmrg<para>
188835c4bbdfSmrgYour InitOutput() routine should initialize each screen you wish to
188935c4bbdfSmrguse by calling AddScreen(), and then it should initialize the pixmap
189035c4bbdfSmrgformats that you support by storing values directly into the
189135c4bbdfSmrgscreenInfo data structure.  You should also set certain
189235c4bbdfSmrgimplementation-dependent numbers and procedures in your screenInfo,
189335c4bbdfSmrgwhich determines the pixmap and scanline padding rules for all screens
189435c4bbdfSmrgin the server.</para>
189535c4bbdfSmrg<para>
189635c4bbdfSmrg<blockquote><programlisting>
189735c4bbdfSmrg
189835c4bbdfSmrg	int AddScreen(scrInitProc, argc, argv)
189935c4bbdfSmrg		Bool (*scrInitProc)();
190035c4bbdfSmrg		int argc;
190135c4bbdfSmrg		char **argv;
190235c4bbdfSmrg</programlisting></blockquote>
190335c4bbdfSmrgYou should call AddScreen(), a DIX procedure, in InitOutput() once for
190435c4bbdfSmrgeach screen to add it to the screenInfo database.  The first argument
190535c4bbdfSmrgis an initialization procedure for the screen that you supply.  The
190635c4bbdfSmrgsecond and third are the argc and argv from main().  It returns the
190735c4bbdfSmrgscreen number of the screen installed, or -1 if there is either
190835c4bbdfSmrginsufficient memory to add the screen, or (*scrInitProc) returned
190935c4bbdfSmrgFALSE.</para>
191035c4bbdfSmrg<para>
191135c4bbdfSmrgThe scrInitProc should be of the following form:
191235c4bbdfSmrg<blockquote><programlisting>
191335c4bbdfSmrg
191435c4bbdfSmrg	Bool scrInitProc(pScreen, argc, argv)
191535c4bbdfSmrg		ScreenPtr pScreen;
191635c4bbdfSmrg		int argc;
191735c4bbdfSmrg		char **argv;
191835c4bbdfSmrg</programlisting></blockquote>
191935c4bbdfSmrgpScreen is the pointer to the screen's new ScreenRec. argc and argv
192035c4bbdfSmrgare as before.  Your screen initialize procedure should return TRUE
192135c4bbdfSmrgupon success or FALSE if the screen cannot be initialized (for
192235c4bbdfSmrg instance, if the screen hardware does not exist on this machine).</para>
192335c4bbdfSmrg<para>
192435c4bbdfSmrgThis procedure must determine what actual device it is supposed to initialize.
192535c4bbdfSmrgIf you have a different procedure for each screen, then it is no problem.
192635c4bbdfSmrgIf you have the same procedure for multiple screens, it may have trouble
192735c4bbdfSmrgfiguring out which screen to initialize each time around, especially if
192835c4bbdfSmrgInitOutput() does not initialize all of the screens.
192935c4bbdfSmrgIt is probably easiest to have one procedure for each screen.</para>
193035c4bbdfSmrg<para>
193135c4bbdfSmrgThe initialization procedure should fill in all the screen procedures
193235c4bbdfSmrgfor that screen (windowing functions, region functions, etc.) and certain
193335c4bbdfSmrgscreen attributes for that screen.</para>
193435c4bbdfSmrg</section>
193535c4bbdfSmrg<section>
193635c4bbdfSmrg  <title>Region Routines in the ScreenRec</title>
193735c4bbdfSmrg<para>
193835c4bbdfSmrgA region is a dynamically allocated data structure that describes an
193935c4bbdfSmrgirregularly shaped piece of real estate in XY pixel space.  You can
194035c4bbdfSmrgthink of it as a set of pixels on the screen to be operated upon with
194135c4bbdfSmrgset operations such as AND and OR.</para>
194235c4bbdfSmrg<para>
194335c4bbdfSmrgA region is frequently implemented as a list of rectangles or bitmaps
194435c4bbdfSmrgthat enclose the selected pixels.  Region operators control the
194535c4bbdfSmrg"clipping policy," or the operations that work on regions.  (The
194635c4bbdfSmrgsample server uses YX-banded rectangles.  Unless you have something
194735c4bbdfSmrgalready implemented for your graphics system, you should keep that
194835c4bbdfSmrgimplementation.)  The procedure pointers to the region operators are
194935c4bbdfSmrglocated in the ScreenRec data structure.  The definition of a region
195035c4bbdfSmrgcan be found in the file Xserver/include/regionstr.h.  The region code
195135c4bbdfSmrgis found in Xserver/mi/miregion.c.  DDX implementations using other
195235c4bbdfSmrgregion formats will need to supply different versions of the region
195335c4bbdfSmrgoperators.</para>
195435c4bbdfSmrg<para>
195535c4bbdfSmrgSince the list of rectangles is unbounded in size, part of the region
195635c4bbdfSmrgdata structure is usually a large, dynamically allocated chunk of
195735c4bbdfSmrgmemory.  As your region operators calculate logical combinations of
195835c4bbdfSmrgregions, these blocks may need to be reallocated by your region
195935c4bbdfSmrgsoftware.  For instance, in the sample server, a RegionRec has some
196035c4bbdfSmrgheader information and a pointer to a dynamically allocated rectangle
196135c4bbdfSmrglist.  Periodically, the rectangle list needs to be expanded with
196235c4bbdfSmrgrealloc(), whereupon the new pointer is remembered in the RegionRec.</para>
196335c4bbdfSmrg<para>
196435c4bbdfSmrgMost of the region operations come in two forms: a function pointer in
196535c4bbdfSmrgthe Screen structure, and a macro.  The server can be compiled so that
196635c4bbdfSmrgthe macros make direct calls to the appropriate functions (instead of
196735c4bbdfSmrgindirecting through a screen function pointer), or it can be compiled
196835c4bbdfSmrgso that the macros are identical to the function pointer forms.
196935c4bbdfSmrgMaking direct calls is faster on many architectures.</para>
197035c4bbdfSmrg<para>
197135c4bbdfSmrg<blockquote><programlisting>
197235c4bbdfSmrg
197335c4bbdfSmrg	RegionPtr pScreen->RegionCreate( rect, size)
197435c4bbdfSmrg		BoxPtr rect;
197535c4bbdfSmrg		int size;
197635c4bbdfSmrg
197735c4bbdfSmrg	macro: RegionPtr RegionCreate(rect, size)
197835c4bbdfSmrg
197935c4bbdfSmrg</programlisting></blockquote>
198035c4bbdfSmrgRegionCreate creates a region that describes ONE rectangle.  The
198135c4bbdfSmrgcaller can avoid unnecessary reallocation and copying by declaring the
198235c4bbdfSmrgprobable maximum number of rectangles that this region will need to
198335c4bbdfSmrgdescribe itself.  Your region routines, though, cannot fail just
198435c4bbdfSmrgbecause the region grows beyond this size.  The caller of this routine
198535c4bbdfSmrgcan pass almost anything as the size; the value is merely a good guess
198635c4bbdfSmrgas to the maximum size until it is proven wrong by subsequent use.
198735c4bbdfSmrgYour region procedures are then on their own in estimating how big the
198835c4bbdfSmrgregion will get.  Your implementation might ignore size, if
198935c4bbdfSmrgapplicable.</para>
199035c4bbdfSmrg<para>
199135c4bbdfSmrg<blockquote><programlisting>
199235c4bbdfSmrg
199335c4bbdfSmrg	void pScreen->RegionInit (pRegion, rect, size)
199435c4bbdfSmrg		RegionPtr	pRegion;
199535c4bbdfSmrg		BoxPtr		rect;
199635c4bbdfSmrg		int		size;
199735c4bbdfSmrg
199835c4bbdfSmrg	macro: RegionInit(pRegion, rect, size)
199935c4bbdfSmrg
200035c4bbdfSmrg</programlisting></blockquote>
200135c4bbdfSmrgGiven an existing raw region structure (such as an local variable), this
200235c4bbdfSmrgroutine fills in the appropriate fields to make this region as usable as
200335c4bbdfSmrgone returned from RegionCreate.  This avoids the additional dynamic memory
200435c4bbdfSmrgallocation overhead for the region structure itself.
200535c4bbdfSmrg</para>
200635c4bbdfSmrg<para>
200735c4bbdfSmrg<blockquote><programlisting>
200835c4bbdfSmrg
200935c4bbdfSmrg	Bool pScreen->RegionCopy(dstrgn, srcrgn)
201035c4bbdfSmrg		RegionPtr dstrgn, srcrgn;
201135c4bbdfSmrg
201235c4bbdfSmrg	macro: Bool RegionCopy(dstrgn, srcrgn)
201335c4bbdfSmrg
201435c4bbdfSmrg</programlisting></blockquote>
201535c4bbdfSmrgRegionCopy copies the description of one region, srcrgn, to another
201635c4bbdfSmrgalready-created region,
201735c4bbdfSmrgdstrgn; returning TRUE if the copy succeeded, and FALSE otherwise.</para>
201835c4bbdfSmrg<para>
201935c4bbdfSmrg<blockquote><programlisting>
202035c4bbdfSmrg
202135c4bbdfSmrg	void pScreen->RegionDestroy( pRegion)
202235c4bbdfSmrg		RegionPtr pRegion;
202335c4bbdfSmrg
202435c4bbdfSmrg	macro: RegionDestroy(pRegion)
202535c4bbdfSmrg
202635c4bbdfSmrg</programlisting></blockquote>
202735c4bbdfSmrgRegionDestroy destroys a region and frees all allocated memory.</para>
202835c4bbdfSmrg<para>
202935c4bbdfSmrg<blockquote><programlisting>
203035c4bbdfSmrg
203135c4bbdfSmrg	void pScreen->RegionUninit (pRegion)
203235c4bbdfSmrg		RegionPtr pRegion;
203335c4bbdfSmrg
203435c4bbdfSmrg	macro: RegionUninit(pRegion)
203535c4bbdfSmrg
203635c4bbdfSmrg</programlisting></blockquote>
203735c4bbdfSmrgFrees everything except the region structure itself, useful when the
203835c4bbdfSmrgregion was originally passed to RegionInit instead of received from
203935c4bbdfSmrgRegionCreate.  When this call returns, pRegion must not be reused until
204035c4bbdfSmrgit has been RegionInit'ed again.</para>
204135c4bbdfSmrg<para>
204235c4bbdfSmrg<blockquote><programlisting>
204335c4bbdfSmrg
204435c4bbdfSmrg	Bool pScreen->Intersect(newReg, reg1, reg2)
204535c4bbdfSmrg		RegionPtr newReg, reg1, reg2;
204635c4bbdfSmrg
204735c4bbdfSmrg	macro: Bool RegionIntersect(newReg, reg1, reg2)
204835c4bbdfSmrg
204935c4bbdfSmrg	Bool  pScreen->Union(newReg, reg1, reg2)
205035c4bbdfSmrg		RegionPtr newReg, reg1, reg2;
205135c4bbdfSmrg
205235c4bbdfSmrg	macro: Bool RegionUnion(newReg, reg1, reg2)
205335c4bbdfSmrg
205435c4bbdfSmrg	Bool  pScreen->Subtract(newReg, regMinuend, regSubtrahend)
205535c4bbdfSmrg		RegionPtr newReg, regMinuend, regSubtrahend;
205635c4bbdfSmrg
205735c4bbdfSmrg	macro: Bool RegionUnion(newReg, regMinuend, regSubtrahend)
205835c4bbdfSmrg
205935c4bbdfSmrg	Bool pScreen->Inverse(newReg, pReg,  pBox)
206035c4bbdfSmrg		RegionPtr newReg, pReg;
206135c4bbdfSmrg		BoxPtr pBox;
206235c4bbdfSmrg
206335c4bbdfSmrg	macro: Bool RegionInverse(newReg, pReg,  pBox)
206435c4bbdfSmrg
206535c4bbdfSmrg</programlisting></blockquote>
206635c4bbdfSmrgThe above four calls all do basic logical operations on regions.  They
206735c4bbdfSmrgset the new region (which already exists) to describe the logical
206835c4bbdfSmrgintersection, union, set difference, or inverse of the region(s) that
206935c4bbdfSmrgwere passed in.  Your routines must be able to handle a situation
207035c4bbdfSmrgwhere the newReg is the same region as one of the other region
207135c4bbdfSmrgarguments.</para>
207235c4bbdfSmrg<para>
207335c4bbdfSmrgThe subtract function removes the Subtrahend from the Minuend and
207435c4bbdfSmrgputs the result in newReg.</para>
207535c4bbdfSmrg<para>
207635c4bbdfSmrgThe inverse function returns a region that is the pBox minus the
207735c4bbdfSmrgregion passed in.  (A true "inverse" would make a region that extends
207835c4bbdfSmrgto infinity in all directions but has holes in the middle.)  It is
207935c4bbdfSmrgundefined for situations where the region extends beyond the box.</para>
208035c4bbdfSmrg<para>
208135c4bbdfSmrgEach routine must return the value TRUE for success.</para>
208235c4bbdfSmrg<para>
208335c4bbdfSmrg<blockquote><programlisting>
208435c4bbdfSmrg
208535c4bbdfSmrg	void pScreen->RegionReset(pRegion, pBox)
208635c4bbdfSmrg		RegionPtr pRegion;
208735c4bbdfSmrg		BoxPtr pBox;
208835c4bbdfSmrg
208935c4bbdfSmrg	macro: RegionReset(pRegion, pBox)
209035c4bbdfSmrg
209135c4bbdfSmrg</programlisting></blockquote>
209235c4bbdfSmrgRegionReset sets the region to describe
209335c4bbdfSmrgone rectangle and reallocates it to a size of one rectangle, if applicable.</para>
209435c4bbdfSmrg<para>
209535c4bbdfSmrg<blockquote><programlisting>
209635c4bbdfSmrg
209735c4bbdfSmrg	void  pScreen->TranslateRegion(pRegion, x, y)
209835c4bbdfSmrg		RegionPtr pRegion;
209935c4bbdfSmrg		int x, y;
210035c4bbdfSmrg
210135c4bbdfSmrg	macro: RegionTranslate(pRegion, x, y)
210235c4bbdfSmrg
210335c4bbdfSmrg</programlisting></blockquote>
210435c4bbdfSmrgTranslateRegion simply moves a region +x in the x direction and +y in the y
210535c4bbdfSmrgdirection.</para>
210635c4bbdfSmrg<para>
210735c4bbdfSmrg<blockquote><programlisting>
210835c4bbdfSmrg
210935c4bbdfSmrg	int  pScreen->RectIn(pRegion, pBox)
211035c4bbdfSmrg		RegionPtr pRegion;
211135c4bbdfSmrg		BoxPtr pBox;
211235c4bbdfSmrg
211335c4bbdfSmrg	macro: int RegionContainsRect(pRegion, pBox)
211435c4bbdfSmrg
211535c4bbdfSmrg</programlisting></blockquote>
211635c4bbdfSmrgRectIn returns one of the defined constants rgnIN, rgnOUT, or rgnPART,
211735c4bbdfSmrgdepending upon whether the box is entirely inside the region, entirely
211835c4bbdfSmrgoutside of the region, or partly in and partly out of the region.
211935c4bbdfSmrgThese constants are defined in Xserver/include/region.h.</para>
212035c4bbdfSmrg<para>
212135c4bbdfSmrg<blockquote><programlisting>
212235c4bbdfSmrg
212335c4bbdfSmrg	Bool pScreen->PointInRegion(pRegion, x, y, pBox)
212435c4bbdfSmrg		RegionPtr pRegion;
212535c4bbdfSmrg		int x, y;
212635c4bbdfSmrg		BoxPtr pBox;
212735c4bbdfSmrg
212835c4bbdfSmrg	macro: Bool RegionContainsPoint(pRegion, x, y, pBox)
212935c4bbdfSmrg
213035c4bbdfSmrg</programlisting></blockquote>
213135c4bbdfSmrgPointInRegion returns true if the point x, y is in the region.  In
213235c4bbdfSmrgaddition, it fills the rectangle pBox with coordinates of a rectangle
213335c4bbdfSmrgthat is entirely inside of pRegion and encloses the point.  In the mi
213435c4bbdfSmrgimplementation, it is the largest such rectangle.  (Due to the sample
213535c4bbdfSmrgserver implementation, this comes cheaply.)</para>
213635c4bbdfSmrg<para>
213735c4bbdfSmrgThis routine used by DIX when tracking the pointing device and
213835c4bbdfSmrgdeciding whether to report mouse events or change the cursor.  For
213935c4bbdfSmrginstance, DIX needs to change the cursor when it moves from one window
214035c4bbdfSmrgto another.  Due to overlapping windows, the shape to check may be
214135c4bbdfSmrgirregular.  A PointInRegion() call for every pointing device movement
214235c4bbdfSmrgmay be too expensive.  The pBox is a kind of wake-up box; DIX need not
214335c4bbdfSmrgcall PointInRegion() again until the cursor wanders outside of the
214435c4bbdfSmrgreturned box.</para>
214535c4bbdfSmrg<para>
214635c4bbdfSmrg<blockquote><programlisting>
214735c4bbdfSmrg
214835c4bbdfSmrg	Bool pScreen->RegionNotEmpty(pRegion)
214935c4bbdfSmrg		RegionPtr pRegion;
215035c4bbdfSmrg
215135c4bbdfSmrg	macro: Bool RegionNotEmpty(pRegion)
215235c4bbdfSmrg
215335c4bbdfSmrg</programlisting></blockquote>
215435c4bbdfSmrgRegionNotEmpty is a boolean function that returns
215535c4bbdfSmrgtrue or false depending upon whether the region encloses any pixels.</para>
215635c4bbdfSmrg<para>
215735c4bbdfSmrg<blockquote><programlisting>
215835c4bbdfSmrg
215935c4bbdfSmrg	void pScreen->RegionEmpty(pRegion)
216035c4bbdfSmrg		RegionPtr pRegion;
216135c4bbdfSmrg
216235c4bbdfSmrg	macro: RegionEmpty(pRegion)
216335c4bbdfSmrg
216435c4bbdfSmrg</programlisting></blockquote>
216535c4bbdfSmrgRegionEmpty sets the region to be empty.</para>
216635c4bbdfSmrg<para>
216735c4bbdfSmrg<blockquote><programlisting>
216835c4bbdfSmrg
216935c4bbdfSmrg	BoxPtr pScreen->RegionExtents(pRegion)
217035c4bbdfSmrg		RegionPtr pRegion;
217135c4bbdfSmrg
217235c4bbdfSmrg	macro: RegionExtents(pRegion)
217335c4bbdfSmrg
217435c4bbdfSmrg</programlisting></blockquote>
217535c4bbdfSmrgRegionExtents returns a rectangle that is the smallest
217635c4bbdfSmrgpossible superset of the entire region.
217735c4bbdfSmrgThe caller will not modify this rectangle, so it can be the one
217835c4bbdfSmrgin your region struct.</para>
217935c4bbdfSmrg<para>
218035c4bbdfSmrg<blockquote><programlisting>
218135c4bbdfSmrg
218235c4bbdfSmrg	Bool pScreen->RegionAppend (pDstRgn, pRegion)
218335c4bbdfSmrg		RegionPtr pDstRgn;
218435c4bbdfSmrg		RegionPtr pRegion;
218535c4bbdfSmrg
218635c4bbdfSmrg	macro: Bool RegionAppend(pDstRgn, pRegion)
218735c4bbdfSmrg
218835c4bbdfSmrg	Bool pScreen->RegionValidate (pRegion, pOverlap)
218935c4bbdfSmrg		RegionPtr pRegion;
219035c4bbdfSmrg		Bool *pOverlap;
219135c4bbdfSmrg
219235c4bbdfSmrg	macro: Bool RegionValidate(pRegion, pOverlap)
219335c4bbdfSmrg
219435c4bbdfSmrg</programlisting></blockquote>
219535c4bbdfSmrgThese functions provide an optimization for clip list generation and
219635c4bbdfSmrgmust be used in conjunction.  The combined effect is to produce the
219735c4bbdfSmrgunion of a collection of regions, by using RegionAppend several times,
219835c4bbdfSmrgand finally calling RegionValidate which takes the intermediate
219935c4bbdfSmrgrepresentation (which needn't be a valid region) and produces the
220035c4bbdfSmrgdesired union.  pOverlap is set to TRUE if any of the original
220135c4bbdfSmrgregions overlap; FALSE otherwise.</para>
220235c4bbdfSmrg<para>
220335c4bbdfSmrg<blockquote><programlisting>
220435c4bbdfSmrg
220535c4bbdfSmrg	RegionPtr pScreen->BitmapToRegion (pPixmap)
220635c4bbdfSmrg		PixmapPtr pPixmap;
220735c4bbdfSmrg
220835c4bbdfSmrg	macro: RegionPtr BitmapToRegion(pScreen, pPixmap)
220935c4bbdfSmrg
221035c4bbdfSmrg</programlisting></blockquote>
221135c4bbdfSmrgGiven a depth-1 pixmap, this routine must create a valid region which
221235c4bbdfSmrgincludes all the areas of the pixmap filled with 1's and excludes the
221335c4bbdfSmrgareas filled with 0's.  This routine returns NULL if out of memory.</para>
221435c4bbdfSmrg<para>
221535c4bbdfSmrg<blockquote><programlisting>
221635c4bbdfSmrg
221735c4bbdfSmrg	RegionPtr pScreen->RectsToRegion (nrects, pRects, ordering)
221835c4bbdfSmrg		int nrects;
221935c4bbdfSmrg		xRectangle *pRects;
222035c4bbdfSmrg		int ordering;
222135c4bbdfSmrg
222235c4bbdfSmrg	macro: RegionPtr RegionFromRects(nrects, pRects, ordering)
222335c4bbdfSmrg
222435c4bbdfSmrg</programlisting></blockquote>
222535c4bbdfSmrgGiven a client-supplied list of rectangles, produces a region which includes
222635c4bbdfSmrgthe union of all the rectangles.  Ordering may be used as a hint which
222735c4bbdfSmrgdescribes how the rectangles are sorted.  As the hint is provided by a
222835c4bbdfSmrgclient, it must not be required to be correct, but the results when it is
222935c4bbdfSmrgnot correct are not defined (core dump is not an option here).</para>
223035c4bbdfSmrg<para>
223135c4bbdfSmrg<blockquote><programlisting>
223235c4bbdfSmrg
223335c4bbdfSmrg	void pScreen->SendGraphicsExpose(client,pRegion,drawable,major,minor)
223435c4bbdfSmrg		ClientPtr client;
223535c4bbdfSmrg		RegionPtr pRegion;
223635c4bbdfSmrg		XID drawable;
223735c4bbdfSmrg		int major;
223835c4bbdfSmrg		int minor;
223935c4bbdfSmrg
224035c4bbdfSmrg</programlisting></blockquote>
224135c4bbdfSmrgSendGraphicsExpose dispatches a list of GraphicsExposure events which
224235c4bbdfSmrgspan the region to the specified client.  If the region is empty, or
224335c4bbdfSmrga NULL pointer, a NoExpose event is sent instead.</para>
224435c4bbdfSmrg</section>
224535c4bbdfSmrg<section>
224635c4bbdfSmrg  <title>Cursor Routines for a Screen</title>
224735c4bbdfSmrg<para>
224835c4bbdfSmrgA cursor is the visual form tied to the pointing device.  The default
224935c4bbdfSmrgcursor is an "X" shape, but the cursor can have any shape.  When a
225035c4bbdfSmrgclient creates a window, it declares what shape the cursor will be
225135c4bbdfSmrgwhen it strays into that window on the screen.</para>
225235c4bbdfSmrg<para>
225335c4bbdfSmrgFor each possible shape the cursor assumes, there is a CursorRec data
225435c4bbdfSmrgstructure.  This data structure contains a pointer to a CursorBits
225535c4bbdfSmrgdata structure which contains a bitmap for the image of the cursor and
225635c4bbdfSmrga bitmap for a mask behind the cursor, in addition, the CursorRec data
225735c4bbdfSmrgstructure contains foreground and background colors for the cursor.
225835c4bbdfSmrgThe CursorBits data structure is shared among multiple CursorRec
225935c4bbdfSmrgstructures which use the same font and glyph to describe both source
226035c4bbdfSmrgand mask.  The cursor image is applied to the screen by applying the
226135c4bbdfSmrgmask first, clearing 1 bits in its form to the background color, and
226235c4bbdfSmrgthen overwriting on the source image, in the foreground color.  (One
226335c4bbdfSmrgbits of the source image that fall on top of zero bits of the mask
226435c4bbdfSmrgimage are undefined.)  This way, a cursor can have transparent parts,
226535c4bbdfSmrgand opaque parts in two colors.  X allows any cursor size, but some
226635c4bbdfSmrghardware cursor schemes allow a maximum of N pixels by M pixels.
226735c4bbdfSmrgTherefore, you are allowed to transform the cursor to a smaller size,
226835c4bbdfSmrgbut be sure to include the hot-spot.</para>
226935c4bbdfSmrg<para>
227035c4bbdfSmrgCursorBits in Xserver/include/cursorstr.h is a device-independent
227135c4bbdfSmrgstructure containing a device-independent representation of the bits
227235c4bbdfSmrgfor the source and mask.  (This is possible because the bitmap
227335c4bbdfSmrgrepresentation is the same for all screens.)</para>
227435c4bbdfSmrg<para>
227535c4bbdfSmrgWhen a cursor is created, it is "realized" for each screen.  At
227635c4bbdfSmrgrealization time, each screen has the chance to convert the bits into
227735c4bbdfSmrgsome other representation that may be more convenient (for instance,
227835c4bbdfSmrgputting the cursor into off-screen memory) and set up its
227935c4bbdfSmrgdevice-private area in either the CursorRec data structure or
228035c4bbdfSmrgCursorBits data structure as appropriate to possibly point to whatever
228135c4bbdfSmrgdata structures are needed.  It is more memory-conservative to share
228235c4bbdfSmrgrealizations by using the CursorBits private field, but this makes the
228335c4bbdfSmrgassumption that the realization is independent of the colors used
228435c4bbdfSmrg(which is typically true).  For instance, the following are the device
228535c4bbdfSmrgprivate entries for a particular screen and cursor:
228635c4bbdfSmrg<blockquote><programlisting>
228735c4bbdfSmrg
228835c4bbdfSmrg	pCursor->devPriv[pScreen->myNum]
228935c4bbdfSmrg	pCursor->bits->devPriv[pScreen->myNum]
229035c4bbdfSmrg
229135c4bbdfSmrg</programlisting></blockquote>
229235c4bbdfSmrgThis is done because the change from one cursor shape to another must
229335c4bbdfSmrgbe fast and responsive; the cursor image should be able to flutter as
229435c4bbdfSmrgfast as the user moves it across the screen.</para>
229535c4bbdfSmrg<para>
229635c4bbdfSmrgYou must implement the following routines for your hardware:
229735c4bbdfSmrg<blockquote><programlisting>
229835c4bbdfSmrg
229935c4bbdfSmrg	Bool pScreen->RealizeCursor( pScr, pCurs)
230035c4bbdfSmrg		ScreenPtr pScr;
230135c4bbdfSmrg		CursorPtr pCurs;
230235c4bbdfSmrg
230335c4bbdfSmrg	Bool pScreen->UnrealizeCursor( pScr, pCurs)
230435c4bbdfSmrg		ScreenPtr pScr;
230535c4bbdfSmrg		CursorPtr pCurs;
230635c4bbdfSmrg
230735c4bbdfSmrg</programlisting></blockquote>
230835c4bbdfSmrg</para>
230935c4bbdfSmrg<para>
231035c4bbdfSmrgRealizeCursor and UnrealizeCursor should realize (allocate and
231135c4bbdfSmrgcalculate all data needed) and unrealize (free the dynamically
231235c4bbdfSmrgallocated data) a given cursor when DIX needs them.  They are called
231335c4bbdfSmrgwhenever a device-independent cursor is created or destroyed.  The
231435c4bbdfSmrgsource and mask bits pointed to by fields in pCurs are undefined for
231535c4bbdfSmrgbits beyond the right edge of the cursor.  This is so because the bits
231635c4bbdfSmrgare in Bitmap format, which may have pad bits on the right edge.  You
231735c4bbdfSmrgshould inhibit UnrealizeCursor() if the cursor is currently in use;
231835c4bbdfSmrgthis happens when the system is reset.</para>
231935c4bbdfSmrg<para>
232035c4bbdfSmrg<blockquote><programlisting>
232135c4bbdfSmrg
232235c4bbdfSmrg	Bool pScreen->DisplayCursor( pScr, pCurs)
232335c4bbdfSmrg		ScreenPtr pScr;
232435c4bbdfSmrg		CursorPtr pCurs;
232535c4bbdfSmrg
232635c4bbdfSmrg</programlisting></blockquote>
232735c4bbdfSmrgDisplayCursor should change the cursor on the given screen to the one
232835c4bbdfSmrgpassed in.  It is called by DIX when the user moves the pointing
232935c4bbdfSmrgdevice into a different window with a different cursor.  The hotspot
233035c4bbdfSmrgin the cursor should be aligned with the current cursor position.</para>
233135c4bbdfSmrg<para>
233235c4bbdfSmrg<blockquote><programlisting>
233335c4bbdfSmrg
233435c4bbdfSmrg	void pScreen->RecolorCursor( pScr, pCurs, displayed)
233535c4bbdfSmrg		ScreenPtr pScr;
233635c4bbdfSmrg		CursorPtr pCurs;
233735c4bbdfSmrg		Bool displayed;
233835c4bbdfSmrg</programlisting></blockquote>
233935c4bbdfSmrgRecolorCursor notifies DDX that the colors in pCurs have changed and
234035c4bbdfSmrgindicates whether this is the cursor currently being displayed.  If it
234135c4bbdfSmrgis, the cursor hardware state may have to be updated.  Whether
234235c4bbdfSmrgdisplayed or not, state created at RealizeCursor time may have to be
234335c4bbdfSmrgupdated.  A generic version, miRecolorCursor, may be used that
234435c4bbdfSmrgdoes an unrealize, a realize, and possibly a display (in micursor.c);
234535c4bbdfSmrghowever this constrains UnrealizeCursor and RealizeCursor to always return
234635c4bbdfSmrgTRUE as no error indication is returned here.</para>
234735c4bbdfSmrg<para>
234835c4bbdfSmrg<blockquote><programlisting>
234935c4bbdfSmrg
235035c4bbdfSmrg	void pScreen->ConstrainCursor( pScr, pBox)
235135c4bbdfSmrg		ScreenPtr pScr;
235235c4bbdfSmrg		BoxPtr pBox;
235335c4bbdfSmrg
235435c4bbdfSmrg</programlisting></blockquote>
235535c4bbdfSmrgConstrainCursor should cause the cursor to restrict its motion to the
235635c4bbdfSmrgrectangle pBox.  DIX code is capable of enforcing this constraint by
235735c4bbdfSmrgforcefully moving the cursor if it strays out of the rectangle, but
235835c4bbdfSmrgConstrainCursor offers a way to send a hint to the driver or hardware
235935c4bbdfSmrgif such support is available.  This can prevent the cursor from
236035c4bbdfSmrgwandering out of the box, then jumping back, as DIX forces it back.</para>
236135c4bbdfSmrg<para>
236235c4bbdfSmrg<blockquote><programlisting>
236335c4bbdfSmrg
236435c4bbdfSmrg	void pScreen->PointerNonInterestBox( pScr, pBox)
236535c4bbdfSmrg		ScreenPtr pScr;
236635c4bbdfSmrg		BoxPtr pBox;
236735c4bbdfSmrg
236835c4bbdfSmrg</programlisting></blockquote>
236935c4bbdfSmrgPointerNonInterestBox is DIX's way of telling the pointing device code
237035c4bbdfSmrgnot to report motion events while the cursor is inside a given
237135c4bbdfSmrgrectangle on the given screen.  It is optional and, if not
237235c4bbdfSmrgimplemented, it should do nothing.  This routine is called only when
237335c4bbdfSmrgthe client has declared that it is not interested in motion events in
237435c4bbdfSmrga given window.  The rectangle you get may be a subset of that window.
237535c4bbdfSmrgIt saves DIX code the time required to discard uninteresting mouse
237635c4bbdfSmrgmotion events.  This is only a hint, which may speed performance.
237735c4bbdfSmrgNothing in DIX currently calls PointerNonInterestBox.</para>
237835c4bbdfSmrg<para>
237935c4bbdfSmrg<blockquote><programlisting>
238035c4bbdfSmrg
238135c4bbdfSmrg	void pScreen->CursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
238235c4bbdfSmrg		ScreenPtr pScr;
238335c4bbdfSmrg		CursorPtr pCurs;
238435c4bbdfSmrg		BoxPtr pHotBox;
238535c4bbdfSmrg		BoxPtr pTopLeftBox;	/* return value */
238635c4bbdfSmrg
238735c4bbdfSmrg</programlisting></blockquote>
238835c4bbdfSmrgCursorLimits should calculate the box that the cursor hot spot is
238935c4bbdfSmrgphysically capable of moving within, as a function of the screen pScr,
239035c4bbdfSmrgthe device-independent cursor pCurs, and a box that DIX hypothetically
239135c4bbdfSmrgwould want the hot spot confined within, pHotBox.  This routine is for
239235c4bbdfSmrginforming DIX only; it alters no state within DDX.</para>
239335c4bbdfSmrg<para>
239435c4bbdfSmrg<blockquote><programlisting>
239535c4bbdfSmrg
239635c4bbdfSmrg	Bool pScreen->SetCursorPosition( pScr, newx, newy, generateEvent)
239735c4bbdfSmrg		ScreenPtr pScr;
239835c4bbdfSmrg		int newx;
239935c4bbdfSmrg		int newy;
240035c4bbdfSmrg		Bool generateEvent;
240135c4bbdfSmrg
240235c4bbdfSmrg</programlisting></blockquote>
240335c4bbdfSmrgSetCursorPosition should artificially move the cursor as though the
240435c4bbdfSmrguser had jerked the pointing device very quickly.  This is called in
240535c4bbdfSmrgresponse to the WarpPointer request from the client, and at other
240635c4bbdfSmrgtimes.  If generateEvent is True, the device should decide whether or
240735c4bbdfSmrgnot to call ProcessInputEvents() and then it must call
240835c4bbdfSmrgDevicePtr->processInputProc.  Its effects are, of course, limited in
240935c4bbdfSmrgvalue for absolute pointing devices such as a tablet.</para>
241035c4bbdfSmrg<para>
241135c4bbdfSmrg<blockquote><programlisting>
241235c4bbdfSmrg
241335c4bbdfSmrg	void NewCurrentScreen(newScreen, x, y)
241435c4bbdfSmrg	    ScreenPtr newScreen;
241535c4bbdfSmrg	    int x,y;
241635c4bbdfSmrg
241735c4bbdfSmrg</programlisting></blockquote>
241835c4bbdfSmrgIf your ddx provides some mechanism for the user to magically move the
241935c4bbdfSmrgpointer between multiple screens, you need to inform DIX when this
242035c4bbdfSmrgoccurs.  You should call NewCurrentScreen to accomplish this, specifying
242135c4bbdfSmrgthe new screen and the new x and y coordinates of the pointer on that screen.</para>
242235c4bbdfSmrg</section>
242335c4bbdfSmrg<section>
242435c4bbdfSmrg  <title>Visuals, Depths and Pixmap Formats for Screens</title>
242535c4bbdfSmrg<para>
242635c4bbdfSmrgThe "depth" of a image is the number of bits that are used per pixel to display it.</para>
242735c4bbdfSmrg<para>
242835c4bbdfSmrgThe "bits per pixel" of a pixmap image that is sent over the client
242935c4bbdfSmrgbyte stream is a number that is either 4, 8, 16, 24 or 32.  It is the
243035c4bbdfSmrgnumber of bits used per pixel in Z format.  For instance, a pixmap
243135c4bbdfSmrgimage that has a depth of six is best sent in Z format as 8 bits per
243235c4bbdfSmrgpixel.</para>
243335c4bbdfSmrg<para>
243435c4bbdfSmrgA "pixmap image format" or a "pixmap format" is a description of the
243535c4bbdfSmrgformat of a pixmap image as it is sent over the byte stream.  For each
243635c4bbdfSmrgdepth available on a server, there is one and only one pixmap format.
243735c4bbdfSmrgThis pixmap image format gives the bits per pixel and the scanline
243835c4bbdfSmrgpadding unit. (For instance, are pixel rows padded to bytes, 16-bit
243935c4bbdfSmrgwords, or 32-bit words?)</para>
244035c4bbdfSmrg<para>
244135c4bbdfSmrgFor each screen, you must decide upon what depth(s) it supports.  You
244235c4bbdfSmrgshould only count the number of bits used for the actual image.  Some
244335c4bbdfSmrgdisplays store additional bits to indicate what window this pixel is
244435c4bbdfSmrgin, how close this object is to a viewer, transparency, and other
244535c4bbdfSmrgdata; do not count these bits.</para>
244635c4bbdfSmrg<para>
244735c4bbdfSmrgA "display class" tells whether the display is monochrome or color,
244835c4bbdfSmrgwhether there is a lookup table, and how the lookup table works.</para>
244935c4bbdfSmrg<para>
245035c4bbdfSmrgA "visual" is a combination of depth, display class, and a description
245135c4bbdfSmrgof how the pixel values result in a color on the screen.  Each visual
245235c4bbdfSmrghas a set of masks and offsets that are used to separate a pixel value
245335c4bbdfSmrginto its red, green, and blue components and a count of the number of
245435c4bbdfSmrgcolormap entries.  Some of these fields are only meaningful when the
245535c4bbdfSmrgclass dictates so.  Each visual also has a screen ID telling which
245635c4bbdfSmrgscreen it is usable on.  Note that the depth does not imply the number
245735c4bbdfSmrgof map_entries; for instance, a display can have 8 bits per pixel but
245835c4bbdfSmrgonly 254 colormap entries for use by applications (the other two being
245935c4bbdfSmrgreserved by hardware for the cursor).</para>
246035c4bbdfSmrg<para>
246135c4bbdfSmrgEach visual is identified by a 32-bit visual ID which the client uses
246235c4bbdfSmrgto choose what visual is desired on a given window.  Clients can be
246335c4bbdfSmrgusing more than one visual on the same screen at the same time.</para>
246435c4bbdfSmrg<para>
246535c4bbdfSmrgThe class of a display describes how this translation takes place.
246635c4bbdfSmrgThere are three ways to do the translation.
246735c4bbdfSmrg<itemizedlist>
246835c4bbdfSmrg<listitem><para>
246935c4bbdfSmrgPseudo - The pixel value, as a whole, is looked up
247035c4bbdfSmrgin a table of length map_entries to
247135c4bbdfSmrgdetermine the color to display.</para></listitem>
247235c4bbdfSmrg<listitem><para>
247335c4bbdfSmrgTrue - The
247435c4bbdfSmrgpixel value is broken up into red, green, and blue fields, each of which
247535c4bbdfSmrgare looked up in separate red, green, and blue lookup tables,
247635c4bbdfSmrgeach of length map_entries.</para></listitem>
247735c4bbdfSmrg<listitem><para>
247835c4bbdfSmrgGray - The pixel value is looked up in a table of length map_entries to
247935c4bbdfSmrgdetermine a gray level to display.</para></listitem>
248035c4bbdfSmrg</itemizedlist>
248135c4bbdfSmrg</para>
248235c4bbdfSmrg<para>
248335c4bbdfSmrgIn addition, the lookup table can be static (resulting colors are fixed for each
248435c4bbdfSmrgpixel value)
248535c4bbdfSmrgor dynamic (lookup entries are under control of the client program).
248635c4bbdfSmrgThis leads to a total of six classes:
248735c4bbdfSmrg<itemizedlist>
248835c4bbdfSmrg<listitem><para>
248935c4bbdfSmrgStatic Gray - The pixel value (of however many bits) determines directly the
249035c4bbdfSmrglevel of gray
249135c4bbdfSmrgthat the pixel assumes.</para></listitem>
249235c4bbdfSmrg<listitem><para>
249335c4bbdfSmrgGray Scale - The pixel value is fed through a lookup table to arrive at the level
249435c4bbdfSmrgof gray to display
249535c4bbdfSmrgfor the given pixel.</para></listitem>
249635c4bbdfSmrg<listitem><para>
249735c4bbdfSmrgStatic Color - The pixel value is fed through a fixed lookup table that yields the
249835c4bbdfSmrgcolor to display
249935c4bbdfSmrgfor that pixel.</para></listitem>
250035c4bbdfSmrg<listitem><para>
250135c4bbdfSmrgPseudoColor - The whole pixel value is fed through a programmable lookup
250235c4bbdfSmrgtable that has one
250335c4bbdfSmrgcolor (including red, green, and blue intensities) for each possible pixel value,
250435c4bbdfSmrgand that color is displayed.</para></listitem>
250535c4bbdfSmrg<listitem><para>
250635c4bbdfSmrgTrue Color - Each pixel value consists of one or more bits
250735c4bbdfSmrgthat directly determine each primary color intensity after being fed through
250835c4bbdfSmrga fixed table.</para></listitem>
250935c4bbdfSmrg<listitem><para>
251035c4bbdfSmrgDirect Color - Each pixel value consists of one or more bits for each primary color.
251135c4bbdfSmrgEach primary color value is individually looked up in a table for that primary
251235c4bbdfSmrgcolor, yielding
251335c4bbdfSmrgan intensity for that primary color.
251435c4bbdfSmrgFor each pixel, the red value is looked up in the
251535c4bbdfSmrgred table, the green value in the green table, and
251635c4bbdfSmrgthe blue value in the blue table.</para></listitem>
251735c4bbdfSmrg</itemizedlist>
251835c4bbdfSmrg</para>
251935c4bbdfSmrg<para>
252035c4bbdfSmrgHere are some examples:
252135c4bbdfSmrg<itemizedlist>
252235c4bbdfSmrg<listitem><para>
252335c4bbdfSmrgA simple monochrome 1 bit per pixel display is Static Gray.</para></listitem>
252435c4bbdfSmrg<listitem><para>
252535c4bbdfSmrgA display that has 2 bits per pixel for a choice
252635c4bbdfSmrgbetween the colors of black, white, green and violet is Static Color.</para></listitem>
252735c4bbdfSmrg<listitem><para>
252835c4bbdfSmrgA display that has three bits per pixel, where
252935c4bbdfSmrgeach bit turns on or off one of the red, green or
253035c4bbdfSmrgblue guns, is in the True Color class.</para></listitem>
253135c4bbdfSmrg<listitem><para>
253235c4bbdfSmrgIf you take the last example and scramble the
253335c4bbdfSmrgcorrespondence between pixel values and colors
253435c4bbdfSmrgit becomes a Static Color display.</para></listitem>
253535c4bbdfSmrg</itemizedlist></para>
253635c4bbdfSmrg<para>
253735c4bbdfSmrgA display has 8 bits per pixel.  The 8 bits select one entry out of 256 entries
253835c4bbdfSmrgin a lookup table, each entry consisting of 24 bits (8bits each for red, green,
253935c4bbdfSmrgand blue).
254035c4bbdfSmrgThe display can show any 256 of 16 million colors on the screen at once.
254135c4bbdfSmrgThis is a pseudocolor display.
254235c4bbdfSmrgThe client application gets to fill the lookup table in this class of display.</para>
254335c4bbdfSmrg<para>
254435c4bbdfSmrgImagine the same hardware from the last example.
254535c4bbdfSmrgYour server software allows the user, on the
254635c4bbdfSmrgcommand line that starts up the server
254735c4bbdfSmrgprogram,
254835c4bbdfSmrgto fill the lookup table to his liking once and for all.
254935c4bbdfSmrgFrom then on, the server software would not change the lookup table
255035c4bbdfSmrguntil it exits.
255135c4bbdfSmrgFor instance, the default might be a lookup table with a reasonable sample of
255235c4bbdfSmrgcolors from throughout the color space.
255335c4bbdfSmrgBut the user could specify that the table be filled with 256 steps of gray scale
255435c4bbdfSmrgbecause he knew ahead of time he would be manipulating a lot of black-and-white
255535c4bbdfSmrgscanned photographs
255635c4bbdfSmrgand not very many color things.
255735c4bbdfSmrgClients would be presented with this unchangeable lookup table.
255835c4bbdfSmrgAlthough the hardware qualifies as a PseudoColor display,
255935c4bbdfSmrgthe facade presented to the X client is that this is a Static Color display.</para>
256035c4bbdfSmrg<para>
256135c4bbdfSmrgYou have to decide what kind of display you have or want
256235c4bbdfSmrgto pretend you have.
256335c4bbdfSmrgWhen you initialize the screen(s), this class value must be set in the
256435c4bbdfSmrgVisualRec data structure along with other display characteristics like the
256535c4bbdfSmrgdepth and other numbers.</para>
256635c4bbdfSmrg<para>
256735c4bbdfSmrgThe allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec.
256835c4bbdfSmrgThese are set up when InitOutput() is called; you should malloc() appropriate blocks
256935c4bbdfSmrgor use static variables initialized to the correct values.</para>
257035c4bbdfSmrg</section>
257135c4bbdfSmrg<section>
257235c4bbdfSmrg<title>Colormaps for Screens</title>
257335c4bbdfSmrg<para>
257435c4bbdfSmrgA colormap is a device-independent
257535c4bbdfSmrgmapping between pixel values and colors displayed on the screen.</para>
257635c4bbdfSmrg<para>
257735c4bbdfSmrgDifferent windows on the same screen can have different
257835c4bbdfSmrgcolormaps at the same time.
257935c4bbdfSmrgAt any given time, the most recently installed
258035c4bbdfSmrgcolormap(s) will be in use in the server
258135c4bbdfSmrgso that its (their) windows' colors will be guaranteed to be correct.
258235c4bbdfSmrgOther windows may be off-color.
258335c4bbdfSmrgAlthough this may seem to be chaotic, in practice most clients
258435c4bbdfSmrguse the default colormap for the screen.</para>
258535c4bbdfSmrg<para>
258635c4bbdfSmrgThe default colormap for a screen is initialized when the screen is initialized.
258735c4bbdfSmrgIt always remains in existence and is not owned by any regular client.  It
258835c4bbdfSmrgis owned by client 0 (the server itself).
258935c4bbdfSmrgMany clients will simply use this default colormap for their drawing.
259035c4bbdfSmrgDepending upon the class of the screen, the entries in this colormap may
259135c4bbdfSmrgbe modifiable by client applications.</para>
259235c4bbdfSmrg</section>
259335c4bbdfSmrg<section>
259435c4bbdfSmrg  <title>Colormap Routines</title>
259535c4bbdfSmrg<para>
259635c4bbdfSmrgYou need to implement the following routines to handle the device-dependent
259735c4bbdfSmrgaspects of color maps.  You will end up placing pointers to these procedures
259835c4bbdfSmrgin your ScreenRec data structure(s).  The sample server implementations of
259935c4bbdfSmrgmany of these routines are in fbcmap.c.</para>
260035c4bbdfSmrg<para>
260135c4bbdfSmrg<blockquote><programlisting>
260235c4bbdfSmrg
260335c4bbdfSmrg	Bool pScreen->CreateColormap(pColormap)
260435c4bbdfSmrg		ColormapPtr pColormap;
260535c4bbdfSmrg
260635c4bbdfSmrg</programlisting></blockquote>
260735c4bbdfSmrgThis routine is called by the DIX CreateColormap routine after it has allocated
260835c4bbdfSmrgall the data for the new colormap and just before it returns to the dispatcher.
260935c4bbdfSmrgIt is the DDX layer's chance to initialize the colormap, particularly if it is
261035c4bbdfSmrga static map.  See the following
261135c4bbdfSmrgsection for more details on initializing colormaps.
261235c4bbdfSmrgThe routine returns FALSE if creation failed, such as due to memory
261335c4bbdfSmrglimitations.
261435c4bbdfSmrgNotice that the colormap has a devPriv field from which you can hang any
261535c4bbdfSmrgcolormap specific storage you need.  Since each colormap might need special
261635c4bbdfSmrginformation, we attached the field to the colormap and not the visual.</para>
261735c4bbdfSmrg<para>
261835c4bbdfSmrg<blockquote><programlisting>
261935c4bbdfSmrg
262035c4bbdfSmrg	void pScreen->DestroyColormap(pColormap)
262135c4bbdfSmrg		ColormapPtr pColormap;
262235c4bbdfSmrg
262335c4bbdfSmrg</programlisting></blockquote>
262435c4bbdfSmrgThis routine is called by the DIX FreeColormap routine after it has uninstalled
262535c4bbdfSmrgthe colormap and notified all interested parties, and before it has freed
262635c4bbdfSmrgany of the colormap storage.
262735c4bbdfSmrgIt is the DDX layer's chance to free any data it added to the colormap.</para>
262835c4bbdfSmrg<para>
262935c4bbdfSmrg<blockquote><programlisting>
263035c4bbdfSmrg
263135c4bbdfSmrg	void pScreen->InstallColormap(pColormap)
263235c4bbdfSmrg		ColormapPtr pColormap;
263335c4bbdfSmrg
263435c4bbdfSmrg</programlisting></blockquote>
263535c4bbdfSmrgInstallColormap should
263635c4bbdfSmrgfill a lookup table on the screen with which the colormap is associated with
263735c4bbdfSmrgthe colors in pColormap.
263835c4bbdfSmrgIf there is only one hardware lookup table for the screen, then all colors on
263935c4bbdfSmrgthe screen may change simultaneously.</para>
264035c4bbdfSmrg<para>
264135c4bbdfSmrgIn the more general case of multiple hardware lookup tables,
264235c4bbdfSmrgthis may cause some other colormap to be
264335c4bbdfSmrguninstalled, meaning that windows that subscribed to the colormap
264435c4bbdfSmrgthat was uninstalled may end up being off-color.
264535c4bbdfSmrgSee the note, below, about uninstalling maps.</para>
264635c4bbdfSmrg<para>
264735c4bbdfSmrg<blockquote><programlisting>
264835c4bbdfSmrg
264935c4bbdfSmrg	void pScreen->UninstallColormap(pColormap)
265035c4bbdfSmrg		ColormapPtr pColormap;
265135c4bbdfSmrg
265235c4bbdfSmrg</programlisting></blockquote>
265335c4bbdfSmrgUninstallColormap should
265435c4bbdfSmrgremove pColormap from screen pColormap->pScreen.
265535c4bbdfSmrgSome other map, such as the default map if possible,
265635c4bbdfSmrgshould be installed in place of pColormap if applicable.
265735c4bbdfSmrgIf
265835c4bbdfSmrgpColormap is the default map, do nothing.
265935c4bbdfSmrgIf any client has requested ColormapNotify events, the DDX layer must notify the client.
266035c4bbdfSmrg(The routine WalkTree() is
266135c4bbdfSmrgbe used to find such windows.  The DIX routines TellNoMap(),
266235c4bbdfSmrgTellNewMap()  and TellGainedMap() are provided to be used as
266335c4bbdfSmrgthe procedure parameter to WalkTree.  These procedures are in
266435c4bbdfSmrgXserver/dix/colormap.c.)</para>
266535c4bbdfSmrg<para>
266635c4bbdfSmrg<blockquote><programlisting>
266735c4bbdfSmrg
266835c4bbdfSmrg	int pScreen->ListInstalledColormaps(pScreen, pCmapList)
266935c4bbdfSmrg		ScreenPtr pScreen;
267035c4bbdfSmrg		XID *pCmapList;
267135c4bbdfSmrg
267235c4bbdfSmrg
267335c4bbdfSmrg</programlisting></blockquote>
267435c4bbdfSmrgListInstalledColormaps fills the pCmapList in with the resource ids
267535c4bbdfSmrgof the installed maps and returns a count of installed maps.
267635c4bbdfSmrgpCmapList will point to an array of size MaxInstalledMaps that was allocated
267735c4bbdfSmrgby the caller.</para>
267835c4bbdfSmrg<para>
267935c4bbdfSmrg<blockquote><programlisting>
268035c4bbdfSmrg
268135c4bbdfSmrg	void pScreen->StoreColors (pmap, ndef, pdefs)
268235c4bbdfSmrg		ColormapPtr pmap;
268335c4bbdfSmrg		int ndef;
268435c4bbdfSmrg		xColorItem *pdefs;
268535c4bbdfSmrg
268635c4bbdfSmrg</programlisting></blockquote>
268735c4bbdfSmrgStoreColors changes some of the entries in the colormap pmap.
268835c4bbdfSmrgThe number of entries to change are ndef, and pdefs points to the information
268935c4bbdfSmrgdescribing what to change.
269035c4bbdfSmrgNote that partial changes of entries in the colormap are allowed.
269135c4bbdfSmrgOnly the colors
269235c4bbdfSmrgindicated in the flags field of each xColorItem need to be changed.
269335c4bbdfSmrgHowever, all three color fields will be sent with the proper value for the
269435c4bbdfSmrgbenefit of screens that may not be able to set part of a colormap value.
269535c4bbdfSmrgIf the screen is a static class, this routine does nothing.
269635c4bbdfSmrgThe structure of colormap entries is nontrivial; see colormapst.h
269735c4bbdfSmrgand the definition of xColorItem in Xproto.h for
269835c4bbdfSmrgmore details.</para>
269935c4bbdfSmrg<para>
270035c4bbdfSmrg<blockquote><programlisting>
270135c4bbdfSmrg
270235c4bbdfSmrg	void pScreen->ResolveColor(pRed, pGreen, pBlue, pVisual)
270335c4bbdfSmrg		unsigned short *pRed, *pGreen, *pBlue;
270435c4bbdfSmrg		VisualPtr pVisual;
270535c4bbdfSmrg
270635c4bbdfSmrg
270735c4bbdfSmrg</programlisting></blockquote>
270835c4bbdfSmrgGiven a requested color, ResolveColor returns the nearest color that this hardware is
270935c4bbdfSmrgcapable of displaying on this visual.
271035c4bbdfSmrgIn other words, this rounds off each value, in place, to the number of bits
271135c4bbdfSmrgper primary color that your screen can use.
271235c4bbdfSmrgRemember that each screen has one of these routines.
271335c4bbdfSmrgThe level of roundoff should be what you would expect from the value
271435c4bbdfSmrgyou put in the bits_per_rgb field of the pVisual.</para>
271535c4bbdfSmrg<para>
271635c4bbdfSmrgEach value is an unsigned value ranging from 0 to 65535.
271735c4bbdfSmrgThe bits least likely to be used are the lowest ones.</para>
271835c4bbdfSmrg<para>
271935c4bbdfSmrgFor example, if you had a pseudocolor display
272035c4bbdfSmrgwith any number of bits per pixel
272135c4bbdfSmrgthat had a lookup table supplying 6 bits for each color gun
272235c4bbdfSmrg(a total of 256K different colors), you would
272335c4bbdfSmrground off each value to 6 bits.  Please don't simply truncate these values
272435c4bbdfSmrgto the upper 6 bits, scale the result so that the maximum value seen
272535c4bbdfSmrgby the client will be 65535 for each primary.  This makes color values
272635c4bbdfSmrgmore portable between different depth displays (a 6-bit truncated white
272735c4bbdfSmrgwill not look white on an 8-bit display).</para>
272835c4bbdfSmrg<section>
272935c4bbdfSmrg<title>Initializing a Colormap</title>
273035c4bbdfSmrg<para>
273135c4bbdfSmrgWhen a client requests a new colormap and when the server creates the default
273235c4bbdfSmrgcolormap, the procedure CreateColormap in the DIX layer is invoked.
273335c4bbdfSmrgThat procedure allocates memory for the colormap and related storage such as
273435c4bbdfSmrgthe lists of which client owns which pixels.
273535c4bbdfSmrgIt then sets a bit, BeingCreated, in the flags field of the ColormapRec
273635c4bbdfSmrgand calls the DDX layer's CreateColormap routine.
273735c4bbdfSmrgThis is your chance to initialize the colormap.
273835c4bbdfSmrgIf the colormap is static, which you can tell by looking at the class field,
273935c4bbdfSmrgyou will want to fill in each color cell to match the hardwares notion of the
274035c4bbdfSmrgcolor for that pixel.
274135c4bbdfSmrgIf the colormap is the default for the screen, which you can tell by looking
274235c4bbdfSmrgat the IsDefault bit in the flags field, you should allocate BlackPixel
274335c4bbdfSmrgand WhitePixel to match the values you set in the pScreen structure.
274435c4bbdfSmrg(Of course, you picked those values to begin with.)</para>
274535c4bbdfSmrg<para>
274635c4bbdfSmrgYou can also wait and use AllocColor() to allocate blackPixel
274735c4bbdfSmrgand whitePixel after the default colormap has been created.
274835c4bbdfSmrgIf the default colormap is static and you initialized it in
274935c4bbdfSmrgpScreen->CreateColormap, then use can use AllocColor afterwards
275035c4bbdfSmrgto choose pixel values with the closest rgb values to those
275135c4bbdfSmrgdesired for blackPixel and whitePixel.
275235c4bbdfSmrgIf the default colormap is dynamic and uninitialized, then
275335c4bbdfSmrgthe rgb values you request will be obeyed, and AllocColor will
275435c4bbdfSmrgagain choose pixel values for you.
275535c4bbdfSmrgThese pixel values can then be stored into the screen.</para>
275635c4bbdfSmrg<para>
275735c4bbdfSmrgThere are two ways to fill in the colormap.
275835c4bbdfSmrgThe simplest way is to use the DIX function AllocColor.
275935c4bbdfSmrg<blockquote><programlisting>
276035c4bbdfSmrg
276135c4bbdfSmrgint AllocColor (pmap, pred, pgreen, pblue, pPix, client)
276235c4bbdfSmrg    ColormapPtr         pmap;
276335c4bbdfSmrg    unsigned short      *pred, *pgreen, *pblue;
276435c4bbdfSmrg    Pixel               *pPix;
276535c4bbdfSmrg    int                 client;
276635c4bbdfSmrg
276735c4bbdfSmrg</programlisting></blockquote>
276835c4bbdfSmrgThis takes three pointers to 16 bit color values and a pointer to a suggested
276935c4bbdfSmrgpixel value.  The pixel value is either an index into one colormap or a
277035c4bbdfSmrgcombination of three indices depending on the type of pmap.
277135c4bbdfSmrgIf your colormap starts out empty, and you don't deliberately pick the same
277235c4bbdfSmrgvalue twice, you will always get your suggested pixel.
277335c4bbdfSmrgThe truly nervous could check that the value returned in *pPix is the one
277435c4bbdfSmrgAllocColor was called with.
277535c4bbdfSmrgIf you don't care which pixel is used, or would like them sequentially
277635c4bbdfSmrgallocated from entry 0, set *pPix to 0.  This will find the first free
277735c4bbdfSmrgpixel and use that.</para>
277835c4bbdfSmrg<para>
277935c4bbdfSmrgAllocColor will take care of all the  bookkeeping  and  will
278035c4bbdfSmrgcall StoreColors to get the colormap rgb values initialized.
278135c4bbdfSmrgThe hardware colormap will be changed whenever this colormap
278235c4bbdfSmrgis installed.</para>
278335c4bbdfSmrg<para>
278435c4bbdfSmrgIf for some reason AllocColor doesn't do what you want, you can do your
278535c4bbdfSmrgown bookkeeping and call StoreColors yourself.  This is much more difficult
278635c4bbdfSmrgand shouldn't be necessary for most devices.</para>
278735c4bbdfSmrg</section>
278835c4bbdfSmrg</section>
278935c4bbdfSmrg<section>
279035c4bbdfSmrg  <title>Fonts for Screens</title>
279135c4bbdfSmrg<para>
279235c4bbdfSmrgA font is a set of bitmaps that depict the symbols in a character set.
279335c4bbdfSmrgEach font is for only one typeface in a given size, in other words,
279435c4bbdfSmrgjust one bitmap for each character.  Parallel fonts may be available
279535c4bbdfSmrgin a variety of sizes and variations, including "bold" and "italic."
279635c4bbdfSmrgX supports fonts for 8-bit and 16-bit character codes (for oriental
279735c4bbdfSmrglanguages that have more than 256 characters in the font).  Glyphs are
279835c4bbdfSmrgbitmaps for individual characters.</para>
279935c4bbdfSmrg<para>
280035c4bbdfSmrgThe source comes with some useful font files in an ASCII, plain-text
280135c4bbdfSmrgformat that should be comprehensible on a wide variety of operating
280235c4bbdfSmrgsystems.  The text format, referred to as BDF, is a slight extension
280335c4bbdfSmrgof the current Adobe 2.1 Bitmap Distribution Format (Adobe Systems,
280435c4bbdfSmrgInc.).</para>
280535c4bbdfSmrg<para>
280635c4bbdfSmrgA short paper in PostScript format is included with the sample server
280735c4bbdfSmrgthat defines BDF.  It includes helpful pictures, which is why it is
280835c4bbdfSmrgdone in PostScript and is not included in this document.</para>
280935c4bbdfSmrg<para>
281035c4bbdfSmrgYour implementation should include some sort of font compiler to read
281135c4bbdfSmrgthese files and generate binary files that are directly usable by your
281235c4bbdfSmrgserver implementation.  The sample server comes with the source for a
281335c4bbdfSmrgfont compiler.</para>
281435c4bbdfSmrg<para>
281535c4bbdfSmrgIt is important the font properties contained in the BDF files are
281635c4bbdfSmrgpreserved across any font compilation. In particular, copyright
281735c4bbdfSmrginformation cannot be casually tossed aside without legal
281835c4bbdfSmrgramifications. Other properties will be important to some
281935c4bbdfSmrgsophisticated applications.</para>
282035c4bbdfSmrg<para>
282135c4bbdfSmrgAll clients get font information from the server.  Therefore, your
282235c4bbdfSmrgserver can support any fonts it wants to.  It should probably support
282335c4bbdfSmrgat least the fonts supplied with the X11 tape.  In principle, you can
282435c4bbdfSmrgconvert fonts from other sources or dream up your own fonts for use on
282535c4bbdfSmrgyour server.</para>
282635c4bbdfSmrg<section>
282735c4bbdfSmrg<title>Portable Compiled Format</title>
282835c4bbdfSmrg<para>
282935c4bbdfSmrgA font compiler is supplied with the sample server.  It has
283035c4bbdfSmrgcompile-time switches to convert the BDF files into a portable binary
283135c4bbdfSmrgform, called Portable Compiled Format or PCF.  This allows for an
283235c4bbdfSmrgarbitrary data format inside the file, and by describing the details
283335c4bbdfSmrgof the format in the header of the file, any PCF file can be read by
283435c4bbdfSmrgany PCF reading client.  By selecting the format which matches the
283535c4bbdfSmrgrequired internal format for your renderer, the PCF reader can avoid
283635c4bbdfSmrgreformatting the data each time it is read in.  The font compiler
283735c4bbdfSmrgshould be quite portable.</para>
283835c4bbdfSmrg<para>
283935c4bbdfSmrgThe fonts included with the tape are stored in fonts/bdf.  The
284035c4bbdfSmrgfont compiler is found in fonts/tools/bdftopcf.</para>
284135c4bbdfSmrg</section>
284235c4bbdfSmrg<section>
284335c4bbdfSmrg  <title>Font Realization</title>
284435c4bbdfSmrg<para>
284535c4bbdfSmrgEach screen configured into the server
284635c4bbdfSmrghas an opportunity at font-load time
284735c4bbdfSmrgto "realize" a font into some internal format if necessary.
284835c4bbdfSmrgThis happens every time the font is loaded into memory.</para>
284935c4bbdfSmrg<para>
285035c4bbdfSmrgA font (FontRec in Xserver/include/dixfontstr.h) is
285135c4bbdfSmrga device-independent structure containing a device-independent
285235c4bbdfSmrgrepresentation of the font.  When a font is created, it is "realized"
285335c4bbdfSmrgfor each screen.  At this point, the screen has the chance to convert
285435c4bbdfSmrgthe font into some other format.  The DDX layer can also put information
285535c4bbdfSmrgin the devPrivate storage.</para>
285635c4bbdfSmrg<para>
285735c4bbdfSmrg<blockquote><programlisting>
285835c4bbdfSmrg
285935c4bbdfSmrg	Bool pScreen->RealizeFont(pScr, pFont)
286035c4bbdfSmrg		ScreenPtr pScr;
286135c4bbdfSmrg		FontPtr pFont;
286235c4bbdfSmrg
286335c4bbdfSmrg	Bool pScreen->UnrealizeFont(pScr, pFont)
286435c4bbdfSmrg		ScreenPtr pScr;
286535c4bbdfSmrg		FontPtr pFont;
286635c4bbdfSmrg
286735c4bbdfSmrg</programlisting></blockquote>
286835c4bbdfSmrgRealizeFont and UnrealizeFont should calculate and allocate these extra data structures and
286935c4bbdfSmrgdispose of them when no longer needed.
287035c4bbdfSmrgThese are called in response to OpenFont and CloseFont requests from
287135c4bbdfSmrgthe client.
287235c4bbdfSmrgThe sample server implementation is in fbscreen.c (which does very little).</para>
287335c4bbdfSmrg</section>
287435c4bbdfSmrg</section>
287535c4bbdfSmrg<section>
287635c4bbdfSmrg  <title>Other Screen Routines</title>
287735c4bbdfSmrg<para>
287835c4bbdfSmrgYou must supply several other screen-specific routines for
287935c4bbdfSmrgyour X server implementation.
288035c4bbdfSmrgSome of these are described in other sections:
288135c4bbdfSmrg<itemizedlist>
288235c4bbdfSmrg<listitem><para>
288335c4bbdfSmrgGetImage() is described in the Drawing Primitives section.</para></listitem>
288435c4bbdfSmrg<listitem><para>
288535c4bbdfSmrgGetSpans() is described in the Pixblit routine section.</para></listitem>
288635c4bbdfSmrg<listitem><para>
288735c4bbdfSmrgSeveral window and pixmap manipulation procedures are
288835c4bbdfSmrgdescribed in the Window section under Drawables.</para></listitem>
288935c4bbdfSmrg<listitem><para>
289035c4bbdfSmrgThe CreateGC() routine is described under Graphics Contexts.</para></listitem>
289135c4bbdfSmrg</itemizedlist>
289235c4bbdfSmrg</para>
289335c4bbdfSmrg<para>
289435c4bbdfSmrg<blockquote><programlisting>
289535c4bbdfSmrg
289635c4bbdfSmrg	void pScreen->QueryBestSize(kind, pWidth, pHeight)
289735c4bbdfSmrg		int kind;
289835c4bbdfSmrg		unsigned short *pWidth, *pHeight;
289935c4bbdfSmrg		ScreenPtr pScreen;
290035c4bbdfSmrg
290135c4bbdfSmrg</programlisting></blockquote>
290235c4bbdfSmrgQueryBestSize() returns the best sizes for cursors, tiles, and stipples
290335c4bbdfSmrgin response to client requests.
290435c4bbdfSmrgkind is one of the defined constants CursorShape, TileShape, or StippleShape
290535c4bbdfSmrg(defined in X.h).
290635c4bbdfSmrgFor CursorShape, return the maximum width and
290735c4bbdfSmrgheight for cursors that you can handle.
290835c4bbdfSmrgFor TileShape and StippleShape, start with the suggested values in pWidth
290935c4bbdfSmrgand pHeight and modify them in place to be optimal values that are
291035c4bbdfSmrggreater than or equal to the suggested values.
291135c4bbdfSmrgThe sample server implementation is in Xserver/fb/fbscreen.c.</para>
291235c4bbdfSmrg<para>
291335c4bbdfSmrg<blockquote><programlisting>
291435c4bbdfSmrg
291535c4bbdfSmrg	pScreen->SourceValidate(pDrawable, x, y, width, height)
291635c4bbdfSmrg		DrawablePtr pDrawable;
291735c4bbdfSmrg		int x, y, width, height;
291835c4bbdfSmrg		unsigned int subWindowMode;
291935c4bbdfSmrg
292035c4bbdfSmrg</programlisting></blockquote>
292125da500fSmrgSourceValidate should be called by any primitive that reads from pDrawable.
292225da500fSmrgIf you know that
292335c4bbdfSmrgyou will never need SourceValidate, you can avoid this check.  Currently,
292435c4bbdfSmrgSourceValidate is used by the mi software cursor code to remove the cursor
292535c4bbdfSmrgfrom the screen when the source rectangle overlaps the cursor position.
292635c4bbdfSmrgx,y,width,height describe the source rectangle (source relative, that is)
292735c4bbdfSmrgfor the copy operation.  subWindowMode comes from the GC or source Picture.
292835c4bbdfSmrg</para>
292935c4bbdfSmrg<para>
293035c4bbdfSmrg<blockquote><programlisting>
293135c4bbdfSmrg
293235c4bbdfSmrg	Bool pScreen->SaveScreen(pScreen, on)
293335c4bbdfSmrg		ScreenPtr pScreen;
293435c4bbdfSmrg		int on;
293535c4bbdfSmrg
293635c4bbdfSmrg</programlisting></blockquote>
293735c4bbdfSmrgSaveScreen() is used for Screen Saver support (see WaitForSomething()).
293835c4bbdfSmrgpScreen is the screen to save.</para>
293935c4bbdfSmrg<para>
294035c4bbdfSmrg<blockquote><programlisting>
294135c4bbdfSmrg
294235c4bbdfSmrg	Bool pScreen->CloseScreen(pScreen)
294335c4bbdfSmrg	    ScreenPtr pScreen;
294435c4bbdfSmrg
294535c4bbdfSmrg</programlisting></blockquote>
294635c4bbdfSmrgWhen the server is reset, it calls this routine for each screen.</para>
294735c4bbdfSmrg<para>
294835c4bbdfSmrg<blockquote><programlisting>
294935c4bbdfSmrg
295035c4bbdfSmrg	Bool pScreen->CreateScreenResources(pScreen)
295135c4bbdfSmrg	    ScreenPtr pScreen;
295235c4bbdfSmrg
295335c4bbdfSmrg</programlisting></blockquote>
295435c4bbdfSmrgIf this routine is not NULL, it will be called once per screen per
295535c4bbdfSmrgserver initialization/reset after all modules have had a chance to
295635c4bbdfSmrgrequest private space on all structures that support them (see
295735c4bbdfSmrg<xref linkend="wrappers_and_privates"/> below).  You may create resources
295835c4bbdfSmrgin this function instead of in the
295935c4bbdfSmrgscreen init function passed to AddScreen in order to guarantee that
296035c4bbdfSmrgall pre-allocated space requests have been registered first.  With the
296135c4bbdfSmrgnew devPrivates mechanism, this is not strictly necessary, however.
296235c4bbdfSmrgThis routine returns TRUE if successful.</para>
296335c4bbdfSmrg</section>
296435c4bbdfSmrg</section>
296535c4bbdfSmrg<section>
296635c4bbdfSmrg<title>Drawables</title>
296735c4bbdfSmrg<para>
296835c4bbdfSmrgA drawable is a descriptor of a surface that graphics are drawn into, either
296935c4bbdfSmrga window on the screen or a pixmap in memory.</para>
297035c4bbdfSmrg<para>
297135c4bbdfSmrgEach drawable has a type, class,
297235c4bbdfSmrgScreenPtr for the screen it is associated with, depth, position, size,
297335c4bbdfSmrgand serial number.
297435c4bbdfSmrgThe type is one of the defined constants DRAWABLE_PIXMAP,
297535c4bbdfSmrgDRAWABLE_WINDOW and UNDRAWABLE_WINDOW.
297635c4bbdfSmrg(An undrawable window is used for window class InputOnly.)
297735c4bbdfSmrgThe serial number is guaranteed to be unique across drawables, and
297835c4bbdfSmrgis used in determining
297935c4bbdfSmrgthe validity of the clipping information in a GC.
298035c4bbdfSmrgThe screen selects the set of procedures used to manipulate and draw into the
298135c4bbdfSmrgdrawable.  Position is used (currently) only by windows; pixmaps must
298235c4bbdfSmrgset these fields to 0,0 as this reduces the amount of conditional code
298335c4bbdfSmrgexecuted throughout the mi code.  Size indicates the actual client-specified
298435c4bbdfSmrgsize of the drawable.
298535c4bbdfSmrgThere are, in fact, no other fields that a window drawable and pixmap
298635c4bbdfSmrgdrawable have in common besides those mentioned here.</para>
298735c4bbdfSmrg<para>
298835c4bbdfSmrgBoth PixmapRecs and WindowRecs are structs that start with a drawable
298935c4bbdfSmrgand continue on with more fields.  Pixmaps have a single pointer field
299035c4bbdfSmrgnamed devPrivate which usually points to the pixmap data but could conceivably be
299135c4bbdfSmrgused for anything that DDX wants.  Both windows and pixmaps also have a
299235c4bbdfSmrgdevPrivates field which can be used for DDX specific data (see <xref linkend="wrappers_and_privates"/>
299335c4bbdfSmrgbelow).  This is done because different graphics hardware has
299435c4bbdfSmrgdifferent requirements for management; if the graphics is always
299535c4bbdfSmrghandled by a processor with an independent address space, there is no
299635c4bbdfSmrgpoint having a pointer to the bit image itself.</para>
299735c4bbdfSmrg<para>
299835c4bbdfSmrgThe definition of a drawable and a pixmap can be found in the file
299935c4bbdfSmrgXserver/include/pixmapstr.h.
300035c4bbdfSmrgThe definition of a window can be found in the file Xserver/include/windowstr.h.</para>
300135c4bbdfSmrg<section>
300235c4bbdfSmrg  <title>Pixmaps</title>
300335c4bbdfSmrg<para>
300435c4bbdfSmrgA pixmap is a three-dimensional array of bits stored somewhere offscreen,
300535c4bbdfSmrgrather than in the visible portion of the screen's display frame buffer.  It
300635c4bbdfSmrgcan be used as a source or destination in graphics operations.  There is no
300735c4bbdfSmrgimplied interpretation of the pixel values in a pixmap, because it has no
300835c4bbdfSmrgassociated visual or colormap.  There is only a depth that indicates the
300935c4bbdfSmrgnumber of significant bits per pixel.  Also, there is no implied physical
301035c4bbdfSmrgsize for each pixel; all graphic units are in numbers of pixels.  Therefore,
301135c4bbdfSmrga pixmap alone does not constitute a complete image; it represents only a
301235c4bbdfSmrgrectangular array of pixel values.</para>
301335c4bbdfSmrg<para>
301435c4bbdfSmrgNote that the pixmap data structure is reference-counted.</para>
301535c4bbdfSmrg<para>
301635c4bbdfSmrgThe server implementation is free to put the pixmap data
301735c4bbdfSmrganywhere it sees fit, according to its graphics hardware setup.  Many
301835c4bbdfSmrgimplementations will simply have the data dynamically allocated in the
301935c4bbdfSmrgserver's address space.  More sophisticated implementations may put the
302035c4bbdfSmrgdata in undisplayed framebuffer storage.</para>
302135c4bbdfSmrg<para>
302235c4bbdfSmrgIn addition to dynamic devPrivates (see <xref linkend="wrappers_and_privates"/>
302335c4bbdfSmrgbelow), the pixmap data structure has two fields that are private to
302435c4bbdfSmrgthe device.  Although you can use them for anything you want, they
302535c4bbdfSmrghave intended purposes.  devKind is intended to be a device specific
302635c4bbdfSmrgindication of the pixmap location (host memory, off-screen, etc.).  In
302735c4bbdfSmrgthe sample server, since all pixmaps are in memory, devKind stores the
302835c4bbdfSmrgwidth of the pixmap in bitmap scanline units.  devPrivate is usually
302935c4bbdfSmrga pointer to the bits in the pixmap.</para>
303035c4bbdfSmrg<para>
303135c4bbdfSmrgA bitmap is a pixmap that is one bit deep.</para>
303235c4bbdfSmrg<para>
303335c4bbdfSmrg<blockquote><programlisting>
303435c4bbdfSmrg
303535c4bbdfSmrg	PixmapPtr pScreen->CreatePixmap(pScreen, width, height, depth)
303635c4bbdfSmrg		ScreenPtr pScreen;
303735c4bbdfSmrg		int width, height, depth;
303835c4bbdfSmrg
303935c4bbdfSmrg</programlisting></blockquote>
304035c4bbdfSmrgThis ScreenRec procedure must create a pixmap of the size
304135c4bbdfSmrgrequested.
304235c4bbdfSmrgIt must allocate a PixmapRec and fill in all of the fields.
304335c4bbdfSmrgThe reference count field must be set to 1.
304435c4bbdfSmrgIf width or height are zero, no space should be allocated
304535c4bbdfSmrgfor the pixmap data, and if the implementation is using the
304635c4bbdfSmrgdevPrivate field as a pointer to the pixmap data, it should be
304735c4bbdfSmrgset to NULL.
304835c4bbdfSmrgIf successful, it returns a pointer to the new pixmap; if not, it returns NULL.
304935c4bbdfSmrgSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
305035c4bbdfSmrg<para>
305135c4bbdfSmrg<blockquote><programlisting>
305235c4bbdfSmrg
305335c4bbdfSmrg	Bool pScreen->DestroyPixmap(pPixmap)
305435c4bbdfSmrg		PixmapPtr pPixmap;
305535c4bbdfSmrg
305635c4bbdfSmrg</programlisting></blockquote>
305735c4bbdfSmrgThis ScreenRec procedure must "destroy" a pixmap.
305835c4bbdfSmrgIt should decrement the reference count and, if zero, it
305935c4bbdfSmrgmust deallocate the PixmapRec and all attached devPrivate blocks.
306035c4bbdfSmrgIf successful, it returns TRUE.
306135c4bbdfSmrgSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
306235c4bbdfSmrg<para>
306335c4bbdfSmrg<blockquote><programlisting>
306435c4bbdfSmrg
306535c4bbdfSmrg	Bool
306635c4bbdfSmrg	pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData)
306735c4bbdfSmrg		PixmapPtr   pPixmap;
306835c4bbdfSmrg		int	    width;
306935c4bbdfSmrg		int	    height;
307035c4bbdfSmrg		int	    depth;
307135c4bbdfSmrg		int	    bitsPerPixel;
307235c4bbdfSmrg		int	    devKind;
307335c4bbdfSmrg		pointer     pPixData;
307435c4bbdfSmrg
307535c4bbdfSmrg</programlisting></blockquote>
307635c4bbdfSmrgThis routine takes a pixmap header and initializes the fields of the PixmapRec to the
307735c4bbdfSmrgparameters of the same name.  pPixmap must have been created via
307835c4bbdfSmrgpScreen->CreatePixmap with a zero width or height to avoid
307935c4bbdfSmrgallocating space for the pixmap data.  pPixData is assumed to be the
308035c4bbdfSmrgpixmap data; it will be stored in an implementation-dependent place
308135c4bbdfSmrg(usually pPixmap->devPrivate.ptr).  This routine returns
308235c4bbdfSmrgTRUE if successful.  See Xserver/mi/miscrinit.c for the sample
308335c4bbdfSmrgserver implementation.</para>
308435c4bbdfSmrg<para>
308535c4bbdfSmrg<blockquote><programlisting>
308635c4bbdfSmrg
308735c4bbdfSmrg	PixmapPtr
308835c4bbdfSmrg	GetScratchPixmapHeader(pScreen, width, height, depth, bitsPerPixel, devKind, pPixData)
308935c4bbdfSmrg		ScreenPtr   pScreen;
309035c4bbdfSmrg		int	    width;
309135c4bbdfSmrg		int	    height;
309235c4bbdfSmrg		int	    depth;
309335c4bbdfSmrg		int	    bitsPerPixel;
309435c4bbdfSmrg		int	    devKind;
309535c4bbdfSmrg		pointer     pPixData;
309635c4bbdfSmrg
309735c4bbdfSmrg	void FreeScratchPixmapHeader(pPixmap)
309835c4bbdfSmrg		PixmapPtr pPixmap;
309935c4bbdfSmrg
310035c4bbdfSmrg</programlisting></blockquote>
310135c4bbdfSmrgDDX should use these two DIX routines when it has a buffer of raw
310235c4bbdfSmrgimage data that it wants to manipulate as a pixmap temporarily,
310335c4bbdfSmrgusually so that some other part of the server can be leveraged to
310435c4bbdfSmrgperform some operation on the data.  The data should be passed in
310535c4bbdfSmrgpPixData, and will be stored in an implementation-dependent place
310635c4bbdfSmrg(usually pPixmap->devPrivate.ptr). The other
310735c4bbdfSmrgfields go into the corresponding PixmapRec fields.
310835c4bbdfSmrgIf successful, GetScratchPixmapHeader returns a valid PixmapPtr which can
310935c4bbdfSmrgbe used anywhere the server expects a pixmap, else
311035c4bbdfSmrgit returns NULL.  The pixmap should be released when no longer needed
311135c4bbdfSmrg(usually within the same function that allocated it)
311235c4bbdfSmrgwith FreeScratchPixmapHeader.</para>
311335c4bbdfSmrg</section>
311435c4bbdfSmrg<section>
311535c4bbdfSmrg  <title>Windows</title>
311635c4bbdfSmrg<para>
311735c4bbdfSmrgA window is a visible, or potentially visible, rectangle on the screen.
311835c4bbdfSmrgDIX windowing functions maintain an internal n-ary tree data structure, which
311935c4bbdfSmrgrepresents the current relationships of the mapped windows.
312035c4bbdfSmrgWindows that are contained in another window are children of that window and
312135c4bbdfSmrgare clipped to the boundaries of the parent.
312235c4bbdfSmrgThe root window in the tree is the window for the entire screen.
312335c4bbdfSmrgSibling windows constitute a doubly-linked list; the parent window has a pointer
312435c4bbdfSmrgto the head and tail of this list.
312535c4bbdfSmrgEach child also has a pointer to its parent.</para>
312635c4bbdfSmrg<para>
312735c4bbdfSmrgThe border of a window is drawn by a DDX procedure when DIX requests that it
312835c4bbdfSmrgbe drawn.  The contents of the window is drawn by the client through
312935c4bbdfSmrgrequests to the server.</para>
313035c4bbdfSmrg<para>
313135c4bbdfSmrgWindow painting is orchestrated through an expose event system.
313235c4bbdfSmrgWhen a region is exposed,
313335c4bbdfSmrgDIX generates an expose event, telling the client to repaint the window and
313435c4bbdfSmrgpassing the region that is the minimal area needed to be repainted.</para>
313535c4bbdfSmrg<para>
313635c4bbdfSmrgAs a favor to clients, the server may retain
313735c4bbdfSmrgthe output to the hidden parts of windows
313835c4bbdfSmrgin off-screen memory; this is called "backing store".
313935c4bbdfSmrgWhen a part of such a window becomes exposed, it
314035c4bbdfSmrgcan quickly move pixels into place instead of
314135c4bbdfSmrgtriggering an expose event and waiting for a client on the other
314235c4bbdfSmrgend of the network to respond.
314335c4bbdfSmrgEven if the network response is insignificant, the time to
314435c4bbdfSmrgintelligently paint a section of a window is usually more than
314535c4bbdfSmrgthe time to just copy already-painted sections.
314635c4bbdfSmrgAt best, the repainting involves blanking out the area to a background color,
314735c4bbdfSmrgwhich will take about the
314835c4bbdfSmrgsame amount of time.
314935c4bbdfSmrgIn this way, backing store can dramatically increase the
315035c4bbdfSmrgperformance of window moves.</para>
315135c4bbdfSmrg<para>
315235c4bbdfSmrgOn the other hand, backing store can be quite complex, because
315335c4bbdfSmrgall graphics drawn to hidden areas must be intercepted and redirected
315435c4bbdfSmrgto the off-screen window sections.
315535c4bbdfSmrgNot only can this be complicated for the server programmer,
315635c4bbdfSmrgbut it can also impact window painting performance.
315735c4bbdfSmrgThe backing store implementation can choose, at any time, to
315835c4bbdfSmrgforget pieces of backing that are written into, relying instead upon
315935c4bbdfSmrgexpose events to repaint for simplicity.</para>
316035c4bbdfSmrg<para>
316135c4bbdfSmrgIn X, the decision to use the backing-store scheme is made
316235c4bbdfSmrgby you, the server implementor.  The sample server implements
316335c4bbdfSmrgbacking store "for free" by reusing the infrastructure for the Composite
316435c4bbdfSmrgextension.  As a side effect, it treats the WhenMapped and Always hints
316535c4bbdfSmrgas equivalent.  However, it will never forget pixel contents when the
316635c4bbdfSmrgwindow is mapped.</para>
316735c4bbdfSmrg<para>
316835c4bbdfSmrgWhen a window operation is requested by the client,
316935c4bbdfSmrgsuch as a window being created or moved,
317035c4bbdfSmrga new state is computed.
317135c4bbdfSmrgDuring this transition, DIX informs DDX what rectangles in what windows are about to
317235c4bbdfSmrgbecome obscured and what rectangles in what windows have become exposed.
317335c4bbdfSmrgThis provides a hook for the implementation of backing store.
317435c4bbdfSmrgIf DDX is unable to restore exposed regions, DIX generates expose
317535c4bbdfSmrgevents to the client.
317635c4bbdfSmrgIt is then the client's responsibility to paint the
317735c4bbdfSmrgwindow parts that were exposed but not restored.</para>
317835c4bbdfSmrg<para>
317935c4bbdfSmrgIf a window is resized, pixels sometimes need to be
318035c4bbdfSmrgmoved, depending upon
318135c4bbdfSmrgthe application.
318235c4bbdfSmrgThe client can request "Gravity" so that
318335c4bbdfSmrgcertain blocks of the window are
318435c4bbdfSmrgmoved as a result of a resize.
318535c4bbdfSmrgFor instance, if the window has controls or other items
318635c4bbdfSmrgthat always hang on the edge of the
318735c4bbdfSmrgwindow, and that edge is moved as a result of the resize,
318835c4bbdfSmrgthen those pixels should be moved
318935c4bbdfSmrgto avoid having the client repaint it.
319035c4bbdfSmrgIf the client needs to repaint it anyway, such an operation takes
319135c4bbdfSmrgtime, so it is desirable
319235c4bbdfSmrgfor the server to approximate the appearance of the window as best
319335c4bbdfSmrgit can while waiting for the client
319435c4bbdfSmrgto do it perfectly.
319535c4bbdfSmrgGravity is used for that, also.</para>
319635c4bbdfSmrg<para>
319735c4bbdfSmrgThe window has several fields used in drawing
319835c4bbdfSmrgoperations:
319935c4bbdfSmrg<itemizedlist>
320035c4bbdfSmrg<listitem><para>
320135c4bbdfSmrgclipList - This region, in conjunction with
320235c4bbdfSmrgthe client clip region in the gc, is used to clip output.
320335c4bbdfSmrgclipList has the window's children subtracted from it, in addition to pieces of sibling windows
320435c4bbdfSmrgthat overlap this window.  To get the list with the
320535c4bbdfSmrgchildren included (subwindow-mode is IncludeInferiors),
320635c4bbdfSmrgthe routine NotClippedByChildren(pWin) returns the unclipped region.</para></listitem>
320735c4bbdfSmrg<listitem><para>
320835c4bbdfSmrgborderClip is the region used by CopyWindow and
320935c4bbdfSmrgincludes the area of the window, its children, and the border, but with the
321035c4bbdfSmrgoverlapping areas of sibling children removed.</para></listitem>
321135c4bbdfSmrg</itemizedlist>
321235c4bbdfSmrgMost of the other fields are for DIX use only.</para>
321335c4bbdfSmrg<section>
321435c4bbdfSmrg<title>Window Procedures in the ScreenRec</title>
321535c4bbdfSmrg<para>
321635c4bbdfSmrgYou should implement
321735c4bbdfSmrgall of the following procedures and store pointers to them in the screen record.</para>
321835c4bbdfSmrg<para>
321935c4bbdfSmrgThe device-independent portion of the server "owns" the window tree.
322035c4bbdfSmrgHowever, clever hardware might want to know the relationship of
322135c4bbdfSmrgmapped windows.  There are pointers to procedures
322235c4bbdfSmrgin the ScreenRec data structure that are called to give the hardware
322335c4bbdfSmrga chance to update its internal state.  These are helpers and
322435c4bbdfSmrghints to DDX only;
322535c4bbdfSmrgthey do not change the window tree, which is only changed by DIX.</para>
322635c4bbdfSmrg<para>
322735c4bbdfSmrg<blockquote><programlisting>
322835c4bbdfSmrg
322935c4bbdfSmrg	Bool pScreen->CreateWindow(pWin)
323035c4bbdfSmrg		WindowPtr pWin;
323135c4bbdfSmrg
323235c4bbdfSmrg</programlisting></blockquote>
323335c4bbdfSmrgThis routine is a hook for when DIX creates a window.
323435c4bbdfSmrgIt should fill in the "Window Procedures in the WindowRec" below
323535c4bbdfSmrgand also allocate the devPrivate block for it.</para>
323635c4bbdfSmrg<para>
323735c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
323835c4bbdfSmrg<para>
323935c4bbdfSmrg<blockquote><programlisting>
324035c4bbdfSmrg
324135c4bbdfSmrg	Bool pScreen->DestroyWindow(pWin);
324235c4bbdfSmrg		WindowPtr pWin;
324335c4bbdfSmrg
324435c4bbdfSmrg</programlisting></blockquote>
324535c4bbdfSmrgThis routine is a hook for when DIX destroys a window.
324635c4bbdfSmrgIt should deallocate the devPrivate block for it and any other blocks that need
324735c4bbdfSmrgto be freed, besides doing other cleanup actions.</para>
324835c4bbdfSmrg<para>
324935c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
325035c4bbdfSmrg<para>
325135c4bbdfSmrg<blockquote><programlisting>
325235c4bbdfSmrg
325335c4bbdfSmrg	Bool pScreen->PositionWindow(pWin, x, y);
325435c4bbdfSmrg		WindowPtr pWin;
325535c4bbdfSmrg		int x, y;
325635c4bbdfSmrg
325735c4bbdfSmrg</programlisting></blockquote>
325835c4bbdfSmrgThis routine is a hook for when DIX moves or resizes a window.
325935c4bbdfSmrgIt should do whatever private operations need to be done when a window is moved or resized.
326035c4bbdfSmrgFor instance, if DDX keeps a pixmap tile used for drawing the background
326135c4bbdfSmrgor border, and it keeps the tile rotated such that it is longword
326235c4bbdfSmrgaligned to longword locations in the frame buffer, then you should rotate your tiles here.
326335c4bbdfSmrgThe actual graphics involved in moving the pixels on the screen and drawing the
326435c4bbdfSmrgborder are handled by CopyWindow(), below.</para>
326535c4bbdfSmrg<para>
326635c4bbdfSmrgSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
326735c4bbdfSmrg<para>
326835c4bbdfSmrg<blockquote><programlisting>
326935c4bbdfSmrg
327035c4bbdfSmrg	Bool pScreen->RealizeWindow(pWin);
327135c4bbdfSmrg		WindowPtr pWin;
327235c4bbdfSmrg
327335c4bbdfSmrg	Bool  pScreen->UnrealizeWindow(pWin);
327435c4bbdfSmrg		WindowPtr pWin;
327535c4bbdfSmrg
327635c4bbdfSmrg</programlisting></blockquote>
327735c4bbdfSmrgThese routines are hooks for when DIX maps (makes visible) and unmaps
327835c4bbdfSmrg(makes invisible) a window.  It should do whatever private operations
327935c4bbdfSmrgneed to be done when these happen, such as allocating or deallocating
328035c4bbdfSmrgstructures that are only needed for visible windows.  RealizeWindow
328135c4bbdfSmrgdoes NOT draw the window border, background or contents;
328235c4bbdfSmrgUnrealizeWindow does NOT erase the window or generate exposure events
328335c4bbdfSmrgfor underlying windows; this is taken care of by DIX.  DIX does,
328435c4bbdfSmrghowever, call PaintWindowBackground() and PaintWindowBorder() to
328535c4bbdfSmrgperform some of these.</para>
328635c4bbdfSmrg<para>
328735c4bbdfSmrg<blockquote><programlisting>
328835c4bbdfSmrg
328935c4bbdfSmrg	Bool pScreen->ChangeWindowAttributes(pWin, vmask)
329035c4bbdfSmrg		WindowPtr pWin;
329135c4bbdfSmrg		unsigned long vmask;
329235c4bbdfSmrg
329335c4bbdfSmrg</programlisting></blockquote>
329435c4bbdfSmrgChangeWindowAttributes is called whenever DIX changes window
329535c4bbdfSmrgattributes, such as the size, front-to-back ordering, title, or
329635c4bbdfSmrganything of lesser severity that affects the window itself.  The
329735c4bbdfSmrgsample server implements this routine.  It computes accelerators for
329835c4bbdfSmrgquickly putting up background and border tiles.  (See description of
329935c4bbdfSmrgthe set of routines stored in the WindowRec.)</para>
330035c4bbdfSmrg<para>
330135c4bbdfSmrg<blockquote><programlisting>
330235c4bbdfSmrg
330335c4bbdfSmrg	int pScreen->ValidateTree(pParent,  pChild, kind)
330435c4bbdfSmrg		WindowPtr pParent, pChild;
330535c4bbdfSmrg		VTKind kind;
330635c4bbdfSmrg
330735c4bbdfSmrg</programlisting></blockquote>
330835c4bbdfSmrgValidateTree calculates the clipping region for the parent window and
330935c4bbdfSmrgall of its children.  This routine must be provided. The sample server
331035c4bbdfSmrghas a machine-independent version in Xserver/mi/mivaltree.c.  This is
331135c4bbdfSmrga very difficult routine to replace.</para>
331235c4bbdfSmrg<para>
331335c4bbdfSmrg<blockquote><programlisting>
331435c4bbdfSmrg
331535c4bbdfSmrg	void pScreen->PostValidateTree(pParent,  pChild, kind)
331635c4bbdfSmrg		WindowPtr pParent, pChild;
331735c4bbdfSmrg		VTKind kind;
331835c4bbdfSmrg
331935c4bbdfSmrg</programlisting></blockquote>
332035c4bbdfSmrgIf this routine is not NULL, DIX calls it shortly after calling
332135c4bbdfSmrgValidateTree, passing it the same arguments.  This is useful for
332235c4bbdfSmrgmanaging multi-layered framebuffers.
332335c4bbdfSmrgThe sample server sets this to NULL.</para>
332435c4bbdfSmrg<para>
332535c4bbdfSmrg<blockquote><programlisting>
332635c4bbdfSmrg
332735c4bbdfSmrg	void pScreen->WindowExposures(pWin, pRegion, pBSRegion)
332835c4bbdfSmrg		WindowPtr pWin;
332935c4bbdfSmrg		RegionPtr pRegion;
333035c4bbdfSmrg		RegionPtr pBSRegion;
333135c4bbdfSmrg
333235c4bbdfSmrg</programlisting></blockquote>
333335c4bbdfSmrgThe WindowExposures() routine
333435c4bbdfSmrgpaints the border and generates exposure events for the window.
333535c4bbdfSmrgpRegion is an unoccluded region of the window, and pBSRegion is an
333635c4bbdfSmrgoccluded region that has backing store.
333735c4bbdfSmrgSince exposure events include a rectangle describing what was exposed,
333835c4bbdfSmrgthis routine may have to send back a series of exposure events, one for
333935c4bbdfSmrgeach rectangle of the region.
334035c4bbdfSmrgThe count field in the expose event is a hint to the
334135c4bbdfSmrgclient as to the number of
334235c4bbdfSmrgregions that are after this one.
334335c4bbdfSmrgThis routine must be provided. The sample
334435c4bbdfSmrgserver has a machine-independent version in Xserver/mi/miexpose.c.</para>
334535c4bbdfSmrg<para>
334635c4bbdfSmrg<blockquote><programlisting>
334735c4bbdfSmrg
334835c4bbdfSmrg	void pScreen->ClipNotify (pWin, dx, dy)
334935c4bbdfSmrg		WindowPtr pWin;
335035c4bbdfSmrg		int dx, dy;
335135c4bbdfSmrg
335235c4bbdfSmrg</programlisting></blockquote>
335335c4bbdfSmrgWhenever the cliplist for a window is changed, this function is called to
335435c4bbdfSmrgperform whatever hardware manipulations might be necessary.  When called,
335535c4bbdfSmrgthe clip list and border clip regions in the window are set to the new
335635c4bbdfSmrgvalues.  dx,dy are the distance that the window has been moved (if at all).</para>
335735c4bbdfSmrg</section>
335835c4bbdfSmrg<section>
335935c4bbdfSmrg  <title>Window Painting Procedures</title>
336035c4bbdfSmrg<para>
336135c4bbdfSmrgIn addition to the procedures listed above, there are two routines which
336235c4bbdfSmrgmanipulate the actual window image directly.
336335c4bbdfSmrgIn the sample server, mi implementations will work for
336435c4bbdfSmrgmost purposes and fb routines speed up situations, such
336535c4bbdfSmrgas solid backgrounds/borders or tiles that are 8, 16 or 32 pixels square.</para>
336635c4bbdfSmrg<para>
336735c4bbdfSmrg<blockquote><programlisting>
336835c4bbdfSmrg
336935c4bbdfSmrg	void pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
337035c4bbdfSmrg		WindowPtr pWin;
337135c4bbdfSmrg		int x, y, w, h;
337235c4bbdfSmrg		Bool generateExposures;
337335c4bbdfSmrg
337435c4bbdfSmrg</programlisting></blockquote>
337535c4bbdfSmrgThis routine is called on a window in response to a ClearToBackground request
337635c4bbdfSmrgfrom the client.
337735c4bbdfSmrgThis request has two different but related functions, depending upon generateExposures.</para>
337835c4bbdfSmrg<para>
337935c4bbdfSmrgIf generateExposures is true, the client is declaring that the given rectangle
338035c4bbdfSmrgon the window is incorrectly painted and needs to be repainted.
338135c4bbdfSmrgThe sample server implementation calculates the exposure region
338235c4bbdfSmrgand hands it to the DIX procedure HandleExposures(), which
338335c4bbdfSmrgcalls the WindowExposures() routine, below, for the window
338435c4bbdfSmrgand all of its child windows.</para>
338535c4bbdfSmrg<para>
338635c4bbdfSmrgIf generateExposures is false, the client is trying to simply erase part
338735c4bbdfSmrgof the window to the background fill style.
338835c4bbdfSmrgClearToBackground should write the background color or tile to the
338935c4bbdfSmrgrectangle in question (probably using PaintWindowBackground).
339035c4bbdfSmrgIf w or h is zero, it clears all the way to the right or lower edge of the window.</para>
339135c4bbdfSmrg<para>
339235c4bbdfSmrgThe sample server implementation is in Xserver/mi/miwindow.c.</para>
339335c4bbdfSmrg<para>
339435c4bbdfSmrg<blockquote><programlisting>
339535c4bbdfSmrg
339635c4bbdfSmrg	void pScreen->CopyWindow(pWin, oldpt, oldRegion);
339735c4bbdfSmrg		WindowPtr pWin;
339835c4bbdfSmrg		DDXPointRec oldpt;
339935c4bbdfSmrg		RegionPtr oldRegion;
340035c4bbdfSmrg
340135c4bbdfSmrg</programlisting></blockquote>
340235c4bbdfSmrgCopyWindow is called when a window is moved, and graphically moves to
340335c4bbdfSmrgpixels of a window on the screen.  It should not change any other
340435c4bbdfSmrgstate within DDX (see PositionWindow(), above).</para>
340535c4bbdfSmrg<para>
340635c4bbdfSmrgoldpt is the old location of the upper-left corner.  oldRegion is the
340735c4bbdfSmrgold region it is coming from.  The new location and new region is
340835c4bbdfSmrgstored in the WindowRec.  oldRegion might modified in place by this
340935c4bbdfSmrgroutine (the sample implementation does this).</para>
341035c4bbdfSmrg<para>
341135c4bbdfSmrgCopyArea could be used, except that this operation has more
341235c4bbdfSmrgcomplications.  First of all, you do not want to copy a rectangle onto
341335c4bbdfSmrga rectangle.  The original window may be obscured by other windows,
341435c4bbdfSmrgand the new window location may be similarly obscured.  Second, some
341535c4bbdfSmrghardware supports multiple windows with multiple depths, and your
341635c4bbdfSmrgroutine needs to take care of that.</para>
341735c4bbdfSmrg<para>
341835c4bbdfSmrgThe pixels in oldRegion (with reference point oldpt) are copied to the
341935c4bbdfSmrgwindow's new region (pWin->borderClip).  pWin->borderClip is gotten
342035c4bbdfSmrgdirectly from the window, rather than passing it as a parameter.</para>
342135c4bbdfSmrg<para>
342235c4bbdfSmrgThe sample server implementation is in Xserver/fb/fbwindow.c.</para>
342335c4bbdfSmrg</section>
342435c4bbdfSmrg<section>
342535c4bbdfSmrg<title>Screen Operations for Multi-Layered Framebuffers</title>
342635c4bbdfSmrg<para>
342735c4bbdfSmrgThe following screen functions are useful if you have a framebuffer with
342835c4bbdfSmrgmultiple sets of independent bit planes, e.g. overlays or underlays in
342935c4bbdfSmrgaddition to the "main" planes.  If you have a simple single-layer
343035c4bbdfSmrgframebuffer, you should probably use the mi versions of these routines
343135c4bbdfSmrgin mi/miwindow.c.  This can be easily accomplished by calling miScreenInit.</para>
343235c4bbdfSmrg<para>
343335c4bbdfSmrg<blockquote><programlisting>
343435c4bbdfSmrg
343535c4bbdfSmrg    void pScreen->MarkWindow(pWin)
343635c4bbdfSmrg	WindowPtr pWin;
343735c4bbdfSmrg
343835c4bbdfSmrg</programlisting></blockquote>
343935c4bbdfSmrgThis formerly dix function MarkWindow has moved to ddx and is accessed
344035c4bbdfSmrgvia this screen function.  This function should store something,
344135c4bbdfSmrgusually a pointer to a device-dependent structure, in pWin->valdata so
344235c4bbdfSmrgthat ValidateTree has the information it needs to validate the window.</para>
344335c4bbdfSmrg<para>
344435c4bbdfSmrg<blockquote><programlisting>
344535c4bbdfSmrg
344635c4bbdfSmrg    Bool pScreen->MarkOverlappedWindows(parent, firstChild, ppLayerWin)
344735c4bbdfSmrg	WindowPtr parent;
344835c4bbdfSmrg	WindowPtr firstChild;
344935c4bbdfSmrg	WindowPtr * ppLayerWin;
345035c4bbdfSmrg
345135c4bbdfSmrg</programlisting></blockquote>
345235c4bbdfSmrgThis formerly dix function MarkWindow has moved to ddx and is accessed
345335c4bbdfSmrgvia this screen function.  In the process, it has grown another
345435c4bbdfSmrgparameter: ppLayerWin, which is filled in with a pointer to the window
345535c4bbdfSmrgat which save under marking and ValidateTree should begin.  In the
345635c4bbdfSmrgsingle-layered framebuffer case, pLayerWin == pWin.</para>
345735c4bbdfSmrg<para>
345835c4bbdfSmrg<blockquote><programlisting>
345935c4bbdfSmrg
346035c4bbdfSmrg    Bool pScreen->ChangeSaveUnder(pLayerWin, firstChild)
346135c4bbdfSmrg	WindowPtr pLayerWin;
346235c4bbdfSmrg	WindowPtr firstChild;
346335c4bbdfSmrg
346435c4bbdfSmrg</programlisting></blockquote>
346535c4bbdfSmrgThe dix functions ChangeSaveUnder and CheckSaveUnder have moved to ddx and
346635c4bbdfSmrgare accessed via this screen function.  pLayerWin should be the window
346735c4bbdfSmrgreturned in the ppLayerWin parameter of MarkOverlappedWindows.  The function
346835c4bbdfSmrgmay turn on backing store for windows that might be covered, and may partially
346935c4bbdfSmrgturn off backing store for windows.  It returns TRUE if PostChangeSaveUnder
347035c4bbdfSmrgneeds to be called to finish turning off backing store.</para>
347135c4bbdfSmrg<para>
347235c4bbdfSmrg<blockquote><programlisting>
347335c4bbdfSmrg
347435c4bbdfSmrg    void pScreen->PostChangeSaveUnder(pLayerWin, firstChild)
347535c4bbdfSmrg	WindowPtr pLayerWin;
347635c4bbdfSmrg	WindowPtr firstChild;
347735c4bbdfSmrg
347835c4bbdfSmrg</programlisting></blockquote>
347935c4bbdfSmrgThe dix function DoChangeSaveUnder has moved to ddx and is accessed via
348035c4bbdfSmrgthis screen function.  This function completes the job of turning off
348135c4bbdfSmrgbacking store that was started by ChangeSaveUnder.</para>
348235c4bbdfSmrg<para>
348335c4bbdfSmrg<blockquote><programlisting>
348435c4bbdfSmrg
348535c4bbdfSmrg    void pScreen->MoveWindow(pWin, x, y, pSib, kind)
348635c4bbdfSmrg	WindowPtr pWin;
348735c4bbdfSmrg	int x;
348835c4bbdfSmrg	int y;
348935c4bbdfSmrg	WindowPtr pSib;
349035c4bbdfSmrg	VTKind kind;
349135c4bbdfSmrg
349235c4bbdfSmrg</programlisting></blockquote>
349335c4bbdfSmrgThe formerly dix function MoveWindow has moved to ddx and is accessed via
349435c4bbdfSmrgthis screen function.  The new position of the window is given by
349535c4bbdfSmrgx,y.  kind is VTMove if the window is only moving, or VTOther if
349635c4bbdfSmrgthe border is also changing.</para>
349735c4bbdfSmrg<para>
349835c4bbdfSmrg<blockquote><programlisting>
349935c4bbdfSmrg
350035c4bbdfSmrg    void pScreen->ResizeWindow(pWin, x, y, w, h, pSib)
350135c4bbdfSmrg	WindowPtr pWin;
350235c4bbdfSmrg	int x;
350335c4bbdfSmrg	int y;
350435c4bbdfSmrg	unsigned int w;
350535c4bbdfSmrg	unsigned int h;
350635c4bbdfSmrg	WindowPtr pSib;
350735c4bbdfSmrg
350835c4bbdfSmrg</programlisting></blockquote>
350935c4bbdfSmrgThe formerly dix function SlideAndSizeWindow has moved to ddx and is accessed via
351035c4bbdfSmrgthis screen function.  The new position is given by x,y.  The new size
351135c4bbdfSmrgis given by w,h.</para>
351235c4bbdfSmrg<para>
351335c4bbdfSmrg<blockquote><programlisting>
351435c4bbdfSmrg
351535c4bbdfSmrg    WindowPtr pScreen->GetLayerWindow(pWin)
351635c4bbdfSmrg	WindowPtr pWin
351735c4bbdfSmrg
351835c4bbdfSmrg</programlisting></blockquote>
351935c4bbdfSmrgThis is a new function which returns a child of the layer parent of pWin.</para>
352035c4bbdfSmrg<para>
352135c4bbdfSmrg<blockquote><programlisting>
352235c4bbdfSmrg
352335c4bbdfSmrg    void pScreen->HandleExposures(pWin)
352435c4bbdfSmrg	WindowPtr pWin;
352535c4bbdfSmrg
352635c4bbdfSmrg</programlisting></blockquote>
352735c4bbdfSmrgThe formerly dix function HandleExposures has moved to ddx and is accessed via
352835c4bbdfSmrgthis screen function.  This function is called after ValidateTree and
352935c4bbdfSmrguses the information contained in valdata to send exposures to windows.</para>
353035c4bbdfSmrg<para>
353135c4bbdfSmrg<blockquote><programlisting>
353235c4bbdfSmrg
353335c4bbdfSmrg    void pScreen->ReparentWindow(pWin, pPriorParent)
353435c4bbdfSmrg	WindowPtr pWin;
353535c4bbdfSmrg	WindowPtr pPriorParent;
353635c4bbdfSmrg
353735c4bbdfSmrg</programlisting></blockquote>
353835c4bbdfSmrgThis function will be called when a window is reparented.  At the time of
353935c4bbdfSmrgthe call, pWin will already be spliced into its new position in the
354035c4bbdfSmrgwindow tree, and pPriorParent is its previous parent.  This function
354135c4bbdfSmrgcan be NULL.</para>
354235c4bbdfSmrg<para>
354335c4bbdfSmrg<blockquote><programlisting>
354435c4bbdfSmrg
354535c4bbdfSmrg    void pScreen->SetShape(pWin)
354635c4bbdfSmrg	WindowPtr pWin;
354735c4bbdfSmrg
354835c4bbdfSmrg</programlisting></blockquote>
354935c4bbdfSmrgThe formerly dix function SetShape has moved to ddx and is accessed via
355035c4bbdfSmrgthis screen function.  The window's new shape will have already been
355135c4bbdfSmrgstored in the window when this function is called.</para>
355235c4bbdfSmrg<para>
355335c4bbdfSmrg<blockquote><programlisting>
355435c4bbdfSmrg
355535c4bbdfSmrg    void pScreen->ChangeBorderWidth(pWin, width)
355635c4bbdfSmrg	WindowPtr pWin;
355735c4bbdfSmrg	unsigned int width;
355835c4bbdfSmrg
355935c4bbdfSmrg</programlisting></blockquote>
356035c4bbdfSmrgThe formerly dix function ChangeBorderWidth has moved to ddx and is accessed via
356135c4bbdfSmrgthis screen function.  The new border width is given by width.</para>
356235c4bbdfSmrg<para>
356335c4bbdfSmrg<blockquote><programlisting>
356435c4bbdfSmrg
356535c4bbdfSmrg    void pScreen->MarkUnrealizedWindow(pChild, pWin, fromConfigure)
356635c4bbdfSmrg	WindowPtr pChild;
356735c4bbdfSmrg	WindowPtr pWin;
356835c4bbdfSmrg	Bool fromConfigure;
356935c4bbdfSmrg
357035c4bbdfSmrg</programlisting></blockquote>
357135c4bbdfSmrgThis function is called for windows that are being unrealized as part of
357235c4bbdfSmrgan UnrealizeTree.  pChild is the window being unrealized, pWin is an
357335c4bbdfSmrgancestor, and the fromConfigure value is simply propagated from UnrealizeTree.</para>
357435c4bbdfSmrg</section>
357535c4bbdfSmrg</section>
357635c4bbdfSmrg</section>
357735c4bbdfSmrg<section>
357835c4bbdfSmrg<title>Graphics Contexts and Validation</title>
357935c4bbdfSmrg<para>
358035c4bbdfSmrgThis graphics context (GC) contains state variables such as foreground and
358135c4bbdfSmrgbackground pixel value (color), the current line style and width,
358235c4bbdfSmrgthe current tile or stipple for pattern generation, the current font for text
358335c4bbdfSmrggeneration, and other similar attributes.</para>
358435c4bbdfSmrg<para>
358535c4bbdfSmrgIn many graphics systems, the equivalent of the graphics context and the
358635c4bbdfSmrgdrawable are combined as one entity.
358735c4bbdfSmrgThe main distinction between the two kinds of status is that a drawable
358835c4bbdfSmrgdescribes a writing surface and the writings that may have already been done
358935c4bbdfSmrgon it, whereas a graphics context describes the drawing process.
359035c4bbdfSmrgA drawable is like a chalkboard.
359135c4bbdfSmrgA GC is like a piece of chalk.</para>
359235c4bbdfSmrg<para>
359335c4bbdfSmrgUnlike many similar systems, there is no "current pen location."
359435c4bbdfSmrgEvery graphic operation is accompanied by the coordinates where it is to happen.</para>
359535c4bbdfSmrg<para>
359635c4bbdfSmrgThe GC also includes two vectors of procedure pointers, the first
359735c4bbdfSmrgoperate on the GC itself and are called GC funcs.  The second, called
359835c4bbdfSmrgGC ops,
359935c4bbdfSmrgcontains the functions that carry out the fundamental graphic operations
360035c4bbdfSmrgsuch as drawing lines, polygons, arcs, text, and copying bitmaps.
360135c4bbdfSmrgThe DDX graphic software can, if it
360235c4bbdfSmrgwants to be smart, change these two vectors of procedure pointers
360335c4bbdfSmrgto take advantage of hardware/firmware in the server machine, which can do
360435c4bbdfSmrga better job under certain circumstances.  To reduce the amount of memory
360535c4bbdfSmrgconsumed by each GC, it is wise to create a few "boilerplate" GC ops vectors
360635c4bbdfSmrgwhich can be shared by every GC which matches the constraints for that set.
360735c4bbdfSmrgAlso, it is usually reasonable to have every GC created by a particular
360835c4bbdfSmrgmodule to share a common set of GC funcs.  Samples of this sort of
360935c4bbdfSmrgsharing can be seen in fb/fbgc.c.</para>
361035c4bbdfSmrg<para>
361135c4bbdfSmrgThe DDX software is notified any time the client (or DIX) uses a changed GC.
361235c4bbdfSmrgFor instance, if the hardware has special support for drawing fixed-width
361335c4bbdfSmrgfonts, DDX can intercept changes to the current font in a GC just before
361435c4bbdfSmrgdrawing is done.  It can plug into either a fixed-width procedure that makes
361535c4bbdfSmrgthe hardware draw characters, or a variable-width procedure that carefully
361635c4bbdfSmrglays out glyphs by hand in software, depending upon the new font that is
361735c4bbdfSmrgselected.</para>
361835c4bbdfSmrg<para>
361935c4bbdfSmrgA definition of these structures can be found in the file
362035c4bbdfSmrgXserver/include/gcstruct.h.</para>
362135c4bbdfSmrg<para>
362235c4bbdfSmrgAlso included in each GC is support for dynamic devPrivates, which the
362335c4bbdfSmrgDDX can use for any purpose (see <xref linkend="wrappers_and_privates"/> below).</para>
362435c4bbdfSmrg<para>
362535c4bbdfSmrgThe DIX routines available for manipulating GCs are
362635c4bbdfSmrgCreateGC, ChangeGC, ChangeGCXIDs, CopyGC, SetClipRects, SetDashes, and FreeGC.
362735c4bbdfSmrg<blockquote><programlisting>
362835c4bbdfSmrg
362935c4bbdfSmrg	GCPtr CreateGC(pDrawable, mask, pval, pStatus)
363035c4bbdfSmrg	    DrawablePtr pDrawable;
363135c4bbdfSmrg	    BITS32 mask;
363235c4bbdfSmrg	    XID *pval;
363335c4bbdfSmrg	    int *pStatus;
363435c4bbdfSmrg
363535c4bbdfSmrg	int ChangeGC(client, pGC, mask, pUnion)
363635c4bbdfSmrg	    ClientPtr client;
363735c4bbdfSmrg	    GCPtr pGC;
363835c4bbdfSmrg	    BITS32 mask;
363935c4bbdfSmrg	    ChangeGCValPtr pUnion;
364035c4bbdfSmrg
364135c4bbdfSmrg	int ChangeGCXIDs(client, pGC, mask, pC32)
364235c4bbdfSmrg	    ClientPtr client;
364335c4bbdfSmrg	    GCPtr pGC;
364435c4bbdfSmrg	    BITS32 mask;
364535c4bbdfSmrg	    CARD32 *pC32;
364635c4bbdfSmrg
364735c4bbdfSmrg	int CopyGC(pgcSrc, pgcDst, mask)
364835c4bbdfSmrg	    GCPtr pgcSrc;
364935c4bbdfSmrg	    GCPtr pgcDst;
365035c4bbdfSmrg	    BITS32 mask;
365135c4bbdfSmrg
365235c4bbdfSmrg	int SetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering)
365335c4bbdfSmrg	    GCPtr pGC;
365435c4bbdfSmrg	    int xOrigin, yOrigin;
365535c4bbdfSmrg	    int nrects;
365635c4bbdfSmrg	    xRectangle *prects;
365735c4bbdfSmrg	    int ordering;
365835c4bbdfSmrg
365935c4bbdfSmrg	SetDashes(pGC, offset, ndash, pdash)
366035c4bbdfSmrg	    GCPtr pGC;
366135c4bbdfSmrg	    unsigned offset;
366235c4bbdfSmrg	    unsigned ndash;
366335c4bbdfSmrg	    unsigned char *pdash;
366435c4bbdfSmrg
366535c4bbdfSmrg	int FreeGC(pGC, gid)
366635c4bbdfSmrg	    GCPtr pGC;
366735c4bbdfSmrg	    GContext gid;
366835c4bbdfSmrg
366935c4bbdfSmrg</programlisting></blockquote>
367035c4bbdfSmrg</para>
367135c4bbdfSmrg<para>
367235c4bbdfSmrgAs a convenience, each Screen structure contains an array of
367335c4bbdfSmrgGCs that are preallocated, one at each depth the screen supports.
367435c4bbdfSmrgThese are particularly useful in the mi code.  Two DIX routines
367535c4bbdfSmrgmust be used to get these GCs:
367635c4bbdfSmrg<blockquote><programlisting>
367735c4bbdfSmrg
367835c4bbdfSmrg	GCPtr GetScratchGC(depth, pScreen)
367935c4bbdfSmrg	    int depth;
368035c4bbdfSmrg	    ScreenPtr pScreen;
368135c4bbdfSmrg
368235c4bbdfSmrg	FreeScratchGC(pGC)
368335c4bbdfSmrg	    GCPtr pGC;
368435c4bbdfSmrg
368535c4bbdfSmrg</programlisting></blockquote>
368635c4bbdfSmrgAlways use these two routines, don't try to extract the scratch
368735c4bbdfSmrgGC yourself -- someone else might be using it, so a new one must
368835c4bbdfSmrgbe created on the fly.</para>
368935c4bbdfSmrg<para>
369035c4bbdfSmrgIf you need a GC for a very long time, say until the server is restarted,
369135c4bbdfSmrgyou should not take one from the pool used by GetScratchGC, but should
369235c4bbdfSmrgget your own using CreateGC or CreateScratchGC.
369335c4bbdfSmrgThis leaves the ones in the pool free for routines that only need it for
369435c4bbdfSmrga little while and don't want to pay a heavy cost to get it.
369535c4bbdfSmrg<blockquote><programlisting>
369635c4bbdfSmrg
369735c4bbdfSmrg	GCPtr CreateScratchGC(pScreen, depth)
369835c4bbdfSmrg	    ScreenPtr pScreen;
369935c4bbdfSmrg	    int depth;
370035c4bbdfSmrg
370135c4bbdfSmrg</programlisting></blockquote>
370235c4bbdfSmrgNULL is returned if the GC cannot be created.
370335c4bbdfSmrgThe GC returned can be freed with FreeScratchGC.</para>
370435c4bbdfSmrg<section>
370535c4bbdfSmrg  <title>Details of Operation</title>
370635c4bbdfSmrg<para>
370735c4bbdfSmrgAt screen initialization, a screen must supply a GC creation procedure.
370835c4bbdfSmrgAt GC creation, the screen must fill in GC funcs and GC ops vectors
370935c4bbdfSmrg(Xserver/include/gcstruct.h).  For any particular GC, the func vector
371035c4bbdfSmrgmust remain constant, while the op vector may vary.  This invariant is to
371135c4bbdfSmrgensure that Wrappers work correctly.</para>
371235c4bbdfSmrg<para>
371335c4bbdfSmrgWhen a client request is processed that results in a change
371435c4bbdfSmrgto the GC, the device-independent state of the GC is updated.
371535c4bbdfSmrgThis includes a record of the state that changed.
371635c4bbdfSmrgThen the ChangeGC GC func is called.
371735c4bbdfSmrgThis is useful for graphics subsystems that are able to process
371835c4bbdfSmrgstate changes in parallel with the server CPU.
371935c4bbdfSmrgDDX may opt not to take any action at GC-modify time.
372035c4bbdfSmrgThis is more efficient if multiple GC-modify requests occur
372135c4bbdfSmrgbetween draws using a given GC.</para>
372235c4bbdfSmrg<para>
372335c4bbdfSmrgValidation occurs at the first draw operation that specifies the GC after
372435c4bbdfSmrgthat GC was modified.  DIX calls then the ValidateGC GC func.  DDX should
372535c4bbdfSmrgthen update its internal state.  DDX internal state may be stored as one or
372635c4bbdfSmrgmore of the following:  1) device private block on the GC; 2) hardware
372735c4bbdfSmrgstate; 3) changes to the GC ops.</para>
372835c4bbdfSmrg<para>
372935c4bbdfSmrgThe GC contains a serial number, which is loaded with a number fetched from
373035c4bbdfSmrgthe window that was drawn into the last time the GC was used.  The serial
373135c4bbdfSmrgnumber in the drawable is changed when the drawable's
373235c4bbdfSmrgclipList or absCorner changes.  Thus, by
373335c4bbdfSmrgcomparing the GC serial number with the drawable serial number, DIX can
373435c4bbdfSmrgforce a validate if the drawable has been changed since the last time it
373535c4bbdfSmrgwas used with this GC.</para>
373635c4bbdfSmrg<para>
373735c4bbdfSmrgIn addition, the drawable serial number is always guaranteed to have the
373835c4bbdfSmrgmost significant bit set to 0.  Thus, the DDX layer can set the most
373935c4bbdfSmrgsignificant bit of the serial number to 1 in a GC to force a validate the next time
374035c4bbdfSmrgthe GC is used.  DIX also uses this technique to indicate that a change has
374135c4bbdfSmrgbeen made to the GC by way of a SetGC, a SetDashes or a SetClip request.</para>
374235c4bbdfSmrg</section>
374335c4bbdfSmrg<section>
374435c4bbdfSmrg  <title>GC Handling Routines</title>
374535c4bbdfSmrg<para>
374635c4bbdfSmrgThe ScreenRec data structure has a pointer for
374735c4bbdfSmrgCreateGC().
374835c4bbdfSmrg<blockquote><programlisting>
374935c4bbdfSmrg
375035c4bbdfSmrg	Bool pScreen->CreateGC(pGC)
375135c4bbdfSmrg		GCPtr pGC;
375235c4bbdfSmrg</programlisting></blockquote>
375335c4bbdfSmrgThis routine must fill in the fields of
375435c4bbdfSmrga dynamically allocated GC that is passed in.
375535c4bbdfSmrgIt does NOT allocate the GC record itself or fill
375635c4bbdfSmrgin the defaults; DIX does that.</para>
375735c4bbdfSmrg<para>
375835c4bbdfSmrgThis must fill in both the GC funcs and ops; none of the drawing
375935c4bbdfSmrgfunctions will be called before the GC has been validated,
376035c4bbdfSmrgbut the others (dealing with allocating of clip regions,
376135c4bbdfSmrgchanging and destroying the GC, etc.) might be.</para>
376235c4bbdfSmrg<para>
376335c4bbdfSmrgThe GC funcs vector contains pointers to 7
376435c4bbdfSmrgroutines and a devPrivate field:
376535c4bbdfSmrg<blockquote><programlisting>
376635c4bbdfSmrg
376735c4bbdfSmrg	pGC->funcs->ChangeGC(pGC, changes)
376835c4bbdfSmrg		GCPtr pGC;
376935c4bbdfSmrg		unsigned long changes;
377035c4bbdfSmrg
377135c4bbdfSmrg</programlisting></blockquote>
377235c4bbdfSmrgThis GC func is called immediately after a field in the GC is changed.
377335c4bbdfSmrgchanges is a bit mask indicating the changed fields of the GC in this
377435c4bbdfSmrgrequest.</para>
377535c4bbdfSmrg<para>
377635c4bbdfSmrgThe ChangeGC routine is useful if you have a system where
377735c4bbdfSmrgstate-changes to the GC can be swallowed immediately by your graphics
377835c4bbdfSmrgsystem, and a validate is not necessary.</para>
377935c4bbdfSmrg<para>
378035c4bbdfSmrg<blockquote><programlisting>
378135c4bbdfSmrg
378235c4bbdfSmrg	pGC->funcs->ValidateGC(pGC, changes, pDraw)
378335c4bbdfSmrg		GCPtr pGC;
378435c4bbdfSmrg		unsigned long changes;
378535c4bbdfSmrg		DrawablePtr pDraw;
378635c4bbdfSmrg
378735c4bbdfSmrg</programlisting></blockquote>
378835c4bbdfSmrgValidateGC is called by DIX just before the GC will be used when one
378935c4bbdfSmrgof many possible changes to the GC or the graphics system has
379035c4bbdfSmrghappened.  It can modify devPrivates data attached to the GC,
379135c4bbdfSmrgchange the op vector, or change hardware according to the
379235c4bbdfSmrgvalues in the GC.  It may not change the device-independent portion of
379335c4bbdfSmrgthe GC itself.</para>
379435c4bbdfSmrg<para>
379535c4bbdfSmrgIn almost all cases, your ValidateGC() procedure should take the
379635c4bbdfSmrgregions that drawing needs to be clipped to and combine them into a
379735c4bbdfSmrgcomposite clip region, which you keep a pointer to in the private part
379835c4bbdfSmrgof the GC.  In this way, your drawing primitive routines (and whatever
379935c4bbdfSmrgis below them) can easily determine what to clip and where.  You
380035c4bbdfSmrgshould combine the regions clientClip (the region that the client
380135c4bbdfSmrgdesires to clip output to) and the region returned by
380235c4bbdfSmrgNotClippedByChildren(), in DIX.  An example is in Xserver/fb/fbgc.c.</para>
380335c4bbdfSmrg<para>
380435c4bbdfSmrgSome kinds of extension software may cause this routine to be called
380535c4bbdfSmrgmore than originally intended; you should not rely on algorithms that
380635c4bbdfSmrgwill break under such circumstances.</para>
380735c4bbdfSmrg<para>
380835c4bbdfSmrgSee the Strategies document for more information on creatively using
380935c4bbdfSmrgthis routine.</para>
381035c4bbdfSmrg<para>
381135c4bbdfSmrg<blockquote><programlisting>
381235c4bbdfSmrg
381335c4bbdfSmrg	pGC->funcs->CopyGC(pGCSrc, mask, pGCDst)
381435c4bbdfSmrg		GCPtr pGCSrc;
381535c4bbdfSmrg		unsigned long mask;
381635c4bbdfSmrg		GCPtr pGCDst;
381735c4bbdfSmrg
381835c4bbdfSmrg</programlisting></blockquote>
381935c4bbdfSmrgThis routine is called by DIX when a GC is being copied to another GC.
382035c4bbdfSmrgThis is for situations where dynamically allocated chunks of memory
382135c4bbdfSmrgare stored in the GC's dynamic devPrivates and need to be transferred to
382235c4bbdfSmrgthe destination GC.</para>
382335c4bbdfSmrg<para>
382435c4bbdfSmrg<blockquote><programlisting>
382535c4bbdfSmrg
382635c4bbdfSmrg	pGC->funcs->DestroyGC(pGC)
382735c4bbdfSmrg		GCPtr pGC;
382835c4bbdfSmrg
382935c4bbdfSmrg</programlisting></blockquote>
383035c4bbdfSmrgThis routine is called before the GC is destroyed for the
383135c4bbdfSmrgentity interested in this GC to clean up after itself.
383235c4bbdfSmrgThis routine is responsible for freeing any auxiliary storage allocated.</para>
383335c4bbdfSmrg</section>
383435c4bbdfSmrg<section>
383535c4bbdfSmrg  <title>GC Clip Region Routines</title>
383635c4bbdfSmrg<para>
383735c4bbdfSmrgThe GC clientClip field requires three procedures to manage it.  These
383835c4bbdfSmrgprocedures are in the GC funcs vector.  The underlying principle is that dix
383935c4bbdfSmrgknows nothing about the internals of the clipping information, (except when
384035c4bbdfSmrgit has come from the client), and so calls ddX whenever it needs to copy,
384135c4bbdfSmrgset, or destroy such information.  It could have been possible for dix not
384235c4bbdfSmrgto allow ddX to touch the field in the GC, and require it to keep its own
384335c4bbdfSmrgcopy in devPriv, but since clip masks can be very large, this seems like a
384435c4bbdfSmrgbad idea.  Thus, the server allows ddX to do whatever it wants to the
384535c4bbdfSmrgclientClip field of the GC, but requires it to do all manipulation itself.</para>
384635c4bbdfSmrg<para>
384735c4bbdfSmrg<blockquote><programlisting>
384835c4bbdfSmrg
384935c4bbdfSmrg	void pGC->funcs->ChangeClip(pGC, type, pValue, nrects)
385035c4bbdfSmrg		GCPtr pGC;
385135c4bbdfSmrg		int type;
385235c4bbdfSmrg		char *pValue;
385335c4bbdfSmrg		int nrects;
385435c4bbdfSmrg
385535c4bbdfSmrg</programlisting></blockquote>
385635c4bbdfSmrgThis routine is called whenever the client changes the client clip
385735c4bbdfSmrgregion.  The pGC points to the GC involved, the type tells what form
385835c4bbdfSmrgthe region has been sent in.  If type is CT_NONE, then there is no
385935c4bbdfSmrgclient clip.  If type is CT_UNSORTED, CT_YBANDED or CT_YXBANDED, then
386035c4bbdfSmrgpValue pointer to a list of rectangles, nrects long.  If type is
386135c4bbdfSmrgCT_REGION, then pValue pointer to a RegionRec from the mi region code.
386235c4bbdfSmrgIf type is CT_PIXMAP pValue is a pointer to a pixmap.  (The defines
386335c4bbdfSmrgfor CT_NONE, etc. are in Xserver/include/gc.h.)  This routine is
386435c4bbdfSmrgresponsible for incrementing any necessary reference counts (e.g. for
386535c4bbdfSmrga pixmap clip mask) for the new clipmask and freeing anything that
386635c4bbdfSmrgused to be in the GC's clipMask field.  The lists of rectangles passed
386735c4bbdfSmrgin can be freed with free(), the regions can be destroyed with the
386835c4bbdfSmrgRegionDestroy field in the screen, and pixmaps can be destroyed by
386935c4bbdfSmrgcalling the screen's DestroyPixmap function.  DIX and MI code expect
387035c4bbdfSmrgwhat they pass in to this to be freed or otherwise inaccessible, and
387135c4bbdfSmrgwill never look inside what's been put in the GC.  This is a good
387235c4bbdfSmrgplace to be wary of storage leaks.</para>
387335c4bbdfSmrg<para>
387435c4bbdfSmrgIn the sample server, this routine transforms either the bitmap or the
387535c4bbdfSmrgrectangle list into a region, so that future routines will have a more
387635c4bbdfSmrgpredictable starting point to work from.  (The validate routine must
387735c4bbdfSmrgtake this client clip region and merge it with other regions to arrive
387835c4bbdfSmrgat a composite clip region before any drawing is done.)</para>
387935c4bbdfSmrg<para>
388035c4bbdfSmrg<blockquote><programlisting>
388135c4bbdfSmrg
388235c4bbdfSmrg	void pGC->funcs->DestroyClip(pGC)
388335c4bbdfSmrg		GCPtr pGC;
388435c4bbdfSmrg
388535c4bbdfSmrg</programlisting></blockquote>
388635c4bbdfSmrgThis routine is called whenever the client clip region must be destroyed.
388735c4bbdfSmrgThe pGC points to the GC involved.  This call should set the clipType
388835c4bbdfSmrgfield of the GC to CT_NONE.
388935c4bbdfSmrgIn the sample server, the pointer to the client clip region is set to NULL
389035c4bbdfSmrgby this routine after destroying the region, so that other software
389135c4bbdfSmrg(including ChangeClip() above) will recognize that there is no client clip region.</para>
389235c4bbdfSmrg<para>
389335c4bbdfSmrg<blockquote><programlisting>
389435c4bbdfSmrg
389535c4bbdfSmrg	void pGC->funcs->CopyClip(pgcDst, pgcSrc)
389635c4bbdfSmrg		GCPtr pgcDst, pgcSrc;
389735c4bbdfSmrg
389835c4bbdfSmrg</programlisting></blockquote>
389935c4bbdfSmrgThis routine makes a copy of the clipMask and clipType from pgcSrc
390035c4bbdfSmrginto pgcDst.  It is responsible for destroying any previous clipMask
390135c4bbdfSmrgin pgcDst.  The clip mask in the source can be the same as the
390235c4bbdfSmrgclip mask in the dst (clients do the strangest things), so care must
390335c4bbdfSmrgbe taken when destroying things.  This call is required because dix
390435c4bbdfSmrgdoes not know how to copy the clip mask from pgcSrc.</para>
390535c4bbdfSmrg</section>
390635c4bbdfSmrg</section>
390735c4bbdfSmrg<section>
390835c4bbdfSmrg  <title>Drawing Primitives</title>
390935c4bbdfSmrg<para>
391035c4bbdfSmrgThe X protocol (rules for the byte stream that goes between client and server)
391135c4bbdfSmrgdoes all graphics using primitive
391235c4bbdfSmrgoperations, which are called Drawing Primitives.
391335c4bbdfSmrgThese include line drawing, area filling, arcs, and text drawing.
391435c4bbdfSmrgYour implementation must supply 16 routines
391535c4bbdfSmrgto perform these on your hardware.
391635c4bbdfSmrg(The number 16 is arbitrary.)</para>
391735c4bbdfSmrg<para>
391835c4bbdfSmrgMore specifically, 16 procedure pointers are in each
391935c4bbdfSmrgGC op vector.
392035c4bbdfSmrgAt any given time, ALL of them MUST point to a valid procedure that
392135c4bbdfSmrgattempts to do the operation assigned, although
392235c4bbdfSmrgthe procedure pointers may change and may
392335c4bbdfSmrgpoint to different procedures to carry out the same operation.
392435c4bbdfSmrgA simple server will leave them all pointing to the same 16 routines, while
392535c4bbdfSmrga more optimized implementation will switch each from one
392635c4bbdfSmrgprocedure to another, depending upon what is most optimal
392735c4bbdfSmrgfor the current GC and drawable.</para>
392835c4bbdfSmrg<para>
392935c4bbdfSmrgThe sample server contains a considerable chunk of code called the
393035c4bbdfSmrgmi (machine independent)
393135c4bbdfSmrgroutines, which serve as drawing primitive routines.
393235c4bbdfSmrgMany server implementations will be able to use these as-is,
393335c4bbdfSmrgbecause they work for arbitrary depths.
393435c4bbdfSmrgThey make no assumptions about the formats of pixmaps
393535c4bbdfSmrgand frame buffers, since they call a set of routines
393635c4bbdfSmrgknown as the "Pixblit Routines" (see next section).
393735c4bbdfSmrgThey do assume that the way to draw is
393835c4bbdfSmrgthrough these low-level routines that apply pixel values rows at a time.
393935c4bbdfSmrgIf your hardware or firmware gives more performance when
394035c4bbdfSmrgthings are done differently, you will want to take this fact into account
394135c4bbdfSmrgand rewrite some or all of the drawing primitives to fit your needs.</para>
394235c4bbdfSmrg<section>
394335c4bbdfSmrg  <title>GC Components</title>
394435c4bbdfSmrg<para>
394535c4bbdfSmrgThis section describes the fields in the GC that affect each drawing primitive.
394635c4bbdfSmrgThe only primitive that is not affected is GetImage, which does not use a GC
394735c4bbdfSmrgbecause its destination is a protocol-style bit image.
394835c4bbdfSmrgSince each drawing primitive mirrors exactly the X protocol request of the
394935c4bbdfSmrgsame name, you should refer to the X protocol specification document
395035c4bbdfSmrgfor more details.</para>
395135c4bbdfSmrg<para>
395235c4bbdfSmrgALL of these routines MUST CLIP to the
395335c4bbdfSmrgappropriate regions in the drawable.
395435c4bbdfSmrgSince there are many regions to clip to simultaneously,
395535c4bbdfSmrgyour ValidateGC routine should combine these into a unified
395635c4bbdfSmrgclip region to which your drawing routines can quickly refer.
395735c4bbdfSmrgThis is exactly what the fb routines supplied with the sample server
395835c4bbdfSmrgdo.
395935c4bbdfSmrgThe mi implementation passes responsibility for clipping while drawing
396035c4bbdfSmrgdown to the Pixblit routines.</para>
396135c4bbdfSmrg<para>
396235c4bbdfSmrgAlso, all of them must adhere to the current plane mask.
396335c4bbdfSmrgThe plane mask has one bit for every bit plane in the drawable;
396435c4bbdfSmrgonly planes with 1 bits in the mask are affected by any drawing operation.</para>
396535c4bbdfSmrg<para>
396635c4bbdfSmrgAll functions except for ImageText calls must obey the alu function.
396735c4bbdfSmrgThis is usually Copy, but could be any of the allowable 16 raster-ops.</para>
396835c4bbdfSmrg<para>
396935c4bbdfSmrgAll of the functions, except for CopyArea, might use the current
397035c4bbdfSmrgforeground and background pixel values.
397135c4bbdfSmrgEach pixel value is 32 bits.
397235c4bbdfSmrgThese correspond to foreground and background colors, but you have
397335c4bbdfSmrgto run them through the colormap to find out what color the pixel values
397435c4bbdfSmrgrepresent.  Do not worry about the color, just apply the pixel value.</para>
397535c4bbdfSmrg<para>
397635c4bbdfSmrgThe routines that draw lines (PolyLine, PolySegment, PolyRect, and PolyArc)
397735c4bbdfSmrguse the line width, line style, cap style, and join style.
397835c4bbdfSmrgLine width is in pixels.
397935c4bbdfSmrgThe line style specifies whether it is solid or dashed, and what kind of dash.
398035c4bbdfSmrgThe cap style specifies whether Rounded, Butt, etc.
398135c4bbdfSmrgThe join style specifies whether joins between joined lines are Miter, Round or Beveled.
398235c4bbdfSmrgWhen lines cross as part of the same polyline, they are assumed to be drawn once.
398335c4bbdfSmrg(See the X protocol specification for more details.)</para>
398435c4bbdfSmrg<para>
398535c4bbdfSmrgZero-width lines are NOT meant to be really zero width; this is the client's way
398635c4bbdfSmrgof telling you that you can optimize line drawing with little regard to
398735c4bbdfSmrgthe end caps and joins.
398835c4bbdfSmrgThey are called "thin" lines and are meant to be one pixel wide.
398935c4bbdfSmrgThese are frequently done in hardware or in a streamlined assembly language
399035c4bbdfSmrgroutine.</para>
399135c4bbdfSmrg<para>
399235c4bbdfSmrgLines with widths greater than zero, though, must all be drawn with the same
399335c4bbdfSmrgalgorithm, because client software assumes that every jag on every
399435c4bbdfSmrgline at an angle will come at the same place.
399535c4bbdfSmrgTwo lines that should have
399635c4bbdfSmrgone pixel in the space between them
399735c4bbdfSmrg(because of their distance apart and their widths) should have such a one-pixel line
399835c4bbdfSmrgof space between them if drawn, regardless of angle.</para>
399935c4bbdfSmrg<para>
400035c4bbdfSmrgThe solid area fill routines (FillPolygon, PolyFillRect, PolyFillArc)
400135c4bbdfSmrgall use the fill rule, which specifies subtle interpretations of
400235c4bbdfSmrgwhat points are inside and what are outside of a given polygon.
400335c4bbdfSmrgThe PolyFillArc routine also uses the arc mode, which specifies
400435c4bbdfSmrgwhether to fill pie segments or single-edge slices of an ellipse.</para>
400535c4bbdfSmrg<para>
400635c4bbdfSmrgThe line drawing, area fill, and PolyText routines must all
400735c4bbdfSmrgapply the correct "fill style."
400835c4bbdfSmrgThis can be either a solid foreground color, a transparent stipple,
400935c4bbdfSmrgan opaque stipple, or a tile.
401035c4bbdfSmrgStipples are bitmaps where the 1 bits represent that the foreground color is written,
401135c4bbdfSmrgand 0 bits represent that either the pixel is left alone (transparent) or that
401235c4bbdfSmrgthe background color is written (opaque).
401335c4bbdfSmrgA tile is a pixmap of the full depth of the GC that is applied in its full glory to all areas.
401435c4bbdfSmrgThe stipple and tile patterns can be any rectangular size, although some implementations
401535c4bbdfSmrgwill be faster for certain sizes such as 8x8 or 32x32.
401635c4bbdfSmrgThe mi implementation passes this responsibility down to the Pixblit routines.</para>
401735c4bbdfSmrg<para>
401835c4bbdfSmrgSee the X protocol document for full details.
401935c4bbdfSmrgThe description of the CreateGC request has a very good, detailed description of these
402035c4bbdfSmrgattributes.</para>
402135c4bbdfSmrg</section>
402235c4bbdfSmrg<section>
402335c4bbdfSmrg<title>The Primitives</title>
402435c4bbdfSmrg<para>
402535c4bbdfSmrgThe Drawing Primitives are as follows:
402635c4bbdfSmrg
402735c4bbdfSmrg<blockquote><programlisting>
402835c4bbdfSmrg
402935c4bbdfSmrg	RegionPtr pGC->ops->CopyArea(src, dst, pGC, srcx, srcy, w, h, dstx, dsty)
403035c4bbdfSmrg		DrawablePtr dst, src;
403135c4bbdfSmrg		GCPtr pGC;
403235c4bbdfSmrg		int srcx, srcy, w, h, dstx, dsty;
403335c4bbdfSmrg
403435c4bbdfSmrg</programlisting></blockquote>
403535c4bbdfSmrgCopyArea copies a rectangle of pixels from one drawable to another of
403635c4bbdfSmrgthe same depth.  To effect scrolling, this must be able to copy from
403735c4bbdfSmrgany drawable to itself, overlapped.  No squeezing or stretching is done
403835c4bbdfSmrgbecause the source and destination are the same size.  However,
403935c4bbdfSmrgeverything is still clipped to the clip regions of the destination
404035c4bbdfSmrgdrawable.</para>
404135c4bbdfSmrg<para>
404235c4bbdfSmrgIf pGC->graphicsExposures is True, any portions of the destination which
404335c4bbdfSmrgwere not valid in the source (either occluded by covering windows, or
404435c4bbdfSmrgoutside the bounds of the drawable) should be collected together and
404535c4bbdfSmrgreturned as a region (if this resultant region is empty, NULL can be
404635c4bbdfSmrgreturned instead).  Furthermore, the invalid bits of the source are
404735c4bbdfSmrgnot copied to the destination and (when the destination is a window)
404835c4bbdfSmrgare filled with the background tile.  The sample routine
404935c4bbdfSmrgmiHandleExposures generates the appropriate return value and fills the
405035c4bbdfSmrginvalid area using pScreen->PaintWindowBackground.</para>
405135c4bbdfSmrg<para>
405235c4bbdfSmrgFor instance, imagine a window that is partially obscured by other
405335c4bbdfSmrgwindows in front of it.  As text is scrolled on your window, the pixels
405435c4bbdfSmrgthat are scrolled out from under obscuring windows will not be
405535c4bbdfSmrgavailable on the screen to copy to the right places, and so an exposure
405635c4bbdfSmrgevent must be sent for the client to correctly repaint them.  Of
405735c4bbdfSmrgcourse, if you implement backing store, you could do this without resorting
405835c4bbdfSmrgto exposure events.</para>
405935c4bbdfSmrg<para>
406035c4bbdfSmrgAn example implementation is fbCopyArea() in Xserver/fb/fbcopy.c.</para>
406135c4bbdfSmrg<para>
406235c4bbdfSmrg<blockquote><programlisting>
406335c4bbdfSmrg
406435c4bbdfSmrg	RegionPtr pGC->ops->CopyPlane(src, dst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
406535c4bbdfSmrg		DrawablePtr dst, src;
406635c4bbdfSmrg		GCPtr pGC;
406735c4bbdfSmrg		int srcx, srcy, w, h, dstx, dsty;
406835c4bbdfSmrg		unsigned long plane;
406935c4bbdfSmrg
407035c4bbdfSmrg</programlisting></blockquote>
407135c4bbdfSmrgCopyPlane must copy one plane of a rectangle from the source drawable
407235c4bbdfSmrgonto the destination drawable.  Because this routine only copies one
407335c4bbdfSmrgbit out of each pixel, it can copy between drawables of different
407435c4bbdfSmrgdepths.  This is the only way of copying between drawables of
407535c4bbdfSmrgdifferent depths, except for copying bitmaps to pixmaps and applying
407635c4bbdfSmrgforeground and background colors to it.  All other conditions of
407735c4bbdfSmrgCopyArea apply to CopyPlane too.</para>
407835c4bbdfSmrg<para>
407935c4bbdfSmrgAn example implementation is fbCopyPlane() in
408035c4bbdfSmrgXserver/fb/fbcopy.c.</para>
408135c4bbdfSmrg<para>
408235c4bbdfSmrg<blockquote><programlisting>
408335c4bbdfSmrg
408435c4bbdfSmrg	void pGC->ops->PolyPoint(dst, pGC, mode, n, pPoint)
408535c4bbdfSmrg		DrawablePtr dst;
408635c4bbdfSmrg		GCPtr pGC;
408735c4bbdfSmrg		int mode;
408835c4bbdfSmrg		int n;
408935c4bbdfSmrg		DDXPointPtr pPoint;
409035c4bbdfSmrg
409135c4bbdfSmrg</programlisting></blockquote>
409235c4bbdfSmrgPolyPoint draws a set of one-pixel dots (foreground color)
409335c4bbdfSmrgat the locations given in the array.
409435c4bbdfSmrgmode is one of the defined constants Origin (absolute coordinates) or Previous
409535c4bbdfSmrg(each coordinate is relative to the last).
409635c4bbdfSmrgNote that this does not use the background color or any tiles or stipples.</para>
409735c4bbdfSmrg<para>
409835c4bbdfSmrgExample implementations are fbPolyPoint() in Xserver/fb/fbpoint.c and
409935c4bbdfSmrgmiPolyPoint in Xserver/mi/mipolypnt.c.</para>
410035c4bbdfSmrg<para>
410135c4bbdfSmrg<blockquote><programlisting>
410235c4bbdfSmrg
410335c4bbdfSmrg	void pGC->ops->Polylines(dst, pGC, mode, n, pPoint)
410435c4bbdfSmrg		DrawablePtr dst;
410535c4bbdfSmrg		GCPtr pGC;
410635c4bbdfSmrg		int mode;
410735c4bbdfSmrg		int n;
410835c4bbdfSmrg		DDXPointPtr pPoint;
410935c4bbdfSmrg
411035c4bbdfSmrg</programlisting></blockquote>
411135c4bbdfSmrgSimilar to PolyPoint, Polylines draws lines between the locations given in the array.
411235c4bbdfSmrgZero-width lines are NOT meant to be really zero width; this is the client's way of
411335c4bbdfSmrgtelling you that you can maximally optimize line drawing with little regard to
411435c4bbdfSmrgthe end caps and joins.
411535c4bbdfSmrgmode is one of the defined constants Previous or Origin, depending upon
411635c4bbdfSmrgwhether the points are each relative to the last or are absolute.</para>
411735c4bbdfSmrg<para>
411835c4bbdfSmrgExample implementations are miWideLine() and miWideDash() in
411935c4bbdfSmrgmi/miwideline.c and miZeroLine() in mi/mizerline.c.</para>
412035c4bbdfSmrg<para>
412135c4bbdfSmrg<blockquote><programlisting>
412235c4bbdfSmrg
412335c4bbdfSmrg	void pGC->ops->PolySegment(dst, pGC, n, pPoint)
412435c4bbdfSmrg		DrawablePtr dst;
412535c4bbdfSmrg		GCPtr pGC;
412635c4bbdfSmrg		int n;
412735c4bbdfSmrg		xSegment *pSegments;
412835c4bbdfSmrg
412935c4bbdfSmrg</programlisting></blockquote>
413035c4bbdfSmrgPolySegments draws unconnected
413135c4bbdfSmrglines between pairs of points in the array; the array must be of
413235c4bbdfSmrgeven size; no interconnecting lines are drawn.</para>
413335c4bbdfSmrg<para>
413435c4bbdfSmrgAn example implementation is miPolySegment() in mipolyseg.c.</para>
413535c4bbdfSmrg<para>
413635c4bbdfSmrg<blockquote><programlisting>
413735c4bbdfSmrg
413835c4bbdfSmrg	void pGC->ops->PolyRectangle(dst, pGC, n, pRect)
413935c4bbdfSmrg		DrawablePtr dst;
414035c4bbdfSmrg		GCPtr pGC;
414135c4bbdfSmrg		int n;
414235c4bbdfSmrg		xRectangle *pRect;
414335c4bbdfSmrg
414435c4bbdfSmrg</programlisting></blockquote>
414535c4bbdfSmrgPolyRectangle draws outlines of rectangles for each rectangle in the array.</para>
414635c4bbdfSmrg<para>
414735c4bbdfSmrgAn example implementation is miPolyRectangle() in Xserver/mi/mipolyrect.c.</para>
414835c4bbdfSmrg<para>
414935c4bbdfSmrg<blockquote><programlisting>
415035c4bbdfSmrg
415135c4bbdfSmrg	void pGC->ops->PolyArc(dst, pGC, n, pArc)
415235c4bbdfSmrg		DrawablePtr dst;
415335c4bbdfSmrg		GCPtr pGC;
415435c4bbdfSmrg		int n;
415535c4bbdfSmrg		xArc*pArc;
415635c4bbdfSmrg
415735c4bbdfSmrg</programlisting></blockquote>
415835c4bbdfSmrgPolyArc draws connected conic arcs according to the descriptions in the array.
415935c4bbdfSmrgSee the protocol specification for more details.</para>
416035c4bbdfSmrg<para>
416135c4bbdfSmrgExample implementations are miZeroPolyArc in Xserver/mi/mizerarc. and
416235c4bbdfSmrgmiPolyArc() in Xserver/mi/miarc.c.</para>
416335c4bbdfSmrg<para>
416435c4bbdfSmrg<blockquote><programlisting>
416535c4bbdfSmrg
416635c4bbdfSmrg	void pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pPoint)
416735c4bbdfSmrg		DrawablePtr dst;
416835c4bbdfSmrg		GCPtr pGC;
416935c4bbdfSmrg		int shape;
417035c4bbdfSmrg		int mode;
417135c4bbdfSmrg		int count;
417235c4bbdfSmrg		DDXPointPtr pPoint;
417335c4bbdfSmrg
417435c4bbdfSmrg</programlisting></blockquote>
417535c4bbdfSmrgFillPolygon fills a polygon specified by the points in the array
417635c4bbdfSmrgwith the appropriate fill style.
417735c4bbdfSmrgIf necessary, an extra border line is assumed between the starting and ending lines.
417835c4bbdfSmrgThe shape can be used as a hint
417935c4bbdfSmrgto optimize filling; it indicates whether it is convex (all interior angles
418035c4bbdfSmrgless than 180), nonconvex (some interior angles greater than 180 but
418135c4bbdfSmrgborder does not cross itself), or complex (border crosses itself).
418235c4bbdfSmrgYou can choose appropriate algorithms or hardware based upon mode.
418335c4bbdfSmrgmode is one of the defined constants Previous or Origin, depending upon
418435c4bbdfSmrgwhether the points are each relative to the last or are absolute.</para>
418535c4bbdfSmrg<para>
418635c4bbdfSmrgAn example implementation is miFillPolygon() in Xserver/mi/mipoly.c.</para>
418735c4bbdfSmrg<para>
418835c4bbdfSmrg<blockquote><programlisting>
418935c4bbdfSmrg
419035c4bbdfSmrg	void pGC->ops->PolyFillRect(dst, pGC, n, pRect)
419135c4bbdfSmrg		DrawablePtr dst;
419235c4bbdfSmrg		GCPtr pGC;
419335c4bbdfSmrg		int n;
419435c4bbdfSmrg		xRectangle *pRect;
419535c4bbdfSmrg
419635c4bbdfSmrg</programlisting></blockquote>
419735c4bbdfSmrgPolyFillRect fills multiple rectangles.</para>
419835c4bbdfSmrg<para>
419935c4bbdfSmrgExample implementations are fbPolyFillRect() in Xserver/fb/fbfillrect.c and
420035c4bbdfSmrgmiPolyFillRect() in Xserver/mi/mifillrct.c.</para>
420135c4bbdfSmrg<para>
420235c4bbdfSmrg<blockquote><programlisting>
420335c4bbdfSmrg
420435c4bbdfSmrg	void pGC->ops->PolyFillArc(dst, pGC, n, pArc)
420535c4bbdfSmrg		DrawablePtr dst;
420635c4bbdfSmrg		GCPtr pGC;
420735c4bbdfSmrg		int n;
420835c4bbdfSmrg		xArc *pArc;
420935c4bbdfSmrg
421035c4bbdfSmrg</programlisting></blockquote>
421135c4bbdfSmrgPolyFillArc fills a shape for each arc in the
421235c4bbdfSmrglist that is bounded by the arc and one or two
421335c4bbdfSmrgline segments with the current fill style.</para>
421435c4bbdfSmrg<para>
421535c4bbdfSmrgAn example implementation is miPolyFillArc() in Xserver/mi/mifillarc.c.</para>
421635c4bbdfSmrg<para>
421735c4bbdfSmrg<blockquote><programlisting>
421835c4bbdfSmrg
421935c4bbdfSmrg	void pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBinImage)
422035c4bbdfSmrg		DrawablePtr dst;
422135c4bbdfSmrg		GCPtr pGC;
422235c4bbdfSmrg		int x, y, w, h;
422335c4bbdfSmrg		int format;
422435c4bbdfSmrg		char *pBinImage;
422535c4bbdfSmrg
422635c4bbdfSmrg</programlisting></blockquote>
422735c4bbdfSmrgPutImage copies a pixmap image into the drawable.  The pixmap image
422835c4bbdfSmrgmust be in X protocol format (either Bitmap, XYPixmap, or ZPixmap),
422935c4bbdfSmrgand format tells the format.  (See the X protocol specification for
423035c4bbdfSmrgdetails on these formats).  You must be able to accept all three
423135c4bbdfSmrgformats, because the client gets to decide which format to send.
423235c4bbdfSmrgEither the drawable and the pixmap image have the same depth, or the
423335c4bbdfSmrgsource pixmap image must be a Bitmap.  If a Bitmap, the foreground and
423435c4bbdfSmrgbackground colors will be applied to the destination.</para>
423535c4bbdfSmrg<para>
423635c4bbdfSmrgAn example implementation is fbPutImage() in Xserver/fb/fbimage.c.</para>
423735c4bbdfSmrg<para>
423835c4bbdfSmrg<blockquote><programlisting>
423935c4bbdfSmrg
424035c4bbdfSmrg	void pScreen->GetImage(src, x, y, w, h, format, planeMask, pBinImage)
424135c4bbdfSmrg		 DrawablePtr src;
424235c4bbdfSmrg		 int x, y, w, h;
424335c4bbdfSmrg		 unsigned int format;
424435c4bbdfSmrg		 unsigned long planeMask;
424535c4bbdfSmrg		 char *pBinImage;
424635c4bbdfSmrg
424735c4bbdfSmrg</programlisting></blockquote>
424835c4bbdfSmrgGetImage copies the bits from the source drawable into
424935c4bbdfSmrgthe destination pointer.  The bits are written into the buffer
425035c4bbdfSmrgaccording to the server-defined pixmap padding rules.
425135c4bbdfSmrgpBinImage is guaranteed to be big enough to hold all
425235c4bbdfSmrgthe bits that must be written.</para>
425335c4bbdfSmrg<para>
425435c4bbdfSmrgThis routine does not correspond exactly to the X protocol GetImage
425535c4bbdfSmrgrequest, since DIX has to break the reply up into buffers of a size
425635c4bbdfSmrgrequested by the transport layer.  If format is ZPixmap, the bits are
425735c4bbdfSmrgwritten in the ZFormat for the depth of the drawable; if there is a 0
425835c4bbdfSmrgbit in the planeMask for a particular plane, all pixels must have the
425935c4bbdfSmrgbit in that plane equal to 0.  If format is XYPixmap, planemask is
426035c4bbdfSmrgguaranteed to have a single bit set; the bits should be written in
426135c4bbdfSmrgBitmap format, which is the format for a single plane of an XYPixmap.</para>
426235c4bbdfSmrg<para>
426335c4bbdfSmrgAn example implementation is miGetImage() in Xserver/mi/mibitblt.c.
426435c4bbdfSmrg<blockquote><programlisting>
426535c4bbdfSmrg
426635c4bbdfSmrg	void pGC->ops->ImageText8(pDraw, pGC, x, y, count, chars)
426735c4bbdfSmrg		DrawablePtr pDraw;
426835c4bbdfSmrg		GCPtr pGC;
426935c4bbdfSmrg		int x, y;
427035c4bbdfSmrg		int count;
427135c4bbdfSmrg		char *chars;
427235c4bbdfSmrg
427335c4bbdfSmrg</programlisting></blockquote>
427435c4bbdfSmrgImageText8 draws text.  The text is drawn in the foreground color; the
427535c4bbdfSmrgbackground color fills the remainder of the character rectangles.  The
427635c4bbdfSmrgcoordinates specify the baseline and start of the text.</para>
427735c4bbdfSmrg<para>
427835c4bbdfSmrgAn example implementation is miImageText8() in Xserver/mi/mipolytext.c.</para>
427935c4bbdfSmrg<para>
428035c4bbdfSmrg<blockquote><programlisting>
428135c4bbdfSmrg
428235c4bbdfSmrg	int pGC->ops->PolyText8(pDraw, pGC, x, y, count, chars)
428335c4bbdfSmrg		DrawablePtr pDraw;
428435c4bbdfSmrg		GCPtr pGC;
428535c4bbdfSmrg		int x, y;
428635c4bbdfSmrg		int count;
428735c4bbdfSmrg		char *chars;
428835c4bbdfSmrg
428935c4bbdfSmrg</programlisting></blockquote>
429035c4bbdfSmrgPolyText8 works like ImageText8, except it draws with
429135c4bbdfSmrgthe current fill style for special effects such as
429235c4bbdfSmrgshaded text.
429335c4bbdfSmrgSee the X protocol specification for more details.</para>
429435c4bbdfSmrg<para>
429535c4bbdfSmrgAn example implementation is miPolyText8() in Xserver/mi/mipolytext.c.</para>
429635c4bbdfSmrg<para>
429735c4bbdfSmrg<blockquote><programlisting>
429835c4bbdfSmrg
429935c4bbdfSmrg	int pGC->ops->PolyText16(pDraw, pGC, x, y, count, chars)
430035c4bbdfSmrg		DrawablePtr pDraw;
430135c4bbdfSmrg		GCPtr pGC;
430235c4bbdfSmrg		int x, y;
430335c4bbdfSmrg		int count;
430435c4bbdfSmrg		unsigned short *chars;
430535c4bbdfSmrg
430635c4bbdfSmrg	void pGC->ops->ImageText16(pDraw, pGC, x, y, count, chars)
430735c4bbdfSmrg		DrawablePtr pDraw;
430835c4bbdfSmrg		GCPtr pGC;
430935c4bbdfSmrg		int x, y;
431035c4bbdfSmrg		int count;
431135c4bbdfSmrg		unsigned short *chars;
431235c4bbdfSmrg
431335c4bbdfSmrg</programlisting></blockquote>
431435c4bbdfSmrgThese two routines are the same as the "8" versions,
431535c4bbdfSmrgexcept that they are for 16-bit character codes (useful
431635c4bbdfSmrgfor oriental writing systems).</para>
431735c4bbdfSmrg<para>
431835c4bbdfSmrgThe primary difference is in the way the character information is
431935c4bbdfSmrglooked up.  The 8-bit and the 16-bit versions obviously have different
432035c4bbdfSmrgkinds of character values to look up; the main goal of the lookup is
432135c4bbdfSmrgto provide a pointer to the CharInfo structs for the characters to
432235c4bbdfSmrgdraw and to pass these pointers to the Glyph routines.  Given a
432335c4bbdfSmrgCharInfo struct, lower-level software can draw the glyph desired with
432435c4bbdfSmrglittle concern for other characteristics of the font.</para>
432535c4bbdfSmrg<para>
432635c4bbdfSmrg16-bit character fonts have a row-and-column scheme, where the 2bytes
432735c4bbdfSmrgof the character code constitute the row and column in a square matrix
432835c4bbdfSmrgof CharInfo structs.  Each font has row and column minimum and maximum
432935c4bbdfSmrgvalues; the CharInfo structures form a two-dimensional matrix.</para>
433035c4bbdfSmrg<para>
433135c4bbdfSmrgExample implementations are miPolyText16() and
433235c4bbdfSmrgmiImageText16() in Xserver/mi/mipolytext.c.</para>
433335c4bbdfSmrg<para>
433435c4bbdfSmrgSee the X protocol specification for more details on these graphic operations.</para>
433535c4bbdfSmrg<para>
433635c4bbdfSmrgThere is a hook in the GC ops, called LineHelper, that used to be used in the
433735c4bbdfSmrgsample implementation by the code for wide lines.  It no longer servers any
433835c4bbdfSmrgpurpose in the sample servers, but still exists, #ifdef'ed by NEED_LINEHELPER,
433935c4bbdfSmrgin case someone needs it.</para>
434035c4bbdfSmrg</section>
434135c4bbdfSmrg</section>
434235c4bbdfSmrg<section>
434335c4bbdfSmrg  <title>Pixblit Procedures</title>
434435c4bbdfSmrg<para>
434535c4bbdfSmrgThe Drawing Primitive functions must be defined for your server.
434635c4bbdfSmrgOne possible way to do this is to use the mi routines from the sample server.
434735c4bbdfSmrgIf you choose to use the mi routines (even part of them!) you must implement
434835c4bbdfSmrgthese Pixblit routines.
434935c4bbdfSmrgThese routines read and write pixel values
435035c4bbdfSmrgand deal directly with the image data.</para>
435135c4bbdfSmrg<para>
435235c4bbdfSmrgThe Pixblit routines for the sample server are part of the "fb"
435335c4bbdfSmrgroutines.  As with the mi routines, the fb routines are
435435c4bbdfSmrgportable but are not as portable as the mi routines.</para>
435535c4bbdfSmrg<para>
435635c4bbdfSmrgThe fb subsystem is a depth-independent framebuffer core, capable of
435735c4bbdfSmrgoperating at any depth from 1 to 32, based on the depth of the window
435835c4bbdfSmrgor pixmap it is currently operating on.  In particular, this means it
435935c4bbdfSmrgcan support pixmaps of multiple depths on the same screen.  It supplies
436035c4bbdfSmrgboth Pixblit routines and higher-level optimized implementations of the
436135c4bbdfSmrgDrawing Primitive routines.  It does make the assumption that the pixel
436235c4bbdfSmrgdata it touches is available in the server's address space.</para>
436335c4bbdfSmrg<para>
436435c4bbdfSmrgIn other words, if you have a "normal" frame buffer type display, you
436535c4bbdfSmrgcan probably use the fb code, and the mi code.  If you
436635c4bbdfSmrghave a stranger hardware, you will have to supply your own Pixblit
436735c4bbdfSmrgroutines, but you can use the mi routines on top of them.  If you have
436835c4bbdfSmrgbetter ways of doing some of the Drawing Primitive functions, then you
436935c4bbdfSmrgmay want to supply some of your own Drawing Primitive routines.  (Even
437035c4bbdfSmrgpeople who write their own Drawing Primitives save at least some of
437135c4bbdfSmrgthe mi code for certain special cases that their hardware or library
437235c4bbdfSmrgor fancy algorithm does not handle.)</para>
437335c4bbdfSmrg<para>
437435c4bbdfSmrgThe client, DIX, and the machine-independent routines do not carry the
437535c4bbdfSmrgfinal responsibility of clipping.  They all depend upon the Pixblit
437635c4bbdfSmrgroutines to do their clipping for them.  The rule is, if you touch the
437735c4bbdfSmrgframe buffer, you clip.</para>
437835c4bbdfSmrg<para>
437935c4bbdfSmrg(The higher level routines may decide to clip at a high level, but
438035c4bbdfSmrgthis is only for increased performance and cannot substitute for
438135c4bbdfSmrgbottom-level clipping.  For instance, the mi routines, DIX, or the
438235c4bbdfSmrgclient may decide to check all character strings to be drawn and chop
438335c4bbdfSmrgoff all characters that would not be displayed.  If so, it must retain
438435c4bbdfSmrgthe character on the edge that is partly displayed so that the Pixblit
438535c4bbdfSmrgroutines can clip off precisely at the right place.)</para>
438635c4bbdfSmrg<para>
438735c4bbdfSmrgTo make this easier, all of the reasons to clip can be combined into
438835c4bbdfSmrgone region in your ValidateGC procedure.  You take this composite clip
438935c4bbdfSmrgregion with you into the Pixblit routines.  (The sample server does
439035c4bbdfSmrgthis.)</para>
439135c4bbdfSmrg<para>
439235c4bbdfSmrgAlso, FillSpans() has to apply tile and stipple patterns.  The
439335c4bbdfSmrgpatterns are all aligned to the window origin so that when two people
439435c4bbdfSmrgwrite patches that are contiguous, they will merge nicely.  (Really,
439535c4bbdfSmrgthey are aligned to the patOrg point in the GC.  This defaults to (0,
439635c4bbdfSmrg0) but can be set by the client to anything.)</para>
439735c4bbdfSmrg<para>
439835c4bbdfSmrgHowever, the mi routines can translate (relocate) the points from
439935c4bbdfSmrgwindow-relative to screen-relative if desired.  If you set the
440035c4bbdfSmrgmiTranslate field in the GC (set it in the CreateGC or ValidateGC
440135c4bbdfSmrgroutine), then the mi output routines will translate all coordinates.
440235c4bbdfSmrgIf it is false, then the coordinates will be passed window-relative.
440335c4bbdfSmrgScreens with no hardware translation will probably set miTranslate to
440435c4bbdfSmrgTRUE, so that geometry (e.g. polygons, rectangles) can be translated,
440535c4bbdfSmrgrather than having the resulting list of scanlines translated; this is
440635c4bbdfSmrggood because the list vertices in a drawing request will generally be
440735c4bbdfSmrgmuch smaller than the list of scanlines it produces.  Similarly,
440835c4bbdfSmrghardware that does translation can set miTranslate to FALSE, and avoid
440935c4bbdfSmrgthe extra addition per vertex, which can be (but is not always)
441035c4bbdfSmrgimportant for getting the highest possible performance.  (Contrast the
441135c4bbdfSmrgbehavior of GetSpans, which is not expected to be called as often, and
441235c4bbdfSmrgso has different constraints.)  The miTranslate field is settable in
441335c4bbdfSmrgeach GC, if , for example, you are mixing several kinds of
441435c4bbdfSmrgdestinations (offscreen pixmaps, main memory pixmaps, backing store,
441535c4bbdfSmrgand windows), all of which have different requirements, on one screen.</para>
441635c4bbdfSmrg<para>
441735c4bbdfSmrgAs with other drawing routines, there are fields in the GC to direct
441835c4bbdfSmrghigher code to the correct routine to execute for each function.  In
441935c4bbdfSmrgthis way, you can optimize for special cases, for example, drawing
442035c4bbdfSmrgsolids versus drawing stipples.</para>
442135c4bbdfSmrg<para>
442235c4bbdfSmrgThe Pixblit routines are broken up into three sets.  The Span routines
442335c4bbdfSmrgsimply fill in rows of pixels.  The Glyph routines fill in character
442435c4bbdfSmrgglyphs.  The PushPixels routine is a three-input bitblt for more
442535c4bbdfSmrgsophisticated image creation.</para>
442635c4bbdfSmrg<para>
442735c4bbdfSmrgIt turns out that the Glyph and PushPixels routines actually have a
442835c4bbdfSmrgmachine-independent implementation that depends upon the Span
442935c4bbdfSmrgroutines.  If you are really pressed for time, you can use these
443035c4bbdfSmrgversions, although they are quite slow.</para>
443135c4bbdfSmrg<section>
443235c4bbdfSmrg<title>Span Routines</title>
443335c4bbdfSmrg<para>
443435c4bbdfSmrgFor these routines, all graphic operations have been reduced to "spans."
443535c4bbdfSmrgA span is a horizontal row of pixels.
443635c4bbdfSmrgIf you can design these routines which write into and read from
443735c4bbdfSmrgrows of pixels at a time, you can use the mi routines.</para>
443835c4bbdfSmrg<para>
443935c4bbdfSmrgEach routine takes
444035c4bbdfSmrga destination drawable to draw into, a GC to use while drawing,
444135c4bbdfSmrgthe number of spans to do, and two pointers to arrays that indicate the list
444235c4bbdfSmrgof starting points and the list of widths of spans.</para>
444335c4bbdfSmrg<para>
444435c4bbdfSmrg<blockquote><programlisting>
444535c4bbdfSmrg
444635c4bbdfSmrg	void pGC->ops->FillSpans(dst, pGC, nSpans, pPoints, pWidths, sorted)
444735c4bbdfSmrg		DrawablePtr dst;
444835c4bbdfSmrg		GCPtr pGC;
444935c4bbdfSmrg		int nSpans;
445035c4bbdfSmrg		DDXPointPtr pPoints;
445135c4bbdfSmrg		int *pWidths;
445235c4bbdfSmrg		int sorted;
445335c4bbdfSmrg
445435c4bbdfSmrg</programlisting></blockquote>
445535c4bbdfSmrgFillSpans should fill horizontal rows of pixels with
445635c4bbdfSmrgthe appropriate patterns, stipples, etc.,
445735c4bbdfSmrgbased on the values in the GC.
445835c4bbdfSmrgThe starting points are in the array at pPoints; the widths are in pWidths.
445935c4bbdfSmrgIf sorted is true, the scan lines are in increasing y order, in which case
446035c4bbdfSmrgyou may be able to make assumptions and optimizations.</para>
446135c4bbdfSmrg<para>
446235c4bbdfSmrgGC components: alu, clipOrg, clientClip, and fillStyle.</para>
446335c4bbdfSmrg<para>
446435c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
446535c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
446635c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
446735c4bbdfSmrg<para>
446835c4bbdfSmrg<blockquote><programlisting>
446935c4bbdfSmrg
447035c4bbdfSmrg	void pGC->ops->SetSpans(pDrawable, pGC, pSrc, ppt, pWidths, nSpans, sorted)
447135c4bbdfSmrg		DrawablePtr pDrawable;
447235c4bbdfSmrg		GCPtr pGC;
447335c4bbdfSmrg		char *pSrc;
447435c4bbdfSmrg		DDXPointPtr pPoints;
447535c4bbdfSmrg		int *pWidths;
447635c4bbdfSmrg		int nSpans;
447735c4bbdfSmrg		int sorted;
447835c4bbdfSmrg
447935c4bbdfSmrg</programlisting></blockquote>
448035c4bbdfSmrgFor each span, this routine should copy pWidths bits from pSrc to
448135c4bbdfSmrgpDrawable at pPoints using the raster-op from the GC.
448235c4bbdfSmrgIf sorted is true, the scan lines are in increasing y order.
448335c4bbdfSmrgThe pixels in pSrc are
448435c4bbdfSmrgpadded according to the screen's padding rules.
448535c4bbdfSmrgThese
448635c4bbdfSmrgcan be used to support
448735c4bbdfSmrginteresting extension libraries, for example, shaded primitives.   It does not
448835c4bbdfSmrguse the tile and stipple.</para>
448935c4bbdfSmrg<para>
449035c4bbdfSmrgGC components: alu, clipOrg, and clientClip</para>
449135c4bbdfSmrg<para>
449235c4bbdfSmrgThe above functions are expected to handle all modifiers in the current
449335c4bbdfSmrgGC.  Therefore, it is expedient to have
449435c4bbdfSmrgdifferent routines to quickly handle common special cases
449535c4bbdfSmrgand reload the procedure pointers
449635c4bbdfSmrgat validate time, as with the other output functions.</para>
449735c4bbdfSmrg<para>
449835c4bbdfSmrg<blockquote><programlisting>
449935c4bbdfSmrg
450035c4bbdfSmrg	void pScreen->GetSpans(pDrawable, wMax, pPoints, pWidths, nSpans)
450135c4bbdfSmrg		DrawablePtr pDrawable;
450235c4bbdfSmrg		int wMax;
450335c4bbdfSmrg		DDXPointPtr pPoints;
450435c4bbdfSmrg		int *pWidths;
450535c4bbdfSmrg		int nSpans;
450635c4bbdfSmrg		char *pDst;
450735c4bbdfSmrg
450835c4bbdfSmrg</programlisting></blockquote>
450935c4bbdfSmrgFor each span, GetSpans gets bits from the drawable starting at pPoints
451035c4bbdfSmrgand continuing for pWidths bits.
451135c4bbdfSmrgEach scanline returned will be server-scanline padded.
451235c4bbdfSmrgThe routine can return NULL if memory cannot be allocated to hold the
451335c4bbdfSmrgresult.</para>
451435c4bbdfSmrg<para>
451535c4bbdfSmrgGetSpans never translates -- for a window, the coordinates are already
451635c4bbdfSmrgscreen-relative.  Consider the case of hardware that doesn't do
451735c4bbdfSmrgtranslation: the mi code that calls ddX will translate each shape
451835c4bbdfSmrg(rectangle, polygon,. etc.) before scan-converting it, which requires
451935c4bbdfSmrgmany fewer additions that having GetSpans translate each span does.
452035c4bbdfSmrgConversely, consider hardware that does translate: it can set its
452135c4bbdfSmrgtranslation point to (0, 0) and get each span, and the only penalty is
452235c4bbdfSmrgthe small number of additions required to translate each shape being
452335c4bbdfSmrgscan-converted by the calling code.  Contrast the behavior of
452435c4bbdfSmrgFillSpans and SetSpans (discussed above under miTranslate), which are
452535c4bbdfSmrgexpected to be used more often.</para>
452635c4bbdfSmrg<para>
452735c4bbdfSmrgThus, the penalty to hardware that does hardware translation is
452835c4bbdfSmrgnegligible, and code that wants to call GetSpans() is greatly
452935c4bbdfSmrgsimplified, both for extensions and the machine-independent core
453035c4bbdfSmrgimplementation.</para>
453135c4bbdfSmrg<section>
453235c4bbdfSmrg  <title>Glyph Routines</title>
453335c4bbdfSmrg<para>
453435c4bbdfSmrgThe Glyph routines draw individual character glyphs for text drawing requests.</para>
453535c4bbdfSmrg<para>
453635c4bbdfSmrgYou have a choice in implementing these routines.  You can use the mi
453735c4bbdfSmrgversions; they depend ultimately upon the span routines.  Although
453835c4bbdfSmrgtext drawing will work, it will be very slow.</para>
453935c4bbdfSmrg<para>
454035c4bbdfSmrg<blockquote><programlisting>
454135c4bbdfSmrg
454235c4bbdfSmrg	void pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
454335c4bbdfSmrg		DrawablePtr pDrawable;
454435c4bbdfSmrg		GCPtr pGC;
454535c4bbdfSmrg		int x , y;
454635c4bbdfSmrg		unsigned int nglyph;
454735c4bbdfSmrg		CharInfoRec **ppci;		/* array of character info */
454835c4bbdfSmrg		pointer unused;			/* unused since R5 */
454935c4bbdfSmrg
455035c4bbdfSmrg</programlisting></blockquote>
455135c4bbdfSmrgGC components: alu, clipOrg, clientClip, font, and fillStyle.</para>
455235c4bbdfSmrg<para>
455335c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
455435c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
455535c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
455635c4bbdfSmrg<para>
455735c4bbdfSmrg<blockquote><programlisting>
455835c4bbdfSmrg
455935c4bbdfSmrg	void pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
456035c4bbdfSmrg		DrawablePtr pDrawable;
456135c4bbdfSmrg		GCPtr pGC;
456235c4bbdfSmrg		int x , y;
456335c4bbdfSmrg		unsigned int nglyph;
456435c4bbdfSmrg		CharInfoRec **ppci;	/* array of character info */
456535c4bbdfSmrg		pointer unused;		/* unused since R5 */
456635c4bbdfSmrg
456735c4bbdfSmrg</programlisting></blockquote>
456835c4bbdfSmrgGC components: clipOrg, clientClip, font, fgPixel, bgPixel</para>
456935c4bbdfSmrg<para>
457035c4bbdfSmrgThese routines must copy the glyphs defined by the bitmaps in
457135c4bbdfSmrgpglyphBase and the font metrics in ppci to the DrawablePtr, pDrawable.
457235c4bbdfSmrgThe poly routine follows all fill, stipple, and tile rules.  The image
457335c4bbdfSmrgroutine simply blasts the glyph onto the glyph's rectangle, in
457435c4bbdfSmrgforeground and background colors.</para>
457535c4bbdfSmrg<para>
457635c4bbdfSmrgMore precisely, the Image routine fills the character rectangle with
457735c4bbdfSmrgthe background color, and then the glyph is applied in the foreground
457835c4bbdfSmrgcolor.  The glyph can extend outside of the character rectangle.
457935c4bbdfSmrgImageGlyph() is used for terminal emulators and informal text purposes
458035c4bbdfSmrgsuch as button labels.</para>
458135c4bbdfSmrg<para>
458235c4bbdfSmrgThe exact specification for the Poly routine is that the glyph is
458335c4bbdfSmrgpainted with the current fill style.  The character rectangle is
458435c4bbdfSmrgirrelevant for this operation.  PolyText, at a higher level, includes
458535c4bbdfSmrgfacilities for font changes within strings and such; it is to be used
458635c4bbdfSmrgfor WYSIWYG word processing and similar systems.</para>
458735c4bbdfSmrg<para>
458835c4bbdfSmrgBoth of these routines must clip themselves to the overall clipping region.</para>
458935c4bbdfSmrg<para>
459035c4bbdfSmrgExample implementations in mi are miPolyGlyphBlt() and
459135c4bbdfSmrgmiImageGlyphBlt() in Xserver/mi/miglblt.c.</para>
459235c4bbdfSmrg</section>
459335c4bbdfSmrg<section>
459435c4bbdfSmrg<title>PushPixels routine</title>
459535c4bbdfSmrg<para>
459635c4bbdfSmrgThe PushPixels routine writes the current fill style onto the drawable
459735c4bbdfSmrgin a certain shape defined by a bitmap.  PushPixels is equivalent to
459835c4bbdfSmrgusing a second stipple.  You can thing of it as pushing the fillStyle
459935c4bbdfSmrgthrough a stencil.  PushPixels is not used by any of the mi rendering code,
460035c4bbdfSmrgbut is used by the mi software cursor code.
460135c4bbdfSmrg<blockquote><para>
460235c4bbdfSmrg	Suppose the stencil is:	00111100
460335c4bbdfSmrg	and the stipple is:	10101010
460435c4bbdfSmrg	PushPixels result:	00101000
460535c4bbdfSmrg</para></blockquote>
460635c4bbdfSmrg</para>
460735c4bbdfSmrg<para>
460835c4bbdfSmrgYou have a choice in implementing this routine.
460935c4bbdfSmrgYou can use the mi version which depends ultimately upon FillSpans().
461035c4bbdfSmrgAlthough it will work, it will be slow.</para>
461135c4bbdfSmrg<para>
461235c4bbdfSmrg<blockquote><programlisting>
461335c4bbdfSmrg
461435c4bbdfSmrg	void pGC->ops->PushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
461535c4bbdfSmrg		GCPtr pGC;
461635c4bbdfSmrg		PixmapPtr pBitMap;
461735c4bbdfSmrg		DrawablePtr pDrawable;
461835c4bbdfSmrg		int dx, dy, xOrg, yOrg;
461935c4bbdfSmrg
462035c4bbdfSmrg</programlisting></blockquote>
462135c4bbdfSmrgGC components: alu, clipOrg, clientClip, and fillStyle.</para>
462235c4bbdfSmrg<para>
462335c4bbdfSmrgGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
462435c4bbdfSmrg(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
462535c4bbdfSmrgand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
462635c4bbdfSmrg<para>
4627ed6184dfSmrgPushPixels applies the foreground color, tile, or stipple from the pGC
462835c4bbdfSmrgthrough a stencil onto pDrawable.  pBitMap points to a stencil (of
462935c4bbdfSmrgwhich we use an area dx wide by dy high), which is oriented over the
463035c4bbdfSmrgdrawable at xOrg, yOrg.  Where there is a 1 bit in the bitmap, the
463135c4bbdfSmrgdestination is set according to the current fill style.  Where there
463235c4bbdfSmrgis a 0 bit in the bitmap, the destination is left the way it is.</para>
463335c4bbdfSmrg<para>
463435c4bbdfSmrgThis routine must clip to the overall clipping region.</para>
463535c4bbdfSmrg<para>
463635c4bbdfSmrgAn Example implementation is miPushPixels() in Xserver/mi/mipushpxl.c.</para>
463735c4bbdfSmrg</section>
463835c4bbdfSmrg</section>
463935c4bbdfSmrg</section>
464035c4bbdfSmrg<section>
464135c4bbdfSmrg  <title>Shutdown Procedures</title>
464235c4bbdfSmrg<para>
464335c4bbdfSmrg<blockquote><programlisting>
464435c4bbdfSmrg	void ddxGiveUp(enum ExitCode error)
464535c4bbdfSmrg</programlisting></blockquote>
464635c4bbdfSmrgSome hardware may require special work to be done before the server
464735c4bbdfSmrgexits so that it is not left in an intermediate state.  As explained
4648ed6184dfSmrgin the OS layer, FatalError() will call ddxGiveUp() just before
464935c4bbdfSmrgterminating the server.  In addition, ddxGiveUp() will be called just
4650ed6184dfSmrgbefore terminating the server on a "clean" death.  What
4651ed6184dfSmrgddxGiveUp does is left unspecified, only that it must exist in the
465235c4bbdfSmrgddx layer.  It is up to local implementors as to what they should
465335c4bbdfSmrgaccomplish before termination.</para>
465435c4bbdfSmrg<section>
465535c4bbdfSmrg  <title>Command Line Procedures</title>
465635c4bbdfSmrg<para>
465735c4bbdfSmrg<blockquote><programlisting>
465835c4bbdfSmrg	int ddxProcessArgument(argc, argv, i)
465935c4bbdfSmrg	    int argc;
466035c4bbdfSmrg	    char *argv[];
466135c4bbdfSmrg	    int i;
466235c4bbdfSmrg
466335c4bbdfSmrg	void
466435c4bbdfSmrg	ddxUseMsg()
466535c4bbdfSmrg
466635c4bbdfSmrg</programlisting></blockquote>
466735c4bbdfSmrgYou should write these routines to deal with device-dependent command line
466835c4bbdfSmrgarguments.  The routine ddxProcessArgument() is called with the command line,
466935c4bbdfSmrgand the current index into argv; you should return zero if the argument
467035c4bbdfSmrgis not a device-dependent one, and otherwise return a count of the number
467135c4bbdfSmrgof elements of argv that are part of this one argument.  For a typical
467235c4bbdfSmrgoption (e.g., "-realtime"), you should return the value one.  This
467335c4bbdfSmrgroutine gets called before checks are made against device-independent
467435c4bbdfSmrgarguments, so it is possible to peek at all arguments or to override
467535c4bbdfSmrgdevice-independent argument processing.  You can document the
467635c4bbdfSmrgdevice-dependent arguments in ddxUseMsg(), which will be
467735c4bbdfSmrgcalled from UseMsg() after printing out the device-independent arguments.</para>
467835c4bbdfSmrg</section>
467935c4bbdfSmrg</section>
468035c4bbdfSmrg<section id="wrappers_and_privates">
468135c4bbdfSmrg  <title>Wrappers and Privates</title>
468235c4bbdfSmrg<para>
468335c4bbdfSmrgTwo new extensibility concepts have been developed for release 4, Wrappers
468435c4bbdfSmrgand devPrivates.  These replace the R3 GCInterest queues, which were not a
468535c4bbdfSmrggeneral enough mechanism for many extensions and only provided hooks into a
468635c4bbdfSmrgsingle data structure.  devPrivates have been revised substantially for
468735c4bbdfSmrgX.Org X server release 1.5, updated again for the 1.9 release and extended
468835c4bbdfSmrgagain for the 1.13 relealse.</para>
468935c4bbdfSmrg<section>
469035c4bbdfSmrg  <title>devPrivates</title>
469135c4bbdfSmrg<para>
469235c4bbdfSmrgdevPrivates provides a way to attach arbitrary private data to various server structures.
469335c4bbdfSmrgAny structure which contains a <structfield>devPrivates</structfield> field of
469435c4bbdfSmrgtype <type>PrivateRec</type> supports this mechanism.  Some structures allow
469535c4bbdfSmrgallocating space for private data after some objects have been created, others
469635c4bbdfSmrgrequire all space allocations be registered before any objects of that type
469735c4bbdfSmrgare created.  <filename class="headerfile">Xserver/include/privates.h</filename>
469835c4bbdfSmrglists which of these cases applies to each structure containing
469935c4bbdfSmrg<structfield>devPrivates</structfield>.</para>
470035c4bbdfSmrg
470135c4bbdfSmrg<para>
470235c4bbdfSmrgTo request private space, use
470335c4bbdfSmrg<blockquote><programlisting>
470435c4bbdfSmrg	Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
470535c4bbdfSmrg</programlisting></blockquote>
470635c4bbdfSmrgThe first argument is a pointer to a <type>DevPrivateKeyRec</type> which
470735c4bbdfSmrgwill serve as the unique identifier for the private data.  Typically this is
470835c4bbdfSmrgthe address of a static <type>DevPrivateKeyRec</type> in your code.
470935c4bbdfSmrgThe second argument is the class of objects for which this key will apply.
471035c4bbdfSmrgThe third argument is the size of the space being requested, or
471135c4bbdfSmrg<constant>0</constant> to only allocate a pointer that the caller will manage.
471235c4bbdfSmrgIf space is requested, this space will be automatically freed when the object
471335c4bbdfSmrgis destroyed.  Note that a call to <function>dixSetPrivate</function>
471435c4bbdfSmrgthat changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
471535c4bbdfSmrgThe function returns <literal>TRUE</literal> unless memory allocation fails.
471635c4bbdfSmrgIf the function is called more than once on the same key, all calls must use
471735c4bbdfSmrgthe same value for <type>size</type> or the server will abort.</para>
471835c4bbdfSmrg
471935c4bbdfSmrg<para>
472035c4bbdfSmrgTo request per-screen private space in an object, use
472135c4bbdfSmrg<blockquote><programlisting>
472235c4bbdfSmrg	Bool dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
472335c4bbdfSmrg</programlisting></blockquote>
472435c4bbdfSmrgThe <parameter>type</parameter> and <parameter>size</parameter> arguments are
472535c4bbdfSmrgthe same as those to <function>dixRegisterPrivateKey</function> but this
472635c4bbdfSmrgfunction ensures the given <parameter>key</parameter> exists on objects of
472735c4bbdfSmrgthe specified type with distinct storage for the given
472835c4bbdfSmrg<parameter>pScreen</parameter>. The key is usable on ScreenPrivate variants
472935c4bbdfSmrgthat are otherwise equivalent to the following Private functions.</para>
473035c4bbdfSmrg
473135c4bbdfSmrg<para>
473235c4bbdfSmrg  To request private space in objects created for a specific screen, use
473335c4bbdfSmrg  <blockquote><programlisting>
473435c4bbdfSmrg    Bool dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, DevPrivateType type, unsigned size);
473535c4bbdfSmrg  </programlisting></blockquote>
473635c4bbdfSmrg  The <parameter>type</parameter> and <parameter>size</parameter> arguments are
473735c4bbdfSmrg  the same as those to <function>dixRegisterPrivateKey</function> but this
473835c4bbdfSmrg  function ensures only that the given <parameter>key</parameter> exists on objects of
473935c4bbdfSmrg  the specified type that are allocated with reference to the specified
474035c4bbdfSmrg  <parameter>pScreen</parameter>. Using the key on objects allocated for
474135c4bbdfSmrg  other screens will result in incorrect results; there is no check made to
474235c4bbdfSmrg  ensure that the caller's screen matches the private's screen. The key is
474335c4bbdfSmrg  usable in any of the following functions. Screen-specific private storage is available
474435c4bbdfSmrg  only for Windows, GCs, Pixmaps and Pictures. Attempts to allocate screen-specific
474535c4bbdfSmrg  privates on other objects will result in a call to FatalError.
474635c4bbdfSmrg</para>
474735c4bbdfSmrg
474835c4bbdfSmrg<para>
474935c4bbdfSmrgTo attach a piece of private data to an object, use:
475035c4bbdfSmrg<blockquote><programlisting>
475135c4bbdfSmrg	void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
475235c4bbdfSmrg</programlisting></blockquote>
475335c4bbdfSmrgThe first argument is the address of the <structfield>devPrivates</structfield>
475435c4bbdfSmrgfield in the target structure.  This field is managed privately by the DIX
475535c4bbdfSmrglayer and should not be directly modified.  The second argument is a pointer
475635c4bbdfSmrgto the <type>DevPrivateKeyRec</type> which you registered with
475735c4bbdfSmrg<function>dixRegisterPrivateKey</function> or allocated with
475835c4bbdfSmrg<function>dixCreatePrivateKey</function>.  Only one
475935c4bbdfSmrgpiece of data with a given key can be attached to an object, and in most cases
476035c4bbdfSmrgeach key is specific to the type of object it was registered for.   (An
476135c4bbdfSmrgexception is the PRIVATE_XSELINUX class which applies to multiple object types.)
476235c4bbdfSmrgThe third argument is the value to store.</para>
476335c4bbdfSmrg<para>
476435c4bbdfSmrgIf private data with the given key is already associated with the object,
476535c4bbdfSmrg<function>dixSetPrivate</function> will overwrite the old value with the
476635c4bbdfSmrgnew one.</para>
476735c4bbdfSmrg
476835c4bbdfSmrg<para>
476935c4bbdfSmrgTo look up a piece of private data, use one of:
477035c4bbdfSmrg<blockquote><programlisting>
477135c4bbdfSmrg	pointer dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
477235c4bbdfSmrg	pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
477335c4bbdfSmrg</programlisting></blockquote>
477435c4bbdfSmrgThe first argument is the address of the <structfield>devPrivates</structfield> field
477535c4bbdfSmrgin the target structure.  The second argument is the key to look up.
477635c4bbdfSmrgIf a non-zero size was given when the key was registered, or if private data
477735c4bbdfSmrgwith the given key is already associated with the object, then
477835c4bbdfSmrg<function>dixLookupPrivate</function> will return the pointer value
477935c4bbdfSmrgwhile <function>dixLookupPrivateAddr</function>
478035c4bbdfSmrgwill return the address of the pointer.</para>
478135c4bbdfSmrg
478235c4bbdfSmrg<para>
478335c4bbdfSmrgWhen implementing new server resource objects that support devPrivates, there
478435c4bbdfSmrgare four steps to perform:
478535c4bbdfSmrgAdd a type value to the <type>DevPrivateType</type> enum in
478635c4bbdfSmrg<filename class="headerfile">Xserver/include/privates.h</filename>,
478735c4bbdfSmrgdeclare a field of type <type>PrivateRec *</type> in your structure;
478835c4bbdfSmrginitialize this field to <literal>NULL</literal> when creating any objects; and
478935c4bbdfSmrgwhen freeing any objects call the <function>dixFreePrivates</function> or
479035c4bbdfSmrg<function>dixFreeObjectWithPrivates</function> function.</para>
479135c4bbdfSmrg</section>
479235c4bbdfSmrg<section>
479335c4bbdfSmrg  <title>Wrappers</title>
479435c4bbdfSmrg<para>
479535c4bbdfSmrgWrappers are not a body of code, nor an interface spec.  They are, instead,
479635c4bbdfSmrga technique for hooking a new module into an existing calling sequence.
479735c4bbdfSmrgThere are limitations on other portions of the server implementation which
479835c4bbdfSmrgmake using wrappers possible; limits on when specific fields of data
479935c4bbdfSmrgstructures may be modified.  They are intended as a replacement for
480035c4bbdfSmrgGCInterest queues, which were not general enough to support existing
480135c4bbdfSmrgmodules; in particular software cursors needed more
480235c4bbdfSmrgcontrol over the activity.  The general mechanism for using wrappers is:
480335c4bbdfSmrg<blockquote><programlisting>
480435c4bbdfSmrgprivateWrapperFunction (object, ...)
480535c4bbdfSmrg	ObjectPtr	object;
480635c4bbdfSmrg{
480735c4bbdfSmrg	pre-wrapped-function-stuff ...
480835c4bbdfSmrg
480935c4bbdfSmrg	object->functionVector = dixLookupPrivate(&amp;object->devPrivates, privateKey);
481035c4bbdfSmrg	(*object->functionVector) (object, ...);
481135c4bbdfSmrg	/*
481235c4bbdfSmrg	 * this next line is occasionally required by the rules governing
481335c4bbdfSmrg	 * wrapper functions.  Always using it will not cause problems.
481435c4bbdfSmrg	 * Not using it when necessary can cause severe troubles.
481535c4bbdfSmrg	 */
481635c4bbdfSmrg	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
481735c4bbdfSmrg	object->functionVector = privateWrapperFunction;
481835c4bbdfSmrg
481935c4bbdfSmrg	post-wrapped-function-stuff ...
482035c4bbdfSmrg}
482135c4bbdfSmrg
482235c4bbdfSmrgprivateInitialize (object)
482335c4bbdfSmrg	ObjectPtr	object;
482435c4bbdfSmrg{
482535c4bbdfSmrg	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
482635c4bbdfSmrg	object->functionVector = privateWrapperFunction;
482735c4bbdfSmrg}
482835c4bbdfSmrg</programlisting></blockquote>
482935c4bbdfSmrg</para>
483035c4bbdfSmrg<para>
483135c4bbdfSmrgThus the privateWrapperFunction provides hooks for performing work both
483235c4bbdfSmrgbefore and after the wrapped function has been called; the process of
483335c4bbdfSmrgresetting the functionVector is called "unwrapping" while the process of
483435c4bbdfSmrgfetching the wrapped function and replacing it with the wrapping function
483535c4bbdfSmrgis called "wrapping".  It should be clear that GCInterest queues could
483635c4bbdfSmrgbe emulated using wrappers.  In general, any function vectors contained in
483735c4bbdfSmrgobjects can be wrapped, but only vectors in GCs and Screens have been tested.</para>
483835c4bbdfSmrg<para>
483935c4bbdfSmrgWrapping screen functions is quite easy; each vector is individually
484035c4bbdfSmrgwrapped.  Screen functions are not supposed to change after initialization,
484135c4bbdfSmrgso rewrapping is technically not necessary, but causes no problems.</para>
484235c4bbdfSmrg<para>
484335c4bbdfSmrgWrapping GC functions is a bit more complicated.  GC's have two tables of
484435c4bbdfSmrgfunction vectors, one hanging from gc->ops and the other from gc->funcs, which
484535c4bbdfSmrgshould be initially wrapped from a CreateGC wrapper.  Wrappers should modify
484635c4bbdfSmrgonly table pointers, not the contents of the tables, as they
484735c4bbdfSmrgmay be shared by more than one GC (and, in the case of funcs, are probably
484835c4bbdfSmrgshared by all gcs).  Your func wrappers may change the GC funcs or ops
484935c4bbdfSmrgpointers, and op wrappers may change the GC op pointers but not the funcs.</para>
485035c4bbdfSmrg<para>
485135c4bbdfSmrgThus, the rule for GC wrappings is: wrap the funcs from CreateGC and, in each
485235c4bbdfSmrgfunc wrapper, unwrap the ops and funcs, call down, and re-wrap.  In each op
485335c4bbdfSmrgwrapper, unwrap the ops, call down, and rewrap afterwards.  Note that in
485435c4bbdfSmrgre-wrapping you must save out the pointer you're replacing again.  This way the
485535c4bbdfSmrgchain will be maintained when wrappers adjust the funcs/ops tables they use.</para>
485635c4bbdfSmrg</section>
485735c4bbdfSmrg</section>
485835c4bbdfSmrg<section>
485935c4bbdfSmrg    <title>Work Queue</title>
486035c4bbdfSmrg<para>
486135c4bbdfSmrgTo queue work for execution when all clients are in a stable state (i.e.
486235c4bbdfSmrgjust before calling select() in WaitForSomething), call:
486335c4bbdfSmrg<blockquote><programlisting>
486435c4bbdfSmrg	Bool QueueWorkProc(function,client,closure)
486535c4bbdfSmrg		Bool		(*function)();
486635c4bbdfSmrg		ClientPtr	client;
486735c4bbdfSmrg		pointer		closure;
486835c4bbdfSmrg</programlisting></blockquote>
486935c4bbdfSmrg</para>
487035c4bbdfSmrg<para>
487135c4bbdfSmrgWhen the server is about to suspend itself, the given function will be
487235c4bbdfSmrgexecuted:
487335c4bbdfSmrg<blockquote><programlisting>
487435c4bbdfSmrg	(*function) (client, closure)
487535c4bbdfSmrg</programlisting></blockquote>
487635c4bbdfSmrg</para>
487735c4bbdfSmrg<para>
487835c4bbdfSmrgNeither client nor closure are actually used inside the work queue routines.</para>
487935c4bbdfSmrg</section>
488035c4bbdfSmrg</section>
488135c4bbdfSmrg<section>
488235c4bbdfSmrg  <title>Summary of Routines</title>
488335c4bbdfSmrg<para>
488435c4bbdfSmrgThis is a summary of the routines discussed in this document.
488535c4bbdfSmrgThe procedure names are in alphabetical order.
488635c4bbdfSmrgThe Struct is the structure it is attached to; if blank, this
488735c4bbdfSmrgprocedure is not attached to a struct and must be named as shown.
488835c4bbdfSmrgThe sample server provides implementations in the following
488935c4bbdfSmrgcategories.  Notice that many of the graphics routines have both
489035c4bbdfSmrgmi and fb implementations.</para>
489135c4bbdfSmrg<para>
489235c4bbdfSmrg<itemizedlist>
489335c4bbdfSmrg<listitem><para>dix	portable to all systems; do not attempt to rewrite (Xserver/dix)</para></listitem>
489435c4bbdfSmrg<listitem><para>os	routine provided in Xserver/os or Xserver/include/os.h</para></listitem>
489535c4bbdfSmrg<listitem><para>ddx	frame buffer dependent (examples in Xserver/fb)</para></listitem>
489635c4bbdfSmrg<listitem><para>mi	routine provided in Xserver/mi</para></listitem>
489735c4bbdfSmrg<listitem><para>hd	hardware dependent (examples in many Xserver/hw directories)</para></listitem>
489835c4bbdfSmrg<listitem><para>none	not implemented in sample implementation</para></listitem>
489935c4bbdfSmrg</itemizedlist>
490035c4bbdfSmrg</para>
490135c4bbdfSmrg	<table frame="all" id="routines-1">
490235c4bbdfSmrg	  <title>Server Routines (Page 1)</title>
490335c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
490435c4bbdfSmrg	    <thead>
490535c4bbdfSmrg	      <row>
490635c4bbdfSmrg		<entry>Procedure</entry>
490735c4bbdfSmrg		<entry>Port</entry>
490835c4bbdfSmrg		<entry>Struct</entry>
490935c4bbdfSmrg	      </row>
491035c4bbdfSmrg	    </thead>
491135c4bbdfSmrg	    <tbody>
491235c4bbdfSmrg<row><entry><function>ALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
491335c4bbdfSmrg<row><entry><function>AddCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
491435c4bbdfSmrg<row><entry><function>AddEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
491535c4bbdfSmrg<row><entry><function>AddInputDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
491635c4bbdfSmrg<row><entry><function>AddScreen</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
491735c4bbdfSmrg<row><entry><function>AdjustWaitForDelay</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
491835c4bbdfSmrg<row><entry><function>Bell</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
491935c4bbdfSmrg<row><entry><function>ChangeClip</function></entry><entry><literal>mi</literal></entry><entry><para>GC func</para></entry></row>
492035c4bbdfSmrg<row><entry><function>ChangeGC</function></entry><entry><literal></literal></entry><entry><para>GC func</para></entry></row>
492135c4bbdfSmrg<row><entry><function>ChangeWindowAttributes</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
492235c4bbdfSmrg<row><entry><function>ClearToBackground</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
492335c4bbdfSmrg<row><entry><function>ClientAuthorized</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
492435c4bbdfSmrg<row><entry><function>ClientSignal</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
492535c4bbdfSmrg<row><entry><function>ClientSleep</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
492635c4bbdfSmrg<row><entry><function>ClientWakeup</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
492735c4bbdfSmrg<row><entry><function>ClipNotify</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
492835c4bbdfSmrg<row><entry><function>CloseScreen</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
492935c4bbdfSmrg<row><entry><function>ConstrainCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
493035c4bbdfSmrg<row><entry><function>CopyArea</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
493135c4bbdfSmrg<row><entry><function>CopyGCDest</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
493235c4bbdfSmrg<row><entry><function>CopyGCSource</function></entry><entry><literal>none</literal></entry><entry><para>GC func</para></entry></row>
493335c4bbdfSmrg<row><entry><function>CopyPlane</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
493435c4bbdfSmrg<row><entry><function>CopyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
493535c4bbdfSmrg<row><entry><function>CreateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
493635c4bbdfSmrg<row><entry><function>CreateCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
493735c4bbdfSmrg<row><entry><function>CreatePixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
493835c4bbdfSmrg<row><entry><function>CreateScreenResources</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
493935c4bbdfSmrg<row><entry><function>CreateWellKnowSockets</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
494035c4bbdfSmrg<row><entry><function>CreateWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
494135c4bbdfSmrg<row><entry><function>CursorLimits</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
494235c4bbdfSmrg<row><entry><function>DEALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
494335c4bbdfSmrg<row><entry><function>DeleteCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
494435c4bbdfSmrg<row><entry><function>DeleteCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
494535c4bbdfSmrg<row><entry><function>DestroyClip</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
494635c4bbdfSmrg<row><entry><function>DestroyGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
494735c4bbdfSmrg<row><entry><function>DestroyPixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
494835c4bbdfSmrg<row><entry><function>DestroyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
494935c4bbdfSmrg<row><entry><function>DisplayCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
495035c4bbdfSmrg<row><entry><function>Error</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495135c4bbdfSmrg<row><entry><function>ErrorF</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495235c4bbdfSmrg<row><entry><function>FatalError</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495335c4bbdfSmrg<row><entry><function>FillPolygon</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
495435c4bbdfSmrg<row><entry><function>FillSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
495535c4bbdfSmrg<row><entry><function>FlushAllOutput</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495635c4bbdfSmrg<row><entry><function>FlushIfCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
495735c4bbdfSmrg<row><entry><function>FreeScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
495835c4bbdfSmrg<row><entry><function>GetImage</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
495935c4bbdfSmrg<row><entry><function>GetMotionEvents</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
496035c4bbdfSmrg<row><entry><function>GetScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
496135c4bbdfSmrg<row><entry><function>GetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
496235c4bbdfSmrg<row><entry><function>GetStaticColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
496335c4bbdfSmrg	    </tbody>
496435c4bbdfSmrg	  </tgroup>
496535c4bbdfSmrg	</table>
496635c4bbdfSmrg
496735c4bbdfSmrg	<table frame="all" id="routines-2">
496835c4bbdfSmrg	  <title>Server Routines (Page 2)</title>
496935c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
497035c4bbdfSmrg	    <thead>
497135c4bbdfSmrg	      <row>
497235c4bbdfSmrg		<entry>Procedure</entry>
497335c4bbdfSmrg		<entry>Port</entry>
497435c4bbdfSmrg		<entry>Struct</entry>
497535c4bbdfSmrg	      </row>
497635c4bbdfSmrg	    </thead>
497735c4bbdfSmrg	    <tbody>
497835c4bbdfSmrg<row><entry><function>ImageGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
497935c4bbdfSmrg<row><entry><function>ImageText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
498035c4bbdfSmrg<row><entry><function>ImageText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
498135c4bbdfSmrg<row><entry><function>InitInput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
498235c4bbdfSmrg<row><entry><function>InitKeyboardDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
498335c4bbdfSmrg<row><entry><function>InitOutput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
498435c4bbdfSmrg<row><entry><function>InitPointerDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
498535c4bbdfSmrg<row><entry><function>InsertFakeRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
498635c4bbdfSmrg<row><entry><function>InstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
498735c4bbdfSmrg<row><entry><function>Intersect</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
498835c4bbdfSmrg<row><entry><function>Inverse</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
498935c4bbdfSmrg<row><entry><function>LineHelper</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
499035c4bbdfSmrg<row><entry><function>ListInstalledColormaps</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
499135c4bbdfSmrg<row><entry><function>LookupKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
499235c4bbdfSmrg<row><entry><function>LookupPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
499335c4bbdfSmrg<row><entry><function>ModifyPixmapHeader</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
499435c4bbdfSmrg<row><entry><function>NextAvailableClient</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
499535c4bbdfSmrg<row><entry><function>OsInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
499635c4bbdfSmrg<row><entry><function>PaintWindowBackground</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
499735c4bbdfSmrg<row><entry><function>PaintWindowBorder</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
499835c4bbdfSmrg<row><entry><function>PointerNonInterestBox</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
499935c4bbdfSmrg<row><entry><function>PointInRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
500035c4bbdfSmrg<row><entry><function>PolyArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500135c4bbdfSmrg<row><entry><function>PolyFillArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500235c4bbdfSmrg<row><entry><function>PolyFillRect</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500335c4bbdfSmrg<row><entry><function>PolyGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500435c4bbdfSmrg<row><entry><function>Polylines</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500535c4bbdfSmrg<row><entry><function>PolyPoint</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500635c4bbdfSmrg<row><entry><function>PolyRectangle</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500735c4bbdfSmrg<row><entry><function>PolySegment</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500835c4bbdfSmrg<row><entry><function>PolyText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
500935c4bbdfSmrg<row><entry><function>PolyText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501035c4bbdfSmrg<row><entry><function>PositionWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
501135c4bbdfSmrg<row><entry><function>ProcessInputEvents</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
501235c4bbdfSmrg<row><entry><function>PushPixels</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501335c4bbdfSmrg<row><entry><function>PutImage</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
501435c4bbdfSmrg<row><entry><function>QueryBestSize</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
501535c4bbdfSmrg<row><entry><function>ReadRequestFromClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
501635c4bbdfSmrg<row><entry><function>RealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
501735c4bbdfSmrg<row><entry><function>RealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
501835c4bbdfSmrg<row><entry><function>RealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
501935c4bbdfSmrg<row><entry><function>RecolorCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
502035c4bbdfSmrg<row><entry><function>RectIn</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502135c4bbdfSmrg<row><entry><function>RegionCopy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502235c4bbdfSmrg<row><entry><function>RegionCreate</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502335c4bbdfSmrg<row><entry><function>RegionDestroy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502435c4bbdfSmrg<row><entry><function>RegionEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502535c4bbdfSmrg<row><entry><function>RegionExtents</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502635c4bbdfSmrg<row><entry><function>RegionNotEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502735c4bbdfSmrg<row><entry><function>RegionReset</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
502835c4bbdfSmrg<row><entry><function>ResolveColor</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
502935c4bbdfSmrg	    </tbody>
503035c4bbdfSmrg	  </tgroup>
503135c4bbdfSmrg	</table>
503235c4bbdfSmrg
503335c4bbdfSmrg	<table frame="all" id="routines-3">
503435c4bbdfSmrg	  <title>Server Routines (Page 3)</title>
503535c4bbdfSmrg	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
503635c4bbdfSmrg	    <thead>
503735c4bbdfSmrg	      <row>
503835c4bbdfSmrg		<entry>Procedure</entry>
503935c4bbdfSmrg		<entry>Port</entry>
504035c4bbdfSmrg		<entry>Struct</entry>
504135c4bbdfSmrg	      </row>
504235c4bbdfSmrg	    </thead>
504335c4bbdfSmrg	    <tbody>
504435c4bbdfSmrg<row><entry><function>RemoveEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
504535c4bbdfSmrg<row><entry><function>ResetCurrentRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
504635c4bbdfSmrg<row><entry><function>SaveScreen</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
504735c4bbdfSmrg<row><entry><function>SetCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
504835c4bbdfSmrg<row><entry><function>SetCursorPosition</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
504935c4bbdfSmrg<row><entry><function>SetInputCheck</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
505035c4bbdfSmrg<row><entry><function>SetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
505135c4bbdfSmrg<row><entry><function>StoreColors</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
505235c4bbdfSmrg<row><entry><function>Subtract</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
505335c4bbdfSmrg<row><entry><function>TimerCancel</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505435c4bbdfSmrg<row><entry><function>TimerCheck</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505535c4bbdfSmrg<row><entry><function>TimerForce</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505635c4bbdfSmrg<row><entry><function>TimerFree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505735c4bbdfSmrg<row><entry><function>TimerInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505835c4bbdfSmrg<row><entry><function>TimerSet</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
505935c4bbdfSmrg<row><entry><function>TimeSinceLastInputEvent</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
506035c4bbdfSmrg<row><entry><function>TranslateRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
506135c4bbdfSmrg<row><entry><function>UninstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
506235c4bbdfSmrg<row><entry><function>Union</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
506335c4bbdfSmrg<row><entry><function>UnrealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
506435c4bbdfSmrg<row><entry><function>UnrealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
506535c4bbdfSmrg<row><entry><function>UnrealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
506635c4bbdfSmrg<row><entry><function>ValidateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
506735c4bbdfSmrg<row><entry><function>ValidateTree</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
506835c4bbdfSmrg<row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
506935c4bbdfSmrg<row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
507035c4bbdfSmrg<row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
507135c4bbdfSmrg	    </tbody>
507235c4bbdfSmrg	  </tgroup>
507335c4bbdfSmrg	</table>
507435c4bbdfSmrg</section>
507535c4bbdfSmrg</article>
5076