svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_shape.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_Shape_Group X Shape extension
10  *
11  * Functions that use the shape extension of the X server to change shape of given windows.
12  */
13
14
15 #ifdef ECORE_XCB_SHAPE
16 static int _shape_available = 0;
17 static xcb_shape_query_version_cookie_t _ecore_xcb_shape_init_cookie;
18 #endif /* ECORE_XCB_SHAPE */
19
20
21 /* To avoid round trips, the initialization is separated in 2
22    functions: _ecore_xcb_shape_init and
23    _ecore_xcb_shape_init_finalize. The first one gets the cookies and
24    the second one gets the replies. */
25
26 void
27 _ecore_x_shape_init(const xcb_query_extension_reply_t *reply)
28 {
29 #ifdef ECORE_XCB_SHAPE
30    if (reply && (reply->present))
31       _ecore_xcb_shape_init_cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn);
32 #endif /* ECORE_XCB_SHAPE */
33 }
34
35 void
36 _ecore_x_shape_init_finalize(void)
37 {
38 #ifdef ECORE_XCB_SHAPE
39    xcb_shape_query_version_reply_t *reply;
40
41    reply = xcb_shape_query_version_reply(_ecore_xcb_conn,
42                                          _ecore_xcb_shape_init_cookie,
43                                          NULL);
44    if (reply)
45      {
46         _shape_available = 1;
47         free(reply);
48      }
49 #endif /* ECORE_XCB_SHAPE */
50 }
51
52
53 /**
54  * Sets the shape of the given window to the given pixmap.
55  * @param dest_win    The given window.
56  * @param source_mask A 2-bit depth pixmap that provides the new shape of the window.
57  *
58  * Sets the shape of the window @p dest_win to the pixmap @p source_mask.
59  * @ingroup Ecore_X_Shape_Group
60  */
61 EAPI void
62 ecore_x_window_shape_mask_set(Ecore_X_Window dest_win,
63                               Ecore_X_Pixmap source_mask)
64 {
65 #ifdef ECORE_XCB_SHAPE
66    xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, source_mask);
67 #endif /* ECORE_XCB_SHAPE */
68 }
69
70 EAPI void
71 ecore_x_window_shape_window_set(Ecore_X_Window dest_win,
72                                 Ecore_X_Window shape_win)
73 {
74 #ifdef ECORE_XCB_SHAPE
75    xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win);
76 #endif /* ECORE_XCB_SHAPE */
77 }
78
79 EAPI void
80 ecore_x_window_shape_window_set_xy(Ecore_X_Window dest_win,
81                                    Ecore_X_Window shape_win,
82                                    int            x,
83                                    int            y)
84 {
85 #ifdef ECORE_XCB_SHAPE
86    xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win);
87 #endif /* ECORE_XCB_SHAPE */
88 }
89
90
91 /**
92  * Sets the shape of the given window to a rectangle.
93  * @param dest_win The given window.
94  * @param x        The X coordinate of the top left corner of the rectangle.
95  * @param y        The Y coordinate of the top left corner of the rectangle.
96  * @param width    The width of the rectangle.
97  * @param height   The height of the rectangle.
98  *
99  * Sets the shape of the window @p dest_win to a rectangle defined  by
100  * @p x, @p y, @p width and @p height.
101  * @ingroup Ecore_X_Shape_Group
102  */
103 EAPI void
104 ecore_x_window_shape_rectangle_set(Ecore_X_Window dest_win,
105                                    int            x,
106                                    int            y,
107                                    int            width,
108                                    int            height)
109 {
110 #ifdef ECORE_XCB_SHAPE
111    xcb_rectangle_t rect;
112
113    rect.x = x;
114    rect.y = y;
115    rect.width = width;
116    rect.height = height;
117    xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect);
118 #endif /* ECORE_XCB_SHAPE */
119 }
120
121 EAPI void
122 ecore_x_window_shape_rectangles_set(Ecore_X_Window     dest_win,
123                                     Ecore_X_Rectangle *rects,
124                                     int                num)
125 {
126 #ifdef ECORE_XCB_SHAPE
127    if (num > 0)
128      xcb_shape_rectangles(_ecore_xcb_conn,
129                           XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING,
130                           0, dest_win, 0, 0, num, (xcb_rectangle_t *)rects);
131    else
132      xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL);
133 #endif /* ECORE_XCB_SHAPE */
134 }
135
136 EAPI void
137 ecore_x_window_shape_window_add(Ecore_X_Window dest_win,
138                                 Ecore_X_Window shape_win)
139 {
140 #ifdef ECORE_XCB_SHAPE
141    xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win);
142 #endif /* ECORE_XCB_SHAPE */
143 }
144
145 EAPI void
146 ecore_x_window_shape_window_add_xy(Ecore_X_Window dest_win,
147                                    Ecore_X_Window shape_win,
148                                    int            x,
149                                    int            y)
150 {
151 #ifdef ECORE_XCB_SHAPE
152    xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win);
153 #endif /* ECORE_XCB_SHAPE */
154 }
155
156 EAPI void
157 ecore_x_window_shape_rectangle_add(Ecore_X_Window dest_win,
158                                    int            x,
159                                    int            y,
160                                    int            width,
161                                    int            height)
162 {
163 #ifdef ECORE_XCB_SHAPE
164    xcb_rectangle_t rect;
165
166    rect.x = x;
167    rect.y = y;
168    rect.width = width;
169    rect.height = height;
170    xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect);
171 #endif /* ECORE_XCB_SHAPE */
172 }
173
174 EAPI void
175 ecore_x_window_shape_rectangle_clip(Ecore_X_Window dest_win,
176                                     int            x,
177                                     int            y,
178                                     int            width,
179                                     int            height)
180 {
181 #ifdef ECORE_XCB_SHAPE
182    xcb_rectangle_t rect;
183    
184    rect.x = x;
185    rect.y = y;
186    rect.width = width;
187    rect.height = height;
188    xcb_shape_rectangles(_ecore_xcb_conn,
189                         XCB_SHAPE_SO_INTERSECT, XCB_SHAPE_SK_BOUNDING,
190                         0, dest_win, 0, 0, 1, &rect);
191 #endif /* ECORE_XCB_SHAPE */
192 }
193
194 EAPI void
195 ecore_x_window_shape_rectangles_add(Ecore_X_Window     dest_win,
196                                     Ecore_X_Rectangle *rects,
197                                     int                num)
198 {
199 #ifdef ECORE_XCB_SHAPE
200    if (num > 0)
201      xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, num, (const xcb_rectangle_t *)rects);
202    else
203      xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL);
204 #endif /* ECORE_XCB_SHAPE */
205 }
206
207
208 /**
209  * Sends the ShapeGetRectangles request.
210  * @param window Requested window.
211  * @ingroup Ecore_X_Shape_Group
212  */
213 EAPI void
214 ecore_x_window_shape_rectangles_get_prefetch(Ecore_X_Window window)
215 {
216 #ifdef ECORE_XCB_SHAPE
217    xcb_shape_get_rectangles_cookie_t cookie;
218
219    cookie = xcb_shape_get_rectangles_unchecked(_ecore_xcb_conn, window, XCB_SHAPE_SK_BOUNDING);
220    _ecore_xcb_cookie_cache(cookie.sequence);
221 #endif /* ECORE_XCB_SHAPE */
222 }
223
224
225 /**
226  * Gets the reply of the ShapeGetRectangles request sent by ecore_x_window_shape_rectangles_get_prefetch().
227  * @ingroup Ecore_X_Shape_Group
228  */
229 EAPI void
230 ecore_x_window_shape_rectangles_get_fetch(void)
231 {
232 #ifdef ECORE_XCB_SHAPE
233    xcb_shape_get_rectangles_cookie_t cookie;
234    xcb_shape_get_rectangles_reply_t *reply;
235
236    cookie.sequence = _ecore_xcb_cookie_get();
237    reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL);
238    _ecore_xcb_reply_cache(reply);
239 #endif /* ECORE_XCB_SHAPE */
240 }
241
242
243 /**
244  * To document.
245  * @param  window  Unused.
246  * @param  num_ret To document.
247  * @return         To document.
248  *
249  * To use this function, you must call before, and in order,
250  * ecore_x_window_shape_rectangles_get_prefetch(), which sends the ShapeGetRectangles request,
251  * then ecore_x_window_shape_rectangles_get_fetch(), which gets the reply.
252  * @ingroup Ecore_X_Shape_Group
253  */
254 EAPI Ecore_X_Rectangle *
255 ecore_x_window_shape_rectangles_get(Ecore_X_Window window __UNUSED__,
256                                     int           *num_ret)
257 {
258    Ecore_X_Rectangle *rects = NULL;
259    uint32_t           num = 0;
260 #ifdef ECORE_XCB_SHAPE
261    xcb_shape_get_rectangles_reply_t *reply;
262
263    reply = _ecore_xcb_reply_get();
264    if (!reply)
265      {
266        if (num_ret) *num_ret = 0;
267        return NULL;
268      }
269
270    num = reply->rectangles_len;
271    rects = malloc(sizeof(Ecore_X_Rectangle) * num);
272    if (rects)
273      memcpy (rects,
274              xcb_shape_get_rectangles_rectangles(reply),
275              num * sizeof (Ecore_X_Rectangle));
276    else
277      num = 0;
278 #endif /* ECORE_XCB_SHAPE */
279
280    if (num_ret) *num_ret = num;
281
282    return rects;
283 }
284
285 EAPI void
286 ecore_x_window_shape_events_select(Ecore_X_Window dest_win,
287                                    int            on)
288 {
289 #ifdef ECORE_XCB_SHAPE
290      xcb_shape_select_input(_ecore_xcb_conn, dest_win, on ? 1 : 0);
291 #endif /* ECORE_XCB_SHAPE */
292 }