[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_xinerama.c
1 #include "ecore_xcb_private.h"
2
3 /**
4  * @defgroup Ecore_X_Xinerama_Group X Xinerama Extension Functions
5  *
6  * Functions related to the X Xinerama extension.
7  */
8
9 #ifdef ECORE_XCB_XINERAMA
10 static int _xinerama_available = 0;
11 static xcb_xinerama_query_version_cookie_t _ecore_xcb_xinerama_init_cookie;
12 #endif /* ECORE_XCB_XINERAMA */
13
14 /* To avoid round trips, the initialization is separated in 2
15    functions: _ecore_xcb_xinerama_init and
16    _ecore_xcb_xinerama_init_finalize. The first one gets the cookies and
17    the second one gets the replies. */
18
19 void
20 _ecore_x_xinerama_init(const xcb_query_extension_reply_t *reply)
21 {
22 #ifdef ECORE_XCB_XINERAMA
23    if (reply && (reply->present))
24       _ecore_xcb_xinerama_init_cookie = xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, 1, 2);
25
26 #endif /* ECORE_XCB_XINERAMA */
27 } /* _ecore_x_xinerama_init */
28
29 void
30 _ecore_x_xinerama_init_finalize(void)
31 {
32 #ifdef ECORE_XCB_XINERAMA
33    xcb_xinerama_query_version_reply_t *reply;
34
35    reply = xcb_xinerama_query_version_reply(_ecore_xcb_conn,
36                                             _ecore_xcb_xinerama_init_cookie, NULL);
37
38    if (reply)
39      {
40         if ((reply->major >= 1) &&
41             (reply->minor >= 1))
42            _xinerama_available = 1;
43
44         free(reply);
45      }
46
47 #endif /* ECORE_XCB_XINERAMA */
48 } /* _ecore_x_xinerama_init_finalize */
49
50 /**
51  * Return whether the X server supports the Xinerama Extension.
52  * @return 1 if the X Xinerama Extension is available, 0 otherwise.
53  *
54  * Return 1 if the X server supports the Fixes Xinerama version 1.1,
55  * 0 otherwise.
56  * @ingroup Ecore_X_Xinerama_Group
57  */
58 EAPI Eina_Bool
59 ecore_x_xinerama_query(void)
60 {
61 #ifdef ECORE_XCB_XINERAMA
62    return _xinerama_available;
63 #else /* ifdef ECORE_XCB_XINERAMA */
64    return 0;
65 #endif /* ECORE_XCB_XINERAMA */
66 } /* ecore_x_xinerama_query */
67
68 /**
69  * Sends the XineramaQueryScreens request.
70  * @ingroup Ecore_X_Xinerama_Group
71  */
72 EAPI void
73 ecore_x_xinerama_query_screens_prefetch(void)
74 {
75 #ifdef ECORE_XCB_XINERAMA
76    xcb_xinerama_query_screens_cookie_t cookie;
77
78    cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn);
79    _ecore_xcb_cookie_cache(cookie.sequence);
80 #endif /* ECORE_XCB_XINERAMA */
81 } /* ecore_x_xinerama_query_screens_prefetch */
82
83 /**
84  * Gets the reply of the XineramaQueryScreens request sent by ecore_x_xinerama_query_screens_prefetch().
85  * @ingroup Ecore_X_Xinerama_Group
86  */
87 EAPI void
88 ecore_x_xinerama_query_screens_fetch(void)
89 {
90 #ifdef ECORE_XCB_XINERAMA
91    xcb_xinerama_query_screens_cookie_t cookie;
92    xcb_xinerama_query_screens_reply_t *reply;
93
94    cookie.sequence = _ecore_xcb_cookie_get();
95    reply = xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
96    _ecore_xcb_reply_cache(reply);
97 #endif /* ECORE_XCB_XINERAMA */
98 } /* ecore_x_xinerama_query_screens_fetch */
99
100 /**
101  * Return the number of screens.
102  * @return The screen count.
103  *
104  * Return the number of screens.
105  *
106  * To use this function, you must call before, and in order,
107  * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request,
108  * then ecore_x_xinerama_query_screens_fetch(), which gets the reply.
109  * @ingroup Ecore_X_Xinerama_Group
110  */
111 EAPI int
112 ecore_x_xinerama_screen_count_get(void)
113 {
114    int screen_count = 0;
115 #ifdef ECORE_XCB_XINERAMA
116    xcb_xinerama_screen_info_iterator_t iter;
117    xcb_xinerama_query_screens_reply_t *reply;
118
119    reply = _ecore_xcb_reply_get();
120    if (!reply)
121       return 0;
122
123    iter = xcb_xinerama_query_screens_screen_info_iterator(reply);
124    screen_count = iter.rem;
125 #endif /* ECORE_XCB_XINERAMA */
126
127    return screen_count;
128 } /* ecore_x_xinerama_screen_count_get */
129
130 /**
131  * Get the geometry of the screen.
132  * @param screen The screen (Unused).
133  * @param x      The X coordinate of the screen.
134  * @param y      The Y coordinate of the screen
135  * @param width  The width of the screen
136  * @param height The height of the screen
137  * @return       1 on success, 0 otherwise.
138  *
139  * Get the geometry of the screen whose number is @p screen. The
140  * returned values are stored in @p x, @p y, @p width and @p height.
141  *
142  * To use this function, you must call before, and in order,
143  * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request,
144  * then ecore_x_xinerama_query_screens_fetch(), which gets the reply.
145  * @ingroup Ecore_X_Xinerama_Group
146  */
147 EAPI Eina_Bool
148 ecore_x_xinerama_screen_geometry_get(int  screen,
149                                      int *x,
150                                      int *y,
151                                      int *width,
152                                      int *height)
153 {
154 #ifdef ECORE_XCB_XINERAMA
155    xcb_xinerama_screen_info_iterator_t iter;
156    xcb_xinerama_query_screens_reply_t *reply;
157
158    reply = _ecore_xcb_reply_get();
159    if (!reply)
160      {
161         if (x)
162            *x = 0;
163
164         if (y)
165            *y = 0;
166
167         if (width)
168            *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
169
170         if (height)
171            *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;
172
173         return 0;
174      }
175
176    iter = xcb_xinerama_query_screens_screen_info_iterator(reply);
177    for (; iter.rem; screen--, xcb_xinerama_screen_info_next(&iter))
178      {
179         if (screen == 0)
180           {
181              if (x)
182                 *x = iter.data->x_org;
183
184              if (y)
185                 *y = iter.data->y_org;
186
187              if (width)
188                 *width = iter.data->width;
189
190              if (height)
191                 *height = iter.data->height;
192
193              return 1;
194           }
195      }
196 #endif /* ECORE_XCB_XINERAMA */
197
198    if (x)
199       *x = 0;
200
201    if (y)
202       *y = 0;
203
204    if (width)
205       *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
206
207    if (height)
208       *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;
209
210    return 0;
211 } /* ecore_x_xinerama_screen_geometry_get */
212