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
98 ecore_x_randr_events_select(Ecore_X_Window window,
101 #ifdef ECORE_XCB_RANDR
102 xcb_randr_select_input(_ecore_xcb_conn, window,
103 on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0);
105 #else /* ifdef ECORE_XCB_RANDR */
107 #endif /* ECORE_XCB_RANDR */
108 } /* ecore_x_randr_events_select */
111 * Sends the GetScreenInfo request.
112 * @param window Window whose properties are requested.
113 * @ingroup Ecore_X_RandR_Group
116 ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window)
118 #ifdef ECORE_XCB_RANDR
119 xcb_randr_get_screen_info_cookie_t cookie;
121 cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn,
122 _xcb_randr_root_to_screen(window));
123 _ecore_xcb_cookie_cache(cookie.sequence);
124 #endif /* ECORE_XCB_RANDR */
125 } /* ecore_x_randr_get_screen_info_prefetch */
128 * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
129 * @ingroup Ecore_X_RandR_Group
132 ecore_x_randr_get_screen_info_fetch(void)
134 #ifdef ECORE_XCB_RANDR
135 xcb_randr_get_screen_info_cookie_t cookie;
136 xcb_randr_get_screen_info_reply_t *reply;
138 cookie.sequence = _ecore_xcb_cookie_get();
139 reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
140 _ecore_xcb_reply_cache(reply);
141 #endif /* ECORE_XCB_RANDR */
142 } /* ecore_x_randr_get_screen_info_fetch */
145 * Get the set of rotations and reflections.
146 * @param root The window (Unused).
147 * @return The set of rotations and reflections.
149 * Get the set of rotations and reflections supported by the screen
150 * associated to @p window (passed to
151 * ecore_x_randr_get_screen_info_prefetch()).
153 * To use this function, you must call before, and in order,
154 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
155 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
156 * @ingroup Ecore_X_RandR_Group
158 EAPI Ecore_X_Randr_Rotation
159 ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__)
161 #ifdef ECORE_XCB_RANDR
162 xcb_randr_get_screen_info_reply_t *reply;
164 reply = _ecore_xcb_reply_get();
168 return reply->rotations;
169 #else /* ifdef ECORE_XCB_RANDR */
171 #endif /* ECORE_XCB_RANDR */
172 } /* ecore_x_randr_screen_rotations_get */
176 * @param root The window (Unused).
177 * @return The rotation.
179 * Get the rotation supported by the screen
180 * associated to @p window (passed to
181 * ecore_x_randr_get_screen_info_prefetch()).
183 * To use this function, you must call before, and in order,
184 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
185 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
186 * @ingroup Ecore_X_RandR_Group
188 EAPI Ecore_X_Randr_Rotation
189 ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__)
191 #ifdef ECORE_XCB_RANDR
192 xcb_randr_get_screen_info_reply_t *reply;
194 reply = _ecore_xcb_reply_get();
198 return reply->rotation;
199 #else /* ifdef ECORE_XCB_RANDR */
201 #endif /* ECORE_XCB_RANDR */
202 } /* ecore_x_randr_screen_rotation_get */
205 * Get the frame buffer sizes.
206 * @param root The window (Unused).
207 * @param num The number of sizes.
210 * Get the list of possible frame buffer sizes (at the normal
211 * orientation supported by the screen associated to @p window (passed
212 * to ecore_x_randr_get_screen_info_prefetch()). Each size indicates
213 * both the linear physical size of the screen and the pixel size.
215 * To use this function, you must call before, and in order,
216 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
217 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
218 * @ingroup Ecore_X_RandR_Group
220 EAPI Ecore_X_Screen_Size *
221 ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__,
224 #ifdef ECORE_XCB_RANDR
225 xcb_randr_get_screen_info_reply_t *reply;
226 xcb_randr_screen_size_t *sizes;
227 Ecore_X_Screen_Size *ret;
234 reply = _ecore_xcb_reply_get();
238 n = xcb_randr_get_screen_info_sizes_length(reply);
239 ret = calloc(n, sizeof(Ecore_X_Screen_Size));
246 sizes = xcb_randr_get_screen_info_sizes(reply);
247 for (i = 0; i < n; i++)
249 ret[i].width = sizes[i].width;
250 ret[i].height = sizes[i].height;
254 #else /* ifdef ECORE_XCB_RANDR */
259 #endif /* ECORE_XCB_RANDR */
260 } /* ecore_x_randr_screen_sizes_get */
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;
297 #endif /* ECORE_XCB_RANDR */
300 } /* ecore_x_randr_current_screen_size_get */
303 * Get the current refresh rate.
304 * @param root The window (Unused).
305 * @return The current refresh rate.
307 * Get the current refresh rate supported by the screen associated
308 * to @p window (passed to
309 * ecore_x_randr_get_screen_info_prefetch()).
311 * To use this function, you must call before, and in order,
312 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
313 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
314 * @ingroup Ecore_X_RandR_Group
316 EAPI Ecore_X_Screen_Refresh_Rate
317 ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__)
319 Ecore_X_Screen_Refresh_Rate ret = { -1 };
320 #ifdef ECORE_XCB_RANDR
321 xcb_randr_get_screen_info_reply_t *reply;
323 reply = _ecore_xcb_reply_get();
327 ret.rate = reply->rate;
328 #endif /* ECORE_XCB_RANDR */
331 } /* ecore_x_randr_current_screen_refresh_rate_get */
334 * Get the refresh rates.
335 * @param root The window (Unused).
336 * @param num The number of refresh rates.
337 * @return The refresh rates.
339 * Get the list of refresh rates for each size supported by the screen
340 * associated to @p window (passed to
341 * ecore_x_randr_get_screen_info_prefetch()). Each element
342 * of 'sizes' has a corresponding element in 'refresh'. An empty list
343 * indicates no known rates, or a device for which refresh is not
346 * To use this function, you must call before, and in order,
347 * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
348 * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
349 * @ingroup Ecore_X_RandR_Group
351 EAPI Ecore_X_Screen_Refresh_Rate *
352 ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root __UNUSED__,
353 int size_id __UNUSED__,
356 #ifdef ECORE_XCB_RANDR
357 xcb_randr_get_screen_info_reply_t *reply;
358 Ecore_X_Screen_Refresh_Rate *ret;
359 Ecore_X_Screen_Refresh_Rate *tmp;
360 xcb_randr_refresh_rates_iterator_t iter;
366 reply = _ecore_xcb_reply_get();
371 ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
378 /* FIXME: maybe there's a missing function in xcb randr implementation */
379 iter = xcb_randr_get_screen_info_rates_iterator(reply);
381 for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++)
383 tmp->rate = iter.data->nRates;
387 #else /* ifdef ECORE_XCB_RANDR */
392 #endif /* ECORE_XCB_RANDR */
393 } /* ecore_x_randr_screen_refresh_rates_get */
395 /* FIXME: round trip. Should we remove it ? */
398 * Set the screen rotation.
399 * @param root The root window.
400 * @param rot The rotation.
402 * Set the rotation of the screen associated to @p root.
404 * Note that that function is blocking.
405 * @ingroup Ecore_X_RandR_Group
408 ecore_x_randr_screen_rotation_set(Ecore_X_Window root,
409 Ecore_X_Randr_Rotation rot)
411 #ifdef ECORE_XCB_RANDR
412 xcb_randr_set_screen_config_cookie_t cookie;
413 xcb_randr_set_screen_config_reply_t *reply_config;
414 xcb_randr_get_screen_info_reply_t *reply;
416 reply = _ecore_xcb_reply_get();
420 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
422 reply->config_timestamp,
426 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
430 #endif /* ECORE_XCB_RANDR */
431 } /* ecore_x_randr_screen_rotation_set */
433 /* FIXME: round trip. Should we remove it ? */
436 * Set the screen size.
437 * @param root The root window.
438 * @param size The size.
440 * Set the size of the screen associated to @p root.
442 * Note that that function is blocking.
443 * @ingroup Ecore_X_RandR_Group
446 ecore_x_randr_screen_size_set(Ecore_X_Window root,
447 Ecore_X_Screen_Size size)
449 #ifdef ECORE_XCB_RANDR
450 xcb_randr_set_screen_config_cookie_t cookie;
451 xcb_randr_set_screen_config_reply_t *reply_config;
452 xcb_randr_get_screen_info_reply_t *reply;
453 xcb_randr_screen_size_iterator_t iter;
457 reply = _ecore_xcb_reply_get();
461 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
462 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
464 if ((iter.data->width = size.width) &&
465 (iter.data->height = size.height) &&
466 (iter.data->mwidth = size.width) &&
467 (iter.data->mheight = size.height))
473 if (size_index == -1)
476 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
478 reply->config_timestamp,
480 XCB_RANDR_ROTATION_ROTATE_0,
482 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
489 #else /* ifdef ECORE_XCB_RANDR */
491 #endif /* ECORE_XCB_RANDR */
492 } /* ecore_x_randr_screen_size_set */
494 /* FIXME: round trip. Should we remove it ? */
497 * Set the screen refresh rate.
498 * @param root The root window.
499 * @param size The size.
500 * @param rate The refresh rate.
502 * Set the size and the refresh rate of the screen associated to
505 * Note that that function is blocking.
506 * @ingroup Ecore_X_RandR_Group
509 ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root,
510 Ecore_X_Screen_Size size,
511 Ecore_X_Screen_Refresh_Rate rate)
513 #ifdef ECORE_XCB_RANDR
514 xcb_randr_set_screen_config_cookie_t cookie;
515 xcb_randr_set_screen_config_reply_t *reply_config;
516 xcb_randr_get_screen_info_reply_t *reply;
517 xcb_randr_screen_size_iterator_t iter;
521 reply = _ecore_xcb_reply_get();
525 iter = xcb_randr_get_screen_info_sizes_iterator(reply);
526 for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
528 if ((iter.data->width = size.width) &&
529 (iter.data->height = size.height) &&
530 (iter.data->mwidth = size.width) &&
531 (iter.data->mheight = size.height))
537 if (size_index == -1)
540 cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
542 reply->config_timestamp,
544 XCB_RANDR_ROTATION_ROTATE_0,
546 reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
553 #else /* ifdef ECORE_XCB_RANDR */
555 #endif /* ECORE_XCB_RANDR */
556 } /* ecore_x_randr_screen_refresh_rate_set */