xref: /OK3568_Linux_fs/external/xserver/doc/Xserver-spec.xml (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun<?xml version="1.0" encoding="ISO-8859-1"?>
2*4882a593Smuzhiyun<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3*4882a593Smuzhiyun "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4*4882a593Smuzhiyun <!ENTITY % xorg-defs SYSTEM "defs.ent"> %xorg-defs;
5*4882a593Smuzhiyun <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs;
6*4882a593Smuzhiyun]>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun<article>
9*4882a593Smuzhiyun  <articleinfo>
10*4882a593Smuzhiyun    <title>Definition of the Porting Layer for the X v11 Sample Server</title>
11*4882a593Smuzhiyun    <titleabbrev>X Porting Layer</titleabbrev>
12*4882a593Smuzhiyun    <author>
13*4882a593Smuzhiyun      <firstname>Susan</firstname><surname>Angebranndt</surname>
14*4882a593Smuzhiyun      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
15*4882a593Smuzhiyun    </author>
16*4882a593Smuzhiyun    <author>
17*4882a593Smuzhiyun      <firstname>Raymond</firstname><surname>Drewry</surname>
18*4882a593Smuzhiyun      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
19*4882a593Smuzhiyun    </author>
20*4882a593Smuzhiyun    <author>
21*4882a593Smuzhiyun      <firstname>Philip</firstname><surname>Karlton</surname>
22*4882a593Smuzhiyun      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
23*4882a593Smuzhiyun    </author>
24*4882a593Smuzhiyun    <author>
25*4882a593Smuzhiyun      <firstname>Todd</firstname><surname>Newman</surname>
26*4882a593Smuzhiyun      <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
27*4882a593Smuzhiyun    </author>
28*4882a593Smuzhiyun    <author>
29*4882a593Smuzhiyun      <firstname>Bob</firstname><surname>Scheifler</surname>
30*4882a593Smuzhiyun      <affiliation><orgname>Massachusetts Institute of Technology</orgname></affiliation>
31*4882a593Smuzhiyun    </author>
32*4882a593Smuzhiyun    <author>
33*4882a593Smuzhiyun      <firstname>Keith</firstname><surname>Packard</surname>
34*4882a593Smuzhiyun      <affiliation><orgname>MIT X Consortium</orgname></affiliation>
35*4882a593Smuzhiyun    </author>
36*4882a593Smuzhiyun    <author>
37*4882a593Smuzhiyun      <firstname>David</firstname><othername>P.</othername><surname>Wiggins</surname>
38*4882a593Smuzhiyun      <affiliation><orgname>X Consortium</orgname></affiliation>
39*4882a593Smuzhiyun    </author>
40*4882a593Smuzhiyun    <author>
41*4882a593Smuzhiyun      <firstname>Jim</firstname><surname>Gettys</surname>
42*4882a593Smuzhiyun      <affiliation><orgname>X.org Foundation and Hewlett Packard</orgname></affiliation>
43*4882a593Smuzhiyun    </author>
44*4882a593Smuzhiyun    <publisher><publishername>The X.Org Foundation</publishername></publisher>
45*4882a593Smuzhiyun    <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
46*4882a593Smuzhiyun    <releaseinfo>X Server Version &xserver.version;</releaseinfo>
47*4882a593Smuzhiyun    <copyright><year>1994</year><holder>X Consortium, Inc.</holder></copyright>
48*4882a593Smuzhiyun    <copyright><year>2004</year><holder>X.org Foundation, Inc.</holder></copyright>
49*4882a593Smuzhiyun    <legalnotice>
50*4882a593Smuzhiyun      <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>
51*4882a593Smuzhiyun      <para>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</para>
52*4882a593Smuzhiyun      <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>
53*4882a593Smuzhiyun      <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>
54*4882a593Smuzhiyun    </legalnotice>
55*4882a593Smuzhiyun    <pubdate>&xserver.reldate;</pubdate>
56*4882a593Smuzhiyun    <revhistory>
57*4882a593Smuzhiyun      <revision>
58*4882a593Smuzhiyun	<revnumber>1.0</revnumber>
59*4882a593Smuzhiyun	<date>27 Oct 2004</date>
60*4882a593Smuzhiyun	<authorinitials>sa</authorinitials>
61*4882a593Smuzhiyun	<revremark>Initial Version</revremark>
62*4882a593Smuzhiyun      </revision>
63*4882a593Smuzhiyun      <revision>
64*4882a593Smuzhiyun	<revnumber>1.1</revnumber>
65*4882a593Smuzhiyun	<date>27 Oct 2004</date>
66*4882a593Smuzhiyun	<authorinitials>bs</authorinitials>
67*4882a593Smuzhiyun	<revremark>Minor Revisions</revremark>
68*4882a593Smuzhiyun      </revision>
69*4882a593Smuzhiyun      <revision>
70*4882a593Smuzhiyun	<revnumber>2.0</revnumber>
71*4882a593Smuzhiyun	<date>27 Oct 2004</date>
72*4882a593Smuzhiyun	<authorinitials>kp</authorinitials>
73*4882a593Smuzhiyun	<revremark>Revised for Release 4 and 5</revremark>
74*4882a593Smuzhiyun      </revision>
75*4882a593Smuzhiyun      <revision>
76*4882a593Smuzhiyun	<revnumber>3.0</revnumber>
77*4882a593Smuzhiyun	<date>27 Oct 2004</date>
78*4882a593Smuzhiyun	<authorinitials>dpw</authorinitials>
79*4882a593Smuzhiyun	<revremark>Revised for Release 6</revremark>
80*4882a593Smuzhiyun      </revision>
81*4882a593Smuzhiyun      <revision>
82*4882a593Smuzhiyun	<revnumber>3.1</revnumber>
83*4882a593Smuzhiyun	<date>27 Oct 2004</date>
84*4882a593Smuzhiyun	<authorinitials>jg</authorinitials>
85*4882a593Smuzhiyun	<revremark>Revised for Release 6.8.2</revremark>
86*4882a593Smuzhiyun      </revision>
87*4882a593Smuzhiyun      <revision>
88*4882a593Smuzhiyun	<revnumber>3.2</revnumber>
89*4882a593Smuzhiyun	<date>17 Dec 2006</date>
90*4882a593Smuzhiyun	<authorinitials>efw</authorinitials>
91*4882a593Smuzhiyun	<revremark>DocBook conversion</revremark>
92*4882a593Smuzhiyun      </revision>
93*4882a593Smuzhiyun      <revision>
94*4882a593Smuzhiyun	<revnumber>3.3</revnumber>
95*4882a593Smuzhiyun	<date>17 Feb 2008</date>
96*4882a593Smuzhiyun	<authorinitials>aj</authorinitials>
97*4882a593Smuzhiyun	<revremark>Revised for backing store changes</revremark>
98*4882a593Smuzhiyun      </revision>
99*4882a593Smuzhiyun      <revision>
100*4882a593Smuzhiyun	<revnumber>3.4</revnumber>
101*4882a593Smuzhiyun	<date>31 Mar 2008</date>
102*4882a593Smuzhiyun	<authorinitials>efw</authorinitials>
103*4882a593Smuzhiyun	<revremark>Revised for devPrivates changes</revremark>
104*4882a593Smuzhiyun      </revision>
105*4882a593Smuzhiyun      <revision>
106*4882a593Smuzhiyun	<revnumber>3.5</revnumber>
107*4882a593Smuzhiyun	<date>July 2010</date>
108*4882a593Smuzhiyun	<authorinitials>ac</authorinitials>
109*4882a593Smuzhiyun	<revremark>Revised for Xorg 1.9 devPrivates changes
110*4882a593Smuzhiyun	  and 1.8 CreateNewResourceType changes</revremark>
111*4882a593Smuzhiyun      </revision>
112*4882a593Smuzhiyun      <revision>
113*4882a593Smuzhiyun	<revnumber>3.6</revnumber>
114*4882a593Smuzhiyun	<date>July 2012</date>
115*4882a593Smuzhiyun	<authorinitials>kp</authorinitials>
116*4882a593Smuzhiyun	<revremark>Revised for X server 1.13 screen-specific devPrivates changes</revremark>
117*4882a593Smuzhiyun      </revision>
118*4882a593Smuzhiyun    </revhistory>
119*4882a593Smuzhiyun    <abstract>
120*4882a593Smuzhiyun      <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:
121*4882a593Smuzhiyun      <orderedlist>
122*4882a593Smuzhiyun	<listitem><para>Read the first section of the "Strategies for Porting" document (Overview of Porting Process).</para></listitem>
123*4882a593Smuzhiyun	<listitem><para>Skim over this document (the Definition document).</para></listitem>
124*4882a593Smuzhiyun	<listitem><para>Skim over the remainder of the Strategies document.</para></listitem>
125*4882a593Smuzhiyun	<listitem><para>Start planning and working, referring to the Strategies and Definition documents.</para></listitem>
126*4882a593Smuzhiyun      </orderedlist>
127*4882a593Smuzhiyun      You may also want to look at the following documents:
128*4882a593Smuzhiyun      <itemizedlist>
129*4882a593Smuzhiyun	<listitem><para>"The X Window System" for an overview of X.</para></listitem>
130*4882a593Smuzhiyun	<listitem><para>"Xlib - C Language X Interface" for a view of what the client programmer sees.</para></listitem>
131*4882a593Smuzhiyun	<listitem><para>"X Window System Protocol" for a terse description of the byte stream protocol between the client and server.</para></listitem>
132*4882a593Smuzhiyun      </itemizedlist>
133*4882a593Smuzhiyun      </para>
134*4882a593Smuzhiyun      <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>
135*4882a593Smuzhiyun      <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>
136*4882a593Smuzhiyun      <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>
137*4882a593Smuzhiyun    </abstract>
138*4882a593Smuzhiyun  </articleinfo>
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun<!-- Original authorship information:
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun.OF 'Porting Layer Definition'- % -'October 27, 2004'
143*4882a593SmuzhiyunDefinition of the Porting Layer
144*4882a593Smuzhiyunfor the X v11 Sample Server
145*4882a593SmuzhiyunSusan Angebranndt
146*4882a593SmuzhiyunRaymond Drewry
147*4882a593SmuzhiyunPhilip Karlton
148*4882a593SmuzhiyunTodd Newman
149*4882a593SmuzhiyunDigital Equipment Corporation
150*4882a593Smuzhiyun
151*4882a593Smuzhiyunminor revisions by
152*4882a593SmuzhiyunBob Scheifler
153*4882a593SmuzhiyunMassachusetts Institute of Technology
154*4882a593Smuzhiyun
155*4882a593SmuzhiyunRevised for Release 4 and Release 5 by
156*4882a593SmuzhiyunKeith Packard
157*4882a593SmuzhiyunMIT X Consortium
158*4882a593Smuzhiyun
159*4882a593SmuzhiyunRevised for Release 6 by
160*4882a593SmuzhiyunDavid P. Wiggins
161*4882a593SmuzhiyunX Consortium
162*4882a593Smuzhiyun
163*4882a593SmuzhiyunMinor Revisions for Release 6.8.2 by
164*4882a593SmuzhiyunJim Gettys
165*4882a593SmuzhiyunX.org Foundation and Hewlett Packard
166*4882a593Smuzhiyun-->
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun<section>
169*4882a593Smuzhiyun  <title>The X Window System</title>
170*4882a593Smuzhiyun<para>
171*4882a593SmuzhiyunThe X Window System, or simply "X," is a
172*4882a593Smuzhiyunwindowing system that provides high-performance, high-level,
173*4882a593Smuzhiyundevice-independent graphics.
174*4882a593Smuzhiyun</para>
175*4882a593Smuzhiyun<para>
176*4882a593SmuzhiyunX is a windowing system designed for bitmapped graphic displays.
177*4882a593SmuzhiyunThe display can have a
178*4882a593Smuzhiyunsimple, monochrome display or it can have a color display with up to 32 bits
179*4882a593Smuzhiyunper pixel with a special graphics processor doing the work.  (In this
180*4882a593Smuzhiyundocument, monochrome means a black and white display with one bit per pixel.
181*4882a593SmuzhiyunEven though the usual meaning of monochrome is more general, this special
182*4882a593Smuzhiyuncase is so common that we decided to reserve the word for this purpose.)
183*4882a593SmuzhiyunIn practice, monochrome displays are now almost unheard of, with 4 bit
184*4882a593Smuzhiyungray scale displays being the low end.
185*4882a593Smuzhiyun</para>
186*4882a593Smuzhiyun<para>
187*4882a593SmuzhiyunX is designed for a networking environment where
188*4882a593Smuzhiyunusers can run applications on machines other than their own workstations.
189*4882a593SmuzhiyunSometimes, the connection is over an Ethernet network with a protocol such as TCP/IP;
190*4882a593Smuzhiyunbut, any "reliable" byte stream is allowable.
191*4882a593SmuzhiyunA high-bandwidth byte stream is preferable; RS-232 at
192*4882a593Smuzhiyun9600 baud would be slow without compression techniques.
193*4882a593Smuzhiyun</para>
194*4882a593Smuzhiyun<para>
195*4882a593SmuzhiyunX by itself allows great freedom of design.
196*4882a593SmuzhiyunFor instance, it does not include any user interface standard.
197*4882a593SmuzhiyunIts intent is to "provide mechanism, not policy."
198*4882a593SmuzhiyunBy making it general, it can be the foundation for a wide
199*4882a593Smuzhiyunvariety of interactive software.
200*4882a593Smuzhiyun</para>
201*4882a593Smuzhiyun<para>
202*4882a593SmuzhiyunFor a more detailed overview, see the document "The X Window System."
203*4882a593SmuzhiyunFor details on the byte stream protocol, see "X Window System protocol."
204*4882a593Smuzhiyun</para>
205*4882a593Smuzhiyun</section>
206*4882a593Smuzhiyun<section>
207*4882a593Smuzhiyun<title>Overview of the Server</title>
208*4882a593Smuzhiyun<para>
209*4882a593SmuzhiyunThe display server
210*4882a593Smuzhiyunmanages windows and simple graphics requests
211*4882a593Smuzhiyunfor the user on behalf of different client applications.
212*4882a593SmuzhiyunThe client applications can be running on any machine on the network.
213*4882a593SmuzhiyunThe server mainly does three things:
214*4882a593Smuzhiyun<itemizedlist>
215*4882a593Smuzhiyun  <listitem><para>Responds to protocol requests from existing clients (mostly graphic and text drawing commands)</para></listitem>
216*4882a593Smuzhiyun  <listitem><para>Sends device input (keystrokes and mouse actions) and other events to existing clients</para></listitem>
217*4882a593Smuzhiyun  <listitem><para>Maintains client connections</para></listitem>
218*4882a593Smuzhiyun</itemizedlist>
219*4882a593Smuzhiyun</para>
220*4882a593Smuzhiyun<para>
221*4882a593SmuzhiyunThe server code is organized into four major pieces:
222*4882a593Smuzhiyun<itemizedlist>
223*4882a593Smuzhiyun  <listitem><para>Device Independent (DIX) layer - code shared among all implementations</para></listitem>
224*4882a593Smuzhiyun  <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>
225*4882a593Smuzhiyun  <listitem><para>Device Dependent (DDX) layer - code that is (potentially) different for each combination of operating system and graphic device</para></listitem>
226*4882a593Smuzhiyun  <listitem><para>Extension Interface - a standard way to add features to the X server</para></listitem>
227*4882a593Smuzhiyun</itemizedlist>
228*4882a593Smuzhiyun</para>
229*4882a593Smuzhiyun<para>
230*4882a593SmuzhiyunThe "porting layer" consists of the OS and DDX layers; these are
231*4882a593Smuzhiyunactually parallel and neither one is on top of the other.
232*4882a593SmuzhiyunThe DIX layer is intended to be portable
233*4882a593Smuzhiyunwithout change to target systems and is not
234*4882a593Smuzhiyundetailed here, although several routines
235*4882a593Smuzhiyunin DIX that are called by DDX are
236*4882a593Smuzhiyundocumented.
237*4882a593SmuzhiyunExtensions incorporate new functionality into the server; and require
238*4882a593Smuzhiyunadditional functionality over a simple DDX.
239*4882a593Smuzhiyun</para>
240*4882a593Smuzhiyun<para>
241*4882a593SmuzhiyunThe following sections outline the functions of the layers.
242*4882a593SmuzhiyunSection 3 briefly tells what you need to know about the DIX layer.
243*4882a593SmuzhiyunThe OS layer is explained in Section 4.
244*4882a593SmuzhiyunSection 5 gives the theory of operation and procedural interface for the
245*4882a593SmuzhiyunDDX layer.
246*4882a593SmuzhiyunSection 6 describes the functions which exist for the extension writer.
247*4882a593Smuzhiyun</para>
248*4882a593Smuzhiyun</section>
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun<section>
251*4882a593Smuzhiyun  <title>DIX Layer</title>
252*4882a593Smuzhiyun<para>
253*4882a593SmuzhiyunThe DIX layer is the machine and device independent part of X.
254*4882a593SmuzhiyunThe source should be common to all operating systems and devices.
255*4882a593SmuzhiyunThe port process should not include changes to this part, therefore internal interfaces to DIX
256*4882a593Smuzhiyunmodules are not discussed, except for public interfaces to the DDX and the OS layers.
257*4882a593SmuzhiyunThe functions described in this section are available for extension writers to use.
258*4882a593Smuzhiyun</para>
259*4882a593Smuzhiyun<para>
260*4882a593SmuzhiyunIn the process of getting your server to work, if
261*4882a593Smuzhiyunyou think that DIX must be modified for purposes other than bug fixes,
262*4882a593Smuzhiyunyou may be doing something wrong.
263*4882a593SmuzhiyunKeep looking for a more compatible solution.
264*4882a593SmuzhiyunWhen the next release of the X server code is available,
265*4882a593Smuzhiyunyou should be able to just drop in the new DIX code and compile it.
266*4882a593SmuzhiyunIf you change DIX,
267*4882a593Smuzhiyunyou will have to remember what changes you made and will have
268*4882a593Smuzhiyunto change the new sources before you can update to the new version.
269*4882a593Smuzhiyun</para>
270*4882a593Smuzhiyun<para>
271*4882a593SmuzhiyunThe heart of the DIX code is a loop called the dispatch loop.
272*4882a593SmuzhiyunEach time the processor goes around the loop, it sends off accumulated input events
273*4882a593Smuzhiyunfrom the input devices to the clients, and it processes requests from the clients.
274*4882a593SmuzhiyunThis loop is the most organized way for the server to
275*4882a593Smuzhiyunprocess the asynchronous requests that
276*4882a593Smuzhiyunit needs to process.
277*4882a593SmuzhiyunMost of these operations are performed by OS and DDX routines that you must supply.
278*4882a593Smuzhiyun</para>
279*4882a593Smuzhiyun<section>
280*4882a593Smuzhiyun  <title>Server Resource System</title>
281*4882a593Smuzhiyun<para>
282*4882a593SmuzhiyunX resources are C structs inside the server.
283*4882a593SmuzhiyunClient applications create and manipulate these objects
284*4882a593Smuzhiyunaccording to the rules of the X byte stream protocol.
285*4882a593SmuzhiyunClient applications refer to resources with resource IDs,
286*4882a593Smuzhiyunwhich are 32-bit integers that are sent over the network.
287*4882a593SmuzhiyunWithin the server, of course, they are just C structs, and we refer to them
288*4882a593Smuzhiyunby pointers.
289*4882a593Smuzhiyun</para>
290*4882a593Smuzhiyun<section>
291*4882a593Smuzhiyun  <title>Pre-Defined Resource Types</title>
292*4882a593Smuzhiyun<para>
293*4882a593SmuzhiyunThe DDX layer has several kinds of resources:
294*4882a593Smuzhiyun<itemizedlist>
295*4882a593Smuzhiyun<listitem><para>Window</para></listitem>
296*4882a593Smuzhiyun<listitem><para>Pixmap</para></listitem>
297*4882a593Smuzhiyun<listitem><para>Screen</para></listitem>
298*4882a593Smuzhiyun<listitem><para>Device</para></listitem>
299*4882a593Smuzhiyun<listitem><para>Colormap</para></listitem>
300*4882a593Smuzhiyun<listitem><para>Font</para></listitem>
301*4882a593Smuzhiyun<listitem><para>Cursor</para></listitem>
302*4882a593Smuzhiyun<listitem><para>Graphics Contexts</para></listitem>
303*4882a593Smuzhiyun</itemizedlist>
304*4882a593Smuzhiyun</para>
305*4882a593Smuzhiyun<para>
306*4882a593SmuzhiyunThe type names of the more
307*4882a593Smuzhiyunimportant server
308*4882a593Smuzhiyunstructs usually end in "Rec," such as "DeviceRec;"
309*4882a593Smuzhiyunthe pointer types usually end in "Ptr," such as "DevicePtr."
310*4882a593Smuzhiyun</para>
311*4882a593Smuzhiyun<para>
312*4882a593SmuzhiyunThe structs and
313*4882a593Smuzhiyunimportant defined constants are declared
314*4882a593Smuzhiyunin .h files that have names that suggest the name of the object.
315*4882a593SmuzhiyunFor instance, there are two .h files for windows,
316*4882a593Smuzhiyunwindow.h and windowstr.h.
317*4882a593Smuzhiyunwindow.h defines only what needs to be defined in order to use windows
318*4882a593Smuzhiyunwithout peeking inside of them;
319*4882a593Smuzhiyunwindowstr.h defines the structs with all of their components in great detail
320*4882a593Smuzhiyunfor those who need it.
321*4882a593Smuzhiyun</para>
322*4882a593Smuzhiyun<para>
323*4882a593SmuzhiyunThree kinds of fields are in these structs:
324*4882a593Smuzhiyun<itemizedlist>
325*4882a593Smuzhiyun<listitem><para>Attribute fields - struct fields that contain values like normal structs</para></listitem>
326*4882a593Smuzhiyun<listitem><para>Pointers to procedures, or structures of procedures, that operate on the object</para></listitem>
327*4882a593Smuzhiyun<listitem><para>A single private field or a devPrivates list (see <xref linkend="wrappers_and_privates"/>)
328*4882a593Smuzhiyunused by your DDX code to store private data.</para></listitem>
329*4882a593Smuzhiyun</itemizedlist>
330*4882a593Smuzhiyun</para>
331*4882a593Smuzhiyun<para>
332*4882a593SmuzhiyunDIX calls through
333*4882a593Smuzhiyunthe struct's procedure pointers to do its tasks.
334*4882a593SmuzhiyunThese procedures are set either directly or indirectly by DDX procedures.
335*4882a593SmuzhiyunMost of
336*4882a593Smuzhiyunthe procedures described in the remainder of this
337*4882a593Smuzhiyundocument are accessed through one of these structs.
338*4882a593SmuzhiyunFor example, the procedure to create a pixmap
339*4882a593Smuzhiyunis attached to a ScreenRec and might be called by using the expression
340*4882a593Smuzhiyun</para>
341*4882a593Smuzhiyun<para>
342*4882a593Smuzhiyun<blockquote>
343*4882a593Smuzhiyun<programlisting>(* pScreen->CreatePixmap)(pScreen, width, height, depth).</programlisting>
344*4882a593Smuzhiyun</blockquote>
345*4882a593Smuzhiyun</para>
346*4882a593Smuzhiyun<para>
347*4882a593SmuzhiyunAll procedure pointers must be set to some routine unless noted otherwise;
348*4882a593Smuzhiyuna null pointer will have unfortunate consequences.
349*4882a593Smuzhiyun</para>
350*4882a593Smuzhiyun<para>
351*4882a593SmuzhiyunProcedure routines will be indicated in the documentation by this convention:
352*4882a593Smuzhiyun<blockquote>
353*4882a593Smuzhiyun<programlisting>void pScreen->MyScreenRoutine(arg, arg, ...)</programlisting>
354*4882a593Smuzhiyun</blockquote>
355*4882a593Smuzhiyunas opposed to a free routine, not in a data structure:
356*4882a593Smuzhiyun<blockquote>
357*4882a593Smuzhiyun<programlisting>void MyFreeRoutine(arg, arg, ...)</programlisting>
358*4882a593Smuzhiyun</blockquote>
359*4882a593Smuzhiyun</para>
360*4882a593Smuzhiyun<para>
361*4882a593SmuzhiyunThe attribute fields are mostly set by DIX; DDX should not modify them
362*4882a593Smuzhiyununless noted otherwise.
363*4882a593Smuzhiyun</para>
364*4882a593Smuzhiyun</section>
365*4882a593Smuzhiyun<section>
366*4882a593Smuzhiyun  <title>Creating Resources and Resource Types</title>
367*4882a593Smuzhiyun<para>
368*4882a593SmuzhiyunThese functions should also be called from your extensionInitProc to
369*4882a593Smuzhiyunallocate all of the various resource classes and types required for
370*4882a593Smuzhiyunthe extension.  Each time the server resets, these types must be reallocated
371*4882a593Smuzhiyunas the old allocations will have been discarded.
372*4882a593SmuzhiyunResource types are integer values starting at 1.  Get
373*4882a593Smuzhiyuna resource type by calling
374*4882a593Smuzhiyun<blockquote><programlisting>
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun    RESTYPE CreateNewResourceType(deleteFunc, char *name)
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun</programlisting></blockquote>
379*4882a593SmuzhiyundeleteFunc will be called to destroy all resources with this
380*4882a593Smuzhiyuntype.   name will be used to identify this type of resource
381*4882a593Smuzhiyunto clients using the X-Resource extension, to security
382*4882a593Smuzhiyunextensions such as SELinux, and to tracing frameworks such as DTrace.
383*4882a593Smuzhiyun[The name argument was added in xorg-server 1.8.]
384*4882a593Smuzhiyun</para>
385*4882a593Smuzhiyun<para>
386*4882a593SmuzhiyunResource classes are masks starting at 1 &lt;&lt; 31 which can
387*4882a593Smuzhiyunbe or'ed with any resource type to provide attributes for the
388*4882a593Smuzhiyuntype.  To allocate a new class bit, call
389*4882a593Smuzhiyun<blockquote><programlisting>
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun    RESTYPE CreateNewResourceClass()
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun</programlisting></blockquote>
394*4882a593Smuzhiyun</para>
395*4882a593Smuzhiyun<para>
396*4882a593SmuzhiyunThere are two ways of looking up resources, by type or
397*4882a593Smuzhiyunby class.  Classes are non-exclusive subsets of the space of
398*4882a593Smuzhiyunall resources, so you can lookup the union of multiple classes.
399*4882a593Smuzhiyun(RC_ANY is the union of all classes).</para>
400*4882a593Smuzhiyun<para>
401*4882a593SmuzhiyunNote that the appropriate class bits must be or'ed into the value returned
402*4882a593Smuzhiyunby CreateNewResourceType when calling resource lookup functions.</para>
403*4882a593Smuzhiyun<para>
404*4882a593SmuzhiyunIf you need to create a ``private'' resource ID for internal use, you
405*4882a593Smuzhiyuncan call FakeClientID.
406*4882a593Smuzhiyun<blockquote><programlisting>
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun	XID FakeClientID(client)
409*4882a593Smuzhiyun	    int client;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun</programlisting></blockquote>
412*4882a593SmuzhiyunThis allocates from ID space reserved for the server.</para>
413*4882a593Smuzhiyun<para>
414*4882a593SmuzhiyunTo associate a resource value with an ID, use AddResource.
415*4882a593Smuzhiyun<blockquote><programlisting>
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun	Bool AddResource(id, type, value)
418*4882a593Smuzhiyun	    XID id;
419*4882a593Smuzhiyun	    RESTYPE type;
420*4882a593Smuzhiyun	    pointer value;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun</programlisting></blockquote>
423*4882a593SmuzhiyunThe type should be the full type of the resource, including any class
424*4882a593Smuzhiyunbits.  If AddResource fails to allocate memory to store the resource,
425*4882a593Smuzhiyunit will call the deleteFunc for the type, and then return False.</para>
426*4882a593Smuzhiyun<para>
427*4882a593SmuzhiyunTo free a resource, use one of the following.
428*4882a593Smuzhiyun<blockquote><programlisting>
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun	void FreeResource(id, skipDeleteFuncType)
431*4882a593Smuzhiyun	    XID id;
432*4882a593Smuzhiyun	    RESTYPE skipDeleteFuncType;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun	void FreeResourceByType(id, type, skipFree)
435*4882a593Smuzhiyun	    XID id;
436*4882a593Smuzhiyun	    RESTYPE type;
437*4882a593Smuzhiyun	    Bool    skipFree;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun</programlisting></blockquote>
440*4882a593SmuzhiyunFreeResource frees all resources matching the given id, regardless of
441*4882a593Smuzhiyuntype; the type's deleteFunc will be called on each matching resource,
442*4882a593Smuzhiyunexcept that skipDeleteFuncType can be set to a single type for which
443*4882a593Smuzhiyunthe deleteFunc should not be called (otherwise pass RT_NONE).
444*4882a593SmuzhiyunFreeResourceByType frees a specific resource matching a given id
445*4882a593Smuzhiyunand type; if skipFree is true, then the deleteFunc is not called.
446*4882a593Smuzhiyun</para>
447*4882a593Smuzhiyun</section>
448*4882a593Smuzhiyun<section>
449*4882a593Smuzhiyun  <title>Looking Up Resources</title>
450*4882a593Smuzhiyun<para>
451*4882a593SmuzhiyunTo look up a resource, use one of the following.
452*4882a593Smuzhiyun<blockquote><programlisting>
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun	int dixLookupResourceByType(
455*4882a593Smuzhiyun	    pointer *result,
456*4882a593Smuzhiyun	    XID id,
457*4882a593Smuzhiyun	    RESTYPE rtype,
458*4882a593Smuzhiyun	    ClientPtr client,
459*4882a593Smuzhiyun	    Mask access_mode);
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun	int dixLookupResourceByClass(
462*4882a593Smuzhiyun	    pointer *result,
463*4882a593Smuzhiyun	    XID id,
464*4882a593Smuzhiyun	    RESTYPE rclass,
465*4882a593Smuzhiyun	    ClientPtr client,
466*4882a593Smuzhiyun	    Mask access_mode);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun</programlisting></blockquote>
469*4882a593SmuzhiyundixLookupResourceByType finds a resource with the given id and exact type.
470*4882a593SmuzhiyundixLookupResourceByClass finds a resource with the given id whose type is
471*4882a593Smuzhiyunincluded in any one of the specified classes.
472*4882a593SmuzhiyunThe client and access_mode must be provided to allow security extensions to
473*4882a593Smuzhiyuncheck if the client has the right privileges for the requested access.
474*4882a593SmuzhiyunThe bitmask values defined in the dixaccess.h header are or'ed together
475*4882a593Smuzhiyunto define the requested access_mode.
476*4882a593Smuzhiyun</para>
477*4882a593Smuzhiyun</section>
478*4882a593Smuzhiyun</section>
479*4882a593Smuzhiyun<section>
480*4882a593Smuzhiyun  <title>Callback Manager</title>
481*4882a593Smuzhiyun<para>
482*4882a593SmuzhiyunTo satisfy a growing number of requests for the introduction of ad hoc
483*4882a593Smuzhiyunnotification style hooks in the server, a generic callback manager was
484*4882a593Smuzhiyunintroduced in R6.  A callback list object can be introduced for each
485*4882a593Smuzhiyunnew hook that is desired, and other modules in the server can register
486*4882a593Smuzhiyuninterest in the new callback list.  The following functions support
487*4882a593Smuzhiyunthese operations.</para>
488*4882a593Smuzhiyun<para>
489*4882a593SmuzhiyunBefore getting bogged down in the interface details, an typical usage
490*4882a593Smuzhiyunexample should establish the framework.  Let's look at the
491*4882a593SmuzhiyunClientStateCallback in dix/dispatch.c.  The purpose of this particular
492*4882a593Smuzhiyuncallback is to notify interested parties when a client's state
493*4882a593Smuzhiyun(initial, running, gone) changes.  The callback is "created" in this
494*4882a593Smuzhiyuncase by simply declaring a variable:
495*4882a593Smuzhiyun<blockquote><programlisting>
496*4882a593Smuzhiyun	CallbackListPtr ClientStateCallback;
497*4882a593Smuzhiyun</programlisting></blockquote>
498*4882a593Smuzhiyun</para>
499*4882a593Smuzhiyun<para>
500*4882a593SmuzhiyunWhenever the client's state changes, the following code appears, which notifies
501*4882a593Smuzhiyunall interested parties of the change:
502*4882a593Smuzhiyun<blockquote><programlisting>
503*4882a593Smuzhiyun	if (ClientStateCallback) CallCallbacks(&amp;ClientStateCallback, (pointer)client);
504*4882a593Smuzhiyun</programlisting></blockquote>
505*4882a593Smuzhiyun</para>
506*4882a593Smuzhiyun<para>
507*4882a593SmuzhiyunInterested parties subscribe to the ClientStateCallback list by saying:
508*4882a593Smuzhiyun<blockquote><programlisting>
509*4882a593Smuzhiyun	AddCallback(&amp;ClientStateCallback, func, data);
510*4882a593Smuzhiyun</programlisting></blockquote>
511*4882a593Smuzhiyun</para>
512*4882a593Smuzhiyun<para>
513*4882a593SmuzhiyunWhen CallCallbacks is invoked on the list, func will be called thusly:
514*4882a593Smuzhiyun<blockquote><programlisting>
515*4882a593Smuzhiyun	(*func)(&amp;ClientStateCallback, data, client)
516*4882a593Smuzhiyun</programlisting></blockquote>
517*4882a593Smuzhiyun</para>
518*4882a593Smuzhiyun<para>
519*4882a593SmuzhiyunNow for the details.
520*4882a593Smuzhiyun<blockquote><programlisting>
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun	Bool AddCallback(pcbl, callback, subscriber_data)
523*4882a593Smuzhiyun	    CallbackListPtr *pcbl;
524*4882a593Smuzhiyun	    CallbackProcPtr callback;
525*4882a593Smuzhiyun	    pointer         subscriber_data;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun</programlisting></blockquote>
528*4882a593SmuzhiyunAdds the (callback, subscriber_data) pair to the given callback list.  Creates the callback
529*4882a593Smuzhiyunlist if it doesn't exist.  Returns TRUE if successful.</para>
530*4882a593Smuzhiyun<para>
531*4882a593Smuzhiyun<blockquote><programlisting>
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun	Bool DeleteCallback(pcbl, callback, subscriber_data)
534*4882a593Smuzhiyun	    CallbackListPtr *pcbl;
535*4882a593Smuzhiyun	    CallbackProcPtr callback;
536*4882a593Smuzhiyun	    pointer         subscriber_data;
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun</programlisting></blockquote>
539*4882a593SmuzhiyunRemoves the (callback, data) pair to the given callback list if present.
540*4882a593SmuzhiyunReturns TRUE if (callback, data) was found.</para>
541*4882a593Smuzhiyun<para>
542*4882a593Smuzhiyun<blockquote><programlisting>
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun	void CallCallbacks(pcbl, call_data)
545*4882a593Smuzhiyun	    CallbackListPtr    *pcbl;
546*4882a593Smuzhiyun	    pointer	    call_data;
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun</programlisting></blockquote>
549*4882a593SmuzhiyunFor each callback currently registered on the given callback list, call
550*4882a593Smuzhiyunit as follows:
551*4882a593Smuzhiyun<blockquote><programlisting>
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun	(*callback)(pcbl, subscriber_data, call_data);
554*4882a593Smuzhiyun</programlisting></blockquote>
555*4882a593Smuzhiyun</para>
556*4882a593Smuzhiyun<para>
557*4882a593Smuzhiyun<blockquote><programlisting>
558*4882a593Smuzhiyun	void DeleteCallbackList(pcbl)
559*4882a593Smuzhiyun	    CallbackListPtr    *pcbl;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun</programlisting></blockquote>
562*4882a593SmuzhiyunDestroys the given callback list.</para>
563*4882a593Smuzhiyun</section>
564*4882a593Smuzhiyun<section>
565*4882a593Smuzhiyun  <title>Extension Interfaces</title>
566*4882a593Smuzhiyun<para>
567*4882a593SmuzhiyunThis function should be called from your extensionInitProc which
568*4882a593Smuzhiyunshould be called by InitExtensions.
569*4882a593Smuzhiyun<blockquote><programlisting>
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun	ExtensionEntry *AddExtension(name, NumEvents,NumErrors,
572*4882a593Smuzhiyun		MainProc, SwappedMainProc, CloseDownProc, MinorOpcodeProc)
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun		const char *name;  /*Null terminate string; case matters*/
575*4882a593Smuzhiyun		int NumEvents;
576*4882a593Smuzhiyun		int NumErrors;
577*4882a593Smuzhiyun		int (* MainProc)(ClientPtr);/*Called if client matches server order*/
578*4882a593Smuzhiyun		int (* SwappedMainProc)(ClientPtr);/*Called if client differs from server*/
579*4882a593Smuzhiyun		void (* CloseDownProc)(ExtensionEntry *);
580*4882a593Smuzhiyun		unsigned short (*MinorOpcodeProc)(ClientPtr);
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun</programlisting></blockquote>
583*4882a593Smuzhiyunname is the name used by clients to refer to the extension.  NumEvents is the
584*4882a593Smuzhiyunnumber of event types used by the extension, NumErrors is the number of
585*4882a593Smuzhiyunerror codes needed by the extension.  MainProc is called whenever a client
586*4882a593Smuzhiyunaccesses the major opcode assigned to the extension.  SwappedMainProc is
587*4882a593Smuzhiyunidentical, except the client using the extension has reversed byte-sex.
588*4882a593SmuzhiyunCloseDownProc is called at server reset time to deallocate any private
589*4882a593Smuzhiyunstorage used by the extension.  MinorOpcodeProc is used by DIX to place the
590*4882a593Smuzhiyunappropriate value into errors.  The DIX routine StandardMinorOpcode can be
591*4882a593Smuzhiyunused here which takes the minor opcode from the normal place in the request
592*4882a593Smuzhiyun(i.e. just after the major opcode).</para>
593*4882a593Smuzhiyun</section>
594*4882a593Smuzhiyun<section>
595*4882a593Smuzhiyun  <title>Macros and Other Helpers</title>
596*4882a593Smuzhiyun<para>
597*4882a593SmuzhiyunThere are a number of macros in Xserver/include/dix.h which
598*4882a593Smuzhiyunare useful to the extension writer.  Ones of particular interest
599*4882a593Smuzhiyunare: REQUEST, REQUEST_SIZE_MATCH, REQUEST_AT_LEAST_SIZE,
600*4882a593SmuzhiyunREQUEST_FIXED_SIZE, LEGAL_NEW_RESOURCE, and
601*4882a593SmuzhiyunVALIDATE_DRAWABLE_AND_GC. Useful byte swapping macros can be found
602*4882a593Smuzhiyunin Xserver/include/dix.h: WriteReplyToClient and WriteSwappedDataToClient; and
603*4882a593Smuzhiyunin Xserver/include/misc.h: bswap_64, bswap_32, bswap_16, LengthRestB, LengthRestS,
604*4882a593SmuzhiyunLengthRestL, SwapRestS, SwapRestL, swapl, swaps, cpswapl, and cpswaps.</para>
605*4882a593Smuzhiyun</section>
606*4882a593Smuzhiyun</section>
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun<section>
609*4882a593Smuzhiyun  <title>OS Layer</title>
610*4882a593Smuzhiyun<para>
611*4882a593SmuzhiyunThis part of the source consists of a few routines that you have to rewrite
612*4882a593Smuzhiyunfor each operating system.
613*4882a593SmuzhiyunThese OS functions maintain the client connections and schedule work
614*4882a593Smuzhiyunto be done for clients.
615*4882a593SmuzhiyunThey also provide an interface to font files,
616*4882a593Smuzhiyunfont name to file name translation, and
617*4882a593Smuzhiyunlow level memory management.
618*4882a593Smuzhiyun<blockquote>
619*4882a593Smuzhiyun<programlisting>void OsInit()</programlisting>
620*4882a593Smuzhiyun</blockquote>
621*4882a593SmuzhiyunOsInit initializes your OS code, performing whatever tasks need to be done.
622*4882a593SmuzhiyunFrequently there is not much to be done.
623*4882a593SmuzhiyunThe sample server implementation is in Xserver/os/osinit.c.
624*4882a593Smuzhiyun</para>
625*4882a593Smuzhiyun<section>
626*4882a593Smuzhiyun  <title>Scheduling and Request Delivery</title>
627*4882a593Smuzhiyun<para>
628*4882a593SmuzhiyunThe main dispatch loop in DIX creates the illusion of multitasking between
629*4882a593Smuzhiyundifferent windows, while the server is itself but a single process.
630*4882a593SmuzhiyunThe dispatch loop breaks up the work for each client into small digestible parts.
631*4882a593SmuzhiyunSome parts are requests from a client, such as individual graphic commands.
632*4882a593SmuzhiyunSome parts are events delivered to the client, such as keystrokes from the user.
633*4882a593SmuzhiyunThe processing of events and requests for different
634*4882a593Smuzhiyunclients can be interleaved with one another so true multitasking
635*4882a593Smuzhiyunis not needed in the server.
636*4882a593Smuzhiyun</para>
637*4882a593Smuzhiyun<para>
638*4882a593SmuzhiyunYou must supply some of the pieces for proper scheduling between clients.
639*4882a593Smuzhiyun<blockquote>
640*4882a593Smuzhiyun<programlisting>
641*4882a593Smuzhiyun	int WaitForSomething(pClientReady)
642*4882a593Smuzhiyun		int *pClientReady;
643*4882a593Smuzhiyun</programlisting>
644*4882a593Smuzhiyun</blockquote>
645*4882a593Smuzhiyun</para>
646*4882a593Smuzhiyun<para>
647*4882a593SmuzhiyunWaitForSomething is the scheduler procedure you must write that will
648*4882a593Smuzhiyunsuspend your server process until something needs to be done.
649*4882a593SmuzhiyunThis call should
650*4882a593Smuzhiyunmake the server suspend until one or more of the following occurs:
651*4882a593Smuzhiyun<itemizedlist>
652*4882a593Smuzhiyun<listitem><para>There is an input event from the user or hardware (see SetInputCheck())</para></listitem>
653*4882a593Smuzhiyun<listitem><para>There are requests waiting from known clients, in which case you should return a count of clients stored in pClientReady</para></listitem>
654*4882a593Smuzhiyun<listitem><para>A new client tries to connect, in which case you should create the client and then continue waiting</para></listitem>
655*4882a593Smuzhiyun</itemizedlist>
656*4882a593Smuzhiyun</para>
657*4882a593Smuzhiyun<para>
658*4882a593SmuzhiyunBefore WaitForSomething() computes the masks to pass to select, poll or
659*4882a593Smuzhiyunsimilar operating system interface, it needs to
660*4882a593Smuzhiyunsee if there is anything to do on the work queue; if so, it must call a DIX
661*4882a593Smuzhiyunroutine called ProcessWorkQueue.
662*4882a593Smuzhiyun<blockquote>
663*4882a593Smuzhiyun<programlisting>
664*4882a593Smuzhiyun	extern WorkQueuePtr	workQueue;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun	if (workQueue)
667*4882a593Smuzhiyun		ProcessWorkQueue ();
668*4882a593Smuzhiyun</programlisting>
669*4882a593Smuzhiyun</blockquote>
670*4882a593Smuzhiyun</para>
671*4882a593Smuzhiyun<para>
672*4882a593SmuzhiyunIf WaitForSomething() decides it is about to do something that might block
673*4882a593Smuzhiyun(in the sample server,  before it calls select() or poll) it must call a DIX
674*4882a593Smuzhiyunroutine called BlockHandler().
675*4882a593Smuzhiyun<blockquote>
676*4882a593Smuzhiyun<programlisting>
677*4882a593Smuzhiyun	void BlockHandler(void *pTimeout)
678*4882a593Smuzhiyun</programlisting>
679*4882a593Smuzhiyun</blockquote>
680*4882a593SmuzhiyunThe types of the arguments are for agreement between the OS and DDX
681*4882a593Smuzhiyunimplementations,  but the pTimeout is a pointer to the information
682*4882a593Smuzhiyundetermining how long the block is allowed to last.
683*4882a593Smuzhiyun</para>
684*4882a593Smuzhiyun<para>
685*4882a593SmuzhiyunIn the sample server,  pTimeout is a pointer.
686*4882a593Smuzhiyun</para>
687*4882a593Smuzhiyun<para>
688*4882a593SmuzhiyunThe DIX BlockHandler() iterates through the Screens,  for each one calling
689*4882a593Smuzhiyunits BlockHandler.  A BlockHandler is declared thus:
690*4882a593Smuzhiyun<blockquote>
691*4882a593Smuzhiyun<programlisting>
692*4882a593Smuzhiyun	void xxxBlockHandler(ScreenPtr pScreen, void *pTimeout)
693*4882a593Smuzhiyun</programlisting>
694*4882a593Smuzhiyun</blockquote>
695*4882a593SmuzhiyunThe arguments are a pointer to the Screen, and the arguments to the
696*4882a593SmuzhiyunDIX BlockHandler().
697*4882a593Smuzhiyun</para>
698*4882a593Smuzhiyun<para>
699*4882a593SmuzhiyunImmediately after WaitForSomething returns from the
700*4882a593Smuzhiyunblock,  even if it didn't actually block,  it must call the DIX routine
701*4882a593SmuzhiyunWakeupHandler().
702*4882a593Smuzhiyun<blockquote>
703*4882a593Smuzhiyun<programlisting>
704*4882a593Smuzhiyun	void WakeupHandler(int result)
705*4882a593Smuzhiyun</programlisting>
706*4882a593Smuzhiyun</blockquote>
707*4882a593SmuzhiyunOnce again,  the types are not specified by DIX.  The result is the
708*4882a593Smuzhiyunsuccess indicator for the thing that (may have) blocked.
709*4882a593SmuzhiyunIn the sample server, result is the result from select() (or equivalent
710*4882a593Smuzhiyunoperating system function).
711*4882a593Smuzhiyun</para>
712*4882a593Smuzhiyun<para>
713*4882a593SmuzhiyunThe DIX WakeupHandler() calls each Screen's
714*4882a593SmuzhiyunWakeupHandler.  A WakeupHandler is declared thus:
715*4882a593Smuzhiyun<blockquote>
716*4882a593Smuzhiyun<programlisting>
717*4882a593Smuzhiyun	void xxxWakeupHandler(ScreenPtr pScreen, int result)
718*4882a593Smuzhiyun</programlisting>
719*4882a593Smuzhiyun</blockquote>
720*4882a593SmuzhiyunThe arguments are the Screen, of the Screen, and the arguments to
721*4882a593Smuzhiyunthe DIX WakeupHandler().
722*4882a593Smuzhiyun</para>
723*4882a593Smuzhiyun<para>
724*4882a593SmuzhiyunIn addition to the per-screen BlockHandlers, any module may register
725*4882a593Smuzhiyunblock and wakeup handlers (only together) using:
726*4882a593Smuzhiyun<blockquote>
727*4882a593Smuzhiyun<programlisting>
728*4882a593Smuzhiyun	Bool RegisterBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
729*4882a593Smuzhiyun		ServerBlockHandlerProcPtr    blockHandler;
730*4882a593Smuzhiyun		ServerWakeupHandlerProcPtr   wakeupHandler;
731*4882a593Smuzhiyun		pointer blockData;
732*4882a593Smuzhiyun</programlisting>
733*4882a593Smuzhiyun</blockquote>
734*4882a593SmuzhiyunA FALSE return code indicates that the registration failed for lack of
735*4882a593Smuzhiyunmemory.  To remove a registered Block handler at other than server reset time
736*4882a593Smuzhiyun(when they are all removed automatically), use:
737*4882a593Smuzhiyun<blockquote>
738*4882a593Smuzhiyun<programlisting>
739*4882a593Smuzhiyun	RemoveBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
740*4882a593Smuzhiyun		ServerBlockHandlerProcPtr   blockHandler;
741*4882a593Smuzhiyun		ServerWakeupHandlerProcPtr  wakeupHandler;
742*4882a593Smuzhiyun		pointer blockData;
743*4882a593Smuzhiyun</programlisting>
744*4882a593Smuzhiyun</blockquote>
745*4882a593SmuzhiyunAll three arguments must match the values passed to
746*4882a593SmuzhiyunRegisterBlockAndWakeupHandlers.
747*4882a593Smuzhiyun</para>
748*4882a593Smuzhiyun<para>
749*4882a593SmuzhiyunThese registered block handlers are called before the per-screen handlers:
750*4882a593Smuzhiyun<blockquote>
751*4882a593Smuzhiyun<programlisting>
752*4882a593Smuzhiyun	void (*ServerBlockHandler) (void *blockData, void *pTimeout)
753*4882a593Smuzhiyun</programlisting>
754*4882a593Smuzhiyun</blockquote>
755*4882a593Smuzhiyun</para>
756*4882a593Smuzhiyun<para>
757*4882a593SmuzhiyunSometimes block handlers need to adjust the time referenced by pTimeout,
758*4882a593Smuzhiyunwhich on UNIX family systems is generally represented by a struct timeval
759*4882a593Smuzhiyunconsisting of seconds and microseconds in 32 bit values.
760*4882a593SmuzhiyunAs a convenience to reduce error prone struct timeval computations which
761*4882a593Smuzhiyunrequire modulus arithmetic and correct overflow behavior in the face of
762*4882a593Smuzhiyunmillisecond wrapping through 32 bits,
763*4882a593Smuzhiyun<blockquote><programlisting>
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun	void AdjustWaitForDelay(void *pTimeout, unsigned long newdelay)
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun</programlisting></blockquote>
768*4882a593Smuzhiyunhas been provided.
769*4882a593Smuzhiyun</para>
770*4882a593Smuzhiyun<para>
771*4882a593SmuzhiyunAny wakeup handlers registered with RegisterBlockAndWakeupHandlers will
772*4882a593Smuzhiyunbe called after the Screen handlers:
773*4882a593Smuzhiyun<blockquote><programlisting>
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun	void (*ServerWakeupHandler) (void *blockData, int result)
776*4882a593Smuzhiyun</programlisting></blockquote>
777*4882a593Smuzhiyun</para>
778*4882a593Smuzhiyun<para>
779*4882a593SmuzhiyunThe WaitForSomething on the sample server also has a built
780*4882a593Smuzhiyunin screen saver that darkens the screen if no input happens for a period of time.
781*4882a593SmuzhiyunThe sample server implementation is in Xserver/os/WaitFor.c.
782*4882a593Smuzhiyun</para>
783*4882a593Smuzhiyun<para>
784*4882a593SmuzhiyunNote that WaitForSomething() may be called when you already have several
785*4882a593Smuzhiyunoutstanding things (events, requests, or new clients) queued up.
786*4882a593SmuzhiyunFor instance, your server may have just done a large graphics request,
787*4882a593Smuzhiyunand it may have been a long time since WaitForSomething() was last called.
788*4882a593SmuzhiyunIf many clients have lots of requests queued up, DIX will only service
789*4882a593Smuzhiyunsome of them for a given client
790*4882a593Smuzhiyunbefore going on to the next client (see isItTimeToYield, below).
791*4882a593SmuzhiyunTherefore, WaitForSomething() will have to report that these same clients
792*4882a593Smuzhiyunstill have requests queued up the next time around.
793*4882a593Smuzhiyun</para>
794*4882a593Smuzhiyun<para>
795*4882a593SmuzhiyunAn implementation should return information on as
796*4882a593Smuzhiyunmany outstanding things as it can.
797*4882a593SmuzhiyunFor instance, if your implementation always checks for client data first and does not
798*4882a593Smuzhiyunreport any input events until there is no client data left,
799*4882a593Smuzhiyunyour mouse and keyboard might get locked out by an application that constantly
800*4882a593Smuzhiyunbarrages the server with graphics drawing requests.
801*4882a593SmuzhiyunTherefore, as a general rule, input devices should always have priority over graphics
802*4882a593Smuzhiyundevices.
803*4882a593Smuzhiyun</para>
804*4882a593Smuzhiyun<para>
805*4882a593SmuzhiyunA list of indexes (client->index) for clients with data ready to be read or
806*4882a593Smuzhiyunprocessed should be returned in pClientReady, and the count of indexes
807*4882a593Smuzhiyunreturned as the result value of the call.
808*4882a593SmuzhiyunThese are not clients that have full requests ready, but any clients who have
809*4882a593Smuzhiyunany data ready to be read or processed.
810*4882a593SmuzhiyunThe DIX dispatcher
811*4882a593Smuzhiyunwill process requests from each client in turn by calling
812*4882a593SmuzhiyunReadRequestFromClient(), below.
813*4882a593Smuzhiyun</para>
814*4882a593Smuzhiyun<para>
815*4882a593SmuzhiyunWaitForSomething() must create new clients as they are requested (by
816*4882a593Smuzhiyunwhatever mechanism at the transport level).  A new client is created
817*4882a593Smuzhiyunby calling the DIX routine:
818*4882a593Smuzhiyun<blockquote><programlisting>
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun	ClientPtr NextAvailableClient(ospriv)
821*4882a593Smuzhiyun		pointer ospriv;
822*4882a593Smuzhiyun</programlisting></blockquote>
823*4882a593SmuzhiyunThis routine returns NULL if a new client cannot be allocated (e.g. maximum
824*4882a593Smuzhiyunnumber of clients reached).  The ospriv argument will be stored into the OS
825*4882a593Smuzhiyunprivate field (pClient->osPrivate), to store OS private information about the
826*4882a593Smuzhiyunclient.  In the sample server, the osPrivate field contains the
827*4882a593Smuzhiyunnumber of the socket for this client. See also "New Client Connections."
828*4882a593SmuzhiyunNextAvailableClient() will call InsertFakeRequest(), so you must be
829*4882a593Smuzhiyunprepared for this.
830*4882a593Smuzhiyun</para>
831*4882a593Smuzhiyun<para>
832*4882a593SmuzhiyunIf there are outstanding input events,
833*4882a593Smuzhiyunyou should make sure that the two SetInputCheck() locations are unequal.
834*4882a593SmuzhiyunThe DIX dispatcher will call your implementation of ProcessInputEvents()
835*4882a593Smuzhiyununtil the SetInputCheck() locations are equal.
836*4882a593Smuzhiyun</para>
837*4882a593Smuzhiyun<para>
838*4882a593SmuzhiyunThe sample server contains an implementation of WaitForSomething().
839*4882a593SmuzhiyunThe
840*4882a593Smuzhiyunfollowing two routines indicate to WaitForSomething() what devices should
841*4882a593Smuzhiyunbe waited for.   fd is an OS dependent type; in the sample server
842*4882a593Smuzhiyunit is an open file descriptor.
843*4882a593Smuzhiyun<blockquote><programlisting>
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun	int AddEnabledDevice(fd)
846*4882a593Smuzhiyun		int fd;
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun	int RemoveEnabledDevice(fd)
849*4882a593Smuzhiyun		int fd;
850*4882a593Smuzhiyun</programlisting></blockquote>
851*4882a593SmuzhiyunThese two routines are
852*4882a593Smuzhiyunusually called by DDX from the initialize cases of the
853*4882a593SmuzhiyunInput Procedures that are stored in the DeviceRec (the
854*4882a593Smuzhiyunroutine passed to AddInputDevice()).
855*4882a593SmuzhiyunThe sample server implementation of AddEnabledDevice
856*4882a593Smuzhiyunand RemoveEnabledDevice are in Xserver/os/connection.c.
857*4882a593Smuzhiyun</para>
858*4882a593Smuzhiyun<section>
859*4882a593Smuzhiyun  <title>Timer Facilities</title>
860*4882a593Smuzhiyun<para>
861*4882a593SmuzhiyunSimilarly, the X server or an extension may need to wait for some timeout.
862*4882a593SmuzhiyunEarly X releases implemented this functionality using block and wakeup handlers,
863*4882a593Smuzhiyunbut this has been rewritten to use a general timer facilty, and the
864*4882a593Smuzhiyuninternal screen saver facilities reimplemented to use Timers.
865*4882a593SmuzhiyunThese functions are TimerInit, TimerForce, TimerSet, TimerCheck, TimerCancel,
866*4882a593Smuzhiyunand TimerFree, as defined in Xserver/include/os.h. A callback function will be called
867*4882a593Smuzhiyunwhen the timer fires, along with the current time, and a user provided argument.
868*4882a593Smuzhiyun<blockquote><programlisting>
869*4882a593Smuzhiyun	typedef	struct _OsTimerRec *OsTimerPtr;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun	typedef CARD32 (*OsTimerCallback)(
872*4882a593Smuzhiyun		OsTimerPtr /* timer */,
873*4882a593Smuzhiyun		CARD32 /* time */,
874*4882a593Smuzhiyun		pointer /* arg */);
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun	 OsTimerPtr TimerSet( OsTimerPtr /* timer */,
877*4882a593Smuzhiyun		int /* flags */,
878*4882a593Smuzhiyun		CARD32 /* millis */,
879*4882a593Smuzhiyun		OsTimerCallback /* func */,
880*4882a593Smuzhiyun		pointer /* arg */);
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun</programlisting></blockquote>
883*4882a593Smuzhiyun</para>
884*4882a593Smuzhiyun<para>
885*4882a593SmuzhiyunTimerSet returns a pointer to a timer structure and sets a timer to the specified time
886*4882a593Smuzhiyunwith the specified argument.  The flags can be TimerAbsolute and TimerForceOld.
887*4882a593SmuzhiyunThe TimerSetOld flag controls whether if the timer is reset and the timer is pending, the
888*4882a593Smuzhiyunwhether the callback function will get called.
889*4882a593SmuzhiyunThe TimerAbsolute flag sets the callback time to an absolute time in the future rather
890*4882a593Smuzhiyunthan a time relative to when TimerSet is called.
891*4882a593SmuzhiyunTimerFree should be called to free the memory allocated
892*4882a593Smuzhiyunfor the timer entry.
893*4882a593Smuzhiyun<blockquote><programlisting>
894*4882a593Smuzhiyun	void TimerInit(void)
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun	Bool TimerForce(OsTimerPtr /* pTimer */)
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun	void TimerCheck(void);
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun	void TimerCancel(OsTimerPtr /* pTimer */)
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun	void TimerFree(OsTimerPtr /* pTimer */)
903*4882a593Smuzhiyun</programlisting></blockquote>
904*4882a593Smuzhiyun</para>
905*4882a593Smuzhiyun<para>
906*4882a593SmuzhiyunTimerInit frees any existing timer entries. TimerForce forces a call to the timer's
907*4882a593Smuzhiyuncallback function and returns true if the timer entry existed, else it returns false and
908*4882a593Smuzhiyundoes not call the callback function. TimerCancel will cancel the specified timer.
909*4882a593SmuzhiyunTimerFree calls TimerCancel and frees the specified timer.
910*4882a593SmuzhiyunCalling TimerCheck will force the server to see if any timer callbacks should be called.
911*4882a593Smuzhiyun</para>
912*4882a593Smuzhiyun</section>
913*4882a593Smuzhiyun</section>
914*4882a593Smuzhiyun<section>
915*4882a593Smuzhiyun  <title>New Client Connections</title>
916*4882a593Smuzhiyun<para>
917*4882a593SmuzhiyunThe process whereby a new client-server connection starts up is
918*4882a593Smuzhiyunvery dependent upon what your byte stream mechanism.
919*4882a593SmuzhiyunThis section describes byte stream initiation using examples from the TCP/IP
920*4882a593Smuzhiyunimplementation on the sample server.
921*4882a593Smuzhiyun</para>
922*4882a593Smuzhiyun<para>
923*4882a593SmuzhiyunThe first thing that happens is a client initiates a connection with the server.
924*4882a593SmuzhiyunHow a client knows to do this depends upon your network facilities and the
925*4882a593SmuzhiyunXlib implementation.
926*4882a593SmuzhiyunIn a typical scenario, a user named Fred
927*4882a593Smuzhiyunon his X workstation is logged onto a Cray
928*4882a593Smuzhiyunsupercomputer running a command shell in an X window.  Fred can type shell
929*4882a593Smuzhiyuncommands and have the Cray respond as though the X server were a dumb terminal.
930*4882a593SmuzhiyunFred types in a command to run an X client application that was linked with Xlib.
931*4882a593SmuzhiyunXlib looks at the shell environment variable DISPLAY, which has the
932*4882a593Smuzhiyunvalue "fredsbittube:0.0."
933*4882a593SmuzhiyunThe host name of Fred's workstation is "fredsbittube," and the 0s are
934*4882a593Smuzhiyunfor multiple screens and multiple X server processes.
935*4882a593Smuzhiyun(Precisely what
936*4882a593Smuzhiyunhappens on your system depends upon how X and Xlib are implemented.)
937*4882a593Smuzhiyun</para>
938*4882a593Smuzhiyun<para>
939*4882a593SmuzhiyunThe client application calls a TCP routine on the
940*4882a593SmuzhiyunCray to open a TCP connection for X
941*4882a593Smuzhiyunto communicate with the network node "fredsbittube."
942*4882a593SmuzhiyunThe TCP software on the Cray does this by looking up the TCP
943*4882a593Smuzhiyunaddress of "fredsbittube" and sending an open request to TCP port 6000
944*4882a593Smuzhiyunon fredsbittube.
945*4882a593Smuzhiyun</para>
946*4882a593Smuzhiyun<para>
947*4882a593SmuzhiyunAll X servers on TCP listen for new clients on port 6000 by default;
948*4882a593Smuzhiyunthis is known as a "well-known port" in IP terminology.
949*4882a593Smuzhiyun</para>
950*4882a593Smuzhiyun<para>
951*4882a593SmuzhiyunThe server receives this request from its port 6000
952*4882a593Smuzhiyunand checks where it came from to see if it is on the server's list
953*4882a593Smuzhiyunof "trustworthy" hosts to talk to.
954*4882a593SmuzhiyunThen, it opens another port for communications with the client.
955*4882a593SmuzhiyunThis is the byte stream that all X communications will go over.
956*4882a593Smuzhiyun</para>
957*4882a593Smuzhiyun<para>
958*4882a593SmuzhiyunActually, it is a bit more complicated than that.
959*4882a593SmuzhiyunEach X server process running on the host machine is called a "display."
960*4882a593SmuzhiyunEach display can have more than one screen that it manages.
961*4882a593Smuzhiyun"corporatehydra:3.2" represents screen 2 on display 3 on
962*4882a593Smuzhiyunthe multi-screened network node corporatehydra.
963*4882a593SmuzhiyunThe open request would be sent on well-known port number 6003.
964*4882a593Smuzhiyun</para>
965*4882a593Smuzhiyun<para>
966*4882a593SmuzhiyunOnce the byte stream is set up, what goes on does not depend very much
967*4882a593Smuzhiyunupon whether or not it is TCP.
968*4882a593SmuzhiyunThe client sends an xConnClientPrefix struct (see Xproto.h) that has the
969*4882a593Smuzhiyunversion numbers for the version of Xlib it is running, some byte-ordering information,
970*4882a593Smuzhiyunand two character strings used for authorization.
971*4882a593SmuzhiyunIf the server does not like the authorization strings
972*4882a593Smuzhiyunor the version numbers do not match within the rules,
973*4882a593Smuzhiyunor if anything else is wrong, it sends a failure
974*4882a593Smuzhiyunresponse with a reason string.
975*4882a593Smuzhiyun</para>
976*4882a593Smuzhiyun<para>
977*4882a593SmuzhiyunIf the information never comes, or comes much too slowly, the connection
978*4882a593Smuzhiyunshould be broken off.  You must implement the connection timeout.  The
979*4882a593Smuzhiyunsample server implements this by keeping a timestamp for each still-connecting
980*4882a593Smuzhiyunclient and, each time just before it attempts to accept new connections, it
981*4882a593Smuzhiyuncloses any connection that are too old.
982*4882a593SmuzhiyunThe connection timeout can be set from the command line.
983*4882a593Smuzhiyun</para>
984*4882a593Smuzhiyun<para>
985*4882a593SmuzhiyunYou must implement whatever authorization schemes you want to support.
986*4882a593SmuzhiyunThe sample server on the distribution tape supports a simple authorization
987*4882a593Smuzhiyunscheme.  The only interface seen by DIX is:
988*4882a593Smuzhiyun<blockquote><programlisting>
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun	char *
991*4882a593Smuzhiyun	ClientAuthorized(client, proto_n, auth_proto, string_n, auth_string)
992*4882a593Smuzhiyun	    ClientPtr client;
993*4882a593Smuzhiyun	    unsigned int proto_n;
994*4882a593Smuzhiyun	    char *auth_proto;
995*4882a593Smuzhiyun	    unsigned int string_n;
996*4882a593Smuzhiyun	    char *auth_string;
997*4882a593Smuzhiyun</programlisting></blockquote>
998*4882a593SmuzhiyunDIX will only call this once per client, once it has read the full initial
999*4882a593Smuzhiyunconnection data from the client.  If the connection should be
1000*4882a593Smuzhiyunaccepted ClientAuthorized() should return NULL, and otherwise should
1001*4882a593Smuzhiyunreturn an error message string.
1002*4882a593Smuzhiyun</para>
1003*4882a593Smuzhiyun<para>
1004*4882a593SmuzhiyunAccepting new connections happens internally to WaitForSomething().
1005*4882a593SmuzhiyunWaitForSomething() must call the DIX routine NextAvailableClient()
1006*4882a593Smuzhiyunto create a client object.
1007*4882a593SmuzhiyunProcessing of the initial connection data will be handled by DIX.
1008*4882a593SmuzhiyunYour OS layer must be able to map from a client
1009*4882a593Smuzhiyunto whatever information your OS code needs to communicate
1010*4882a593Smuzhiyunon the given byte stream to the client.
1011*4882a593SmuzhiyunDIX uses this ClientPtr to refer to
1012*4882a593Smuzhiyunthe client from now on.   The sample server uses the osPrivate field in
1013*4882a593Smuzhiyunthe ClientPtr to store the file descriptor for the socket, the
1014*4882a593Smuzhiyuninput and output buffers, and authorization information.
1015*4882a593Smuzhiyun</para>
1016*4882a593Smuzhiyun<para>
1017*4882a593SmuzhiyunTo initialize the methods you choose to allow clients to connect to
1018*4882a593Smuzhiyunyour server, main() calls the routine
1019*4882a593Smuzhiyun<blockquote><programlisting>
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun	void CreateWellKnownSockets()
1022*4882a593Smuzhiyun</programlisting></blockquote>
1023*4882a593SmuzhiyunThis routine is called only once, and not called when the server
1024*4882a593Smuzhiyunis reset.  To recreate any sockets during server resets, the following
1025*4882a593Smuzhiyunroutine is called from the main loop:
1026*4882a593Smuzhiyun<blockquote><programlisting>
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun	void ResetWellKnownSockets()
1029*4882a593Smuzhiyun</programlisting></blockquote>
1030*4882a593SmuzhiyunSample implementations of both of these routines are found in
1031*4882a593SmuzhiyunXserver/os/connection.c.
1032*4882a593Smuzhiyun</para>
1033*4882a593Smuzhiyun<para>
1034*4882a593SmuzhiyunFor more details, see the section called "Connection Setup" in the X protocol specification.
1035*4882a593Smuzhiyun</para>
1036*4882a593Smuzhiyun</section>
1037*4882a593Smuzhiyun<section>
1038*4882a593Smuzhiyun  <title>Reading Data from Clients</title>
1039*4882a593Smuzhiyun<para>
1040*4882a593SmuzhiyunRequests from the client are read in as a byte stream by the OS layer.
1041*4882a593SmuzhiyunThey may be in the form of several blocks of bytes delivered in sequence; requests may
1042*4882a593Smuzhiyunbe broken up over block boundaries or there may be many requests per block.
1043*4882a593SmuzhiyunEach request carries with it length information.
1044*4882a593SmuzhiyunIt is the responsibility of the following routine to break it up into request blocks.
1045*4882a593Smuzhiyun<blockquote><programlisting>
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun	int ReadRequestFromClient(who)
1048*4882a593Smuzhiyun		ClientPtr who;
1049*4882a593Smuzhiyun</programlisting></blockquote>
1050*4882a593Smuzhiyun</para>
1051*4882a593Smuzhiyun<para>
1052*4882a593SmuzhiyunYou must write
1053*4882a593Smuzhiyunthe routine ReadRequestFromClient() to get one request from the byte stream
1054*4882a593Smuzhiyunbelonging to client "who."
1055*4882a593SmuzhiyunYou must swap the third and fourth bytes (the second 16-bit word) according to the
1056*4882a593Smuzhiyunbyte-swap rules of
1057*4882a593Smuzhiyunthe protocol to determine the length of the
1058*4882a593Smuzhiyunrequest.
1059*4882a593SmuzhiyunThis length is measured in 32-bit words, not in bytes.  Therefore, the
1060*4882a593Smuzhiyuntheoretical maximum request is 256K.
1061*4882a593Smuzhiyun(However, the maximum length allowed is dependent upon the server's input
1062*4882a593Smuzhiyunbuffer.  This size is sent to the client upon connection.  The maximum
1063*4882a593Smuzhiyunsize is the constant MAX_REQUEST_SIZE in Xserver/include/os.h)
1064*4882a593SmuzhiyunThe rest of the request you return is
1065*4882a593Smuzhiyunassumed NOT to be correctly swapped for internal
1066*4882a593Smuzhiyunuse, because that is the responsibility of DIX.
1067*4882a593Smuzhiyun</para>
1068*4882a593Smuzhiyun<para>
1069*4882a593SmuzhiyunThe 'who' argument is the ClientPtr returned from WaitForSomething.
1070*4882a593SmuzhiyunThe return value indicating status should be set to the (positive) byte count if the read is successful,
1071*4882a593Smuzhiyun0 if the read was blocked, or a negative error code if an error happened.
1072*4882a593Smuzhiyun</para>
1073*4882a593Smuzhiyun<para>
1074*4882a593SmuzhiyunYou must then store a pointer to
1075*4882a593Smuzhiyunthe bytes of the request in the client request buffer field;
1076*4882a593Smuzhiyunwho->requestBuffer.  This can simply be a pointer into your buffer;
1077*4882a593SmuzhiyunDIX may modify it in place but will not otherwise cause damage.
1078*4882a593SmuzhiyunOf course, the request must be contiguous; you must
1079*4882a593Smuzhiyunshuffle it around in your buffers if not.
1080*4882a593Smuzhiyun</para>
1081*4882a593Smuzhiyun<para>
1082*4882a593SmuzhiyunThe sample server implementation is in Xserver/os/io.c.
1083*4882a593Smuzhiyun</para>
1084*4882a593Smuzhiyun<section><title>Inserting Data for Clients</title>
1085*4882a593Smuzhiyun<para>
1086*4882a593SmuzhiyunDIX can insert data into the client stream, and can cause a "replay" of
1087*4882a593Smuzhiyunthe current request.
1088*4882a593Smuzhiyun<blockquote><programlisting>
1089*4882a593Smuzhiyun
1090*4882a593Smuzhiyun	Bool InsertFakeRequest(client, data, count)
1091*4882a593Smuzhiyun	    ClientPtr client;
1092*4882a593Smuzhiyun	    char *data;
1093*4882a593Smuzhiyun	    int count;
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun	int ResetCurrentRequest(client)
1096*4882a593Smuzhiyun	    ClientPtr client;
1097*4882a593Smuzhiyun</programlisting></blockquote>
1098*4882a593Smuzhiyun</para>
1099*4882a593Smuzhiyun<para>
1100*4882a593SmuzhiyunInsertFakeRequest() must insert the specified number of bytes of data
1101*4882a593Smuzhiyuninto the head of the input buffer for the client.  This may be a
1102*4882a593Smuzhiyuncomplete request, or it might be a partial request.  For example,
1103*4882a593SmuzhiyunNextAvailableCient() will insert a partial request in order to read
1104*4882a593Smuzhiyunthe initial connection data sent by the client.  The routine returns FALSE
1105*4882a593Smuzhiyunif memory could not be allocated.  ResetCurrentRequest()
1106*4882a593Smuzhiyunshould "back up" the input buffer so that the currently executing request
1107*4882a593Smuzhiyunwill be reexecuted.  DIX may have altered some values (e.g. the overall
1108*4882a593Smuzhiyunrequest length), so you must recheck to see if you still have a complete
1109*4882a593Smuzhiyunrequest.  ResetCurrentRequest() should always cause a yield (isItTimeToYield).
1110*4882a593Smuzhiyun</para>
1111*4882a593Smuzhiyun</section>
1112*4882a593Smuzhiyun</section>
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun<section>
1115*4882a593Smuzhiyun  <title>Sending Events, Errors And Replies To Clients</title>
1116*4882a593Smuzhiyun<para>
1117*4882a593Smuzhiyun<blockquote><programlisting>
1118*4882a593Smuzhiyun
1119*4882a593Smuzhiyun	int WriteToClient(who, n, buf)
1120*4882a593Smuzhiyun		ClientPtr who;
1121*4882a593Smuzhiyun		int n;
1122*4882a593Smuzhiyun		char *buf;
1123*4882a593Smuzhiyun</programlisting></blockquote>
1124*4882a593SmuzhiyunWriteToClient should write n bytes starting at buf to the
1125*4882a593SmuzhiyunClientPtr "who".
1126*4882a593SmuzhiyunIt returns the number of bytes written, but for simplicity,
1127*4882a593Smuzhiyunthe number returned must be either the same value as the number
1128*4882a593Smuzhiyunrequested, or -1, signaling an error.
1129*4882a593SmuzhiyunThe sample server implementation is in Xserver/os/io.c.
1130*4882a593Smuzhiyun</para>
1131*4882a593Smuzhiyun<para>
1132*4882a593Smuzhiyun<blockquote><programlisting>
1133*4882a593Smuzhiyun	void SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
1134*4882a593Smuzhiyun	    ClientPtr client;
1135*4882a593Smuzhiyun	    unsigned int majorCode;
1136*4882a593Smuzhiyun	    unsigned int minorCode;
1137*4882a593Smuzhiyun	    XID resId;
1138*4882a593Smuzhiyun	    int errorCode;
1139*4882a593Smuzhiyun</programlisting></blockquote>
1140*4882a593SmuzhiyunSendErrorToClient can be used to send errors back to clients,
1141*4882a593Smuzhiyunalthough in most cases your request function should simply return
1142*4882a593Smuzhiyunthe error code, having set client->errorValue to the appropriate
1143*4882a593Smuzhiyunerror value to return to the client, and DIX will call this
1144*4882a593Smuzhiyunfunction with the correct opcodes for you.
1145*4882a593Smuzhiyun</para>
1146*4882a593Smuzhiyun<para>
1147*4882a593Smuzhiyun<blockquote><programlisting>
1148*4882a593Smuzhiyun
1149*4882a593Smuzhiyun	void FlushAllOutput()
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun	void FlushIfCriticalOutputPending()
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun	void SetCriticalOutputPending()
1154*4882a593Smuzhiyun</programlisting></blockquote>
1155*4882a593SmuzhiyunThese three routines may be implemented to support buffered or delayed
1156*4882a593Smuzhiyunwrites to clients, but at the very least, the stubs must exist.
1157*4882a593SmuzhiyunFlushAllOutput() unconditionally flushes all output to clients;
1158*4882a593SmuzhiyunFlushIfCriticalOutputPending() flushes output only if
1159*4882a593SmuzhiyunSetCriticalOutputPending() has be called since the last time output
1160*4882a593Smuzhiyunwas flushed.
1161*4882a593SmuzhiyunThe sample server implementation is in Xserver/os/io.c and
1162*4882a593Smuzhiyunactually ignores requests to flush output on a per-client basis
1163*4882a593Smuzhiyunif it knows that there
1164*4882a593Smuzhiyunare requests in that client's input queue.
1165*4882a593Smuzhiyun</para>
1166*4882a593Smuzhiyun</section>
1167*4882a593Smuzhiyun<section>
1168*4882a593Smuzhiyun  <title>Font Support</title>
1169*4882a593Smuzhiyun<para>
1170*4882a593SmuzhiyunIn the sample server, fonts are encoded in disk files or fetched from the
1171*4882a593Smuzhiyunfont server.   The two fonts required by the server, <quote>fixed</quote>
1172*4882a593Smuzhiyunand <quote>cursor</quote> are commonly compiled into the font library.
1173*4882a593SmuzhiyunFor disk fonts, there is one file per font, with a file name like
1174*4882a593Smuzhiyun"fixed.pcf".  Font server fonts are read over the network using the
1175*4882a593SmuzhiyunX Font Server Protocol.  The disk directories containing disk fonts and
1176*4882a593Smuzhiyunthe names of the font servers are listed together in the current "font path."
1177*4882a593Smuzhiyun</para>
1178*4882a593Smuzhiyun<para>
1179*4882a593SmuzhiyunIn principle, you can put all your fonts in ROM or in RAM in your server.
1180*4882a593SmuzhiyunYou can put them all in one library file on disk.
1181*4882a593SmuzhiyunYou could generate them on the fly from stroke descriptions.  By placing the
1182*4882a593Smuzhiyunappropriate code in the Font Library, you will automatically export fonts in
1183*4882a593Smuzhiyunthat format both through the X server and the Font server.
1184*4882a593Smuzhiyun</para>
1185*4882a593Smuzhiyun<para>
1186*4882a593SmuzhiyunThe code for processing fonts in different formats, as well as handling the
1187*4882a593Smuzhiyunmetadata files for them on disk (such as <filename>fonts.dir</filename>) is
1188*4882a593Smuzhiyunlocated in the libXfont library, which is provided as a separately compiled
1189*4882a593Smuzhiyunmodule.  These routines are
1190*4882a593Smuzhiyunshared between the X server and the Font server, so instead of this document
1191*4882a593Smuzhiyunspecifying what you must implement, simply refer to the font
1192*4882a593Smuzhiyunlibrary interface specification for the details.  All of the interface code to the Font
1193*4882a593Smuzhiyunlibrary is contained in dix/dixfonts.c
1194*4882a593Smuzhiyun</para>
1195*4882a593Smuzhiyun</section>
1196*4882a593Smuzhiyun<section>
1197*4882a593Smuzhiyun  <title>Memory Management</title>
1198*4882a593Smuzhiyun<para>
1199*4882a593SmuzhiyunMemory management is based on functions in the C runtime library, malloc(),
1200*4882a593Smuzhiyunrealloc(), and free(), and you should simply call the C library functions
1201*4882a593Smuzhiyundirectly.  Consult a C runtime library reference manual for more details.
1202*4882a593Smuzhiyun</para>
1203*4882a593Smuzhiyun<para>
1204*4882a593SmuzhiyunTreat memory allocation carefully in your implementation.  Memory
1205*4882a593Smuzhiyunleaks can be very hard to find and are frustrating to a user.  An X
1206*4882a593Smuzhiyunserver could be running for days or weeks without being reset, just
1207*4882a593Smuzhiyunlike a regular terminal.  If you leak a few dozen k per day, that will
1208*4882a593Smuzhiyunadd up and will cause problems for users that leave their workstations
1209*4882a593Smuzhiyunon.
1210*4882a593Smuzhiyun</para>
1211*4882a593Smuzhiyun</section>
1212*4882a593Smuzhiyun<section>
1213*4882a593Smuzhiyun  <title>Client Scheduling</title>
1214*4882a593Smuzhiyun<para>
1215*4882a593SmuzhiyunThe X server
1216*4882a593Smuzhiyunhas the ability to schedule clients much like an operating system would,
1217*4882a593Smuzhiyunsuspending and restarting them without regard for the state of their input
1218*4882a593Smuzhiyunbuffers.  This functionality allows the X server to suspend one client and
1219*4882a593Smuzhiyuncontinue processing requests from other clients while waiting for a
1220*4882a593Smuzhiyunlong-term network activity (like loading a font) before continuing with the
1221*4882a593Smuzhiyunfirst client.
1222*4882a593Smuzhiyun<blockquote><programlisting>
1223*4882a593Smuzhiyun	Bool isItTimeToYield;
1224*4882a593Smuzhiyun</programlisting></blockquote>
1225*4882a593SmuzhiyunisItTimeToYield is a global variable you can set
1226*4882a593Smuzhiyunif you want to tell
1227*4882a593SmuzhiyunDIX to end the client's "time slice" and start paying attention to the next client.
1228*4882a593SmuzhiyunAfter the current request is finished, DIX will move to the next client.
1229*4882a593Smuzhiyun</para>
1230*4882a593Smuzhiyun<para>
1231*4882a593SmuzhiyunIn the sample
1232*4882a593Smuzhiyunserver, ReadRequestFromClient() sets isItTimeToYield after
1233*4882a593Smuzhiyun10 requests packets in a row are read from the same client.
1234*4882a593Smuzhiyun</para>
1235*4882a593Smuzhiyun<para>
1236*4882a593SmuzhiyunThis scheduling algorithm can have a serious effect upon performance when two
1237*4882a593Smuzhiyunclients are drawing into their windows simultaneously.
1238*4882a593SmuzhiyunIf it allows one client to run until its request
1239*4882a593Smuzhiyunqueue is empty by ignoring isItTimeToYield, the client's queue may
1240*4882a593Smuzhiyunin fact never empty and other clients will be blocked out.
1241*4882a593SmuzhiyunOn the other hand, if it switchs between different clients too quickly,
1242*4882a593Smuzhiyunperformance may suffer due to too much switching between contexts.
1243*4882a593SmuzhiyunFor example, if a graphics processor needs to be set up with drawing modes
1244*4882a593Smuzhiyunbefore drawing, and two different clients are drawing with
1245*4882a593Smuzhiyundifferent modes into two different windows, you may
1246*4882a593Smuzhiyunswitch your graphics processor modes so often that performance is impacted.
1247*4882a593Smuzhiyun</para>
1248*4882a593Smuzhiyun<para>
1249*4882a593SmuzhiyunSee the Strategies document for
1250*4882a593Smuzhiyunheuristics on setting isItTimeToYield.
1251*4882a593Smuzhiyun</para>
1252*4882a593Smuzhiyun<para>
1253*4882a593SmuzhiyunThe following functions provide the ability to suspend request
1254*4882a593Smuzhiyunprocessing on a particular client, resuming it at some later time:
1255*4882a593Smuzhiyun<blockquote><programlisting>
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun	int IgnoreClient (who)
1258*4882a593Smuzhiyun		ClientPtr who;
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun	int AttendClient (who)
1261*4882a593Smuzhiyun		ClientPtr who;
1262*4882a593Smuzhiyun</programlisting></blockquote>
1263*4882a593SmuzhiyunIgnore client is responsible for pretending that the given client doesn't
1264*4882a593Smuzhiyunexist.  WaitForSomething should not return this client as ready for reading
1265*4882a593Smuzhiyunand should not return if only this client is ready.  AttendClient undoes
1266*4882a593Smuzhiyunwhatever IgnoreClient did, setting it up for input again.
1267*4882a593Smuzhiyun</para>
1268*4882a593Smuzhiyun<para>
1269*4882a593SmuzhiyunThree functions support "process control" for X clients:
1270*4882a593Smuzhiyun<blockquote><programlisting>
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun	Bool ClientSleep (client, function, closure)
1273*4882a593Smuzhiyun		ClientPtr	client;
1274*4882a593Smuzhiyun		Bool		(*function)();
1275*4882a593Smuzhiyun		pointer		closure;
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun</programlisting></blockquote>
1278*4882a593SmuzhiyunThis suspends the current client (the calling routine is responsible for
1279*4882a593Smuzhiyunmaking its way back to Dispatch()).  No more X requests will be processed
1280*4882a593Smuzhiyunfor this client until ClientWakeup is called.
1281*4882a593Smuzhiyun<blockquote><programlisting>
1282*4882a593Smuzhiyun
1283*4882a593Smuzhiyun	Bool ClientSignal (client)
1284*4882a593Smuzhiyun		ClientPtr	client;
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun</programlisting></blockquote>
1287*4882a593SmuzhiyunThis function causes a call to the (*function) parameter passed to
1288*4882a593SmuzhiyunClientSleep to be queued on the work queue.  This does not automatically
1289*4882a593Smuzhiyun"wakeup" the client, but the function called is free to do so by calling:
1290*4882a593Smuzhiyun<blockquote><programlisting>
1291*4882a593Smuzhiyun
1292*4882a593Smuzhiyun	ClientWakeup (client)
1293*4882a593Smuzhiyun		ClientPtr	client;
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun</programlisting></blockquote>
1296*4882a593SmuzhiyunThis re-enables X request processing for the specified client.
1297*4882a593Smuzhiyun</para>
1298*4882a593Smuzhiyun</section>
1299*4882a593Smuzhiyun<section>
1300*4882a593Smuzhiyun  <title>Other OS Functions</title>
1301*4882a593Smuzhiyun<para>
1302*4882a593Smuzhiyun<blockquote><programlisting>
1303*4882a593Smuzhiyun	void
1304*4882a593Smuzhiyun	ErrorF(char *f, ...)
1305*4882a593Smuzhiyun
1306*4882a593Smuzhiyun	void
1307*4882a593Smuzhiyun	FatalError(char *f, ...)
1308*4882a593Smuzhiyun</programlisting></blockquote>
1309*4882a593SmuzhiyunYou should write these three routines to provide for diagnostic output
1310*4882a593Smuzhiyunfrom the dix and ddx layers, although implementing them to produce no
1311*4882a593Smuzhiyunoutput will not affect the correctness of your server.  ErrorF() and
1312*4882a593SmuzhiyunFatalError() take a printf() type of format specification in the first
1313*4882a593Smuzhiyunargument and an implementation-dependent number of arguments following
1314*4882a593Smuzhiyunthat.  Normally, the formats passed to ErrorF() and FatalError()
1315*4882a593Smuzhiyunshould be terminated with a newline.
1316*4882a593Smuzhiyun</para>
1317*4882a593Smuzhiyun<para>
1318*4882a593SmuzhiyunAfter printing the message arguments, FatalError() must be implemented
1319*4882a593Smuzhiyunsuch that the server will call AbortDDX() to give the ddx layer
1320*4882a593Smuzhiyuna chance to reset the hardware, and then
1321*4882a593Smuzhiyunterminate the server; it must not return.
1322*4882a593Smuzhiyun</para>
1323*4882a593Smuzhiyun<para>
1324*4882a593SmuzhiyunThe sample server implementation for these routines
1325*4882a593Smuzhiyunis in Xserver/os/log.c along with other routines for logging messages.
1326*4882a593Smuzhiyun</para>
1327*4882a593Smuzhiyun</section>
1328*4882a593Smuzhiyun</section>
1329*4882a593Smuzhiyun
1330*4882a593Smuzhiyun<section>
1331*4882a593Smuzhiyun  <title>DDX Layer</title>
1332*4882a593Smuzhiyun<para>
1333*4882a593SmuzhiyunThis section describes the
1334*4882a593Smuzhiyuninterface between DIX and DDX.
1335*4882a593SmuzhiyunWhile there may be an OS-dependent driver interface between DDX
1336*4882a593Smuzhiyunand the physical device, that interface is left to the DDX
1337*4882a593Smuzhiyunimplementor and is not specified here.
1338*4882a593Smuzhiyun</para>
1339*4882a593Smuzhiyun<para>
1340*4882a593SmuzhiyunThe DDX layer does most of its work through procedures that are
1341*4882a593Smuzhiyunpointed to by different structs.
1342*4882a593SmuzhiyunAs previously described, the behavior of these resources is largely determined by
1343*4882a593Smuzhiyunthese procedure pointers.
1344*4882a593SmuzhiyunMost of these routines are for graphic display on the screen or support functions thereof.
1345*4882a593SmuzhiyunThe rest are for user input from input devices.
1346*4882a593Smuzhiyun</para>
1347*4882a593Smuzhiyun<section>
1348*4882a593Smuzhiyun  <title>Input</title>
1349*4882a593Smuzhiyun<para>
1350*4882a593SmuzhiyunIn this document "input" refers to input from the user,
1351*4882a593Smuzhiyunsuch as mouse, keyboard, and
1352*4882a593Smuzhiyunbar code readers.
1353*4882a593SmuzhiyunX input devices are of several types: keyboard, pointing device, and
1354*4882a593Smuzhiyunmany others.  The core server has support for extension devices as
1355*4882a593Smuzhiyundescribed by the X Input Extension document; the interfaces used by
1356*4882a593Smuzhiyunthat extension are described elsewhere.  The core devices are actually
1357*4882a593Smuzhiyunimplemented as two collections of devices, the mouse is a ButtonDevice,
1358*4882a593Smuzhiyuna ValuatorDevice and a PtrFeedbackDevice while the keyboard is a KeyDevice,
1359*4882a593Smuzhiyuna FocusDevice and a KbdFeedbackDevice.  Each part implements a portion of
1360*4882a593Smuzhiyunthe functionality of the device.  This abstraction is hidden from view for
1361*4882a593Smuzhiyuncore devices by DIX.
1362*4882a593Smuzhiyun</para>
1363*4882a593Smuzhiyun<para>
1364*4882a593SmuzhiyunYou, the DDX programmer, are
1365*4882a593Smuzhiyunresponsible for some of the routines in this section.
1366*4882a593SmuzhiyunOthers are DIX routines that you should call to do the things you need to do in these DDX routines.
1367*4882a593SmuzhiyunPay attention to which is which.
1368*4882a593Smuzhiyun</para>
1369*4882a593Smuzhiyun<section>
1370*4882a593Smuzhiyun  <title>Input Device Data Structures</title>
1371*4882a593Smuzhiyun<para>
1372*4882a593SmuzhiyunDIX keeps a global directory of devices in a central data structure
1373*4882a593Smuzhiyuncalled InputInfo.
1374*4882a593SmuzhiyunFor each device there is a device structure called a DeviceRec.
1375*4882a593SmuzhiyunDIX can locate any DeviceRec through InputInfo.
1376*4882a593SmuzhiyunIn addition, it has a special pointer to identify the main pointing device
1377*4882a593Smuzhiyunand a special pointer to identify the main keyboard.
1378*4882a593Smuzhiyun</para>
1379*4882a593Smuzhiyun<para>
1380*4882a593SmuzhiyunThe DeviceRec (Xserver/include/input.h) is a device-independent
1381*4882a593Smuzhiyunstructure that contains the state of an input device.
1382*4882a593SmuzhiyunA DevicePtr is simply a pointer to a DeviceRec.
1383*4882a593Smuzhiyun</para>
1384*4882a593Smuzhiyun<para>
1385*4882a593SmuzhiyunAn xEvent describes an event the server reports to a client.
1386*4882a593SmuzhiyunDefined in Xproto.h, it is a huge struct of union of structs that have fields for
1387*4882a593Smuzhiyunall kinds of events.
1388*4882a593SmuzhiyunAll of the variants overlap, so that the struct is actually very small in memory.
1389*4882a593Smuzhiyun</para>
1390*4882a593Smuzhiyun</section>
1391*4882a593Smuzhiyun<section>
1392*4882a593Smuzhiyun  <title>Processing Events</title>
1393*4882a593Smuzhiyun<para>
1394*4882a593SmuzhiyunThe main DDX input interface is the following routine:
1395*4882a593Smuzhiyun<blockquote><programlisting>
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun	void ProcessInputEvents()
1398*4882a593Smuzhiyun</programlisting></blockquote>
1399*4882a593SmuzhiyunYou must write this routine to deliver input events from the user.
1400*4882a593SmuzhiyunDIX calls it when input is pending (see next section), and possibly
1401*4882a593Smuzhiyuneven when it is not.
1402*4882a593SmuzhiyunYou should write it to get events from each device and deliver
1403*4882a593Smuzhiyunthe events to DIX.
1404*4882a593SmuzhiyunTo deliver the events to DIX, DDX should call the following
1405*4882a593Smuzhiyunroutine:
1406*4882a593Smuzhiyun<blockquote><programlisting>
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun	void DevicePtr->processInputProc(pEvent, device, count)
1409*4882a593Smuzhiyun		    xEventPtr events;
1410*4882a593Smuzhiyun		    DeviceIntPtr device;
1411*4882a593Smuzhiyun		    int count;
1412*4882a593Smuzhiyun</programlisting></blockquote>
1413*4882a593SmuzhiyunThis is the "input proc" for the device, a DIX procedure.
1414*4882a593SmuzhiyunDIX will fill in this procedure pointer to one of its own routines by
1415*4882a593Smuzhiyunthe time ProcessInputEvents() is called the first time.
1416*4882a593SmuzhiyunCall this input proc routine as many times as needed to
1417*4882a593Smuzhiyundeliver as many events as should be delivered.
1418*4882a593SmuzhiyunDIX will buffer them up and send them out as needed.  Count is set
1419*4882a593Smuzhiyunto the number of event records which make up one atomic device event and
1420*4882a593Smuzhiyunis always 1 for the core devices (see the X Input Extension for descriptions
1421*4882a593Smuzhiyunof devices which may use count &#x3E; 1).
1422*4882a593Smuzhiyun</para>
1423*4882a593Smuzhiyun<para>
1424*4882a593SmuzhiyunFor example, your ProcessInputEvents() routine might check the mouse and the
1425*4882a593Smuzhiyunkeyboard.
1426*4882a593SmuzhiyunIf the keyboard had several keystrokes queued up, it could just call
1427*4882a593Smuzhiyunthe keyboard's processInputProc as many times as needed to flush its internal queue.
1428*4882a593Smuzhiyun</para>
1429*4882a593Smuzhiyun<para>
1430*4882a593Smuzhiyunevent is an xEvent struct you pass to the input proc.
1431*4882a593SmuzhiyunWhen the input proc returns, it is finished with the event rec, and you can fill
1432*4882a593Smuzhiyunin new values and call the input proc again with it.
1433*4882a593Smuzhiyun</para>
1434*4882a593Smuzhiyun<para>
1435*4882a593SmuzhiyunYou should deliver the events in the same order that they were generated.
1436*4882a593Smuzhiyun</para>
1437*4882a593Smuzhiyun<para>
1438*4882a593SmuzhiyunFor keyboard and pointing devices the xEvent variant should be keyButtonPointer.
1439*4882a593SmuzhiyunFill in the following fields in the xEvent record:
1440*4882a593Smuzhiyun<itemizedlist>
1441*4882a593Smuzhiyun
1442*4882a593Smuzhiyun<listitem><para>type - is one of the following: KeyPress, KeyRelease, ButtonPress,
1443*4882a593Smuzhiyun					ButtonRelease, or MotionNotify</para></listitem>
1444*4882a593Smuzhiyun<listitem><para>detail - for KeyPress or KeyRelease fields, this should be the
1445*4882a593Smuzhiyun					key number (not the ASCII code); otherwise unused</para></listitem>
1446*4882a593Smuzhiyun<listitem><para>time - is the time that the event happened (32-bits, in milliseconds, arbitrary origin)</para></listitem>
1447*4882a593Smuzhiyun<listitem><para>rootX - is the x coordinate of cursor</para></listitem>
1448*4882a593Smuzhiyun<listitem><para>rootY - is the y coordinate of cursor</para></listitem>
1449*4882a593Smuzhiyun
1450*4882a593Smuzhiyun</itemizedlist>
1451*4882a593SmuzhiyunThe rest of the fields are filled in by DIX.
1452*4882a593Smuzhiyun</para>
1453*4882a593Smuzhiyun<para>
1454*4882a593SmuzhiyunThe time stamp is maintained by your code in the DDX layer, and it is your responsibility to
1455*4882a593Smuzhiyunstamp all events correctly.
1456*4882a593Smuzhiyun</para>
1457*4882a593Smuzhiyun<para>
1458*4882a593SmuzhiyunThe x and y coordinates of the pointing device and the time must be filled in for all event types
1459*4882a593Smuzhiyunincluding keyboard events.
1460*4882a593Smuzhiyun</para>
1461*4882a593Smuzhiyun<para>
1462*4882a593SmuzhiyunThe pointing device must report all button press and release events.
1463*4882a593SmuzhiyunIn addition, it should report a MotionNotify event every time it gets called
1464*4882a593Smuzhiyunif the pointing device has moved since the last notify.
1465*4882a593SmuzhiyunIntermediate pointing device moves are stored in a special GetMotionEvents buffer,
1466*4882a593Smuzhiyunbecause most client programs are not interested in them.
1467*4882a593Smuzhiyun</para>
1468*4882a593Smuzhiyun<para>
1469*4882a593SmuzhiyunThere are quite a collection of sample implementations of this routine,
1470*4882a593Smuzhiyunone for each supported device.
1471*4882a593Smuzhiyun</para>
1472*4882a593Smuzhiyun</section>
1473*4882a593Smuzhiyun<section>
1474*4882a593Smuzhiyun<title>Telling DIX When Input is Pending</title>
1475*4882a593Smuzhiyun<para>
1476*4882a593SmuzhiyunIn the server's dispatch loop, DIX checks to see
1477*4882a593Smuzhiyunif there is any device input pending whenever WaitForSomething() returns.
1478*4882a593SmuzhiyunIf the check says that input is pending, DIX calls the
1479*4882a593SmuzhiyunDDX routine ProcessInputEvents().
1480*4882a593Smuzhiyun</para>
1481*4882a593Smuzhiyun<para>
1482*4882a593SmuzhiyunThis check for pending input must be very quick; a procedure call
1483*4882a593Smuzhiyunis too slow.
1484*4882a593SmuzhiyunThe code that does the check is a hardwired IF
1485*4882a593Smuzhiyunstatement in DIX code that simply compares the values
1486*4882a593Smuzhiyunpointed to by two pointers.
1487*4882a593SmuzhiyunIf the values are different, then it assumes that input is pending and
1488*4882a593SmuzhiyunProcessInputEvents() is called by DIX.
1489*4882a593Smuzhiyun</para>
1490*4882a593Smuzhiyun<para>
1491*4882a593SmuzhiyunYou must pass pointers to DIX to tell it what values to compare.
1492*4882a593SmuzhiyunThe following procedure
1493*4882a593Smuzhiyunis used to set these pointers:
1494*4882a593Smuzhiyun<blockquote><programlisting>
1495*4882a593Smuzhiyun
1496*4882a593Smuzhiyun	void SetInputCheck(p1, p2)
1497*4882a593Smuzhiyun		long *p1, *p2;
1498*4882a593Smuzhiyun</programlisting></blockquote>
1499*4882a593SmuzhiyunYou should call it sometime during initialization to indicate to DIX the
1500*4882a593Smuzhiyuncorrect locations to check.
1501*4882a593SmuzhiyunYou should
1502*4882a593Smuzhiyunpay special attention to the size of what they actually point to,
1503*4882a593Smuzhiyunbecause the locations are assumed to be longs.
1504*4882a593Smuzhiyun</para>
1505*4882a593Smuzhiyun<para>
1506*4882a593SmuzhiyunThese two pointers are initialized by DIX
1507*4882a593Smuzhiyunto point to arbitrary values that
1508*4882a593Smuzhiyunare different.
1509*4882a593SmuzhiyunIn other words, if you forget to call this routine during initialization,
1510*4882a593Smuzhiyunthe worst thing that will happen is that
1511*4882a593SmuzhiyunProcessInputEvents will be called when
1512*4882a593Smuzhiyunthere are no events to process.
1513*4882a593Smuzhiyun</para>
1514*4882a593Smuzhiyun<para>
1515*4882a593Smuzhiyunp1 and p2 might
1516*4882a593Smuzhiyunpoint at the head and tail of some shared
1517*4882a593Smuzhiyunmemory queue.
1518*4882a593SmuzhiyunAnother use would be to have one point at a constant 0, with the
1519*4882a593Smuzhiyunother pointing at some mask containing 1s
1520*4882a593Smuzhiyunfor each input device that has
1521*4882a593Smuzhiyunsomething pending.
1522*4882a593Smuzhiyun</para>
1523*4882a593Smuzhiyun<para>
1524*4882a593SmuzhiyunThe DDX layer of the sample server calls SetInputCheck()
1525*4882a593Smuzhiyunonce when the
1526*4882a593Smuzhiyunserver's private internal queue is initialized.
1527*4882a593SmuzhiyunIt passes pointers to the queue's head and tail.  See Xserver/mi/mieq.c.
1528*4882a593Smuzhiyun</para>
1529*4882a593Smuzhiyun<para>
1530*4882a593Smuzhiyun<blockquote><programlisting>
1531*4882a593Smuzhiyun	int TimeSinceLastInputEvent()
1532*4882a593Smuzhiyun</programlisting></blockquote>
1533*4882a593SmuzhiyunDDX must time stamp all hardware input
1534*4882a593Smuzhiyunevents.  But DIX sometimes needs to know the
1535*4882a593Smuzhiyuntime and the OS layer needs to know the time since the last hardware
1536*4882a593Smuzhiyuninput event in
1537*4882a593Smuzhiyunorder for the screen saver to work.   TimeSinceLastInputEvent() returns
1538*4882a593Smuzhiyunthe this time in milliseconds.
1539*4882a593Smuzhiyun</para>
1540*4882a593Smuzhiyun</section>
1541*4882a593Smuzhiyun<section>
1542*4882a593Smuzhiyun  <title>Controlling Input Devices</title>
1543*4882a593Smuzhiyun<para>
1544*4882a593SmuzhiyunYou must write four routines to do various device-specific
1545*4882a593Smuzhiyunthings with the keyboard and pointing device.
1546*4882a593SmuzhiyunThey can have any name you wish because
1547*4882a593Smuzhiyunyou pass the procedure pointers to DIX routines.
1548*4882a593Smuzhiyun</para>
1549*4882a593Smuzhiyun<para>
1550*4882a593Smuzhiyun<blockquote><programlisting>
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun	int pInternalDevice->valuator->GetMotionProc(pdevice, coords, start, stop, pScreen)
1553*4882a593Smuzhiyun		DeviceIntPtr pdevice;
1554*4882a593Smuzhiyun		xTimecoord * coords;
1555*4882a593Smuzhiyun		unsigned long start;
1556*4882a593Smuzhiyun		unsigned long stop;
1557*4882a593Smuzhiyun		ScreenPtr pScreen;
1558*4882a593Smuzhiyun</programlisting></blockquote>
1559*4882a593SmuzhiyunYou write this DDX routine to fill in coords with all the motion
1560*4882a593Smuzhiyunevents that have times (32-bit count of milliseconds) between time
1561*4882a593Smuzhiyunstart and time stop.  It should return the number of motion events
1562*4882a593Smuzhiyunreturned.  If there is no motion events support, this routine should
1563*4882a593Smuzhiyundo nothing and return zero.  The maximum number of coords to return is
1564*4882a593Smuzhiyunset in InitPointerDeviceStruct(), below.
1565*4882a593Smuzhiyun</para>
1566*4882a593Smuzhiyun<para>
1567*4882a593SmuzhiyunWhen the user drags the pointing device, the cursor position
1568*4882a593Smuzhiyuntheoretically sweeps through an infinite number of points.  Normally,
1569*4882a593Smuzhiyuna client that is concerned with points other than the starting and
1570*4882a593Smuzhiyunending points will receive a pointer-move event only as often as the
1571*4882a593Smuzhiyunserver generates them. (Move events do not queue up; each new one
1572*4882a593Smuzhiyunreplaces the last in the queue.)  A server, if desired, can implement
1573*4882a593Smuzhiyuna scheme to save these intermediate events in a motion buffer.  A
1574*4882a593Smuzhiyunclient application, like a paint program, may then request that these
1575*4882a593Smuzhiyunevents be delivered to it through the GetMotionProc routine.
1576*4882a593Smuzhiyun</para>
1577*4882a593Smuzhiyun<para>
1578*4882a593Smuzhiyun<blockquote><programlisting>
1579*4882a593Smuzhiyun
1580*4882a593Smuzhiyun	void pInternalDevice->bell->BellProc(percent, pDevice, ctrl, unknown)
1581*4882a593Smuzhiyun		int percent;
1582*4882a593Smuzhiyun		DeviceIntPtr pDevice;
1583*4882a593Smuzhiyun		pointer ctrl;
1584*4882a593Smuzhiyun		int class;
1585*4882a593Smuzhiyun</programlisting></blockquote>
1586*4882a593SmuzhiyunYou need to write this routine to ring the bell on the keyboard.
1587*4882a593Smuzhiyunloud is a number from 0 to 100, with 100 being the loudest.
1588*4882a593SmuzhiyunClass is either BellFeedbackClass or KbdFeedbackClass (from XI.h).
1589*4882a593Smuzhiyun</para>
1590*4882a593Smuzhiyun<para>
1591*4882a593Smuzhiyun<blockquote><programlisting>
1592*4882a593Smuzhiyun
1593*4882a593Smuzhiyun	void pInternalDevice->somedevice->CtrlProc(device, ctrl)
1594*4882a593Smuzhiyun		DevicePtr device;
1595*4882a593Smuzhiyun		SomethingCtrl *ctrl;
1596*4882a593Smuzhiyun
1597*4882a593Smuzhiyun</programlisting></blockquote>
1598*4882a593SmuzhiyunYou write two versions of this procedure, one for the keyboard and one for the pointing device.
1599*4882a593SmuzhiyunDIX calls it to inform DDX when a client has requested changes in the current
1600*4882a593Smuzhiyunsettings for the particular device.
1601*4882a593SmuzhiyunFor a keyboard, this might be the repeat threshold and rate.
1602*4882a593SmuzhiyunFor a pointing device, this might be a scaling factor (coarse or fine) for position reporting.
1603*4882a593SmuzhiyunSee input.h for the ctrl structures.
1604*4882a593Smuzhiyun</para>
1605*4882a593Smuzhiyun</section>
1606*4882a593Smuzhiyun<section>
1607*4882a593Smuzhiyun  <title>Input Initialization</title>
1608*4882a593Smuzhiyun<para>
1609*4882a593SmuzhiyunInput initialization is a bit complicated.
1610*4882a593SmuzhiyunIt all starts with InitInput(), a routine that you write to call
1611*4882a593SmuzhiyunAddInputDevice() twice
1612*4882a593Smuzhiyun(once for pointing device and once for keyboard.)
1613*4882a593Smuzhiyun</para>
1614*4882a593Smuzhiyun<para>
1615*4882a593SmuzhiyunWhen you Add the devices, a routine you supply for each device
1616*4882a593Smuzhiyungets called to initialize them.
1617*4882a593SmuzhiyunYour individual initialize routines must call InitKeyboardDeviceStruct()
1618*4882a593Smuzhiyunor InitPointerDeviceStruct(), depending upon which it is.
1619*4882a593SmuzhiyunIn other words, you indicate twice that the keyboard is the keyboard and
1620*4882a593Smuzhiyunthe pointer is the pointer.
1621*4882a593Smuzhiyun</para>
1622*4882a593Smuzhiyun<para>
1623*4882a593Smuzhiyun<blockquote><programlisting>
1624*4882a593Smuzhiyun
1625*4882a593Smuzhiyun	void InitInput(argc, argv)
1626*4882a593Smuzhiyun	    int argc;
1627*4882a593Smuzhiyun	    char **argv;
1628*4882a593Smuzhiyun</programlisting></blockquote>
1629*4882a593SmuzhiyunInitInput is a DDX routine you must write to initialize the
1630*4882a593Smuzhiyuninput subsystem in DDX.
1631*4882a593SmuzhiyunIt must call AddInputDevice() for each device that might generate events.
1632*4882a593Smuzhiyun</para>
1633*4882a593Smuzhiyun<para>
1634*4882a593Smuzhiyun<blockquote><programlisting>
1635*4882a593Smuzhiyun
1636*4882a593Smuzhiyun	DevicePtr AddInputDevice(deviceProc, autoStart)
1637*4882a593Smuzhiyun		DeviceProc deviceProc;
1638*4882a593Smuzhiyun		Bool autoStart;
1639*4882a593Smuzhiyun</programlisting></blockquote>
1640*4882a593SmuzhiyunAddInputDevice is a DIX routine you call to create a device object.
1641*4882a593SmuzhiyundeviceProc is a DDX routine that is called by DIX to do various operations.
1642*4882a593SmuzhiyunAutoStart should be TRUE for devices that need to be turned on at
1643*4882a593Smuzhiyuninitialization time with a special call, as opposed to waiting for some
1644*4882a593Smuzhiyunclient application to
1645*4882a593Smuzhiyunturn them on.
1646*4882a593SmuzhiyunThis routine returns NULL if sufficient memory cannot be allocated to
1647*4882a593Smuzhiyuninstall the device.
1648*4882a593Smuzhiyun</para>
1649*4882a593Smuzhiyun<para>
1650*4882a593SmuzhiyunNote also that except for the main keyboard and pointing device,
1651*4882a593Smuzhiyunan extension is needed to provide for a client interface to a device.
1652*4882a593Smuzhiyun</para>
1653*4882a593Smuzhiyun<para>
1654*4882a593SmuzhiyunThe following DIX
1655*4882a593Smuzhiyunprocedures return the specified DevicePtr. They may or may not be useful
1656*4882a593Smuzhiyunto DDX implementors.
1657*4882a593Smuzhiyun</para>
1658*4882a593Smuzhiyun<para>
1659*4882a593Smuzhiyun<blockquote><programlisting>
1660*4882a593Smuzhiyun
1661*4882a593Smuzhiyun	DevicePtr LookupKeyboardDevice()
1662*4882a593Smuzhiyun</programlisting></blockquote>
1663*4882a593SmuzhiyunLookupKeyboardDevice returns pointer for current main keyboard device.
1664*4882a593Smuzhiyun</para>
1665*4882a593Smuzhiyun<para>
1666*4882a593Smuzhiyun<blockquote><programlisting>
1667*4882a593Smuzhiyun
1668*4882a593Smuzhiyun	DevicePtr LookupPointerDevice()
1669*4882a593Smuzhiyun</programlisting></blockquote>
1670*4882a593SmuzhiyunLookupPointerDevice returns pointer for current main pointing device.
1671*4882a593Smuzhiyun</para>
1672*4882a593Smuzhiyun<para>
1673*4882a593SmuzhiyunA DeviceProc (the kind passed to AddInputDevice()) in the following form:
1674*4882a593Smuzhiyun<blockquote><programlisting>
1675*4882a593Smuzhiyun
1676*4882a593Smuzhiyun	Bool pInternalDevice->DeviceProc(device, action);
1677*4882a593Smuzhiyun		DeviceIntPtr device;
1678*4882a593Smuzhiyun		int action;
1679*4882a593Smuzhiyun</programlisting></blockquote>
1680*4882a593SmuzhiyunYou must write a DeviceProc for each device.
1681*4882a593Smuzhiyundevice points to the device record.
1682*4882a593Smuzhiyunaction tells what action to take;
1683*4882a593Smuzhiyunit will be one of  these defined constants  (defined in input.h):
1684*4882a593Smuzhiyun<itemizedlist>
1685*4882a593Smuzhiyun<listitem><para>
1686*4882a593SmuzhiyunDEVICE_INIT -
1687*4882a593SmuzhiyunAt DEVICE_INIT time, the device should initialize itself by calling
1688*4882a593SmuzhiyunInitPointerDeviceStruct(), InitKeyboardDeviceStruct(), or a similar
1689*4882a593Smuzhiyunroutine (see below)
1690*4882a593Smuzhiyunand "opening" the device if necessary.
1691*4882a593SmuzhiyunIf you return a non-zero (i.e., != Success) value from the DEVICE_INIT
1692*4882a593Smuzhiyuncall, that device will be considered unavailable. If either the main keyboard
1693*4882a593Smuzhiyunor main pointing device cannot be initialized, the DIX code will refuse
1694*4882a593Smuzhiyunto continue booting up.</para></listitem>
1695*4882a593Smuzhiyun<listitem><para>
1696*4882a593SmuzhiyunDEVICE_ON - If the DeviceProc is called with DEVICE_ON, then it is
1697*4882a593Smuzhiyunallowed to start
1698*4882a593Smuzhiyunputting events into the client stream by calling through the ProcessInputProc
1699*4882a593Smuzhiyunin the device.</para></listitem>
1700*4882a593Smuzhiyun<listitem><para>
1701*4882a593SmuzhiyunDEVICE_OFF - If the DeviceProc is called with DEVICE_OFF, no further
1702*4882a593Smuzhiyunevents from that
1703*4882a593Smuzhiyundevice should be given to the DIX layer.
1704*4882a593SmuzhiyunThe device will appear to be dead to the user.</para></listitem>
1705*4882a593Smuzhiyun<listitem><para>
1706*4882a593SmuzhiyunDEVICE_CLOSE - At DEVICE_CLOSE (terminate or reset) time, the device should
1707*4882a593Smuzhiyunbe totally closed down.</para></listitem>
1708*4882a593Smuzhiyun</itemizedlist>
1709*4882a593Smuzhiyun</para>
1710*4882a593Smuzhiyun<para>
1711*4882a593Smuzhiyun<blockquote><programlisting>
1712*4882a593Smuzhiyun
1713*4882a593Smuzhiyun	void InitPointerDeviceStruct(device, map, mapLength,
1714*4882a593Smuzhiyun			GetMotionEvents, ControlProc, numMotionEvents)
1715*4882a593Smuzhiyun		DevicePtr device;
1716*4882a593Smuzhiyun		CARD8 *map;
1717*4882a593Smuzhiyun		int mapLength;
1718*4882a593Smuzhiyun		ValuatorMotionProcPtr ControlProc;
1719*4882a593Smuzhiyun		PtrCtrlProcPtr GetMotionEvents;
1720*4882a593Smuzhiyun		int numMotionEvents;
1721*4882a593Smuzhiyun</programlisting></blockquote>
1722*4882a593SmuzhiyunInitPointerDeviceStruct is a DIX routine you call at DEVICE_INIT time to declare
1723*4882a593Smuzhiyunsome operating routines and data structures for a pointing device.
1724*4882a593Smuzhiyunmap and mapLength are as described in the X Window
1725*4882a593SmuzhiyunSystem protocol specification.
1726*4882a593SmuzhiyunControlProc and GetMotionEvents are DDX routines, see above.
1727*4882a593Smuzhiyun</para>
1728*4882a593Smuzhiyun<para>
1729*4882a593SmuzhiyunnumMotionEvents is for the motion-buffer-size for the GetMotionEvents
1730*4882a593Smuzhiyunrequest.
1731*4882a593SmuzhiyunA typical length for a motion buffer would be 100 events.
1732*4882a593SmuzhiyunA server that does not implement this capability should set
1733*4882a593SmuzhiyunnumMotionEvents to zero.
1734*4882a593Smuzhiyun</para>
1735*4882a593Smuzhiyun<para>
1736*4882a593Smuzhiyun<blockquote><programlisting>
1737*4882a593Smuzhiyun
1738*4882a593Smuzhiyun	void InitKeyboardDeviceStruct(device, pKeySyms, pModifiers, Bell, ControlProc)
1739*4882a593Smuzhiyun		DevicePtr device;
1740*4882a593Smuzhiyun		KeySymsPtr pKeySyms;
1741*4882a593Smuzhiyun		CARD8 *pModifiers;
1742*4882a593Smuzhiyun		BellProcPtr Bell;
1743*4882a593Smuzhiyun		KbdCtrlProcPtr ControlProc;
1744*4882a593Smuzhiyun
1745*4882a593Smuzhiyun</programlisting></blockquote>
1746*4882a593SmuzhiyunYou call this DIX routine when a keyboard device is initialized and
1747*4882a593Smuzhiyunits device procedure is called with
1748*4882a593SmuzhiyunDEVICE_INIT.
1749*4882a593SmuzhiyunThe formats of the keysyms and modifier maps are defined in
1750*4882a593SmuzhiyunXserver/include/input.h.
1751*4882a593SmuzhiyunThey describe the layout of keys on the keyboards, and the glyphs
1752*4882a593Smuzhiyunassociated with them.  ( See the next section for information on
1753*4882a593Smuzhiyunsetting up the modifier map and the keysym map.)
1754*4882a593SmuzhiyunControlProc and Bell are DDX routines, see above.
1755*4882a593Smuzhiyun</para>
1756*4882a593Smuzhiyun</section>
1757*4882a593Smuzhiyun<section>
1758*4882a593Smuzhiyun  <title>Keyboard Mapping and Keycodes</title>
1759*4882a593Smuzhiyun<para>
1760*4882a593SmuzhiyunWhen you send a keyboard event, you send a report that a given key has
1761*4882a593Smuzhiyuneither been pressed or has been released.  There must be a keycode for
1762*4882a593Smuzhiyuneach key that identifies the key; the keycode-to-key mapping can be
1763*4882a593Smuzhiyunany mapping you desire, because you specify the mapping in a table you
1764*4882a593Smuzhiyunset up for DIX.  However, you are restricted by the protocol
1765*4882a593Smuzhiyunspecification to keycode values in the range 8 to 255 inclusive.
1766*4882a593Smuzhiyun</para>
1767*4882a593Smuzhiyun<para>
1768*4882a593SmuzhiyunThe keycode mapping information that you set up consists of the following:
1769*4882a593Smuzhiyun<itemizedlist>
1770*4882a593Smuzhiyun<listitem><para>
1771*4882a593SmuzhiyunA minimum and maximum keycode number</para></listitem>
1772*4882a593Smuzhiyun<listitem><para>
1773*4882a593SmuzhiyunAn array of sets of keysyms for each key, that is of length
1774*4882a593Smuzhiyunmaxkeycode - minkeycode + 1.
1775*4882a593SmuzhiyunEach element of this array is a list of codes for symbols that are on that key.
1776*4882a593SmuzhiyunThere is no limit to the number of symbols that can be on a key.</para></listitem>
1777*4882a593Smuzhiyun</itemizedlist>
1778*4882a593SmuzhiyunOnce the map is set up, DIX keeps and
1779*4882a593Smuzhiyunmaintains the client's changes to it.
1780*4882a593Smuzhiyun</para>
1781*4882a593Smuzhiyun<para>
1782*4882a593SmuzhiyunThe X protocol defines standard names to indicate the symbol(s)
1783*4882a593Smuzhiyunprinted on each keycap. (See X11/keysym.h)
1784*4882a593Smuzhiyun</para>
1785*4882a593Smuzhiyun<para>
1786*4882a593SmuzhiyunLegal modifier keys must generate both up and down transitions.  When
1787*4882a593Smuzhiyuna client tries to change a modifier key (for instance, to make "A" the
1788*4882a593Smuzhiyun"Control" key), DIX calls the following routine, which should return
1789*4882a593SmuzhiyunTRUE if the key can be used as a modifier on the given device:
1790*4882a593Smuzhiyun<blockquote><programlisting>
1791*4882a593Smuzhiyun
1792*4882a593Smuzhiyun	Bool LegalModifier(key, pDev)
1793*4882a593Smuzhiyun	    unsigned int key;
1794*4882a593Smuzhiyun	    DevicePtr pDev;
1795*4882a593Smuzhiyun</programlisting></blockquote>
1796*4882a593Smuzhiyun</para>
1797*4882a593Smuzhiyun</section>
1798*4882a593Smuzhiyun</section>
1799*4882a593Smuzhiyun<section>
1800*4882a593Smuzhiyun<title>Screens</title>
1801*4882a593Smuzhiyun<para>
1802*4882a593SmuzhiyunDifferent computer graphics
1803*4882a593Smuzhiyundisplays have different capabilities.
1804*4882a593SmuzhiyunSome are simple monochrome
1805*4882a593Smuzhiyunframe buffers that are just lying
1806*4882a593Smuzhiyunthere in memory, waiting to be written into.
1807*4882a593SmuzhiyunOthers are color displays with many bits per pixel using some color lookup table.
1808*4882a593SmuzhiyunStill others have high-speed graphic processors that prefer to do all of the work
1809*4882a593Smuzhiyunthemselves,
1810*4882a593Smuzhiyunincluding maintaining their own high-level, graphic data structures.
1811*4882a593Smuzhiyun</para>
1812*4882a593Smuzhiyun<section>
1813*4882a593Smuzhiyun  <title>Screen Hardware Requirements</title>
1814*4882a593Smuzhiyun<para>
1815*4882a593SmuzhiyunThe only requirement on screens is that you be able to both read
1816*4882a593Smuzhiyunand write locations in the frame buffer.
1817*4882a593SmuzhiyunAll screens must have a depth of 32 or less (unless you use
1818*4882a593Smuzhiyunan X extension to allow a greater depth).
1819*4882a593SmuzhiyunAll screens must fit into one of the classes listed in the section
1820*4882a593Smuzhiyunin this document on Visuals and Depths.
1821*4882a593Smuzhiyun</para>
1822*4882a593Smuzhiyun<para>
1823*4882a593SmuzhiyunX uses the pixel as its fundamental unit of distance on the screen.
1824*4882a593SmuzhiyunTherefore, most programs will measure everything in pixels.</para>
1825*4882a593Smuzhiyun<para>
1826*4882a593SmuzhiyunThe sample server assumes square pixels.
1827*4882a593SmuzhiyunSerious WYSIWYG (what you see is what you get) applications for
1828*4882a593Smuzhiyunpublishing and drawing programs will adjust for
1829*4882a593Smuzhiyundifferent screen resolutions automatically.
1830*4882a593SmuzhiyunConsiderable work
1831*4882a593Smuzhiyunis involved in compensating for non-square pixels (a bit in the DDX
1832*4882a593Smuzhiyuncode for the sample server but quite a bit in the client applications).</para>
1833*4882a593Smuzhiyun</section>
1834*4882a593Smuzhiyun<section>
1835*4882a593Smuzhiyun  <title>Data Structures</title>
1836*4882a593Smuzhiyun<para>
1837*4882a593SmuzhiyunX supports multiple screens that are connected to the same
1838*4882a593Smuzhiyunserver.  Therefore, all the per-screen information is bundled into one data
1839*4882a593Smuzhiyunstructure of attributes and procedures, which is the ScreenRec (see
1840*4882a593SmuzhiyunXserver/include/scrnintstr.h).
1841*4882a593SmuzhiyunThe procedure entry points in a ScreenRec operate on
1842*4882a593Smuzhiyunregions, colormaps, cursors, and fonts, because these resources
1843*4882a593Smuzhiyuncan differ in format from one screen to another.</para>
1844*4882a593Smuzhiyun<para>
1845*4882a593SmuzhiyunWindows are areas on the screen that can be drawn into by graphic
1846*4882a593Smuzhiyunroutines.  "Pixmaps" are off-screen graphic areas that can be drawn
1847*4882a593Smuzhiyuninto.  They are both considered drawables and are described in the
1848*4882a593Smuzhiyunsection on Drawables.  All graphic operations work on drawables, and
1849*4882a593Smuzhiyunoperations are available to copy patches from one drawable to another.</para>
1850*4882a593Smuzhiyun<para>
1851*4882a593SmuzhiyunThe pixel image data in all drawables is in a format that is private
1852*4882a593Smuzhiyunto DDX.  In fact, each instance of a drawable is associated with a
1853*4882a593Smuzhiyungiven screen.  Presumably, the pixel image data for pixmaps is chosen
1854*4882a593Smuzhiyunto be conveniently understood by the hardware.  All screens in a
1855*4882a593Smuzhiyunsingle server must be able to handle all pixmaps depths declared in
1856*4882a593Smuzhiyunthe connection setup information.</para>
1857*4882a593Smuzhiyun<para>
1858*4882a593SmuzhiyunPixmap images are transferred to the server in one of two ways:
1859*4882a593SmuzhiyunXYPixmap or ZPimap.  XYPixmaps are a series of bitmaps, one for each
1860*4882a593Smuzhiyunbit plane of the image, using the bitmap padding rules from the
1861*4882a593Smuzhiyunconnection setup.  ZPixmaps are a series of bits, nibbles, bytes or
1862*4882a593Smuzhiyunwords, one for each pixel, using the format rules (padding and so on)
1863*4882a593Smuzhiyunfor the appropriate depth.</para>
1864*4882a593Smuzhiyun<para>
1865*4882a593SmuzhiyunAll screens in a given server must agree on a set of pixmap image
1866*4882a593Smuzhiyunformats (PixmapFormat) to support (depth, number of bits per pixel,
1867*4882a593Smuzhiyunetc.).</para>
1868*4882a593Smuzhiyun<para>
1869*4882a593SmuzhiyunThere is no color interpretation of bits in the pixmap.  Pixmaps
1870*4882a593Smuzhiyundo not contain pixel values.  The interpretation is made only when
1871*4882a593Smuzhiyunthe bits are transferred onto the screen.</para>
1872*4882a593Smuzhiyun<para>
1873*4882a593SmuzhiyunThe screenInfo structure (in scrnintstr.h) is a global data structure
1874*4882a593Smuzhiyunthat has a pointer to an array of ScreenRecs, one for each screen on
1875*4882a593Smuzhiyunthe server.  (These constitute the one and only description of each
1876*4882a593Smuzhiyunscreen in the server.)  Each screen has an identifying index (0, 1, 2, ...).
1877*4882a593SmuzhiyunIn addition, the screenInfo struct contains global server-wide
1878*4882a593Smuzhiyundetails, such as the bit- and byte- order in all bit images, and the
1879*4882a593Smuzhiyunlist of pixmap image formats that are supported.  The X protocol
1880*4882a593Smuzhiyuninsists that these must be the same for all screens on the server.</para>
1881*4882a593Smuzhiyun</section>
1882*4882a593Smuzhiyun<section>
1883*4882a593Smuzhiyun  <title>Output Initialization</title>
1884*4882a593Smuzhiyun<para>
1885*4882a593Smuzhiyun<blockquote><programlisting>
1886*4882a593Smuzhiyun
1887*4882a593Smuzhiyun	InitOutput(pScreenInfo, argc, argv)
1888*4882a593Smuzhiyun		ScreenInfo *pScreenInfo;
1889*4882a593Smuzhiyun		int argc;
1890*4882a593Smuzhiyun		char **argv;
1891*4882a593Smuzhiyun</programlisting></blockquote>
1892*4882a593SmuzhiyunUpon initialization, your DDX routine InitOutput() is called by DIX.
1893*4882a593SmuzhiyunIt is passed a pointer to screenInfo to initialize.  It is also passed
1894*4882a593Smuzhiyunthe argc and argv from main() for your server for the command-line
1895*4882a593Smuzhiyunarguments.  These arguments may indicate what or how many screen
1896*4882a593Smuzhiyundevice(s) to use or in what way to use them.  For instance, your
1897*4882a593Smuzhiyunserver command line may allow a "-D" flag followed by the name of the
1898*4882a593Smuzhiyunscreen device to use.</para>
1899*4882a593Smuzhiyun<para>
1900*4882a593SmuzhiyunYour InitOutput() routine should initialize each screen you wish to
1901*4882a593Smuzhiyunuse by calling AddScreen(), and then it should initialize the pixmap
1902*4882a593Smuzhiyunformats that you support by storing values directly into the
1903*4882a593SmuzhiyunscreenInfo data structure.  You should also set certain
1904*4882a593Smuzhiyunimplementation-dependent numbers and procedures in your screenInfo,
1905*4882a593Smuzhiyunwhich determines the pixmap and scanline padding rules for all screens
1906*4882a593Smuzhiyunin the server.</para>
1907*4882a593Smuzhiyun<para>
1908*4882a593Smuzhiyun<blockquote><programlisting>
1909*4882a593Smuzhiyun
1910*4882a593Smuzhiyun	int AddScreen(scrInitProc, argc, argv)
1911*4882a593Smuzhiyun		Bool (*scrInitProc)();
1912*4882a593Smuzhiyun		int argc;
1913*4882a593Smuzhiyun		char **argv;
1914*4882a593Smuzhiyun</programlisting></blockquote>
1915*4882a593SmuzhiyunYou should call AddScreen(), a DIX procedure, in InitOutput() once for
1916*4882a593Smuzhiyuneach screen to add it to the screenInfo database.  The first argument
1917*4882a593Smuzhiyunis an initialization procedure for the screen that you supply.  The
1918*4882a593Smuzhiyunsecond and third are the argc and argv from main().  It returns the
1919*4882a593Smuzhiyunscreen number of the screen installed, or -1 if there is either
1920*4882a593Smuzhiyuninsufficient memory to add the screen, or (*scrInitProc) returned
1921*4882a593SmuzhiyunFALSE.</para>
1922*4882a593Smuzhiyun<para>
1923*4882a593SmuzhiyunThe scrInitProc should be of the following form:
1924*4882a593Smuzhiyun<blockquote><programlisting>
1925*4882a593Smuzhiyun
1926*4882a593Smuzhiyun	Bool scrInitProc(pScreen, argc, argv)
1927*4882a593Smuzhiyun		ScreenPtr pScreen;
1928*4882a593Smuzhiyun		int argc;
1929*4882a593Smuzhiyun		char **argv;
1930*4882a593Smuzhiyun</programlisting></blockquote>
1931*4882a593SmuzhiyunpScreen is the pointer to the screen's new ScreenRec. argc and argv
1932*4882a593Smuzhiyunare as before.  Your screen initialize procedure should return TRUE
1933*4882a593Smuzhiyunupon success or FALSE if the screen cannot be initialized (for
1934*4882a593Smuzhiyun instance, if the screen hardware does not exist on this machine).</para>
1935*4882a593Smuzhiyun<para>
1936*4882a593SmuzhiyunThis procedure must determine what actual device it is supposed to initialize.
1937*4882a593SmuzhiyunIf you have a different procedure for each screen, then it is no problem.
1938*4882a593SmuzhiyunIf you have the same procedure for multiple screens, it may have trouble
1939*4882a593Smuzhiyunfiguring out which screen to initialize each time around, especially if
1940*4882a593SmuzhiyunInitOutput() does not initialize all of the screens.
1941*4882a593SmuzhiyunIt is probably easiest to have one procedure for each screen.</para>
1942*4882a593Smuzhiyun<para>
1943*4882a593SmuzhiyunThe initialization procedure should fill in all the screen procedures
1944*4882a593Smuzhiyunfor that screen (windowing functions, region functions, etc.) and certain
1945*4882a593Smuzhiyunscreen attributes for that screen.</para>
1946*4882a593Smuzhiyun</section>
1947*4882a593Smuzhiyun<section>
1948*4882a593Smuzhiyun  <title>Region Routines in the ScreenRec</title>
1949*4882a593Smuzhiyun<para>
1950*4882a593SmuzhiyunA region is a dynamically allocated data structure that describes an
1951*4882a593Smuzhiyunirregularly shaped piece of real estate in XY pixel space.  You can
1952*4882a593Smuzhiyunthink of it as a set of pixels on the screen to be operated upon with
1953*4882a593Smuzhiyunset operations such as AND and OR.</para>
1954*4882a593Smuzhiyun<para>
1955*4882a593SmuzhiyunA region is frequently implemented as a list of rectangles or bitmaps
1956*4882a593Smuzhiyunthat enclose the selected pixels.  Region operators control the
1957*4882a593Smuzhiyun"clipping policy," or the operations that work on regions.  (The
1958*4882a593Smuzhiyunsample server uses YX-banded rectangles.  Unless you have something
1959*4882a593Smuzhiyunalready implemented for your graphics system, you should keep that
1960*4882a593Smuzhiyunimplementation.)  The procedure pointers to the region operators are
1961*4882a593Smuzhiyunlocated in the ScreenRec data structure.  The definition of a region
1962*4882a593Smuzhiyuncan be found in the file Xserver/include/regionstr.h.  The region code
1963*4882a593Smuzhiyunis found in Xserver/mi/miregion.c.  DDX implementations using other
1964*4882a593Smuzhiyunregion formats will need to supply different versions of the region
1965*4882a593Smuzhiyunoperators.</para>
1966*4882a593Smuzhiyun<para>
1967*4882a593SmuzhiyunSince the list of rectangles is unbounded in size, part of the region
1968*4882a593Smuzhiyundata structure is usually a large, dynamically allocated chunk of
1969*4882a593Smuzhiyunmemory.  As your region operators calculate logical combinations of
1970*4882a593Smuzhiyunregions, these blocks may need to be reallocated by your region
1971*4882a593Smuzhiyunsoftware.  For instance, in the sample server, a RegionRec has some
1972*4882a593Smuzhiyunheader information and a pointer to a dynamically allocated rectangle
1973*4882a593Smuzhiyunlist.  Periodically, the rectangle list needs to be expanded with
1974*4882a593Smuzhiyunrealloc(), whereupon the new pointer is remembered in the RegionRec.</para>
1975*4882a593Smuzhiyun<para>
1976*4882a593SmuzhiyunMost of the region operations come in two forms: a function pointer in
1977*4882a593Smuzhiyunthe Screen structure, and a macro.  The server can be compiled so that
1978*4882a593Smuzhiyunthe macros make direct calls to the appropriate functions (instead of
1979*4882a593Smuzhiyunindirecting through a screen function pointer), or it can be compiled
1980*4882a593Smuzhiyunso that the macros are identical to the function pointer forms.
1981*4882a593SmuzhiyunMaking direct calls is faster on many architectures.</para>
1982*4882a593Smuzhiyun<para>
1983*4882a593Smuzhiyun<blockquote><programlisting>
1984*4882a593Smuzhiyun
1985*4882a593Smuzhiyun	RegionPtr pScreen->RegionCreate( rect, size)
1986*4882a593Smuzhiyun		BoxPtr rect;
1987*4882a593Smuzhiyun		int size;
1988*4882a593Smuzhiyun
1989*4882a593Smuzhiyun	macro: RegionPtr RegionCreate(rect, size)
1990*4882a593Smuzhiyun
1991*4882a593Smuzhiyun</programlisting></blockquote>
1992*4882a593SmuzhiyunRegionCreate creates a region that describes ONE rectangle.  The
1993*4882a593Smuzhiyuncaller can avoid unnecessary reallocation and copying by declaring the
1994*4882a593Smuzhiyunprobable maximum number of rectangles that this region will need to
1995*4882a593Smuzhiyundescribe itself.  Your region routines, though, cannot fail just
1996*4882a593Smuzhiyunbecause the region grows beyond this size.  The caller of this routine
1997*4882a593Smuzhiyuncan pass almost anything as the size; the value is merely a good guess
1998*4882a593Smuzhiyunas to the maximum size until it is proven wrong by subsequent use.
1999*4882a593SmuzhiyunYour region procedures are then on their own in estimating how big the
2000*4882a593Smuzhiyunregion will get.  Your implementation might ignore size, if
2001*4882a593Smuzhiyunapplicable.</para>
2002*4882a593Smuzhiyun<para>
2003*4882a593Smuzhiyun<blockquote><programlisting>
2004*4882a593Smuzhiyun
2005*4882a593Smuzhiyun	void pScreen->RegionInit (pRegion, rect, size)
2006*4882a593Smuzhiyun		RegionPtr	pRegion;
2007*4882a593Smuzhiyun		BoxPtr		rect;
2008*4882a593Smuzhiyun		int		size;
2009*4882a593Smuzhiyun
2010*4882a593Smuzhiyun	macro: RegionInit(pRegion, rect, size)
2011*4882a593Smuzhiyun
2012*4882a593Smuzhiyun</programlisting></blockquote>
2013*4882a593SmuzhiyunGiven an existing raw region structure (such as an local variable), this
2014*4882a593Smuzhiyunroutine fills in the appropriate fields to make this region as usable as
2015*4882a593Smuzhiyunone returned from RegionCreate.  This avoids the additional dynamic memory
2016*4882a593Smuzhiyunallocation overhead for the region structure itself.
2017*4882a593Smuzhiyun</para>
2018*4882a593Smuzhiyun<para>
2019*4882a593Smuzhiyun<blockquote><programlisting>
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun	Bool pScreen->RegionCopy(dstrgn, srcrgn)
2022*4882a593Smuzhiyun		RegionPtr dstrgn, srcrgn;
2023*4882a593Smuzhiyun
2024*4882a593Smuzhiyun	macro: Bool RegionCopy(dstrgn, srcrgn)
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun</programlisting></blockquote>
2027*4882a593SmuzhiyunRegionCopy copies the description of one region, srcrgn, to another
2028*4882a593Smuzhiyunalready-created region,
2029*4882a593Smuzhiyundstrgn; returning TRUE if the copy succeeded, and FALSE otherwise.</para>
2030*4882a593Smuzhiyun<para>
2031*4882a593Smuzhiyun<blockquote><programlisting>
2032*4882a593Smuzhiyun
2033*4882a593Smuzhiyun	void pScreen->RegionDestroy( pRegion)
2034*4882a593Smuzhiyun		RegionPtr pRegion;
2035*4882a593Smuzhiyun
2036*4882a593Smuzhiyun	macro: RegionDestroy(pRegion)
2037*4882a593Smuzhiyun
2038*4882a593Smuzhiyun</programlisting></blockquote>
2039*4882a593SmuzhiyunRegionDestroy destroys a region and frees all allocated memory.</para>
2040*4882a593Smuzhiyun<para>
2041*4882a593Smuzhiyun<blockquote><programlisting>
2042*4882a593Smuzhiyun
2043*4882a593Smuzhiyun	void pScreen->RegionUninit (pRegion)
2044*4882a593Smuzhiyun		RegionPtr pRegion;
2045*4882a593Smuzhiyun
2046*4882a593Smuzhiyun	macro: RegionUninit(pRegion)
2047*4882a593Smuzhiyun
2048*4882a593Smuzhiyun</programlisting></blockquote>
2049*4882a593SmuzhiyunFrees everything except the region structure itself, useful when the
2050*4882a593Smuzhiyunregion was originally passed to RegionInit instead of received from
2051*4882a593SmuzhiyunRegionCreate.  When this call returns, pRegion must not be reused until
2052*4882a593Smuzhiyunit has been RegionInit'ed again.</para>
2053*4882a593Smuzhiyun<para>
2054*4882a593Smuzhiyun<blockquote><programlisting>
2055*4882a593Smuzhiyun
2056*4882a593Smuzhiyun	Bool pScreen->Intersect(newReg, reg1, reg2)
2057*4882a593Smuzhiyun		RegionPtr newReg, reg1, reg2;
2058*4882a593Smuzhiyun
2059*4882a593Smuzhiyun	macro: Bool RegionIntersect(newReg, reg1, reg2)
2060*4882a593Smuzhiyun
2061*4882a593Smuzhiyun	Bool  pScreen->Union(newReg, reg1, reg2)
2062*4882a593Smuzhiyun		RegionPtr newReg, reg1, reg2;
2063*4882a593Smuzhiyun
2064*4882a593Smuzhiyun	macro: Bool RegionUnion(newReg, reg1, reg2)
2065*4882a593Smuzhiyun
2066*4882a593Smuzhiyun	Bool  pScreen->Subtract(newReg, regMinuend, regSubtrahend)
2067*4882a593Smuzhiyun		RegionPtr newReg, regMinuend, regSubtrahend;
2068*4882a593Smuzhiyun
2069*4882a593Smuzhiyun	macro: Bool RegionUnion(newReg, regMinuend, regSubtrahend)
2070*4882a593Smuzhiyun
2071*4882a593Smuzhiyun	Bool pScreen->Inverse(newReg, pReg,  pBox)
2072*4882a593Smuzhiyun		RegionPtr newReg, pReg;
2073*4882a593Smuzhiyun		BoxPtr pBox;
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun	macro: Bool RegionInverse(newReg, pReg,  pBox)
2076*4882a593Smuzhiyun
2077*4882a593Smuzhiyun</programlisting></blockquote>
2078*4882a593SmuzhiyunThe above four calls all do basic logical operations on regions.  They
2079*4882a593Smuzhiyunset the new region (which already exists) to describe the logical
2080*4882a593Smuzhiyunintersection, union, set difference, or inverse of the region(s) that
2081*4882a593Smuzhiyunwere passed in.  Your routines must be able to handle a situation
2082*4882a593Smuzhiyunwhere the newReg is the same region as one of the other region
2083*4882a593Smuzhiyunarguments.</para>
2084*4882a593Smuzhiyun<para>
2085*4882a593SmuzhiyunThe subtract function removes the Subtrahend from the Minuend and
2086*4882a593Smuzhiyunputs the result in newReg.</para>
2087*4882a593Smuzhiyun<para>
2088*4882a593SmuzhiyunThe inverse function returns a region that is the pBox minus the
2089*4882a593Smuzhiyunregion passed in.  (A true "inverse" would make a region that extends
2090*4882a593Smuzhiyunto infinity in all directions but has holes in the middle.)  It is
2091*4882a593Smuzhiyunundefined for situations where the region extends beyond the box.</para>
2092*4882a593Smuzhiyun<para>
2093*4882a593SmuzhiyunEach routine must return the value TRUE for success.</para>
2094*4882a593Smuzhiyun<para>
2095*4882a593Smuzhiyun<blockquote><programlisting>
2096*4882a593Smuzhiyun
2097*4882a593Smuzhiyun	void pScreen->RegionReset(pRegion, pBox)
2098*4882a593Smuzhiyun		RegionPtr pRegion;
2099*4882a593Smuzhiyun		BoxPtr pBox;
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun	macro: RegionReset(pRegion, pBox)
2102*4882a593Smuzhiyun
2103*4882a593Smuzhiyun</programlisting></blockquote>
2104*4882a593SmuzhiyunRegionReset sets the region to describe
2105*4882a593Smuzhiyunone rectangle and reallocates it to a size of one rectangle, if applicable.</para>
2106*4882a593Smuzhiyun<para>
2107*4882a593Smuzhiyun<blockquote><programlisting>
2108*4882a593Smuzhiyun
2109*4882a593Smuzhiyun	void  pScreen->TranslateRegion(pRegion, x, y)
2110*4882a593Smuzhiyun		RegionPtr pRegion;
2111*4882a593Smuzhiyun		int x, y;
2112*4882a593Smuzhiyun
2113*4882a593Smuzhiyun	macro: RegionTranslate(pRegion, x, y)
2114*4882a593Smuzhiyun
2115*4882a593Smuzhiyun</programlisting></blockquote>
2116*4882a593SmuzhiyunTranslateRegion simply moves a region +x in the x direction and +y in the y
2117*4882a593Smuzhiyundirection.</para>
2118*4882a593Smuzhiyun<para>
2119*4882a593Smuzhiyun<blockquote><programlisting>
2120*4882a593Smuzhiyun
2121*4882a593Smuzhiyun	int  pScreen->RectIn(pRegion, pBox)
2122*4882a593Smuzhiyun		RegionPtr pRegion;
2123*4882a593Smuzhiyun		BoxPtr pBox;
2124*4882a593Smuzhiyun
2125*4882a593Smuzhiyun	macro: int RegionContainsRect(pRegion, pBox)
2126*4882a593Smuzhiyun
2127*4882a593Smuzhiyun</programlisting></blockquote>
2128*4882a593SmuzhiyunRectIn returns one of the defined constants rgnIN, rgnOUT, or rgnPART,
2129*4882a593Smuzhiyundepending upon whether the box is entirely inside the region, entirely
2130*4882a593Smuzhiyunoutside of the region, or partly in and partly out of the region.
2131*4882a593SmuzhiyunThese constants are defined in Xserver/include/region.h.</para>
2132*4882a593Smuzhiyun<para>
2133*4882a593Smuzhiyun<blockquote><programlisting>
2134*4882a593Smuzhiyun
2135*4882a593Smuzhiyun	Bool pScreen->PointInRegion(pRegion, x, y, pBox)
2136*4882a593Smuzhiyun		RegionPtr pRegion;
2137*4882a593Smuzhiyun		int x, y;
2138*4882a593Smuzhiyun		BoxPtr pBox;
2139*4882a593Smuzhiyun
2140*4882a593Smuzhiyun	macro: Bool RegionContainsPoint(pRegion, x, y, pBox)
2141*4882a593Smuzhiyun
2142*4882a593Smuzhiyun</programlisting></blockquote>
2143*4882a593SmuzhiyunPointInRegion returns true if the point x, y is in the region.  In
2144*4882a593Smuzhiyunaddition, it fills the rectangle pBox with coordinates of a rectangle
2145*4882a593Smuzhiyunthat is entirely inside of pRegion and encloses the point.  In the mi
2146*4882a593Smuzhiyunimplementation, it is the largest such rectangle.  (Due to the sample
2147*4882a593Smuzhiyunserver implementation, this comes cheaply.)</para>
2148*4882a593Smuzhiyun<para>
2149*4882a593SmuzhiyunThis routine used by DIX when tracking the pointing device and
2150*4882a593Smuzhiyundeciding whether to report mouse events or change the cursor.  For
2151*4882a593Smuzhiyuninstance, DIX needs to change the cursor when it moves from one window
2152*4882a593Smuzhiyunto another.  Due to overlapping windows, the shape to check may be
2153*4882a593Smuzhiyunirregular.  A PointInRegion() call for every pointing device movement
2154*4882a593Smuzhiyunmay be too expensive.  The pBox is a kind of wake-up box; DIX need not
2155*4882a593Smuzhiyuncall PointInRegion() again until the cursor wanders outside of the
2156*4882a593Smuzhiyunreturned box.</para>
2157*4882a593Smuzhiyun<para>
2158*4882a593Smuzhiyun<blockquote><programlisting>
2159*4882a593Smuzhiyun
2160*4882a593Smuzhiyun	Bool pScreen->RegionNotEmpty(pRegion)
2161*4882a593Smuzhiyun		RegionPtr pRegion;
2162*4882a593Smuzhiyun
2163*4882a593Smuzhiyun	macro: Bool RegionNotEmpty(pRegion)
2164*4882a593Smuzhiyun
2165*4882a593Smuzhiyun</programlisting></blockquote>
2166*4882a593SmuzhiyunRegionNotEmpty is a boolean function that returns
2167*4882a593Smuzhiyuntrue or false depending upon whether the region encloses any pixels.</para>
2168*4882a593Smuzhiyun<para>
2169*4882a593Smuzhiyun<blockquote><programlisting>
2170*4882a593Smuzhiyun
2171*4882a593Smuzhiyun	void pScreen->RegionEmpty(pRegion)
2172*4882a593Smuzhiyun		RegionPtr pRegion;
2173*4882a593Smuzhiyun
2174*4882a593Smuzhiyun	macro: RegionEmpty(pRegion)
2175*4882a593Smuzhiyun
2176*4882a593Smuzhiyun</programlisting></blockquote>
2177*4882a593SmuzhiyunRegionEmpty sets the region to be empty.</para>
2178*4882a593Smuzhiyun<para>
2179*4882a593Smuzhiyun<blockquote><programlisting>
2180*4882a593Smuzhiyun
2181*4882a593Smuzhiyun	BoxPtr pScreen->RegionExtents(pRegion)
2182*4882a593Smuzhiyun		RegionPtr pRegion;
2183*4882a593Smuzhiyun
2184*4882a593Smuzhiyun	macro: RegionExtents(pRegion)
2185*4882a593Smuzhiyun
2186*4882a593Smuzhiyun</programlisting></blockquote>
2187*4882a593SmuzhiyunRegionExtents returns a rectangle that is the smallest
2188*4882a593Smuzhiyunpossible superset of the entire region.
2189*4882a593SmuzhiyunThe caller will not modify this rectangle, so it can be the one
2190*4882a593Smuzhiyunin your region struct.</para>
2191*4882a593Smuzhiyun<para>
2192*4882a593Smuzhiyun<blockquote><programlisting>
2193*4882a593Smuzhiyun
2194*4882a593Smuzhiyun	Bool pScreen->RegionAppend (pDstRgn, pRegion)
2195*4882a593Smuzhiyun		RegionPtr pDstRgn;
2196*4882a593Smuzhiyun		RegionPtr pRegion;
2197*4882a593Smuzhiyun
2198*4882a593Smuzhiyun	macro: Bool RegionAppend(pDstRgn, pRegion)
2199*4882a593Smuzhiyun
2200*4882a593Smuzhiyun	Bool pScreen->RegionValidate (pRegion, pOverlap)
2201*4882a593Smuzhiyun		RegionPtr pRegion;
2202*4882a593Smuzhiyun		Bool *pOverlap;
2203*4882a593Smuzhiyun
2204*4882a593Smuzhiyun	macro: Bool RegionValidate(pRegion, pOverlap)
2205*4882a593Smuzhiyun
2206*4882a593Smuzhiyun</programlisting></blockquote>
2207*4882a593SmuzhiyunThese functions provide an optimization for clip list generation and
2208*4882a593Smuzhiyunmust be used in conjunction.  The combined effect is to produce the
2209*4882a593Smuzhiyununion of a collection of regions, by using RegionAppend several times,
2210*4882a593Smuzhiyunand finally calling RegionValidate which takes the intermediate
2211*4882a593Smuzhiyunrepresentation (which needn't be a valid region) and produces the
2212*4882a593Smuzhiyundesired union.  pOverlap is set to TRUE if any of the original
2213*4882a593Smuzhiyunregions overlap; FALSE otherwise.</para>
2214*4882a593Smuzhiyun<para>
2215*4882a593Smuzhiyun<blockquote><programlisting>
2216*4882a593Smuzhiyun
2217*4882a593Smuzhiyun	RegionPtr pScreen->BitmapToRegion (pPixmap)
2218*4882a593Smuzhiyun		PixmapPtr pPixmap;
2219*4882a593Smuzhiyun
2220*4882a593Smuzhiyun	macro: RegionPtr BitmapToRegion(pScreen, pPixmap)
2221*4882a593Smuzhiyun
2222*4882a593Smuzhiyun</programlisting></blockquote>
2223*4882a593SmuzhiyunGiven a depth-1 pixmap, this routine must create a valid region which
2224*4882a593Smuzhiyunincludes all the areas of the pixmap filled with 1's and excludes the
2225*4882a593Smuzhiyunareas filled with 0's.  This routine returns NULL if out of memory.</para>
2226*4882a593Smuzhiyun<para>
2227*4882a593Smuzhiyun<blockquote><programlisting>
2228*4882a593Smuzhiyun
2229*4882a593Smuzhiyun	RegionPtr pScreen->RectsToRegion (nrects, pRects, ordering)
2230*4882a593Smuzhiyun		int nrects;
2231*4882a593Smuzhiyun		xRectangle *pRects;
2232*4882a593Smuzhiyun		int ordering;
2233*4882a593Smuzhiyun
2234*4882a593Smuzhiyun	macro: RegionPtr RegionFromRects(nrects, pRects, ordering)
2235*4882a593Smuzhiyun
2236*4882a593Smuzhiyun</programlisting></blockquote>
2237*4882a593SmuzhiyunGiven a client-supplied list of rectangles, produces a region which includes
2238*4882a593Smuzhiyunthe union of all the rectangles.  Ordering may be used as a hint which
2239*4882a593Smuzhiyundescribes how the rectangles are sorted.  As the hint is provided by a
2240*4882a593Smuzhiyunclient, it must not be required to be correct, but the results when it is
2241*4882a593Smuzhiyunnot correct are not defined (core dump is not an option here).</para>
2242*4882a593Smuzhiyun<para>
2243*4882a593Smuzhiyun<blockquote><programlisting>
2244*4882a593Smuzhiyun
2245*4882a593Smuzhiyun	void pScreen->SendGraphicsExpose(client,pRegion,drawable,major,minor)
2246*4882a593Smuzhiyun		ClientPtr client;
2247*4882a593Smuzhiyun		RegionPtr pRegion;
2248*4882a593Smuzhiyun		XID drawable;
2249*4882a593Smuzhiyun		int major;
2250*4882a593Smuzhiyun		int minor;
2251*4882a593Smuzhiyun
2252*4882a593Smuzhiyun</programlisting></blockquote>
2253*4882a593SmuzhiyunSendGraphicsExpose dispatches a list of GraphicsExposure events which
2254*4882a593Smuzhiyunspan the region to the specified client.  If the region is empty, or
2255*4882a593Smuzhiyuna NULL pointer, a NoExpose event is sent instead.</para>
2256*4882a593Smuzhiyun</section>
2257*4882a593Smuzhiyun<section>
2258*4882a593Smuzhiyun  <title>Cursor Routines for a Screen</title>
2259*4882a593Smuzhiyun<para>
2260*4882a593SmuzhiyunA cursor is the visual form tied to the pointing device.  The default
2261*4882a593Smuzhiyuncursor is an "X" shape, but the cursor can have any shape.  When a
2262*4882a593Smuzhiyunclient creates a window, it declares what shape the cursor will be
2263*4882a593Smuzhiyunwhen it strays into that window on the screen.</para>
2264*4882a593Smuzhiyun<para>
2265*4882a593SmuzhiyunFor each possible shape the cursor assumes, there is a CursorRec data
2266*4882a593Smuzhiyunstructure.  This data structure contains a pointer to a CursorBits
2267*4882a593Smuzhiyundata structure which contains a bitmap for the image of the cursor and
2268*4882a593Smuzhiyuna bitmap for a mask behind the cursor, in addition, the CursorRec data
2269*4882a593Smuzhiyunstructure contains foreground and background colors for the cursor.
2270*4882a593SmuzhiyunThe CursorBits data structure is shared among multiple CursorRec
2271*4882a593Smuzhiyunstructures which use the same font and glyph to describe both source
2272*4882a593Smuzhiyunand mask.  The cursor image is applied to the screen by applying the
2273*4882a593Smuzhiyunmask first, clearing 1 bits in its form to the background color, and
2274*4882a593Smuzhiyunthen overwriting on the source image, in the foreground color.  (One
2275*4882a593Smuzhiyunbits of the source image that fall on top of zero bits of the mask
2276*4882a593Smuzhiyunimage are undefined.)  This way, a cursor can have transparent parts,
2277*4882a593Smuzhiyunand opaque parts in two colors.  X allows any cursor size, but some
2278*4882a593Smuzhiyunhardware cursor schemes allow a maximum of N pixels by M pixels.
2279*4882a593SmuzhiyunTherefore, you are allowed to transform the cursor to a smaller size,
2280*4882a593Smuzhiyunbut be sure to include the hot-spot.</para>
2281*4882a593Smuzhiyun<para>
2282*4882a593SmuzhiyunCursorBits in Xserver/include/cursorstr.h is a device-independent
2283*4882a593Smuzhiyunstructure containing a device-independent representation of the bits
2284*4882a593Smuzhiyunfor the source and mask.  (This is possible because the bitmap
2285*4882a593Smuzhiyunrepresentation is the same for all screens.)</para>
2286*4882a593Smuzhiyun<para>
2287*4882a593SmuzhiyunWhen a cursor is created, it is "realized" for each screen.  At
2288*4882a593Smuzhiyunrealization time, each screen has the chance to convert the bits into
2289*4882a593Smuzhiyunsome other representation that may be more convenient (for instance,
2290*4882a593Smuzhiyunputting the cursor into off-screen memory) and set up its
2291*4882a593Smuzhiyundevice-private area in either the CursorRec data structure or
2292*4882a593SmuzhiyunCursorBits data structure as appropriate to possibly point to whatever
2293*4882a593Smuzhiyundata structures are needed.  It is more memory-conservative to share
2294*4882a593Smuzhiyunrealizations by using the CursorBits private field, but this makes the
2295*4882a593Smuzhiyunassumption that the realization is independent of the colors used
2296*4882a593Smuzhiyun(which is typically true).  For instance, the following are the device
2297*4882a593Smuzhiyunprivate entries for a particular screen and cursor:
2298*4882a593Smuzhiyun<blockquote><programlisting>
2299*4882a593Smuzhiyun
2300*4882a593Smuzhiyun	pCursor->devPriv[pScreen->myNum]
2301*4882a593Smuzhiyun	pCursor->bits->devPriv[pScreen->myNum]
2302*4882a593Smuzhiyun
2303*4882a593Smuzhiyun</programlisting></blockquote>
2304*4882a593SmuzhiyunThis is done because the change from one cursor shape to another must
2305*4882a593Smuzhiyunbe fast and responsive; the cursor image should be able to flutter as
2306*4882a593Smuzhiyunfast as the user moves it across the screen.</para>
2307*4882a593Smuzhiyun<para>
2308*4882a593SmuzhiyunYou must implement the following routines for your hardware:
2309*4882a593Smuzhiyun<blockquote><programlisting>
2310*4882a593Smuzhiyun
2311*4882a593Smuzhiyun	Bool pScreen->RealizeCursor( pScr, pCurs)
2312*4882a593Smuzhiyun		ScreenPtr pScr;
2313*4882a593Smuzhiyun		CursorPtr pCurs;
2314*4882a593Smuzhiyun
2315*4882a593Smuzhiyun	Bool pScreen->UnrealizeCursor( pScr, pCurs)
2316*4882a593Smuzhiyun		ScreenPtr pScr;
2317*4882a593Smuzhiyun		CursorPtr pCurs;
2318*4882a593Smuzhiyun
2319*4882a593Smuzhiyun</programlisting></blockquote>
2320*4882a593Smuzhiyun</para>
2321*4882a593Smuzhiyun<para>
2322*4882a593SmuzhiyunRealizeCursor and UnrealizeCursor should realize (allocate and
2323*4882a593Smuzhiyuncalculate all data needed) and unrealize (free the dynamically
2324*4882a593Smuzhiyunallocated data) a given cursor when DIX needs them.  They are called
2325*4882a593Smuzhiyunwhenever a device-independent cursor is created or destroyed.  The
2326*4882a593Smuzhiyunsource and mask bits pointed to by fields in pCurs are undefined for
2327*4882a593Smuzhiyunbits beyond the right edge of the cursor.  This is so because the bits
2328*4882a593Smuzhiyunare in Bitmap format, which may have pad bits on the right edge.  You
2329*4882a593Smuzhiyunshould inhibit UnrealizeCursor() if the cursor is currently in use;
2330*4882a593Smuzhiyunthis happens when the system is reset.</para>
2331*4882a593Smuzhiyun<para>
2332*4882a593Smuzhiyun<blockquote><programlisting>
2333*4882a593Smuzhiyun
2334*4882a593Smuzhiyun	Bool pScreen->DisplayCursor( pScr, pCurs)
2335*4882a593Smuzhiyun		ScreenPtr pScr;
2336*4882a593Smuzhiyun		CursorPtr pCurs;
2337*4882a593Smuzhiyun
2338*4882a593Smuzhiyun</programlisting></blockquote>
2339*4882a593SmuzhiyunDisplayCursor should change the cursor on the given screen to the one
2340*4882a593Smuzhiyunpassed in.  It is called by DIX when the user moves the pointing
2341*4882a593Smuzhiyundevice into a different window with a different cursor.  The hotspot
2342*4882a593Smuzhiyunin the cursor should be aligned with the current cursor position.</para>
2343*4882a593Smuzhiyun<para>
2344*4882a593Smuzhiyun<blockquote><programlisting>
2345*4882a593Smuzhiyun
2346*4882a593Smuzhiyun	void pScreen->RecolorCursor( pScr, pCurs, displayed)
2347*4882a593Smuzhiyun		ScreenPtr pScr;
2348*4882a593Smuzhiyun		CursorPtr pCurs;
2349*4882a593Smuzhiyun		Bool displayed;
2350*4882a593Smuzhiyun</programlisting></blockquote>
2351*4882a593SmuzhiyunRecolorCursor notifies DDX that the colors in pCurs have changed and
2352*4882a593Smuzhiyunindicates whether this is the cursor currently being displayed.  If it
2353*4882a593Smuzhiyunis, the cursor hardware state may have to be updated.  Whether
2354*4882a593Smuzhiyundisplayed or not, state created at RealizeCursor time may have to be
2355*4882a593Smuzhiyunupdated.  A generic version, miRecolorCursor, may be used that
2356*4882a593Smuzhiyundoes an unrealize, a realize, and possibly a display (in micursor.c);
2357*4882a593Smuzhiyunhowever this constrains UnrealizeCursor and RealizeCursor to always return
2358*4882a593SmuzhiyunTRUE as no error indication is returned here.</para>
2359*4882a593Smuzhiyun<para>
2360*4882a593Smuzhiyun<blockquote><programlisting>
2361*4882a593Smuzhiyun
2362*4882a593Smuzhiyun	void pScreen->ConstrainCursor( pScr, pBox)
2363*4882a593Smuzhiyun		ScreenPtr pScr;
2364*4882a593Smuzhiyun		BoxPtr pBox;
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun</programlisting></blockquote>
2367*4882a593SmuzhiyunConstrainCursor should cause the cursor to restrict its motion to the
2368*4882a593Smuzhiyunrectangle pBox.  DIX code is capable of enforcing this constraint by
2369*4882a593Smuzhiyunforcefully moving the cursor if it strays out of the rectangle, but
2370*4882a593SmuzhiyunConstrainCursor offers a way to send a hint to the driver or hardware
2371*4882a593Smuzhiyunif such support is available.  This can prevent the cursor from
2372*4882a593Smuzhiyunwandering out of the box, then jumping back, as DIX forces it back.</para>
2373*4882a593Smuzhiyun<para>
2374*4882a593Smuzhiyun<blockquote><programlisting>
2375*4882a593Smuzhiyun
2376*4882a593Smuzhiyun	void pScreen->PointerNonInterestBox( pScr, pBox)
2377*4882a593Smuzhiyun		ScreenPtr pScr;
2378*4882a593Smuzhiyun		BoxPtr pBox;
2379*4882a593Smuzhiyun
2380*4882a593Smuzhiyun</programlisting></blockquote>
2381*4882a593SmuzhiyunPointerNonInterestBox is DIX's way of telling the pointing device code
2382*4882a593Smuzhiyunnot to report motion events while the cursor is inside a given
2383*4882a593Smuzhiyunrectangle on the given screen.  It is optional and, if not
2384*4882a593Smuzhiyunimplemented, it should do nothing.  This routine is called only when
2385*4882a593Smuzhiyunthe client has declared that it is not interested in motion events in
2386*4882a593Smuzhiyuna given window.  The rectangle you get may be a subset of that window.
2387*4882a593SmuzhiyunIt saves DIX code the time required to discard uninteresting mouse
2388*4882a593Smuzhiyunmotion events.  This is only a hint, which may speed performance.
2389*4882a593SmuzhiyunNothing in DIX currently calls PointerNonInterestBox.</para>
2390*4882a593Smuzhiyun<para>
2391*4882a593Smuzhiyun<blockquote><programlisting>
2392*4882a593Smuzhiyun
2393*4882a593Smuzhiyun	void pScreen->CursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
2394*4882a593Smuzhiyun		ScreenPtr pScr;
2395*4882a593Smuzhiyun		CursorPtr pCurs;
2396*4882a593Smuzhiyun		BoxPtr pHotBox;
2397*4882a593Smuzhiyun		BoxPtr pTopLeftBox;	/* return value */
2398*4882a593Smuzhiyun
2399*4882a593Smuzhiyun</programlisting></blockquote>
2400*4882a593SmuzhiyunCursorLimits should calculate the box that the cursor hot spot is
2401*4882a593Smuzhiyunphysically capable of moving within, as a function of the screen pScr,
2402*4882a593Smuzhiyunthe device-independent cursor pCurs, and a box that DIX hypothetically
2403*4882a593Smuzhiyunwould want the hot spot confined within, pHotBox.  This routine is for
2404*4882a593Smuzhiyuninforming DIX only; it alters no state within DDX.</para>
2405*4882a593Smuzhiyun<para>
2406*4882a593Smuzhiyun<blockquote><programlisting>
2407*4882a593Smuzhiyun
2408*4882a593Smuzhiyun	Bool pScreen->SetCursorPosition( pScr, newx, newy, generateEvent)
2409*4882a593Smuzhiyun		ScreenPtr pScr;
2410*4882a593Smuzhiyun		int newx;
2411*4882a593Smuzhiyun		int newy;
2412*4882a593Smuzhiyun		Bool generateEvent;
2413*4882a593Smuzhiyun
2414*4882a593Smuzhiyun</programlisting></blockquote>
2415*4882a593SmuzhiyunSetCursorPosition should artificially move the cursor as though the
2416*4882a593Smuzhiyunuser had jerked the pointing device very quickly.  This is called in
2417*4882a593Smuzhiyunresponse to the WarpPointer request from the client, and at other
2418*4882a593Smuzhiyuntimes.  If generateEvent is True, the device should decide whether or
2419*4882a593Smuzhiyunnot to call ProcessInputEvents() and then it must call
2420*4882a593SmuzhiyunDevicePtr->processInputProc.  Its effects are, of course, limited in
2421*4882a593Smuzhiyunvalue for absolute pointing devices such as a tablet.</para>
2422*4882a593Smuzhiyun<para>
2423*4882a593Smuzhiyun<blockquote><programlisting>
2424*4882a593Smuzhiyun
2425*4882a593Smuzhiyun	void NewCurrentScreen(newScreen, x, y)
2426*4882a593Smuzhiyun	    ScreenPtr newScreen;
2427*4882a593Smuzhiyun	    int x,y;
2428*4882a593Smuzhiyun
2429*4882a593Smuzhiyun</programlisting></blockquote>
2430*4882a593SmuzhiyunIf your ddx provides some mechanism for the user to magically move the
2431*4882a593Smuzhiyunpointer between multiple screens, you need to inform DIX when this
2432*4882a593Smuzhiyunoccurs.  You should call NewCurrentScreen to accomplish this, specifying
2433*4882a593Smuzhiyunthe new screen and the new x and y coordinates of the pointer on that screen.</para>
2434*4882a593Smuzhiyun</section>
2435*4882a593Smuzhiyun<section>
2436*4882a593Smuzhiyun  <title>Visuals, Depths and Pixmap Formats for Screens</title>
2437*4882a593Smuzhiyun<para>
2438*4882a593SmuzhiyunThe "depth" of a image is the number of bits that are used per pixel to display it.</para>
2439*4882a593Smuzhiyun<para>
2440*4882a593SmuzhiyunThe "bits per pixel" of a pixmap image that is sent over the client
2441*4882a593Smuzhiyunbyte stream is a number that is either 4, 8, 16, 24 or 32.  It is the
2442*4882a593Smuzhiyunnumber of bits used per pixel in Z format.  For instance, a pixmap
2443*4882a593Smuzhiyunimage that has a depth of six is best sent in Z format as 8 bits per
2444*4882a593Smuzhiyunpixel.</para>
2445*4882a593Smuzhiyun<para>
2446*4882a593SmuzhiyunA "pixmap image format" or a "pixmap format" is a description of the
2447*4882a593Smuzhiyunformat of a pixmap image as it is sent over the byte stream.  For each
2448*4882a593Smuzhiyundepth available on a server, there is one and only one pixmap format.
2449*4882a593SmuzhiyunThis pixmap image format gives the bits per pixel and the scanline
2450*4882a593Smuzhiyunpadding unit. (For instance, are pixel rows padded to bytes, 16-bit
2451*4882a593Smuzhiyunwords, or 32-bit words?)</para>
2452*4882a593Smuzhiyun<para>
2453*4882a593SmuzhiyunFor each screen, you must decide upon what depth(s) it supports.  You
2454*4882a593Smuzhiyunshould only count the number of bits used for the actual image.  Some
2455*4882a593Smuzhiyundisplays store additional bits to indicate what window this pixel is
2456*4882a593Smuzhiyunin, how close this object is to a viewer, transparency, and other
2457*4882a593Smuzhiyundata; do not count these bits.</para>
2458*4882a593Smuzhiyun<para>
2459*4882a593SmuzhiyunA "display class" tells whether the display is monochrome or color,
2460*4882a593Smuzhiyunwhether there is a lookup table, and how the lookup table works.</para>
2461*4882a593Smuzhiyun<para>
2462*4882a593SmuzhiyunA "visual" is a combination of depth, display class, and a description
2463*4882a593Smuzhiyunof how the pixel values result in a color on the screen.  Each visual
2464*4882a593Smuzhiyunhas a set of masks and offsets that are used to separate a pixel value
2465*4882a593Smuzhiyuninto its red, green, and blue components and a count of the number of
2466*4882a593Smuzhiyuncolormap entries.  Some of these fields are only meaningful when the
2467*4882a593Smuzhiyunclass dictates so.  Each visual also has a screen ID telling which
2468*4882a593Smuzhiyunscreen it is usable on.  Note that the depth does not imply the number
2469*4882a593Smuzhiyunof map_entries; for instance, a display can have 8 bits per pixel but
2470*4882a593Smuzhiyunonly 254 colormap entries for use by applications (the other two being
2471*4882a593Smuzhiyunreserved by hardware for the cursor).</para>
2472*4882a593Smuzhiyun<para>
2473*4882a593SmuzhiyunEach visual is identified by a 32-bit visual ID which the client uses
2474*4882a593Smuzhiyunto choose what visual is desired on a given window.  Clients can be
2475*4882a593Smuzhiyunusing more than one visual on the same screen at the same time.</para>
2476*4882a593Smuzhiyun<para>
2477*4882a593SmuzhiyunThe class of a display describes how this translation takes place.
2478*4882a593SmuzhiyunThere are three ways to do the translation.
2479*4882a593Smuzhiyun<itemizedlist>
2480*4882a593Smuzhiyun<listitem><para>
2481*4882a593SmuzhiyunPseudo - The pixel value, as a whole, is looked up
2482*4882a593Smuzhiyunin a table of length map_entries to
2483*4882a593Smuzhiyundetermine the color to display.</para></listitem>
2484*4882a593Smuzhiyun<listitem><para>
2485*4882a593SmuzhiyunTrue - The
2486*4882a593Smuzhiyunpixel value is broken up into red, green, and blue fields, each of which
2487*4882a593Smuzhiyunare looked up in separate red, green, and blue lookup tables,
2488*4882a593Smuzhiyuneach of length map_entries.</para></listitem>
2489*4882a593Smuzhiyun<listitem><para>
2490*4882a593SmuzhiyunGray - The pixel value is looked up in a table of length map_entries to
2491*4882a593Smuzhiyundetermine a gray level to display.</para></listitem>
2492*4882a593Smuzhiyun</itemizedlist>
2493*4882a593Smuzhiyun</para>
2494*4882a593Smuzhiyun<para>
2495*4882a593SmuzhiyunIn addition, the lookup table can be static (resulting colors are fixed for each
2496*4882a593Smuzhiyunpixel value)
2497*4882a593Smuzhiyunor dynamic (lookup entries are under control of the client program).
2498*4882a593SmuzhiyunThis leads to a total of six classes:
2499*4882a593Smuzhiyun<itemizedlist>
2500*4882a593Smuzhiyun<listitem><para>
2501*4882a593SmuzhiyunStatic Gray - The pixel value (of however many bits) determines directly the
2502*4882a593Smuzhiyunlevel of gray
2503*4882a593Smuzhiyunthat the pixel assumes.</para></listitem>
2504*4882a593Smuzhiyun<listitem><para>
2505*4882a593SmuzhiyunGray Scale - The pixel value is fed through a lookup table to arrive at the level
2506*4882a593Smuzhiyunof gray to display
2507*4882a593Smuzhiyunfor the given pixel.</para></listitem>
2508*4882a593Smuzhiyun<listitem><para>
2509*4882a593SmuzhiyunStatic Color - The pixel value is fed through a fixed lookup table that yields the
2510*4882a593Smuzhiyuncolor to display
2511*4882a593Smuzhiyunfor that pixel.</para></listitem>
2512*4882a593Smuzhiyun<listitem><para>
2513*4882a593SmuzhiyunPseudoColor - The whole pixel value is fed through a programmable lookup
2514*4882a593Smuzhiyuntable that has one
2515*4882a593Smuzhiyuncolor (including red, green, and blue intensities) for each possible pixel value,
2516*4882a593Smuzhiyunand that color is displayed.</para></listitem>
2517*4882a593Smuzhiyun<listitem><para>
2518*4882a593SmuzhiyunTrue Color - Each pixel value consists of one or more bits
2519*4882a593Smuzhiyunthat directly determine each primary color intensity after being fed through
2520*4882a593Smuzhiyuna fixed table.</para></listitem>
2521*4882a593Smuzhiyun<listitem><para>
2522*4882a593SmuzhiyunDirect Color - Each pixel value consists of one or more bits for each primary color.
2523*4882a593SmuzhiyunEach primary color value is individually looked up in a table for that primary
2524*4882a593Smuzhiyuncolor, yielding
2525*4882a593Smuzhiyunan intensity for that primary color.
2526*4882a593SmuzhiyunFor each pixel, the red value is looked up in the
2527*4882a593Smuzhiyunred table, the green value in the green table, and
2528*4882a593Smuzhiyunthe blue value in the blue table.</para></listitem>
2529*4882a593Smuzhiyun</itemizedlist>
2530*4882a593Smuzhiyun</para>
2531*4882a593Smuzhiyun<para>
2532*4882a593SmuzhiyunHere are some examples:
2533*4882a593Smuzhiyun<itemizedlist>
2534*4882a593Smuzhiyun<listitem><para>
2535*4882a593SmuzhiyunA simple monochrome 1 bit per pixel display is Static Gray.</para></listitem>
2536*4882a593Smuzhiyun<listitem><para>
2537*4882a593SmuzhiyunA display that has 2 bits per pixel for a choice
2538*4882a593Smuzhiyunbetween the colors of black, white, green and violet is Static Color.</para></listitem>
2539*4882a593Smuzhiyun<listitem><para>
2540*4882a593SmuzhiyunA display that has three bits per pixel, where
2541*4882a593Smuzhiyuneach bit turns on or off one of the red, green or
2542*4882a593Smuzhiyunblue guns, is in the True Color class.</para></listitem>
2543*4882a593Smuzhiyun<listitem><para>
2544*4882a593SmuzhiyunIf you take the last example and scramble the
2545*4882a593Smuzhiyuncorrespondence between pixel values and colors
2546*4882a593Smuzhiyunit becomes a Static Color display.</para></listitem>
2547*4882a593Smuzhiyun</itemizedlist></para>
2548*4882a593Smuzhiyun<para>
2549*4882a593SmuzhiyunA display has 8 bits per pixel.  The 8 bits select one entry out of 256 entries
2550*4882a593Smuzhiyunin a lookup table, each entry consisting of 24 bits (8bits each for red, green,
2551*4882a593Smuzhiyunand blue).
2552*4882a593SmuzhiyunThe display can show any 256 of 16 million colors on the screen at once.
2553*4882a593SmuzhiyunThis is a pseudocolor display.
2554*4882a593SmuzhiyunThe client application gets to fill the lookup table in this class of display.</para>
2555*4882a593Smuzhiyun<para>
2556*4882a593SmuzhiyunImagine the same hardware from the last example.
2557*4882a593SmuzhiyunYour server software allows the user, on the
2558*4882a593Smuzhiyuncommand line that starts up the server
2559*4882a593Smuzhiyunprogram,
2560*4882a593Smuzhiyunto fill the lookup table to his liking once and for all.
2561*4882a593SmuzhiyunFrom then on, the server software would not change the lookup table
2562*4882a593Smuzhiyununtil it exits.
2563*4882a593SmuzhiyunFor instance, the default might be a lookup table with a reasonable sample of
2564*4882a593Smuzhiyuncolors from throughout the color space.
2565*4882a593SmuzhiyunBut the user could specify that the table be filled with 256 steps of gray scale
2566*4882a593Smuzhiyunbecause he knew ahead of time he would be manipulating a lot of black-and-white
2567*4882a593Smuzhiyunscanned photographs
2568*4882a593Smuzhiyunand not very many color things.
2569*4882a593SmuzhiyunClients would be presented with this unchangeable lookup table.
2570*4882a593SmuzhiyunAlthough the hardware qualifies as a PseudoColor display,
2571*4882a593Smuzhiyunthe facade presented to the X client is that this is a Static Color display.</para>
2572*4882a593Smuzhiyun<para>
2573*4882a593SmuzhiyunYou have to decide what kind of display you have or want
2574*4882a593Smuzhiyunto pretend you have.
2575*4882a593SmuzhiyunWhen you initialize the screen(s), this class value must be set in the
2576*4882a593SmuzhiyunVisualRec data structure along with other display characteristics like the
2577*4882a593Smuzhiyundepth and other numbers.</para>
2578*4882a593Smuzhiyun<para>
2579*4882a593SmuzhiyunThe allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec.
2580*4882a593SmuzhiyunThese are set up when InitOutput() is called; you should malloc() appropriate blocks
2581*4882a593Smuzhiyunor use static variables initialized to the correct values.</para>
2582*4882a593Smuzhiyun</section>
2583*4882a593Smuzhiyun<section>
2584*4882a593Smuzhiyun<title>Colormaps for Screens</title>
2585*4882a593Smuzhiyun<para>
2586*4882a593SmuzhiyunA colormap is a device-independent
2587*4882a593Smuzhiyunmapping between pixel values and colors displayed on the screen.</para>
2588*4882a593Smuzhiyun<para>
2589*4882a593SmuzhiyunDifferent windows on the same screen can have different
2590*4882a593Smuzhiyuncolormaps at the same time.
2591*4882a593SmuzhiyunAt any given time, the most recently installed
2592*4882a593Smuzhiyuncolormap(s) will be in use in the server
2593*4882a593Smuzhiyunso that its (their) windows' colors will be guaranteed to be correct.
2594*4882a593SmuzhiyunOther windows may be off-color.
2595*4882a593SmuzhiyunAlthough this may seem to be chaotic, in practice most clients
2596*4882a593Smuzhiyunuse the default colormap for the screen.</para>
2597*4882a593Smuzhiyun<para>
2598*4882a593SmuzhiyunThe default colormap for a screen is initialized when the screen is initialized.
2599*4882a593SmuzhiyunIt always remains in existence and is not owned by any regular client.  It
2600*4882a593Smuzhiyunis owned by client 0 (the server itself).
2601*4882a593SmuzhiyunMany clients will simply use this default colormap for their drawing.
2602*4882a593SmuzhiyunDepending upon the class of the screen, the entries in this colormap may
2603*4882a593Smuzhiyunbe modifiable by client applications.</para>
2604*4882a593Smuzhiyun</section>
2605*4882a593Smuzhiyun<section>
2606*4882a593Smuzhiyun  <title>Colormap Routines</title>
2607*4882a593Smuzhiyun<para>
2608*4882a593SmuzhiyunYou need to implement the following routines to handle the device-dependent
2609*4882a593Smuzhiyunaspects of color maps.  You will end up placing pointers to these procedures
2610*4882a593Smuzhiyunin your ScreenRec data structure(s).  The sample server implementations of
2611*4882a593Smuzhiyunmany of these routines are in fbcmap.c.</para>
2612*4882a593Smuzhiyun<para>
2613*4882a593Smuzhiyun<blockquote><programlisting>
2614*4882a593Smuzhiyun
2615*4882a593Smuzhiyun	Bool pScreen->CreateColormap(pColormap)
2616*4882a593Smuzhiyun		ColormapPtr pColormap;
2617*4882a593Smuzhiyun
2618*4882a593Smuzhiyun</programlisting></blockquote>
2619*4882a593SmuzhiyunThis routine is called by the DIX CreateColormap routine after it has allocated
2620*4882a593Smuzhiyunall the data for the new colormap and just before it returns to the dispatcher.
2621*4882a593SmuzhiyunIt is the DDX layer's chance to initialize the colormap, particularly if it is
2622*4882a593Smuzhiyuna static map.  See the following
2623*4882a593Smuzhiyunsection for more details on initializing colormaps.
2624*4882a593SmuzhiyunThe routine returns FALSE if creation failed, such as due to memory
2625*4882a593Smuzhiyunlimitations.
2626*4882a593SmuzhiyunNotice that the colormap has a devPriv field from which you can hang any
2627*4882a593Smuzhiyuncolormap specific storage you need.  Since each colormap might need special
2628*4882a593Smuzhiyuninformation, we attached the field to the colormap and not the visual.</para>
2629*4882a593Smuzhiyun<para>
2630*4882a593Smuzhiyun<blockquote><programlisting>
2631*4882a593Smuzhiyun
2632*4882a593Smuzhiyun	void pScreen->DestroyColormap(pColormap)
2633*4882a593Smuzhiyun		ColormapPtr pColormap;
2634*4882a593Smuzhiyun
2635*4882a593Smuzhiyun</programlisting></blockquote>
2636*4882a593SmuzhiyunThis routine is called by the DIX FreeColormap routine after it has uninstalled
2637*4882a593Smuzhiyunthe colormap and notified all interested parties, and before it has freed
2638*4882a593Smuzhiyunany of the colormap storage.
2639*4882a593SmuzhiyunIt is the DDX layer's chance to free any data it added to the colormap.</para>
2640*4882a593Smuzhiyun<para>
2641*4882a593Smuzhiyun<blockquote><programlisting>
2642*4882a593Smuzhiyun
2643*4882a593Smuzhiyun	void pScreen->InstallColormap(pColormap)
2644*4882a593Smuzhiyun		ColormapPtr pColormap;
2645*4882a593Smuzhiyun
2646*4882a593Smuzhiyun</programlisting></blockquote>
2647*4882a593SmuzhiyunInstallColormap should
2648*4882a593Smuzhiyunfill a lookup table on the screen with which the colormap is associated with
2649*4882a593Smuzhiyunthe colors in pColormap.
2650*4882a593SmuzhiyunIf there is only one hardware lookup table for the screen, then all colors on
2651*4882a593Smuzhiyunthe screen may change simultaneously.</para>
2652*4882a593Smuzhiyun<para>
2653*4882a593SmuzhiyunIn the more general case of multiple hardware lookup tables,
2654*4882a593Smuzhiyunthis may cause some other colormap to be
2655*4882a593Smuzhiyununinstalled, meaning that windows that subscribed to the colormap
2656*4882a593Smuzhiyunthat was uninstalled may end up being off-color.
2657*4882a593SmuzhiyunSee the note, below, about uninstalling maps.</para>
2658*4882a593Smuzhiyun<para>
2659*4882a593Smuzhiyun<blockquote><programlisting>
2660*4882a593Smuzhiyun
2661*4882a593Smuzhiyun	void pScreen->UninstallColormap(pColormap)
2662*4882a593Smuzhiyun		ColormapPtr pColormap;
2663*4882a593Smuzhiyun
2664*4882a593Smuzhiyun</programlisting></blockquote>
2665*4882a593SmuzhiyunUninstallColormap should
2666*4882a593Smuzhiyunremove pColormap from screen pColormap->pScreen.
2667*4882a593SmuzhiyunSome other map, such as the default map if possible,
2668*4882a593Smuzhiyunshould be installed in place of pColormap if applicable.
2669*4882a593SmuzhiyunIf
2670*4882a593SmuzhiyunpColormap is the default map, do nothing.
2671*4882a593SmuzhiyunIf any client has requested ColormapNotify events, the DDX layer must notify the client.
2672*4882a593Smuzhiyun(The routine WalkTree() is
2673*4882a593Smuzhiyunbe used to find such windows.  The DIX routines TellNoMap(),
2674*4882a593SmuzhiyunTellNewMap()  and TellGainedMap() are provided to be used as
2675*4882a593Smuzhiyunthe procedure parameter to WalkTree.  These procedures are in
2676*4882a593SmuzhiyunXserver/dix/colormap.c.)</para>
2677*4882a593Smuzhiyun<para>
2678*4882a593Smuzhiyun<blockquote><programlisting>
2679*4882a593Smuzhiyun
2680*4882a593Smuzhiyun	int pScreen->ListInstalledColormaps(pScreen, pCmapList)
2681*4882a593Smuzhiyun		ScreenPtr pScreen;
2682*4882a593Smuzhiyun		XID *pCmapList;
2683*4882a593Smuzhiyun
2684*4882a593Smuzhiyun
2685*4882a593Smuzhiyun</programlisting></blockquote>
2686*4882a593SmuzhiyunListInstalledColormaps fills the pCmapList in with the resource ids
2687*4882a593Smuzhiyunof the installed maps and returns a count of installed maps.
2688*4882a593SmuzhiyunpCmapList will point to an array of size MaxInstalledMaps that was allocated
2689*4882a593Smuzhiyunby the caller.</para>
2690*4882a593Smuzhiyun<para>
2691*4882a593Smuzhiyun<blockquote><programlisting>
2692*4882a593Smuzhiyun
2693*4882a593Smuzhiyun	void pScreen->StoreColors (pmap, ndef, pdefs)
2694*4882a593Smuzhiyun		ColormapPtr pmap;
2695*4882a593Smuzhiyun		int ndef;
2696*4882a593Smuzhiyun		xColorItem *pdefs;
2697*4882a593Smuzhiyun
2698*4882a593Smuzhiyun</programlisting></blockquote>
2699*4882a593SmuzhiyunStoreColors changes some of the entries in the colormap pmap.
2700*4882a593SmuzhiyunThe number of entries to change are ndef, and pdefs points to the information
2701*4882a593Smuzhiyundescribing what to change.
2702*4882a593SmuzhiyunNote that partial changes of entries in the colormap are allowed.
2703*4882a593SmuzhiyunOnly the colors
2704*4882a593Smuzhiyunindicated in the flags field of each xColorItem need to be changed.
2705*4882a593SmuzhiyunHowever, all three color fields will be sent with the proper value for the
2706*4882a593Smuzhiyunbenefit of screens that may not be able to set part of a colormap value.
2707*4882a593SmuzhiyunIf the screen is a static class, this routine does nothing.
2708*4882a593SmuzhiyunThe structure of colormap entries is nontrivial; see colormapst.h
2709*4882a593Smuzhiyunand the definition of xColorItem in Xproto.h for
2710*4882a593Smuzhiyunmore details.</para>
2711*4882a593Smuzhiyun<para>
2712*4882a593Smuzhiyun<blockquote><programlisting>
2713*4882a593Smuzhiyun
2714*4882a593Smuzhiyun	void pScreen->ResolveColor(pRed, pGreen, pBlue, pVisual)
2715*4882a593Smuzhiyun		unsigned short *pRed, *pGreen, *pBlue;
2716*4882a593Smuzhiyun		VisualPtr pVisual;
2717*4882a593Smuzhiyun
2718*4882a593Smuzhiyun
2719*4882a593Smuzhiyun</programlisting></blockquote>
2720*4882a593SmuzhiyunGiven a requested color, ResolveColor returns the nearest color that this hardware is
2721*4882a593Smuzhiyuncapable of displaying on this visual.
2722*4882a593SmuzhiyunIn other words, this rounds off each value, in place, to the number of bits
2723*4882a593Smuzhiyunper primary color that your screen can use.
2724*4882a593SmuzhiyunRemember that each screen has one of these routines.
2725*4882a593SmuzhiyunThe level of roundoff should be what you would expect from the value
2726*4882a593Smuzhiyunyou put in the bits_per_rgb field of the pVisual.</para>
2727*4882a593Smuzhiyun<para>
2728*4882a593SmuzhiyunEach value is an unsigned value ranging from 0 to 65535.
2729*4882a593SmuzhiyunThe bits least likely to be used are the lowest ones.</para>
2730*4882a593Smuzhiyun<para>
2731*4882a593SmuzhiyunFor example, if you had a pseudocolor display
2732*4882a593Smuzhiyunwith any number of bits per pixel
2733*4882a593Smuzhiyunthat had a lookup table supplying 6 bits for each color gun
2734*4882a593Smuzhiyun(a total of 256K different colors), you would
2735*4882a593Smuzhiyunround off each value to 6 bits.  Please don't simply truncate these values
2736*4882a593Smuzhiyunto the upper 6 bits, scale the result so that the maximum value seen
2737*4882a593Smuzhiyunby the client will be 65535 for each primary.  This makes color values
2738*4882a593Smuzhiyunmore portable between different depth displays (a 6-bit truncated white
2739*4882a593Smuzhiyunwill not look white on an 8-bit display).</para>
2740*4882a593Smuzhiyun<section>
2741*4882a593Smuzhiyun<title>Initializing a Colormap</title>
2742*4882a593Smuzhiyun<para>
2743*4882a593SmuzhiyunWhen a client requests a new colormap and when the server creates the default
2744*4882a593Smuzhiyuncolormap, the procedure CreateColormap in the DIX layer is invoked.
2745*4882a593SmuzhiyunThat procedure allocates memory for the colormap and related storage such as
2746*4882a593Smuzhiyunthe lists of which client owns which pixels.
2747*4882a593SmuzhiyunIt then sets a bit, BeingCreated, in the flags field of the ColormapRec
2748*4882a593Smuzhiyunand calls the DDX layer's CreateColormap routine.
2749*4882a593SmuzhiyunThis is your chance to initialize the colormap.
2750*4882a593SmuzhiyunIf the colormap is static, which you can tell by looking at the class field,
2751*4882a593Smuzhiyunyou will want to fill in each color cell to match the hardwares notion of the
2752*4882a593Smuzhiyuncolor for that pixel.
2753*4882a593SmuzhiyunIf the colormap is the default for the screen, which you can tell by looking
2754*4882a593Smuzhiyunat the IsDefault bit in the flags field, you should allocate BlackPixel
2755*4882a593Smuzhiyunand WhitePixel to match the values you set in the pScreen structure.
2756*4882a593Smuzhiyun(Of course, you picked those values to begin with.)</para>
2757*4882a593Smuzhiyun<para>
2758*4882a593SmuzhiyunYou can also wait and use AllocColor() to allocate blackPixel
2759*4882a593Smuzhiyunand whitePixel after the default colormap has been created.
2760*4882a593SmuzhiyunIf the default colormap is static and you initialized it in
2761*4882a593SmuzhiyunpScreen->CreateColormap, then use can use AllocColor afterwards
2762*4882a593Smuzhiyunto choose pixel values with the closest rgb values to those
2763*4882a593Smuzhiyundesired for blackPixel and whitePixel.
2764*4882a593SmuzhiyunIf the default colormap is dynamic and uninitialized, then
2765*4882a593Smuzhiyunthe rgb values you request will be obeyed, and AllocColor will
2766*4882a593Smuzhiyunagain choose pixel values for you.
2767*4882a593SmuzhiyunThese pixel values can then be stored into the screen.</para>
2768*4882a593Smuzhiyun<para>
2769*4882a593SmuzhiyunThere are two ways to fill in the colormap.
2770*4882a593SmuzhiyunThe simplest way is to use the DIX function AllocColor.
2771*4882a593Smuzhiyun<blockquote><programlisting>
2772*4882a593Smuzhiyun
2773*4882a593Smuzhiyunint AllocColor (pmap, pred, pgreen, pblue, pPix, client)
2774*4882a593Smuzhiyun    ColormapPtr         pmap;
2775*4882a593Smuzhiyun    unsigned short      *pred, *pgreen, *pblue;
2776*4882a593Smuzhiyun    Pixel               *pPix;
2777*4882a593Smuzhiyun    int                 client;
2778*4882a593Smuzhiyun
2779*4882a593Smuzhiyun</programlisting></blockquote>
2780*4882a593SmuzhiyunThis takes three pointers to 16 bit color values and a pointer to a suggested
2781*4882a593Smuzhiyunpixel value.  The pixel value is either an index into one colormap or a
2782*4882a593Smuzhiyuncombination of three indices depending on the type of pmap.
2783*4882a593SmuzhiyunIf your colormap starts out empty, and you don't deliberately pick the same
2784*4882a593Smuzhiyunvalue twice, you will always get your suggested pixel.
2785*4882a593SmuzhiyunThe truly nervous could check that the value returned in *pPix is the one
2786*4882a593SmuzhiyunAllocColor was called with.
2787*4882a593SmuzhiyunIf you don't care which pixel is used, or would like them sequentially
2788*4882a593Smuzhiyunallocated from entry 0, set *pPix to 0.  This will find the first free
2789*4882a593Smuzhiyunpixel and use that.</para>
2790*4882a593Smuzhiyun<para>
2791*4882a593SmuzhiyunAllocColor will take care of all the  bookkeeping  and  will
2792*4882a593Smuzhiyuncall StoreColors to get the colormap rgb values initialized.
2793*4882a593SmuzhiyunThe hardware colormap will be changed whenever this colormap
2794*4882a593Smuzhiyunis installed.</para>
2795*4882a593Smuzhiyun<para>
2796*4882a593SmuzhiyunIf for some reason AllocColor doesn't do what you want, you can do your
2797*4882a593Smuzhiyunown bookkeeping and call StoreColors yourself.  This is much more difficult
2798*4882a593Smuzhiyunand shouldn't be necessary for most devices.</para>
2799*4882a593Smuzhiyun</section>
2800*4882a593Smuzhiyun</section>
2801*4882a593Smuzhiyun<section>
2802*4882a593Smuzhiyun  <title>Fonts for Screens</title>
2803*4882a593Smuzhiyun<para>
2804*4882a593SmuzhiyunA font is a set of bitmaps that depict the symbols in a character set.
2805*4882a593SmuzhiyunEach font is for only one typeface in a given size, in other words,
2806*4882a593Smuzhiyunjust one bitmap for each character.  Parallel fonts may be available
2807*4882a593Smuzhiyunin a variety of sizes and variations, including "bold" and "italic."
2808*4882a593SmuzhiyunX supports fonts for 8-bit and 16-bit character codes (for oriental
2809*4882a593Smuzhiyunlanguages that have more than 256 characters in the font).  Glyphs are
2810*4882a593Smuzhiyunbitmaps for individual characters.</para>
2811*4882a593Smuzhiyun<para>
2812*4882a593SmuzhiyunThe source comes with some useful font files in an ASCII, plain-text
2813*4882a593Smuzhiyunformat that should be comprehensible on a wide variety of operating
2814*4882a593Smuzhiyunsystems.  The text format, referred to as BDF, is a slight extension
2815*4882a593Smuzhiyunof the current Adobe 2.1 Bitmap Distribution Format (Adobe Systems,
2816*4882a593SmuzhiyunInc.).</para>
2817*4882a593Smuzhiyun<para>
2818*4882a593SmuzhiyunA short paper in PostScript format is included with the sample server
2819*4882a593Smuzhiyunthat defines BDF.  It includes helpful pictures, which is why it is
2820*4882a593Smuzhiyundone in PostScript and is not included in this document.</para>
2821*4882a593Smuzhiyun<para>
2822*4882a593SmuzhiyunYour implementation should include some sort of font compiler to read
2823*4882a593Smuzhiyunthese files and generate binary files that are directly usable by your
2824*4882a593Smuzhiyunserver implementation.  The sample server comes with the source for a
2825*4882a593Smuzhiyunfont compiler.</para>
2826*4882a593Smuzhiyun<para>
2827*4882a593SmuzhiyunIt is important the font properties contained in the BDF files are
2828*4882a593Smuzhiyunpreserved across any font compilation. In particular, copyright
2829*4882a593Smuzhiyuninformation cannot be casually tossed aside without legal
2830*4882a593Smuzhiyunramifications. Other properties will be important to some
2831*4882a593Smuzhiyunsophisticated applications.</para>
2832*4882a593Smuzhiyun<para>
2833*4882a593SmuzhiyunAll clients get font information from the server.  Therefore, your
2834*4882a593Smuzhiyunserver can support any fonts it wants to.  It should probably support
2835*4882a593Smuzhiyunat least the fonts supplied with the X11 tape.  In principle, you can
2836*4882a593Smuzhiyunconvert fonts from other sources or dream up your own fonts for use on
2837*4882a593Smuzhiyunyour server.</para>
2838*4882a593Smuzhiyun<section>
2839*4882a593Smuzhiyun<title>Portable Compiled Format</title>
2840*4882a593Smuzhiyun<para>
2841*4882a593SmuzhiyunA font compiler is supplied with the sample server.  It has
2842*4882a593Smuzhiyuncompile-time switches to convert the BDF files into a portable binary
2843*4882a593Smuzhiyunform, called Portable Compiled Format or PCF.  This allows for an
2844*4882a593Smuzhiyunarbitrary data format inside the file, and by describing the details
2845*4882a593Smuzhiyunof the format in the header of the file, any PCF file can be read by
2846*4882a593Smuzhiyunany PCF reading client.  By selecting the format which matches the
2847*4882a593Smuzhiyunrequired internal format for your renderer, the PCF reader can avoid
2848*4882a593Smuzhiyunreformatting the data each time it is read in.  The font compiler
2849*4882a593Smuzhiyunshould be quite portable.</para>
2850*4882a593Smuzhiyun<para>
2851*4882a593SmuzhiyunThe fonts included with the tape are stored in fonts/bdf.  The
2852*4882a593Smuzhiyunfont compiler is found in fonts/tools/bdftopcf.</para>
2853*4882a593Smuzhiyun</section>
2854*4882a593Smuzhiyun<section>
2855*4882a593Smuzhiyun  <title>Font Realization</title>
2856*4882a593Smuzhiyun<para>
2857*4882a593SmuzhiyunEach screen configured into the server
2858*4882a593Smuzhiyunhas an opportunity at font-load time
2859*4882a593Smuzhiyunto "realize" a font into some internal format if necessary.
2860*4882a593SmuzhiyunThis happens every time the font is loaded into memory.</para>
2861*4882a593Smuzhiyun<para>
2862*4882a593SmuzhiyunA font (FontRec in Xserver/include/dixfontstr.h) is
2863*4882a593Smuzhiyuna device-independent structure containing a device-independent
2864*4882a593Smuzhiyunrepresentation of the font.  When a font is created, it is "realized"
2865*4882a593Smuzhiyunfor each screen.  At this point, the screen has the chance to convert
2866*4882a593Smuzhiyunthe font into some other format.  The DDX layer can also put information
2867*4882a593Smuzhiyunin the devPrivate storage.</para>
2868*4882a593Smuzhiyun<para>
2869*4882a593Smuzhiyun<blockquote><programlisting>
2870*4882a593Smuzhiyun
2871*4882a593Smuzhiyun	Bool pScreen->RealizeFont(pScr, pFont)
2872*4882a593Smuzhiyun		ScreenPtr pScr;
2873*4882a593Smuzhiyun		FontPtr pFont;
2874*4882a593Smuzhiyun
2875*4882a593Smuzhiyun	Bool pScreen->UnrealizeFont(pScr, pFont)
2876*4882a593Smuzhiyun		ScreenPtr pScr;
2877*4882a593Smuzhiyun		FontPtr pFont;
2878*4882a593Smuzhiyun
2879*4882a593Smuzhiyun</programlisting></blockquote>
2880*4882a593SmuzhiyunRealizeFont and UnrealizeFont should calculate and allocate these extra data structures and
2881*4882a593Smuzhiyundispose of them when no longer needed.
2882*4882a593SmuzhiyunThese are called in response to OpenFont and CloseFont requests from
2883*4882a593Smuzhiyunthe client.
2884*4882a593SmuzhiyunThe sample server implementation is in fbscreen.c (which does very little).</para>
2885*4882a593Smuzhiyun</section>
2886*4882a593Smuzhiyun</section>
2887*4882a593Smuzhiyun<section>
2888*4882a593Smuzhiyun  <title>Other Screen Routines</title>
2889*4882a593Smuzhiyun<para>
2890*4882a593SmuzhiyunYou must supply several other screen-specific routines for
2891*4882a593Smuzhiyunyour X server implementation.
2892*4882a593SmuzhiyunSome of these are described in other sections:
2893*4882a593Smuzhiyun<itemizedlist>
2894*4882a593Smuzhiyun<listitem><para>
2895*4882a593SmuzhiyunGetImage() is described in the Drawing Primitives section.</para></listitem>
2896*4882a593Smuzhiyun<listitem><para>
2897*4882a593SmuzhiyunGetSpans() is described in the Pixblit routine section.</para></listitem>
2898*4882a593Smuzhiyun<listitem><para>
2899*4882a593SmuzhiyunSeveral window and pixmap manipulation procedures are
2900*4882a593Smuzhiyundescribed in the Window section under Drawables.</para></listitem>
2901*4882a593Smuzhiyun<listitem><para>
2902*4882a593SmuzhiyunThe CreateGC() routine is described under Graphics Contexts.</para></listitem>
2903*4882a593Smuzhiyun</itemizedlist>
2904*4882a593Smuzhiyun</para>
2905*4882a593Smuzhiyun<para>
2906*4882a593Smuzhiyun<blockquote><programlisting>
2907*4882a593Smuzhiyun
2908*4882a593Smuzhiyun	void pScreen->QueryBestSize(kind, pWidth, pHeight)
2909*4882a593Smuzhiyun		int kind;
2910*4882a593Smuzhiyun		unsigned short *pWidth, *pHeight;
2911*4882a593Smuzhiyun		ScreenPtr pScreen;
2912*4882a593Smuzhiyun
2913*4882a593Smuzhiyun</programlisting></blockquote>
2914*4882a593SmuzhiyunQueryBestSize() returns the best sizes for cursors, tiles, and stipples
2915*4882a593Smuzhiyunin response to client requests.
2916*4882a593Smuzhiyunkind is one of the defined constants CursorShape, TileShape, or StippleShape
2917*4882a593Smuzhiyun(defined in X.h).
2918*4882a593SmuzhiyunFor CursorShape, return the maximum width and
2919*4882a593Smuzhiyunheight for cursors that you can handle.
2920*4882a593SmuzhiyunFor TileShape and StippleShape, start with the suggested values in pWidth
2921*4882a593Smuzhiyunand pHeight and modify them in place to be optimal values that are
2922*4882a593Smuzhiyungreater than or equal to the suggested values.
2923*4882a593SmuzhiyunThe sample server implementation is in Xserver/fb/fbscreen.c.</para>
2924*4882a593Smuzhiyun<para>
2925*4882a593Smuzhiyun<blockquote><programlisting>
2926*4882a593Smuzhiyun
2927*4882a593Smuzhiyun	pScreen->SourceValidate(pDrawable, x, y, width, height)
2928*4882a593Smuzhiyun		DrawablePtr pDrawable;
2929*4882a593Smuzhiyun		int x, y, width, height;
2930*4882a593Smuzhiyun		unsigned int subWindowMode;
2931*4882a593Smuzhiyun
2932*4882a593Smuzhiyun</programlisting></blockquote>
2933*4882a593SmuzhiyunSourceValidate should be called by any primitive that reads from pDrawable.
2934*4882a593SmuzhiyunIf you know that
2935*4882a593Smuzhiyunyou will never need SourceValidate, you can avoid this check.  Currently,
2936*4882a593SmuzhiyunSourceValidate is used by the mi software cursor code to remove the cursor
2937*4882a593Smuzhiyunfrom the screen when the source rectangle overlaps the cursor position.
2938*4882a593Smuzhiyunx,y,width,height describe the source rectangle (source relative, that is)
2939*4882a593Smuzhiyunfor the copy operation.  subWindowMode comes from the GC or source Picture.
2940*4882a593Smuzhiyun</para>
2941*4882a593Smuzhiyun<para>
2942*4882a593Smuzhiyun<blockquote><programlisting>
2943*4882a593Smuzhiyun
2944*4882a593Smuzhiyun	Bool pScreen->SaveScreen(pScreen, on)
2945*4882a593Smuzhiyun		ScreenPtr pScreen;
2946*4882a593Smuzhiyun		int on;
2947*4882a593Smuzhiyun
2948*4882a593Smuzhiyun</programlisting></blockquote>
2949*4882a593SmuzhiyunSaveScreen() is used for Screen Saver support (see WaitForSomething()).
2950*4882a593SmuzhiyunpScreen is the screen to save.</para>
2951*4882a593Smuzhiyun<para>
2952*4882a593Smuzhiyun<blockquote><programlisting>
2953*4882a593Smuzhiyun
2954*4882a593Smuzhiyun	Bool pScreen->CloseScreen(pScreen)
2955*4882a593Smuzhiyun	    ScreenPtr pScreen;
2956*4882a593Smuzhiyun
2957*4882a593Smuzhiyun</programlisting></blockquote>
2958*4882a593SmuzhiyunWhen the server is reset, it calls this routine for each screen.</para>
2959*4882a593Smuzhiyun<para>
2960*4882a593Smuzhiyun<blockquote><programlisting>
2961*4882a593Smuzhiyun
2962*4882a593Smuzhiyun	Bool pScreen->CreateScreenResources(pScreen)
2963*4882a593Smuzhiyun	    ScreenPtr pScreen;
2964*4882a593Smuzhiyun
2965*4882a593Smuzhiyun</programlisting></blockquote>
2966*4882a593SmuzhiyunIf this routine is not NULL, it will be called once per screen per
2967*4882a593Smuzhiyunserver initialization/reset after all modules have had a chance to
2968*4882a593Smuzhiyunrequest private space on all structures that support them (see
2969*4882a593Smuzhiyun<xref linkend="wrappers_and_privates"/> below).  You may create resources
2970*4882a593Smuzhiyunin this function instead of in the
2971*4882a593Smuzhiyunscreen init function passed to AddScreen in order to guarantee that
2972*4882a593Smuzhiyunall pre-allocated space requests have been registered first.  With the
2973*4882a593Smuzhiyunnew devPrivates mechanism, this is not strictly necessary, however.
2974*4882a593SmuzhiyunThis routine returns TRUE if successful.</para>
2975*4882a593Smuzhiyun</section>
2976*4882a593Smuzhiyun</section>
2977*4882a593Smuzhiyun<section>
2978*4882a593Smuzhiyun<title>Drawables</title>
2979*4882a593Smuzhiyun<para>
2980*4882a593SmuzhiyunA drawable is a descriptor of a surface that graphics are drawn into, either
2981*4882a593Smuzhiyuna window on the screen or a pixmap in memory.</para>
2982*4882a593Smuzhiyun<para>
2983*4882a593SmuzhiyunEach drawable has a type, class,
2984*4882a593SmuzhiyunScreenPtr for the screen it is associated with, depth, position, size,
2985*4882a593Smuzhiyunand serial number.
2986*4882a593SmuzhiyunThe type is one of the defined constants DRAWABLE_PIXMAP,
2987*4882a593SmuzhiyunDRAWABLE_WINDOW and UNDRAWABLE_WINDOW.
2988*4882a593Smuzhiyun(An undrawable window is used for window class InputOnly.)
2989*4882a593SmuzhiyunThe serial number is guaranteed to be unique across drawables, and
2990*4882a593Smuzhiyunis used in determining
2991*4882a593Smuzhiyunthe validity of the clipping information in a GC.
2992*4882a593SmuzhiyunThe screen selects the set of procedures used to manipulate and draw into the
2993*4882a593Smuzhiyundrawable.  Position is used (currently) only by windows; pixmaps must
2994*4882a593Smuzhiyunset these fields to 0,0 as this reduces the amount of conditional code
2995*4882a593Smuzhiyunexecuted throughout the mi code.  Size indicates the actual client-specified
2996*4882a593Smuzhiyunsize of the drawable.
2997*4882a593SmuzhiyunThere are, in fact, no other fields that a window drawable and pixmap
2998*4882a593Smuzhiyundrawable have in common besides those mentioned here.</para>
2999*4882a593Smuzhiyun<para>
3000*4882a593SmuzhiyunBoth PixmapRecs and WindowRecs are structs that start with a drawable
3001*4882a593Smuzhiyunand continue on with more fields.  Pixmaps have a single pointer field
3002*4882a593Smuzhiyunnamed devPrivate which usually points to the pixmap data but could conceivably be
3003*4882a593Smuzhiyunused for anything that DDX wants.  Both windows and pixmaps also have a
3004*4882a593SmuzhiyundevPrivates field which can be used for DDX specific data (see <xref linkend="wrappers_and_privates"/>
3005*4882a593Smuzhiyunbelow).  This is done because different graphics hardware has
3006*4882a593Smuzhiyundifferent requirements for management; if the graphics is always
3007*4882a593Smuzhiyunhandled by a processor with an independent address space, there is no
3008*4882a593Smuzhiyunpoint having a pointer to the bit image itself.</para>
3009*4882a593Smuzhiyun<para>
3010*4882a593SmuzhiyunThe definition of a drawable and a pixmap can be found in the file
3011*4882a593SmuzhiyunXserver/include/pixmapstr.h.
3012*4882a593SmuzhiyunThe definition of a window can be found in the file Xserver/include/windowstr.h.</para>
3013*4882a593Smuzhiyun<section>
3014*4882a593Smuzhiyun  <title>Pixmaps</title>
3015*4882a593Smuzhiyun<para>
3016*4882a593SmuzhiyunA pixmap is a three-dimensional array of bits stored somewhere offscreen,
3017*4882a593Smuzhiyunrather than in the visible portion of the screen's display frame buffer.  It
3018*4882a593Smuzhiyuncan be used as a source or destination in graphics operations.  There is no
3019*4882a593Smuzhiyunimplied interpretation of the pixel values in a pixmap, because it has no
3020*4882a593Smuzhiyunassociated visual or colormap.  There is only a depth that indicates the
3021*4882a593Smuzhiyunnumber of significant bits per pixel.  Also, there is no implied physical
3022*4882a593Smuzhiyunsize for each pixel; all graphic units are in numbers of pixels.  Therefore,
3023*4882a593Smuzhiyuna pixmap alone does not constitute a complete image; it represents only a
3024*4882a593Smuzhiyunrectangular array of pixel values.</para>
3025*4882a593Smuzhiyun<para>
3026*4882a593SmuzhiyunNote that the pixmap data structure is reference-counted.</para>
3027*4882a593Smuzhiyun<para>
3028*4882a593SmuzhiyunThe server implementation is free to put the pixmap data
3029*4882a593Smuzhiyunanywhere it sees fit, according to its graphics hardware setup.  Many
3030*4882a593Smuzhiyunimplementations will simply have the data dynamically allocated in the
3031*4882a593Smuzhiyunserver's address space.  More sophisticated implementations may put the
3032*4882a593Smuzhiyundata in undisplayed framebuffer storage.</para>
3033*4882a593Smuzhiyun<para>
3034*4882a593SmuzhiyunIn addition to dynamic devPrivates (see <xref linkend="wrappers_and_privates"/>
3035*4882a593Smuzhiyunbelow), the pixmap data structure has two fields that are private to
3036*4882a593Smuzhiyunthe device.  Although you can use them for anything you want, they
3037*4882a593Smuzhiyunhave intended purposes.  devKind is intended to be a device specific
3038*4882a593Smuzhiyunindication of the pixmap location (host memory, off-screen, etc.).  In
3039*4882a593Smuzhiyunthe sample server, since all pixmaps are in memory, devKind stores the
3040*4882a593Smuzhiyunwidth of the pixmap in bitmap scanline units.  devPrivate is usually
3041*4882a593Smuzhiyuna pointer to the bits in the pixmap.</para>
3042*4882a593Smuzhiyun<para>
3043*4882a593SmuzhiyunA bitmap is a pixmap that is one bit deep.</para>
3044*4882a593Smuzhiyun<para>
3045*4882a593Smuzhiyun<blockquote><programlisting>
3046*4882a593Smuzhiyun
3047*4882a593Smuzhiyun	PixmapPtr pScreen->CreatePixmap(pScreen, width, height, depth)
3048*4882a593Smuzhiyun		ScreenPtr pScreen;
3049*4882a593Smuzhiyun		int width, height, depth;
3050*4882a593Smuzhiyun
3051*4882a593Smuzhiyun</programlisting></blockquote>
3052*4882a593SmuzhiyunThis ScreenRec procedure must create a pixmap of the size
3053*4882a593Smuzhiyunrequested.
3054*4882a593SmuzhiyunIt must allocate a PixmapRec and fill in all of the fields.
3055*4882a593SmuzhiyunThe reference count field must be set to 1.
3056*4882a593SmuzhiyunIf width or height are zero, no space should be allocated
3057*4882a593Smuzhiyunfor the pixmap data, and if the implementation is using the
3058*4882a593SmuzhiyundevPrivate field as a pointer to the pixmap data, it should be
3059*4882a593Smuzhiyunset to NULL.
3060*4882a593SmuzhiyunIf successful, it returns a pointer to the new pixmap; if not, it returns NULL.
3061*4882a593SmuzhiyunSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
3062*4882a593Smuzhiyun<para>
3063*4882a593Smuzhiyun<blockquote><programlisting>
3064*4882a593Smuzhiyun
3065*4882a593Smuzhiyun	Bool pScreen->DestroyPixmap(pPixmap)
3066*4882a593Smuzhiyun		PixmapPtr pPixmap;
3067*4882a593Smuzhiyun
3068*4882a593Smuzhiyun</programlisting></blockquote>
3069*4882a593SmuzhiyunThis ScreenRec procedure must "destroy" a pixmap.
3070*4882a593SmuzhiyunIt should decrement the reference count and, if zero, it
3071*4882a593Smuzhiyunmust deallocate the PixmapRec and all attached devPrivate blocks.
3072*4882a593SmuzhiyunIf successful, it returns TRUE.
3073*4882a593SmuzhiyunSee Xserver/fb/fbpixmap.c for the sample server implementation.</para>
3074*4882a593Smuzhiyun<para>
3075*4882a593Smuzhiyun<blockquote><programlisting>
3076*4882a593Smuzhiyun
3077*4882a593Smuzhiyun	Bool
3078*4882a593Smuzhiyun	pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData)
3079*4882a593Smuzhiyun		PixmapPtr   pPixmap;
3080*4882a593Smuzhiyun		int	    width;
3081*4882a593Smuzhiyun		int	    height;
3082*4882a593Smuzhiyun		int	    depth;
3083*4882a593Smuzhiyun		int	    bitsPerPixel;
3084*4882a593Smuzhiyun		int	    devKind;
3085*4882a593Smuzhiyun		pointer     pPixData;
3086*4882a593Smuzhiyun
3087*4882a593Smuzhiyun</programlisting></blockquote>
3088*4882a593SmuzhiyunThis routine takes a pixmap header and initializes the fields of the PixmapRec to the
3089*4882a593Smuzhiyunparameters of the same name.  pPixmap must have been created via
3090*4882a593SmuzhiyunpScreen->CreatePixmap with a zero width or height to avoid
3091*4882a593Smuzhiyunallocating space for the pixmap data.  pPixData is assumed to be the
3092*4882a593Smuzhiyunpixmap data; it will be stored in an implementation-dependent place
3093*4882a593Smuzhiyun(usually pPixmap->devPrivate.ptr).  This routine returns
3094*4882a593SmuzhiyunTRUE if successful.  See Xserver/mi/miscrinit.c for the sample
3095*4882a593Smuzhiyunserver implementation.</para>
3096*4882a593Smuzhiyun<para>
3097*4882a593Smuzhiyun<blockquote><programlisting>
3098*4882a593Smuzhiyun
3099*4882a593Smuzhiyun	PixmapPtr
3100*4882a593Smuzhiyun	GetScratchPixmapHeader(pScreen, width, height, depth, bitsPerPixel, devKind, pPixData)
3101*4882a593Smuzhiyun		ScreenPtr   pScreen;
3102*4882a593Smuzhiyun		int	    width;
3103*4882a593Smuzhiyun		int	    height;
3104*4882a593Smuzhiyun		int	    depth;
3105*4882a593Smuzhiyun		int	    bitsPerPixel;
3106*4882a593Smuzhiyun		int	    devKind;
3107*4882a593Smuzhiyun		pointer     pPixData;
3108*4882a593Smuzhiyun
3109*4882a593Smuzhiyun	void FreeScratchPixmapHeader(pPixmap)
3110*4882a593Smuzhiyun		PixmapPtr pPixmap;
3111*4882a593Smuzhiyun
3112*4882a593Smuzhiyun</programlisting></blockquote>
3113*4882a593SmuzhiyunDDX should use these two DIX routines when it has a buffer of raw
3114*4882a593Smuzhiyunimage data that it wants to manipulate as a pixmap temporarily,
3115*4882a593Smuzhiyunusually so that some other part of the server can be leveraged to
3116*4882a593Smuzhiyunperform some operation on the data.  The data should be passed in
3117*4882a593SmuzhiyunpPixData, and will be stored in an implementation-dependent place
3118*4882a593Smuzhiyun(usually pPixmap->devPrivate.ptr). The other
3119*4882a593Smuzhiyunfields go into the corresponding PixmapRec fields.
3120*4882a593SmuzhiyunIf successful, GetScratchPixmapHeader returns a valid PixmapPtr which can
3121*4882a593Smuzhiyunbe used anywhere the server expects a pixmap, else
3122*4882a593Smuzhiyunit returns NULL.  The pixmap should be released when no longer needed
3123*4882a593Smuzhiyun(usually within the same function that allocated it)
3124*4882a593Smuzhiyunwith FreeScratchPixmapHeader.</para>
3125*4882a593Smuzhiyun</section>
3126*4882a593Smuzhiyun<section>
3127*4882a593Smuzhiyun  <title>Windows</title>
3128*4882a593Smuzhiyun<para>
3129*4882a593SmuzhiyunA window is a visible, or potentially visible, rectangle on the screen.
3130*4882a593SmuzhiyunDIX windowing functions maintain an internal n-ary tree data structure, which
3131*4882a593Smuzhiyunrepresents the current relationships of the mapped windows.
3132*4882a593SmuzhiyunWindows that are contained in another window are children of that window and
3133*4882a593Smuzhiyunare clipped to the boundaries of the parent.
3134*4882a593SmuzhiyunThe root window in the tree is the window for the entire screen.
3135*4882a593SmuzhiyunSibling windows constitute a doubly-linked list; the parent window has a pointer
3136*4882a593Smuzhiyunto the head and tail of this list.
3137*4882a593SmuzhiyunEach child also has a pointer to its parent.</para>
3138*4882a593Smuzhiyun<para>
3139*4882a593SmuzhiyunThe border of a window is drawn by a DDX procedure when DIX requests that it
3140*4882a593Smuzhiyunbe drawn.  The contents of the window is drawn by the client through
3141*4882a593Smuzhiyunrequests to the server.</para>
3142*4882a593Smuzhiyun<para>
3143*4882a593SmuzhiyunWindow painting is orchestrated through an expose event system.
3144*4882a593SmuzhiyunWhen a region is exposed,
3145*4882a593SmuzhiyunDIX generates an expose event, telling the client to repaint the window and
3146*4882a593Smuzhiyunpassing the region that is the minimal area needed to be repainted.</para>
3147*4882a593Smuzhiyun<para>
3148*4882a593SmuzhiyunAs a favor to clients, the server may retain
3149*4882a593Smuzhiyunthe output to the hidden parts of windows
3150*4882a593Smuzhiyunin off-screen memory; this is called "backing store".
3151*4882a593SmuzhiyunWhen a part of such a window becomes exposed, it
3152*4882a593Smuzhiyuncan quickly move pixels into place instead of
3153*4882a593Smuzhiyuntriggering an expose event and waiting for a client on the other
3154*4882a593Smuzhiyunend of the network to respond.
3155*4882a593SmuzhiyunEven if the network response is insignificant, the time to
3156*4882a593Smuzhiyunintelligently paint a section of a window is usually more than
3157*4882a593Smuzhiyunthe time to just copy already-painted sections.
3158*4882a593SmuzhiyunAt best, the repainting involves blanking out the area to a background color,
3159*4882a593Smuzhiyunwhich will take about the
3160*4882a593Smuzhiyunsame amount of time.
3161*4882a593SmuzhiyunIn this way, backing store can dramatically increase the
3162*4882a593Smuzhiyunperformance of window moves.</para>
3163*4882a593Smuzhiyun<para>
3164*4882a593SmuzhiyunOn the other hand, backing store can be quite complex, because
3165*4882a593Smuzhiyunall graphics drawn to hidden areas must be intercepted and redirected
3166*4882a593Smuzhiyunto the off-screen window sections.
3167*4882a593SmuzhiyunNot only can this be complicated for the server programmer,
3168*4882a593Smuzhiyunbut it can also impact window painting performance.
3169*4882a593SmuzhiyunThe backing store implementation can choose, at any time, to
3170*4882a593Smuzhiyunforget pieces of backing that are written into, relying instead upon
3171*4882a593Smuzhiyunexpose events to repaint for simplicity.</para>
3172*4882a593Smuzhiyun<para>
3173*4882a593SmuzhiyunIn X, the decision to use the backing-store scheme is made
3174*4882a593Smuzhiyunby you, the server implementor.  The sample server implements
3175*4882a593Smuzhiyunbacking store "for free" by reusing the infrastructure for the Composite
3176*4882a593Smuzhiyunextension.  As a side effect, it treats the WhenMapped and Always hints
3177*4882a593Smuzhiyunas equivalent.  However, it will never forget pixel contents when the
3178*4882a593Smuzhiyunwindow is mapped.</para>
3179*4882a593Smuzhiyun<para>
3180*4882a593SmuzhiyunWhen a window operation is requested by the client,
3181*4882a593Smuzhiyunsuch as a window being created or moved,
3182*4882a593Smuzhiyuna new state is computed.
3183*4882a593SmuzhiyunDuring this transition, DIX informs DDX what rectangles in what windows are about to
3184*4882a593Smuzhiyunbecome obscured and what rectangles in what windows have become exposed.
3185*4882a593SmuzhiyunThis provides a hook for the implementation of backing store.
3186*4882a593SmuzhiyunIf DDX is unable to restore exposed regions, DIX generates expose
3187*4882a593Smuzhiyunevents to the client.
3188*4882a593SmuzhiyunIt is then the client's responsibility to paint the
3189*4882a593Smuzhiyunwindow parts that were exposed but not restored.</para>
3190*4882a593Smuzhiyun<para>
3191*4882a593SmuzhiyunIf a window is resized, pixels sometimes need to be
3192*4882a593Smuzhiyunmoved, depending upon
3193*4882a593Smuzhiyunthe application.
3194*4882a593SmuzhiyunThe client can request "Gravity" so that
3195*4882a593Smuzhiyuncertain blocks of the window are
3196*4882a593Smuzhiyunmoved as a result of a resize.
3197*4882a593SmuzhiyunFor instance, if the window has controls or other items
3198*4882a593Smuzhiyunthat always hang on the edge of the
3199*4882a593Smuzhiyunwindow, and that edge is moved as a result of the resize,
3200*4882a593Smuzhiyunthen those pixels should be moved
3201*4882a593Smuzhiyunto avoid having the client repaint it.
3202*4882a593SmuzhiyunIf the client needs to repaint it anyway, such an operation takes
3203*4882a593Smuzhiyuntime, so it is desirable
3204*4882a593Smuzhiyunfor the server to approximate the appearance of the window as best
3205*4882a593Smuzhiyunit can while waiting for the client
3206*4882a593Smuzhiyunto do it perfectly.
3207*4882a593SmuzhiyunGravity is used for that, also.</para>
3208*4882a593Smuzhiyun<para>
3209*4882a593SmuzhiyunThe window has several fields used in drawing
3210*4882a593Smuzhiyunoperations:
3211*4882a593Smuzhiyun<itemizedlist>
3212*4882a593Smuzhiyun<listitem><para>
3213*4882a593SmuzhiyunclipList - This region, in conjunction with
3214*4882a593Smuzhiyunthe client clip region in the gc, is used to clip output.
3215*4882a593SmuzhiyunclipList has the window's children subtracted from it, in addition to pieces of sibling windows
3216*4882a593Smuzhiyunthat overlap this window.  To get the list with the
3217*4882a593Smuzhiyunchildren included (subwindow-mode is IncludeInferiors),
3218*4882a593Smuzhiyunthe routine NotClippedByChildren(pWin) returns the unclipped region.</para></listitem>
3219*4882a593Smuzhiyun<listitem><para>
3220*4882a593SmuzhiyunborderClip is the region used by CopyWindow and
3221*4882a593Smuzhiyunincludes the area of the window, its children, and the border, but with the
3222*4882a593Smuzhiyunoverlapping areas of sibling children removed.</para></listitem>
3223*4882a593Smuzhiyun</itemizedlist>
3224*4882a593SmuzhiyunMost of the other fields are for DIX use only.</para>
3225*4882a593Smuzhiyun<section>
3226*4882a593Smuzhiyun<title>Window Procedures in the ScreenRec</title>
3227*4882a593Smuzhiyun<para>
3228*4882a593SmuzhiyunYou should implement
3229*4882a593Smuzhiyunall of the following procedures and store pointers to them in the screen record.</para>
3230*4882a593Smuzhiyun<para>
3231*4882a593SmuzhiyunThe device-independent portion of the server "owns" the window tree.
3232*4882a593SmuzhiyunHowever, clever hardware might want to know the relationship of
3233*4882a593Smuzhiyunmapped windows.  There are pointers to procedures
3234*4882a593Smuzhiyunin the ScreenRec data structure that are called to give the hardware
3235*4882a593Smuzhiyuna chance to update its internal state.  These are helpers and
3236*4882a593Smuzhiyunhints to DDX only;
3237*4882a593Smuzhiyunthey do not change the window tree, which is only changed by DIX.</para>
3238*4882a593Smuzhiyun<para>
3239*4882a593Smuzhiyun<blockquote><programlisting>
3240*4882a593Smuzhiyun
3241*4882a593Smuzhiyun	Bool pScreen->CreateWindow(pWin)
3242*4882a593Smuzhiyun		WindowPtr pWin;
3243*4882a593Smuzhiyun
3244*4882a593Smuzhiyun</programlisting></blockquote>
3245*4882a593SmuzhiyunThis routine is a hook for when DIX creates a window.
3246*4882a593SmuzhiyunIt should fill in the "Window Procedures in the WindowRec" below
3247*4882a593Smuzhiyunand also allocate the devPrivate block for it.</para>
3248*4882a593Smuzhiyun<para>
3249*4882a593SmuzhiyunSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
3250*4882a593Smuzhiyun<para>
3251*4882a593Smuzhiyun<blockquote><programlisting>
3252*4882a593Smuzhiyun
3253*4882a593Smuzhiyun	Bool pScreen->DestroyWindow(pWin);
3254*4882a593Smuzhiyun		WindowPtr pWin;
3255*4882a593Smuzhiyun
3256*4882a593Smuzhiyun</programlisting></blockquote>
3257*4882a593SmuzhiyunThis routine is a hook for when DIX destroys a window.
3258*4882a593SmuzhiyunIt should deallocate the devPrivate block for it and any other blocks that need
3259*4882a593Smuzhiyunto be freed, besides doing other cleanup actions.</para>
3260*4882a593Smuzhiyun<para>
3261*4882a593SmuzhiyunSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
3262*4882a593Smuzhiyun<para>
3263*4882a593Smuzhiyun<blockquote><programlisting>
3264*4882a593Smuzhiyun
3265*4882a593Smuzhiyun	Bool pScreen->PositionWindow(pWin, x, y);
3266*4882a593Smuzhiyun		WindowPtr pWin;
3267*4882a593Smuzhiyun		int x, y;
3268*4882a593Smuzhiyun
3269*4882a593Smuzhiyun</programlisting></blockquote>
3270*4882a593SmuzhiyunThis routine is a hook for when DIX moves or resizes a window.
3271*4882a593SmuzhiyunIt should do whatever private operations need to be done when a window is moved or resized.
3272*4882a593SmuzhiyunFor instance, if DDX keeps a pixmap tile used for drawing the background
3273*4882a593Smuzhiyunor border, and it keeps the tile rotated such that it is longword
3274*4882a593Smuzhiyunaligned to longword locations in the frame buffer, then you should rotate your tiles here.
3275*4882a593SmuzhiyunThe actual graphics involved in moving the pixels on the screen and drawing the
3276*4882a593Smuzhiyunborder are handled by CopyWindow(), below.</para>
3277*4882a593Smuzhiyun<para>
3278*4882a593SmuzhiyunSee Xserver/fb/fbwindow.c for the sample server implementation.</para>
3279*4882a593Smuzhiyun<para>
3280*4882a593Smuzhiyun<blockquote><programlisting>
3281*4882a593Smuzhiyun
3282*4882a593Smuzhiyun	Bool pScreen->RealizeWindow(pWin);
3283*4882a593Smuzhiyun		WindowPtr pWin;
3284*4882a593Smuzhiyun
3285*4882a593Smuzhiyun	Bool  pScreen->UnrealizeWindow(pWin);
3286*4882a593Smuzhiyun		WindowPtr pWin;
3287*4882a593Smuzhiyun
3288*4882a593Smuzhiyun</programlisting></blockquote>
3289*4882a593SmuzhiyunThese routines are hooks for when DIX maps (makes visible) and unmaps
3290*4882a593Smuzhiyun(makes invisible) a window.  It should do whatever private operations
3291*4882a593Smuzhiyunneed to be done when these happen, such as allocating or deallocating
3292*4882a593Smuzhiyunstructures that are only needed for visible windows.  RealizeWindow
3293*4882a593Smuzhiyundoes NOT draw the window border, background or contents;
3294*4882a593SmuzhiyunUnrealizeWindow does NOT erase the window or generate exposure events
3295*4882a593Smuzhiyunfor underlying windows; this is taken care of by DIX.  DIX does,
3296*4882a593Smuzhiyunhowever, call PaintWindowBackground() and PaintWindowBorder() to
3297*4882a593Smuzhiyunperform some of these.</para>
3298*4882a593Smuzhiyun<para>
3299*4882a593Smuzhiyun<blockquote><programlisting>
3300*4882a593Smuzhiyun
3301*4882a593Smuzhiyun	Bool pScreen->ChangeWindowAttributes(pWin, vmask)
3302*4882a593Smuzhiyun		WindowPtr pWin;
3303*4882a593Smuzhiyun		unsigned long vmask;
3304*4882a593Smuzhiyun
3305*4882a593Smuzhiyun</programlisting></blockquote>
3306*4882a593SmuzhiyunChangeWindowAttributes is called whenever DIX changes window
3307*4882a593Smuzhiyunattributes, such as the size, front-to-back ordering, title, or
3308*4882a593Smuzhiyunanything of lesser severity that affects the window itself.  The
3309*4882a593Smuzhiyunsample server implements this routine.  It computes accelerators for
3310*4882a593Smuzhiyunquickly putting up background and border tiles.  (See description of
3311*4882a593Smuzhiyunthe set of routines stored in the WindowRec.)</para>
3312*4882a593Smuzhiyun<para>
3313*4882a593Smuzhiyun<blockquote><programlisting>
3314*4882a593Smuzhiyun
3315*4882a593Smuzhiyun	int pScreen->ValidateTree(pParent,  pChild, kind)
3316*4882a593Smuzhiyun		WindowPtr pParent, pChild;
3317*4882a593Smuzhiyun		VTKind kind;
3318*4882a593Smuzhiyun
3319*4882a593Smuzhiyun</programlisting></blockquote>
3320*4882a593SmuzhiyunValidateTree calculates the clipping region for the parent window and
3321*4882a593Smuzhiyunall of its children.  This routine must be provided. The sample server
3322*4882a593Smuzhiyunhas a machine-independent version in Xserver/mi/mivaltree.c.  This is
3323*4882a593Smuzhiyuna very difficult routine to replace.</para>
3324*4882a593Smuzhiyun<para>
3325*4882a593Smuzhiyun<blockquote><programlisting>
3326*4882a593Smuzhiyun
3327*4882a593Smuzhiyun	void pScreen->PostValidateTree(pParent,  pChild, kind)
3328*4882a593Smuzhiyun		WindowPtr pParent, pChild;
3329*4882a593Smuzhiyun		VTKind kind;
3330*4882a593Smuzhiyun
3331*4882a593Smuzhiyun</programlisting></blockquote>
3332*4882a593SmuzhiyunIf this routine is not NULL, DIX calls it shortly after calling
3333*4882a593SmuzhiyunValidateTree, passing it the same arguments.  This is useful for
3334*4882a593Smuzhiyunmanaging multi-layered framebuffers.
3335*4882a593SmuzhiyunThe sample server sets this to NULL.</para>
3336*4882a593Smuzhiyun<para>
3337*4882a593Smuzhiyun<blockquote><programlisting>
3338*4882a593Smuzhiyun
3339*4882a593Smuzhiyun	void pScreen->WindowExposures(pWin, pRegion, pBSRegion)
3340*4882a593Smuzhiyun		WindowPtr pWin;
3341*4882a593Smuzhiyun		RegionPtr pRegion;
3342*4882a593Smuzhiyun		RegionPtr pBSRegion;
3343*4882a593Smuzhiyun
3344*4882a593Smuzhiyun</programlisting></blockquote>
3345*4882a593SmuzhiyunThe WindowExposures() routine
3346*4882a593Smuzhiyunpaints the border and generates exposure events for the window.
3347*4882a593SmuzhiyunpRegion is an unoccluded region of the window, and pBSRegion is an
3348*4882a593Smuzhiyunoccluded region that has backing store.
3349*4882a593SmuzhiyunSince exposure events include a rectangle describing what was exposed,
3350*4882a593Smuzhiyunthis routine may have to send back a series of exposure events, one for
3351*4882a593Smuzhiyuneach rectangle of the region.
3352*4882a593SmuzhiyunThe count field in the expose event is a hint to the
3353*4882a593Smuzhiyunclient as to the number of
3354*4882a593Smuzhiyunregions that are after this one.
3355*4882a593SmuzhiyunThis routine must be provided. The sample
3356*4882a593Smuzhiyunserver has a machine-independent version in Xserver/mi/miexpose.c.</para>
3357*4882a593Smuzhiyun<para>
3358*4882a593Smuzhiyun<blockquote><programlisting>
3359*4882a593Smuzhiyun
3360*4882a593Smuzhiyun	void pScreen->ClipNotify (pWin, dx, dy)
3361*4882a593Smuzhiyun		WindowPtr pWin;
3362*4882a593Smuzhiyun		int dx, dy;
3363*4882a593Smuzhiyun
3364*4882a593Smuzhiyun</programlisting></blockquote>
3365*4882a593SmuzhiyunWhenever the cliplist for a window is changed, this function is called to
3366*4882a593Smuzhiyunperform whatever hardware manipulations might be necessary.  When called,
3367*4882a593Smuzhiyunthe clip list and border clip regions in the window are set to the new
3368*4882a593Smuzhiyunvalues.  dx,dy are the distance that the window has been moved (if at all).</para>
3369*4882a593Smuzhiyun</section>
3370*4882a593Smuzhiyun<section>
3371*4882a593Smuzhiyun  <title>Window Painting Procedures</title>
3372*4882a593Smuzhiyun<para>
3373*4882a593SmuzhiyunIn addition to the procedures listed above, there are two routines which
3374*4882a593Smuzhiyunmanipulate the actual window image directly.
3375*4882a593SmuzhiyunIn the sample server, mi implementations will work for
3376*4882a593Smuzhiyunmost purposes and fb routines speed up situations, such
3377*4882a593Smuzhiyunas solid backgrounds/borders or tiles that are 8, 16 or 32 pixels square.</para>
3378*4882a593Smuzhiyun<para>
3379*4882a593Smuzhiyun<blockquote><programlisting>
3380*4882a593Smuzhiyun
3381*4882a593Smuzhiyun	void pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
3382*4882a593Smuzhiyun		WindowPtr pWin;
3383*4882a593Smuzhiyun		int x, y, w, h;
3384*4882a593Smuzhiyun		Bool generateExposures;
3385*4882a593Smuzhiyun
3386*4882a593Smuzhiyun</programlisting></blockquote>
3387*4882a593SmuzhiyunThis routine is called on a window in response to a ClearToBackground request
3388*4882a593Smuzhiyunfrom the client.
3389*4882a593SmuzhiyunThis request has two different but related functions, depending upon generateExposures.</para>
3390*4882a593Smuzhiyun<para>
3391*4882a593SmuzhiyunIf generateExposures is true, the client is declaring that the given rectangle
3392*4882a593Smuzhiyunon the window is incorrectly painted and needs to be repainted.
3393*4882a593SmuzhiyunThe sample server implementation calculates the exposure region
3394*4882a593Smuzhiyunand hands it to the DIX procedure HandleExposures(), which
3395*4882a593Smuzhiyuncalls the WindowExposures() routine, below, for the window
3396*4882a593Smuzhiyunand all of its child windows.</para>
3397*4882a593Smuzhiyun<para>
3398*4882a593SmuzhiyunIf generateExposures is false, the client is trying to simply erase part
3399*4882a593Smuzhiyunof the window to the background fill style.
3400*4882a593SmuzhiyunClearToBackground should write the background color or tile to the
3401*4882a593Smuzhiyunrectangle in question (probably using PaintWindowBackground).
3402*4882a593SmuzhiyunIf w or h is zero, it clears all the way to the right or lower edge of the window.</para>
3403*4882a593Smuzhiyun<para>
3404*4882a593SmuzhiyunThe sample server implementation is in Xserver/mi/miwindow.c.</para>
3405*4882a593Smuzhiyun<para>
3406*4882a593Smuzhiyun<blockquote><programlisting>
3407*4882a593Smuzhiyun
3408*4882a593Smuzhiyun	void pScreen->CopyWindow(pWin, oldpt, oldRegion);
3409*4882a593Smuzhiyun		WindowPtr pWin;
3410*4882a593Smuzhiyun		DDXPointRec oldpt;
3411*4882a593Smuzhiyun		RegionPtr oldRegion;
3412*4882a593Smuzhiyun
3413*4882a593Smuzhiyun</programlisting></blockquote>
3414*4882a593SmuzhiyunCopyWindow is called when a window is moved, and graphically moves to
3415*4882a593Smuzhiyunpixels of a window on the screen.  It should not change any other
3416*4882a593Smuzhiyunstate within DDX (see PositionWindow(), above).</para>
3417*4882a593Smuzhiyun<para>
3418*4882a593Smuzhiyunoldpt is the old location of the upper-left corner.  oldRegion is the
3419*4882a593Smuzhiyunold region it is coming from.  The new location and new region is
3420*4882a593Smuzhiyunstored in the WindowRec.  oldRegion might modified in place by this
3421*4882a593Smuzhiyunroutine (the sample implementation does this).</para>
3422*4882a593Smuzhiyun<para>
3423*4882a593SmuzhiyunCopyArea could be used, except that this operation has more
3424*4882a593Smuzhiyuncomplications.  First of all, you do not want to copy a rectangle onto
3425*4882a593Smuzhiyuna rectangle.  The original window may be obscured by other windows,
3426*4882a593Smuzhiyunand the new window location may be similarly obscured.  Second, some
3427*4882a593Smuzhiyunhardware supports multiple windows with multiple depths, and your
3428*4882a593Smuzhiyunroutine needs to take care of that.</para>
3429*4882a593Smuzhiyun<para>
3430*4882a593SmuzhiyunThe pixels in oldRegion (with reference point oldpt) are copied to the
3431*4882a593Smuzhiyunwindow's new region (pWin->borderClip).  pWin->borderClip is gotten
3432*4882a593Smuzhiyundirectly from the window, rather than passing it as a parameter.</para>
3433*4882a593Smuzhiyun<para>
3434*4882a593SmuzhiyunThe sample server implementation is in Xserver/fb/fbwindow.c.</para>
3435*4882a593Smuzhiyun</section>
3436*4882a593Smuzhiyun<section>
3437*4882a593Smuzhiyun<title>Screen Operations for Multi-Layered Framebuffers</title>
3438*4882a593Smuzhiyun<para>
3439*4882a593SmuzhiyunThe following screen functions are useful if you have a framebuffer with
3440*4882a593Smuzhiyunmultiple sets of independent bit planes, e.g. overlays or underlays in
3441*4882a593Smuzhiyunaddition to the "main" planes.  If you have a simple single-layer
3442*4882a593Smuzhiyunframebuffer, you should probably use the mi versions of these routines
3443*4882a593Smuzhiyunin mi/miwindow.c.  This can be easily accomplished by calling miScreenInit.</para>
3444*4882a593Smuzhiyun<para>
3445*4882a593Smuzhiyun<blockquote><programlisting>
3446*4882a593Smuzhiyun
3447*4882a593Smuzhiyun    void pScreen->MarkWindow(pWin)
3448*4882a593Smuzhiyun	WindowPtr pWin;
3449*4882a593Smuzhiyun
3450*4882a593Smuzhiyun</programlisting></blockquote>
3451*4882a593SmuzhiyunThis formerly dix function MarkWindow has moved to ddx and is accessed
3452*4882a593Smuzhiyunvia this screen function.  This function should store something,
3453*4882a593Smuzhiyunusually a pointer to a device-dependent structure, in pWin->valdata so
3454*4882a593Smuzhiyunthat ValidateTree has the information it needs to validate the window.</para>
3455*4882a593Smuzhiyun<para>
3456*4882a593Smuzhiyun<blockquote><programlisting>
3457*4882a593Smuzhiyun
3458*4882a593Smuzhiyun    Bool pScreen->MarkOverlappedWindows(parent, firstChild, ppLayerWin)
3459*4882a593Smuzhiyun	WindowPtr parent;
3460*4882a593Smuzhiyun	WindowPtr firstChild;
3461*4882a593Smuzhiyun	WindowPtr * ppLayerWin;
3462*4882a593Smuzhiyun
3463*4882a593Smuzhiyun</programlisting></blockquote>
3464*4882a593SmuzhiyunThis formerly dix function MarkWindow has moved to ddx and is accessed
3465*4882a593Smuzhiyunvia this screen function.  In the process, it has grown another
3466*4882a593Smuzhiyunparameter: ppLayerWin, which is filled in with a pointer to the window
3467*4882a593Smuzhiyunat which save under marking and ValidateTree should begin.  In the
3468*4882a593Smuzhiyunsingle-layered framebuffer case, pLayerWin == pWin.</para>
3469*4882a593Smuzhiyun<para>
3470*4882a593Smuzhiyun<blockquote><programlisting>
3471*4882a593Smuzhiyun
3472*4882a593Smuzhiyun    Bool pScreen->ChangeSaveUnder(pLayerWin, firstChild)
3473*4882a593Smuzhiyun	WindowPtr pLayerWin;
3474*4882a593Smuzhiyun	WindowPtr firstChild;
3475*4882a593Smuzhiyun
3476*4882a593Smuzhiyun</programlisting></blockquote>
3477*4882a593SmuzhiyunThe dix functions ChangeSaveUnder and CheckSaveUnder have moved to ddx and
3478*4882a593Smuzhiyunare accessed via this screen function.  pLayerWin should be the window
3479*4882a593Smuzhiyunreturned in the ppLayerWin parameter of MarkOverlappedWindows.  The function
3480*4882a593Smuzhiyunmay turn on backing store for windows that might be covered, and may partially
3481*4882a593Smuzhiyunturn off backing store for windows.  It returns TRUE if PostChangeSaveUnder
3482*4882a593Smuzhiyunneeds to be called to finish turning off backing store.</para>
3483*4882a593Smuzhiyun<para>
3484*4882a593Smuzhiyun<blockquote><programlisting>
3485*4882a593Smuzhiyun
3486*4882a593Smuzhiyun    void pScreen->PostChangeSaveUnder(pLayerWin, firstChild)
3487*4882a593Smuzhiyun	WindowPtr pLayerWin;
3488*4882a593Smuzhiyun	WindowPtr firstChild;
3489*4882a593Smuzhiyun
3490*4882a593Smuzhiyun</programlisting></blockquote>
3491*4882a593SmuzhiyunThe dix function DoChangeSaveUnder has moved to ddx and is accessed via
3492*4882a593Smuzhiyunthis screen function.  This function completes the job of turning off
3493*4882a593Smuzhiyunbacking store that was started by ChangeSaveUnder.</para>
3494*4882a593Smuzhiyun<para>
3495*4882a593Smuzhiyun<blockquote><programlisting>
3496*4882a593Smuzhiyun
3497*4882a593Smuzhiyun    void pScreen->MoveWindow(pWin, x, y, pSib, kind)
3498*4882a593Smuzhiyun	WindowPtr pWin;
3499*4882a593Smuzhiyun	int x;
3500*4882a593Smuzhiyun	int y;
3501*4882a593Smuzhiyun	WindowPtr pSib;
3502*4882a593Smuzhiyun	VTKind kind;
3503*4882a593Smuzhiyun
3504*4882a593Smuzhiyun</programlisting></blockquote>
3505*4882a593SmuzhiyunThe formerly dix function MoveWindow has moved to ddx and is accessed via
3506*4882a593Smuzhiyunthis screen function.  The new position of the window is given by
3507*4882a593Smuzhiyunx,y.  kind is VTMove if the window is only moving, or VTOther if
3508*4882a593Smuzhiyunthe border is also changing.</para>
3509*4882a593Smuzhiyun<para>
3510*4882a593Smuzhiyun<blockquote><programlisting>
3511*4882a593Smuzhiyun
3512*4882a593Smuzhiyun    void pScreen->ResizeWindow(pWin, x, y, w, h, pSib)
3513*4882a593Smuzhiyun	WindowPtr pWin;
3514*4882a593Smuzhiyun	int x;
3515*4882a593Smuzhiyun	int y;
3516*4882a593Smuzhiyun	unsigned int w;
3517*4882a593Smuzhiyun	unsigned int h;
3518*4882a593Smuzhiyun	WindowPtr pSib;
3519*4882a593Smuzhiyun
3520*4882a593Smuzhiyun</programlisting></blockquote>
3521*4882a593SmuzhiyunThe formerly dix function SlideAndSizeWindow has moved to ddx and is accessed via
3522*4882a593Smuzhiyunthis screen function.  The new position is given by x,y.  The new size
3523*4882a593Smuzhiyunis given by w,h.</para>
3524*4882a593Smuzhiyun<para>
3525*4882a593Smuzhiyun<blockquote><programlisting>
3526*4882a593Smuzhiyun
3527*4882a593Smuzhiyun    WindowPtr pScreen->GetLayerWindow(pWin)
3528*4882a593Smuzhiyun	WindowPtr pWin
3529*4882a593Smuzhiyun
3530*4882a593Smuzhiyun</programlisting></blockquote>
3531*4882a593SmuzhiyunThis is a new function which returns a child of the layer parent of pWin.</para>
3532*4882a593Smuzhiyun<para>
3533*4882a593Smuzhiyun<blockquote><programlisting>
3534*4882a593Smuzhiyun
3535*4882a593Smuzhiyun    void pScreen->HandleExposures(pWin)
3536*4882a593Smuzhiyun	WindowPtr pWin;
3537*4882a593Smuzhiyun
3538*4882a593Smuzhiyun</programlisting></blockquote>
3539*4882a593SmuzhiyunThe formerly dix function HandleExposures has moved to ddx and is accessed via
3540*4882a593Smuzhiyunthis screen function.  This function is called after ValidateTree and
3541*4882a593Smuzhiyunuses the information contained in valdata to send exposures to windows.</para>
3542*4882a593Smuzhiyun<para>
3543*4882a593Smuzhiyun<blockquote><programlisting>
3544*4882a593Smuzhiyun
3545*4882a593Smuzhiyun    void pScreen->ReparentWindow(pWin, pPriorParent)
3546*4882a593Smuzhiyun	WindowPtr pWin;
3547*4882a593Smuzhiyun	WindowPtr pPriorParent;
3548*4882a593Smuzhiyun
3549*4882a593Smuzhiyun</programlisting></blockquote>
3550*4882a593SmuzhiyunThis function will be called when a window is reparented.  At the time of
3551*4882a593Smuzhiyunthe call, pWin will already be spliced into its new position in the
3552*4882a593Smuzhiyunwindow tree, and pPriorParent is its previous parent.  This function
3553*4882a593Smuzhiyuncan be NULL.</para>
3554*4882a593Smuzhiyun<para>
3555*4882a593Smuzhiyun<blockquote><programlisting>
3556*4882a593Smuzhiyun
3557*4882a593Smuzhiyun    void pScreen->SetShape(pWin)
3558*4882a593Smuzhiyun	WindowPtr pWin;
3559*4882a593Smuzhiyun
3560*4882a593Smuzhiyun</programlisting></blockquote>
3561*4882a593SmuzhiyunThe formerly dix function SetShape has moved to ddx and is accessed via
3562*4882a593Smuzhiyunthis screen function.  The window's new shape will have already been
3563*4882a593Smuzhiyunstored in the window when this function is called.</para>
3564*4882a593Smuzhiyun<para>
3565*4882a593Smuzhiyun<blockquote><programlisting>
3566*4882a593Smuzhiyun
3567*4882a593Smuzhiyun    void pScreen->ChangeBorderWidth(pWin, width)
3568*4882a593Smuzhiyun	WindowPtr pWin;
3569*4882a593Smuzhiyun	unsigned int width;
3570*4882a593Smuzhiyun
3571*4882a593Smuzhiyun</programlisting></blockquote>
3572*4882a593SmuzhiyunThe formerly dix function ChangeBorderWidth has moved to ddx and is accessed via
3573*4882a593Smuzhiyunthis screen function.  The new border width is given by width.</para>
3574*4882a593Smuzhiyun<para>
3575*4882a593Smuzhiyun<blockquote><programlisting>
3576*4882a593Smuzhiyun
3577*4882a593Smuzhiyun    void pScreen->MarkUnrealizedWindow(pChild, pWin, fromConfigure)
3578*4882a593Smuzhiyun	WindowPtr pChild;
3579*4882a593Smuzhiyun	WindowPtr pWin;
3580*4882a593Smuzhiyun	Bool fromConfigure;
3581*4882a593Smuzhiyun
3582*4882a593Smuzhiyun</programlisting></blockquote>
3583*4882a593SmuzhiyunThis function is called for windows that are being unrealized as part of
3584*4882a593Smuzhiyunan UnrealizeTree.  pChild is the window being unrealized, pWin is an
3585*4882a593Smuzhiyunancestor, and the fromConfigure value is simply propagated from UnrealizeTree.</para>
3586*4882a593Smuzhiyun</section>
3587*4882a593Smuzhiyun</section>
3588*4882a593Smuzhiyun</section>
3589*4882a593Smuzhiyun<section>
3590*4882a593Smuzhiyun<title>Graphics Contexts and Validation</title>
3591*4882a593Smuzhiyun<para>
3592*4882a593SmuzhiyunThis graphics context (GC) contains state variables such as foreground and
3593*4882a593Smuzhiyunbackground pixel value (color), the current line style and width,
3594*4882a593Smuzhiyunthe current tile or stipple for pattern generation, the current font for text
3595*4882a593Smuzhiyungeneration, and other similar attributes.</para>
3596*4882a593Smuzhiyun<para>
3597*4882a593SmuzhiyunIn many graphics systems, the equivalent of the graphics context and the
3598*4882a593Smuzhiyundrawable are combined as one entity.
3599*4882a593SmuzhiyunThe main distinction between the two kinds of status is that a drawable
3600*4882a593Smuzhiyundescribes a writing surface and the writings that may have already been done
3601*4882a593Smuzhiyunon it, whereas a graphics context describes the drawing process.
3602*4882a593SmuzhiyunA drawable is like a chalkboard.
3603*4882a593SmuzhiyunA GC is like a piece of chalk.</para>
3604*4882a593Smuzhiyun<para>
3605*4882a593SmuzhiyunUnlike many similar systems, there is no "current pen location."
3606*4882a593SmuzhiyunEvery graphic operation is accompanied by the coordinates where it is to happen.</para>
3607*4882a593Smuzhiyun<para>
3608*4882a593SmuzhiyunThe GC also includes two vectors of procedure pointers, the first
3609*4882a593Smuzhiyunoperate on the GC itself and are called GC funcs.  The second, called
3610*4882a593SmuzhiyunGC ops,
3611*4882a593Smuzhiyuncontains the functions that carry out the fundamental graphic operations
3612*4882a593Smuzhiyunsuch as drawing lines, polygons, arcs, text, and copying bitmaps.
3613*4882a593SmuzhiyunThe DDX graphic software can, if it
3614*4882a593Smuzhiyunwants to be smart, change these two vectors of procedure pointers
3615*4882a593Smuzhiyunto take advantage of hardware/firmware in the server machine, which can do
3616*4882a593Smuzhiyuna better job under certain circumstances.  To reduce the amount of memory
3617*4882a593Smuzhiyunconsumed by each GC, it is wise to create a few "boilerplate" GC ops vectors
3618*4882a593Smuzhiyunwhich can be shared by every GC which matches the constraints for that set.
3619*4882a593SmuzhiyunAlso, it is usually reasonable to have every GC created by a particular
3620*4882a593Smuzhiyunmodule to share a common set of GC funcs.  Samples of this sort of
3621*4882a593Smuzhiyunsharing can be seen in fb/fbgc.c.</para>
3622*4882a593Smuzhiyun<para>
3623*4882a593SmuzhiyunThe DDX software is notified any time the client (or DIX) uses a changed GC.
3624*4882a593SmuzhiyunFor instance, if the hardware has special support for drawing fixed-width
3625*4882a593Smuzhiyunfonts, DDX can intercept changes to the current font in a GC just before
3626*4882a593Smuzhiyundrawing is done.  It can plug into either a fixed-width procedure that makes
3627*4882a593Smuzhiyunthe hardware draw characters, or a variable-width procedure that carefully
3628*4882a593Smuzhiyunlays out glyphs by hand in software, depending upon the new font that is
3629*4882a593Smuzhiyunselected.</para>
3630*4882a593Smuzhiyun<para>
3631*4882a593SmuzhiyunA definition of these structures can be found in the file
3632*4882a593SmuzhiyunXserver/include/gcstruct.h.</para>
3633*4882a593Smuzhiyun<para>
3634*4882a593SmuzhiyunAlso included in each GC is support for dynamic devPrivates, which the
3635*4882a593SmuzhiyunDDX can use for any purpose (see <xref linkend="wrappers_and_privates"/> below).</para>
3636*4882a593Smuzhiyun<para>
3637*4882a593SmuzhiyunThe DIX routines available for manipulating GCs are
3638*4882a593SmuzhiyunCreateGC, ChangeGC, ChangeGCXIDs, CopyGC, SetClipRects, SetDashes, and FreeGC.
3639*4882a593Smuzhiyun<blockquote><programlisting>
3640*4882a593Smuzhiyun
3641*4882a593Smuzhiyun	GCPtr CreateGC(pDrawable, mask, pval, pStatus)
3642*4882a593Smuzhiyun	    DrawablePtr pDrawable;
3643*4882a593Smuzhiyun	    BITS32 mask;
3644*4882a593Smuzhiyun	    XID *pval;
3645*4882a593Smuzhiyun	    int *pStatus;
3646*4882a593Smuzhiyun
3647*4882a593Smuzhiyun	int ChangeGC(client, pGC, mask, pUnion)
3648*4882a593Smuzhiyun	    ClientPtr client;
3649*4882a593Smuzhiyun	    GCPtr pGC;
3650*4882a593Smuzhiyun	    BITS32 mask;
3651*4882a593Smuzhiyun	    ChangeGCValPtr pUnion;
3652*4882a593Smuzhiyun
3653*4882a593Smuzhiyun	int ChangeGCXIDs(client, pGC, mask, pC32)
3654*4882a593Smuzhiyun	    ClientPtr client;
3655*4882a593Smuzhiyun	    GCPtr pGC;
3656*4882a593Smuzhiyun	    BITS32 mask;
3657*4882a593Smuzhiyun	    CARD32 *pC32;
3658*4882a593Smuzhiyun
3659*4882a593Smuzhiyun	int CopyGC(pgcSrc, pgcDst, mask)
3660*4882a593Smuzhiyun	    GCPtr pgcSrc;
3661*4882a593Smuzhiyun	    GCPtr pgcDst;
3662*4882a593Smuzhiyun	    BITS32 mask;
3663*4882a593Smuzhiyun
3664*4882a593Smuzhiyun	int SetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering)
3665*4882a593Smuzhiyun	    GCPtr pGC;
3666*4882a593Smuzhiyun	    int xOrigin, yOrigin;
3667*4882a593Smuzhiyun	    int nrects;
3668*4882a593Smuzhiyun	    xRectangle *prects;
3669*4882a593Smuzhiyun	    int ordering;
3670*4882a593Smuzhiyun
3671*4882a593Smuzhiyun	SetDashes(pGC, offset, ndash, pdash)
3672*4882a593Smuzhiyun	    GCPtr pGC;
3673*4882a593Smuzhiyun	    unsigned offset;
3674*4882a593Smuzhiyun	    unsigned ndash;
3675*4882a593Smuzhiyun	    unsigned char *pdash;
3676*4882a593Smuzhiyun
3677*4882a593Smuzhiyun	int FreeGC(pGC, gid)
3678*4882a593Smuzhiyun	    GCPtr pGC;
3679*4882a593Smuzhiyun	    GContext gid;
3680*4882a593Smuzhiyun
3681*4882a593Smuzhiyun</programlisting></blockquote>
3682*4882a593Smuzhiyun</para>
3683*4882a593Smuzhiyun<para>
3684*4882a593SmuzhiyunAs a convenience, each Screen structure contains an array of
3685*4882a593SmuzhiyunGCs that are preallocated, one at each depth the screen supports.
3686*4882a593SmuzhiyunThese are particularly useful in the mi code.  Two DIX routines
3687*4882a593Smuzhiyunmust be used to get these GCs:
3688*4882a593Smuzhiyun<blockquote><programlisting>
3689*4882a593Smuzhiyun
3690*4882a593Smuzhiyun	GCPtr GetScratchGC(depth, pScreen)
3691*4882a593Smuzhiyun	    int depth;
3692*4882a593Smuzhiyun	    ScreenPtr pScreen;
3693*4882a593Smuzhiyun
3694*4882a593Smuzhiyun	FreeScratchGC(pGC)
3695*4882a593Smuzhiyun	    GCPtr pGC;
3696*4882a593Smuzhiyun
3697*4882a593Smuzhiyun</programlisting></blockquote>
3698*4882a593SmuzhiyunAlways use these two routines, don't try to extract the scratch
3699*4882a593SmuzhiyunGC yourself -- someone else might be using it, so a new one must
3700*4882a593Smuzhiyunbe created on the fly.</para>
3701*4882a593Smuzhiyun<para>
3702*4882a593SmuzhiyunIf you need a GC for a very long time, say until the server is restarted,
3703*4882a593Smuzhiyunyou should not take one from the pool used by GetScratchGC, but should
3704*4882a593Smuzhiyunget your own using CreateGC or CreateScratchGC.
3705*4882a593SmuzhiyunThis leaves the ones in the pool free for routines that only need it for
3706*4882a593Smuzhiyuna little while and don't want to pay a heavy cost to get it.
3707*4882a593Smuzhiyun<blockquote><programlisting>
3708*4882a593Smuzhiyun
3709*4882a593Smuzhiyun	GCPtr CreateScratchGC(pScreen, depth)
3710*4882a593Smuzhiyun	    ScreenPtr pScreen;
3711*4882a593Smuzhiyun	    int depth;
3712*4882a593Smuzhiyun
3713*4882a593Smuzhiyun</programlisting></blockquote>
3714*4882a593SmuzhiyunNULL is returned if the GC cannot be created.
3715*4882a593SmuzhiyunThe GC returned can be freed with FreeScratchGC.</para>
3716*4882a593Smuzhiyun<section>
3717*4882a593Smuzhiyun  <title>Details of Operation</title>
3718*4882a593Smuzhiyun<para>
3719*4882a593SmuzhiyunAt screen initialization, a screen must supply a GC creation procedure.
3720*4882a593SmuzhiyunAt GC creation, the screen must fill in GC funcs and GC ops vectors
3721*4882a593Smuzhiyun(Xserver/include/gcstruct.h).  For any particular GC, the func vector
3722*4882a593Smuzhiyunmust remain constant, while the op vector may vary.  This invariant is to
3723*4882a593Smuzhiyunensure that Wrappers work correctly.</para>
3724*4882a593Smuzhiyun<para>
3725*4882a593SmuzhiyunWhen a client request is processed that results in a change
3726*4882a593Smuzhiyunto the GC, the device-independent state of the GC is updated.
3727*4882a593SmuzhiyunThis includes a record of the state that changed.
3728*4882a593SmuzhiyunThen the ChangeGC GC func is called.
3729*4882a593SmuzhiyunThis is useful for graphics subsystems that are able to process
3730*4882a593Smuzhiyunstate changes in parallel with the server CPU.
3731*4882a593SmuzhiyunDDX may opt not to take any action at GC-modify time.
3732*4882a593SmuzhiyunThis is more efficient if multiple GC-modify requests occur
3733*4882a593Smuzhiyunbetween draws using a given GC.</para>
3734*4882a593Smuzhiyun<para>
3735*4882a593SmuzhiyunValidation occurs at the first draw operation that specifies the GC after
3736*4882a593Smuzhiyunthat GC was modified.  DIX calls then the ValidateGC GC func.  DDX should
3737*4882a593Smuzhiyunthen update its internal state.  DDX internal state may be stored as one or
3738*4882a593Smuzhiyunmore of the following:  1) device private block on the GC; 2) hardware
3739*4882a593Smuzhiyunstate; 3) changes to the GC ops.</para>
3740*4882a593Smuzhiyun<para>
3741*4882a593SmuzhiyunThe GC contains a serial number, which is loaded with a number fetched from
3742*4882a593Smuzhiyunthe window that was drawn into the last time the GC was used.  The serial
3743*4882a593Smuzhiyunnumber in the drawable is changed when the drawable's
3744*4882a593SmuzhiyunclipList or absCorner changes.  Thus, by
3745*4882a593Smuzhiyuncomparing the GC serial number with the drawable serial number, DIX can
3746*4882a593Smuzhiyunforce a validate if the drawable has been changed since the last time it
3747*4882a593Smuzhiyunwas used with this GC.</para>
3748*4882a593Smuzhiyun<para>
3749*4882a593SmuzhiyunIn addition, the drawable serial number is always guaranteed to have the
3750*4882a593Smuzhiyunmost significant bit set to 0.  Thus, the DDX layer can set the most
3751*4882a593Smuzhiyunsignificant bit of the serial number to 1 in a GC to force a validate the next time
3752*4882a593Smuzhiyunthe GC is used.  DIX also uses this technique to indicate that a change has
3753*4882a593Smuzhiyunbeen made to the GC by way of a SetGC, a SetDashes or a SetClip request.</para>
3754*4882a593Smuzhiyun</section>
3755*4882a593Smuzhiyun<section>
3756*4882a593Smuzhiyun  <title>GC Handling Routines</title>
3757*4882a593Smuzhiyun<para>
3758*4882a593SmuzhiyunThe ScreenRec data structure has a pointer for
3759*4882a593SmuzhiyunCreateGC().
3760*4882a593Smuzhiyun<blockquote><programlisting>
3761*4882a593Smuzhiyun
3762*4882a593Smuzhiyun	Bool pScreen->CreateGC(pGC)
3763*4882a593Smuzhiyun		GCPtr pGC;
3764*4882a593Smuzhiyun</programlisting></blockquote>
3765*4882a593SmuzhiyunThis routine must fill in the fields of
3766*4882a593Smuzhiyuna dynamically allocated GC that is passed in.
3767*4882a593SmuzhiyunIt does NOT allocate the GC record itself or fill
3768*4882a593Smuzhiyunin the defaults; DIX does that.</para>
3769*4882a593Smuzhiyun<para>
3770*4882a593SmuzhiyunThis must fill in both the GC funcs and ops; none of the drawing
3771*4882a593Smuzhiyunfunctions will be called before the GC has been validated,
3772*4882a593Smuzhiyunbut the others (dealing with allocating of clip regions,
3773*4882a593Smuzhiyunchanging and destroying the GC, etc.) might be.</para>
3774*4882a593Smuzhiyun<para>
3775*4882a593SmuzhiyunThe GC funcs vector contains pointers to 7
3776*4882a593Smuzhiyunroutines and a devPrivate field:
3777*4882a593Smuzhiyun<blockquote><programlisting>
3778*4882a593Smuzhiyun
3779*4882a593Smuzhiyun	pGC->funcs->ChangeGC(pGC, changes)
3780*4882a593Smuzhiyun		GCPtr pGC;
3781*4882a593Smuzhiyun		unsigned long changes;
3782*4882a593Smuzhiyun
3783*4882a593Smuzhiyun</programlisting></blockquote>
3784*4882a593SmuzhiyunThis GC func is called immediately after a field in the GC is changed.
3785*4882a593Smuzhiyunchanges is a bit mask indicating the changed fields of the GC in this
3786*4882a593Smuzhiyunrequest.</para>
3787*4882a593Smuzhiyun<para>
3788*4882a593SmuzhiyunThe ChangeGC routine is useful if you have a system where
3789*4882a593Smuzhiyunstate-changes to the GC can be swallowed immediately by your graphics
3790*4882a593Smuzhiyunsystem, and a validate is not necessary.</para>
3791*4882a593Smuzhiyun<para>
3792*4882a593Smuzhiyun<blockquote><programlisting>
3793*4882a593Smuzhiyun
3794*4882a593Smuzhiyun	pGC->funcs->ValidateGC(pGC, changes, pDraw)
3795*4882a593Smuzhiyun		GCPtr pGC;
3796*4882a593Smuzhiyun		unsigned long changes;
3797*4882a593Smuzhiyun		DrawablePtr pDraw;
3798*4882a593Smuzhiyun
3799*4882a593Smuzhiyun</programlisting></blockquote>
3800*4882a593SmuzhiyunValidateGC is called by DIX just before the GC will be used when one
3801*4882a593Smuzhiyunof many possible changes to the GC or the graphics system has
3802*4882a593Smuzhiyunhappened.  It can modify devPrivates data attached to the GC,
3803*4882a593Smuzhiyunchange the op vector, or change hardware according to the
3804*4882a593Smuzhiyunvalues in the GC.  It may not change the device-independent portion of
3805*4882a593Smuzhiyunthe GC itself.</para>
3806*4882a593Smuzhiyun<para>
3807*4882a593SmuzhiyunIn almost all cases, your ValidateGC() procedure should take the
3808*4882a593Smuzhiyunregions that drawing needs to be clipped to and combine them into a
3809*4882a593Smuzhiyuncomposite clip region, which you keep a pointer to in the private part
3810*4882a593Smuzhiyunof the GC.  In this way, your drawing primitive routines (and whatever
3811*4882a593Smuzhiyunis below them) can easily determine what to clip and where.  You
3812*4882a593Smuzhiyunshould combine the regions clientClip (the region that the client
3813*4882a593Smuzhiyundesires to clip output to) and the region returned by
3814*4882a593SmuzhiyunNotClippedByChildren(), in DIX.  An example is in Xserver/fb/fbgc.c.</para>
3815*4882a593Smuzhiyun<para>
3816*4882a593SmuzhiyunSome kinds of extension software may cause this routine to be called
3817*4882a593Smuzhiyunmore than originally intended; you should not rely on algorithms that
3818*4882a593Smuzhiyunwill break under such circumstances.</para>
3819*4882a593Smuzhiyun<para>
3820*4882a593SmuzhiyunSee the Strategies document for more information on creatively using
3821*4882a593Smuzhiyunthis routine.</para>
3822*4882a593Smuzhiyun<para>
3823*4882a593Smuzhiyun<blockquote><programlisting>
3824*4882a593Smuzhiyun
3825*4882a593Smuzhiyun	pGC->funcs->CopyGC(pGCSrc, mask, pGCDst)
3826*4882a593Smuzhiyun		GCPtr pGCSrc;
3827*4882a593Smuzhiyun		unsigned long mask;
3828*4882a593Smuzhiyun		GCPtr pGCDst;
3829*4882a593Smuzhiyun
3830*4882a593Smuzhiyun</programlisting></blockquote>
3831*4882a593SmuzhiyunThis routine is called by DIX when a GC is being copied to another GC.
3832*4882a593SmuzhiyunThis is for situations where dynamically allocated chunks of memory
3833*4882a593Smuzhiyunare stored in the GC's dynamic devPrivates and need to be transferred to
3834*4882a593Smuzhiyunthe destination GC.</para>
3835*4882a593Smuzhiyun<para>
3836*4882a593Smuzhiyun<blockquote><programlisting>
3837*4882a593Smuzhiyun
3838*4882a593Smuzhiyun	pGC->funcs->DestroyGC(pGC)
3839*4882a593Smuzhiyun		GCPtr pGC;
3840*4882a593Smuzhiyun
3841*4882a593Smuzhiyun</programlisting></blockquote>
3842*4882a593SmuzhiyunThis routine is called before the GC is destroyed for the
3843*4882a593Smuzhiyunentity interested in this GC to clean up after itself.
3844*4882a593SmuzhiyunThis routine is responsible for freeing any auxiliary storage allocated.</para>
3845*4882a593Smuzhiyun</section>
3846*4882a593Smuzhiyun<section>
3847*4882a593Smuzhiyun  <title>GC Clip Region Routines</title>
3848*4882a593Smuzhiyun<para>
3849*4882a593SmuzhiyunThe GC clientClip field requires three procedures to manage it.  These
3850*4882a593Smuzhiyunprocedures are in the GC funcs vector.  The underlying principle is that dix
3851*4882a593Smuzhiyunknows nothing about the internals of the clipping information, (except when
3852*4882a593Smuzhiyunit has come from the client), and so calls ddX whenever it needs to copy,
3853*4882a593Smuzhiyunset, or destroy such information.  It could have been possible for dix not
3854*4882a593Smuzhiyunto allow ddX to touch the field in the GC, and require it to keep its own
3855*4882a593Smuzhiyuncopy in devPriv, but since clip masks can be very large, this seems like a
3856*4882a593Smuzhiyunbad idea.  Thus, the server allows ddX to do whatever it wants to the
3857*4882a593SmuzhiyunclientClip field of the GC, but requires it to do all manipulation itself.</para>
3858*4882a593Smuzhiyun<para>
3859*4882a593Smuzhiyun<blockquote><programlisting>
3860*4882a593Smuzhiyun
3861*4882a593Smuzhiyun	void pGC->funcs->ChangeClip(pGC, type, pValue, nrects)
3862*4882a593Smuzhiyun		GCPtr pGC;
3863*4882a593Smuzhiyun		int type;
3864*4882a593Smuzhiyun		char *pValue;
3865*4882a593Smuzhiyun		int nrects;
3866*4882a593Smuzhiyun
3867*4882a593Smuzhiyun</programlisting></blockquote>
3868*4882a593SmuzhiyunThis routine is called whenever the client changes the client clip
3869*4882a593Smuzhiyunregion.  The pGC points to the GC involved, the type tells what form
3870*4882a593Smuzhiyunthe region has been sent in.  If type is CT_NONE, then there is no
3871*4882a593Smuzhiyunclient clip.  If type is CT_UNSORTED, CT_YBANDED or CT_YXBANDED, then
3872*4882a593SmuzhiyunpValue pointer to a list of rectangles, nrects long.  If type is
3873*4882a593SmuzhiyunCT_REGION, then pValue pointer to a RegionRec from the mi region code.
3874*4882a593SmuzhiyunIf type is CT_PIXMAP pValue is a pointer to a pixmap.  (The defines
3875*4882a593Smuzhiyunfor CT_NONE, etc. are in Xserver/include/gc.h.)  This routine is
3876*4882a593Smuzhiyunresponsible for incrementing any necessary reference counts (e.g. for
3877*4882a593Smuzhiyuna pixmap clip mask) for the new clipmask and freeing anything that
3878*4882a593Smuzhiyunused to be in the GC's clipMask field.  The lists of rectangles passed
3879*4882a593Smuzhiyunin can be freed with free(), the regions can be destroyed with the
3880*4882a593SmuzhiyunRegionDestroy field in the screen, and pixmaps can be destroyed by
3881*4882a593Smuzhiyuncalling the screen's DestroyPixmap function.  DIX and MI code expect
3882*4882a593Smuzhiyunwhat they pass in to this to be freed or otherwise inaccessible, and
3883*4882a593Smuzhiyunwill never look inside what's been put in the GC.  This is a good
3884*4882a593Smuzhiyunplace to be wary of storage leaks.</para>
3885*4882a593Smuzhiyun<para>
3886*4882a593SmuzhiyunIn the sample server, this routine transforms either the bitmap or the
3887*4882a593Smuzhiyunrectangle list into a region, so that future routines will have a more
3888*4882a593Smuzhiyunpredictable starting point to work from.  (The validate routine must
3889*4882a593Smuzhiyuntake this client clip region and merge it with other regions to arrive
3890*4882a593Smuzhiyunat a composite clip region before any drawing is done.)</para>
3891*4882a593Smuzhiyun<para>
3892*4882a593Smuzhiyun<blockquote><programlisting>
3893*4882a593Smuzhiyun
3894*4882a593Smuzhiyun	void pGC->funcs->DestroyClip(pGC)
3895*4882a593Smuzhiyun		GCPtr pGC;
3896*4882a593Smuzhiyun
3897*4882a593Smuzhiyun</programlisting></blockquote>
3898*4882a593SmuzhiyunThis routine is called whenever the client clip region must be destroyed.
3899*4882a593SmuzhiyunThe pGC points to the GC involved.  This call should set the clipType
3900*4882a593Smuzhiyunfield of the GC to CT_NONE.
3901*4882a593SmuzhiyunIn the sample server, the pointer to the client clip region is set to NULL
3902*4882a593Smuzhiyunby this routine after destroying the region, so that other software
3903*4882a593Smuzhiyun(including ChangeClip() above) will recognize that there is no client clip region.</para>
3904*4882a593Smuzhiyun<para>
3905*4882a593Smuzhiyun<blockquote><programlisting>
3906*4882a593Smuzhiyun
3907*4882a593Smuzhiyun	void pGC->funcs->CopyClip(pgcDst, pgcSrc)
3908*4882a593Smuzhiyun		GCPtr pgcDst, pgcSrc;
3909*4882a593Smuzhiyun
3910*4882a593Smuzhiyun</programlisting></blockquote>
3911*4882a593SmuzhiyunThis routine makes a copy of the clipMask and clipType from pgcSrc
3912*4882a593Smuzhiyuninto pgcDst.  It is responsible for destroying any previous clipMask
3913*4882a593Smuzhiyunin pgcDst.  The clip mask in the source can be the same as the
3914*4882a593Smuzhiyunclip mask in the dst (clients do the strangest things), so care must
3915*4882a593Smuzhiyunbe taken when destroying things.  This call is required because dix
3916*4882a593Smuzhiyundoes not know how to copy the clip mask from pgcSrc.</para>
3917*4882a593Smuzhiyun</section>
3918*4882a593Smuzhiyun</section>
3919*4882a593Smuzhiyun<section>
3920*4882a593Smuzhiyun  <title>Drawing Primitives</title>
3921*4882a593Smuzhiyun<para>
3922*4882a593SmuzhiyunThe X protocol (rules for the byte stream that goes between client and server)
3923*4882a593Smuzhiyundoes all graphics using primitive
3924*4882a593Smuzhiyunoperations, which are called Drawing Primitives.
3925*4882a593SmuzhiyunThese include line drawing, area filling, arcs, and text drawing.
3926*4882a593SmuzhiyunYour implementation must supply 16 routines
3927*4882a593Smuzhiyunto perform these on your hardware.
3928*4882a593Smuzhiyun(The number 16 is arbitrary.)</para>
3929*4882a593Smuzhiyun<para>
3930*4882a593SmuzhiyunMore specifically, 16 procedure pointers are in each
3931*4882a593SmuzhiyunGC op vector.
3932*4882a593SmuzhiyunAt any given time, ALL of them MUST point to a valid procedure that
3933*4882a593Smuzhiyunattempts to do the operation assigned, although
3934*4882a593Smuzhiyunthe procedure pointers may change and may
3935*4882a593Smuzhiyunpoint to different procedures to carry out the same operation.
3936*4882a593SmuzhiyunA simple server will leave them all pointing to the same 16 routines, while
3937*4882a593Smuzhiyuna more optimized implementation will switch each from one
3938*4882a593Smuzhiyunprocedure to another, depending upon what is most optimal
3939*4882a593Smuzhiyunfor the current GC and drawable.</para>
3940*4882a593Smuzhiyun<para>
3941*4882a593SmuzhiyunThe sample server contains a considerable chunk of code called the
3942*4882a593Smuzhiyunmi (machine independent)
3943*4882a593Smuzhiyunroutines, which serve as drawing primitive routines.
3944*4882a593SmuzhiyunMany server implementations will be able to use these as-is,
3945*4882a593Smuzhiyunbecause they work for arbitrary depths.
3946*4882a593SmuzhiyunThey make no assumptions about the formats of pixmaps
3947*4882a593Smuzhiyunand frame buffers, since they call a set of routines
3948*4882a593Smuzhiyunknown as the "Pixblit Routines" (see next section).
3949*4882a593SmuzhiyunThey do assume that the way to draw is
3950*4882a593Smuzhiyunthrough these low-level routines that apply pixel values rows at a time.
3951*4882a593SmuzhiyunIf your hardware or firmware gives more performance when
3952*4882a593Smuzhiyunthings are done differently, you will want to take this fact into account
3953*4882a593Smuzhiyunand rewrite some or all of the drawing primitives to fit your needs.</para>
3954*4882a593Smuzhiyun<section>
3955*4882a593Smuzhiyun  <title>GC Components</title>
3956*4882a593Smuzhiyun<para>
3957*4882a593SmuzhiyunThis section describes the fields in the GC that affect each drawing primitive.
3958*4882a593SmuzhiyunThe only primitive that is not affected is GetImage, which does not use a GC
3959*4882a593Smuzhiyunbecause its destination is a protocol-style bit image.
3960*4882a593SmuzhiyunSince each drawing primitive mirrors exactly the X protocol request of the
3961*4882a593Smuzhiyunsame name, you should refer to the X protocol specification document
3962*4882a593Smuzhiyunfor more details.</para>
3963*4882a593Smuzhiyun<para>
3964*4882a593SmuzhiyunALL of these routines MUST CLIP to the
3965*4882a593Smuzhiyunappropriate regions in the drawable.
3966*4882a593SmuzhiyunSince there are many regions to clip to simultaneously,
3967*4882a593Smuzhiyunyour ValidateGC routine should combine these into a unified
3968*4882a593Smuzhiyunclip region to which your drawing routines can quickly refer.
3969*4882a593SmuzhiyunThis is exactly what the fb routines supplied with the sample server
3970*4882a593Smuzhiyundo.
3971*4882a593SmuzhiyunThe mi implementation passes responsibility for clipping while drawing
3972*4882a593Smuzhiyundown to the Pixblit routines.</para>
3973*4882a593Smuzhiyun<para>
3974*4882a593SmuzhiyunAlso, all of them must adhere to the current plane mask.
3975*4882a593SmuzhiyunThe plane mask has one bit for every bit plane in the drawable;
3976*4882a593Smuzhiyunonly planes with 1 bits in the mask are affected by any drawing operation.</para>
3977*4882a593Smuzhiyun<para>
3978*4882a593SmuzhiyunAll functions except for ImageText calls must obey the alu function.
3979*4882a593SmuzhiyunThis is usually Copy, but could be any of the allowable 16 raster-ops.</para>
3980*4882a593Smuzhiyun<para>
3981*4882a593SmuzhiyunAll of the functions, except for CopyArea, might use the current
3982*4882a593Smuzhiyunforeground and background pixel values.
3983*4882a593SmuzhiyunEach pixel value is 32 bits.
3984*4882a593SmuzhiyunThese correspond to foreground and background colors, but you have
3985*4882a593Smuzhiyunto run them through the colormap to find out what color the pixel values
3986*4882a593Smuzhiyunrepresent.  Do not worry about the color, just apply the pixel value.</para>
3987*4882a593Smuzhiyun<para>
3988*4882a593SmuzhiyunThe routines that draw lines (PolyLine, PolySegment, PolyRect, and PolyArc)
3989*4882a593Smuzhiyunuse the line width, line style, cap style, and join style.
3990*4882a593SmuzhiyunLine width is in pixels.
3991*4882a593SmuzhiyunThe line style specifies whether it is solid or dashed, and what kind of dash.
3992*4882a593SmuzhiyunThe cap style specifies whether Rounded, Butt, etc.
3993*4882a593SmuzhiyunThe join style specifies whether joins between joined lines are Miter, Round or Beveled.
3994*4882a593SmuzhiyunWhen lines cross as part of the same polyline, they are assumed to be drawn once.
3995*4882a593Smuzhiyun(See the X protocol specification for more details.)</para>
3996*4882a593Smuzhiyun<para>
3997*4882a593SmuzhiyunZero-width lines are NOT meant to be really zero width; this is the client's way
3998*4882a593Smuzhiyunof telling you that you can optimize line drawing with little regard to
3999*4882a593Smuzhiyunthe end caps and joins.
4000*4882a593SmuzhiyunThey are called "thin" lines and are meant to be one pixel wide.
4001*4882a593SmuzhiyunThese are frequently done in hardware or in a streamlined assembly language
4002*4882a593Smuzhiyunroutine.</para>
4003*4882a593Smuzhiyun<para>
4004*4882a593SmuzhiyunLines with widths greater than zero, though, must all be drawn with the same
4005*4882a593Smuzhiyunalgorithm, because client software assumes that every jag on every
4006*4882a593Smuzhiyunline at an angle will come at the same place.
4007*4882a593SmuzhiyunTwo lines that should have
4008*4882a593Smuzhiyunone pixel in the space between them
4009*4882a593Smuzhiyun(because of their distance apart and their widths) should have such a one-pixel line
4010*4882a593Smuzhiyunof space between them if drawn, regardless of angle.</para>
4011*4882a593Smuzhiyun<para>
4012*4882a593SmuzhiyunThe solid area fill routines (FillPolygon, PolyFillRect, PolyFillArc)
4013*4882a593Smuzhiyunall use the fill rule, which specifies subtle interpretations of
4014*4882a593Smuzhiyunwhat points are inside and what are outside of a given polygon.
4015*4882a593SmuzhiyunThe PolyFillArc routine also uses the arc mode, which specifies
4016*4882a593Smuzhiyunwhether to fill pie segments or single-edge slices of an ellipse.</para>
4017*4882a593Smuzhiyun<para>
4018*4882a593SmuzhiyunThe line drawing, area fill, and PolyText routines must all
4019*4882a593Smuzhiyunapply the correct "fill style."
4020*4882a593SmuzhiyunThis can be either a solid foreground color, a transparent stipple,
4021*4882a593Smuzhiyunan opaque stipple, or a tile.
4022*4882a593SmuzhiyunStipples are bitmaps where the 1 bits represent that the foreground color is written,
4023*4882a593Smuzhiyunand 0 bits represent that either the pixel is left alone (transparent) or that
4024*4882a593Smuzhiyunthe background color is written (opaque).
4025*4882a593SmuzhiyunA tile is a pixmap of the full depth of the GC that is applied in its full glory to all areas.
4026*4882a593SmuzhiyunThe stipple and tile patterns can be any rectangular size, although some implementations
4027*4882a593Smuzhiyunwill be faster for certain sizes such as 8x8 or 32x32.
4028*4882a593SmuzhiyunThe mi implementation passes this responsibility down to the Pixblit routines.</para>
4029*4882a593Smuzhiyun<para>
4030*4882a593SmuzhiyunSee the X protocol document for full details.
4031*4882a593SmuzhiyunThe description of the CreateGC request has a very good, detailed description of these
4032*4882a593Smuzhiyunattributes.</para>
4033*4882a593Smuzhiyun</section>
4034*4882a593Smuzhiyun<section>
4035*4882a593Smuzhiyun<title>The Primitives</title>
4036*4882a593Smuzhiyun<para>
4037*4882a593SmuzhiyunThe Drawing Primitives are as follows:
4038*4882a593Smuzhiyun
4039*4882a593Smuzhiyun<blockquote><programlisting>
4040*4882a593Smuzhiyun
4041*4882a593Smuzhiyun	RegionPtr pGC->ops->CopyArea(src, dst, pGC, srcx, srcy, w, h, dstx, dsty)
4042*4882a593Smuzhiyun		DrawablePtr dst, src;
4043*4882a593Smuzhiyun		GCPtr pGC;
4044*4882a593Smuzhiyun		int srcx, srcy, w, h, dstx, dsty;
4045*4882a593Smuzhiyun
4046*4882a593Smuzhiyun</programlisting></blockquote>
4047*4882a593SmuzhiyunCopyArea copies a rectangle of pixels from one drawable to another of
4048*4882a593Smuzhiyunthe same depth.  To effect scrolling, this must be able to copy from
4049*4882a593Smuzhiyunany drawable to itself, overlapped.  No squeezing or stretching is done
4050*4882a593Smuzhiyunbecause the source and destination are the same size.  However,
4051*4882a593Smuzhiyuneverything is still clipped to the clip regions of the destination
4052*4882a593Smuzhiyundrawable.</para>
4053*4882a593Smuzhiyun<para>
4054*4882a593SmuzhiyunIf pGC->graphicsExposures is True, any portions of the destination which
4055*4882a593Smuzhiyunwere not valid in the source (either occluded by covering windows, or
4056*4882a593Smuzhiyunoutside the bounds of the drawable) should be collected together and
4057*4882a593Smuzhiyunreturned as a region (if this resultant region is empty, NULL can be
4058*4882a593Smuzhiyunreturned instead).  Furthermore, the invalid bits of the source are
4059*4882a593Smuzhiyunnot copied to the destination and (when the destination is a window)
4060*4882a593Smuzhiyunare filled with the background tile.  The sample routine
4061*4882a593SmuzhiyunmiHandleExposures generates the appropriate return value and fills the
4062*4882a593Smuzhiyuninvalid area using pScreen->PaintWindowBackground.</para>
4063*4882a593Smuzhiyun<para>
4064*4882a593SmuzhiyunFor instance, imagine a window that is partially obscured by other
4065*4882a593Smuzhiyunwindows in front of it.  As text is scrolled on your window, the pixels
4066*4882a593Smuzhiyunthat are scrolled out from under obscuring windows will not be
4067*4882a593Smuzhiyunavailable on the screen to copy to the right places, and so an exposure
4068*4882a593Smuzhiyunevent must be sent for the client to correctly repaint them.  Of
4069*4882a593Smuzhiyuncourse, if you implement backing store, you could do this without resorting
4070*4882a593Smuzhiyunto exposure events.</para>
4071*4882a593Smuzhiyun<para>
4072*4882a593SmuzhiyunAn example implementation is fbCopyArea() in Xserver/fb/fbcopy.c.</para>
4073*4882a593Smuzhiyun<para>
4074*4882a593Smuzhiyun<blockquote><programlisting>
4075*4882a593Smuzhiyun
4076*4882a593Smuzhiyun	RegionPtr pGC->ops->CopyPlane(src, dst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
4077*4882a593Smuzhiyun		DrawablePtr dst, src;
4078*4882a593Smuzhiyun		GCPtr pGC;
4079*4882a593Smuzhiyun		int srcx, srcy, w, h, dstx, dsty;
4080*4882a593Smuzhiyun		unsigned long plane;
4081*4882a593Smuzhiyun
4082*4882a593Smuzhiyun</programlisting></blockquote>
4083*4882a593SmuzhiyunCopyPlane must copy one plane of a rectangle from the source drawable
4084*4882a593Smuzhiyunonto the destination drawable.  Because this routine only copies one
4085*4882a593Smuzhiyunbit out of each pixel, it can copy between drawables of different
4086*4882a593Smuzhiyundepths.  This is the only way of copying between drawables of
4087*4882a593Smuzhiyundifferent depths, except for copying bitmaps to pixmaps and applying
4088*4882a593Smuzhiyunforeground and background colors to it.  All other conditions of
4089*4882a593SmuzhiyunCopyArea apply to CopyPlane too.</para>
4090*4882a593Smuzhiyun<para>
4091*4882a593SmuzhiyunAn example implementation is fbCopyPlane() in
4092*4882a593SmuzhiyunXserver/fb/fbcopy.c.</para>
4093*4882a593Smuzhiyun<para>
4094*4882a593Smuzhiyun<blockquote><programlisting>
4095*4882a593Smuzhiyun
4096*4882a593Smuzhiyun	void pGC->ops->PolyPoint(dst, pGC, mode, n, pPoint)
4097*4882a593Smuzhiyun		DrawablePtr dst;
4098*4882a593Smuzhiyun		GCPtr pGC;
4099*4882a593Smuzhiyun		int mode;
4100*4882a593Smuzhiyun		int n;
4101*4882a593Smuzhiyun		DDXPointPtr pPoint;
4102*4882a593Smuzhiyun
4103*4882a593Smuzhiyun</programlisting></blockquote>
4104*4882a593SmuzhiyunPolyPoint draws a set of one-pixel dots (foreground color)
4105*4882a593Smuzhiyunat the locations given in the array.
4106*4882a593Smuzhiyunmode is one of the defined constants Origin (absolute coordinates) or Previous
4107*4882a593Smuzhiyun(each coordinate is relative to the last).
4108*4882a593SmuzhiyunNote that this does not use the background color or any tiles or stipples.</para>
4109*4882a593Smuzhiyun<para>
4110*4882a593SmuzhiyunExample implementations are fbPolyPoint() in Xserver/fb/fbpoint.c and
4111*4882a593SmuzhiyunmiPolyPoint in Xserver/mi/mipolypnt.c.</para>
4112*4882a593Smuzhiyun<para>
4113*4882a593Smuzhiyun<blockquote><programlisting>
4114*4882a593Smuzhiyun
4115*4882a593Smuzhiyun	void pGC->ops->Polylines(dst, pGC, mode, n, pPoint)
4116*4882a593Smuzhiyun		DrawablePtr dst;
4117*4882a593Smuzhiyun		GCPtr pGC;
4118*4882a593Smuzhiyun		int mode;
4119*4882a593Smuzhiyun		int n;
4120*4882a593Smuzhiyun		DDXPointPtr pPoint;
4121*4882a593Smuzhiyun
4122*4882a593Smuzhiyun</programlisting></blockquote>
4123*4882a593SmuzhiyunSimilar to PolyPoint, Polylines draws lines between the locations given in the array.
4124*4882a593SmuzhiyunZero-width lines are NOT meant to be really zero width; this is the client's way of
4125*4882a593Smuzhiyuntelling you that you can maximally optimize line drawing with little regard to
4126*4882a593Smuzhiyunthe end caps and joins.
4127*4882a593Smuzhiyunmode is one of the defined constants Previous or Origin, depending upon
4128*4882a593Smuzhiyunwhether the points are each relative to the last or are absolute.</para>
4129*4882a593Smuzhiyun<para>
4130*4882a593SmuzhiyunExample implementations are miWideLine() and miWideDash() in
4131*4882a593Smuzhiyunmi/miwideline.c and miZeroLine() in mi/mizerline.c.</para>
4132*4882a593Smuzhiyun<para>
4133*4882a593Smuzhiyun<blockquote><programlisting>
4134*4882a593Smuzhiyun
4135*4882a593Smuzhiyun	void pGC->ops->PolySegment(dst, pGC, n, pPoint)
4136*4882a593Smuzhiyun		DrawablePtr dst;
4137*4882a593Smuzhiyun		GCPtr pGC;
4138*4882a593Smuzhiyun		int n;
4139*4882a593Smuzhiyun		xSegment *pSegments;
4140*4882a593Smuzhiyun
4141*4882a593Smuzhiyun</programlisting></blockquote>
4142*4882a593SmuzhiyunPolySegments draws unconnected
4143*4882a593Smuzhiyunlines between pairs of points in the array; the array must be of
4144*4882a593Smuzhiyuneven size; no interconnecting lines are drawn.</para>
4145*4882a593Smuzhiyun<para>
4146*4882a593SmuzhiyunAn example implementation is miPolySegment() in mipolyseg.c.</para>
4147*4882a593Smuzhiyun<para>
4148*4882a593Smuzhiyun<blockquote><programlisting>
4149*4882a593Smuzhiyun
4150*4882a593Smuzhiyun	void pGC->ops->PolyRectangle(dst, pGC, n, pRect)
4151*4882a593Smuzhiyun		DrawablePtr dst;
4152*4882a593Smuzhiyun		GCPtr pGC;
4153*4882a593Smuzhiyun		int n;
4154*4882a593Smuzhiyun		xRectangle *pRect;
4155*4882a593Smuzhiyun
4156*4882a593Smuzhiyun</programlisting></blockquote>
4157*4882a593SmuzhiyunPolyRectangle draws outlines of rectangles for each rectangle in the array.</para>
4158*4882a593Smuzhiyun<para>
4159*4882a593SmuzhiyunAn example implementation is miPolyRectangle() in Xserver/mi/mipolyrect.c.</para>
4160*4882a593Smuzhiyun<para>
4161*4882a593Smuzhiyun<blockquote><programlisting>
4162*4882a593Smuzhiyun
4163*4882a593Smuzhiyun	void pGC->ops->PolyArc(dst, pGC, n, pArc)
4164*4882a593Smuzhiyun		DrawablePtr dst;
4165*4882a593Smuzhiyun		GCPtr pGC;
4166*4882a593Smuzhiyun		int n;
4167*4882a593Smuzhiyun		xArc*pArc;
4168*4882a593Smuzhiyun
4169*4882a593Smuzhiyun</programlisting></blockquote>
4170*4882a593SmuzhiyunPolyArc draws connected conic arcs according to the descriptions in the array.
4171*4882a593SmuzhiyunSee the protocol specification for more details.</para>
4172*4882a593Smuzhiyun<para>
4173*4882a593SmuzhiyunExample implementations are miZeroPolyArc in Xserver/mi/mizerarc. and
4174*4882a593SmuzhiyunmiPolyArc() in Xserver/mi/miarc.c.</para>
4175*4882a593Smuzhiyun<para>
4176*4882a593Smuzhiyun<blockquote><programlisting>
4177*4882a593Smuzhiyun
4178*4882a593Smuzhiyun	void pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pPoint)
4179*4882a593Smuzhiyun		DrawablePtr dst;
4180*4882a593Smuzhiyun		GCPtr pGC;
4181*4882a593Smuzhiyun		int shape;
4182*4882a593Smuzhiyun		int mode;
4183*4882a593Smuzhiyun		int count;
4184*4882a593Smuzhiyun		DDXPointPtr pPoint;
4185*4882a593Smuzhiyun
4186*4882a593Smuzhiyun</programlisting></blockquote>
4187*4882a593SmuzhiyunFillPolygon fills a polygon specified by the points in the array
4188*4882a593Smuzhiyunwith the appropriate fill style.
4189*4882a593SmuzhiyunIf necessary, an extra border line is assumed between the starting and ending lines.
4190*4882a593SmuzhiyunThe shape can be used as a hint
4191*4882a593Smuzhiyunto optimize filling; it indicates whether it is convex (all interior angles
4192*4882a593Smuzhiyunless than 180), nonconvex (some interior angles greater than 180 but
4193*4882a593Smuzhiyunborder does not cross itself), or complex (border crosses itself).
4194*4882a593SmuzhiyunYou can choose appropriate algorithms or hardware based upon mode.
4195*4882a593Smuzhiyunmode is one of the defined constants Previous or Origin, depending upon
4196*4882a593Smuzhiyunwhether the points are each relative to the last or are absolute.</para>
4197*4882a593Smuzhiyun<para>
4198*4882a593SmuzhiyunAn example implementation is miFillPolygon() in Xserver/mi/mipoly.c.</para>
4199*4882a593Smuzhiyun<para>
4200*4882a593Smuzhiyun<blockquote><programlisting>
4201*4882a593Smuzhiyun
4202*4882a593Smuzhiyun	void pGC->ops->PolyFillRect(dst, pGC, n, pRect)
4203*4882a593Smuzhiyun		DrawablePtr dst;
4204*4882a593Smuzhiyun		GCPtr pGC;
4205*4882a593Smuzhiyun		int n;
4206*4882a593Smuzhiyun		xRectangle *pRect;
4207*4882a593Smuzhiyun
4208*4882a593Smuzhiyun</programlisting></blockquote>
4209*4882a593SmuzhiyunPolyFillRect fills multiple rectangles.</para>
4210*4882a593Smuzhiyun<para>
4211*4882a593SmuzhiyunExample implementations are fbPolyFillRect() in Xserver/fb/fbfillrect.c and
4212*4882a593SmuzhiyunmiPolyFillRect() in Xserver/mi/mifillrct.c.</para>
4213*4882a593Smuzhiyun<para>
4214*4882a593Smuzhiyun<blockquote><programlisting>
4215*4882a593Smuzhiyun
4216*4882a593Smuzhiyun	void pGC->ops->PolyFillArc(dst, pGC, n, pArc)
4217*4882a593Smuzhiyun		DrawablePtr dst;
4218*4882a593Smuzhiyun		GCPtr pGC;
4219*4882a593Smuzhiyun		int n;
4220*4882a593Smuzhiyun		xArc *pArc;
4221*4882a593Smuzhiyun
4222*4882a593Smuzhiyun</programlisting></blockquote>
4223*4882a593SmuzhiyunPolyFillArc fills a shape for each arc in the
4224*4882a593Smuzhiyunlist that is bounded by the arc and one or two
4225*4882a593Smuzhiyunline segments with the current fill style.</para>
4226*4882a593Smuzhiyun<para>
4227*4882a593SmuzhiyunAn example implementation is miPolyFillArc() in Xserver/mi/mifillarc.c.</para>
4228*4882a593Smuzhiyun<para>
4229*4882a593Smuzhiyun<blockquote><programlisting>
4230*4882a593Smuzhiyun
4231*4882a593Smuzhiyun	void pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBinImage)
4232*4882a593Smuzhiyun		DrawablePtr dst;
4233*4882a593Smuzhiyun		GCPtr pGC;
4234*4882a593Smuzhiyun		int x, y, w, h;
4235*4882a593Smuzhiyun		int format;
4236*4882a593Smuzhiyun		char *pBinImage;
4237*4882a593Smuzhiyun
4238*4882a593Smuzhiyun</programlisting></blockquote>
4239*4882a593SmuzhiyunPutImage copies a pixmap image into the drawable.  The pixmap image
4240*4882a593Smuzhiyunmust be in X protocol format (either Bitmap, XYPixmap, or ZPixmap),
4241*4882a593Smuzhiyunand format tells the format.  (See the X protocol specification for
4242*4882a593Smuzhiyundetails on these formats).  You must be able to accept all three
4243*4882a593Smuzhiyunformats, because the client gets to decide which format to send.
4244*4882a593SmuzhiyunEither the drawable and the pixmap image have the same depth, or the
4245*4882a593Smuzhiyunsource pixmap image must be a Bitmap.  If a Bitmap, the foreground and
4246*4882a593Smuzhiyunbackground colors will be applied to the destination.</para>
4247*4882a593Smuzhiyun<para>
4248*4882a593SmuzhiyunAn example implementation is fbPutImage() in Xserver/fb/fbimage.c.</para>
4249*4882a593Smuzhiyun<para>
4250*4882a593Smuzhiyun<blockquote><programlisting>
4251*4882a593Smuzhiyun
4252*4882a593Smuzhiyun	void pScreen->GetImage(src, x, y, w, h, format, planeMask, pBinImage)
4253*4882a593Smuzhiyun		 DrawablePtr src;
4254*4882a593Smuzhiyun		 int x, y, w, h;
4255*4882a593Smuzhiyun		 unsigned int format;
4256*4882a593Smuzhiyun		 unsigned long planeMask;
4257*4882a593Smuzhiyun		 char *pBinImage;
4258*4882a593Smuzhiyun
4259*4882a593Smuzhiyun</programlisting></blockquote>
4260*4882a593SmuzhiyunGetImage copies the bits from the source drawable into
4261*4882a593Smuzhiyunthe destination pointer.  The bits are written into the buffer
4262*4882a593Smuzhiyunaccording to the server-defined pixmap padding rules.
4263*4882a593SmuzhiyunpBinImage is guaranteed to be big enough to hold all
4264*4882a593Smuzhiyunthe bits that must be written.</para>
4265*4882a593Smuzhiyun<para>
4266*4882a593SmuzhiyunThis routine does not correspond exactly to the X protocol GetImage
4267*4882a593Smuzhiyunrequest, since DIX has to break the reply up into buffers of a size
4268*4882a593Smuzhiyunrequested by the transport layer.  If format is ZPixmap, the bits are
4269*4882a593Smuzhiyunwritten in the ZFormat for the depth of the drawable; if there is a 0
4270*4882a593Smuzhiyunbit in the planeMask for a particular plane, all pixels must have the
4271*4882a593Smuzhiyunbit in that plane equal to 0.  If format is XYPixmap, planemask is
4272*4882a593Smuzhiyunguaranteed to have a single bit set; the bits should be written in
4273*4882a593SmuzhiyunBitmap format, which is the format for a single plane of an XYPixmap.</para>
4274*4882a593Smuzhiyun<para>
4275*4882a593SmuzhiyunAn example implementation is miGetImage() in Xserver/mi/mibitblt.c.
4276*4882a593Smuzhiyun<blockquote><programlisting>
4277*4882a593Smuzhiyun
4278*4882a593Smuzhiyun	void pGC->ops->ImageText8(pDraw, pGC, x, y, count, chars)
4279*4882a593Smuzhiyun		DrawablePtr pDraw;
4280*4882a593Smuzhiyun		GCPtr pGC;
4281*4882a593Smuzhiyun		int x, y;
4282*4882a593Smuzhiyun		int count;
4283*4882a593Smuzhiyun		char *chars;
4284*4882a593Smuzhiyun
4285*4882a593Smuzhiyun</programlisting></blockquote>
4286*4882a593SmuzhiyunImageText8 draws text.  The text is drawn in the foreground color; the
4287*4882a593Smuzhiyunbackground color fills the remainder of the character rectangles.  The
4288*4882a593Smuzhiyuncoordinates specify the baseline and start of the text.</para>
4289*4882a593Smuzhiyun<para>
4290*4882a593SmuzhiyunAn example implementation is miImageText8() in Xserver/mi/mipolytext.c.</para>
4291*4882a593Smuzhiyun<para>
4292*4882a593Smuzhiyun<blockquote><programlisting>
4293*4882a593Smuzhiyun
4294*4882a593Smuzhiyun	int pGC->ops->PolyText8(pDraw, pGC, x, y, count, chars)
4295*4882a593Smuzhiyun		DrawablePtr pDraw;
4296*4882a593Smuzhiyun		GCPtr pGC;
4297*4882a593Smuzhiyun		int x, y;
4298*4882a593Smuzhiyun		int count;
4299*4882a593Smuzhiyun		char *chars;
4300*4882a593Smuzhiyun
4301*4882a593Smuzhiyun</programlisting></blockquote>
4302*4882a593SmuzhiyunPolyText8 works like ImageText8, except it draws with
4303*4882a593Smuzhiyunthe current fill style for special effects such as
4304*4882a593Smuzhiyunshaded text.
4305*4882a593SmuzhiyunSee the X protocol specification for more details.</para>
4306*4882a593Smuzhiyun<para>
4307*4882a593SmuzhiyunAn example implementation is miPolyText8() in Xserver/mi/mipolytext.c.</para>
4308*4882a593Smuzhiyun<para>
4309*4882a593Smuzhiyun<blockquote><programlisting>
4310*4882a593Smuzhiyun
4311*4882a593Smuzhiyun	int pGC->ops->PolyText16(pDraw, pGC, x, y, count, chars)
4312*4882a593Smuzhiyun		DrawablePtr pDraw;
4313*4882a593Smuzhiyun		GCPtr pGC;
4314*4882a593Smuzhiyun		int x, y;
4315*4882a593Smuzhiyun		int count;
4316*4882a593Smuzhiyun		unsigned short *chars;
4317*4882a593Smuzhiyun
4318*4882a593Smuzhiyun	void pGC->ops->ImageText16(pDraw, pGC, x, y, count, chars)
4319*4882a593Smuzhiyun		DrawablePtr pDraw;
4320*4882a593Smuzhiyun		GCPtr pGC;
4321*4882a593Smuzhiyun		int x, y;
4322*4882a593Smuzhiyun		int count;
4323*4882a593Smuzhiyun		unsigned short *chars;
4324*4882a593Smuzhiyun
4325*4882a593Smuzhiyun</programlisting></blockquote>
4326*4882a593SmuzhiyunThese two routines are the same as the "8" versions,
4327*4882a593Smuzhiyunexcept that they are for 16-bit character codes (useful
4328*4882a593Smuzhiyunfor oriental writing systems).</para>
4329*4882a593Smuzhiyun<para>
4330*4882a593SmuzhiyunThe primary difference is in the way the character information is
4331*4882a593Smuzhiyunlooked up.  The 8-bit and the 16-bit versions obviously have different
4332*4882a593Smuzhiyunkinds of character values to look up; the main goal of the lookup is
4333*4882a593Smuzhiyunto provide a pointer to the CharInfo structs for the characters to
4334*4882a593Smuzhiyundraw and to pass these pointers to the Glyph routines.  Given a
4335*4882a593SmuzhiyunCharInfo struct, lower-level software can draw the glyph desired with
4336*4882a593Smuzhiyunlittle concern for other characteristics of the font.</para>
4337*4882a593Smuzhiyun<para>
4338*4882a593Smuzhiyun16-bit character fonts have a row-and-column scheme, where the 2bytes
4339*4882a593Smuzhiyunof the character code constitute the row and column in a square matrix
4340*4882a593Smuzhiyunof CharInfo structs.  Each font has row and column minimum and maximum
4341*4882a593Smuzhiyunvalues; the CharInfo structures form a two-dimensional matrix.</para>
4342*4882a593Smuzhiyun<para>
4343*4882a593SmuzhiyunExample implementations are miPolyText16() and
4344*4882a593SmuzhiyunmiImageText16() in Xserver/mi/mipolytext.c.</para>
4345*4882a593Smuzhiyun<para>
4346*4882a593SmuzhiyunSee the X protocol specification for more details on these graphic operations.</para>
4347*4882a593Smuzhiyun<para>
4348*4882a593SmuzhiyunThere is a hook in the GC ops, called LineHelper, that used to be used in the
4349*4882a593Smuzhiyunsample implementation by the code for wide lines.  It no longer servers any
4350*4882a593Smuzhiyunpurpose in the sample servers, but still exists, #ifdef'ed by NEED_LINEHELPER,
4351*4882a593Smuzhiyunin case someone needs it.</para>
4352*4882a593Smuzhiyun</section>
4353*4882a593Smuzhiyun</section>
4354*4882a593Smuzhiyun<section>
4355*4882a593Smuzhiyun  <title>Pixblit Procedures</title>
4356*4882a593Smuzhiyun<para>
4357*4882a593SmuzhiyunThe Drawing Primitive functions must be defined for your server.
4358*4882a593SmuzhiyunOne possible way to do this is to use the mi routines from the sample server.
4359*4882a593SmuzhiyunIf you choose to use the mi routines (even part of them!) you must implement
4360*4882a593Smuzhiyunthese Pixblit routines.
4361*4882a593SmuzhiyunThese routines read and write pixel values
4362*4882a593Smuzhiyunand deal directly with the image data.</para>
4363*4882a593Smuzhiyun<para>
4364*4882a593SmuzhiyunThe Pixblit routines for the sample server are part of the "fb"
4365*4882a593Smuzhiyunroutines.  As with the mi routines, the fb routines are
4366*4882a593Smuzhiyunportable but are not as portable as the mi routines.</para>
4367*4882a593Smuzhiyun<para>
4368*4882a593SmuzhiyunThe fb subsystem is a depth-independent framebuffer core, capable of
4369*4882a593Smuzhiyunoperating at any depth from 1 to 32, based on the depth of the window
4370*4882a593Smuzhiyunor pixmap it is currently operating on.  In particular, this means it
4371*4882a593Smuzhiyuncan support pixmaps of multiple depths on the same screen.  It supplies
4372*4882a593Smuzhiyunboth Pixblit routines and higher-level optimized implementations of the
4373*4882a593SmuzhiyunDrawing Primitive routines.  It does make the assumption that the pixel
4374*4882a593Smuzhiyundata it touches is available in the server's address space.</para>
4375*4882a593Smuzhiyun<para>
4376*4882a593SmuzhiyunIn other words, if you have a "normal" frame buffer type display, you
4377*4882a593Smuzhiyuncan probably use the fb code, and the mi code.  If you
4378*4882a593Smuzhiyunhave a stranger hardware, you will have to supply your own Pixblit
4379*4882a593Smuzhiyunroutines, but you can use the mi routines on top of them.  If you have
4380*4882a593Smuzhiyunbetter ways of doing some of the Drawing Primitive functions, then you
4381*4882a593Smuzhiyunmay want to supply some of your own Drawing Primitive routines.  (Even
4382*4882a593Smuzhiyunpeople who write their own Drawing Primitives save at least some of
4383*4882a593Smuzhiyunthe mi code for certain special cases that their hardware or library
4384*4882a593Smuzhiyunor fancy algorithm does not handle.)</para>
4385*4882a593Smuzhiyun<para>
4386*4882a593SmuzhiyunThe client, DIX, and the machine-independent routines do not carry the
4387*4882a593Smuzhiyunfinal responsibility of clipping.  They all depend upon the Pixblit
4388*4882a593Smuzhiyunroutines to do their clipping for them.  The rule is, if you touch the
4389*4882a593Smuzhiyunframe buffer, you clip.</para>
4390*4882a593Smuzhiyun<para>
4391*4882a593Smuzhiyun(The higher level routines may decide to clip at a high level, but
4392*4882a593Smuzhiyunthis is only for increased performance and cannot substitute for
4393*4882a593Smuzhiyunbottom-level clipping.  For instance, the mi routines, DIX, or the
4394*4882a593Smuzhiyunclient may decide to check all character strings to be drawn and chop
4395*4882a593Smuzhiyunoff all characters that would not be displayed.  If so, it must retain
4396*4882a593Smuzhiyunthe character on the edge that is partly displayed so that the Pixblit
4397*4882a593Smuzhiyunroutines can clip off precisely at the right place.)</para>
4398*4882a593Smuzhiyun<para>
4399*4882a593SmuzhiyunTo make this easier, all of the reasons to clip can be combined into
4400*4882a593Smuzhiyunone region in your ValidateGC procedure.  You take this composite clip
4401*4882a593Smuzhiyunregion with you into the Pixblit routines.  (The sample server does
4402*4882a593Smuzhiyunthis.)</para>
4403*4882a593Smuzhiyun<para>
4404*4882a593SmuzhiyunAlso, FillSpans() has to apply tile and stipple patterns.  The
4405*4882a593Smuzhiyunpatterns are all aligned to the window origin so that when two people
4406*4882a593Smuzhiyunwrite patches that are contiguous, they will merge nicely.  (Really,
4407*4882a593Smuzhiyunthey are aligned to the patOrg point in the GC.  This defaults to (0,
4408*4882a593Smuzhiyun0) but can be set by the client to anything.)</para>
4409*4882a593Smuzhiyun<para>
4410*4882a593SmuzhiyunHowever, the mi routines can translate (relocate) the points from
4411*4882a593Smuzhiyunwindow-relative to screen-relative if desired.  If you set the
4412*4882a593SmuzhiyunmiTranslate field in the GC (set it in the CreateGC or ValidateGC
4413*4882a593Smuzhiyunroutine), then the mi output routines will translate all coordinates.
4414*4882a593SmuzhiyunIf it is false, then the coordinates will be passed window-relative.
4415*4882a593SmuzhiyunScreens with no hardware translation will probably set miTranslate to
4416*4882a593SmuzhiyunTRUE, so that geometry (e.g. polygons, rectangles) can be translated,
4417*4882a593Smuzhiyunrather than having the resulting list of scanlines translated; this is
4418*4882a593Smuzhiyungood because the list vertices in a drawing request will generally be
4419*4882a593Smuzhiyunmuch smaller than the list of scanlines it produces.  Similarly,
4420*4882a593Smuzhiyunhardware that does translation can set miTranslate to FALSE, and avoid
4421*4882a593Smuzhiyunthe extra addition per vertex, which can be (but is not always)
4422*4882a593Smuzhiyunimportant for getting the highest possible performance.  (Contrast the
4423*4882a593Smuzhiyunbehavior of GetSpans, which is not expected to be called as often, and
4424*4882a593Smuzhiyunso has different constraints.)  The miTranslate field is settable in
4425*4882a593Smuzhiyuneach GC, if , for example, you are mixing several kinds of
4426*4882a593Smuzhiyundestinations (offscreen pixmaps, main memory pixmaps, backing store,
4427*4882a593Smuzhiyunand windows), all of which have different requirements, on one screen.</para>
4428*4882a593Smuzhiyun<para>
4429*4882a593SmuzhiyunAs with other drawing routines, there are fields in the GC to direct
4430*4882a593Smuzhiyunhigher code to the correct routine to execute for each function.  In
4431*4882a593Smuzhiyunthis way, you can optimize for special cases, for example, drawing
4432*4882a593Smuzhiyunsolids versus drawing stipples.</para>
4433*4882a593Smuzhiyun<para>
4434*4882a593SmuzhiyunThe Pixblit routines are broken up into three sets.  The Span routines
4435*4882a593Smuzhiyunsimply fill in rows of pixels.  The Glyph routines fill in character
4436*4882a593Smuzhiyunglyphs.  The PushPixels routine is a three-input bitblt for more
4437*4882a593Smuzhiyunsophisticated image creation.</para>
4438*4882a593Smuzhiyun<para>
4439*4882a593SmuzhiyunIt turns out that the Glyph and PushPixels routines actually have a
4440*4882a593Smuzhiyunmachine-independent implementation that depends upon the Span
4441*4882a593Smuzhiyunroutines.  If you are really pressed for time, you can use these
4442*4882a593Smuzhiyunversions, although they are quite slow.</para>
4443*4882a593Smuzhiyun<section>
4444*4882a593Smuzhiyun<title>Span Routines</title>
4445*4882a593Smuzhiyun<para>
4446*4882a593SmuzhiyunFor these routines, all graphic operations have been reduced to "spans."
4447*4882a593SmuzhiyunA span is a horizontal row of pixels.
4448*4882a593SmuzhiyunIf you can design these routines which write into and read from
4449*4882a593Smuzhiyunrows of pixels at a time, you can use the mi routines.</para>
4450*4882a593Smuzhiyun<para>
4451*4882a593SmuzhiyunEach routine takes
4452*4882a593Smuzhiyuna destination drawable to draw into, a GC to use while drawing,
4453*4882a593Smuzhiyunthe number of spans to do, and two pointers to arrays that indicate the list
4454*4882a593Smuzhiyunof starting points and the list of widths of spans.</para>
4455*4882a593Smuzhiyun<para>
4456*4882a593Smuzhiyun<blockquote><programlisting>
4457*4882a593Smuzhiyun
4458*4882a593Smuzhiyun	void pGC->ops->FillSpans(dst, pGC, nSpans, pPoints, pWidths, sorted)
4459*4882a593Smuzhiyun		DrawablePtr dst;
4460*4882a593Smuzhiyun		GCPtr pGC;
4461*4882a593Smuzhiyun		int nSpans;
4462*4882a593Smuzhiyun		DDXPointPtr pPoints;
4463*4882a593Smuzhiyun		int *pWidths;
4464*4882a593Smuzhiyun		int sorted;
4465*4882a593Smuzhiyun
4466*4882a593Smuzhiyun</programlisting></blockquote>
4467*4882a593SmuzhiyunFillSpans should fill horizontal rows of pixels with
4468*4882a593Smuzhiyunthe appropriate patterns, stipples, etc.,
4469*4882a593Smuzhiyunbased on the values in the GC.
4470*4882a593SmuzhiyunThe starting points are in the array at pPoints; the widths are in pWidths.
4471*4882a593SmuzhiyunIf sorted is true, the scan lines are in increasing y order, in which case
4472*4882a593Smuzhiyunyou may be able to make assumptions and optimizations.</para>
4473*4882a593Smuzhiyun<para>
4474*4882a593SmuzhiyunGC components: alu, clipOrg, clientClip, and fillStyle.</para>
4475*4882a593Smuzhiyun<para>
4476*4882a593SmuzhiyunGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
4477*4882a593Smuzhiyun(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
4478*4882a593Smuzhiyunand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
4479*4882a593Smuzhiyun<para>
4480*4882a593Smuzhiyun<blockquote><programlisting>
4481*4882a593Smuzhiyun
4482*4882a593Smuzhiyun	void pGC->ops->SetSpans(pDrawable, pGC, pSrc, ppt, pWidths, nSpans, sorted)
4483*4882a593Smuzhiyun		DrawablePtr pDrawable;
4484*4882a593Smuzhiyun		GCPtr pGC;
4485*4882a593Smuzhiyun		char *pSrc;
4486*4882a593Smuzhiyun		DDXPointPtr pPoints;
4487*4882a593Smuzhiyun		int *pWidths;
4488*4882a593Smuzhiyun		int nSpans;
4489*4882a593Smuzhiyun		int sorted;
4490*4882a593Smuzhiyun
4491*4882a593Smuzhiyun</programlisting></blockquote>
4492*4882a593SmuzhiyunFor each span, this routine should copy pWidths bits from pSrc to
4493*4882a593SmuzhiyunpDrawable at pPoints using the raster-op from the GC.
4494*4882a593SmuzhiyunIf sorted is true, the scan lines are in increasing y order.
4495*4882a593SmuzhiyunThe pixels in pSrc are
4496*4882a593Smuzhiyunpadded according to the screen's padding rules.
4497*4882a593SmuzhiyunThese
4498*4882a593Smuzhiyuncan be used to support
4499*4882a593Smuzhiyuninteresting extension libraries, for example, shaded primitives.   It does not
4500*4882a593Smuzhiyunuse the tile and stipple.</para>
4501*4882a593Smuzhiyun<para>
4502*4882a593SmuzhiyunGC components: alu, clipOrg, and clientClip</para>
4503*4882a593Smuzhiyun<para>
4504*4882a593SmuzhiyunThe above functions are expected to handle all modifiers in the current
4505*4882a593SmuzhiyunGC.  Therefore, it is expedient to have
4506*4882a593Smuzhiyundifferent routines to quickly handle common special cases
4507*4882a593Smuzhiyunand reload the procedure pointers
4508*4882a593Smuzhiyunat validate time, as with the other output functions.</para>
4509*4882a593Smuzhiyun<para>
4510*4882a593Smuzhiyun<blockquote><programlisting>
4511*4882a593Smuzhiyun
4512*4882a593Smuzhiyun	void pScreen->GetSpans(pDrawable, wMax, pPoints, pWidths, nSpans)
4513*4882a593Smuzhiyun		DrawablePtr pDrawable;
4514*4882a593Smuzhiyun		int wMax;
4515*4882a593Smuzhiyun		DDXPointPtr pPoints;
4516*4882a593Smuzhiyun		int *pWidths;
4517*4882a593Smuzhiyun		int nSpans;
4518*4882a593Smuzhiyun		char *pDst;
4519*4882a593Smuzhiyun
4520*4882a593Smuzhiyun</programlisting></blockquote>
4521*4882a593SmuzhiyunFor each span, GetSpans gets bits from the drawable starting at pPoints
4522*4882a593Smuzhiyunand continuing for pWidths bits.
4523*4882a593SmuzhiyunEach scanline returned will be server-scanline padded.
4524*4882a593SmuzhiyunThe routine can return NULL if memory cannot be allocated to hold the
4525*4882a593Smuzhiyunresult.</para>
4526*4882a593Smuzhiyun<para>
4527*4882a593SmuzhiyunGetSpans never translates -- for a window, the coordinates are already
4528*4882a593Smuzhiyunscreen-relative.  Consider the case of hardware that doesn't do
4529*4882a593Smuzhiyuntranslation: the mi code that calls ddX will translate each shape
4530*4882a593Smuzhiyun(rectangle, polygon,. etc.) before scan-converting it, which requires
4531*4882a593Smuzhiyunmany fewer additions that having GetSpans translate each span does.
4532*4882a593SmuzhiyunConversely, consider hardware that does translate: it can set its
4533*4882a593Smuzhiyuntranslation point to (0, 0) and get each span, and the only penalty is
4534*4882a593Smuzhiyunthe small number of additions required to translate each shape being
4535*4882a593Smuzhiyunscan-converted by the calling code.  Contrast the behavior of
4536*4882a593SmuzhiyunFillSpans and SetSpans (discussed above under miTranslate), which are
4537*4882a593Smuzhiyunexpected to be used more often.</para>
4538*4882a593Smuzhiyun<para>
4539*4882a593SmuzhiyunThus, the penalty to hardware that does hardware translation is
4540*4882a593Smuzhiyunnegligible, and code that wants to call GetSpans() is greatly
4541*4882a593Smuzhiyunsimplified, both for extensions and the machine-independent core
4542*4882a593Smuzhiyunimplementation.</para>
4543*4882a593Smuzhiyun<section>
4544*4882a593Smuzhiyun  <title>Glyph Routines</title>
4545*4882a593Smuzhiyun<para>
4546*4882a593SmuzhiyunThe Glyph routines draw individual character glyphs for text drawing requests.</para>
4547*4882a593Smuzhiyun<para>
4548*4882a593SmuzhiyunYou have a choice in implementing these routines.  You can use the mi
4549*4882a593Smuzhiyunversions; they depend ultimately upon the span routines.  Although
4550*4882a593Smuzhiyuntext drawing will work, it will be very slow.</para>
4551*4882a593Smuzhiyun<para>
4552*4882a593Smuzhiyun<blockquote><programlisting>
4553*4882a593Smuzhiyun
4554*4882a593Smuzhiyun	void pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
4555*4882a593Smuzhiyun		DrawablePtr pDrawable;
4556*4882a593Smuzhiyun		GCPtr pGC;
4557*4882a593Smuzhiyun		int x , y;
4558*4882a593Smuzhiyun		unsigned int nglyph;
4559*4882a593Smuzhiyun		CharInfoRec **ppci;		/* array of character info */
4560*4882a593Smuzhiyun		pointer unused;			/* unused since R5 */
4561*4882a593Smuzhiyun
4562*4882a593Smuzhiyun</programlisting></blockquote>
4563*4882a593SmuzhiyunGC components: alu, clipOrg, clientClip, font, and fillStyle.</para>
4564*4882a593Smuzhiyun<para>
4565*4882a593SmuzhiyunGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
4566*4882a593Smuzhiyun(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
4567*4882a593Smuzhiyunand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
4568*4882a593Smuzhiyun<para>
4569*4882a593Smuzhiyun<blockquote><programlisting>
4570*4882a593Smuzhiyun
4571*4882a593Smuzhiyun	void pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
4572*4882a593Smuzhiyun		DrawablePtr pDrawable;
4573*4882a593Smuzhiyun		GCPtr pGC;
4574*4882a593Smuzhiyun		int x , y;
4575*4882a593Smuzhiyun		unsigned int nglyph;
4576*4882a593Smuzhiyun		CharInfoRec **ppci;	/* array of character info */
4577*4882a593Smuzhiyun		pointer unused;		/* unused since R5 */
4578*4882a593Smuzhiyun
4579*4882a593Smuzhiyun</programlisting></blockquote>
4580*4882a593SmuzhiyunGC components: clipOrg, clientClip, font, fgPixel, bgPixel</para>
4581*4882a593Smuzhiyun<para>
4582*4882a593SmuzhiyunThese routines must copy the glyphs defined by the bitmaps in
4583*4882a593SmuzhiyunpglyphBase and the font metrics in ppci to the DrawablePtr, pDrawable.
4584*4882a593SmuzhiyunThe poly routine follows all fill, stipple, and tile rules.  The image
4585*4882a593Smuzhiyunroutine simply blasts the glyph onto the glyph's rectangle, in
4586*4882a593Smuzhiyunforeground and background colors.</para>
4587*4882a593Smuzhiyun<para>
4588*4882a593SmuzhiyunMore precisely, the Image routine fills the character rectangle with
4589*4882a593Smuzhiyunthe background color, and then the glyph is applied in the foreground
4590*4882a593Smuzhiyuncolor.  The glyph can extend outside of the character rectangle.
4591*4882a593SmuzhiyunImageGlyph() is used for terminal emulators and informal text purposes
4592*4882a593Smuzhiyunsuch as button labels.</para>
4593*4882a593Smuzhiyun<para>
4594*4882a593SmuzhiyunThe exact specification for the Poly routine is that the glyph is
4595*4882a593Smuzhiyunpainted with the current fill style.  The character rectangle is
4596*4882a593Smuzhiyunirrelevant for this operation.  PolyText, at a higher level, includes
4597*4882a593Smuzhiyunfacilities for font changes within strings and such; it is to be used
4598*4882a593Smuzhiyunfor WYSIWYG word processing and similar systems.</para>
4599*4882a593Smuzhiyun<para>
4600*4882a593SmuzhiyunBoth of these routines must clip themselves to the overall clipping region.</para>
4601*4882a593Smuzhiyun<para>
4602*4882a593SmuzhiyunExample implementations in mi are miPolyGlyphBlt() and
4603*4882a593SmuzhiyunmiImageGlyphBlt() in Xserver/mi/miglblt.c.</para>
4604*4882a593Smuzhiyun</section>
4605*4882a593Smuzhiyun<section>
4606*4882a593Smuzhiyun<title>PushPixels routine</title>
4607*4882a593Smuzhiyun<para>
4608*4882a593SmuzhiyunThe PushPixels routine writes the current fill style onto the drawable
4609*4882a593Smuzhiyunin a certain shape defined by a bitmap.  PushPixels is equivalent to
4610*4882a593Smuzhiyunusing a second stipple.  You can thing of it as pushing the fillStyle
4611*4882a593Smuzhiyunthrough a stencil.  PushPixels is not used by any of the mi rendering code,
4612*4882a593Smuzhiyunbut is used by the mi software cursor code.
4613*4882a593Smuzhiyun<blockquote><para>
4614*4882a593Smuzhiyun	Suppose the stencil is:	00111100
4615*4882a593Smuzhiyun	and the stipple is:	10101010
4616*4882a593Smuzhiyun	PushPixels result:	00101000
4617*4882a593Smuzhiyun</para></blockquote>
4618*4882a593Smuzhiyun</para>
4619*4882a593Smuzhiyun<para>
4620*4882a593SmuzhiyunYou have a choice in implementing this routine.
4621*4882a593SmuzhiyunYou can use the mi version which depends ultimately upon FillSpans().
4622*4882a593SmuzhiyunAlthough it will work, it will be slow.</para>
4623*4882a593Smuzhiyun<para>
4624*4882a593Smuzhiyun<blockquote><programlisting>
4625*4882a593Smuzhiyun
4626*4882a593Smuzhiyun	void pGC->ops->PushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
4627*4882a593Smuzhiyun		GCPtr pGC;
4628*4882a593Smuzhiyun		PixmapPtr pBitMap;
4629*4882a593Smuzhiyun		DrawablePtr pDrawable;
4630*4882a593Smuzhiyun		int dx, dy, xOrg, yOrg;
4631*4882a593Smuzhiyun
4632*4882a593Smuzhiyun</programlisting></blockquote>
4633*4882a593SmuzhiyunGC components: alu, clipOrg, clientClip, and fillStyle.</para>
4634*4882a593Smuzhiyun<para>
4635*4882a593SmuzhiyunGC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
4636*4882a593Smuzhiyun(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
4637*4882a593Smuzhiyunand stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
4638*4882a593Smuzhiyun<para>
4639*4882a593SmuzhiyunPushPixels applys the foreground color, tile, or stipple from the pGC
4640*4882a593Smuzhiyunthrough a stencil onto pDrawable.  pBitMap points to a stencil (of
4641*4882a593Smuzhiyunwhich we use an area dx wide by dy high), which is oriented over the
4642*4882a593Smuzhiyundrawable at xOrg, yOrg.  Where there is a 1 bit in the bitmap, the
4643*4882a593Smuzhiyundestination is set according to the current fill style.  Where there
4644*4882a593Smuzhiyunis a 0 bit in the bitmap, the destination is left the way it is.</para>
4645*4882a593Smuzhiyun<para>
4646*4882a593SmuzhiyunThis routine must clip to the overall clipping region.</para>
4647*4882a593Smuzhiyun<para>
4648*4882a593SmuzhiyunAn Example implementation is miPushPixels() in Xserver/mi/mipushpxl.c.</para>
4649*4882a593Smuzhiyun</section>
4650*4882a593Smuzhiyun</section>
4651*4882a593Smuzhiyun</section>
4652*4882a593Smuzhiyun<section>
4653*4882a593Smuzhiyun  <title>Shutdown Procedures</title>
4654*4882a593Smuzhiyun<para>
4655*4882a593Smuzhiyun<blockquote><programlisting>
4656*4882a593Smuzhiyun	void AbortDDX(enum ExitCode error)
4657*4882a593Smuzhiyun	void ddxGiveUp(enum ExitCode error)
4658*4882a593Smuzhiyun</programlisting></blockquote>
4659*4882a593SmuzhiyunSome hardware may require special work to be done before the server
4660*4882a593Smuzhiyunexits so that it is not left in an intermediate state.  As explained
4661*4882a593Smuzhiyunin the OS layer, FatalError() will call AbortDDX() just before
4662*4882a593Smuzhiyunterminating the server.  In addition, ddxGiveUp() will be called just
4663*4882a593Smuzhiyunbefore terminating the server on a "clean" death.  What AbortDDX() and
4664*4882a593SmuzhiyunddxGiveUP do is left unspecified, only that stubs must exist in the
4665*4882a593Smuzhiyunddx layer.  It is up to local implementors as to what they should
4666*4882a593Smuzhiyunaccomplish before termination.</para>
4667*4882a593Smuzhiyun<section>
4668*4882a593Smuzhiyun  <title>Command Line Procedures</title>
4669*4882a593Smuzhiyun<para>
4670*4882a593Smuzhiyun<blockquote><programlisting>
4671*4882a593Smuzhiyun	int ddxProcessArgument(argc, argv, i)
4672*4882a593Smuzhiyun	    int argc;
4673*4882a593Smuzhiyun	    char *argv[];
4674*4882a593Smuzhiyun	    int i;
4675*4882a593Smuzhiyun
4676*4882a593Smuzhiyun	void
4677*4882a593Smuzhiyun	ddxUseMsg()
4678*4882a593Smuzhiyun
4679*4882a593Smuzhiyun</programlisting></blockquote>
4680*4882a593SmuzhiyunYou should write these routines to deal with device-dependent command line
4681*4882a593Smuzhiyunarguments.  The routine ddxProcessArgument() is called with the command line,
4682*4882a593Smuzhiyunand the current index into argv; you should return zero if the argument
4683*4882a593Smuzhiyunis not a device-dependent one, and otherwise return a count of the number
4684*4882a593Smuzhiyunof elements of argv that are part of this one argument.  For a typical
4685*4882a593Smuzhiyunoption (e.g., "-realtime"), you should return the value one.  This
4686*4882a593Smuzhiyunroutine gets called before checks are made against device-independent
4687*4882a593Smuzhiyunarguments, so it is possible to peek at all arguments or to override
4688*4882a593Smuzhiyundevice-independent argument processing.  You can document the
4689*4882a593Smuzhiyundevice-dependent arguments in ddxUseMsg(), which will be
4690*4882a593Smuzhiyuncalled from UseMsg() after printing out the device-independent arguments.</para>
4691*4882a593Smuzhiyun</section>
4692*4882a593Smuzhiyun</section>
4693*4882a593Smuzhiyun<section id="wrappers_and_privates">
4694*4882a593Smuzhiyun  <title>Wrappers and Privates</title>
4695*4882a593Smuzhiyun<para>
4696*4882a593SmuzhiyunTwo new extensibility concepts have been developed for release 4, Wrappers
4697*4882a593Smuzhiyunand devPrivates.  These replace the R3 GCInterest queues, which were not a
4698*4882a593Smuzhiyungeneral enough mechanism for many extensions and only provided hooks into a
4699*4882a593Smuzhiyunsingle data structure.  devPrivates have been revised substantially for
4700*4882a593SmuzhiyunX.Org X server release 1.5, updated again for the 1.9 release and extended
4701*4882a593Smuzhiyunagain for the 1.13 relealse.</para>
4702*4882a593Smuzhiyun<section>
4703*4882a593Smuzhiyun  <title>devPrivates</title>
4704*4882a593Smuzhiyun<para>
4705*4882a593SmuzhiyundevPrivates provides a way to attach arbitrary private data to various server structures.
4706*4882a593SmuzhiyunAny structure which contains a <structfield>devPrivates</structfield> field of
4707*4882a593Smuzhiyuntype <type>PrivateRec</type> supports this mechanism.  Some structures allow
4708*4882a593Smuzhiyunallocating space for private data after some objects have been created, others
4709*4882a593Smuzhiyunrequire all space allocations be registered before any objects of that type
4710*4882a593Smuzhiyunare created.  <filename class="headerfile">Xserver/include/privates.h</filename>
4711*4882a593Smuzhiyunlists which of these cases applies to each structure containing
4712*4882a593Smuzhiyun<structfield>devPrivates</structfield>.</para>
4713*4882a593Smuzhiyun
4714*4882a593Smuzhiyun<para>
4715*4882a593SmuzhiyunTo request private space, use
4716*4882a593Smuzhiyun<blockquote><programlisting>
4717*4882a593Smuzhiyun	Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
4718*4882a593Smuzhiyun</programlisting></blockquote>
4719*4882a593SmuzhiyunThe first argument is a pointer to a <type>DevPrivateKeyRec</type> which
4720*4882a593Smuzhiyunwill serve as the unique identifier for the private data.  Typically this is
4721*4882a593Smuzhiyunthe address of a static <type>DevPrivateKeyRec</type> in your code.
4722*4882a593SmuzhiyunThe second argument is the class of objects for which this key will apply.
4723*4882a593SmuzhiyunThe third argument is the size of the space being requested, or
4724*4882a593Smuzhiyun<constant>0</constant> to only allocate a pointer that the caller will manage.
4725*4882a593SmuzhiyunIf space is requested, this space will be automatically freed when the object
4726*4882a593Smuzhiyunis destroyed.  Note that a call to <function>dixSetPrivate</function>
4727*4882a593Smuzhiyunthat changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
4728*4882a593SmuzhiyunThe function returns <literal>TRUE</literal> unless memory allocation fails.
4729*4882a593SmuzhiyunIf the function is called more than once on the same key, all calls must use
4730*4882a593Smuzhiyunthe same value for <type>size</type> or the server will abort.</para>
4731*4882a593Smuzhiyun
4732*4882a593Smuzhiyun<para>
4733*4882a593SmuzhiyunTo request per-screen private space in an object, use
4734*4882a593Smuzhiyun<blockquote><programlisting>
4735*4882a593Smuzhiyun	Bool dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
4736*4882a593Smuzhiyun</programlisting></blockquote>
4737*4882a593SmuzhiyunThe <parameter>type</parameter> and <parameter>size</parameter> arguments are
4738*4882a593Smuzhiyunthe same as those to <function>dixRegisterPrivateKey</function> but this
4739*4882a593Smuzhiyunfunction ensures the given <parameter>key</parameter> exists on objects of
4740*4882a593Smuzhiyunthe specified type with distinct storage for the given
4741*4882a593Smuzhiyun<parameter>pScreen</parameter>. The key is usable on ScreenPrivate variants
4742*4882a593Smuzhiyunthat are otherwise equivalent to the following Private functions.</para>
4743*4882a593Smuzhiyun
4744*4882a593Smuzhiyun<para>
4745*4882a593Smuzhiyun  To request private space in objects created for a specific screen, use
4746*4882a593Smuzhiyun  <blockquote><programlisting>
4747*4882a593Smuzhiyun    Bool dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, DevPrivateType type, unsigned size);
4748*4882a593Smuzhiyun  </programlisting></blockquote>
4749*4882a593Smuzhiyun  The <parameter>type</parameter> and <parameter>size</parameter> arguments are
4750*4882a593Smuzhiyun  the same as those to <function>dixRegisterPrivateKey</function> but this
4751*4882a593Smuzhiyun  function ensures only that the given <parameter>key</parameter> exists on objects of
4752*4882a593Smuzhiyun  the specified type that are allocated with reference to the specified
4753*4882a593Smuzhiyun  <parameter>pScreen</parameter>. Using the key on objects allocated for
4754*4882a593Smuzhiyun  other screens will result in incorrect results; there is no check made to
4755*4882a593Smuzhiyun  ensure that the caller's screen matches the private's screen. The key is
4756*4882a593Smuzhiyun  usable in any of the following functions. Screen-specific private storage is available
4757*4882a593Smuzhiyun  only for Windows, GCs, Pixmaps and Pictures. Attempts to allocate screen-specific
4758*4882a593Smuzhiyun  privates on other objects will result in a call to FatalError.
4759*4882a593Smuzhiyun</para>
4760*4882a593Smuzhiyun
4761*4882a593Smuzhiyun<para>
4762*4882a593SmuzhiyunTo attach a piece of private data to an object, use:
4763*4882a593Smuzhiyun<blockquote><programlisting>
4764*4882a593Smuzhiyun	void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
4765*4882a593Smuzhiyun</programlisting></blockquote>
4766*4882a593SmuzhiyunThe first argument is the address of the <structfield>devPrivates</structfield>
4767*4882a593Smuzhiyunfield in the target structure.  This field is managed privately by the DIX
4768*4882a593Smuzhiyunlayer and should not be directly modified.  The second argument is a pointer
4769*4882a593Smuzhiyunto the <type>DevPrivateKeyRec</type> which you registered with
4770*4882a593Smuzhiyun<function>dixRegisterPrivateKey</function> or allocated with
4771*4882a593Smuzhiyun<function>dixCreatePrivateKey</function>.  Only one
4772*4882a593Smuzhiyunpiece of data with a given key can be attached to an object, and in most cases
4773*4882a593Smuzhiyuneach key is specific to the type of object it was registered for.   (An
4774*4882a593Smuzhiyunexception is the PRIVATE_XSELINUX class which applies to multiple object types.)
4775*4882a593SmuzhiyunThe third argument is the value to store.</para>
4776*4882a593Smuzhiyun<para>
4777*4882a593SmuzhiyunIf private data with the given key is already associated with the object,
4778*4882a593Smuzhiyun<function>dixSetPrivate</function> will overwrite the old value with the
4779*4882a593Smuzhiyunnew one.</para>
4780*4882a593Smuzhiyun
4781*4882a593Smuzhiyun<para>
4782*4882a593SmuzhiyunTo look up a piece of private data, use one of:
4783*4882a593Smuzhiyun<blockquote><programlisting>
4784*4882a593Smuzhiyun	pointer dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
4785*4882a593Smuzhiyun	pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
4786*4882a593Smuzhiyun</programlisting></blockquote>
4787*4882a593SmuzhiyunThe first argument is the address of the <structfield>devPrivates</structfield> field
4788*4882a593Smuzhiyunin the target structure.  The second argument is the key to look up.
4789*4882a593SmuzhiyunIf a non-zero size was given when the key was registered, or if private data
4790*4882a593Smuzhiyunwith the given key is already associated with the object, then
4791*4882a593Smuzhiyun<function>dixLookupPrivate</function> will return the pointer value
4792*4882a593Smuzhiyunwhile <function>dixLookupPrivateAddr</function>
4793*4882a593Smuzhiyunwill return the address of the pointer.</para>
4794*4882a593Smuzhiyun
4795*4882a593Smuzhiyun<para>
4796*4882a593SmuzhiyunWhen implementing new server resource objects that support devPrivates, there
4797*4882a593Smuzhiyunare four steps to perform:
4798*4882a593SmuzhiyunAdd a type value to the <type>DevPrivateType</type> enum in
4799*4882a593Smuzhiyun<filename class="headerfile">Xserver/include/privates.h</filename>,
4800*4882a593Smuzhiyundeclare a field of type <type>PrivateRec *</type> in your structure;
4801*4882a593Smuzhiyuninitialize this field to <literal>NULL</literal> when creating any objects; and
4802*4882a593Smuzhiyunwhen freeing any objects call the <function>dixFreePrivates</function> or
4803*4882a593Smuzhiyun<function>dixFreeObjectWithPrivates</function> function.</para>
4804*4882a593Smuzhiyun</section>
4805*4882a593Smuzhiyun<section>
4806*4882a593Smuzhiyun  <title>Wrappers</title>
4807*4882a593Smuzhiyun<para>
4808*4882a593SmuzhiyunWrappers are not a body of code, nor an interface spec.  They are, instead,
4809*4882a593Smuzhiyuna technique for hooking a new module into an existing calling sequence.
4810*4882a593SmuzhiyunThere are limitations on other portions of the server implementation which
4811*4882a593Smuzhiyunmake using wrappers possible; limits on when specific fields of data
4812*4882a593Smuzhiyunstructures may be modified.  They are intended as a replacement for
4813*4882a593SmuzhiyunGCInterest queues, which were not general enough to support existing
4814*4882a593Smuzhiyunmodules; in particular software cursors needed more
4815*4882a593Smuzhiyuncontrol over the activity.  The general mechanism for using wrappers is:
4816*4882a593Smuzhiyun<blockquote><programlisting>
4817*4882a593SmuzhiyunprivateWrapperFunction (object, ...)
4818*4882a593Smuzhiyun	ObjectPtr	object;
4819*4882a593Smuzhiyun{
4820*4882a593Smuzhiyun	pre-wrapped-function-stuff ...
4821*4882a593Smuzhiyun
4822*4882a593Smuzhiyun	object->functionVector = dixLookupPrivate(&amp;object->devPrivates, privateKey);
4823*4882a593Smuzhiyun	(*object->functionVector) (object, ...);
4824*4882a593Smuzhiyun	/*
4825*4882a593Smuzhiyun	 * this next line is occasionally required by the rules governing
4826*4882a593Smuzhiyun	 * wrapper functions.  Always using it will not cause problems.
4827*4882a593Smuzhiyun	 * Not using it when necessary can cause severe troubles.
4828*4882a593Smuzhiyun	 */
4829*4882a593Smuzhiyun	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
4830*4882a593Smuzhiyun	object->functionVector = privateWrapperFunction;
4831*4882a593Smuzhiyun
4832*4882a593Smuzhiyun	post-wrapped-function-stuff ...
4833*4882a593Smuzhiyun}
4834*4882a593Smuzhiyun
4835*4882a593SmuzhiyunprivateInitialize (object)
4836*4882a593Smuzhiyun	ObjectPtr	object;
4837*4882a593Smuzhiyun{
4838*4882a593Smuzhiyun	dixSetPrivate(&amp;object->devPrivates, privateKey, object->functionVector);
4839*4882a593Smuzhiyun	object->functionVector = privateWrapperFunction;
4840*4882a593Smuzhiyun}
4841*4882a593Smuzhiyun</programlisting></blockquote>
4842*4882a593Smuzhiyun</para>
4843*4882a593Smuzhiyun<para>
4844*4882a593SmuzhiyunThus the privateWrapperFunction provides hooks for performing work both
4845*4882a593Smuzhiyunbefore and after the wrapped function has been called; the process of
4846*4882a593Smuzhiyunresetting the functionVector is called "unwrapping" while the process of
4847*4882a593Smuzhiyunfetching the wrapped function and replacing it with the wrapping function
4848*4882a593Smuzhiyunis called "wrapping".  It should be clear that GCInterest queues could
4849*4882a593Smuzhiyunbe emulated using wrappers.  In general, any function vectors contained in
4850*4882a593Smuzhiyunobjects can be wrapped, but only vectors in GCs and Screens have been tested.</para>
4851*4882a593Smuzhiyun<para>
4852*4882a593SmuzhiyunWrapping screen functions is quite easy; each vector is individually
4853*4882a593Smuzhiyunwrapped.  Screen functions are not supposed to change after initialization,
4854*4882a593Smuzhiyunso rewrapping is technically not necessary, but causes no problems.</para>
4855*4882a593Smuzhiyun<para>
4856*4882a593SmuzhiyunWrapping GC functions is a bit more complicated.  GC's have two tables of
4857*4882a593Smuzhiyunfunction vectors, one hanging from gc->ops and the other from gc->funcs, which
4858*4882a593Smuzhiyunshould be initially wrapped from a CreateGC wrapper.  Wrappers should modify
4859*4882a593Smuzhiyunonly table pointers, not the contents of the tables, as they
4860*4882a593Smuzhiyunmay be shared by more than one GC (and, in the case of funcs, are probably
4861*4882a593Smuzhiyunshared by all gcs).  Your func wrappers may change the GC funcs or ops
4862*4882a593Smuzhiyunpointers, and op wrappers may change the GC op pointers but not the funcs.</para>
4863*4882a593Smuzhiyun<para>
4864*4882a593SmuzhiyunThus, the rule for GC wrappings is: wrap the funcs from CreateGC and, in each
4865*4882a593Smuzhiyunfunc wrapper, unwrap the ops and funcs, call down, and re-wrap.  In each op
4866*4882a593Smuzhiyunwrapper, unwrap the ops, call down, and rewrap afterwards.  Note that in
4867*4882a593Smuzhiyunre-wrapping you must save out the pointer you're replacing again.  This way the
4868*4882a593Smuzhiyunchain will be maintained when wrappers adjust the funcs/ops tables they use.</para>
4869*4882a593Smuzhiyun</section>
4870*4882a593Smuzhiyun</section>
4871*4882a593Smuzhiyun<section>
4872*4882a593Smuzhiyun    <title>Work Queue</title>
4873*4882a593Smuzhiyun<para>
4874*4882a593SmuzhiyunTo queue work for execution when all clients are in a stable state (i.e.
4875*4882a593Smuzhiyunjust before calling select() in WaitForSomething), call:
4876*4882a593Smuzhiyun<blockquote><programlisting>
4877*4882a593Smuzhiyun	Bool QueueWorkProc(function,client,closure)
4878*4882a593Smuzhiyun		Bool		(*function)();
4879*4882a593Smuzhiyun		ClientPtr	client;
4880*4882a593Smuzhiyun		pointer		closure;
4881*4882a593Smuzhiyun</programlisting></blockquote>
4882*4882a593Smuzhiyun</para>
4883*4882a593Smuzhiyun<para>
4884*4882a593SmuzhiyunWhen the server is about to suspend itself, the given function will be
4885*4882a593Smuzhiyunexecuted:
4886*4882a593Smuzhiyun<blockquote><programlisting>
4887*4882a593Smuzhiyun	(*function) (client, closure)
4888*4882a593Smuzhiyun</programlisting></blockquote>
4889*4882a593Smuzhiyun</para>
4890*4882a593Smuzhiyun<para>
4891*4882a593SmuzhiyunNeither client nor closure are actually used inside the work queue routines.</para>
4892*4882a593Smuzhiyun</section>
4893*4882a593Smuzhiyun</section>
4894*4882a593Smuzhiyun<section>
4895*4882a593Smuzhiyun  <title>Summary of Routines</title>
4896*4882a593Smuzhiyun<para>
4897*4882a593SmuzhiyunThis is a summary of the routines discussed in this document.
4898*4882a593SmuzhiyunThe procedure names are in alphabetical order.
4899*4882a593SmuzhiyunThe Struct is the structure it is attached to; if blank, this
4900*4882a593Smuzhiyunprocedure is not attached to a struct and must be named as shown.
4901*4882a593SmuzhiyunThe sample server provides implementations in the following
4902*4882a593Smuzhiyuncategories.  Notice that many of the graphics routines have both
4903*4882a593Smuzhiyunmi and fb implementations.</para>
4904*4882a593Smuzhiyun<para>
4905*4882a593Smuzhiyun<itemizedlist>
4906*4882a593Smuzhiyun<listitem><para>dix	portable to all systems; do not attempt to rewrite (Xserver/dix)</para></listitem>
4907*4882a593Smuzhiyun<listitem><para>os	routine provided in Xserver/os or Xserver/include/os.h</para></listitem>
4908*4882a593Smuzhiyun<listitem><para>ddx	frame buffer dependent (examples in Xserver/fb)</para></listitem>
4909*4882a593Smuzhiyun<listitem><para>mi	routine provided in Xserver/mi</para></listitem>
4910*4882a593Smuzhiyun<listitem><para>hd	hardware dependent (examples in many Xserver/hw directories)</para></listitem>
4911*4882a593Smuzhiyun<listitem><para>none	not implemented in sample implementation</para></listitem>
4912*4882a593Smuzhiyun</itemizedlist>
4913*4882a593Smuzhiyun</para>
4914*4882a593Smuzhiyun	<table frame="all" id="routines-1">
4915*4882a593Smuzhiyun	  <title>Server Routines (Page 1)</title>
4916*4882a593Smuzhiyun	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
4917*4882a593Smuzhiyun	    <thead>
4918*4882a593Smuzhiyun	      <row>
4919*4882a593Smuzhiyun		<entry>Procedure</entry>
4920*4882a593Smuzhiyun		<entry>Port</entry>
4921*4882a593Smuzhiyun		<entry>Struct</entry>
4922*4882a593Smuzhiyun	      </row>
4923*4882a593Smuzhiyun	    </thead>
4924*4882a593Smuzhiyun	    <tbody>
4925*4882a593Smuzhiyun<row><entry><function>ALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4926*4882a593Smuzhiyun<row><entry><function>AbortDDX</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
4927*4882a593Smuzhiyun<row><entry><function>AddCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4928*4882a593Smuzhiyun<row><entry><function>AddEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4929*4882a593Smuzhiyun<row><entry><function>AddInputDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4930*4882a593Smuzhiyun<row><entry><function>AddScreen</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4931*4882a593Smuzhiyun<row><entry><function>AdjustWaitForDelay</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4932*4882a593Smuzhiyun<row><entry><function>Bell</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
4933*4882a593Smuzhiyun<row><entry><function>ChangeClip</function></entry><entry><literal>mi</literal></entry><entry><para>GC func</para></entry></row>
4934*4882a593Smuzhiyun<row><entry><function>ChangeGC</function></entry><entry><literal></literal></entry><entry><para>GC func</para></entry></row>
4935*4882a593Smuzhiyun<row><entry><function>ChangeWindowAttributes</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4936*4882a593Smuzhiyun<row><entry><function>ClearToBackground</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
4937*4882a593Smuzhiyun<row><entry><function>ClientAuthorized</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4938*4882a593Smuzhiyun<row><entry><function>ClientSignal</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4939*4882a593Smuzhiyun<row><entry><function>ClientSleep</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4940*4882a593Smuzhiyun<row><entry><function>ClientWakeup</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4941*4882a593Smuzhiyun<row><entry><function>ClipNotify</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4942*4882a593Smuzhiyun<row><entry><function>CloseScreen</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
4943*4882a593Smuzhiyun<row><entry><function>ConstrainCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
4944*4882a593Smuzhiyun<row><entry><function>CopyArea</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4945*4882a593Smuzhiyun<row><entry><function>CopyGCDest</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
4946*4882a593Smuzhiyun<row><entry><function>CopyGCSource</function></entry><entry><literal>none</literal></entry><entry><para>GC func</para></entry></row>
4947*4882a593Smuzhiyun<row><entry><function>CopyPlane</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4948*4882a593Smuzhiyun<row><entry><function>CopyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
4949*4882a593Smuzhiyun<row><entry><function>CreateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4950*4882a593Smuzhiyun<row><entry><function>CreateCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4951*4882a593Smuzhiyun<row><entry><function>CreatePixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4952*4882a593Smuzhiyun<row><entry><function>CreateScreenResources</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4953*4882a593Smuzhiyun<row><entry><function>CreateWellKnowSockets</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4954*4882a593Smuzhiyun<row><entry><function>CreateWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4955*4882a593Smuzhiyun<row><entry><function>CursorLimits</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
4956*4882a593Smuzhiyun<row><entry><function>DEALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4957*4882a593Smuzhiyun<row><entry><function>DeleteCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4958*4882a593Smuzhiyun<row><entry><function>DeleteCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4959*4882a593Smuzhiyun<row><entry><function>DestroyClip</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
4960*4882a593Smuzhiyun<row><entry><function>DestroyGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
4961*4882a593Smuzhiyun<row><entry><function>DestroyPixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4962*4882a593Smuzhiyun<row><entry><function>DestroyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4963*4882a593Smuzhiyun<row><entry><function>DisplayCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
4964*4882a593Smuzhiyun<row><entry><function>Error</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4965*4882a593Smuzhiyun<row><entry><function>ErrorF</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4966*4882a593Smuzhiyun<row><entry><function>FatalError</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4967*4882a593Smuzhiyun<row><entry><function>FillPolygon</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4968*4882a593Smuzhiyun<row><entry><function>FillSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
4969*4882a593Smuzhiyun<row><entry><function>FlushAllOutput</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4970*4882a593Smuzhiyun<row><entry><function>FlushIfCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
4971*4882a593Smuzhiyun<row><entry><function>FreeScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4972*4882a593Smuzhiyun<row><entry><function>GetImage</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
4973*4882a593Smuzhiyun<row><entry><function>GetMotionEvents</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
4974*4882a593Smuzhiyun<row><entry><function>GetScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4975*4882a593Smuzhiyun<row><entry><function>GetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4976*4882a593Smuzhiyun<row><entry><function>GetStaticColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
4977*4882a593Smuzhiyun	    </tbody>
4978*4882a593Smuzhiyun	  </tgroup>
4979*4882a593Smuzhiyun	</table>
4980*4882a593Smuzhiyun
4981*4882a593Smuzhiyun	<table frame="all" id="routines-2">
4982*4882a593Smuzhiyun	  <title>Server Routines (Page 2)</title>
4983*4882a593Smuzhiyun	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
4984*4882a593Smuzhiyun	    <thead>
4985*4882a593Smuzhiyun	      <row>
4986*4882a593Smuzhiyun		<entry>Procedure</entry>
4987*4882a593Smuzhiyun		<entry>Port</entry>
4988*4882a593Smuzhiyun		<entry>Struct</entry>
4989*4882a593Smuzhiyun	      </row>
4990*4882a593Smuzhiyun	    </thead>
4991*4882a593Smuzhiyun	    <tbody>
4992*4882a593Smuzhiyun<row><entry><function>ImageGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4993*4882a593Smuzhiyun<row><entry><function>ImageText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4994*4882a593Smuzhiyun<row><entry><function>ImageText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
4995*4882a593Smuzhiyun<row><entry><function>InitInput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
4996*4882a593Smuzhiyun<row><entry><function>InitKeyboardDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4997*4882a593Smuzhiyun<row><entry><function>InitOutput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
4998*4882a593Smuzhiyun<row><entry><function>InitPointerDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
4999*4882a593Smuzhiyun<row><entry><function>InsertFakeRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5000*4882a593Smuzhiyun<row><entry><function>InstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5001*4882a593Smuzhiyun<row><entry><function>Intersect</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5002*4882a593Smuzhiyun<row><entry><function>Inverse</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5003*4882a593Smuzhiyun<row><entry><function>LegalModifier</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
5004*4882a593Smuzhiyun<row><entry><function>LineHelper</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5005*4882a593Smuzhiyun<row><entry><function>ListInstalledColormaps</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5006*4882a593Smuzhiyun<row><entry><function>LookupKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
5007*4882a593Smuzhiyun<row><entry><function>LookupPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
5008*4882a593Smuzhiyun<row><entry><function>ModifyPixmapHeader</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5009*4882a593Smuzhiyun<row><entry><function>NextAvailableClient</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
5010*4882a593Smuzhiyun<row><entry><function>OsInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5011*4882a593Smuzhiyun<row><entry><function>PaintWindowBackground</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
5012*4882a593Smuzhiyun<row><entry><function>PaintWindowBorder</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
5013*4882a593Smuzhiyun<row><entry><function>PointerNonInterestBox</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5014*4882a593Smuzhiyun<row><entry><function>PointInRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5015*4882a593Smuzhiyun<row><entry><function>PolyArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5016*4882a593Smuzhiyun<row><entry><function>PolyFillArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5017*4882a593Smuzhiyun<row><entry><function>PolyFillRect</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5018*4882a593Smuzhiyun<row><entry><function>PolyGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5019*4882a593Smuzhiyun<row><entry><function>Polylines</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5020*4882a593Smuzhiyun<row><entry><function>PolyPoint</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5021*4882a593Smuzhiyun<row><entry><function>PolyRectangle</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5022*4882a593Smuzhiyun<row><entry><function>PolySegment</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5023*4882a593Smuzhiyun<row><entry><function>PolyText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5024*4882a593Smuzhiyun<row><entry><function>PolyText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5025*4882a593Smuzhiyun<row><entry><function>PositionWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5026*4882a593Smuzhiyun<row><entry><function>ProcessInputEvents</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
5027*4882a593Smuzhiyun<row><entry><function>PushPixels</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5028*4882a593Smuzhiyun<row><entry><function>PutImage</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
5029*4882a593Smuzhiyun<row><entry><function>QueryBestSize</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5030*4882a593Smuzhiyun<row><entry><function>ReadRequestFromClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5031*4882a593Smuzhiyun<row><entry><function>RealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5032*4882a593Smuzhiyun<row><entry><function>RealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5033*4882a593Smuzhiyun<row><entry><function>RealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5034*4882a593Smuzhiyun<row><entry><function>RecolorCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5035*4882a593Smuzhiyun<row><entry><function>RectIn</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5036*4882a593Smuzhiyun<row><entry><function>RegionCopy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5037*4882a593Smuzhiyun<row><entry><function>RegionCreate</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5038*4882a593Smuzhiyun<row><entry><function>RegionDestroy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5039*4882a593Smuzhiyun<row><entry><function>RegionEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5040*4882a593Smuzhiyun<row><entry><function>RegionExtents</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5041*4882a593Smuzhiyun<row><entry><function>RegionNotEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5042*4882a593Smuzhiyun<row><entry><function>RegionReset</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5043*4882a593Smuzhiyun<row><entry><function>ResolveColor</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5044*4882a593Smuzhiyun	    </tbody>
5045*4882a593Smuzhiyun	  </tgroup>
5046*4882a593Smuzhiyun	</table>
5047*4882a593Smuzhiyun
5048*4882a593Smuzhiyun	<table frame="all" id="routines-3">
5049*4882a593Smuzhiyun	  <title>Server Routines (Page 3)</title>
5050*4882a593Smuzhiyun	  <tgroup cols='3' align='left' colsep='1' rowsep='1'>
5051*4882a593Smuzhiyun	    <thead>
5052*4882a593Smuzhiyun	      <row>
5053*4882a593Smuzhiyun		<entry>Procedure</entry>
5054*4882a593Smuzhiyun		<entry>Port</entry>
5055*4882a593Smuzhiyun		<entry>Struct</entry>
5056*4882a593Smuzhiyun	      </row>
5057*4882a593Smuzhiyun	    </thead>
5058*4882a593Smuzhiyun	    <tbody>
5059*4882a593Smuzhiyun<row><entry><function>RemoveEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5060*4882a593Smuzhiyun<row><entry><function>ResetCurrentRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5061*4882a593Smuzhiyun<row><entry><function>SaveScreen</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5062*4882a593Smuzhiyun<row><entry><function>SetCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5063*4882a593Smuzhiyun<row><entry><function>SetCursorPosition</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5064*4882a593Smuzhiyun<row><entry><function>SetInputCheck</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
5065*4882a593Smuzhiyun<row><entry><function>SetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
5066*4882a593Smuzhiyun<row><entry><function>StoreColors</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5067*4882a593Smuzhiyun<row><entry><function>Subtract</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5068*4882a593Smuzhiyun<row><entry><function>TimerCancel</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5069*4882a593Smuzhiyun<row><entry><function>TimerCheck</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5070*4882a593Smuzhiyun<row><entry><function>TimerForce</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5071*4882a593Smuzhiyun<row><entry><function>TimerFree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5072*4882a593Smuzhiyun<row><entry><function>TimerInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5073*4882a593Smuzhiyun<row><entry><function>TimerSet</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5074*4882a593Smuzhiyun<row><entry><function>TimeSinceLastInputEvent</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
5075*4882a593Smuzhiyun<row><entry><function>TranslateRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5076*4882a593Smuzhiyun<row><entry><function>UninstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5077*4882a593Smuzhiyun<row><entry><function>Union</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5078*4882a593Smuzhiyun<row><entry><function>UnrealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
5079*4882a593Smuzhiyun<row><entry><function>UnrealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5080*4882a593Smuzhiyun<row><entry><function>UnrealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
5081*4882a593Smuzhiyun<row><entry><function>ValidateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
5082*4882a593Smuzhiyun<row><entry><function>ValidateTree</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
5083*4882a593Smuzhiyun<row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5084*4882a593Smuzhiyun<row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
5085*4882a593Smuzhiyun<row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
5086*4882a593Smuzhiyun	    </tbody>
5087*4882a593Smuzhiyun	  </tgroup>
5088*4882a593Smuzhiyun	</table>
5089*4882a593Smuzhiyun</section>
5090*4882a593Smuzhiyun</article>
5091