コード例 #1
0
/**
 * Get the geometry of the screen.
 * @param screen The screen (Unused).
 * @param x      The X coordinate of the screen.
 * @param y      The Y coordinate of the screen
 * @param width  The width of the screen
 * @param height The height of the screen
 * @return       1 on success, 0 otherwise.
 *
 * Get the geometry of the screen whose number is @p screen. The
 * returned values are stored in @p x, @p y, @p width and @p height.
 *
 * To use this function, you must call before, and in order,
 * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request,
 * then ecore_x_xinerama_query_screens_fetch(), which gets the reply.
 * @ingroup Ecore_X_Xinerama_Group
 */
EAPI int
ecore_x_xinerama_screen_geometry_get(int  screen,
                                     int *x,
                                     int *y,
                                     int *width,
                                     int *height)
{
#ifdef ECORE_XCB_XINERAMA
   xcb_xinerama_screen_info_iterator_t iter;
   xcb_xinerama_query_screens_reply_t *reply;

   reply = _ecore_xcb_reply_get();
   if (!reply)
     {
        if (x) *x = 0;
        if (y) *y = 0;
        if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
        if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;

        return 0;
     }

   iter = xcb_xinerama_query_screens_screen_info_iterator(reply);
   for (; iter.rem; screen--, xcb_xinerama_screen_info_next(&iter))
     {
        if (screen == 0)
          {
             if (x) *x = iter.data->x_org;
             if (y) *y = iter.data->y_org;
             if (width) *width = iter.data->width;
             if (height) *height = iter.data->height;
             return 1;
          }
     }
#endif /* ECORE_XCB_XINERAMA */

   if (x) *x = 0;
   if (y) *y = 0;
   if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
   if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;

   return 0;
}
コード例 #2
0
ファイル: ScreenManager.cpp プロジェクト: w1ndy/toywm
bool ScreenManager::scanXinerama(xcb_connection_t *conn)
{
    xcb_generic_error_t *err;
    xcb_xinerama_screen_info_t *screen;

    xcb_xinerama_query_screens_cookie_t cookie =
        xcb_xinerama_query_screens(conn);
    const xcb_xinerama_query_screens_reply_t *reply =
        xcb_xinerama_query_screens_reply(conn, cookie, &err);
    if (err) {
        LOG_ERROR("Error %d while querying xinerama.", err->error_code);
        return false;
    }

    int length = xcb_xinerama_query_screens_screen_info_length(reply);
    xcb_xinerama_screen_info_iterator_t iter =
        xcb_xinerama_query_screens_screen_info_iterator(reply);

    int id = 0;
    char idbuf[5];
    if (!length) {
        LOG_ERROR("No screen found using xinerama.");
        return false;
    } else {
        while (length--) {
            screen = iter.data;
            Screen s;
            sprintf(idbuf, "%d", id);
            s.setName(std::string("Xinerama-") + idbuf);
            s.setX(screen->x_org);
            s.setY(screen->y_org);
            s.setWidth(screen->width);
            s.setHeight(screen->height);
            updateScreen(s);
            xcb_xinerama_screen_info_next(&iter);
        }
    }
    return true;
}
コード例 #3
0
ファイル: lighthouse.c プロジェクト: infokiller/lighthouse
/* @brief Attempts to find secondary displays and updates settings.screen_* data
 *        with the dimensions of the found screens.
 *
 * Note: failure is somewhat expected and is handled by simply using the default
 *       xcb screen's dimension parameters.
 *
 * @param connection A connection to the Xorg server.
 * @param screen A screen created by xcb's xcb_setup_roots function.
 * @return 0 on success and 1 on failure.
 */
static int32_t get_multiscreen_settings(xcb_connection_t *connection, xcb_screen_t *screen) {
  /* First check randr. */
  const xcb_query_extension_reply_t *extension_reply = xcb_get_extension_data(connection, &xcb_randr_id);
  if (extension_reply && extension_reply->present) {
    debug("Found randr support, searching for displays.\n");
    /* Find x, y and width, height. */
    xcb_randr_get_screen_resources_current_reply_t *randr_reply = xcb_randr_get_screen_resources_current_reply(connection, xcb_randr_get_screen_resources_current(connection, screen->root), NULL);
    if (!randr_reply) {
      fprintf(stderr, "Failed to get randr set up.\n");
    } else {
      int32_t num_outputs = xcb_randr_get_screen_resources_current_outputs_length(randr_reply);
      if (num_outputs < settings.screen) {
        fprintf(stderr, "Screen selected not found.\n");
        /* Default back to the first screen. */
        settings.screen = 0;
      }
      xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(randr_reply);
      uint32_t output_index = settings.screen;
      xcb_randr_get_output_info_reply_t *randr_output = NULL;
      do {
        if (randr_output) { free(randr_output); }
        randr_output = xcb_randr_get_output_info_reply(connection, xcb_randr_get_output_info(connection, outputs[output_index], XCB_CURRENT_TIME), NULL);
        output_index++;
      } while ((randr_output->connection != XCB_RANDR_CONNECTION_CONNECTED) && (output_index < num_outputs));
      if (randr_output) {
        xcb_randr_get_crtc_info_reply_t *randr_crtc = xcb_randr_get_crtc_info_reply(connection, xcb_randr_get_crtc_info(connection, randr_output->crtc, XCB_CURRENT_TIME), NULL);
        if (!randr_crtc) {
          fprintf(stderr, "Unable to connect to randr crtc\n");
          free(randr_output);
          free(randr_reply);
          goto xinerama;
        }
        settings.screen_width = randr_crtc->width;
        settings.screen_height = randr_crtc->height;
        settings.screen_x = randr_crtc->x;
        settings.screen_y = randr_crtc->y;
        debug("randr screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height);

        free(randr_crtc);
        free(randr_output);
        free(randr_reply);
        return 0;
      }
      free(randr_output);
      free(randr_reply);
    }
  }
xinerama:
  debug("Did not find randr support, attempting xinerama\n");

  /* Still here? Let's try xinerama! */
  extension_reply = xcb_get_extension_data(connection, &xcb_xinerama_id);
  if (extension_reply && extension_reply->present) {
    debug("Found xinerama support, searching for displays.\n");
    xcb_xinerama_is_active_reply_t *xinerama_is_active_reply = xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), NULL);
    if (xinerama_is_active_reply && xinerama_is_active_reply->state) {
      free(xinerama_is_active_reply);
      /* Find x, y and width, height. */
      xcb_xinerama_query_screens_reply_t *screen_reply = xcb_xinerama_query_screens_reply(connection, xcb_xinerama_query_screens_unchecked(connection), NULL);
      xcb_xinerama_screen_info_iterator_t iter = xcb_xinerama_query_screens_screen_info_iterator(screen_reply);
      free(screen_reply);
      if (iter.rem < settings.screen) {
        fprintf(stderr, "Screen selected not found.\n");
        /* Default back to the first screen. */
        settings.screen = 0;
      }
      /* Jump to the appropriate screen. */
      int32_t i = 0;
      while (i < settings.screen) {
        xcb_xinerama_screen_info_next(&iter);
        i++;
      }
      settings.screen_width = iter.data->width;
      settings.screen_height = iter.data->height;
      settings.screen_x = iter.data->x_org;
      settings.screen_y = iter.data->y_org;
      debug("xinerama screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height);
      return 0;
    }
  }

  debug("Multiscreen search failed.\n");
  return 1;
}