diff options
Diffstat (limited to '')
| -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; +} + | 
