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