2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "ecore_xcb_private.h"
9 * @defgroup Ecore_X_RandR_Group X RandR Extension Functions
11 * Functions related to the X RandR extension.
15 #ifdef ECORE_XCB_RANDR
16 static int _randr_available = 0;
17 static xcb_randr_query_version_cookie_t _ecore_xcb_randr_init_cookie;
18 #endif /* ECORE_XCB_RANDR */
21 /* To avoid round trips, the initialization is separated in 2
22 functions: _ecore_xcb_randr_init and
23 _ecore_xcb_randr_init_finalize. The first one gets the cookies and
24 the second one gets the replies and set the atoms. */
27 _ecore_x_randr_init(const xcb_query_extension_reply_t *reply)
29 #ifdef ECORE_XCB_RANDR
30 if (reply && (reply->present))
31 _ecore_xcb_randr_init_cookie = xcb_randr_query_version_unchecked(_ecore_xcb_conn, 1, 2);
32 #endif /* ECORE_XCB_RANDR */
36 _ecore_x_randr_init_finalize(void)
38 #ifdef ECORE_XCB_RANDR
39 xcb_randr_query_version_reply_t *reply;
41 reply = xcb_randr_query_version_reply(_ecore_xcb_conn,
42 _ecore_xcb_randr_init_cookie, NULL);
46 if ((reply->major_version >= 1) &&
47 (reply->minor_version >= 1))
51 #endif /* ECORE_XCB_RANDR */
55 * Return whether the X server supports the RandR Extension.
56 * @return 1 if the X RandR Extension is available, 0 otherwise.
58 * Return 1 if the X server supports the RandR Extension version 1.1,
60 * @ingroup Ecore_X_RandR_Group
63 ecore_x_randr_query(void)
65 #ifdef ECORE_XCB_RANDR
66 return _randr_available;
69 #endif /* ECORE_XCB_RANDR */
74 _xcb_randr_root_to_screen(Ecore_X_Window root)
76 xcb_screen_iterator_t iter;
78 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
79 for (; iter.rem; xcb_screen_next(&iter))
81 if (iter.data->root == root)
82 return iter.data->root;
89 * Select if the ScreenChangeNotify events will be sent.
90 * @param window The window.
91 * @param on 1 to enable, 0 to disable.
92 * @return 1 on success, 0 otherwise.
94 * If @p on value is @c 1, ScreenChangeNotify events
95 * will be sent when the screen configuration changes, either from
96 * this protocol extension, or due to detected external screen
97 * configuration changes. ScreenChangeNotify may also be sent when
98 * this request executes if the screen configuration has changed since
99 * the client connected, to avoid race conditions.
100 * @ingroup Ecore_X_RandR_Group
103 ecore_x_randr_events_select(Ecore_X_Window window,
106 #ifdef ECORE_XCB_RANDR
107 xcb_randr_select_input(_ecore_xcb_conn, window,
108 on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0);
112 #endif /* ECORE_XCB_RANDR */
116 * Sends the GetScreenInfo request.
117 * @param window Window whose properties are requested.
118 * @ingroup Ecore_X_RandR_Group
121 ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window)
123 #ifdef ECORE_XCB_RANDR
124 xcb_randr_get_screen_info_cookie_t cookie;
126 cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn,
127 _xcb_randr_root_to_screen(window));
128 _ecore_xcb_cookie_cache(cookie.sequence);
129 #endif /* ECORE_XCB_RANDR */
134 * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
135 * @ingroup Ecore_X_RandR_Group
138 ecore_x_randr_get_screen_info_fetch(void)
140 #ifdef ECORE_XCB_RANDR
141 xcb_randr_get_screen_info_cookie_t cookie;
142 xcb_randr_get_screen_info_reply_t *reply;
144 cookie.sequence = _ecore_xcb_cookie_get();
145 reply =xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
146 _ecore_xcb_reply_cache(reply);
147 #endif /* ECORE_XCB_RANDR */
151 * Get the set of rotations and reflections.
152 * @param root The window (Unused).
153 * @return The set of rotations and reflections.
155 * Get the set of rotations and reflections supported by the screen
156 * associated to @p window (passed to
157 * ecore_x_randr_get_screen_info_prefetch()).
159 * To use this function, you must call before, and in order,
160 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
161 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
162 * @ingroup Ecore_X_RandR_Group
164 EAPI Ecore_X_Randr_Rotation
165 ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__)
167 #ifdef ECORE_XCB_RANDR
168 xcb_randr_get_screen_info_reply_t *reply;
170 reply = _ecore_xcb_reply_get();
174 return reply->rotations;
177 #endif /* ECORE_XCB_RANDR */
182 * @param root The window (Unused).
183 * @return The rotation.
185 * Get the rotation supported by the screen
186 * associated to @p window (passed to
187 * ecore_x_randr_get_screen_info_prefetch()).
189 * To use this function, you must call before, and in order,
190 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
191 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
192 * @ingroup Ecore_X_RandR_Group
194 EAPI Ecore_X_Randr_Rotation
195 ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__)
197 #ifdef ECORE_XCB_RANDR
198 xcb_randr_get_screen_info_reply_t *reply;
200 reply = _ecore_xcb_reply_get();
204 return reply->rotation;
207 #endif /* ECORE_XCB_RANDR */
211 * Get the frame buffer sizes.
212 * @param root The window (Unused).
213 * @param num The number of sizes.
216 * Get the list of possible frame buffer sizes (at the normal
217 * orientation supported by the screen associated to @p window (passed
218 * to ecore_x_randr_get_screen_info_prefetch()). Each size indicates
219 * both the linear physical size of the screen and the pixel size.
221 * To use this function, you must call before, and in order,
222 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
223 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
224 * @ingroup Ecore_X_RandR_Group
226 EAPI Ecore_X_Screen_Size *
227 ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__,
230 #ifdef ECORE_XCB_RANDR
231 xcb_randr_get_screen_info_reply_t *reply;
232 xcb_randr_screen_size_t *sizes;
233 Ecore_X_Screen_Size *ret;
239 reply = _ecore_xcb_reply_get();
243 n = xcb_randr_get_screen_info_sizes_length(reply);
244 ret = calloc(n, sizeof(Ecore_X_Screen_Size));
245 if (!ret) return NULL;
248 sizes = xcb_randr_get_screen_info_sizes(reply);
249 for (i = 0; i < n; i++)
251 ret[i].width = sizes[i].width;
252 ret[i].height = sizes[i].height;
259 #endif /* ECORE_XCB_RANDR */
263 * Get the current frame buffer size.
264 * @param root The window (Unused).
265 * @return The active size.
267 * Get the active frame buffer size supported by the screen associated
268 * to @p window (passed to
269 * ecore_x_randr_get_screen_info_prefetch()).
271 * To use this function, you must call before, and in order,
272 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
273 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
274 * @ingroup Ecore_X_RandR_Group
276 EAPI Ecore_X_Screen_Size
277 ecore_x_randr_current_screen_size_get(Ecore_X_Window root __UNUSED__)
279 Ecore_X_Screen_Size ret = { -1, -1 };
280 #ifdef ECORE_XCB_RANDR
281 xcb_randr_get_screen_info_reply_t *reply;
282 xcb_randr_screen_size_t *sizes;
285 reply = _ecore_xcb_reply_get();
289 size_index = reply->sizeID;
290 sizes = xcb_randr_get_screen_info_sizes(reply);
291 if (size_index < reply->nSizes)
293 ret.width = sizes[size_index].mwidth;
294 ret.height = sizes[size_index].mheight;
296 #endif /* ECORE_XCB_RANDR */
302 * Get the current refresh rate.
303 * @param root The window (Unused).
304 * @return The current refresh rate.
306 * Get the current refresh rate supported by the screen associated
307 * to @p window (passed to
308 * ecore_x_randr_get_screen_info_prefetch()).
310 * To use this function, you must call before, and in order,
311 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
312 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
313 * @ingroup Ecore_X_RandR_Group
315 EAPI Ecore_X_Screen_Refresh_Rate
316 ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__)
318 Ecore_X_Screen_Refresh_Rate ret = { -1 };
319 #ifdef ECORE_XCB_RANDR
320 xcb_randr_get_screen_info_reply_t *reply;
322 reply = _ecore_xcb_reply_get();
326 ret.rate = reply->rate;
327 #endif /* ECORE_XCB_RANDR */
333 * Get the refresh rates.
334 * @param root The window (Unused).
335 * @param num The number of refresh rates.
336 * @return The refresh rates.
338 * Get the list of refresh rates for each size supported by the screen
339 * associated to @p window (passed to
340 * ecore_x_randr_get_screen_info_prefetch()). Each element
341 * of 'sizes' has a corresponding element in 'refresh'. An empty list
342 * indicates no known rates, or a device for which refresh is not
345 * To use this function, you must call before, and in order,
346 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
347 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
348 * @ingroup Ecore_X_RandR_Group
350 EAPI Ecore_X_Screen_Refresh_Rate *
351 ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root __UNUSED__,
352 int size_id __UNUSED__,
355 #ifdef ECORE_XCB_RANDR
356 xcb_randr_get_screen_info_reply_t *reply;
357 Ecore_X_Screen_Refresh_Rate *ret;
358 Ecore_X_Screen_Refresh_Rate *tmp;
359 xcb_randr_refresh_rates_iterator_t iter;
364 reply = _ecore_xcb_reply_get();
369 ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
375 /* FIXME: maybe there's a missing function in xcb randr implementation */
376 iter = xcb_randr_get_screen_info_rates_iterator(reply);
378 for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++)
380 tmp->rate = iter.data->nRates;;
387 #endif /* ECORE_XCB_RANDR */
390 /* FIXME: round trip. Should we remove it ? */
393 * Set the screen rotation.
394 * @param root The root window.
395 * @param rot The rotation.
397 * Set the rotation of the screen associated to @p root.
399 * Note that that function is blocking.
400 * @ingroup Ecore_X_RandR_Group
403 ecore_x_randr_screen_rotation_set(Ecore_X_Window root,
404 Ecore_X_Randr_Rotation rot)
406 #ifdef ECORE_XCB_RANDR
407 xcb_randr_set_screen_config_cookie_t cookie;
408 xcb_randr_set_screen_config_reply_t *reply_config;
409 xcb_randr_get_screen_info_reply_t *reply;
411 reply = _ecore_xcb_reply_get();
415 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
417 reply->config_timestamp,
421 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
424 #endif /* ECORE_XCB_RANDR */
427 /* FIXME: round trip. Should we remove it ? */
430 * Set the screen size.
431 * @param root The root window.
432 * @param size The size.
434 * Set the size of the screen associated to @p root.
436 * Note that that function is blocking.
437 * @ingroup Ecore_X_RandR_Group
440 ecore_x_randr_screen_size_set(Ecore_X_Window root,
441 Ecore_X_Screen_Size size)
443 #ifdef ECORE_XCB_RANDR
444 xcb_randr_set_screen_config_cookie_t cookie;
445 xcb_randr_set_screen_config_reply_t *reply_config;
446 xcb_randr_get_screen_info_reply_t *reply;
447 xcb_randr_screen_size_iterator_t iter;
451 reply = _ecore_xcb_reply_get();
455 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
456 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
458 if ((iter.data->width = size.width) &&
459 (iter.data->height = size.height) &&
460 (iter.data->mwidth = size.width) &&
461 (iter.data->mheight = size.height))
467 if (size_index == -1) return 0;
469 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
471 reply->config_timestamp,
473 XCB_RANDR_ROTATION_ROTATE_0,
475 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
484 #endif /* ECORE_XCB_RANDR */
487 /* FIXME: round trip. Should we remove it ? */
490 * Set the screen refresh rate.
491 * @param root The root window.
492 * @param size The size.
493 * @param rate The refresh rate.
495 * Set the size and the refresh rate of the screen associated to
498 * Note that that function is blocking.
499 * @ingroup Ecore_X_RandR_Group
502 ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root,
503 Ecore_X_Screen_Size size,
504 Ecore_X_Screen_Refresh_Rate rate)
506 #ifdef ECORE_XCB_RANDR
507 xcb_randr_set_screen_config_cookie_t cookie;
508 xcb_randr_set_screen_config_reply_t *reply_config;
509 xcb_randr_get_screen_info_reply_t *reply;
510 xcb_randr_screen_size_iterator_t iter;
514 reply = _ecore_xcb_reply_get();
518 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
519 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
521 if ((iter.data->width = size.width) &&
522 (iter.data->height = size.height) &&
523 (iter.data->mwidth = size.width) &&
524 (iter.data->mheight = size.height))
530 if (size_index == -1) return 0;
532 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
534 reply->config_timestamp,
536 XCB_RANDR_ROTATION_ROTATE_0,
538 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
547 #endif /* ECORE_XCB_RANDR */