XCB Protocol Implementation Macro Language by Jamey Sharp # Terminology In this document, terms shall be used as follows. A "field" is a unit of information in a real protocol request. Fields are never visible to programmers using XCB. A "reply field" is a unit of information in a real protocol reply. Reply fields are directly visible to programmers using XCB. A "param" ("parameter") is a unit of information passed to a protocol request wrapper function. It may or may not correspond to a field. # Responses These macros desribe all data that comes from the X server. ## Extension Support: BEGINEXTENSION and ENDEXTENSION BEGINEXTENSION(X name, C name)
ENDEXTENSION An extension's X name is the string used to identify it to the server (e.g. 'DPMS', 'SHAPE', 'XVideo'). The X protocol specification says that the X name of the extension "should use the ISO Latin-1 encoding, and uppercase and lowercase matter." An extension's C name should be a valid C identifier which can be guessed easily from the X name: it will appear in some names visible to programmers using XCB. ## VOIDREQUEST VOIDREQUEST(name, 0 or more [[[#Request''Parameters''and_Fields|[]][PARAMs]]) Creates a function named [[XcbApi#XCBName][XCB<name>|XcbApi]] returning [[XcbApi#XCBNameCookie][XCBVoidCookie|XcbApi]] and accepting whatever parameters are necessary to deliver the given [[[#Request''Parameters''and_Fields|[]][PARAMs]] to the X server. Requests created with this macro do not expect a reply. ## REQUEST REQUEST(name, 0 or more [[[#Request''Parameters''and''Fields|[]][PARAMs]], 1 or more [[[#Field''Declarations|[]][FIELDs]]) Creates a function named [[XcbApi#XCBName][XCB<name>|XcbApi]] whose return result is an [[XcbApi#XCBNameCookie][XCB<name>Cookie|XcbApi]] and whose parameters are whatever is necessary to deliver the given [[[#Request''Parameters''and_Fields|[]][PARAMs]] to the X server. Declares the struct [[XcbApi#XCBNameCookie][XCB<name>Cookie|XcbApi]]. Creates a function named [[XcbApi#XCBNameReply][XCB<name>Reply|XcbApi]] returning a pointer to [[XcbApi#XCBNameRep][XCB<name>Rep|XcbApi]] which forces a cookie returned from [[XcbApi#XCBName][XCB<name>|XcbApi]], waiting for the response from the server if necessary. The [[[#Field_Declarations|[]][FIELDs]] must be quoted. ## EVENT EVENT(name, number, 1 or more FIELDs) Declares the struct [[XcbApi#XCBEventNameEvent][XCB<name>Event|XcbApi]] containing the given FIELDs. Also defines [[XcbApi#XCBEventName][XCB<name>|XcbApi]] equal to number. ## EVENTCOPY EVENTCOPY(new name, new number, old name) (undocumented) ## ERROR ERROR(name, number, 1 or more FIELDs) Declares the struct [[XcbApi#XCBErrorNameError][XCB<name>Error|XcbApi]] containing the given FIELDs. Also defines [[XcbApi#XCBErrorName][XCB<name>|XcbApi]] equal to number. ## ERRORCOPY ERRORCOPY(new name, new number, old name) (undocumented) ## Request Parameters and Fields These PARAM and FIELD macros may only appear within the second parameter to the [[[#REQUEST|[]][REQUEST]] or [[[#VOIDREQUEST|[]][VOIDREQUEST]] macros, and must always be quoted. All of these macro calls must appear in the order specified by Appendix B (Protocol Encoding) of the X Window System Protocol specification, or the equivalent documentation for any extension. However, [[[#LISTPARAM|[]][LISTs]] (including !LISTofVALUEs) are always grouped after any fixed-length section. Information about padding bytes must be known, so you may need to specify it using the [[[#PAD|[]][PAD]] macro. However, in several cases this information can be inferred by the macros and thus can be omitted: * After the last fixed-length field in a fixed-length request or reply. * After the last fixed-length field in a variable-length request. * Between each variable-length field and the next 4-byte aligned boundary in a request. ### OPCODE OPCODE(number) For extensions, this macro generates code to look up the major number and sets the minor number to the given value. For the core protocol, this macro sets the major number to the given value. ### PAD PAD(bytes) Inserts the given number of padding bytes. ### PARAM PARAM(type, name) Defines a parameter with a field of the same type. ### VALUEPARAM VALUEPARAM(bitmask type, bitmask name, value array name) Defines a BITMASK/LISTofVALUE parameter pair. The bitmask type should probably be either CARD16 or CARD32, depending on the specified width of the bitmask. The value array must be given to the generated function in the order the X server expects. Caution! No type-, value-, or bounds-checking is done on this array by XCB. The X server and your operating system may not catch errors either, leading to odd results if you're not careful. ### LISTPARAM LISTPARAM(element type, list name, optional length expression) Defines a !LISTofFOO parameter. The length of the list may be given as any C expression and may reference any of the other fields of this request. If the length is not given, then it is obtained in a language-dependent manner. In C, a [[[#LOCALPARAM|[]][LOCALPARAM]] is automatically generated for `name_len` immediately before the list parameter. Note that requests like QueryTextExtents require a [[[#LOCALPARAM|[]][LOCALPARAM]] for the length field, while others like InternAtom require a [[[#PARAM|[]][PARAM]]. The recommended idiom for strings is to pass the length of the string into XCB, because it is much easier for callers to convert null-terminated strings to this style of counted strings than to go the other way around, and because requiring null-terminated strings as input could cause some valid protocol requests to be impossible to produce using XCB.
[[!format txt """ PARAM(CARD16, `name_len') LISTPARAM(char, `name', `name_len') """]] _Example macro usage for strings with on-wire lengths._ [[!format txt """ LISTPARAM(char, `path') """]] _Example macro usage for strings without on-wire lengths._
### LOCALPARAM LOCALPARAM(type, name) Defines a parameter with no associated field. The name can be used in expressions. This macro can be useful in conjunction with LISTs where you need to pass the number of items to the [[[#LISTPARAM|[]][LISTPARAM]] macro, but in the protocol the list length is implicit in the request length. ### EXPRFIELD EXPRFIELD(field name, expression) Defines a field which should be filled in with the given expression. The field has no associated parameter. The name can be used in expressions. This macro can be useful when the protocol requires an explicit field containing a value which is easily calculated from the information available. In the core protocol, the only request that this is used for is QueryTextExtents, where the length of the string is implicit in the length of the request, with the exception that whether the string is odd or even length must be specified separately. This declaration expresses that: [[!format txt """ EXPRFIELD(BOOL, `odd''length', `string''len & 1') """]] Historically, EXPRFIELD was also used to allow C-style null-terminated strings to be passed to XCB and converted to counted strings automatically. _This usage is deprecated._ See [[[#LISTPARAM|[]][LISTPARAM]].
[[!format txt """ EXPRFIELD(CARD16, `name_len', `strlen(name)') LISTPARAM(char, `name', `name_len') """]] _Deprecated example of converting a null-terminated string to a counted string._
## ARRAYREPLY ARRAYREPLY(field type, field name, length name) Deprecated: use [[[#LISTFIELD|[]][LISTFIELD]]. ## REPLY REPLY(type, name) Deprecated: use [[[#FIELD|[]][FIELD]] # Utility Macros ## Header File Generation ### HEADERONLY and SOURCEONLY These two macros are deprecated. They're too language-specific to appear in generics.xcb, and XCB should be able to figure out where to put all declarations on its own anyway. Code which should appear only in a header (.h) file or only in an implementation (.c) file may be enclosed in the HEADERONLY and SOURCEONLY macros. ### XCBGEN and ENDXCBGEN XCBGEN(header name)
ENDXCBGEN() The first line (aside from comments) of any XCB protocol implementation should contain a call to the XCBGEN macro, and the last line should contain a call to the ENDXCBGEN macro. The header name should generally be the base name of the source file, with all lowercase letters capitalized, and all other characters converted to underscores ("_"): for example, xcb_conn.m4 uses XCB_CONN here. XCBGEN automatically causes the header file to be #included by the implementation file. ## Internal Macros ### TOUPPER TOUPPER(string) Transliterates lowercase characters to uppercase. ### UCFIRST UCFIRST(string) Transliterates the first character of the string to uppercase. ### SPLIT SPLIT(substring, string) Split a string into a list of strings, at each point that the given substring appears. ### JOIN JOIN(sep, string, ...) Join a list of strings with a given string as separator. ### MAP MAP(macro, string, ...) Applies the macro to each following string and returns the transformed list. ### UNIMPLEMENTED (undocumented) ### Diversions PUSHDIV and divert should never be called with any number except -1. Instead, save the return value of ALLOCDIV into a macro that is named for the contents of the diversion, and use that macro.
[[!format txt """ define(`FUNCDIV', ALLOCDIV) """]] _Example of creating a new diversion._
Any use of `divert(0)` should be replaced with POPDIV(), and the first call to divert before that should be replaced with a call to PUSHDIV. This ensures that the protocol description file can be used in a wide variety of ways, including those that want only the values of the macros and diversions created inside the file. #### ALLOCDIV ALLOCDIV() Returns a diversion number not currently in use. #### PUSHDIV PUSHDIV(diversion) Pushes the given diversion onto the diversion stack, switching to it in the process. #### POPDIV POPDIV() Pops the current diversion off the diversion stack, returning to the diversion which was in effect before the last [[[#PUSHDIV|[]][PUSHDIV]]. ### Indentation #### INDENT INDENT() Move line indentation to the right 4 spaces. #### UNINDENT UNINDENT() Move line indentation to the left 4 spaces. #### TAB TAB() Indent current line according to the current indentation level set by [[[#INDENT|[]][INDENT]] and [[[#UNINDENT|[]][UNINDENT]]. ### Functions #### FUNCTION FUNCTION(return type and function name, params, body) Declares a C function, placing the appropriate prototype in the header file and the complete function in the implementation file. #### STATICFUNCTION STATICFUNCTION(return type and function name, params, body) Declares a static-scope C function. No prototype is placed in the header file, and the keyword static is applied to the function in the implementation file. #### INLINEFUNCTION INLINEFUNCTION(return type and function name, params, body) Declare a C function which should be compiled inline if possible. The function is placed in the header file and declared "static inline". A future implementation of these macros should fall back to generating a regular function if inlines aren't supported by the compiler, but this isn't implemented yet. # Types ## TYPEDEF TYPEDEF(old name, new name) (undocumented) ## ENUM ENUM(type name, name list) (undocumented) ## XIDTYPE XIDTYPE(name) Declares a struct holding an XID, and a function to allocate new instances of this struct. ## STRUCT STRUCT(name, 1 or more FIELDs) Typedefs a structure defined to contain the given fields so that it has the given name. ## UNION UNION(name, 1 or more FIELDs) Typedefs a union defined to contain the given fields so that it has the given name. ## Field Declarations These declarations may be used in [[[#STRUCT|[]][STRUCT]], [[[#UNION|[]][UNION]], or [[[#REQUEST|[]][REQUEST]] reply definitions. ### FIELD FIELD(type, name) Declares a field of the given type with the given name. ### LISTFIELD LISTFIELD(type, name, quantity) Declares a list with the given name and containing the given quantity of elements of the given type. If the given type is fixed-length, declares the [[XcbApi#XCBNameField][XCB<request><field>|XcbApi]] function. If the given type has an iterator, declares the [[XcbApi#XCBNameFieldIter][XCB<request><field>Iter|XcbApi]] function. Declares the [[XcbApi#XCBNameFieldLength][XCB<request><field>Length|XcbApi]] function. ### ARRAYFIELD ARRAYFIELD(type, name, quantity) Deprecated: use [[[#LISTFIELD|[]][LISTFIELD]]. # Undocumented These macros need to be documented. ## COMMENT (undocumented)