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