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