XCB: an X Protocol C Binding
Total Page:16
File Type:pdf, Size:1020Kb
XCB: An X Protocol C Binding Bart Massey Jamey Sharp Computer Science Department Portland State University fbart,[email protected] October 6, 2001 Abstract protocol requests and responses to an API for the C programming language [KR78]; as the repository The standard X Window System binding for the C of a number of performance optimizations of the C programming language, Xlib, is a very successful API, such as caching and grouping of requests; as piece of software across a wide range of applica- a base for GUI toolkit implementations; and as a tions. However, for many modern uses, Xlib is not focal point for convenience routines and extensions an ideal fit: its size, complexity, difficulty of ex- necessary to build functional, internationalized and tension and synchronous interface are particularly standards-conforming standalone programs without problematic. toolkit support. The XCB “X Protocol C Binding”, currently under Unfortunately, these roles have been somewhat development, is a response to these and other con- contradictory, and the long history of Xlib has not cerns. XCB is intended to be a simpler and more generally worked in its favor. The current Xlib suf- direct binding of protocol objects to C functions; fers from a number of outright defects. careful design of the XCB API and internal data structures and thorough modularization provides a 1.1 Xlib Features solution that is size and time efficient, maintain- able, easy to use both by single-threaded and multi- Xlib has a number of notable features, resulting threaded applications and easily extensible. Some both from an excellent initial design and the ma- features of Xlib have been sacrificed in achieving turity attained through 15 years of large-scale use. these goals, notably i18n support and convenience Perhaps the most important is its completeness: the buffering and caching features, but the cost will XFree86 Xlib release includes support for every likely be worth it for toolkit developers and for protocol request provided by X11R6 and libraries those looking to write specialized applications lay- for every protocol extension request supported by ered atop the XCB API. XFree86, as well as support for a rich set of conve- nience features. Among these convenience features are automatic marshaling of multiple requests (for 1 Xlib example, combining a series of DrawPoint re- quests into a PolyPoint request), automatic de- Perhaps the oldest software in modern X Window composition of large requests and tools for auto- System [SG86] distributions is Xlib [SG92]: the matic input canonicalization and internationaliza- oldest files in the current XFree861 distribution tion (i18n) of both input and output. have a 1985 copyright. Xlib has played an impor- The large-scale usage of Xlib has also made it a tant role in the development of the X Window Sys- thoroughly use-tested piece of software. It has been tem in several ways: as the standard binding of X carefully maintained, and its reliability is currently 1http://xfree86.org quite high. In particular, its code embodies many clever solutions to subtle problems in X protocol this problem, but ultimately it seems difficult to se- interaction. Since the protocol has co-evolved with riously shrink Xlib without significantly changing Xlib, both have been adjusted to work well together. the API and excising substantial parts of its func- tionality. The X protocol is bandwidth efficient. Requests, replies and events are parsimonious in size. The Because of the size, complexity and ubiquity of simple representations of the protocol allow most Xlib, it is quite difficult to maintain, especially to transactions to be easily compressed by a general extend. Potential authors of new X protocol exten- purpose method such as gzip [Gai93], further im- sions are often deterred not by the difficulty of the proving performance. Xlib contains a number of server-side work, but by the difficulty of adding li- optimizations designed to improve this bandwidth brary support for the extension: there is little sup- efficiency. Notable among these are buffered out- port in Xlib for extensions, so a great deal of new put of requests2 and a reasonable amount of local code typically needs to be written on the client side. caching of server state. This may be a major factor in the dearth of new ex- tensions over the last 10 years or so.4 The choice of the C programming language as the standard binding language for X clients was a natu- Xlib can also be difficult to use. For example, many ral one, given the C server implementation and the X protocol items are XIDs, small integers. Unfortu- efficiency and accessibility of the language. It has nately, C provides no way to declare incompatible since proven a fortuitous decision. Because most types isomorphic to small integers. This occasion- other programming languages provide an interface ally leads to type errors in Xlib usage that are not to C source or binaries, Xlib has been used as a statically detected: passing a window ID where a binding by toolkits and programs written in lan- font ID was required, for example. The use of C guages ranging from C++ and Java to Scheme and structure and union types to “wrap” small integers Prolog. can solve this problem, but in 1985 a few C compil- ers still had trouble treating structures in the largely 1.2 Xlib Areas For Improvement first-class fashion required by the standard: struc- ture return was particularly problematic, and some compilers even had problems with structure copy- While Xlib is highly successful, there are still areas ing. that could use improvement. Xlib is arcane: even experienced X programmers must frequently refer As another example, user memory management of to the documentation in order to use it successfully. Xlib data is complicated by a couple of factors. This is due to several factors: first, the difficulty of First, because the XAlloc() and XFree() inter- building a transparent API in C; second, accretion; faces are used instead of their normal malloc() but third and especially the fact that Xlib tries to and free() counterparts, traditional memory al- be a general purpose interface suitable for writing location debugging and leak-detection tools are dif- everything from small toolkit components to large ficult to use to detect and diagnose Xlib usage er- applications directly. rors. This may be one of the reasons why X appli- cations so commonly leak storage. Another is that Because of XLib’s generality and emphasis on con- Xlib routines occasionally return allocated storage venience functions, the library is complex and over- containing pointers to other unallocated storage: it sized; little of its code is regularly used by applica- is the responsibility of the Xlib user to free the ref- 3 tions. Work by Jim Gettys has recently reduced erents before freeing the referencing block, by call- 5 2Xlib contains a support for a timer that periodically flushes ing the appropriate destructor routine rather than the output stream to reduce latency. While XCB takes the po- XFree(). Needless to say, this is error-prone, and sition that this is an activity better performed by the API client, which may be able to do a better job with reduced complexity, 4Keith Packard, personal communication, August 2001. this mechanism in any case does help control request latency. 5Often the destructor’s name contains “destroy” rather than 3Personal communication, June 2001. “free”, adding to the confusion. the resulting errors are difficult to detect. proach. XCB is intended to be a simple and direct binding of X protocol transactions to C language The design goals of Xlib are somewhat contradic- function calls, with the minimum amount of ma- tory. Modern toolkits such as Gtk and Qt eschew chinery necessary to achieve this aim. most of the special features of Xlib, such as its com- plicated input model and i18n semantics, and use It is assumed that the principle clients of XCB just the protocol binding. This is not merely waste- will be of two types: toolkits intended for higher- ful: interference from Xlib also makes it difficult level program implementation and small libraries to do certain styles of toolkit optimization, such as intended to ease the direct use of XCB. Thus, cer- latency hiding and the use of multiple threads. tain constraints of the Xlib design disappear. Fea- tures such as i18n and most caching, that can be bet- While Xlib attempts to be re-entrant, its complexity ter managed at a higher layer, may be eliminated. and the “retrofitted” nature of the reentrancy sup- Controlling the syntactic details of the API inter- port make exploiting this feature difficult. In par- face also becomes slightly less critical (although the ticular, the Xlib API is not easily suited to thread- current design seems rather pleasant in this regard). based use. For example, it is difficult to obtain the sequence number of a request in a multi-threaded 2.1 XCB Structure environment, as the sequence counter may be ad- vanced by a second request between the time the first request is sent and the counter is queried. In The basic structure of XCB is in two layers, as illus- addition, many Xlib calls that retrieve information, trated in Figure 1. A lower layer, XCB Connection, such as GetNextEvent, come in two basic forms: a supports the establishment of an X server con- blocking form that locks critical data structures and nection and handles buffering and batching of re- a non-blocking form that is subject to races with quests and responses. XCB Connection exports other threads. a simple API to the upper XCB Protocol layer. XCB Protocol, in turn, provides a quite direct C While Xlib and the protocol are bandwidth- API for the core X Protocol.