[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_randr.c
1 #include "ecore_xcb_private.h"
2
3 /**
4  * @defgroup Ecore_X_RandR_Group X RandR Extension Functions
5  *
6  * Functions related to the X RandR extension.
7  */
8
9 #ifdef ECORE_XCB_RANDR
10 static int _randr_available = 0;
11 static xcb_randr_query_version_cookie_t _ecore_xcb_randr_init_cookie;
12 #endif /* ECORE_XCB_RANDR */
13
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. */
18
19 void
20 _ecore_x_randr_init(const xcb_query_extension_reply_t *reply)
21 {
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);
25
26 #endif /* ECORE_XCB_RANDR */
27 } /* _ecore_x_randr_init */
28
29 void
30 _ecore_x_randr_init_finalize(void)
31 {
32 #ifdef ECORE_XCB_RANDR
33    xcb_randr_query_version_reply_t *reply;
34
35    reply = xcb_randr_query_version_reply(_ecore_xcb_conn,
36                                          _ecore_xcb_randr_init_cookie, NULL);
37
38    if (reply)
39      {
40         if ((reply->major_version >= 1) &&
41             (reply->minor_version >= 1))
42            _randr_available = 1;
43
44         free(reply);
45      }
46
47 #endif /* ECORE_XCB_RANDR */
48 } /* _ecore_x_randr_init_finalize */
49
50 /**
51  * Return whether the X server supports the RandR Extension.
52  * @return 1 if the X RandR Extension is available, 0 otherwise.
53  *
54  * Return 1 if the X server supports the RandR Extension version 1.1,
55  * 0 otherwise.
56  * @ingroup Ecore_X_RandR_Group
57  */
58 EAPI Eina_Bool
59 ecore_x_randr_query(void)
60 {
61 #ifdef ECORE_XCB_RANDR
62    return _randr_available;
63 #else /* ifdef ECORE_XCB_RANDR */
64    return 0;
65 #endif /* ECORE_XCB_RANDR */
66 } /* ecore_x_randr_query */
67
68 static Ecore_X_Window
69 _xcb_randr_root_to_screen(Ecore_X_Window root)
70 {
71    xcb_screen_iterator_t iter;
72
73    iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
74    for (; iter.rem; xcb_screen_next(&iter))
75      {
76         if (iter.data->root == root)
77            return iter.data->root;
78      }
79
80    return XCB_NONE;
81 } /* _xcb_randr_root_to_screen */
82
83 /**
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.
88  *
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
96  */
97 /*
98 EAPI Eina_Bool
99 ecore_x_randr_events_select(Ecore_X_Window window,
100                             int            on)
101 {
102 #ifdef ECORE_XCB_RANDR
103    xcb_randr_select_input(_ecore_xcb_conn, window,
104                           on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0);
105    return 1;
106 #else
107    return 0;
108 #endif
109 }*/
110
111 /**
112  * Sends the GetScreenInfo request.
113  * @param window Window whose properties are requested.
114  * @ingroup Ecore_X_RandR_Group
115  */
116 EAPI void
117 ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window)
118 {
119 #ifdef ECORE_XCB_RANDR
120    xcb_randr_get_screen_info_cookie_t cookie;
121
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 */
127
128 /**
129  * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
130  * @ingroup Ecore_X_RandR_Group
131  */
132 EAPI void
133 ecore_x_randr_get_screen_info_fetch(void)
134 {
135 #ifdef ECORE_XCB_RANDR
136    xcb_randr_get_screen_info_cookie_t cookie;
137    xcb_randr_get_screen_info_reply_t *reply;
138
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 */
144
145 /**
146  * Get the set of rotations and reflections.
147  * @param root The window (Unused).
148  * @return     The set of rotations and reflections.
149  *
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()).
153  *
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
158  */
159 /*
160 EAPI Ecore_X_Randr_Rotation
161 ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__)
162 {
163 #ifdef ECORE_XCB_RANDR
164    xcb_randr_get_screen_info_reply_t *reply;
165
166    reply = _ecore_xcb_reply_get();
167    if (!reply)
168       return 0;
169
170    return reply->rotations;
171 #else
172    return 0;
173 #endif
174 }*/
175
176 /**
177  * Get the rotation.
178  * @param root The window (Unused).
179  * @return     The rotation.
180  *
181  * Get the rotation supported by the screen
182  * associated to @p window (passed to
183  * ecore_x_randr_get_screen_info_prefetch()).
184  *
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
189  */
190 /*
191 EAPI Ecore_X_Randr_Rotation
192 ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__)
193 {
194 #ifdef ECORE_XCB_RANDR
195    xcb_randr_get_screen_info_reply_t *reply;
196
197    reply = _ecore_xcb_reply_get();
198    if (!reply)
199       return 0;
200
201    return reply->rotation;
202 #else
203    return 0;
204 #endif
205 }*/
206
207 /**
208  * Get the frame buffer sizes.
209  * @param root The window (Unused).
210  * @param num  The number of sizes.
211  * @return     The sizes.
212  *
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.
217  *
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
222  */
223 /*
224 EAPI Ecore_X_Screen_Size *
225 ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__,
226                                int                *num)
227 {
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;
232    int n;
233    int i;
234
235    if (num)
236       *num = 0;
237
238    reply = _ecore_xcb_reply_get();
239    if (!reply)
240       return NULL;
241
242    n = xcb_randr_get_screen_info_sizes_length(reply);
243    ret = calloc(n, sizeof(Ecore_X_Screen_Size));
244    if (!ret)
245       return NULL;
246
247    if (num)
248       *num = n;
249
250    sizes = xcb_randr_get_screen_info_sizes(reply);
251    for (i = 0; i < n; i++)
252      {
253         ret[i].width = sizes[i].width;
254         ret[i].height = sizes[i].height;
255      }
256
257    return ret;
258 #else
259    if (num)
260       *num = 0;
261
262    return NULL;
263 #endif
264 }*/
265
266 /**
267  * Get the current frame buffer size.
268  * @param root The window (Unused).
269  * @return     The active size.
270  *
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()).
274  *
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
279  */
280 /*
281 EAPI Ecore_X_Screen_Size
282 ecore_x_randr_current_screen_size_get(Ecore_X_Window root __UNUSED__)
283 {
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;
288    uint16_t size_index;
289
290    reply = _ecore_xcb_reply_get();
291    if (!reply)
292       return ret;
293
294    size_index = reply->sizeID;
295    sizes = xcb_randr_get_screen_info_sizes(reply);
296    if (size_index < reply->nSizes)
297      {
298         ret.width = sizes[size_index].mwidth;
299         ret.height = sizes[size_index].mheight;
300      }
301
302 #endif
303
304    return ret;
305 }*/
306
307 /**
308  * Get the current refresh rate.
309  * @param root The window (Unused).
310  * @return     The current refresh rate.
311  *
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()).
315  *
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
320  */
321 /*
322 EAPI Ecore_X_Screen_Refresh_Rate
323 ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__)
324 {
325    Ecore_X_Screen_Refresh_Rate ret = { -1 };
326 #ifdef ECORE_XCB_RANDR
327    xcb_randr_get_screen_info_reply_t *reply;
328
329    reply = _ecore_xcb_reply_get();
330    if (!reply)
331       return ret;
332
333    ret.rate = reply->rate;
334 #endif
335
336    return ret;
337 }*/
338
339 /**
340  * Get the refresh rates.
341  * @param root The window (Unused).
342  * @param num  The number of refresh rates.
343  * @return     The refresh rates.
344  *
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
350  * relevant.
351  *
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
356  */
357 /*
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__,
361                                        int                *num)
362 {
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;
368    uint16_t n;
369
370    if (num)
371       *num = 0;
372
373    reply = _ecore_xcb_reply_get();
374    if (!reply)
375       return NULL;
376
377    n = reply->nSizes;
378    ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
379    if (!ret)
380       return NULL;
381
382    if (num)
383       *num = n;
384
385    iter = xcb_randr_get_screen_info_rates_iterator(reply);
386    tmp = ret;
387    for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++)
388      {
389         tmp->rate = iter.data->nRates;
390      }
391
392    return ret;
393 #else
394    if (num)
395       *num = 0;
396
397    return NULL;
398 #endif
399 }*/
400
401 /* FIXME: round trip. Should we remove it ? */
402
403 /**
404  * Set the screen rotation.
405  * @param root The root window.
406  * @param rot  The rotation.
407  *
408  * Set the rotation of the screen associated to @p root.
409  *
410  * Note that that function is blocking.
411  * @ingroup Ecore_X_RandR_Group
412  */
413 /*
414 EAPI void
415 ecore_x_randr_screen_rotation_set(Ecore_X_Window         root,
416                                   Ecore_X_Randr_Rotation rot)
417 {
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;
422
423    reply = _ecore_xcb_reply_get();
424    if (!reply)
425       return;
426
427    cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
428                                                   XCB_CURRENT_TIME,
429                                                   reply->config_timestamp,
430                                                   reply->sizeID,
431                                                   rot,
432                                                   0);
433    reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
434    if (reply_config)
435       free(reply_config);
436
437 #endif
438 }*/
439
440 /* FIXME: round trip. Should we remove it ? */
441
442 /**
443  * Set the screen size.
444  * @param root The root window.
445  * @param size The size.
446  *
447  * Set the size of the screen associated to @p root.
448  *
449  * Note that that function is blocking.
450  * @ingroup Ecore_X_RandR_Group
451  */
452 /*
453 EAPI int
454 ecore_x_randr_screen_size_set(Ecore_X_Window      root,
455                               Ecore_X_Screen_Size size)
456 {
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;
462    int size_index = -1;
463    int i;
464
465    reply = _ecore_xcb_reply_get();
466    if (!reply)
467       return 0;
468
469    iter = xcb_randr_get_screen_info_sizes_iterator(reply);
470    for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
471      {
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))
476           {
477              size_index = i;
478              break;
479           }
480      }
481    if (size_index == -1)
482       return 0;
483
484    cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
485                                                   XCB_CURRENT_TIME,
486                                                   reply->config_timestamp,
487                                                   size_index,
488                                                   XCB_RANDR_ROTATION_ROTATE_0,
489                                                   0);
490    reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
491    if (!reply_config)
492       return 0;
493
494    free(reply_config);
495
496    return 1;
497 #else
498    return 0;
499 #endif
500 }*/
501
502 /* FIXME: round trip. Should we remove it ? */
503
504 /**
505  * Set the screen refresh rate.
506  * @param root The root window.
507  * @param size The size.
508  * @param rate The refresh rate.
509  *
510  * Set the size and the refresh rate of the screen associated to
511  * @p root.
512  *
513  * Note that that function is blocking.
514  * @ingroup Ecore_X_RandR_Group
515  */
516 /*
517 EAPI int
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)
521 {
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;
527    int size_index = -1;
528    int i;
529
530    reply = _ecore_xcb_reply_get();
531    if (!reply)
532       return 0;
533
534    iter = xcb_randr_get_screen_info_sizes_iterator(reply);
535    for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
536      {
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))
541           {
542              size_index = i;
543              break;
544           }
545      }
546    if (size_index == -1)
547       return 0;
548
549    cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
550                                                   XCB_CURRENT_TIME,
551                                                   reply->config_timestamp,
552                                                   size_index,
553                                                   XCB_RANDR_ROTATION_ROTATE_0,
554                                                   rate.rate);
555    reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
556    if (!reply_config)
557       return 0;
558
559    free(reply_config);
560
561    return 1;
562 #else
563    return 0;
564 #endif
565 }*/
566