<head>
<title>Basic Graphics Programming With The XCB Library</title>
- <link href="xcb.css" rel="stylesheet" type="text/css" />
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <link href="xcb.css" rel="stylesheet" type="text/css">
</head>
<body>
</div>
<div class="toc">
<ol>
- <li><a class="section" href="#intro">Introduction</a></li>
- <li><a class="section" href="#Xmodel">The client and server model of the X window system</a></li>
- <li><a class="section" href="#asynch">GUI programming: the asynchronous model</a></li>
- <li><a class="section" href="#notions">Basic XCB notions</a></li>
+ <li><a class="section" href="#intro">Introduction</a>
+ <li><a class="section" href="#Xmodel">The client and server model of the X window system</a>
+ <li><a class="section" href="#asynch">GUI programming: the asynchronous model</a>
+ <li><a class="section" href="#notions">Basic XCB notions</a>
<ol>
- <li><a class="subsection" href="#conn">The X Connection</a></li>
- <li><a class="subsection" href="#requestsreplies">Requests and replies: the Xlib killers</a></li>
- <li><a class="subsection" href="#gc">The Graphics Context</a></li>
- <li>Object handles</li>
- <li>Memory allocation for XCB structures</li>
- <li><a class="subsection" href="#events">Events</a></li>
+ <li><a class="subsection" href="#conn">The X Connection</a>
+ <li><a class="subsection" href="#requestsreplies">Requests and replies: the Xlib killers</a>
+ <li><a class="subsection" href="#gc">The Graphics Context</a>
+ <li>Object handles
+ <li>Memory allocation for XCB structures
+ <li><a class="subsection" href="#events">Events</a>
</ol>
- <li><a class="section" href="#use">Using XCB-based programs</a></li>
+ <li><a class="section" href="#use">Using XCB-based programs</a>
<ol>
- <li><a class="subsection" href="#inst">Installation of XCB</a></li>
- <li><a class="subsection" href="#comp">Compiling XCB-based programs</a></li>
+ <li><a class="subsection" href="#inst">Installation of XCB</a>
+ <li><a class="subsection" href="#comp">Compiling XCB-based programs</a>
</ol>
- <li><a class="section" href="#openconn">Opening and closing the connection to an X server</a></li>
- <li><a class="section" href="#screen">Checking basic information about a connection</a></li>
- <li><a class="section" href="#helloworld">Creating a basic window - the "hello world" program</a></li>
- <li><a class="section" href="#drawing">Drawing in a window</a></li>
+ <li><a class="section" href="#openconn">Opening and closing the connection to an X server</a>
+ <li><a class="section" href="#screen">Checking basic information about a connection</a>
+ <li><a class="section" href="#helloworld">Creating a basic window - the "hello world" program</a>
+ <li><a class="section" href="#drawing">Drawing in a window</a>
<ol>
- <li><a class="subsection" href="#allocgc">Allocating a Graphics Context</a></li>
- <li><a class="subsection" href="#changegc">Changing the attributes of a Graphics Context</a></li>
- <li><a class="subsection" href="#drawingprim">Drawing primitives: point, line, box, circle,...</a></li>
+ <li><a class="subsection" href="#allocgc">Allocating a Graphics Context</a>
+ <li><a class="subsection" href="#changegc">Changing the attributes of a Graphics Context</a>
+ <li><a class="subsection" href="#drawingprim">Drawing primitives: point, line, box, circle,...</a>
</ol>
- <li><a class="section" href="#xevents">X Events</a></li>
+ <li><a class="section" href="#xevents">X Events</a>
<ol>
- <li><a class="subsection" href="#register">Registering for event types using event masks</a></li>
- <li><a class="subsection" href="#loop">Receiving events: writing the events loop</a></li>
- <li><a class="subsection" href="#expose">Expose events</a></li>
- <li><a class="subsection" href="#userinput">Getting user input</a></li>
- <ol>
- <li><a class="subsubsection" href="#mousepressrelease">Mouse button press and release events</a></li>
- <li><a class="subsubsection" href="#mousemvnt">Mouse movement events</a></li>
- <li><a class="subsubsection" href="#mouseenter">Mouse pointer enter and leave events</a></li>
- <li><a class="subsubsection" href="#focus">The keyboard focus</a></li>
- <li><a class="subsubsection" href="#keypress">Keyboard press and release events</a></li>
- </ol>
- <li><a class="subsection" href="#eventex">X events: a complete example</a></li>
+ <li><a class="subsection" href="#register">Registering for event types using event masks</a>
+ <li><a class="subsection" href="#loop">Receiving events: writing the events loop</a>
+ <li><a class="subsection" href="#expose">Expose events</a>
+ <li><a class="subsection" href="#userinput">Getting user input</a>
+ <ol>
+ <li><a class="subsubsection" href="#mousepressrelease">Mouse button press and release events</a>
+ <li><a class="subsubsection" href="#mousemvnt">Mouse movement events</a>
+ <li><a class="subsubsection" href="#mouseenter">Mouse pointer enter and leave events</a>
+ <li><a class="subsubsection" href="#focus">The keyboard focus</a>
+ <li><a class="subsubsection" href="#keypress">Keyboard press and release events</a>
+ </ol>
+ <li><a class="subsection" href="#eventex">X events: a complete example</a>
</ol>
- <li><a class="section" href="#font">Handling text and fonts</a></li>
+ <li><a class="section" href="#font">Handling text and fonts</a>
<ol>
- <li><a class="subsection" href="#fontstruct">The Font structure</a></li>
- <li>Loading a Font</li>
- <li>Assigning a Font to a Graphic Context</li>
- <li>Drawing text in a window</li>
+ <li><a class="subsection" href="#fontstruct">The Font structure</a>
+ <li>Loading a Font
+ <li>Assigning a Font to a Graphic Context
+ <li>Drawing text in a window
</ol>
- <li>Windows hierarchy</li>
+ <li>Windows hierarchy
<ol>
- <li>Root, parent and child windows</li>
- <li>Events propagation</li>
+ <li>Root, parent and child windows
+ <li>Events propagation
</ol>
- <li><a class="section" href="#wm">Interacting with the window manager</a></li>
+ <li><a class="section" href="#wm">Interacting with the window manager</a>
<ol>
- <li><a class="subsection" href="#wmprop">Window properties</a></li>
- <li><a class="subsection" href="#wmname">Setting the window name and icon name</a></li>
- <li>Setting preferred window size(s)</li>
- <li>Setting miscellaneous window manager hints</li>
- <li>Setting an application's icon</li>
+ <li><a class="subsection" href="#wmprop">Window properties</a>
+ <li><a class="subsection" href="#wmname">Setting the window name and icon name</a>
+ <li>Setting preferred window size(s)
+ <li>Setting miscellaneous window manager hints
+ <li>Setting an application's icon
</ol>
- <li><a class="section" href="#winop">Simple window operations</a></li>
+ <li><a class="section" href="#winop">Simple window operations</a>
<ol>
- <li><a class="subsection" href="#winmap">Mapping and un-mapping a window</a></li>
- <li><a class="subsection" href="#winconf">Configuring a window</a></li>
- <li><a class="subsection" href="#winmove">Moving a window around the screen</a></li>
- <li><a class="subsection" href="#winsize">Resizing a window</a></li>
- <li><a class="subsection" href="#winstack">Changing windows stacking order: raise and lower</a></li>
- <li>Iconifying and de-iconifying a window</li>
- <li><a class="subsection" href="#wingetinfo">Getting informations about a window</a></li>
+ <li><a class="subsection" href="#winmap">Mapping and un-mapping a window</a>
+ <li><a class="subsection" href="#winconf">Configuring a window</a>
+ <li><a class="subsection" href="#winmove">Moving a window around the screen</a>
+ <li><a class="subsection" href="#winsize">Resizing a window</a>
+ <li><a class="subsection" href="#winstack">Changing windows stacking order: raise and lower</a>
+ <li>Iconifying and de-iconifying a window
+ <li><a class="subsection" href="#wingetinfo">Getting informations about a window</a>
</ol>
- <li><a class="section" href="#usecolor">Using colors to paint the rainbow</a></li>
+ <li><a class="section" href="#usecolor">Using colors to paint the rainbow</a>
<ol>
- <li><a class="subsection" href="#colormap">Color maps</a></li>
- <li><a class="subsection" href="#colormapalloc">Allocating and freeing Color Maps</a></li>
- <li><a class="subsection" href="#alloccolor">Allocating and freeing a color entry</a></li>
- <li>Drawing with a color</li>
+ <li><a class="subsection" href="#colormap">Color maps</a>
+ <li><a class="subsection" href="#colormapalloc">Allocating and freeing Color Maps</a>
+ <li><a class="subsection" href="#alloccolor">Allocating and freeing a color entry</a>
+ <li>Drawing with a color
</ol>
- <li><a class="section" href="#pixmaps">X Bitmaps and Pixmaps</a></li>
+ <li><a class="section" href="#pixmaps">X Bitmaps and Pixmaps</a>
<ol>
- <li><a class="subsection" href="#pixmapswhat">What is a X Bitmap ? An X Pixmap ?</a></li>
- <li>Loading a bitmap from a file</li>
- <li>Drawing a bitmap in a window</li>
- <li><a class="subsection" href="#pixmapscreate">Creating a pixmap</a></li>
- <li><a class="subsection" href="#pixmapsdraw">Drawing a pixmap in a window</a></li>
- <li><a class="subsection" href="#pixmapsfree">Freeing a pixmap</a></li>
+ <li><a class="subsection" href="#pixmapswhat">What is a X Bitmap ? An X Pixmap ?</a>
+ <li>Loading a bitmap from a file
+ <li>Drawing a bitmap in a window
+ <li><a class="subsection" href="#pixmapscreate">Creating a pixmap</a>
+ <li><a class="subsection" href="#pixmapsdraw">Drawing a pixmap in a window</a>
+ <li><a class="subsection" href="#pixmapsfree">Freeing a pixmap</a>
</ol>
- <li>Messing with the mouse cursor</li>
+ <li>Messing with the mouse cursor
<ol>
- <li>Creating and destroying a mouse cursor</li>
- <li>Setting a window's mouse cursor</li>
+ <li>Creating and destroying a mouse cursor
+ <li>Setting a window's mouse cursor
</ol>
- <li><a class="subsection" href="#translation">Translation of basic Xlib functions and macros</a></li>
+ <li><a class="subsection" href="#translation">Translation of basic Xlib functions and macros</a>
<ol>
- <li><a class="subsection" href="#displaystructure">Members of the Display structure</a></li>
+ <li><a class="subsection" href="#displaystructure">Members of the Display structure</a>
<ol>
- <li><a class="subsection" href="#ConnectionNumber">ConnectionNumber</a></li>
- <li><a class="subsection" href="#DefaultScreen">DefaultScreen</a></li>
- <li><a class="subsection" href="#QLength">QLength</a></li>
- <li><a class="subsection" href="#ScreenCount">ScreenCount</a></li>
- <li><a class="subsection" href="#ServerVendor">ServerVendor</a></li>
- <li><a class="subsection" href="#ProtocolVersion">ProtocolVersion</a></li>
- <li><a class="subsection" href="#ProtocolRevision">ProtocolRevision</a></li>
- <li><a class="subsection" href="#VendorRelease">VendorRelease</a></li>
- <li><a class="subsection" href="#DisplayString">DisplayString</a></li>
- <li><a class="subsection" href="#BitmapUnit">BitmapUnit</a></li>
- <li><a class="subsection" href="#BitmapBitOrder">BitmapBitOrder</a></li>
- <li><a class="subsection" href="#BitmapPad">BitmapPad</a></li>
- <li><a class="subsection" href="#ImageByteOrder">ImageByteOrder</a></li>
+ <li><a class="subsection" href="#ConnectionNumber">ConnectionNumber</a>
+ <li><a class="subsection" href="#DefaultScreen">DefaultScreen</a>
+ <li><a class="subsection" href="#QLength">QLength</a>
+ <li><a class="subsection" href="#ScreenCount">ScreenCount</a>
+ <li><a class="subsection" href="#ServerVendor">ServerVendor</a>
+ <li><a class="subsection" href="#ProtocolVersion">ProtocolVersion</a>
+ <li><a class="subsection" href="#ProtocolRevision">ProtocolRevision</a>
+ <li><a class="subsection" href="#VendorRelease">VendorRelease</a>
+ <li><a class="subsection" href="#DisplayString">DisplayString</a>
+ <li><a class="subsection" href="#BitmapUnit">BitmapUnit</a>
+ <li><a class="subsection" href="#BitmapBitOrder">BitmapBitOrder</a>
+ <li><a class="subsection" href="#BitmapPad">BitmapPad</a>
+ <li><a class="subsection" href="#ImageByteOrder">ImageByteOrder</a>
</ol>
- <li><a class="subsection" href="#screenofdisplay">ScreenOfDisplay related functions</a></li>
+ <li><a class="subsection" href="#screenofdisplay">ScreenOfDisplay related functions</a>
<ol>
- <li><a class="subsection" href="#ScreenOfDisplay">ScreenOfDisplay</a></li>
- <li><a class="subsection" href="#DefaultScreenOfDisplay">DefaultScreenOfDisplay</a></li>
- <li><a class="subsection" href="#RootWindow">RootWindow / RootWindowOfScreen</a></li>
- <li><a class="subsection" href="#DefaultRootWindow">DefaultRootWindow</a></li>
- <li><a class="subsection" href="#DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a></li>
- <li><a class="subsection" href="#DefaultGC">DefaultGC / DefaultGCOfScreen</a></li>
- <li><a class="subsection" href="#BlackPixel">BlackPixel / BlackPixelOfScreen</a></li>
- <li><a class="subsection" href="#WhitePixel">WhitePixel / WhitePixelOfScreen</a></li>
- <li><a class="subsection" href="#DisplayWidth">DisplayWidth / WidthOfScreen</a></li>
- <li><a class="subsection" href="#DisplayHeight">DisplayHeight / HeightOfScreen</a></li>
- <li><a class="subsection" href="#DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a></li>
- <li><a class="subsection" href="#DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a></li>
- <li><a class="subsection" href="#DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a></li>
- <li><a class="subsection" href="#DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a></li>
- <li><a class="subsection" href="#MinCmapsOfScreen">MinCmapsOfScreen</a></li>
- <li><a class="subsection" href="#MaxCmapsOfScreen">MaxCmapsOfScreen</a></li>
- <li><a class="subsection" href="#DoesSaveUnders">DoesSaveUnders</a></li>
- <li><a class="subsection" href="#DoesBackingStore">DoesBackingStore</a></li>
- <li><a class="subsection" href="#EventMaskOfScreen">EventMaskOfScreen</a></li>
+ <li><a class="subsection" href="#ScreenOfDisplay">ScreenOfDisplay</a>
+ <li><a class="subsection" href="#DefaultScreenOfDisplay">DefaultScreenOfDisplay</a>
+ <li><a class="subsection" href="#RootWindow">RootWindow / RootWindowOfScreen</a>
+ <li><a class="subsection" href="#DefaultRootWindow">DefaultRootWindow</a>
+ <li><a class="subsection" href="#DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a>
+ <li><a class="subsection" href="#DefaultGC">DefaultGC / DefaultGCOfScreen</a>
+ <li><a class="subsection" href="#BlackPixel">BlackPixel / BlackPixelOfScreen</a>
+ <li><a class="subsection" href="#WhitePixel">WhitePixel / WhitePixelOfScreen</a>
+ <li><a class="subsection" href="#DisplayWidth">DisplayWidth / WidthOfScreen</a>
+ <li><a class="subsection" href="#DisplayHeight">DisplayHeight / HeightOfScreen</a>
+ <li><a class="subsection" href="#DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a>
+ <li><a class="subsection" href="#DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a>
+ <li><a class="subsection" href="#DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a>
+ <li><a class="subsection" href="#DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a>
+ <li><a class="subsection" href="#MinCmapsOfScreen">MinCmapsOfScreen</a>
+ <li><a class="subsection" href="#MaxCmapsOfScreen">MaxCmapsOfScreen</a>
+ <li><a class="subsection" href="#DoesSaveUnders">DoesSaveUnders</a>
+ <li><a class="subsection" href="#DoesBackingStore">DoesBackingStore</a>
+ <li><a class="subsection" href="#EventMaskOfScreen">EventMaskOfScreen</a>
</ol>
- <li><a class="subsection" href="#misc">Miscellaneaous macros</a></li>
+ <li><a class="subsection" href="#misc">Miscellaneaous macros</a>
<ol>
- <li><a class="subsection" href="#DisplayOfScreen">DisplayOfScreen</a></li>
- <li><a class="subsection" href="#DisplayCells">DisplayCells / CellsOfScreen</a></li>
+ <li><a class="subsection" href="#DisplayOfScreen">DisplayOfScreen</a>
+ <li><a class="subsection" href="#DisplayCells">DisplayCells / CellsOfScreen</a>
</ol>
</ol>
</ol>
</div>
<div class="section">
<ol>
- <li class="title"><a name="intro">Introduction</a></li>
+ <li class="title"><a name="intro">Introduction</a>
<p>
This tutorial is based on the
<a href="http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html">Xlib Tutorial</a>
Window System</a> protocol for many years now. It is an
excellent piece of work, but there are applications for which it
is not ideal, for example
+ </p>
<ul>
<li><b>Small platforms</b>: Xlib is a large piece of code, and
- it's difficult to make it smaller</li>
+ it's difficult to make it smaller
<li><b>Latency hiding</b>: Xlib requests requiring a reply are
- effectively synchronous: they block until the reply appears,
- whether the result is needed immediately or not.</li>
- <li><b>Direct access to the protocol</b>: Xlib does quite a
- bit of caching, layering, and similar optimizations. While this
- is normally a feature, it makes it difficult to simply emit
- specified X protocol requests and process specific
- responses.</li>
- <li><b>Threaded applications</b>: While Xlib does attempt to
- support multithreading, the API makes this difficult and
- error-prone.</li>
- <li><b>New extensions</b>: The Xlib infrastructure provides
- limited support for the new creation of X extension client side
- code.</li>
+ effectively synchronous: they block until the reply appears,
+ whether the result is needed immediately or not.
+ <li><b>Direct access to the protocol</b>: Xlib does quite a
+ bit of caching, layering, and similar optimizations. While this
+ is normally a feature, it makes it difficult to simply emit
+ specified X protocol requests and process specific
+ responses.
+ <li><b>Threaded applications</b>: While Xlib does attempt to
+ support multithreading, the API makes this difficult and
+ error-prone.
+ <li><b>New extensions</b>: The Xlib infrastructure provides
+ limited support for the new creation of X extension client side
+ code.
</ul>
- </p>
<p>
For these reasons, among others, XCB, an X C binding, has been
designed to solve the above problems and thus provide a base for
+ </p>
<ul>
- <li>Toolkit implementation.</li>
- <li>Direct protocol-level programming.</li>
- <li>Lightweight emulation of commonly used portions of the
- Xlib API (in progress)</li>
+ <li>Toolkit implementation.
+ <li>Direct protocol-level programming.
+ <li>Lightweight emulation of commonly used portions of the
+ Xlib API (in progress)
</ul>
- </p>
- <p></p>
- <li class="title"><a name="Xmodel">The client and server model of the X window system</a></li>
+ <br>
+ <li class="title"><a name="Xmodel">The client and server model of the X window system</a>
<p>
The X Window System was developed with one major goal:
flexibility. The idea was that the way things look is one thing,
using shared memory, or using Unix domain sockets (a method for
creating a logical channel on a Unix system between two processes).
</p>
- <li class="title"><a name="asynch">GUI programming: the asynchronous model</a></li>
+ <li class="title"><a name="asynch">GUI programming: the asynchronous model</a>
<p>
Unlike conventional computer programs, that carry some serial
nature, a GUI program usually uses an asynchronous programming
</p>
<p>
So the way a GUI program looks is something like that:
+ </p>
<ol>
- <li>Perform initialization routines.</li>
- <li>Connect to the X server.</li>
- <li>Perform X-related initialization.</li>
- <li>While not finished:</li>
- <ol>
- <li>Receive the next event from the X server.</li>
- <li>Handle the event, possibly sending various drawing
- requests to the X server.</li>
- <li>If the event was a quit message, exit the loop.</li>
- </ol>
- <li>Close down the connection to the X server. </li>
- <li>Perform cleanup operations.</li>
+ <li>Perform initialization routines.
+ <li>Connect to the X server.
+ <li>Perform X-related initialization.
+ <li>While not finished:
+ <ol>
+ <li>Receive the next event from the X server.
+ <li>Handle the event, possibly sending various drawing
+ requests to the X server.
+ <li>If the event was a quit message, exit the loop.
+ </ol>
+ <li>Close down the connection to the X server.
+ <li>Perform cleanup operations.
</ol>
- </p>
- <p></p>
- <li class="title"><a name="notions">Basic XCB notions</a></li>
+ <br>
+ <li class="title"><a name="notions">Basic XCB notions</a>
<p>
XCB has been created to eliminate the needs of
programs to actually implement the X protocol layer. This
the basic XCB notions. They will be detailed later.
</p>
<ol>
- <li class="subtitle"><a name="conn">The X Connection</a></li>
- <p>
- The major notion of using XCB is the X Connection. This is a
- structure representing the connection we have open with a
- given X server. It hides a queue of messages coming from the
- server, and a queue of pending requests that our client
- intends to send to the server. In XCB, this structure is named
- 'XCBConnection'. When we open a connection to an X server, the
- library returns a pointer to such a structure. Later, we
- supply this pointer to any XCB function that should send
- messages to the X server or receive messages from this server.
- </p>
+ <li class="subtitle"><a name="conn">The X Connection</a>
+ <p>
+ The major notion of using XCB is the X Connection. This is a
+ structure representing the connection we have open with a
+ given X server. It hides a queue of messages coming from the
+ server, and a queue of pending requests that our client
+ intends to send to the server. In XCB, this structure is named
+ 'XCBConnection'. When we open a connection to an X server, the
+ library returns a pointer to such a structure. Later, we
+ supply this pointer to any XCB function that should send
+ messages to the X server or receive messages from this server.
+ </p>
<li class="subtitle"><a name="requestsreplies">Requests and
- replies: the Xlib killers</a></li>
- <p>
+ replies: the Xlib killers</a>
+ <p>
To ask informations to the X server, we have to make a request
and ask for a reply. With Xlib, these two tasks are
automatically done: Xlib locks the system, sends a request,
requests/replies with Xlib, with a round-trip latency
<b>T_round_trip</b> that is 5 times long as the time required
to write or read a request/reply (<b>T_write/T_read</b>):
- </p>
- <pre class="text">
+ </p>
+ <pre class="text">
W-----RW-----RW-----RW-----R
</pre>
<ul>
- <li>W: Writing request</li>
- <li>-: Stalled, waiting for data</li>
- <li>R: Reading reply</li>
+ <li>W: Writing request
+ <li>-: Stalled, waiting for data
+ <li>R: Reading reply
</ul>
<p>
The total time is N * (T_write + T_round_trip + T_read).
when we need them. Here is the time-line for 4
requests/replies when we use this property of XCB:
</p>
- <pre class="text">
+ <pre class="text">
WWWW--RRRR
</pre>
<p>
{
struct timeval timev;
- gettimeofday(&timev, NULL);
+ gettimeofday(&timev, NULL);
return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
}
return 1;
}
</pre>
- <li class="subtitle"><a name="gc">The Graphic Context</a></li>
- <p>
- When we perform various drawing operations (graphics, text,
- etc), we may specify various options for controlling how the
- data will be drawn (what foreground and background colors to
- use, how line edges will be connected, what font to use when
- drawing some text, etc). In order to avoid the need to supply
- hundreds of parameters to each drawing function, a graphical
- context structure is used. We set the various drawing options
- in this structure, and then we pass a pointer to this
- structure to any drawing routines. This is rather handy, as we
- often need to perform several drawing requests with the same
- options. Thus, we would initialize a graphical context, set
- the desired options, and pass this structure to all drawing
- functions.
- </p>
+ <li class="subtitle"><a name="gc">The Graphic Context</a>
+ <p>
+ When we perform various drawing operations (graphics, text,
+ etc), we may specify various options for controlling how the
+ data will be drawn (what foreground and background colors to
+ use, how line edges will be connected, what font to use when
+ drawing some text, etc). In order to avoid the need to supply
+ hundreds of parameters to each drawing function, a graphical
+ context structure is used. We set the various drawing options
+ in this structure, and then we pass a pointer to this
+ structure to any drawing routines. This is rather handy, as we
+ often need to perform several drawing requests with the same
+ options. Thus, we would initialize a graphical context, set
+ the desired options, and pass this structure to all drawing
+ functions.
+ </p>
<p>
Note that graphic contexts have no client-side structure in
XCB, they're just XIDs. Xlib has a client-side structure
because it caches the GC contents so it can avoid making
redundant requests, but of course XCB doesn't do that.
</p>
- <li class="subtitle"><a name="events">Events</a></li>
- <p>
- A structure is used to pass events received from the X
- server. XCB supports exactly the events specified in the
- protocol (33 events). This structure contains the type
- of event received, as well as the data associated with the
- event (e.g. position on the screen where the event was
- generated, mouse button associated with the event, region of
- the screen associated with a "redraw" event, etc). The way to
- read the event's data epends on the event type.
- </p>
+ <li class="subtitle"><a name="events">Events</a>
+ <p>
+ A structure is used to pass events received from the X
+ server. XCB supports exactly the events specified in the
+ protocol (33 events). This structure contains the type
+ of event received, as well as the data associated with the
+ event (e.g. position on the screen where the event was
+ generated, mouse button associated with the event, region of
+ the screen associated with a "redraw" event, etc). The way to
+ read the event's data epends on the event type.
+ </p>
</ol>
- <p></p>
- <li class="title"><a name="use">Using XCB-based programs</a></li>
- <p></p>
+ <br>
+ <li class="title"><a name="use">Using XCB-based programs</a>
+ <br>
<ol>
- <li class="subtitle"><a name="inst">Installation of XCB</a></li>
- <p>
- To build XCB from source, you need to have installed at
- least:
- </p>
- <ul>
- <li>pkgconfig 0.15.0</li>
- <li>automake 1.7</li>
- <li>autoconf 2.50</li>
- <li><a href="http://www.check.org">check</a></li>
- <li><a href="http://xmlsoft.org/XSLT/">xsltproc</a></li>
- </ul>
- <p>
- You have to checkout in CVS the following modules:
- </p>
- <ul>
- <li>Xproto from xlibs</li>
- <li>Xau from xlibs</li>
- <li>xcb-proto</li>
- <li>xcb</li>
- </ul>
- <p>
- Note that Xproto and xcb-proto exist only to install header
- files, so typing 'make' or 'make all' will produce the message
- "Nothing to be done for 'all'". That's normal.
- </p>
- <li class="subtitle"><a name="comp">Compiling XCB-based programs</a></li>
- <p>
- Compiling XCB-based programs requires linking them with the XCB
- library. This is easily done thanks to pkgconfig:
- </p>
- <pre class="text">
+ <li class="subtitle"><a name="inst">Installation of XCB</a>
+ <p>
+ To build XCB from source, you need to have installed at
+ least:
+ </p>
+ <ul>
+ <li>pkgconfig 0.15.0
+ <li>automake 1.7
+ <li>autoconf 2.50
+ <li><a href="http://www.check.org">check</a>
+ <li><a href="http://xmlsoft.org/XSLT/">xsltproc</a>
+ </ul>
+ <p>
+ You have to checkout in CVS the following modules:
+ </p>
+ <ul>
+ <li>Xproto from xlibs
+ <li>Xau from xlibs
+ <li>xcb-proto
+ <li>xcb
+ </ul>
+ <p>
+ Note that Xproto and xcb-proto exist only to install header
+ files, so typing 'make' or 'make all' will produce the message
+ "Nothing to be done for 'all'". That's normal.
+ </p>
+ <li class="subtitle"><a name="comp">Compiling XCB-based programs</a>
+ <p>
+ Compiling XCB-based programs requires linking them with the XCB
+ library. This is easily done thanks to pkgconfig:
+ </p>
+ <pre class="text">
gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
</pre>
</ol>
- <li class="title"><a name="openconn">Opening and closing the connection to an X server</a></li>
+ <li class="title"><a name="openconn">Opening and closing the connection to an X server</a>
<p>
An X program first needs to open the connection to the X
server. There is a function that opens a connection. It requires
</pre>
<div class="comp">
<div class="title">
- Comparison Xlib/XCB
- </div>
- <div class="xlib">
- <ul>
- <li>XOpenDisplay ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBConnect ()</li>
- </ul>
- </div>
- <div class="xlib">
- <ul>
- <li>XCloseDisplay ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBDisconnect ()</li>
- </ul>
- </div>
+ Comparison Xlib/XCB
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XOpenDisplay ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBConnect ()
+ </ul>
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XCloseDisplay ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBDisconnect ()
+ </ul>
+ </div>
</div>
<p>
</p>
- <li class="title"><a name="screen">Checking basic information about a connection</a></li>
+ <li class="title"><a name="screen">Checking basic information about a connection</a>
<p>
Once we opened a connection to an X server, we should check some
basic informations about it: what screens it has, what is the
XCBSCREENIter iter;
/* Open the connection to the X server. Use the DISPLAY environment variable */
- c = XCBConnect (NULL, &screen_nbr);
+ c = XCBConnect (NULL, &screen_nbr);
/* Get the screen #screen_nbr */
iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
- for (; iter.rem; --screen_nbr, XCBSCREENNext (&iter))
+ for (; iter.rem; --screen_nbr, XCBSCREENNext (&iter))
if (screen_nbr == 0)
{
screen = iter.data;
return 1;
}
</pre>
- <li class="title"><a name="helloworld">Creating a basic window - the "hello world" program</a></li>
+ <li class="title"><a name="helloworld">Creating a basic window - the "hello world" program</a>
<p>
After we got some basic informations about our screen, we can
create our first window. In the X Window System, a window is
XCBVoidCookie XCBCreateWindow (XCBConnection *c, /* Pointer to the XCBConnection structure */
CARD8 depth, /* Depth of the screen */
XCBWINDOW wid, /* Id of the window */
- XCBWINDOW parent, /* Id of an existing window that should be the parent of the new window */
- INT16 x, /* X position of the top-left corner of the window (in pixels) */
- INT16 y, /* Y position of the top-left corner of the window (in pixels) */
- CARD16 width, /* Width of the window (in pixels) */
- CARD16 height, /* Height of the window (in pixels) */
- CARD16 border_width, /* Width of the window's border (in pixels) */
- CARD16 _class,
- XCBVISUALID visual,
- CARD32 value_mask,
- const CARD32 *value_list);
+ XCBWINDOW parent, /* Id of an existing window that should be the parent of the new window */
+ INT16 x, /* X position of the top-left corner of the window (in pixels) */
+ INT16 y, /* Y position of the top-left corner of the window (in pixels) */
+ CARD16 width, /* Width of the window (in pixels) */
+ CARD16 height, /* Height of the window (in pixels) */
+ CARD16 border_width, /* Width of the window's border (in pixels) */
+ CARD16 _class,
+ XCBVISUALID visual,
+ CARD32 value_mask,
+ const CARD32 *value_list);
</pre>
<p>
The fact that we created the window does not mean that it will
/* Create the window */
XCBCreateWindow (c, /* Connection */
- 0, /* depth */
- win.window, /* window Id */
- screen->root, /* parent window */
- 0, 0, /* x, y */
- 150, 150, /* width, height */
- 10, /* border_width */
- InputOutput, /* class */
- screen->root_visual, /* visual */
- 0, NULL); /* masks, not used yet */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ 150, 150, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ 0, NULL); /* masks, not used yet */
/* Map the window on the screen */
XCBMapWindow (c, win.window);
</p>
<div class="comp">
<div class="title">
- Comparison Xlib/XCB
- </div>
- <div class="xlib">
- <ul>
- <li>XCreateWindow ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBWINDOWNew ()</li>
- <li>XCBCreateWindow ()</li>
- </ul>
- </div>
+ Comparison Xlib/XCB
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XCreateWindow ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBWINDOWNew ()
+ <li>XCBCreateWindow ()
+ </ul>
+ </div>
</div>
- <p></p>
- <li class="title"><a name="drawing">Drawing in a window</a></li>
+ <br>
+ <li class="title"><a name="drawing">Drawing in a window</a>
<p>
Drawing in a window can be done using various graphical
functions (drawing pixels, lines, rectangles, etc). In order to
with, etc). This is done using a graphical context.
</p>
<ol>
- <li class="subtitle"><a name="allocgc">Allocating a Graphics Context</a></li>
+ <li class="subtitle"><a name="allocgc">Allocating a Graphics Context</a>
<p>
- As we said, a graphical context defines several attributes to
- be used with the various drawing functions. For this, we
- define a graphical context. We can use more than one graphical
- context with a single window, in order to draw in multiple
- styles (different colors, different line widths, etc). In XCB,
- a Graphics Context is, as a window, characterized by an Id:
+ As we said, a graphical context defines several attributes to
+ be used with the various drawing functions. For this, we
+ define a graphical context. We can use more than one graphical
+ context with a single window, in order to draw in multiple
+ styles (different colors, different line widths, etc). In XCB,
+ a Graphics Context is, as a window, characterized by an Id:
</p>
- <pre class="code">
+ <pre class="code">
typedef struct {
CARD32 xid;
} XCBGCONTEXT;
</pre>
<p>
We first ask the X server to attribute an Id to our graphic
- context with this function:
+ context with this function:
</p>
- <pre class="code">
+ <pre class="code">
XCBGCONTEXT XCBGCONTEXTNew (XCBConnection *c);
</pre>
<p>
Then, we set the attributes of the graphic context with this function:
</p>
- <pre class="code">
+ <pre class="code">
XCBVoidCookie XCBCreateGC (XCBConnection *c,
XCBGCONTEXT cid,
- XCBDRAWABLE drawable,
- CARD32 value_mask,
- const CARD32 *value_list);
+ XCBDRAWABLE drawable,
+ CARD32 value_mask,
+ const CARD32 *value_list);
</pre>
<p>
- We give now an example on how to allocate a graphic context
- that specifies that each drawing functions that use it will
- draw in foreground with a black color.
- </p>
+ We give now an example on how to allocate a graphic context
+ that specifies that each drawing functions that use it will
+ draw in foreground with a black color.
+ </p>
<pre class="code">
#include <X11/XCB/xcb.h>
</pre>
<p>
Note should be taken regarding the role of "value_mask" and
- "value_list" in the prototype of <span class="code">XCBCreateGC()</span>. Since a
- graphic context has many attributes, and since we often just
- want to define a few of them, we need to be able to tell the
- <span class="code">XCBCreateGC()</span> which attributes we
- want to set. This is what the "value_mask" parameter is
- for. We then use the "value_list" parameter to specify actual
- values for the attribute we defined in "value_mask". Thus, for
- each constant used in "value_list", we will use the matching
- constant in "value_mask". In this case, we define a graphic
- context with one attribute: when drawing (a point, a line,
- etc), the foreground color will be black. The rest of the
- attributes of this graphic context will be set to their
- default values.
- </p>
- <p>
- See the next Subsection for more details.
- </p>
+ "value_list" in the prototype of <span class="code">XCBCreateGC()</span>. Since a
+ graphic context has many attributes, and since we often just
+ want to define a few of them, we need to be able to tell the
+ <span class="code">XCBCreateGC()</span> which attributes we
+ want to set. This is what the "value_mask" parameter is
+ for. We then use the "value_list" parameter to specify actual
+ values for the attribute we defined in "value_mask". Thus, for
+ each constant used in "value_list", we will use the matching
+ constant in "value_mask". In this case, we define a graphic
+ context with one attribute: when drawing (a point, a line,
+ etc), the foreground color will be black. The rest of the
+ attributes of this graphic context will be set to their
+ default values.
+ </p>
+ <p>
+ See the next Subsection for more details.
+ </p>
<div class="comp">
<div class="title">
- Comparison Xlib/XCB
- </div>
- <div class="xlib">
- <ul>
- <li>XCreateGC ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBGCONTEXTNew ()</li>
- <li>XCBCreateGC ()</li>
- </ul>
- </div>
+ Comparison Xlib/XCB
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XCreateGC ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBGCONTEXTNew ()
+ <li>XCBCreateGC ()
+ </ul>
+ </div>
</div>
- <p></p>
- <li class="subtitle"><a name="changegc">Changing the attributes of a Graphics Context</a></li>
- <p>
- Once we have allocated a Graphic Context, we may need to
- change its attributes (for example, changing the foreground
- color we use to draw a line, or changing the attributes of the
- font we use to display strings. See Subsections Drawing with a
- color and Assigning a Font to a Graphic Context). This is done
- by using this function:
- </p>
- <pre class="code">
+ <br>
+ <li class="subtitle"><a name="changegc">Changing the attributes of a Graphics Context</a>
+ <p>
+ Once we have allocated a Graphic Context, we may need to
+ change its attributes (for example, changing the foreground
+ color we use to draw a line, or changing the attributes of the
+ font we use to display strings. See Subsections Drawing with a
+ color and Assigning a Font to a Graphic Context). This is done
+ by using this function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBChangeGC (XCBConnection *c, /* The XCB Connection */
XCBGCONTEXT gc, /* The Graphic Context */
- CARD32 value_mask, /* Components of the Graphic Context that have to be set */
- const CARD32 *value_list); /* Value as specified by value_mask */
-</pre>
- <p>
- The <span class="code">value_mask</span> parameter could take
- these values:
- </p>
- <ul>
- <li>GCFunction</li>
- <li>GCPlaneMask</li>
- <li>GCForeground</li>
- <li>GCBackground</li>
- <li>GCLineWidth</li>
- <li>GCLineStyle</li>
- <li>GCCapStyle</li>
- <li>GCJoinStyle</li>
- <li>GCFillStyle</li>
- <li>GCFillRule</li>
- <li>GCTile</li>
- <li>GCStipple</li>
- <li>GCTileStipXOrigin</li>
- <li>GCTileStipYOrigin</li>
- <li>GCFont</li>
- <li>GCSubwindowMode</li>
- <li>GCGraphicsExposures</li>
- <li>GCClipXOrigin</li>
- <li>GCClipYOrigin</li>
- <li>GCClipMask</li>
- <li>GCDashOffset</li>
- <li>GCDashList</li>
- <li>GCArcMode</li>
- </ul>
- <p>
- It is possible to set several attributes at the same
- time (for example setting the attributes of a font and the
- color which will be used to display a string), by OR'ing these
- values in <span class="code">value_mask</span>. Then
- <span class="code">value_list</span> has to be an array which
- lists the value for the respective attributes. See Subsection
- Drawing with a color to have an example.
- </p>
- <p>
- <b>TODO</b>: set the links of the 3 subsections, once they will
- be written :)
- </p>
- <p>
- <b>TODO</b>: give an example which sets several attributes.
- </p>
- <li class="subtitle"><a name="drawingprim">Drawing primitives: point, line, box, circle,...</a></li>
- <p>
- After we have created a Graphic Context, we can draw on a
- window using this Graphic Context, with a set of XCB
- functions, collectively called "drawing primitive". Let see
- how they are used.
- </p>
- <p>
- To draw a point, or several points, we use
- </p>
- <pre class="code">
+ CARD32 value_mask, /* Components of the Graphic Context that have to be set */
+ const CARD32 *value_list); /* Value as specified by value_mask */
+</pre>
+ <p>
+ The <span class="code">value_mask</span> parameter could take
+ these values:
+ </p>
+ <ul>
+ <li>GCFunction
+ <li>GCPlaneMask
+ <li>GCForeground
+ <li>GCBackground
+ <li>GCLineWidth
+ <li>GCLineStyle
+ <li>GCCapStyle
+ <li>GCJoinStyle
+ <li>GCFillStyle
+ <li>GCFillRule
+ <li>GCTile
+ <li>GCStipple
+ <li>GCTileStipXOrigin
+ <li>GCTileStipYOrigin
+ <li>GCFont
+ <li>GCSubwindowMode
+ <li>GCGraphicsExposures
+ <li>GCClipXOrigin
+ <li>GCClipYOrigin
+ <li>GCClipMask
+ <li>GCDashOffset
+ <li>GCDashList
+ <li>GCArcMode
+ </ul>
+ <p>
+ It is possible to set several attributes at the same
+ time (for example setting the attributes of a font and the
+ color which will be used to display a string), by OR'ing these
+ values in <span class="code">value_mask</span>. Then
+ <span class="code">value_list</span> has to be an array which
+ lists the value for the respective attributes. See Subsection
+ Drawing with a color to have an example.
+ </p>
+ <p>
+ <b>TODO</b>: set the links of the 3 subsections, once they will
+ be written :)
+ </p>
+ <p>
+ <b>TODO</b>: give an example which sets several attributes.
+ </p>
+ <li class="subtitle"><a name="drawingprim">Drawing primitives: point, line, box, circle,...</a>
+ <p>
+ After we have created a Graphic Context, we can draw on a
+ window using this Graphic Context, with a set of XCB
+ functions, collectively called "drawing primitive". Let see
+ how they are used.
+ </p>
+ <p>
+ To draw a point, or several points, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyPoint (XCBConnection *c, /* The connection to the X server */
BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
- XCBDRAWABLE drawable, /* The drawable on which we want to draw the point(s) */
- XCBGCONTEXT gc, /* The Graphic Context we use to draw the point(s) */
- CARD32 points_len, /* The number of points */
- const XCBPOINT *points); /* An array of points */
-</pre>
- <p>
- The <span class="code">coordinate_mode</span> parameter
- specifies the coordinate mode. Available values are
- </p>
- <ul>
- <li><span class="code">CoordModeOrigin</span></li>
- <li><span class="code">CoordModePrevious</span></li>
- </ul>
- <p>
- The <span class="code">XCBPOINT</span> type is just a
- structure with two fields (the coordinates of the point):
- </p>
- <pre class="code">
+ XCBDRAWABLE drawable, /* The drawable on which we want to draw the point(s) */
+ XCBGCONTEXT gc, /* The Graphic Context we use to draw the point(s) */
+ CARD32 points_len, /* The number of points */
+ const XCBPOINT *points); /* An array of points */
+</pre>
+ <p>
+ The <span class="code">coordinate_mode</span> parameter
+ specifies the coordinate mode. Available values are
+ </p>
+ <ul>
+ <li><span class="code">CoordModeOrigin</span>
+ <li><span class="code">CoordModePrevious</span>
+ </ul>
+ <p>
+ The <span class="code">XCBPOINT</span> type is just a
+ structure with two fields (the coordinates of the point):
+ </p>
+ <pre class="code">
typedef struct {
INT16 x;
INT16 y;
} XCBPOINT;
</pre>
<p>
- You could see an example in xpoints.c. <b>TODO</b> Set the link.
- </p>
- <p>
- To draw a line, or a polygonal line, we use
- </p>
- <pre class="code">
+ You could see an example in xpoints.c. <b>TODO</b> Set the link.
+ </p>
+ <p>
+ To draw a line, or a polygonal line, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyLine (XCBConnection *c, /* The connection to the X server */
BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
- XCBDRAWABLE drawable, /* The drawable on which we want to draw the line(s) */
- XCBGCONTEXT gc, /* The Graphic Context we use to draw the line(s) */
- CARD32 points_len, /* The number of points in the polygonal line */
- const XCBPOINT *points); /* An array of points */
-</pre>
- <p>
- This function will draw the line between the first and the
- second points, then the line between the second and the third
- points, and so on.
- </p>
- <p>
- To draw a segment, or several segments, we use
- </p>
- <pre class="code">
+ XCBDRAWABLE drawable, /* The drawable on which we want to draw the line(s) */
+ XCBGCONTEXT gc, /* The Graphic Context we use to draw the line(s) */
+ CARD32 points_len, /* The number of points in the polygonal line */
+ const XCBPOINT *points); /* An array of points */
+</pre>
+ <p>
+ This function will draw the line between the first and the
+ second points, then the line between the second and the third
+ points, and so on.
+ </p>
+ <p>
+ To draw a segment, or several segments, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolySegment (XCBConnection *c, /* The connection to the X server */
XCBDRAWABLE drawable, /* The drawable on which we want to draw the segment(s) */
- XCBGCONTEXT gc, /* The Graphic Context we use to draw the segment(s) */
- CARD32 segments_len, /* The number of segments */
- const XCBSEGMENT *segments); /* An array of segments */
-</pre>
- <p>
- The <span class="code">XCBSEGMENT</span> type is just a
- structure with four fields (the coordinates of the two points
- that define the segment):
- </p>
- <pre class="code">
+ XCBGCONTEXT gc, /* The Graphic Context we use to draw the segment(s) */
+ CARD32 segments_len, /* The number of segments */
+ const XCBSEGMENT *segments); /* An array of segments */
+</pre>
+ <p>
+ The <span class="code">XCBSEGMENT</span> type is just a
+ structure with four fields (the coordinates of the two points
+ that define the segment):
+ </p>
+ <pre class="code">
typedef struct {
INT16 x1;
INT16 y1;
INT16 y2;
} XCBSEGMENT;
</pre>
- <p>
- To draw a rectangle, or several rectangles, we use
- </p>
- <pre class="code">
+ <p>
+ To draw a rectangle, or several rectangles, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyRectangle (XCBConnection *c, /* The connection to the X server */
- XCBDRAWABLE drawable, /* The drawable on which we want to draw the rectangle(s) */
- XCBGCONTEXT gc, /* The Graphic Context we use to draw the rectangle(s) */
- CARD32 rectangles_len, /* The number of rectangles */
- const XCBRECTANGLE *rectangles); /* An array of rectangles */
-</pre>
- <p>
- The <span class="code">XCBRECTANGLE</span> type is just a
- structure with four fields (the coordinates of the top-left
- corner of the rectangle, and its width and height):
- </p>
- <pre class="code">
+ XCBDRAWABLE drawable, /* The drawable on which we want to draw the rectangle(s) */
+ XCBGCONTEXT gc, /* The Graphic Context we use to draw the rectangle(s) */
+ CARD32 rectangles_len, /* The number of rectangles */
+ const XCBRECTANGLE *rectangles); /* An array of rectangles */
+</pre>
+ <p>
+ The <span class="code">XCBRECTANGLE</span> type is just a
+ structure with four fields (the coordinates of the top-left
+ corner of the rectangle, and its width and height):
+ </p>
+ <pre class="code">
typedef struct {
INT16 x;
INT16 y;
CARD16 height;
} XCBRECTANGLE;
</pre>
- <p>
- <b>TODO</b>: there's no coordinate_mode. Is it normal ?
- </p>
- <p>
- To draw an elliptical arc, or several elliptical arcs, we use
- </p>
- <pre class="code">
+ <p>
+ <b>TODO</b>: there's no coordinate_mode. Is it normal ?
+ </p>
+ <p>
+ To draw an elliptical arc, or several elliptical arcs, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyArc (XCBConnection *c, /* The connection to the X server */
XCBDRAWABLE drawable, /* The drawable on which we want to draw the arc(s) */
- XCBGCONTEXT gc, /* The Graphic Context we use to draw the arc(s) */
- CARD32 arcs_len, /* The number of arcs */
- const XCBARC *arcs); /* An array of arcs */
-</pre>
- <p>
- The <span class="code">XCBARC</span> type is a structure with
- six fields:
- </p>
- <pre class="code">
+ XCBGCONTEXT gc, /* The Graphic Context we use to draw the arc(s) */
+ CARD32 arcs_len, /* The number of arcs */
+ const XCBARC *arcs); /* An array of arcs */
+</pre>
+ <p>
+ The <span class="code">XCBARC</span> type is a structure with
+ six fields:
+ </p>
+ <pre class="code">
typedef struct {
INT16 x; /* Top left x coordinate of the rectangle surrounding the ellipse */
INT16 y; /* Top left y coordinate of the rectangle surrounding the ellipse */
INT16 angle2; /* Angle at which the arc ends */
} XCBARC;
</pre>
- <div class="emph">
- <p>
- Note: the angles are expressed in units of 1/64 of a degree,
- so to have an angle of 90 degrees, starting at 0,
- <span class="code">angle1 = 0</span> and
- <span class="code">angle2 = 90 << 6</span>. Positive angles
- indicate counterclockwise motion, while negative angles
- indicate clockwise motion.
- </p>
- </div>
- <p>
- <b>TODO</b>: there's no coordinate_mode. Is it normal ?
- </p>
- <p>
- <b>TODO</b>: I think that (x,y) should be the center of the
- ellipse, and (width, height) the radius. It's more logical.
- </p>
- <p>
- The corresponding function which fill inside the geometrical
- object are listed below, without further explanation, as they
- are used as the above functions.
- </p>
- <p>
- To Fill a polygon defined by the points given as arguments ,
- we use
- </p>
- <pre class="code">
+ <div class="emph">
+ <p>
+ Note: the angles are expressed in units of 1/64 of a degree,
+ so to have an angle of 90 degrees, starting at 0,
+ <span class="code">angle1 = 0</span> and
+ <span class="code">angle2 = 90 << 6</span>. Positive angles
+ indicate counterclockwise motion, while negative angles
+ indicate clockwise motion.
+ </p>
+ </div>
+ <p>
+ <b>TODO</b>: there's no coordinate_mode. Is it normal ?
+ </p>
+ <p>
+ <b>TODO</b>: I think that (x,y) should be the center of the
+ ellipse, and (width, height) the radius. It's more logical.
+ </p>
+ <p>
+ The corresponding function which fill inside the geometrical
+ object are listed below, without further explanation, as they
+ are used as the above functions.
+ </p>
+ <p>
+ To Fill a polygon defined by the points given as arguments ,
+ we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBFillPoly (XCBConnection *c,
XCBDRAWABLE drawable,
- XCBGCONTEXT gc,
- CARD8 shape,
- CARD8 coordinate_mode,
- CARD32 points_len,
- const XCBPOINT *points);
-</pre>
- <p>
- The <span class="code">shape</span> parameter specifies a
- shape that helps the server to improve performance. Available
- values are
- </p>
- <ul>
- <li><span class="code">Complex</span></li>
- <li><span class="code">Convex</span></li>
- <li><span class="code">Nonconvex</span></li>
- </ul>
- <p>
- To fill one or several rectangles, we use
- </p>
- <pre class="code">
+ XCBGCONTEXT gc,
+ CARD8 shape,
+ CARD8 coordinate_mode,
+ CARD32 points_len,
+ const XCBPOINT *points);
+</pre>
+ <p>
+ The <span class="code">shape</span> parameter specifies a
+ shape that helps the server to improve performance. Available
+ values are
+ </p>
+ <ul>
+ <li><span class="code">Complex</span>
+ <li><span class="code">Convex</span>
+ <li><span class="code">Nonconvex</span>
+ </ul>
+ <p>
+ To fill one or several rectangles, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyFillRectangle (XCBConnection *c,
XCBDRAWABLE drawable,
- XCBGCONTEXT gc,
- CARD32 rectangles_len,
- const XCBRECTANGLE *rectangles);
-</pre>
- <p>
- To fill one or several arcs, we use
- </p>
- <pre class="code">
+ XCBGCONTEXT gc,
+ CARD32 rectangles_len,
+ const XCBRECTANGLE *rectangles);
+</pre>
+ <p>
+ To fill one or several arcs, we use
+ </p>
+ <pre class="code">
XCBVoidCookie XCBPolyFillArc (XCBConnection *c,
XCBDRAWABLE drawable,
- XCBGCONTEXT gc,
- CARD32 arcs_len,
- const XCBARC *arcs);
-</pre>
- <p></p>
- <p>
- To illustrate these functions, here is an example that draws
- four points, a polygonal line, two segments, two rectangles
- and two arcs. Remark that we use events for the first time, as
- an introduction to the next section.
- </p>
- <pre class="code">
+ XCBGCONTEXT gc,
+ CARD32 arcs_len,
+ const XCBARC *arcs);
+</pre>
+ <br>
+ <p>
+ To illustrate these functions, here is an example that draws
+ four points, a polygonal line, two segments, two rectangles
+ and two arcs. Remark that we use events for the first time, as
+ an introduction to the next section.
+ </p>
+ <pre class="code">
#include <stdlib.h>
#include <stdio.h>
/* Get the depth of the screen. Needed in order to draw something */
int
get_depth(XCBConnection *c,
- XCBSCREEN *root)
+ XCBSCREEN *root)
{
XCBDRAWABLE drawable;
XCBGetGeometryRep *geom;
values[0] = screen->white_pixel;
values[1] = ExposureMask;
XCBCreateWindow (c, /* Connection */
- 0, /* depth */
- win.window, /* window Id */
- screen->root, /* parent window */
- 0, 0, /* x, y */
- 150, 150, /* width, height */
- 10, /* border_width */
- InputOutput, /* class */
- screen->root_visual, /* visual */
- mask, values); /* masks */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ 150, 150, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ mask, values); /* masks */
/* Map the window on the screen */
XCBMapWindow (c, win.window);
while ((e = XCBWaitEvent (c)))
{
switch (e->response_type)
- {
- case XCBExpose:
- {
- /* We draw the points */
- XCBPolyPoint (c, CoordModeOrigin, win, foreground, 4, points);
-
- /* We draw the polygonal line */
- XCBPolyLine (c, CoordModeOrigin, win, foreground, 4, polyline);
-
- /* We draw the segements */
- XCBPolySegment (c, win, foreground, 2, segments);
-
- /* We draw the rectangles */
- XCBPolyRectangle (c, win, foreground, 2, rectangles);
-
- /* We draw the arcs */
- XCBPolyArc (c, win, foreground, 2, arcs);
-
- /* We flush the request */
- XCBSync (c, 0);
-
- break;
- }
- default:
- {
- /* Unknown event type, ignore it */
- break;
- }
- }
+ {
+ case XCBExpose:
+ {
+ /* We draw the points */
+ XCBPolyPoint (c, CoordModeOrigin, win, foreground, 4, points);
+
+ /* We draw the polygonal line */
+ XCBPolyLine (c, CoordModeOrigin, win, foreground, 4, polyline);
+
+ /* We draw the segements */
+ XCBPolySegment (c, win, foreground, 2, segments);
+
+ /* We draw the rectangles */
+ XCBPolyRectangle (c, win, foreground, 2, rectangles);
+
+ /* We draw the arcs */
+ XCBPolyArc (c, win, foreground, 2, arcs);
+
+ /* We flush the request */
+ XCBSync (c, 0);
+
+ break;
+ }
+ default:
+ {
+ /* Unknown event type, ignore it */
+ break;
+ }
+ }
/* Free the Generic Event */
free (e);
}
}
</pre>
</ol>
- <li class="title"><a name="xevents">X Events</a></li>
+ <li class="title"><a name="xevents">X Events</a>
<p>
In an X program, everything is driven by events. Event painting
on the screen is sometimes done as a response to an event (an
received as a set of events.
</p>
<ol>
- <li class="subtitle"><a name="register">Registering for event types using event masks</a></li>
- <p>
- During the creation of a window, you should give it what kind
- of events it wishes to receive. Thus, you may register for
- various mouse (also called pointer) events, keyboard events,
- expose events, and so on. This is done for optimizing the
- server-to-client connection (i.e. why send a program (that
- might even be running at the other side of the globe) an event
- it is not interested in ?)
- </p>
- <p>
- In XCB, you use the "value_mask" and "value_list" data in the
- <span class="code">XCBCreateWindow()</span> function to
- register for events. Here is how we register for
- <span class="code">Expose</span> event when creating a window:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="register">Registering for event types using event masks</a>
+ <p>
+ During the creation of a window, you should give it what kind
+ of events it wishes to receive. Thus, you may register for
+ various mouse (also called pointer) events, keyboard events,
+ expose events, and so on. This is done for optimizing the
+ server-to-client connection (i.e. why send a program (that
+ might even be running at the other side of the globe) an event
+ it is not interested in ?)
+ </p>
+ <p>
+ In XCB, you use the "value_mask" and "value_list" data in the
+ <span class="code">XCBCreateWindow()</span> function to
+ register for events. Here is how we register for
+ <span class="code">Expose</span> event when creating a window:
+ </p>
+ <pre class="code">
mask = XCBCWEventMask;
valwin[0] = ExposureMask;
win.window = XCBWINDOWNew (c);
XCBCreateWindow (c, depth, win.window, root->root,
- 0, 0, 150, 150, 10,
- InputOutput, root->root_visual,
- mask, valwin);
+ 0, 0, 150, 150, 10,
+ InputOutput, root->root_visual,
+ mask, valwin);
</pre>
<p>
- <span class="code">ExposureMask</span> is a constant defined
- in the "X.h" header file. If we wanted to register to several
- event types, we can logically "or" them, as follows:
- </p>
- <pre class="code">
+ <span class="code">ExposureMask</span> is a constant defined
+ in the "X.h" header file. If we wanted to register to several
+ event types, we can logically "or" them, as follows:
+ </p>
+ <pre class="code">
mask = XCBCWEventMask;
valwin[0] = ExposureMask | ButtonPressMask;
win.window = XCBWINDOWNew (c);
XCBCreateWindow (c, depth, win.window, root->root,
- 0, 0, 150, 150, 10,
- InputOutput, root->root_visual,
- mask, valwin);
-</pre>
- <p>
- This registers for <span class="code">Expose</span> events as
- well as for mouse button presses insode the created
- window. You should note that a mask may represent several
- event sub-types.
- </p>
- <p>
- The values that a mask could take are given
- by the <span class="code">XCBCW</span> enumeration:
- </p>
- <pre class="code">
+ 0, 0, 150, 150, 10,
+ InputOutput, root->root_visual,
+ mask, valwin);
+</pre>
+ <p>
+ This registers for <span class="code">Expose</span> events as
+ well as for mouse button presses insode the created
+ window. You should note that a mask may represent several
+ event sub-types.
+ </p>
+ <p>
+ The values that a mask could take are given
+ by the <span class="code">XCBCW</span> enumeration:
+ </p>
+ <pre class="code">
typedef enum {
XCBCWBackPixmap = 1L<<0,
XCBCWBackPixel = 1L<<1,
XCBCWCursor = 1L<<14
} XCBCW;
</pre>
- <div class="emph">
+ <div class="emph">
<p>Note: we must be careful when setting the values of the valwin
parameter, as they have to follow the order the
- <span class="code">XCBCW</span> enumeration. Here is an
+ <span class="code">XCBCW</span> enumeration. Here is an
example:
- </p>
- </div>
- <pre class="code">
+ </p>
+ </div>
+ <pre class="code">
mask = XCBCWEventMask | XCBCWBackPixmap;
valwin[0] = None; /* for XCBCWBackPixmap (whose value is 1) */
valwin[1] = ExposureMask | ButtonPressMask; /* for XCBCWEventMask, whose value (2048) */
/* is superior to the one of XCBCWBackPixmap */
</pre>
- <p>
- If the window has already been created, we can use the
- <span class="code">XCBConfigureWindow()</span> function to set
- the events that the window will receive. The subsection
- <a href="#winconf">Configuring a window</a> shows its
- prototype. As an example, here is a piece of code that
- configures the window to receive the
- <span class="code">Expose</span> and
- <span class="code">ButtonPressMask</span> events:
- </p>
- <pre class="code">
+ <p>
+ If the window has already been created, we can use the
+ <span class="code">XCBConfigureWindow()</span> function to set
+ the events that the window will receive. The subsection
+ <a href="#winconf">Configuring a window</a> shows its
+ prototype. As an example, here is a piece of code that
+ configures the window to receive the
+ <span class="code">Expose</span> and
+ <span class="code">ButtonPressMask</span> events:
+ </p>
+ <pre class="code">
const static CARD32 values[] = { ExposureMask | ButtonPressMask };
/* The connection c and the window win are supposed to be defined */
XCBConfigureWindow (c, win, XCBCWEventMask, values);
</pre>
- <div class="emph">
- <p>
- Note: A common bug programmers do is adding code to handle new
- event types in their program, while forgetting to add the
- masks for these events in the creation of the window. Such a
- programmer then should sit down for hours debugging his
- program, wondering "Why doesn't my program notice that I
- released the button?", only to find that they registered for
- button press events but not for button release events.
- </p>
- </div>
- <li class="subtitle"><a name="loop">Receiving events: writing the events loop</a></li>
- <p>
- After we have registered for the event types we are interested
- in, we need to enter a loop of receiving events and handling
- them. There are two ways to receive events: a blocking way and
- a non blocking way:
- </p>
- <ul>
- <li>
- <span class="code">XCBWaitEvent (XCBConnection *c)</span>
- is the blocking way. It waits (so blocks...) until an event is
- queued in the X server. Then it retrieves it into a newly
- allocated structure (it dequeues it from the queue) and returns
- it. This structure has to be freed. The function returns
- <span class="code">NULL</span> if an error occurs.
- </li>
- <br />
- <li>
- <span class="code">XCBPollForEvent (XCBConnection *c, int
- *error)</span> is the non blocking way. It looks at the event
- queue and returns (and dequeues too) an existing event into
- a newly allocated structure. This structure has to be
- freed. It returns <span class="code">NULL</span> if there is
- no event. If an error occurs, the parameter <span
- class="code">error</span> will be filled with the error
- status.
- </li>
- </ul>
- <p>
- There are various ways to write such a loop. We present two
- ways to write such a loop, with the two functions above. The
- first one uses <span class="code">XCBWaitEvent</span>, which
- is similar to an event Xlib loop using only <span
- class="code">XNextEvent</span>:
- </p>
- <pre class="code">
+ <div class="emph">
+ <p>
+ Note: A common bug programmers do is adding code to handle new
+ event types in their program, while forgetting to add the
+ masks for these events in the creation of the window. Such a
+ programmer then should sit down for hours debugging his
+ program, wondering "Why doesn't my program notice that I
+ released the button?", only to find that they registered for
+ button press events but not for button release events.
+ </p>
+ </div>
+ <li class="subtitle"><a name="loop">Receiving events: writing the events loop</a>
+ <p>
+ After we have registered for the event types we are interested
+ in, we need to enter a loop of receiving events and handling
+ them. There are two ways to receive events: a blocking way and
+ a non blocking way:
+ </p>
+ <ul>
+ <li>
+ <span class="code">XCBWaitEvent (XCBConnection *c)</span>
+ is the blocking way. It waits (so blocks...) until an event is
+ queued in the X server. Then it retrieves it into a newly
+ allocated structure (it dequeues it from the queue) and returns
+ it. This structure has to be freed. The function returns
+ <span class="code">NULL</span> if an error occurs.
+
+ <br>
+ <li>
+ <span class="code">XCBPollForEvent (XCBConnection *c, int
+ *error)</span> is the non blocking way. It looks at the event
+ queue and returns (and dequeues too) an existing event into
+ a newly allocated structure. This structure has to be
+ freed. It returns <span class="code">NULL</span> if there is
+ no event. If an error occurs, the parameter <span
+ class="code">error</span> will be filled with the error
+ status.
+
+ </ul>
+ <p>
+ There are various ways to write such a loop. We present two
+ ways to write such a loop, with the two functions above. The
+ first one uses <span class="code">XCBWaitEvent</span>, which
+ is similar to an event Xlib loop using only <span
+ class="code">XNextEvent</span>:
+ </p>
+ <pre class="code">
XCBGenericEvent *e;
while ((e = XCBWaitEvent (c)))
{
switch (e->response_type)
- {
- case XCBExpose:
- {
- /* Handle the Expose event type */
- XCBExposeEvent *ev = (XCBExposeEvent *)e;
-
- /* ... */
-
- break;
- }
- case XCBButtonPress:
- {
- /* Handle the ButtonPress event type */
- XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
-
- /* ... */
-
- break;
- }
- default:
- {
- /* Unknown event type, ignore it */
- break;
- }
- }
+ {
+ case XCBExpose:
+ {
+ /* Handle the Expose event type */
+ XCBExposeEvent *ev = (XCBExposeEvent *)e;
+
+ /* ... */
+
+ break;
+ }
+ case XCBButtonPress:
+ {
+ /* Handle the ButtonPress event type */
+ XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
+
+ /* ... */
+
+ break;
+ }
+ default:
+ {
+ /* Unknown event type, ignore it */
+ break;
+ }
+ }
/* Free the Generic Event */
free (e);
}
</pre>
- <p>
- You will certainly want to use <span
- class="code">XCBPollForEvent(XCBConnection *c, int
- *error)</span> if, in Xlib, you use <span
- class="code">XPending</span>:
- </p>
- <pre class="code">
+ <p>
+ You will certainly want to use <span
+ class="code">XCBPollForEvent(XCBConnection *c, int
+ *error)</span> if, in Xlib, you use <span
+ class="code">XPending</span>:
+ </p>
+ <pre class="code">
while (XPending (display))
{
XEvent ev;
- XNextEvent(d, &ev);
+ XNextEvent(d, &ev);
/* Manage your event */
}
</pre>
<p>
- Such a loop in XCB looks like:
- </p>
- <pre class="code">
+ Such a loop in XCB looks like:
+ </p>
+ <pre class="code">
XCBGenericEvent *ev;
while ((ev = XCBPollForEvent (conn, 0)))
/* Manage your event */
}
</pre>
- <p>
- The events are managed in the same way as with <span
- class="code">XCBWaitEvent</span>.
- Obviously, we will need to give the user some way of
- terminating the program. This is usually done by handling a
- special "quit" event, as we will soon see.
- </p>
- <div class="comp">
- <div class="title">
- Comparison Xlib/XCB
- </div>
- <div class="xlib">
- <ul>
- <li>XNextEvent ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBWaitEvent ()</li>
- </ul>
- </div>
- <div class="xlib">
- <ul>
- <li>XPending ()</li>
- <li>XNextEvent ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBPollForEvent ()</li>
- <br />
- </ul>
- </div>
- </div>
- <p />
- <li class="subtitle"><a name="expose">Expose events</a></li>
- <p>
- The <span class="code">Expose</span> event is one of the most
- basic (and most used) events an application may receive. It
- will be sent to us in one of several cases:
- <ul>
- <li>A window that covered part of our window has moved
- away, exposing part (or all) of our window.</li>
- <li>Our window was raised above other windows.</li>
- <li>Our window mapped for the first time.</li>
- <li>Our window was de-iconified.</li>
- </ul>
- </p>
- <p>
- You should note the implicit assumption hidden here: the
- contents of our window is lost when it is being obscured
- (covered) by either windows. One may wonder why the X server
- does not save this contents. The answer is: to save
- memory. After all, the number of windows on a display at a
- given time may be very large, and storing the contents of all
- of them might require a lot of memory. Actually, there is a
- way to tell the X server to store the contents of a window in
- special cases, as we will see later.
- </p>
- <p>
- When we get an <span class="code">Expose</span> event, we
- should take the event's data from the members of the following
- structure:
- </p>
- <pre class="code">
+ <p>
+ The events are managed in the same way as with <span
+ class="code">XCBWaitEvent</span>.
+ Obviously, we will need to give the user some way of
+ terminating the program. This is usually done by handling a
+ special "quit" event, as we will soon see.
+ </p>
+ <div class="comp">
+ <div class="title">
+ Comparison Xlib/XCB
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XNextEvent ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBWaitEvent ()
+ </ul>
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XPending ()
+ <li>XNextEvent ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBPollForEvent ()
+ <br>
+ </ul>
+ </div>
+ </div>
+ <br>
+ <li class="subtitle"><a name="expose">Expose events</a>
+ <p>
+ The <span class="code">Expose</span> event is one of the most
+ basic (and most used) events an application may receive. It
+ will be sent to us in one of several cases:
+ </p>
+ <ul>
+ <li>A window that covered part of our window has moved
+ away, exposing part (or all) of our window.
+ <li>Our window was raised above other windows.
+ <li>Our window mapped for the first time.
+ <li>Our window was de-iconified.
+ </ul>
+ <p>
+ You should note the implicit assumption hidden here: the
+ contents of our window is lost when it is being obscured
+ (covered) by either windows. One may wonder why the X server
+ does not save this contents. The answer is: to save
+ memory. After all, the number of windows on a display at a
+ given time may be very large, and storing the contents of all
+ of them might require a lot of memory. Actually, there is a
+ way to tell the X server to store the contents of a window in
+ special cases, as we will see later.
+ </p>
+ <p>
+ When we get an <span class="code">Expose</span> event, we
+ should take the event's data from the members of the following
+ structure:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type; /* The type of the event, here it is XCBExpose */
CARD8 pad0;
CARD16 count;
} XCBExposeEvent;
</pre>
- <li class="subtitle"><a name="userinput">Getting user input</a></li>
- <p>
- User input traditionally comes from two sources: the mouse
- and the keyboard. Various event types exist to notify us of
- user input (a key being presses on the keyboard, a key being
- released on the keyboard, the mouse moving over our window,
- the mouse entering (or leaving) our window, and so on.
- </p>
- <ol>
- <li class="subsubtitle"><a name="mousepressrelease">Mouse button press and release events</a></li>
- <p>
- The first event type we will deal with is a mouse
- button-press (or button-release) event in our window. In
- order to register to such an event type, we should add one
- (or more) of the following masks when we create our window:
- </p>
- <ul>
- <li><span class="code">ButtonPressMask</span>: notify us
- of any button that was pressed in one of our windows.</li>
- <li><span class="code">ButtonReleaseMask</span>: notify us
- of any button that was released in one of our windows.</li>
- </ul>
- <p>
- The structure to be checked for in our events loop is the
- same for these two events, and is the following:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="userinput">Getting user input</a>
+ <p>
+ User input traditionally comes from two sources: the mouse
+ and the keyboard. Various event types exist to notify us of
+ user input (a key being presses on the keyboard, a key being
+ released on the keyboard, the mouse moving over our window,
+ the mouse entering (or leaving) our window, and so on.
+ </p>
+ <ol>
+ <li class="subsubtitle"><a name="mousepressrelease">Mouse button press and release events</a>
+ <p>
+ The first event type we will deal with is a mouse
+ button-press (or button-release) event in our window. In
+ order to register to such an event type, we should add one
+ (or more) of the following masks when we create our window:
+ </p>
+ <ul>
+ <li><span class="code">ButtonPressMask</span>: notify us
+ of any button that was pressed in one of our windows.
+ <li><span class="code">ButtonReleaseMask</span>: notify us
+ of any button that was released in one of our windows.
+ </ul>
+ <p>
+ The structure to be checked for in our events loop is the
+ same for these two events, and is the following:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type; /* The type of the event, here it is XCBButtonPressEvent or XCBButtonReleaseEvent */
XCBBUTTON detail;
typedef XCBButtonPressEvent XCBButtonReleaseEvent;
</pre>
<p>
- The <span class="code">time</span> field may be used to calculate "double-click"
- situations by an application (e.g. if the mouse button was
- clicked two times in a duration shorter than a given amount
- of time, assume this was a double click).
- </p>
+ The <span class="code">time</span> field may be used to calculate "double-click"
+ situations by an application (e.g. if the mouse button was
+ clicked two times in a duration shorter than a given amount
+ of time, assume this was a double click).
+ </p>
+ <p>
+ The <span class="code">state</span> field is a mask of the buttons held down during
+ the event. It is a bitwise OR of any of the following:
+ </p>
+ <ul>
+ <li><span class="code">Button1Mask</span>
+ <li><span class="code">Button2Mask</span>
+ <li><span class="code">Button3Mask</span>
+ <li><span class="code">Button4Mask</span>
+ <li><span class="code">Button5Mask</span>
+ <li><span class="code">ShiftMask</span>
+ <li><span class="code">LockMask</span>
+ <li><span class="code">ControlMask</span>
+ <li><span class="code">Mod1Mask</span>
+ <li><span class="code">Mod2Mask</span>
+ <li><span class="code">Mod3Mask</span>
+ <li><span class="code">Mod4Mask</span>
+ <li><span class="code">Mod5Mask</span>
+ </ul>
+ <p>
+ Their names are self explanatory, where the first 5 refer to
+ the mouse buttons that are being pressed, while the rest
+ refer to various "special keys" that are being pressed (Mod1
+ is usually the 'Alt' key or the 'Meta' key).
+ </p>
+ <p>
+ <b>TODO:</b> Problem: it seems that the state does not
+ change when clicking with various buttons.
+ </p>
+ <li class="subsubtitle"><a name="mousemvnt">Mouse movement events</a>
+ <p>
+ Similar to mouse button press and release events, we also
+ can be notified of various mouse movement events. These can
+ be split into two families. One is of mouse pointer
+ movement while no buttons are pressed, and the second is a
+ mouse pointer motion while one (or more) of the buttons are
+ pressed (this is sometimes called "a mouse drag operation",
+ or just "dragging"). The following event masks may be added
+ during the creation of our window:
+ </p>
+ <ul>
+ <li><span class="code">PointerMotionMask</span>: events of
+ the pointer moving in one of the windows controlled by our
+ application, while no mouse button is held pressed.
+ <li><span class="code">ButtonMotionMask</span>: Events of
+ the pointer moving while one or more of the mouse buttons
+ is held pressed.
+ <li><span class="code">Button1MotionMask</span>: same as
+ <span class="code">ButtonMotionMask</span>, but only when
+ the 1st mouse button is held pressed.
+ <li><span class="code">Button2MotionMask</span>,
+ <span class="code">Button3MotionMask</span>,
+ <span class="code">Button4MotionMask</span>,
+ <span class="code">Button5MotionMask</span>: same as
+ <span class="code">Button1MotionMask</span>, but
+ respectively for 2nd, 3rd, 4th and 5th mouse button.
+ </ul>
<p>
- The <span class="code">state</span> field is a mask of the buttons held down during
- the event. It is a bitwise OR of any of the following:
- </p>
- <ul>
- <li><span class="code">Button1Mask</span></li>
- <li><span class="code">Button2Mask</span></li>
- <li><span class="code">Button3Mask</span></li>
- <li><span class="code">Button4Mask</span></li>
- <li><span class="code">Button5Mask</span></li>
- <li><span class="code">ShiftMask</span></li>
- <li><span class="code">LockMask</span></li>
- <li><span class="code">ControlMask</span></li>
- <li><span class="code">Mod1Mask</span></li>
- <li><span class="code">Mod2Mask</span></li>
- <li><span class="code">Mod3Mask</span></li>
- <li><span class="code">Mod4Mask</span></li>
- <li><span class="code">Mod5Mask</span></li>
- </ul>
- <p>
- Their names are self explanatory, where the first 5 refer to
- the mouse buttons that are being pressed, while the rest
- refer to various "special keys" that are being pressed (Mod1
- is usually the 'Alt' key or the 'Meta' key).
- </p>
- <p>
- <b>TODO:</b> Problem: it seems that the state does not
- change when clicking with various buttons.
- </p>
- <li class="subsubtitle"><a name="mousemvnt">Mouse movement events</a></li>
- <p>
- Similar to mouse button press and release events, we also
- can be notified of various mouse movement events. These can
- be split into two families. One is of mouse pointer
- movement while no buttons are pressed, and the second is a
- mouse pointer motion while one (or more) of the buttons are
- pressed (this is sometimes called "a mouse drag operation",
- or just "dragging"). The following event masks may be added
- during the creation of our window:
- </p>
- <ul>
- <li><span class="code">PointerMotionMask</span>: events of
- the pointer moving in one of the windows controlled by our
- application, while no mouse button is held pressed.</li>
- <li><span class="code">ButtonMotionMask</span>: Events of
- the pointer moving while one or more of the mouse buttons
- is held pressed.</li>
- <li><span class="code">Button1MotionMask</span>: same as
- <span class="code">ButtonMotionMask</span>, but only when
- the 1st mouse button is held pressed.</li>
- <li><span class="code">Button2MotionMask</span>,
- <span class="code">Button3MotionMask</span>,
- <span class="code">Button4MotionMask</span>,
- <span class="code">Button5MotionMask</span>: same as
- <span class="code">Button1MotionMask</span>, but
- respectively for 2nd, 3rd, 4th and 5th mouse button.</li>
- </ul>
- <p>
- The structure to be checked for in our events loop is the
- same for these events, and is the following:
- </p>
- <pre class="code">
+ The structure to be checked for in our events loop is the
+ same for these events, and is the following:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type; /* The type of the event */
BYTE detail;
BOOL same_screen;
} XCBMotionNotifyEvent;
</pre>
- <li class="subsubtitle"><a name="mouseenter">Mouse pointer enter and leave events</a></li>
- <p>
- Another type of event that applications might be interested
- at, is a mouse pointer entering a window the program
- controls, or leaving such a window. Some programs use these
- events to show the user tht the applications is now in
- focus. In order to register for such an event type, we
- should add one (or more) of the following masks when we
- create our window:
- </p>
- <ul>
- <li><span class="code">EnterWindowMask</span>: notify us
- when the mouse pointer enters any of our controlled
- windows.</li>
- <li><span class="code">LeaveWindowMask</span>: notify us
- when the mouse pointer leaves any of our controlled
- windows.</li>
- </ul>
- <p>
- The structure to be checked for in our events loop is the
- same for these two events, and is the following:
- </p>
- <pre class="code">
+ <li class="subsubtitle"><a name="mouseenter">Mouse pointer enter and leave events</a>
+ <p>
+ Another type of event that applications might be interested
+ at, is a mouse pointer entering a window the program
+ controls, or leaving such a window. Some programs use these
+ events to show the user tht the applications is now in
+ focus. In order to register for such an event type, we
+ should add one (or more) of the following masks when we
+ create our window:
+ </p>
+ <ul>
+ <li><span class="code">EnterWindowMask</span>: notify us
+ when the mouse pointer enters any of our controlled
+ windows.
+ <li><span class="code">LeaveWindowMask</span>: notify us
+ when the mouse pointer leaves any of our controlled
+ windows.
+ </ul>
+ <p>
+ The structure to be checked for in our events loop is the
+ same for these two events, and is the following:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type; /* The type of the event */
BYTE detail;
typedef XCBEnterNotifyEvent XCBLeaveNotifyEvent;
</pre>
- <li class="subsubtitle"><a name="focus">The keyboard focus</a></li>
- <p>
- There may be many windows on a screen, but only a single
- keyboard attached to them. How does the X server then know
- which window should be sent a given keyboard input ? This is
- done using the keyboard focus. Only a single window on the
- screen may have the keyboard focus at a given time. There
- is a XCB function that allow a program to set the keyboard
- focus to a given window. The user can usually set the
- keyboard ficus using the window manager (often by clicking
- on the title bar of the desired window). Once our window
- has the keyboard focus, every key press or key release will
- cause an event to be sent to our program (if it regsitered
- for these event types...).
- </p>
- <li class="subsubtitle"><a name="keypress">Keyboard press and release events</a></li>
- <p>
- If a window controlled by our program currently holds the
- keyboard focus, it can receive key press and key release
- events. So, we should add one (or more) of the following
- masks when we create our window:
- </p>
- <ul>
- <li><span class="code">KeyPressMask</span>: notify us when
- a key was pressed while any of our controlled windows had
- the keyboard focus.</li>
- <li><span class="code">KeyReleaseMask</span>: notify us
- when a key was released while any of our controlled
- windows had the keyboard focus.</li>
- </ul>
- <p>
- The structure to be checked for in our events loop is the
- same for these two events, and is the following:
- </p>
- <pre class="code">
+ <li class="subsubtitle"><a name="focus">The keyboard focus</a>
+ <p>
+ There may be many windows on a screen, but only a single
+ keyboard attached to them. How does the X server then know
+ which window should be sent a given keyboard input ? This is
+ done using the keyboard focus. Only a single window on the
+ screen may have the keyboard focus at a given time. There
+ is a XCB function that allow a program to set the keyboard
+ focus to a given window. The user can usually set the
+ keyboard ficus using the window manager (often by clicking
+ on the title bar of the desired window). Once our window
+ has the keyboard focus, every key press or key release will
+ cause an event to be sent to our program (if it regsitered
+ for these event types...).
+ </p>
+ <li class="subsubtitle"><a name="keypress">Keyboard press and release events</a>
+ <p>
+ If a window controlled by our program currently holds the
+ keyboard focus, it can receive key press and key release
+ events. So, we should add one (or more) of the following
+ masks when we create our window:
+ </p>
+ <ul>
+ <li><span class="code">KeyPressMask</span>: notify us when
+ a key was pressed while any of our controlled windows had
+ the keyboard focus.
+ <li><span class="code">KeyReleaseMask</span>: notify us
+ when a key was released while any of our controlled
+ windows had the keyboard focus.
+ </ul>
+ <p>
+ The structure to be checked for in our events loop is the
+ same for these two events, and is the following:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type; /* The type of the event */
XCBKEYCODE detail;
typedef XCBKeyPressEvent XCBKeyReleaseEvent;
</pre>
<p>
- The <span class="code">detail</span> field refer to the
- physical key on the keyboard.
- </p>
- <p>
+ The <span class="code">detail</span> field refer to the
+ physical key on the keyboard.
+ </p>
+ <p>
<b>TODO:</b> Talk about getting the ASCII code from the key code.
- </p>
- </ol>
- <li class="subtitle"><a name="eventex">X events: a complete example</a></li>
- <p>
- As an example for handling events, we show a program that
- creates a window, enter an events loop and check for all the
- events described above, and write on the terminal the relevant
- characteristics of the event. With this code, it should be
- easy to add drawing operations, like those which have been
- described above.
- </p>
+ </p>
+ </ol>
+ <li class="subtitle"><a name="eventex">X events: a complete example</a>
+ <p>
+ As an example for handling events, we show a program that
+ creates a window, enter an events loop and check for all the
+ events described above, and write on the terminal the relevant
+ characteristics of the event. With this code, it should be
+ easy to add drawing operations, like those which have been
+ described above.
+ </p>
<pre class="code">
#include <malloc.h>
#include <stdio.h>
PointerMotionMask | EnterWindowMask | LeaveWindowMask |
KeyPressMask | KeyReleaseMask;
XCBCreateWindow (c, /* Connection */
- 0, /* depth */
- win.window, /* window Id */
- screen->root, /* parent window */
- 0, 0, /* x, y */
- 150, 150, /* width, height */
- 10, /* border_width */
- InputOutput, /* class */
- screen->root_visual, /* visual */
- mask, values); /* masks */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ 150, 150, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ mask, values); /* masks */
/* Map the window on the screen */
XCBMapWindow (c, win.window);
while ((e = XCBWaitEvent (c)))
{
switch (e->response_type)
- {
- case XCBExpose:
- {
- XCBExposeEvent *ev = (XCBExposeEvent *)e;
-
- printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
- ev->window.xid, ev->x, ev->y, ev->width, ev->height);
- break;
- }
- case XCBButtonPress:
- {
- XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
- int button_num = 0;
-
- if ((ev->state | Button1Mask) == Button1Mask)
- button_num = 1;
- if ((ev->state | Button2Mask) == Button2Mask)
- button_num = 2;
- if ((ev->state | Button3Mask) == Button3Mask)
- button_num = 3;
- if ((ev->state | Button4Mask) == Button4Mask)
- button_num = 4;
- if ((ev->state | Button5Mask) == Button5Mask)
- button_num = 5;
-
- switch (ev->detail.id)
- {
- case 4:
- {
- printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
+ {
+ case XCBExpose:
+ {
+ XCBExposeEvent *ev = (XCBExposeEvent *)e;
+
+ printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
+ ev->window.xid, ev->x, ev->y, ev->width, ev->height);
+ break;
+ }
+ case XCBButtonPress:
+ {
+ XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
+ int button_num = 0;
+
+ if ((ev->state | Button1Mask) == Button1Mask)
+ button_num = 1;
+ if ((ev->state | Button2Mask) == Button2Mask)
+ button_num = 2;
+ if ((ev->state | Button3Mask) == Button3Mask)
+ button_num = 3;
+ if ((ev->state | Button4Mask) == Button4Mask)
+ button_num = 4;
+ if ((ev->state | Button5Mask) == Button5Mask)
+ button_num = 5;
+
+ switch (ev->detail.id)
+ {
+ case 4:
+ {
+ printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- case 5:
- {
- printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
+ break;
+ }
+ case 5:
+ {
+ printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- default:
- printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
+ break;
+ }
+ default:
+ printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
- }
- break;
- }
- case XCBButtonRelease:
- {
- XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
- int button_num = 0;
-
- if ((ev->state | Button1Mask) == Button1Mask)
- button_num = 1;
- if ((ev->state | Button2Mask) == Button2Mask)
- button_num = 2;
- if ((ev->state | Button3Mask) == Button3Mask)
- button_num = 3;
- if ((ev->state | Button4Mask) == Button4Mask)
- button_num = 4;
- if ((ev->state | Button5Mask) == Button5Mask)
- button_num = 5;
-
- printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
+ }
+ break;
+ }
+ case XCBButtonRelease:
+ {
+ XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
+ int button_num = 0;
+
+ if ((ev->state | Button1Mask) == Button1Mask)
+ button_num = 1;
+ if ((ev->state | Button2Mask) == Button2Mask)
+ button_num = 2;
+ if ((ev->state | Button3Mask) == Button3Mask)
+ button_num = 3;
+ if ((ev->state | Button4Mask) == Button4Mask)
+ button_num = 4;
+ if ((ev->state | Button5Mask) == Button5Mask)
+ button_num = 5;
+
+ printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- case XCBMotionNotify:
- {
- XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
-
- printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
+ break;
+ }
+ case XCBMotionNotify:
+ {
+ XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
+
+ printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- case XCBEnterNotify:
- {
- XCBEnterNotifyEvent *ev = (XCBEnterNotifyEvent *)e;
-
- printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
+ break;
+ }
+ case XCBEnterNotify:
+ {
+ XCBEnterNotifyEvent *ev = (XCBEnterNotifyEvent *)e;
+
+ printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- case XCBLeaveNotify:
- {
- XCBLeaveNotifyEvent *ev = (XCBLeaveNotifyEvent *)e;
-
- printf ("Mouse leaved window %ld, at coordinates (%d,%d)\n",
+ break;
+ }
+ case XCBLeaveNotify:
+ {
+ XCBLeaveNotifyEvent *ev = (XCBLeaveNotifyEvent *)e;
+
+ printf ("Mouse leaved window %ld, at coordinates (%d,%d)\n",
ev->event.xid, ev->event_x, ev->event_y);
- break;
- }
- case XCBKeyPress:
- {
- XCBKeyPressEvent *ev = (XCBKeyPressEvent *)e;
+ break;
+ }
+ case XCBKeyPress:
+ {
+ XCBKeyPressEvent *ev = (XCBKeyPressEvent *)e;
- printf ("Key pressed in window %ld\n",
+ printf ("Key pressed in window %ld\n",
ev->event.xid);
- break;
- }
- case XCBKeyRelease:
- {
- XCBKeyReleaseEvent *ev = (XCBKeyReleaseEvent *)e;
+ break;
+ }
+ case XCBKeyRelease:
+ {
+ XCBKeyReleaseEvent *ev = (XCBKeyReleaseEvent *)e;
- printf ("Key releaseed in window %ld\n",
+ printf ("Key releaseed in window %ld\n",
ev->event.xid);
- break;
- }
- default:
- {
- /* Unknown event type, ignore it */
- break;
- }
- }
+ break;
+ }
+ default:
+ {
+ /* Unknown event type, ignore it */
+ break;
+ }
+ }
/* Free the Generic Event */
free (e);
}
}
</pre>
</ol>
- <li class="title"><a name="font">Handling text and fonts</a></li>
+ <li class="title"><a name="font">Handling text and fonts</a>
<p>
Besides drawing graphics on a window, we often want to draw
text. Text strings have two major properties: the characters to
draw the text in a window, using the Graphic Context.
</p>
<ol>
- <li class="subtitle"><a name="fontstruct">The Font structure</a></li>
- <p>
- In order to support flexible fonts, a font structure is
- defined. You know what ? Its an Id:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="fontstruct">The Font structure</a>
+ <p>
+ In order to support flexible fonts, a font structure is
+ defined. You know what ? Its an Id:
+ </p>
+ <pre class="code">
typedef struct {
CARD32 xid;
} XCBFONT;
</pre>
- <p>
- It is used to contain information about a font, and is passed
- to several functions that handle fonts selection and text drawing.
- </p>
+ <p>
+ It is used to contain information about a font, and is passed
+ to several functions that handle fonts selection and text drawing.
+ </p>
</ol>
- <li class="title"><a name="wm">Interacting with the window manager</a></li>
+ <li class="title"><a name="wm">Interacting with the window manager</a>
<p>
After we have seen how to create windows and draw on them, we
take one step back, and look at how our windows are interacting
treat our application's windows.
</p>
<ol>
- <li class="subtitle"><a name="wmprop">Window properties</a></li>
- <p>
- Many of the parameters communicated to the window manager are
- passed using data called "properties". These properties are
- attached by the X server to different windows, and are stores
- in a format that makes it possible to read them from different
- machines that may use different architectures (remember that
- an X client program may run on a remote machine).
- </p>
- <p>
- The property and its type (a string, an integer, etc) are
- Id. Their type are <span class="code">XCBATOM</span>:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="wmprop">Window properties</a>
+ <p>
+ Many of the parameters communicated to the window manager are
+ passed using data called "properties". These properties are
+ attached by the X server to different windows, and are stores
+ in a format that makes it possible to read them from different
+ machines that may use different architectures (remember that
+ an X client program may run on a remote machine).
+ </p>
+ <p>
+ The property and its type (a string, an integer, etc) are
+ Id. Their type are <span class="code">XCBATOM</span>:
+ </p>
+ <pre class="code">
typedef struct {
CARD32 xid;
} XCBATOM;
</pre>
- <p>
- To change the property of a window, we use the following
- function:
- </p>
- <pre class="code">
+ <p>
+ To change the property of a window, we use the following
+ function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBChangeProperty (XCBConnection *c, /* Connection to the X server */
CARD8 mode, /* Property mode */
- XCBWINDOW window, /* Window */
- XCBATOM property, /* Property to change */
- XCBATOM type, /* Type of the property */
- CARD8 format, /* Format of the property (8, 16, 32) */
- CARD32 data_len, /* Length of the data parameter */
- const void *data); /* Data */
-</pre>
- <p>
- The <span class="code">mode</span> parameter coud be one of
- the following value (defined in the X.h header file):
- </p>
- <ul>
- <li>PropModeReplace</li>
- <li>PropModePrepend</li>
- <li>PropModeAppend</li>
- </ul>
- <p></p>
- <li class="subtitle"><a name="wmname">Setting the window name and icon name</a></li>
- <p>
- The firt thing we want to do would be to set the name for our
- window. This is done using the
- <span class="code">XCBChangeProperty()</span> function. This
- name may be used by the window manager as the title of the
- window (in the title bar), in a task list, etc. The property
- atom to use to set the name of a window is
- <span class="code">WM_NAME</span> (and
- <span class="code">WM_ICON_NAME</span> for the iconified
- window) and its type is <span class="code">STRING</span>. Here
- is an example of utilization:
- </p>
- <pre class="code">
+ XCBWINDOW window, /* Window */
+ XCBATOM property, /* Property to change */
+ XCBATOM type, /* Type of the property */
+ CARD8 format, /* Format of the property (8, 16, 32) */
+ CARD32 data_len, /* Length of the data parameter */
+ const void *data); /* Data */
+</pre>
+ <p>
+ The <span class="code">mode</span> parameter coud be one of
+ the following value (defined in the X.h header file):
+ </p>
+ <ul>
+ <li>PropModeReplace
+ <li>PropModePrepend
+ <li>PropModeAppend
+ </ul>
+ <br>
+ <li class="subtitle"><a name="wmname">Setting the window name and icon name</a>
+ <p>
+ The firt thing we want to do would be to set the name for our
+ window. This is done using the
+ <span class="code">XCBChangeProperty()</span> function. This
+ name may be used by the window manager as the title of the
+ window (in the title bar), in a task list, etc. The property
+ atom to use to set the name of a window is
+ <span class="code">WM_NAME</span> (and
+ <span class="code">WM_ICON_NAME</span> for the iconified
+ window) and its type is <span class="code">STRING</span>. Here
+ is an example of utilization:
+ </p>
+ <pre class="code">
#include <string.h>
#include <X11/XCB/xcb.h>
/* Create the window */
XCBCreateWindow (c, /* Connection */
- 0, /* depth */
- win.window, /* window Id */
- screen->root, /* parent window */
- 0, 0, /* x, y */
- 250, 150, /* width, height */
- 10, /* border_width */
- InputOutput, /* class */
- screen->root_visual, /* visual */
- 0, NULL); /* masks, not used */
+ 0, /* depth */
+ win.window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ 250, 150, /* width, height */
+ 10, /* border_width */
+ InputOutput, /* class */
+ screen->root_visual, /* visual */
+ 0, NULL); /* masks, not used */
/* Set the title of the window */
XCBChangeProperty(c, PropModeReplace, win.window,
- WM_NAME, STRING, 8,
- strlen(title), title);
+ WM_NAME, STRING, 8,
+ strlen(title), title);
/* Set the title of the window icon */
XCBChangeProperty(c, PropModeReplace, win.window,
- WM_ICON_NAME, STRING, 8,
- strlen(title_icon), title_icon);
+ WM_ICON_NAME, STRING, 8,
+ strlen(title_icon), title_icon);
/* Map the window on the screen */
XCBMapWindow (c, win.window);
return 1;
}
</pre>
- <div class="emph">
+ <div class="emph">
<p>Note: the use of the atoms needs our program to be compiled
and linked against xcb_atom, so that we have to use
- </p>
- </div>
- <pre class="text">
+ </p>
+ </div>
+ <pre class="text">
gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
</pre>
- <div class="emph">
+ <div class="emph">
<p>
- for the program to compile fine.
- </p>
- </div>
+ for the program to compile fine.
+ </p>
+ </div>
</ol>
- <li class="title"><a name="winop">Simple window operations</a></li>
+ <li class="title"><a name="winop">Simple window operations</a>
<p>
One more thing we can do to our window is manipulate them on the
screen (resize them, move them, raise or lower them, iconify
by XCB for this purpose.
</p>
<ol>
- <li class="subtitle"><a name="winmap">Mapping and un-mapping a window</a></li>
- <p>
- The first pair of operations we can apply on a window is
- mapping it, or un-mapping it. Mapping a window causes the
- window to appear on the screen, as we have seen in our simple
- window program example. Un-mapping it causes it to be removed
- from the screen (although the window as a logical entity still
- exists). This gives the effect of making a window hidden
- (unmapped) and shown again (mapped). For example, if we have a
- dialog box window in our program, instead of creating it every
- time the user asks to open it, we can create the window once,
- in an un-mapped mode, and when the user asks to open it, we
- simply map the window on the screen. When the user clicked the
- 'OK' or 'Cancel' button, we simply un-map the window. This is
- much faster than creating and destroying the window, however,
- the cost is wasted resources, both on the client side, and on
- the X server side.
- </p>
- <p>
- To map a window, you use the following function:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="winmap">Mapping and un-mapping a window</a>
+ <p>
+ The first pair of operations we can apply on a window is
+ mapping it, or un-mapping it. Mapping a window causes the
+ window to appear on the screen, as we have seen in our simple
+ window program example. Un-mapping it causes it to be removed
+ from the screen (although the window as a logical entity still
+ exists). This gives the effect of making a window hidden
+ (unmapped) and shown again (mapped). For example, if we have a
+ dialog box window in our program, instead of creating it every
+ time the user asks to open it, we can create the window once,
+ in an un-mapped mode, and when the user asks to open it, we
+ simply map the window on the screen. When the user clicked the
+ 'OK' or 'Cancel' button, we simply un-map the window. This is
+ much faster than creating and destroying the window, however,
+ the cost is wasted resources, both on the client side, and on
+ the X server side.
+ </p>
+ <p>
+ To map a window, you use the following function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBMapWindow(XCBConnection *c, XCBWINDOW window);
</pre>
<p>
- To have a simple example, see the <a href="#helloworld">example</a>
- above. The mapping operation will cause an
- <span class="code">Expose</span> event to be sent to our
- application, unless the window is completely covered by other
- windows.
- </p>
- <p>
- Un-mapping a window is also simple. You use the function
- </p>
- <pre class="code">
+ To have a simple example, see the <a href="#helloworld">example</a>
+ above. The mapping operation will cause an
+ <span class="code">Expose</span> event to be sent to our
+ application, unless the window is completely covered by other
+ windows.
+ </p>
+ <p>
+ Un-mapping a window is also simple. You use the function
+ </p>
+ <pre class="code">
XCBVoidCookie XCBUnmapWindow(XCBConnection *c, XCBWINDOW window);
</pre>
- <p>
- The utilization of this function is the same as
- <span class="code">XCBMapWindow()</span>.
- </p>
- <li class="subtitle"><a name="winconf">Configuring a window</a></li>
- <p>
- As we have seen when we have created our first window, in the
- X Events subsection, we can set some attributes to the window
- (that is, the position, the size, the events the window will
- receive, etc). If we want to modify them, but the window is
- already created, we can change them by using the following
- function:
- </p>
- <pre class="code">
+ <p>
+ The utilization of this function is the same as
+ <span class="code">XCBMapWindow()</span>.
+ </p>
+ <li class="subtitle"><a name="winconf">Configuring a window</a>
+ <p>
+ As we have seen when we have created our first window, in the
+ X Events subsection, we can set some attributes to the window
+ (that is, the position, the size, the events the window will
+ receive, etc). If we want to modify them, but the window is
+ already created, we can change them by using the following
+ function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBConfigureWindow (XCBConnection *c, /* The connection to the X server*/
XCBWINDOW window, /* The window to configure */
- CARD16 value_mask, /* The mask */
- const CARD32 *value_list); /* The values to set */
-</pre>
- <p>
- We set the <span class="code">value_mask</span> to one or
- several mask values that are in the X.h header:
- <ul>
- <li><span class="code">CWX</span>: new x coordinate of the window's top left corner</li>
- <li><span class="code">CWY</span>: new y coordinate of the window's top left corner</li>
- <li><span class="code">CWWidth</span>: new width of the window</li>
- <li><span class="code">CWHeight</span>: new height of the window</li>
- <li><span class="code">CWBorderWidth</span>: new width of the border of the window</li>
- <li><span class="code">CWSibling</span></li>
- <li><span class="code">CWStackMode</span>: the new stacking order</li>
- </ul>
- </p>
- <p>
- We then give to <span class="code">value_mask</span> the new
- value. We now describe how to use
- <span class="code">XCBConfigureWindow</span> in some useful
- situations.
- </p>
- <li class="subtitle"><a name="winmove">Moving a window around the screen</a></li>
- <p>
- An operation we might want to do with windows is to move them
- to a different location. This can be done like this:
- </p>
- <pre class="code">
+ CARD16 value_mask, /* The mask */
+ const CARD32 *value_list); /* The values to set */
+</pre>
+ <p>
+ We set the <span class="code">value_mask</span> to one or
+ several mask values that are in the X.h header:
+ </p>
+ <ul>
+ <li><span class="code">CWX</span>: new x coordinate of the window's top left corner
+ <li><span class="code">CWY</span>: new y coordinate of the window's top left corner
+ <li><span class="code">CWWidth</span>: new width of the window
+ <li><span class="code">CWHeight</span>: new height of the window
+ <li><span class="code">CWBorderWidth</span>: new width of the border of the window
+ <li><span class="code">CWSibling</span>
+ <li><span class="code">CWStackMode</span>: the new stacking order
+ </ul>
+ <p>
+ We then give to <span class="code">value_mask</span> the new
+ value. We now describe how to use
+ <span class="code">XCBConfigureWindow</span> in some useful
+ situations.
+ </p>
+ <li class="subtitle"><a name="winmove">Moving a window around the screen</a>
+ <p>
+ An operation we might want to do with windows is to move them
+ to a different location. This can be done like this:
+ </p>
+ <pre class="code">
const static CARD32 values[] = { 10, 20 };
/* The connection c and the window win are supposed to be defined */
/* Move the window to coordinates x = 10 and y = 20 */
XCBConfigureWindow (c, win, CWX | CWY, values);
</pre>
- <p>
- Note that when the window is moved, it might get partially
- exposed or partially hidden by other windows, and thus we
- might get <span class="code">Expose</span> events due to this
- operation.
- </p>
- <li class="subtitle"><a name="winsize">Resizing a window</a></li>
- <p>
- Yet another operation we can do is to change the size of a
- window. This is done using the following code:
- </p>
- <pre class="code">
+ <p>
+ Note that when the window is moved, it might get partially
+ exposed or partially hidden by other windows, and thus we
+ might get <span class="code">Expose</span> events due to this
+ operation.
+ </p>
+ <li class="subtitle"><a name="winsize">Resizing a window</a>
+ <p>
+ Yet another operation we can do is to change the size of a
+ window. This is done using the following code:
+ </p>
+ <pre class="code">
const static CARD32 values[] = { 200, 300 };
/* The connection c and the window win are supposed to be defined */
/* Resize the window to width = 10 and height = 20 */
XCBConfigureWindow (c, win, CWWidth | CWHeight, values);
</pre>
- <p>
- We can also combine the move and resize operations using one
- single call to <span class="code">XCBConfigureWindow</span>:
- </p>
- <pre class="code">
+ <p>
+ We can also combine the move and resize operations using one
+ single call to <span class="code">XCBConfigureWindow</span>:
+ </p>
+ <pre class="code">
const static CARD32 values[] = { 10, 20, 200, 300 };
/* The connection c and the window win are supposed to be defined */
/* and resize the window to width = 10 and height = 20 */
XCBConfigureWindow (c, win, CWX | CWY | CWWidth | CWHeight, values);
</pre>
- <li class="subtitle"><a name="winstack">Changing windows stacking order: raise and lower</a></li>
- <p>
- Until now, we changed properties of a single window. We'll see
- that there are properties that relate to the window and other
- windows. One of hem is the stacking order. That is, the order
- in which the windows are layered on top of each other. The
- front-most window is said to be on the top of the stack, while
- the back-most window is at the bottom of the stack. Here is
- how to manipulate our windows stack order:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="winstack">Changing windows stacking order: raise and lower</a>
+ <p>
+ Until now, we changed properties of a single window. We'll see
+ that there are properties that relate to the window and other
+ windows. One of hem is the stacking order. That is, the order
+ in which the windows are layered on top of each other. The
+ front-most window is said to be on the top of the stack, while
+ the back-most window is at the bottom of the stack. Here is
+ how to manipulate our windows stack order:
+ </p>
+ <pre class="code">
const static CARD32 values[] = { Above };
/* The connection c and the window win are supposed to be defined */
/* Move the window on the top of the stack */
XCBConfigureWindow (c, win, CWStackMode, values);
</pre>
- <pre class="code">
+ <pre class="code">
const static CARD32 values[] = { Below };
/* The connection c and the window win are supposed to be defined */
/* Move the window on the bottom of the stack */
XCBConfigureWindow (c, win, CWStackMode, values);
</pre>
- <li class="subtitle"><a name="wingetinfo">Getting information about a window</a></li>
- <p>
- Just like we can set various attributes of our windows, we can
- also ask the X server supply the current values of these
- attributes. For example, we can check where a window is
- located on the screen, what is its current size, whether it is
- mapped or not, etc. The structure that contains some of this
- information is
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="wingetinfo">Getting information about a window</a>
+ <p>
+ Just like we can set various attributes of our windows, we can
+ also ask the X server supply the current values of these
+ attributes. For example, we can check where a window is
+ located on the screen, what is its current size, whether it is
+ mapped or not, etc. The structure that contains some of this
+ information is
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type;
CARD8 depth; /* depth of the window */
} XCBGetGeometryRep;
</pre>
<p>
- XCB fill this structure with two functions:
- </p>
- <pre class="code">
+ XCB fill this structure with two functions:
+ </p>
+ <pre class="code">
XCBGetGeometryCookie XCBGetGeometry (XCBConnection *c,
XCBDRAWABLE drawable);
XCBGetGeometryRep *XCBGetGeometryReply (XCBConnection *c,
XCBGenericError **e);
</pre>
<p>
- You use them as follows:
- </p>
- <pre class="code">
+ You use them as follows:
+ </p>
+ <pre class="code">
XCBConnection *c;
XCBDRAWABLE win;
XCBGetGeometryRep *geom;
free (geom);
</pre>
<p>
- Remark that you have to free the structure, as
- <span class="code">XCBGetGeometryReply</span> allocates a
- newly one.
- </p>
- <p>
- One problem is that the returned location of the window is
- relative to its parent window. This makes these coordinates
- rather useless for any window manipulation functions, like
- moving it on the screen. In order to overcome this problem, we
- need to take a two-step operation. First, we find out the Id
- of the parent window of our window. We then translate the
- above relative coordinates to the screen coordinates.
- </p>
- <p>
- To get the Id of the parent window, we need this structure:
- </p>
- <pre class="code">
+ Remark that you have to free the structure, as
+ <span class="code">XCBGetGeometryReply</span> allocates a
+ newly one.
+ </p>
+ <p>
+ One problem is that the returned location of the window is
+ relative to its parent window. This makes these coordinates
+ rather useless for any window manipulation functions, like
+ moving it on the screen. In order to overcome this problem, we
+ need to take a two-step operation. First, we find out the Id
+ of the parent window of our window. We then translate the
+ above relative coordinates to the screen coordinates.
+ </p>
+ <p>
+ To get the Id of the parent window, we need this structure:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type;
CARD8 pad0;
} XCBQueryTreeRep;
</pre>
<p>
- To fill this structure, we use these two functions:
- </p>
- <pre class="code">
+ To fill this structure, we use these two functions:
+ </p>
+ <pre class="code">
XCBQueryTreeCookie XCBQueryTree (XCBConnection *c,
XCBWINDOW window);
XCBQueryTreeRep *XCBQueryTreeReply (XCBConnection *c,
XCBQueryTreeCookie cookie,
- XCBGenericError **e);
+ XCBGenericError **e);
</pre>
<p>
- The translated coordinates will be found in this structure:
- </p>
- <pre class="code">
+ The translated coordinates will be found in this structure:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type;
BOOL same_screen;
} XCBTranslateCoordinatesRep;
</pre>
<p>
- As usual, we need two functions to fill this structure:
- </p>
- <pre class="code">
+ As usual, we need two functions to fill this structure:
+ </p>
+ <pre class="code">
XCBTranslateCoordinatesCookie XCBTranslateCoordinates (XCBConnection *c,
XCBWINDOW src_window,
- XCBWINDOW dst_window,
- INT16 src_x,
- INT16 src_y);
+ XCBWINDOW dst_window,
+ INT16 src_x,
+ INT16 src_y);
XCBTranslateCoordinatesRep *XCBTranslateCoordinatesReply (XCBConnection *c,
- XCBTranslateCoordinatesCookie cookie,
- XCBGenericError **e);
+ XCBTranslateCoordinatesCookie cookie,
+ XCBGenericError **e);
</pre>
<p>
- We use them as follows:
- </p>
- <pre class="code">
+ We use them as follows:
+ </p>
+ <pre class="code">
XCBConnection *c;
XCBDRAWABLE win;
XCBGetGeometryRep *geom;
trans = XCBTranslateCoordinatesReply (c,
XCBTranslateCoordinates (c,
win,
- tree->parent,
- geom->x, geom->y),
+ tree->parent,
+ geom->x, geom->y),
0);
if (!trans)
return 0;
free (geom);
</pre>
<p>
- Of course, as for <span class="code">geom</span>,
- <span class="code">tree</span> and
- <span class="code">trans</span> have to be freed.
- </p>
- <p>
- The work is a bit hard, but XCB is a very low-level library.
- </p>
- <p>
- <b>TODO:</b> the utilization of these functions should be a
- prog, which displays the coordinates of the window.
- </p>
- <p>
- There is another structure that gives informations about our window:
- </p>
- <pre class="code">
+ Of course, as for <span class="code">geom</span>,
+ <span class="code">tree</span> and
+ <span class="code">trans</span> have to be freed.
+ </p>
+ <p>
+ The work is a bit hard, but XCB is a very low-level library.
+ </p>
+ <p>
+ <b>TODO:</b> the utilization of these functions should be a
+ prog, which displays the coordinates of the window.
+ </p>
+ <p>
+ There is another structure that gives informations about our window:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type;
CARD8 backing_store;
} XCBGetWindowAttributesRep;
</pre>
<p>
- XCB supplies these two functions to fill it:
- </p>
- <pre class="code">
+ XCB supplies these two functions to fill it:
+ </p>
+ <pre class="code">
XCBGetWindowAttributesCookie XCBGetWindowAttributes (XCBConnection *c,
XCBWINDOW window);
XCBGetWindowAttributesRep *XCBGetWindowAttributesReply (XCBConnection *c,
XCBGetWindowAttributesCookie cookie,
- XCBGenericError **e);
+ XCBGenericError **e);
</pre>
<p>
- You use them as follows:
- </p>
- <pre class="code">
+ You use them as follows:
+ </p>
+ <pre class="code">
XCBConnection *c;
XCBDRAWABLE win;
XCBGetWindowAttributesRep *attr;
free (attr);
</pre>
<p>
- As for <span class="code">geom</span>,
- <span class="code">attr</span> has to be freed.
- </p>
+ As for <span class="code">geom</span>,
+ <span class="code">attr</span> has to be freed.
+ </p>
</ol>
- <li class="title"><a name="usecolor">Using colors to paint the rainbow</a></li>
+ <li class="title"><a name="usecolor">Using colors to paint the rainbow</a>
<p>
Up until now, all our painting operation were done using black
and white. We will (finally) see now how to draw using colors.
</p>
<ol>
- <li class="subtitle"><a name="colormap">Color maps</a></li>
- <p>
- In the beginning, there were not enough colors. Screen
- controllers could only support a limited number of colors
- simultaneously (initially 2, then 4, 16 and 256). Because of
- this, an application could not just ask to draw in a "light
- purple-red" color, and expect that color to be available. Each
- application allocated the colors it needed, and when all the
- color entries (4, 16, 256 colors) were in use, the next color
- allocation would fail.
- </p>
- <p>
- Thus, the notion of "a color map" was introduced. A color map
- is a table whose size is the same as the number of
- simultaneous colors a given screen controller. Each entry
- contained the RGB (Red, Green and Blue) values of a different
- color (all colors can be drawn using some combination of red,
- green and blue). When an application wants to draw on the
- screen, it does not specify which color to use. Rather, it
- specifies which color entry of some color map to be used
- during this drawing. Change the value in this color map entry
- and the drawing will use a different color.
- </p>
- <p>
- In order to be able to draw using colors that got something to
- do with what the programmer intended, color map allocation
- functions are supplied. You could ask to allocate entry for a
- color with a set of RGB values. If one already existed, you
- would get its index in the table. If none existed, and the
- table was not full, a new cell would be allocated to contain
- the given RGB values, and its index returned. If the table was
- full, the procedure would fail. You could then ask to get a
- color map entry with a color that is closest to the one you
- were asking for. This would mean that the actual drawing on
- the screen would be done using colors similar to what you
- wanted, but not the same.
- </p>
- <p>
- On today's more modern screens where one runs an X server with
- support for 16 million colors, this limitation looks a little
- silly, but remember that there are still older computers with
- older graphics cards out there. Using color map, support for
- these screen becomes transparent to you. On a display
- supporting 16 million colors, any color entry allocation
- request would succeed. On a display supporting a limited
- number of colors, some color allocation requests would return
- similar colors. It won't look as good, but your application
- would still work.
- </p>
- <li class="subtitle"><a name="colormapalloc">Allocating and freeing Color Maps</a></li>
- <p>
- When you draw using XCB, you can choose to use the standard
- color map of the screen your window is displayed on, or you
- can allocate a new color map and apply it to a window. In the
- latter case, each time the mouse moves onto your window, the
- screen color map will be replaced by your window's color map,
- and you'll see all the other windows on screen change their
- colors into something quite bizzare. In fact, this is the
- effect you get with X applications that use the "-install"
- command line option.
- </p>
- <p>
- In XCB, a color map is (as often in X) an Id:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="colormap">Color maps</a>
+ <p>
+ In the beginning, there were not enough colors. Screen
+ controllers could only support a limited number of colors
+ simultaneously (initially 2, then 4, 16 and 256). Because of
+ this, an application could not just ask to draw in a "light
+ purple-red" color, and expect that color to be available. Each
+ application allocated the colors it needed, and when all the
+ color entries (4, 16, 256 colors) were in use, the next color
+ allocation would fail.
+ </p>
+ <p>
+ Thus, the notion of "a color map" was introduced. A color map
+ is a table whose size is the same as the number of
+ simultaneous colors a given screen controller. Each entry
+ contained the RGB (Red, Green and Blue) values of a different
+ color (all colors can be drawn using some combination of red,
+ green and blue). When an application wants to draw on the
+ screen, it does not specify which color to use. Rather, it
+ specifies which color entry of some color map to be used
+ during this drawing. Change the value in this color map entry
+ and the drawing will use a different color.
+ </p>
+ <p>
+ In order to be able to draw using colors that got something to
+ do with what the programmer intended, color map allocation
+ functions are supplied. You could ask to allocate entry for a
+ color with a set of RGB values. If one already existed, you
+ would get its index in the table. If none existed, and the
+ table was not full, a new cell would be allocated to contain
+ the given RGB values, and its index returned. If the table was
+ full, the procedure would fail. You could then ask to get a
+ color map entry with a color that is closest to the one you
+ were asking for. This would mean that the actual drawing on
+ the screen would be done using colors similar to what you
+ wanted, but not the same.
+ </p>
+ <p>
+ On today's more modern screens where one runs an X server with
+ support for 16 million colors, this limitation looks a little
+ silly, but remember that there are still older computers with
+ older graphics cards out there. Using color map, support for
+ these screen becomes transparent to you. On a display
+ supporting 16 million colors, any color entry allocation
+ request would succeed. On a display supporting a limited
+ number of colors, some color allocation requests would return
+ similar colors. It won't look as good, but your application
+ would still work.
+ </p>
+ <li class="subtitle"><a name="colormapalloc">Allocating and freeing Color Maps</a>
+ <p>
+ When you draw using XCB, you can choose to use the standard
+ color map of the screen your window is displayed on, or you
+ can allocate a new color map and apply it to a window. In the
+ latter case, each time the mouse moves onto your window, the
+ screen color map will be replaced by your window's color map,
+ and you'll see all the other windows on screen change their
+ colors into something quite bizzare. In fact, this is the
+ effect you get with X applications that use the "-install"
+ command line option.
+ </p>
+ <p>
+ In XCB, a color map is (as often in X) an Id:
+ </p>
+ <pre class="code">
typedef struct {
CARD32 xid;
} XCBCOLORMAP;
</pre>
- <p>
- In order to access the screen's default color map, you just
- have to retrieve the <span class="code">default_colormap</span>
- field of the <span class="code">XCBSCREEN</span> structure
- (see Section
- <a href="#screen">Checking basic information about a connection</a>):
- </p>
- <pre class="code">
+ <p>
+ In order to access the screen's default color map, you just
+ have to retrieve the <span class="code">default_colormap</span>
+ field of the <span class="code">XCBSCREEN</span> structure
+ (see Section
+ <a href="#screen">Checking basic information about a connection</a>):
+ </p>
+ <pre class="code">
#include <stdio.h>
#include <X11/XCB/xcb.h>
return 1;
}
</pre>
- <p>
- This will return the color map used by default on the first
- screen (again, remember that an X server may support several
- different screens, each of which might have its own resources).
- </p>
- <p>
- The other option, that of allocating a new colormap, works as
- follows. We first ask the X server to give an Id to our color
- map, with this function:
- </p>
- <pre class="code">
+ <p>
+ This will return the color map used by default on the first
+ screen (again, remember that an X server may support several
+ different screens, each of which might have its own resources).
+ </p>
+ <p>
+ The other option, that of allocating a new colormap, works as
+ follows. We first ask the X server to give an Id to our color
+ map, with this function:
+ </p>
+ <pre class="code">
XCBCOLORMAP XCBCOLORMAPNew (XCBConnection *c);
</pre>
- <p>
- Then, we create the color map with
- </p>
- <pre class="code">
+ <p>
+ Then, we create the color map with
+ </p>
+ <pre class="code">
XCBVoidCookie XCBCreateColormap (XCBConnection *c, /* Pointer to the XCBConnection structure */
BYTE alloc, /* Colormap entries to be allocated (AllocNone or AllocAll) */
- XCBCOLORMAP mid, /* Id of the color map */
- XCBWINDOW window, /* Window on whose screen the colormap will be created */
- XCBVISUALID visual); /* Id of the visual supported by the screen */
-</pre>
- <p>
- Here is an example of creation of a new color map:
- </p>
- <pre class="code">
+ XCBCOLORMAP mid, /* Id of the color map */
+ XCBWINDOW window, /* Window on whose screen the colormap will be created */
+ XCBVISUALID visual); /* Id of the visual supported by the screen */
+</pre>
+ <p>
+ Here is an example of creation of a new color map:
+ </p>
+ <pre class="code">
#include <X11/XCB/xcb.h>
int
}
</pre>
<p>
- Note that the window parameter is only used to allow the X
- server to create the color map for the given screen. We can
- then use this color map for any window drawn on the same screen.
- </p>
- <p>
- To free a color map, it suffices to use this function:
- </p>
- <pre class="code">
+ Note that the window parameter is only used to allow the X
+ server to create the color map for the given screen. We can
+ then use this color map for any window drawn on the same screen.
+ </p>
+ <p>
+ To free a color map, it suffices to use this function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBFreeColormap (XCBConnection *c, /* The connection */
XCBCOLORMAP cmap); /* The color map */
</pre>
<div class="comp">
<div class="title">
- Comparison Xlib/XCB
+ Comparison Xlib/XCB
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XCreateColormap ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBCOLORMAPNew ()
+ <li>XCBCreateColormap ()
+ </ul>
+ </div>
+ <div class="xlib">
+ <ul>
+ <li>XFreeColormap ()
+ </ul>
+ </div>
+ <div class="xcb">
+ <ul>
+ <li>XCBFreeColormap ()
+ </ul>
</div>
- <div class="xlib">
- <ul>
- <li>XCreateColormap ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBCOLORMAPNew ()</li>
- <li>XCBCreateColormap ()</li>
- </ul>
- </div>
- <div class="xlib">
- <ul>
- <li>XFreeColormap ()</li>
- </ul>
- </div>
- <div class="xcb">
- <ul>
- <li>XCBFreeColormap ()</li>
- </ul>
- </div>
</div>
- <p></p>
- <li class="subtitle"><a name="alloccolor">Allocating and freeing a color entry</a></li>
- <p>
- Once we got access to some color map, we can start allocating
- colors. The informations related to a color are stored in the
- following structure:
- </p>
- <pre class="code">
+ <br>
+ <li class="subtitle"><a name="alloccolor">Allocating and freeing a color entry</a>
+ <p>
+ Once we got access to some color map, we can start allocating
+ colors. The informations related to a color are stored in the
+ following structure:
+ </p>
+ <pre class="code">
typedef struct {
BYTE response_type;
CARD8 pad0;
<pre class="code">
XCBAllocColorCookie XCBAllocColor (XCBConnection *c,
XCBCOLORMAP cmap,
- CARD16 red,
- CARD16 green,
- CARD16 blue);
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue);
XCBAllocColorRep *XCBAllocColorReply (XCBConnection *c,
XCBAllocColorCookie cookie,
- XCBGenericError **e);
+ XCBGenericError **e);
</pre>
<p>
The fuction <span class="code">XCBAllocColor()</span> takes the
<b>TODO</b>: Talk about freeing colors.
</p>
</ol>
- <li class="title"><a name="pixmaps">X Bitmaps and Pixmaps</a></li>
+ <li class="title"><a name="pixmaps">X Bitmaps and Pixmaps</a>
<p>
One thing many so-called "Multi-Media" applications need to do,
is display images. In the X world, this is done using bitmaps
pixmaps).
</p>
<ol>
- <li class="subtitle"><a name="pixmapswhat">What is a X Bitmap? An X Pixmap?</a></li>
- <p>
- An X bitmap is a two-color image stored in a format specific
- to the X window system. When stored in a file, the bitmap data
- looks like a C source file. It contains variables defining the
- width and the height of the bitmap, an array containing the
- bit values of the bitmap (the size of the array is
- weight*height), and an optional hot-spot location (that will
- be explained later, when discussing mouse cursors).
- </p>
- <p>
- An X pixmap is a format used to stored images in the memory of
- an X server. This format can store both black and white images
- (such as x bitmaps) as well as color images. It is the only
- image format supported by the X protocol, and any image to be
- drawn on screen, should be first translated into this format.
- </p>
- <p>
- In actuality, an X pixmap can be thought of as a window that
- does not appear on the screen. Many graphics operations that
- work on windows, will also work on pixmaps. Indeed, the type
- of X pixmap in XCB is an Id like a window:
- </p>
- <pre class="code">
+ <li class="subtitle"><a name="pixmapswhat">What is a X Bitmap? An X Pixmap?</a>
+ <p>
+ An X bitmap is a two-color image stored in a format specific
+ to the X window system. When stored in a file, the bitmap data
+ looks like a C source file. It contains variables defining the
+ width and the height of the bitmap, an array containing the
+ bit values of the bitmap (the size of the array is
+ weight*height), and an optional hot-spot location (that will
+ be explained later, when discussing mouse cursors).
+ </p>
+ <p>
+ An X pixmap is a format used to stored images in the memory of
+ an X server. This format can store both black and white images
+ (such as x bitmaps) as well as color images. It is the only
+ image format supported by the X protocol, and any image to be
+ drawn on screen, should be first translated into this format.
+ </p>
+ <p>
+ In actuality, an X pixmap can be thought of as a window that
+ does not appear on the screen. Many graphics operations that
+ work on windows, will also work on pixmaps. Indeed, the type
+ of X pixmap in XCB is an Id like a window:
+ </p>
+ <pre class="code">
typedef struct {
CARD32 xid;
} XCBPIXMAP;
</pre>
- <p>
- In order to make the difference between a window and a pixmap,
- XCB introduces a drawable type, which is a <b>union</b>
- </p>
- <pre class="code">
+ <p>
+ In order to make the difference between a window and a pixmap,
+ XCB introduces a drawable type, which is a <b>union</b>
+ </p>
+ <pre class="code">
typedef union {
XCBWINDOW window;
XCBPIXMAP pixmap;
} XCBDRAWABLE;
</pre>
<p>
- in order to avoid confusion between a window and a pixmap. The
- operations that will work indifferently on a window or a pixmap
- will require a <span class="code">XCBDRAWABLE</span>
- </p>
- <div class="emph">
- <p>
- Remark: In Xlib, there is no specific difference between a
- <span class="code">Drawable</span>, a
- <span class="code">Pixmap</span> or a
- <span class="code">Window</span>: all are 32 bit long
- integer.
- </p>
- </div>
- <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a></li>
- <p>
- Sometimes we want to create an un-initialized pixmap, so we
- can later draw into it. This is useful for image drawing
- programs (creating a new empty canvas will cause the creation
- of a new pixmap on which the drawing can be stored). It is
- also useful when reading various image formats: we load the
- image data into memory, create a pixmap on the server, and
- then draw the decoded image data onto that pixmap.
- </p>
- <p>
- To create a new pixmap, we first ask the X server to give an
- Id to our pixmap, with this function:
- </p>
- <pre class="code">
+ in order to avoid confusion between a window and a pixmap. The
+ operations that will work indifferently on a window or a pixmap
+ will require a <span class="code">XCBDRAWABLE</span>
+ </p>
+ <div class="emph">
+ <p>
+ Remark: In Xlib, there is no specific difference between a
+ <span class="code">Drawable</span>, a
+ <span class="code">Pixmap</span> or a
+ <span class="code">Window</span>: all are 32 bit long
+ integer.
+ </p>
+ </div>
+ <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a>
+ <p>
+ Sometimes we want to create an un-initialized pixmap, so we
+ can later draw into it. This is useful for image drawing
+ programs (creating a new empty canvas will cause the creation
+ of a new pixmap on which the drawing can be stored). It is
+ also useful when reading various image formats: we load the
+ image data into memory, create a pixmap on the server, and
+ then draw the decoded image data onto that pixmap.
+ </p>
+ <p>
+ To create a new pixmap, we first ask the X server to give an
+ Id to our pixmap, with this function:
+ </p>
+ <pre class="code">
XCBPIXMAP XCBPIXMAPNew (XCBConnection *c);
</pre>
<p>
- Then, XCB supplies the following function to create new pixmaps:
- </p>
- <pre class="code">
+ Then, XCB supplies the following function to create new pixmaps:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBCreatePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
CARD8 depth, /* Depth of the screen */
- XCBPIXMAP pid, /* Id of the pixmap */
- XCBDRAWABLE drawable,
- CARD16 width, /* Width of the window (in pixels) */
- CARD16 height); /* Height of the window (in pixels) */
-</pre>
- <p>
- <b>TODO</b>: Explain the drawable parameter, and give an
- example (like xpoints.c)
- </p>
- <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window</li>
- <p>
- Once we got a handle to a pixmap, we can draw it on some
- window, using the following function:
- </p>
- <pre class="code">
+ XCBPIXMAP pid, /* Id of the pixmap */
+ XCBDRAWABLE drawable,
+ CARD16 width, /* Width of the window (in pixels) */
+ CARD16 height); /* Height of the window (in pixels) */
+</pre>
+ <p>
+ <b>TODO</b>: Explain the drawable parameter, and give an
+ example (like xpoints.c)
+ </p>
+ <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window
+ <p>
+ Once we got a handle to a pixmap, we can draw it on some
+ window, using the following function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBCopyArea (XCBConnection *c, /* Pointer to the XCBConnection structure */
XCBDRAWABLE src_drawable, /* The Drawable we want to paste */
- XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
- XCBGCONTEXT gc, /* A Graphic Context */
- INT16 src_x, /* Top left x coordinate of the region we want to copy */
- INT16 src_y, /* Top left y coordinate of the region we want to copy */
- INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
- INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
- CARD16 width, /* Width of the region we want to copy */
- CARD16 height); /* Height of the region we want to copy */
-</pre>
- <p>
- As you can see, we could copy the whole pixmap, as well as
- only a given rectangle of the pixmap. This is useful to
- optimize the drawing speed: we could copy only what we have
- modified in the pixmap.
- </p>
- <p>
- <b>One important note should be made</b>: it is possible to
- create pixmaps with different depths on the same screen. When
- we perform copy operations (a pixmap onto a window, etc), we
- should make sure that both source and target have the same
- depth. If they have a different depth, the operation would
- fail. The exception to this is if we copy a specific bit plane
- of the source pixmap using the
- <span class="code">XCBCopyPlane</span> function. In such an
- event, we can copy a specific plain to the target window (in
- actuality, setting a specific bit in the color of each pixel
- copied). This can be used to generate strange graphic effects
- in widow, but that is beyond the scope of this tutorial.
- </p>
- <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap</li>
- <p>
- Finally, when we are done using a given pixmap, we should free
- it, in order to free resources of the X server. This is done
- using this function:
- </p>
- <pre class="code">
+ XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
+ XCBGCONTEXT gc, /* A Graphic Context */
+ INT16 src_x, /* Top left x coordinate of the region we want to copy */
+ INT16 src_y, /* Top left y coordinate of the region we want to copy */
+ INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
+ INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
+ CARD16 width, /* Width of the region we want to copy */
+ CARD16 height); /* Height of the region we want to copy */
+</pre>
+ <p>
+ As you can see, we could copy the whole pixmap, as well as
+ only a given rectangle of the pixmap. This is useful to
+ optimize the drawing speed: we could copy only what we have
+ modified in the pixmap.
+ </p>
+ <p>
+ <b>One important note should be made</b>: it is possible to
+ create pixmaps with different depths on the same screen. When
+ we perform copy operations (a pixmap onto a window, etc), we
+ should make sure that both source and target have the same
+ depth. If they have a different depth, the operation would
+ fail. The exception to this is if we copy a specific bit plane
+ of the source pixmap using the
+ <span class="code">XCBCopyPlane</span> function. In such an
+ event, we can copy a specific plain to the target window (in
+ actuality, setting a specific bit in the color of each pixel
+ copied). This can be used to generate strange graphic effects
+ in widow, but that is beyond the scope of this tutorial.
+ </p>
+ <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap
+ <p>
+ Finally, when we are done using a given pixmap, we should free
+ it, in order to free resources of the X server. This is done
+ using this function:
+ </p>
+ <pre class="code">
XCBVoidCookie XCBFreePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
XCBPIXMAP pixmap); /* A given pixmap */
</pre>
- <p>
- Of course, after having freed it, we must not try accessing
- the pixmap again.
- </p>
- <p>
- <b>TODO</b>: Give an example, or a link to xpoints.c
- </p>
+ <p>
+ Of course, after having freed it, we must not try accessing
+ the pixmap again.
+ </p>
+ <p>
+ <b>TODO</b>: Give an example, or a link to xpoints.c
+ </p>
</ol>
- <li class="title"><a name="translation">Translation of basic Xlib functions and macros</a></li>
+ <li class="title"><a name="translation">Translation of basic Xlib functions and macros</a>
<p>
The problem when you want to port an Xlib program to XCB is that
you don't know if the Xlib function that you want to "translate"
provides. It's usually just a member of a structure.
</p>
<ol>
- <li class="subtitle"><a name="displaystructure">Members of the Display structure</a></li>
+ <li class="subtitle"><a name="displaystructure">Members of the Display structure</a>
In this section, we look at how to translate the macros that
return some members of the <span class="code">Display</span>
structure. They are obtained by using a function that requires a
(via the function <span class="code">XCBGetSetup</span>), or
a function that requires that structure.
<ol>
- <li class="subtitle"><a name="ConnectionNumber">ConnectionNumber</a></li>
+ <li class="subtitle"><a name="ConnectionNumber">ConnectionNumber</a>
<p>
This number is the file descriptor that connects the client
to the server. You just have to use that function:
<pre class="code">
int XCBGetFileDescriptor(XCBConnection *c);
</pre>
- <li class="subtitle"><a name="DefaultScreen"></a>DefaultScreen</li>
+ <li class="subtitle"><a name="DefaultScreen"></a>DefaultScreen
<p>
That number is not stored by XCB. It is returned in the
second parameter of the function <span class="code"><a href="#openconn">XCBConnect</a></span>.
/* you pass the name of the display you want to XCBConnect */
-c = XCBConnect (display_name, &screen_default_nbr);
+c = XCBConnect (display_name, &screen_default_nbr);
/* screen_default_nbr contains now the number of the default screen */
</pre>
- <li class="subtitle"><a name="QLength"></a>QLength</li>
+ <li class="subtitle"><a name="QLength"></a>QLength
<p>
Not documented yet.
</p>
- <li class="subtitle"><a name="ScreenCount"></a>ScreenCount</li>
+ <li class="subtitle"><a name="ScreenCount"></a>ScreenCount
<p>
You get the count of screens with the functions
<span class="code">XCBGetSetup</span>
/* screen_count contains now the count of screens */
</pre>
- <li class="subtitle"><a name="ServerVendor"></a>ServerVendor</li>
+ <li class="subtitle"><a name="ServerVendor"></a>ServerVendor
<p>
You get the name of the vendor of the server hardware with
the functions <span class="code">XCBGetSetup</span>
/* vendor contains now the name of the vendor. Must be freed when not used anymore */
</pre>
- <li class="subtitle"><a name="ProtocolVersion"></a>ProtocolVersion</li>
+ <li class="subtitle"><a name="ProtocolVersion"></a>ProtocolVersion
<p>
You get the major version of the protocol in the
<span class="code">XCBConnSetupSuccessRep</span>
/* protocol_major_version contains now the major version of the protocol */
</pre>
- <li class="subtitle"><a name="ProtocolRevision"></a>ProtocolRevision</li>
+ <li class="subtitle"><a name="ProtocolRevision"></a>ProtocolRevision
<p>
You get the minor version of the protocol in the
<span class="code">XCBConnSetupSuccessRep</span>
/* protocol_minor_version contains now the minor version of the protocol */
</pre>
- <li class="subtitle"><a name="VendorRelease"></a>VendorRelease</li>
+ <li class="subtitle"><a name="VendorRelease"></a>VendorRelease
<p>
You get the number of the release of the server hardware in the
<span class="code">XCBConnSetupSuccessRep</span>
/* release_number contains now the number of the release of the server hardware */
</pre>
- <li class="subtitle"><a name="DisplayString"></a>DisplayString</li>
+ <li class="subtitle"><a name="DisplayString"></a>DisplayString
<p>
The name of the display is not stored in XCB. You have to
store it by yourself.
</p>
- <li class="subtitle"><a name="BitmapUnit"></a>BitmapUnit</li>
+ <li class="subtitle"><a name="BitmapUnit"></a>BitmapUnit
<p>
You get the bitmap scanline unit in the
<span class="code">XCBConnSetupSuccessRep</span>
/* bitmap_format_scanline_unit contains now the bitmap scanline unit */
</pre>
- <li class="subtitle"><a name="BitmapBitOrder"></a>BitmapBitOrder</li>
+ <li class="subtitle"><a name="BitmapBitOrder"></a>BitmapBitOrder
<p>
You get the bitmap bit order in the
<span class="code">XCBConnSetupSuccessRep</span>
/* bitmap_format_bit_order contains now the bitmap bit order */
</pre>
- <li class="subtitle"><a name="BitmapPad"></a>BitmapPad</li>
+ <li class="subtitle"><a name="BitmapPad"></a>BitmapPad
<p>
You get the bitmap scanline pad in the
<span class="code">XCBConnSetupSuccessRep</span>
/* bitmap_format_scanline_pad contains now the bitmap scanline pad */
</pre>
- <li class="subtitle"><a name="ImageByteOrder"></a>ImageByteOrder</li>
+ <li class="subtitle"><a name="ImageByteOrder"></a>ImageByteOrder
<p>
You get the image byte order in the
<span class="code">XCBConnSetupSuccessRep</span>
/* image_byte_order contains now the image byte order */
</pre>
</ol>
- <li class="subtitle"><a name="screenofdisplay">ScreenOfDisplay related functions</a></li>
+ <li class="subtitle"><a name="screenofdisplay">ScreenOfDisplay related functions</a>
<p>
in Xlib, <span class="code">ScreenOfDisplay</span> returns a
<span class="code">Screen</span> structure that contains
more) as, with XCB, you will use the same code.
</p>
<ol>
- <li class="subtitle"><a name="ScreenOfDisplay">ScreenOfDisplay</a></li>
+ <li class="subtitle"><a name="ScreenOfDisplay">ScreenOfDisplay</a>
<p>
This function returns the Xlib <span class="code">Screen</span>
structure. With XCB, you iterate over all the screens and
XCBSCREENIter iter;
iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
- for (; iter.rem; --screen, XCBSCREENNext (&iter))
+ for (; iter.rem; --screen, XCBSCREENNext (&iter))
if (screen == 0)
return iter.data;
function, as they just grab a specific member of the
<span class="code">XCBSCREEN</span> structure.
</p>
- <li class="subtitle"><a name="DefaultScreenOfDisplay"></a>DefaultScreenOfDisplay</li>
+ <li class="subtitle"><a name="DefaultScreenOfDisplay"></a>DefaultScreenOfDisplay
<p>
It is the default screen that you obtain when you connect to
the X server. It suffices to call the <a href="#ScreenOfDisplay">ScreenOfDisplay</a>
/* you pass the name of the display you want to XCBConnect */
-c = XCBConnect (display_name, &screen_default_nbr);
+c = XCBConnect (display_name, &screen_default_nbr);
default_screen = ScreenOfDisplay (c, screen_default_nbr);
/* default_screen contains now the default root window, or a NULL window if no screen is found */
</pre>
- <li class="subtitle"><a name="RootWindow">RootWindow / RootWindowOfScreen</a></li>
+ <li class="subtitle"><a name="RootWindow">RootWindow / RootWindowOfScreen</a>
<p>
</p>
<pre class="code">
/* root_window contains now the root window, or a NULL window if no screen is found */
</pre>
- <li class="subtitle"><a name="DefaultRootWindow">DefaultRootWindow</a></li>
+ <li class="subtitle"><a name="DefaultRootWindow">DefaultRootWindow</a>
<p>
It is the root window of the default screen. So, you call
<a name="ScreenOfDisplay">ScreenOfDisplay</a> with the
/* you pass the name of the display you want to XCBConnect */
-c = XCBConnect (display_name, &screen_default_nbr);
+c = XCBConnect (display_name, &screen_default_nbr);
screen = ScreenOfDisplay (c, screen_default_nbr);
if (screen)
root_window = screen->root;
/* root_window contains now the default root window, or a NULL window if no screen is found */
</pre>
- <li class="subtitle"><a name="DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a></li>
+ <li class="subtitle"><a name="DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a>
<p>
While a Visual is, in Xlib, a structure, in XCB, there are
two types: <span class="code">XCBVISUALID</span>, which is
XCBDEPTHIter depth_iter;
depth_iter = XCBSCREENAllowedDepthsIter (screen);
- for (; depth_iter.rem; XCBDEPTHNext (&depth_iter))
+ for (; depth_iter.rem; XCBDEPTHNext (&depth_iter))
{
XCBVISUALTYPEIter visual_iter;
visual_iter = XCBDEPTHVisualsIter (depth_iter.data);
- for (; visual_iter.rem; XCBVISUALTYPENext (&visual_iter))
+ for (; visual_iter.rem; XCBVISUALTYPENext (&visual_iter))
{
if (screen->root_visual.id == visual_iter.data->visual_id.id)
{
/* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
</pre>
- <li class="subtitle"><a name="DefaultGC">DefaultGC / DefaultGCOfScreen</a></li>
+ <li class="subtitle"><a name="DefaultGC">DefaultGC / DefaultGCOfScreen</a>
<p>
This default Graphic Context is just a newly created Graphic
Context, associated to the root window of a
/* gc contains now the default graphic context */
</pre>
- <li class="subtitle"><a name="BlackPixel">BlackPixel / BlackPixelOfScreen</a></li>
+ <li class="subtitle"><a name="BlackPixel">BlackPixel / BlackPixelOfScreen</a>
<p>
It is the Id of the black pixel, which is in the structure
of an <span class="code">XCBSCREEN</span>.
/* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="WhitePixel">WhitePixel / WhitePixelOfScreen</a></li>
+ <li class="subtitle"><a name="WhitePixel">WhitePixel / WhitePixelOfScreen</a>
<p>
It is the Id of the white pixel, which is in the structure
of an <span class="code">XCBSCREEN</span>.
/* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DisplayWidth">DisplayWidth / WidthOfScreen</a></li>
+ <li class="subtitle"><a name="DisplayWidth">DisplayWidth / WidthOfScreen</a>
<p>
It is the width in pixels of the screen that you want, and
which is in the structure of the corresponding
/* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DisplayHeight">DisplayHeight / HeightOfScreen</a></li>
+ <li class="subtitle"><a name="DisplayHeight">DisplayHeight / HeightOfScreen</a>
<p>
It is the height in pixels of the screen that you want, and
which is in the structure of the corresponding
/* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a></li>
+ <li class="subtitle"><a name="DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a>
<p>
It is the width in millimeters of the screen that you want, and
which is in the structure of the corresponding
/* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a></li>
+ <li class="subtitle"><a name="DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a>
<p>
It is the height in millimeters of the screen that you want, and
which is in the structure of the corresponding
/* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a></li>
+ <li class="subtitle"><a name="DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a>
<p>
It is the depth (in bits) of the root window of the
screen. You get it from the <span class="code">XCBSCREEN</span> structure.
/* root_depth contains now the depth of the root window, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a></li>
+ <li class="subtitle"><a name="DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a>
<p>
This is the default colormap of the screen (and not the
(default) colormap of the default screen !). As usual, you
/* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
</pre>
- <li class="subtitle"><a name="MinCmapsOfScreen"></a>MinCmapsOfScreen</li>
+ <li class="subtitle"><a name="MinCmapsOfScreen"></a>MinCmapsOfScreen
<p>
You get the minimum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
</p>
/* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="MaxCmapsOfScreen"></a>MaxCmapsOfScreen</li>
+ <li class="subtitle"><a name="MaxCmapsOfScreen"></a>MaxCmapsOfScreen
<p>
You get the maximum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
</p>
/* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
</pre>
- <li class="subtitle"><a name="DoesSaveUnders"></a>DoesSaveUnders</li>
+ <li class="subtitle"><a name="DoesSaveUnders"></a>DoesSaveUnders
<p>
You know if <span class="code">save_unders</span> is set,
by looking in the <span class="code">XCBSCREEN</span> structure:
/* save_unders contains now the value of save_unders, or FALSE if no screen is found */
</pre>
- <li class="subtitle"><a name="DoesBackingStore"></a>DoesBackingStore</li>
+ <li class="subtitle"><a name="DoesBackingStore"></a>DoesBackingStore
<p>
You know the value of <span class="code">backing_stores</span>,
by looking in the <span class="code">XCBSCREEN</span> structure:
/* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
</pre>
- <li class="subtitle"><a name="EventMaskOfScreen"></a>EventMaskOfScreen</li>
+ <li class="subtitle"><a name="EventMaskOfScreen"></a>EventMaskOfScreen
<p>
To get the current input masks,
you look in the <span class="code">XCBSCREEN</span> structure:
/* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
</pre>
</ol>
- <li class="subtitle"><a name="misc">Miscellaneous macros</a></li>
+ <li class="subtitle"><a name="misc">Miscellaneous macros</a>
<ol>
- <li class="subtitle"><a name="DisplayOfScreen"></a>DisplayOfScreen</li>
+ <li class="subtitle"><a name="DisplayOfScreen"></a>DisplayOfScreen
<p>
in Xlib, the <span class="code">Screen</span> structure
stores its associated <span class="code">Display</span>
hence, it's also not the case in XCB. So you have to store
it by yourself.
</p>
- <li class="subtitle"><a name="DisplayCells"></a>DisplayCells / CellsOfScreen</li>
+ <li class="subtitle"><a name="DisplayCells"></a>DisplayCells / CellsOfScreen
<p>
To get the colormap entries,
you look in the <span class="code">XCBVISUALTYPE</span>