diff options
Diffstat (limited to 'src/blueshift_iccprofile.c')
-rw-r--r-- | src/blueshift_iccprofile.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/blueshift_iccprofile.c b/src/blueshift_iccprofile.c new file mode 100644 index 0000000..152b547 --- /dev/null +++ b/src/blueshift_iccprofile.c @@ -0,0 +1,212 @@ +/** + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#define _GNU_SOURCE /* for strcasestr */ +#include <stdlib.h> +#include <stdio.h> +#include <alloca.h> +#include <string.h> + +#include <xcb/xcb.h> + + + +/** + * Connection to the X server + */ +static xcb_connection_t* connection; + +/** + * Used to store errors in + */ +static xcb_generic_error_t* error; + + + +/** + * Main entry point of the program + * + * @param argc Length of `argv` + * @param argv Command line arguments + * @return Zero on success + */ +int main(int argc, char** argv) +{ + const xcb_setup_t* setup; + xcb_screen_iterator_t iter; + int screen_count; + xcb_screen_t* screens; + int screen_i; + + (void) argc; + (void) argv; + + + /* Get X connection */ + + connection = xcb_connect(NULL, NULL); + + + /* Get screen information */ + + setup = xcb_get_setup(connection); + iter = xcb_setup_roots_iterator(setup); + screen_count = iter.rem; + screens = iter.data; + + for (screen_i = 0; screen_i < screen_count; screen_i++) + { + xcb_screen_t* screen = screens + screen_i; + xcb_list_properties_cookie_t list_cookie; + xcb_list_properties_reply_t* list_reply; + xcb_atom_t* atoms; + xcb_atom_t* atoms_end; + + + /* Get root window properties */ + + list_cookie = xcb_list_properties(connection, screen->root); + list_reply = xcb_list_properties_reply(connection, list_cookie, &error); + + if (error) + { + fprintf(stderr, "Screen root window property list query returned %i\n", error->error_code); + xcb_disconnect(connection); + return 1; + } + + atoms = xcb_list_properties_atoms(list_reply); + atoms_end = atoms + xcb_list_properties_atoms_length(list_reply); + + for (; atoms != atoms_end; atoms++) + { + xcb_get_atom_name_cookie_t name_cookie; + xcb_get_atom_name_reply_t* name_reply; + char* name; + char* name_; + int len; + xcb_get_property_cookie_t prop_cookie; + xcb_get_property_reply_t* prop_reply; + int monitor; + + + /* Get root window property name */ + + name_cookie = xcb_get_atom_name(connection, *atoms); + name_reply = xcb_get_atom_name_reply(connection, name_cookie, &error); + + if (error) + { + fprintf(stderr, "Screen root window property name query returned %i\n", error->error_code); + free(list_reply); + xcb_disconnect(connection); + return 1; + } + + name_ = xcb_get_atom_name_name(name_reply); + len = xcb_get_atom_name_name_length(name_reply); + + name = alloca((len + 1) * sizeof(char)); + memcpy(name, name_, len * sizeof(char)); + *(name + len) = 0; + free(name_reply); + + + /* Check property name pattern */ + + if (!strcmp(name, "_icc_profile")) + monitor = 0; + else if (strcasestr(name, "_icc_profile_") == name) + { + name += strlen("_icc_profile_"); + monitor = 0; + if (*name) + continue; + while (*name) + { + char c = *name; + if (('0' <= c) && (c <= '9')) + monitor = monitor * 10 - (c & 15); + else + goto monitor_bad; + } + monitor = -monitor; + goto monitor_ok; + + monitor_bad: + continue; + } + else + continue; + + + /* Get root window property value */ + + monitor_ok: + prop_cookie = xcb_get_property(connection, 0, screen->root, *atoms, XCB_GET_PROPERTY_TYPE_ANY, 0, 0); + prop_reply = xcb_get_property_reply(connection, prop_cookie, &error); + + if (error) + { + fprintf(stderr, "Screen root window property value query returned %i\n", error->error_code); + free(prop_reply); + free(list_reply); + xcb_disconnect(connection); + return 1; + } + + len = prop_reply->bytes_after; + free(prop_reply); + + prop_cookie = xcb_get_property(connection, 0, screen->root, *atoms, XCB_GET_PROPERTY_TYPE_ANY, 0, len); + prop_reply = xcb_get_property_reply(connection, prop_cookie, &error); + + if (error) + { + fprintf(stderr, "Screen root window property value query returned %i\n", error->error_code); + free(prop_reply); + free(list_reply); + xcb_disconnect(connection); + return 1; + } + + { + char* value = alloca((len + 1) * sizeof(char)); + char* value_ = xcb_get_property_value(prop_reply); + + memcpy(value, value_, len); + *(value + len) = 0; + + printf("%i: %i: %s", screen_i, monitor, value); + fflush(stdout); + putchar('\0'); + putchar('\n'); + } + + free(prop_reply); + } + + free(list_reply); + } + + fflush(stdout); + + /* Free resources **/ + + xcb_disconnect(connection); + return 0; +} + |