From f52513b09580c1533e6c48a4162d3d5f61f3b081 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 5 Mar 2021 18:23:13 +0100 Subject: misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libgamma_x_randr_site_initialise.c | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 libgamma_x_randr_site_initialise.c (limited to 'libgamma_x_randr_site_initialise.c') diff --git a/libgamma_x_randr_site_initialise.c b/libgamma_x_randr_site_initialise.c new file mode 100644 index 0000000..61c011b --- /dev/null +++ b/libgamma_x_randr_site_initialise.c @@ -0,0 +1,82 @@ +/* See LICENSE file for copyright and license details. */ +#define IN_LIBGAMMA_X_RANDR +#include "common.h" + + +/** + * Initialise an allocated site state + * + * @param this The site state to initialise + * @param site The site identifier, unless it is `NULL` it must a + * `free`:able. Once the state is destroyed the library + * will attempt to free it. There you should not free + * it yourself, and it must not be a string constant + * or allocate on the stack. Note however that it will + * not be free:d if this function fails. + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int +libgamma_x_randr_site_initialise(libgamma_site_state_t *restrict this, char *restrict site) +{ + xcb_generic_error_t *error = NULL; + xcb_connection_t *restrict connection; + xcb_randr_query_version_cookie_t cookie; + xcb_randr_query_version_reply_t *restrict reply; + const xcb_setup_t *restrict setup; + xcb_screen_iterator_t iter; + + /* Connect to the display server */ + this->data = connection = xcb_connect(site, NULL); + if (!connection || xcb_connection_has_error(connection)) + return LIBGAMMA_OPEN_SITE_FAILED; + + /* Query the version of the X RandR extension protocol */ + cookie = xcb_randr_query_version(connection, RANDR_VERSION_MAJOR, RANDR_VERSION_MINOR); + reply = xcb_randr_query_version_reply(connection, cookie, &error); + + /* Check for version query failure */ + if (error || !reply) { + /* Release resources */ + free(reply); + /* If `xcb_connect` failed, both `error` and `reply` will be `NULL`. + * TODO: Can both be `NULL` for any other reason? */ + if (!error && !reply) + return LIBGAMMA_OPEN_SITE_FAILED; + xcb_disconnect(connection); + /* Translate and report error. */ + if (error != NULL) + return libgamma_x_randr_internal_translate_error(error->error_code, LIBGAMMA_PROTOCOL_VERSION_QUERY_FAILED, 0); + return LIBGAMMA_PROTOCOL_VERSION_QUERY_FAILED; + } + + /* Check protocol compatibility, + we require 1.3 but 2.x may not be backwards compatible */ + if (reply->major_version != RANDR_VERSION_MAJOR || reply->minor_version < RANDR_VERSION_MINOR) { +#ifdef DEBUG + /* Print used protocol */ + fprintf(stderr, "libgamma: RandR protocol version: %u.%u", reply->major_version, reply->minor_version); +#endif + /* Release resources */ + free(reply); + xcb_disconnect(connection); + /* Report error */ + return LIBGAMMA_PROTOCOL_VERSION_NOT_SUPPORTED; + } + + /* We do not longer need to know the version of the protocol */ + free(reply); + + /* Get available screens */ + setup = xcb_get_setup(connection); + if (!setup) { + xcb_disconnect(connection); + return LIBGAMMA_LIST_PARTITIONS_FAILED; + } + iter = xcb_setup_roots_iterator(setup); + /* Get the number of available screens */ + this->partitions_available = (size_t)iter.rem; + + /* Sanity check the number of available screens. */ + return iter.rem >= 0 ? 0 : LIBGAMMA_NEGATIVE_PARTITION_COUNT; +} -- cgit v1.2.3-70-g09d2