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