In this commit, we learned about X11 iterators, which iterate through
monstrous things allocated in memory that you just have to "know" are of a certain structure. In this case, we used `xcb_screen_next` to say that we want the first (and all) screens attached to our current X11 session. And we used `xcb_setup_roots_iterator(xcb_get_setup(connection))` to initialize our iterator to our connection object in local memory. Other things we've learned along the way: the file description that represents our connection can be a TCP/IP socket or a Unix Domain socket (a filesystem socket, named or not), and the only way to know which is to find if there's a hostname before the colon ':' in the display name of the server. Not sure how that's going to work. Also, found a really good reference: [Basic Graphics Tutorial with XCB](https://www.x.org/releases/X11R7.6/doc/libxcb/tutorial/index.html). It doesn't cover our specific use-case, but it's worth looking into.
This commit is contained in:
parent
59a0c6acbf
commit
bafa8bfd23
|
@ -0,0 +1,53 @@
|
|||
# XCB
|
||||
|
||||
XCB is a library for communicating with the X-Windows system used on
|
||||
Linux, FreeBSD, and other Unix-like operating systems. XCB's interface
|
||||
is written in C.
|
||||
|
||||
- Connecting, Verifying Connection, and Disconnecting the server.
|
||||
-
|
||||
|
||||
## Connecting.
|
||||
|
||||
X-Windows is a server. It listens for events (keyboard events, mouse
|
||||
events, timer events from connected programs, etc.) and "stores" the
|
||||
results on a *display*, which is intended to be seen with the human
|
||||
eye. A display is made up of one or more *screens*. Screens can be
|
||||
literal (one of the physical devices in a multi-monitor setup) or
|
||||
virtual (a virtualized desktop where the window manager supports
|
||||
different "pages" on the same monitor), or even just parts of the same
|
||||
physical screen space broken up by some logic.
|
||||
|
||||
To connect to X via XCB, you use the `xcb_connect` function. It takes two
|
||||
arguments, a string with the name of the display, and a
|
||||
pointer-to-int to the preferred screen. It returns an opaque data
|
||||
structure, 'xcb_connection_t'.
|
||||
|
||||
```
|
||||
xcb_connection_t* xcbConnection = xcb_connect(const char* display, int* screen);
|
||||
```
|
||||
|
||||
There are variants for connection-with-authorization, and
|
||||
connection-with-file-descriptor.
|
||||
|
||||
This function always returns an allocated structure, even on failure.
|
||||
You _must_ test for failure with:
|
||||
|
||||
```
|
||||
int error = xcb_connection_has_error(xcb_connection_t* xcbConnection);
|
||||
```
|
||||
|
||||
The error is an number defined in `xcb.h`. See that file for the list
|
||||
of possible failure modes.
|
||||
|
||||
## Disconnecting
|
||||
|
||||
You _must_ close the connection when you are finished. In the event
|
||||
of a connection failure, you _must_ still call this function to
|
||||
free the memory XCB used to report the connection failure:
|
||||
|
||||
```
|
||||
void xcb_disconnect(xcb_connection_t* xcbConnection);
|
||||
```
|
||||
|
||||
|
|
@ -2,8 +2,13 @@
|
|||
#include <xcb/xcb.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
xcb_connection_t *sXRandR11XCBConnection = xcb_connect(nullptr, nullptr);
|
||||
std::cout << sXRandR11XCBConnection << std::endl;
|
||||
xcb_disconnect(sXRandR11XCBConnection);
|
||||
xcb_connection_t *xConnection = xcb_connect(nullptr, nullptr);
|
||||
for (auto iter = xcb_setup_roots_iterator(xcb_get_setup(xConnection));
|
||||
iter.rem; xcb_screen_next(&iter)) {
|
||||
xcb_screen_t *screen = iter.data;
|
||||
std::cout << "Screen " << iter.index << " (" << screen->width_in_pixels
|
||||
<< ", " << screen->height_in_pixels << ")" << std::endl;
|
||||
}
|
||||
xcb_disconnect(xConnection);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue