Exemplo n.º 1
0
int
randr_start(randr_state_t *state)
{
	xcb_generic_error_t *error;

	int screen_num = state->screen_num;
	if (screen_num < 0) screen_num = state->preferred_screen;

	/* Get screen */
	const xcb_setup_t *setup = xcb_get_setup(state->conn);
	xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
	state->screen = NULL;

	for (int i = 0; iter.rem > 0; i++) {
		if (i == screen_num) {
			state->screen = iter.data;
			break;
		}
		xcb_screen_next(&iter);
	}

	if (state->screen == NULL) {
		fprintf(stderr, _("Screen %i could not be found.\n"),
			screen_num);
		return -1;
	}

	/* Get list of CRTCs for the screen */
	xcb_randr_get_screen_resources_current_cookie_t res_cookie =
		xcb_randr_get_screen_resources_current(state->conn,
						       state->screen->root);
	xcb_randr_get_screen_resources_current_reply_t *res_reply =
		xcb_randr_get_screen_resources_current_reply(state->conn,
							     res_cookie,
							     &error);

	if (error) {
		fprintf(stderr, _("`%s' returned error %d\n"),
			"RANDR Get Screen Resources Current",
			error->error_code);
		return -1;
	}

	state->crtc_count = res_reply->num_crtcs;
	state->crtcs = calloc(state->crtc_count, sizeof(randr_crtc_state_t));
	if (state->crtcs == NULL) {
		perror("malloc");
		state->crtc_count = 0;
		return -1;
	}

	xcb_randr_crtc_t *crtcs =
		xcb_randr_get_screen_resources_current_crtcs(res_reply);

	/* Save CRTC identifier in state */
	for (int i = 0; i < state->crtc_count; i++) {
		state->crtcs[i].crtc = crtcs[i];
	}

	free(res_reply);

	/* Save size and gamma ramps of all CRTCs.
	   Current gamma ramps are saved so we can restore them
	   at program exit. */
	for (int i = 0; i < state->crtc_count; i++) {
		xcb_randr_crtc_t crtc = state->crtcs[i].crtc;

		/* Request size of gamma ramps */
		xcb_randr_get_crtc_gamma_size_cookie_t gamma_size_cookie =
			xcb_randr_get_crtc_gamma_size(state->conn, crtc);
		xcb_randr_get_crtc_gamma_size_reply_t *gamma_size_reply =
			xcb_randr_get_crtc_gamma_size_reply(state->conn,
							    gamma_size_cookie,
							    &error);

		if (error) {
			fprintf(stderr, _("`%s' returned error %d\n"),
				"RANDR Get CRTC Gamma Size",
				error->error_code);
			return -1;
		}

		unsigned int ramp_size = gamma_size_reply->size;
		state->crtcs[i].ramp_size = ramp_size;

		free(gamma_size_reply);

		if (ramp_size == 0) {
			fprintf(stderr, _("Gamma ramp size too small: %i\n"),
				ramp_size);
			return -1;
		}

		/* Request current gamma ramps */
		xcb_randr_get_crtc_gamma_cookie_t gamma_get_cookie =
			xcb_randr_get_crtc_gamma(state->conn, crtc);
		xcb_randr_get_crtc_gamma_reply_t *gamma_get_reply =
			xcb_randr_get_crtc_gamma_reply(state->conn,
						       gamma_get_cookie,
						       &error);

		if (error) {
			fprintf(stderr, _("`%s' returned error %d\n"),
				"RANDR Get CRTC Gamma", error->error_code);
			return -1;
		}

		uint16_t *gamma_r =
			xcb_randr_get_crtc_gamma_red(gamma_get_reply);
		uint16_t *gamma_g =
			xcb_randr_get_crtc_gamma_green(gamma_get_reply);
		uint16_t *gamma_b =
			xcb_randr_get_crtc_gamma_blue(gamma_get_reply);

		/* Allocate space for saved gamma ramps */
		state->crtcs[i].saved_ramps =
			malloc(3*ramp_size*sizeof(uint16_t));
		if (state->crtcs[i].saved_ramps == NULL) {
			perror("malloc");
			free(gamma_get_reply);
			return -1;
		}

		/* Copy gamma ramps into CRTC state */
		memcpy(&state->crtcs[i].saved_ramps[0*ramp_size], gamma_r,
		       ramp_size*sizeof(uint16_t));
		memcpy(&state->crtcs[i].saved_ramps[1*ramp_size], gamma_g,
		       ramp_size*sizeof(uint16_t));
		memcpy(&state->crtcs[i].saved_ramps[2*ramp_size], gamma_b,
		       ramp_size*sizeof(uint16_t));

		free(gamma_get_reply);
	}

	return 0;
}
Exemplo n.º 2
0
int x11_initialise_animation(int coarse_fine, double duration, double degrees, const char* output)
{
  xcb_generic_error_t* error = NULL;
  xcb_randr_query_version_cookie_t version_cookie;
  xcb_randr_query_version_reply_t* version_reply = NULL;
  const xcb_setup_t* setup;
  xcb_screen_iterator_t iter;
  xcb_screen_t* screen;
  xcb_randr_get_screen_resources_current_cookie_t screen_cookie;
  xcb_randr_get_output_info_cookie_t output_cookie;
  xcb_randr_crtc_t* crtcs = NULL;
  xcb_randr_output_t* outputs = NULL;
  int found_output = 0;
  size_t i, n;
  xcb_randr_get_crtc_transform_cookie_t transform_cookie;
  xcb_randr_get_crtc_transform_reply_t* transform_reply = NULL;
  
  fine = coarse_fine ? (coarse_fine == 1) : 1;
  
  connection = NULL;
  screen_reply = NULL;
  output_reply = NULL;
  
  connection = xcb_connect(NULL, NULL);
  if (connection == NULL)
    goto pfail;
  
  version_cookie = xcb_randr_query_version(connection, RANDR_VERSION_MAJOR, RANDR_VERSION_MINOR);
  version_reply = xcb_randr_query_version_reply(connection, version_cookie, &error);
  
  if ((error != NULL) || (version_reply == NULL))
    {
      if ((error == NULL) && (version_reply == NULL))
	connection = NULL;
      goto pfail;
    }
  
  if ((version_reply->major_version != RANDR_VERSION_MAJOR) ||
      (version_reply->minor_version < RANDR_VERSION_MINOR))
    {
      fprintf(stderr, "%s: wrong RandR version\n", argv0);
      goto fail;
    }
  
  free(version_reply), version_reply = NULL;
  
  setup = xcb_get_setup(connection);
  if (setup == NULL)
    goto pfail;
  
  iter = xcb_setup_roots_iterator(setup);
  
  for (; (iter.rem > 0) && !found_output; xcb_screen_next(&iter))
    {
      screen = iter.data;
      if (screen == NULL)
	abort();
      
      screen_cookie = xcb_randr_get_screen_resources_current(connection, screen->root);
      screen_reply = xcb_randr_get_screen_resources_current_reply(connection, screen_cookie, &error);
      if (error != NULL)
	goto pfail;
      
      crtcs = xcb_randr_get_screen_resources_current_crtcs(screen_reply);
      outputs = xcb_randr_get_screen_resources_current_outputs(screen_reply);
      if (outputs == NULL)
	goto pfail;
      
      for (i = 0, n = (size_t)(screen_reply->num_outputs); (i < n) && !found_output; i++)
	{
	  uint8_t* name;
	  uint16_t length;
	  char* namez = NULL;
	  uint16_t j;
	  
	  output_cookie = xcb_randr_get_output_info(connection, outputs[i], screen_reply->config_timestamp);
	  output_reply = xcb_randr_get_output_info_reply(connection, output_cookie, &error);
	  if (error != NULL)
	    goto pfail;
	  
	  if (output_reply->connection != XCB_RANDR_CONNECTION_CONNECTED)
	    goto next_output;
	  
	  name = xcb_randr_get_output_info_name(output_reply);
	  length = output_reply->name_len;
	  if (name == NULL)
	    goto pfail;
	  
	  namez = malloc(((size_t)length + 1) * sizeof(char));
	  if (namez == NULL)
	    goto pfail;
	  namez[length] = '\0';
	  while (length--)
	    namez[length] = (char)(name[length]);
	  
	  if (strcmp(namez, output))
	      goto next_output;
	  found_output = 1;
	  free(namez), namez = NULL;
	  
	  for (j = 0; j < screen_reply->num_crtcs; j++)
	    if (crtcs[j] == output_reply->crtc)
	      break;
	  if (j == screen_reply->num_crtcs)
	    {
	      fprintf(stderr, "%s: could not find CRTC associated with output: %s\n", argv0, output);
	      goto fail;
	    }
	  crtc = crtcs[j];
	  
	  goto exit_search_loop;
	  
	next_output:
	  free(namez);
	  free(output_reply), output_reply = NULL;
	}
      
      free(screen_reply), screen_reply = NULL;
    }
 exit_search_loop:
  
  if (!found_output)
    {
      fprintf(stderr, "%s: could not find output: %s\n", argv0, output);
      goto fail;
    }
  
  transform_cookie = xcb_randr_get_crtc_transform(connection, crtc);
  transform_reply = xcb_randr_get_crtc_transform_reply(connection, transform_cookie, &error);
  if (error != NULL)
    goto pfail;
  
  original_transform = transform_reply->pending_transform;
  free(transform_reply);
  
  return 0;
  
 pfail:
  perror(argv0);
 fail:
  free(version_reply);
  free(screen_reply);
  free(output_reply);
  free(transform_reply);
  if (connection != NULL)
    xcb_disconnect(connection);
  return -1;
  
  return (void)duration, (void)degrees, -1; /* TODO */
}
Exemplo n.º 3
0
CGError CGGetOnlineDisplayList(uint32_t max_size, CGDirectDisplayID* displays_out, uint32_t* count_out)
{
  uint32_t i;
  
  if (conn == NULL)
    {
      xcb_generic_error_t* error;
      xcb_screen_iterator_t iter;
      xcb_randr_get_screen_resources_current_cookie_t res_cookie;
      xcb_randr_get_crtc_gamma_cookie_t gamma_cookie;
      xcb_randr_get_crtc_gamma_reply_t* gamma_reply;
      
      conn = xcb_connect(NULL, NULL);
      
      iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
      res_cookie = xcb_randr_get_screen_resources_current(conn, iter.data->root);
      res_reply = xcb_randr_get_screen_resources_current_reply(conn, res_cookie, &error);
      
      if (error)
	{
	  fprintf(stderr, "Failed to open X connection\n");
	  xcb_disconnect(conn);
	  crtc_count = 0;
	  return ~kCGErrorSuccess;
	}
      
      crtc_count = (uint32_t)(res_reply->num_crtcs);
      crtcs = xcb_randr_get_screen_resources_current_crtcs(res_reply);
      
      original_ramps = malloc(crtc_count * 3 * 256 * sizeof(uint16_t));
      if (original_ramps == NULL)
	{
	  perror("malloc");
	  xcb_disconnect(conn);
	  crtc_count = 0;
	  return ~kCGErrorSuccess;
	}
      
      for (i = 0; i < crtc_count; i++)
	{
	  gamma_cookie = xcb_randr_get_crtc_gamma(conn, crtcs[i]);
	  gamma_reply = xcb_randr_get_crtc_gamma_reply(conn, gamma_cookie, &error);
	  
	  if (error)
	    {
	      fprintf(stderr, "Failed to read gamma ramps\n");
	      xcb_disconnect(conn);
	      crtc_count = 0;
	      return ~kCGErrorSuccess;
	    }
	  
#define __DEST(C)  original_ramps + (C + 3 * i) * 256
#define __SRC(C)  xcb_randr_get_crtc_gamma_##C(gamma_reply)
	  memcpy(__DEST(0), __SRC(red),   256 * sizeof(uint16_t));
	  memcpy(__DEST(1), __SRC(green), 256 * sizeof(uint16_t));
	  memcpy(__DEST(2), __SRC(blue),  256 * sizeof(uint16_t));
#undef __SRC
#undef __DEST
	  
	  free(gamma_reply);
	}
    }
  
  for (i = 0; (i < max_size) && (i < crtc_count); i++)
    *(displays_out + i) = (CGDirectDisplayID)i;
  
  *count_out = i;
  return kCGErrorSuccess;
}