1 #include "ecore_xcb_private.h"
4 * @defgroup Ecore_X_RandR_Group X RandR Extension Functions
6 * Functions related to the X RandR extension.
10 static int _randr_available = 0;
11 static xcb_randr_query_version_cookie_t _ecore_xcb_randr_init_cookie;
12 #endif /* ECORE_XCB_RANDR */
14 /* To avoid round trips, the initialization is separated in 2
15 functions: _ecore_xcb_randr_init and
16 _ecore_xcb_randr_init_finalize. The first one gets the cookies and
17 the second one gets the replies and set the atoms. */
20 _ecore_x_randr_init(const xcb_query_extension_reply_t *reply)
22 #ifdef ECORE_XCB_RANDR
23 if (reply && (reply->present))
24 _ecore_xcb_randr_init_cookie = xcb_randr_query_version_unchecked(_ecore_xcb_conn, 1, 2);
26 #endif /* ECORE_XCB_RANDR */
27 } /* _ecore_x_randr_init */
30 _ecore_x_randr_init_finalize(void)
32 #ifdef ECORE_XCB_RANDR
33 xcb_randr_query_version_reply_t *reply;
35 reply = xcb_randr_query_version_reply(_ecore_xcb_conn,
36 _ecore_xcb_randr_init_cookie, NULL);
40 if ((reply->major_version >= 1) &&
41 (reply->minor_version >= 1))
47 #endif /* ECORE_XCB_RANDR */
48 } /* _ecore_x_randr_init_finalize */
51 * Return whether the X server supports the RandR Extension.
52 * @return 1 if the X RandR Extension is available, 0 otherwise.
54 * Return 1 if the X server supports the RandR Extension version 1.1,
56 * @ingroup Ecore_X_RandR_Group
59 ecore_x_randr_query(void)
61 #ifdef ECORE_XCB_RANDR
62 return _randr_available;
63 #else /* ifdef ECORE_XCB_RANDR */
65 #endif /* ECORE_XCB_RANDR */
66 } /* ecore_x_randr_query */
69 _xcb_randr_root_to_screen(Ecore_X_Window root)
71 xcb_screen_iterator_t iter;
73 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
74 for (; iter.rem; xcb_screen_next(&iter))
76 if (iter.data->root == root)
77 return iter.data->root;
81 } /* _xcb_randr_root_to_screen */
84 * Select if the ScreenChangeNotify events will be sent.
85 * @param window The window.
86 * @param on 1 to enable, 0 to disable.
87 * @return 1 on success, 0 otherwise.
89 * If @p on value is @c 1, ScreenChangeNotify events
90 * will be sent when the screen configuration changes, either from
91 * this protocol extension, or due to detected external screen
92 * configuration changes. ScreenChangeNotify may also be sent when
93 * this request executes if the screen configuration has changed since
94 * the client connected, to avoid race conditions.
95 * @ingroup Ecore_X_RandR_Group
99 ecore_x_randr_events_select(Ecore_X_Window window,
102 #ifdef ECORE_XCB_RANDR
103 xcb_randr_select_input(_ecore_xcb_conn, window,
104 on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0);
112 * Sends the GetScreenInfo request.
113 * @param window Window whose properties are requested.
114 * @ingroup Ecore_X_RandR_Group
117 ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window)
119 #ifdef ECORE_XCB_RANDR
120 xcb_randr_get_screen_info_cookie_t cookie;
122 cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn,
123 _xcb_randr_root_to_screen(window));
124 _ecore_xcb_cookie_cache(cookie.sequence);
125 #endif /* ECORE_XCB_RANDR */
126 } /* ecore_x_randr_get_screen_info_prefetch */
129 * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
130 * @ingroup Ecore_X_RandR_Group
133 ecore_x_randr_get_screen_info_fetch(void)
135 #ifdef ECORE_XCB_RANDR
136 xcb_randr_get_screen_info_cookie_t cookie;
137 xcb_randr_get_screen_info_reply_t *reply;
139 cookie.sequence = _ecore_xcb_cookie_get();
140 reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
141 _ecore_xcb_reply_cache(reply);
142 #endif /* ECORE_XCB_RANDR */
143 } /* ecore_x_randr_get_screen_info_fetch */
146 * Get the set of rotations and reflections.
147 * @param root The window (Unused).
148 * @return The set of rotations and reflections.
150 * Get the set of rotations and reflections supported by the screen
151 * associated to @p window (passed to
152 * ecore_x_randr_get_screen_info_prefetch()).
154 * To use this function, you must call before, and in order,
155 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
156 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
157 * @ingroup Ecore_X_RandR_Group
160 EAPI Ecore_X_Randr_Rotation
161 ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__)
163 #ifdef ECORE_XCB_RANDR
164 xcb_randr_get_screen_info_reply_t *reply;
166 reply = _ecore_xcb_reply_get();
170 return reply->rotations;
178 * @param root The window (Unused).
179 * @return The rotation.
181 * Get the rotation supported by the screen
182 * associated to @p window (passed to
183 * ecore_x_randr_get_screen_info_prefetch()).
185 * To use this function, you must call before, and in order,
186 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
187 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
188 * @ingroup Ecore_X_RandR_Group
191 EAPI Ecore_X_Randr_Rotation
192 ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__)
194 #ifdef ECORE_XCB_RANDR
195 xcb_randr_get_screen_info_reply_t *reply;
197 reply = _ecore_xcb_reply_get();
201 return reply->rotation;
208 * Get the frame buffer sizes.
209 * @param root The window (Unused).
210 * @param num The number of sizes.
213 * Get the list of possible frame buffer sizes (at the normal
214 * orientation supported by the screen associated to @p window (passed
215 * to ecore_x_randr_get_screen_info_prefetch()). Each size indicates
216 * both the linear physical size of the screen and the pixel size.
218 * To use this function, you must call before, and in order,
219 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
220 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
221 * @ingroup Ecore_X_RandR_Group
224 EAPI Ecore_X_Screen_Size *
225 ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__,
228 #ifdef ECORE_XCB_RANDR
229 xcb_randr_get_screen_info_reply_t *reply;
230 xcb_randr_screen_size_t *sizes;
231 Ecore_X_Screen_Size *ret;
238 reply = _ecore_xcb_reply_get();
242 n = xcb_randr_get_screen_info_sizes_length(reply);
243 ret = calloc(n, sizeof(Ecore_X_Screen_Size));
250 sizes = xcb_randr_get_screen_info_sizes(reply);
251 for (i = 0; i < n; i++)
253 ret[i].width = sizes[i].width;
254 ret[i].height = sizes[i].height;
267 * Get the current frame buffer size.
268 * @param root The window (Unused).
269 * @return The active size.
271 * Get the active frame buffer size supported by the screen associated
272 * to @p window (passed to
273 * ecore_x_randr_get_screen_info_prefetch()).
275 * To use this function, you must call before, and in order,
276 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
277 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
278 * @ingroup Ecore_X_RandR_Group
281 EAPI Ecore_X_Screen_Size
282 ecore_x_randr_current_screen_size_get(Ecore_X_Window root __UNUSED__)
284 Ecore_X_Screen_Size ret = { -1, -1 };
285 #ifdef ECORE_XCB_RANDR
286 xcb_randr_get_screen_info_reply_t *reply;
287 xcb_randr_screen_size_t *sizes;
290 reply = _ecore_xcb_reply_get();
294 size_index = reply->sizeID;
295 sizes = xcb_randr_get_screen_info_sizes(reply);
296 if (size_index < reply->nSizes)
298 ret.width = sizes[size_index].mwidth;
299 ret.height = sizes[size_index].mheight;
308 * Get the current refresh rate.
309 * @param root The window (Unused).
310 * @return The current refresh rate.
312 * Get the current refresh rate supported by the screen associated
313 * to @p window (passed to
314 * ecore_x_randr_get_screen_info_prefetch()).
316 * To use this function, you must call before, and in order,
317 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
318 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
319 * @ingroup Ecore_X_RandR_Group
322 EAPI Ecore_X_Screen_Refresh_Rate
323 ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__)
325 Ecore_X_Screen_Refresh_Rate ret = { -1 };
326 #ifdef ECORE_XCB_RANDR
327 xcb_randr_get_screen_info_reply_t *reply;
329 reply = _ecore_xcb_reply_get();
333 ret.rate = reply->rate;
340 * Get the refresh rates.
341 * @param root The window (Unused).
342 * @param num The number of refresh rates.
343 * @return The refresh rates.
345 * Get the list of refresh rates for each size supported by the screen
346 * associated to @p window (passed to
347 * ecore_x_randr_get_screen_info_prefetch()). Each element
348 * of 'sizes' has a corresponding element in 'refresh'. An empty list
349 * indicates no known rates, or a device for which refresh is not
352 * To use this function, you must call before, and in order,
353 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
354 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
355 * @ingroup Ecore_X_RandR_Group
358 EAPI Ecore_X_Screen_Refresh_Rate *
359 ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root __UNUSED__,
360 int size_id __UNUSED__,
363 #ifdef ECORE_XCB_RANDR
364 xcb_randr_get_screen_info_reply_t *reply;
365 Ecore_X_Screen_Refresh_Rate *ret;
366 Ecore_X_Screen_Refresh_Rate *tmp;
367 xcb_randr_refresh_rates_iterator_t iter;
373 reply = _ecore_xcb_reply_get();
378 ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
385 iter = xcb_randr_get_screen_info_rates_iterator(reply);
387 for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++)
389 tmp->rate = iter.data->nRates;
401 /* FIXME: round trip. Should we remove it ? */
404 * Set the screen rotation.
405 * @param root The root window.
406 * @param rot The rotation.
408 * Set the rotation of the screen associated to @p root.
410 * Note that that function is blocking.
411 * @ingroup Ecore_X_RandR_Group
415 ecore_x_randr_screen_rotation_set(Ecore_X_Window root,
416 Ecore_X_Randr_Rotation rot)
418 #ifdef ECORE_XCB_RANDR
419 xcb_randr_set_screen_config_cookie_t cookie;
420 xcb_randr_set_screen_config_reply_t *reply_config;
421 xcb_randr_get_screen_info_reply_t *reply;
423 reply = _ecore_xcb_reply_get();
427 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
429 reply->config_timestamp,
433 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
440 /* FIXME: round trip. Should we remove it ? */
443 * Set the screen size.
444 * @param root The root window.
445 * @param size The size.
447 * Set the size of the screen associated to @p root.
449 * Note that that function is blocking.
450 * @ingroup Ecore_X_RandR_Group
454 ecore_x_randr_screen_size_set(Ecore_X_Window root,
455 Ecore_X_Screen_Size size)
457 #ifdef ECORE_XCB_RANDR
458 xcb_randr_set_screen_config_cookie_t cookie;
459 xcb_randr_set_screen_config_reply_t *reply_config;
460 xcb_randr_get_screen_info_reply_t *reply;
461 xcb_randr_screen_size_iterator_t iter;
465 reply = _ecore_xcb_reply_get();
469 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
470 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
472 if ((iter.data->width = size.width) &&
473 (iter.data->height = size.height) &&
474 (iter.data->mwidth = size.width) &&
475 (iter.data->mheight = size.height))
481 if (size_index == -1)
484 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
486 reply->config_timestamp,
488 XCB_RANDR_ROTATION_ROTATE_0,
490 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
502 /* FIXME: round trip. Should we remove it ? */
505 * Set the screen refresh rate.
506 * @param root The root window.
507 * @param size The size.
508 * @param rate The refresh rate.
510 * Set the size and the refresh rate of the screen associated to
513 * Note that that function is blocking.
514 * @ingroup Ecore_X_RandR_Group
518 ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root,
519 Ecore_X_Screen_Size size,
520 Ecore_X_Screen_Refresh_Rate rate)
522 #ifdef ECORE_XCB_RANDR
523 xcb_randr_set_screen_config_cookie_t cookie;
524 xcb_randr_set_screen_config_reply_t *reply_config;
525 xcb_randr_get_screen_info_reply_t *reply;
526 xcb_randr_screen_size_iterator_t iter;
530 reply = _ecore_xcb_reply_get();
534 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
535 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
537 if ((iter.data->width = size.width) &&
538 (iter.data->height = size.height) &&
539 (iter.data->mwidth = size.width) &&
540 (iter.data->mheight = size.height))
546 if (size_index == -1)
549 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
551 reply->config_timestamp,
553 XCB_RANDR_ROTATION_ROTATE_0,
555 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);