[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_fixes.c
1 #include "ecore_xcb_private.h"
2
3 /**
4  * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions
5  *
6  * Functions related to the X Fixes extension.
7  */
8
9 #ifdef ECORE_XCB_FIXES
10 static int _xfixes_available = 0;
11 static xcb_xfixes_query_version_cookie_t _ecore_xcb_xfixes_init_cookie;
12 #endif /* ECORE_XCB_FIXES */
13
14 /* To avoid round trips, the initialization is separated in 2
15    functions: _ecore_xcb_xfixes_init and
16    _ecore_xcb_xfixes_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_xfixes_init(const xcb_query_extension_reply_t *reply)
21 {
22 #ifdef ECORE_XCB_FIXES
23    if (reply && (reply->present))
24       _ecore_xcb_xfixes_init_cookie = xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, 4, 0);
25
26 #endif /* ECORE_XCB_FIXES */
27 } /* _ecore_x_xfixes_init */
28
29 void
30 _ecore_x_xfixes_init_finalize(void)
31 {
32 #ifdef ECORE_XCB_FIXES
33    xcb_xfixes_query_version_reply_t *reply;
34
35    reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn,
36                                           _ecore_xcb_xfixes_init_cookie, NULL);
37
38    if (reply)
39      {
40         if (reply->major_version >= 3)
41            _xfixes_available = 1;
42
43         free(reply);
44      }
45
46 #endif /* ECORE_XCB_FIXES */
47 } /* _ecore_x_xfixes_init_finalize */
48
49 /**
50  * Return whether the X server supports the Fixes Extension.
51  * @return 1 if the X Fixes Extension is available, 0 otherwise.
52  *
53  * Return 1 if the X server supports the Fixes Extension version 3.0,
54  * 0 otherwise.
55  * @ingroup Ecore_X_Fixes_Group
56  */
57 EAPI int
58 ecore_x_xfixes_query(void)
59 {
60 #ifdef ECORE_XCB_FIXES
61    return _xfixes_available;
62 #else /* ifdef ECORE_XCB_FIXES */
63    return 0;
64 #endif /* ECORE_XCB_FIXES */
65 } /* ecore_x_xfixes_query */
66
67 /**
68  * Create a region from rectangles.
69  * @param rects The rectangles used to initialize the region.
70  * @param num   The number of rectangles.
71  * @return      The newly created region.
72  *
73  * Create a region initialized to the specified list of rectangles
74  * @p rects. The rectangles may be specified in any order, their union
75  * becomes the region.
76  * @ingroup Ecore_X_Fixes_Group
77  */
78 EAPI Ecore_X_Region
79 ecore_x_region_new(Ecore_X_Rectangle *rects,
80                    int                num)
81 {
82    Ecore_X_Region region = XCB_NONE;
83
84 #ifdef ECORE_XCB_FIXES
85    region = xcb_generate_id(_ecore_xcb_conn);
86    xcb_xfixes_create_region(_ecore_xcb_conn, region, num, (xcb_rectangle_t *)rects);
87 #endif /* ECORE_XCB_FIXES */
88
89    return region;
90 } /* ecore_x_region_new */
91
92 /**
93  * Create a region from a pixmap.
94  * @param bitmap The bitmap used to initialize the region.
95  * @return       The newly created region.
96  *
97  * Creates a region initialized to the set of 'one' pixels in @p bitmap
98  * (which must be of depth 1, else Match error).
99  * @ingroup Ecore_X_Fixes_Group
100  */
101 EAPI Ecore_X_Region
102 ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
103 {
104    Ecore_X_Region region = XCB_NONE;
105
106 #ifdef ECORE_XCB_FIXES
107    region = xcb_generate_id(_ecore_xcb_conn);
108    xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap);
109 #endif /* ECORE_XCB_FIXES */
110
111    return region;
112 } /* ecore_x_region_new_from_bitmap */
113
114 /**
115  * Create a region from a window.
116  * @param window The window used to initialize the region.
117  * @param type   The type of the region.
118  * @return       The newly created region.
119  *
120  * Creates a region initialized to the specified @p window region. See
121  * the Shape extension for the definition of Bounding and Clip
122  * regions.
123  * @ingroup Ecore_X_Fixes_Group
124  */
125 EAPI Ecore_X_Region
126 ecore_x_region_new_from_window(Ecore_X_Window      window,
127                                Ecore_X_Region_Type type)
128 {
129    Ecore_X_Region region = XCB_NONE;
130
131 #ifdef ECORE_XCB_FIXES
132    region = xcb_generate_id(_ecore_xcb_conn);
133    xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, window, type);
134 #endif /* ECORE_XCB_FIXES */
135
136    return region;
137 } /* ecore_x_region_new_from_window */
138
139 /**
140  * Create a region from a graphic context.
141  * @param gc The graphic context used to initialize the region.
142  * @return   The newly created region.
143  *
144  * Creates a region initialized from the clip list of @p gc.
145  * @ingroup Ecore_X_Fixes_Group
146  */
147 EAPI Ecore_X_Region
148 ecore_x_region_new_from_gc(Ecore_X_GC gc)
149 {
150    Ecore_X_Region region = XCB_NONE;
151
152 #ifdef ECORE_XCB_FIXES
153    region = xcb_generate_id(_ecore_xcb_conn);
154    xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc);
155 #endif /* ECORE_XCB_FIXES */
156
157    return region;
158 } /* ecore_x_region_new_from_gc */
159
160 /**
161  * Create a region from a picture.
162  * @param picture The picture used to initialize the region.
163  * @return        The newly created region.
164  *
165  * Creates a region initialized from the clip list of @p picture.
166  * @ingroup Ecore_X_Fixes_Group
167  */
168 EAPI Ecore_X_Region
169 ecore_x_region_new_from_picture(Ecore_X_Picture picture)
170 {
171    Ecore_X_Region region = XCB_NONE;
172
173 #ifdef ECORE_XCB_FIXES
174    region = xcb_generate_id(_ecore_xcb_conn);
175    xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture);
176 #endif /* ECORE_XCB_FIXES */
177
178    return region;
179 } /* ecore_x_region_new_from_picture */
180
181 /**
182  * Destroy a region.
183  * @param region The region to destroy.
184  *
185  * Destroy the specified @p region.
186  * @ingroup Ecore_X_Fixes_Group
187  */
188 EAPI void
189 ecore_x_region_free(Ecore_X_Region region)
190 {
191 #ifdef ECORE_XCB_FIXES
192    xcb_xfixes_destroy_region(_ecore_xcb_conn, region);
193 #endif /* ECORE_XCB_FIXES */
194 } /* ecore_x_region_free */
195
196 /**
197  * Set the content of a region.
198  * @param region The region to destroy.
199  * @param rects  The rectangles used to set the region.
200  * @param num    The number of rectangles.
201  *
202  * Replace the current contents of @p region with the region formed
203  * by the union of the rectangles @p rects.
204  * @ingroup Ecore_X_Fixes_Group
205  */
206 EAPI void
207 ecore_x_region_set(Ecore_X_Region     region,
208                    Ecore_X_Rectangle *rects,
209                    int                num)
210 {
211 #ifdef ECORE_XCB_FIXES
212    xcb_xfixes_set_region(_ecore_xcb_conn, region, num, (xcb_rectangle_t *)rects);
213 #endif /* ECORE_XCB_FIXES */
214 } /* ecore_x_region_set */
215
216 /**
217  * Copy the content of a region.
218  * @param dest   The destination region.
219  * @param source The source region.
220  *
221  * Replace the contents of @p dest with the contents of @p source.
222  * @ingroup Ecore_X_Fixes_Group
223  */
224 EAPI void
225 ecore_x_region_copy(Ecore_X_Region dest,
226                     Ecore_X_Region source)
227 {
228 #ifdef ECORE_XCB_FIXES
229    xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest);
230 #endif /* ECORE_XCB_FIXES */
231 } /* ecore_x_region_copy */
232
233 /**
234  * Make the union of two regions.
235  * @param dest    The destination region.
236  * @param source1 The first source region.
237  * @param source2 The second source region.
238  *
239  * Replace the contents of @p dest with the union of @p source1 and
240  * @p source2.
241  * @ingroup Ecore_X_Fixes_Group
242  */
243 EAPI void
244 ecore_x_region_combine(Ecore_X_Region dest,
245                        Ecore_X_Region source1,
246                        Ecore_X_Region source2)
247 {
248 #ifdef ECORE_XCB_FIXES
249    xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest);
250 #endif /* ECORE_XCB_FIXES */
251 } /* ecore_x_region_combine */
252
253 /**
254  * Make the intersection of two regions.
255  * @param dest    The destination region.
256  * @param source1 The first source region.
257  * @param source2 The second source region.
258  *
259  * Replace the contents of @p dest with the intersection of @p source1 and
260  * @p source2.
261  * @ingroup Ecore_X_Fixes_Group
262  */
263 EAPI void
264 ecore_x_region_intersect(Ecore_X_Region dest,
265                          Ecore_X_Region source1,
266                          Ecore_X_Region source2)
267 {
268 #ifdef ECORE_XCB_FIXES
269    xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest);
270 #endif /* ECORE_XCB_FIXES */
271 } /* ecore_x_region_intersect */
272
273 /**
274  * Make the subtraction of two regions.
275  * @param dest    The destination region.
276  * @param source1 The first source region.
277  * @param source2 The second source region.
278  *
279  * Replace the contents of @p dest with the subtraction of @p source1 by
280  * @p source2.
281  * @ingroup Ecore_X_Fixes_Group
282  */
283 EAPI void
284 ecore_x_region_subtract(Ecore_X_Region dest,
285                         Ecore_X_Region source1,
286                         Ecore_X_Region source2)
287 {
288 #ifdef ECORE_XCB_FIXES
289    xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest);
290 #endif /* ECORE_XCB_FIXES */
291 } /* ecore_x_region_subtract */
292
293 /**
294  * Make the subtraction of regions by bounds.
295  * @param dest   The destination region.
296  * @param bounds The bounds.
297  * @param source The source region.
298  *
299  * The @p source region is subtracted from the region specified by
300  * @p bounds.  The result is placed in @p dest, replacing its
301  * contents.
302  * @ingroup Ecore_X_Fixes_Group
303  */
304 EAPI void
305 ecore_x_region_invert(Ecore_X_Region     dest,
306                       Ecore_X_Rectangle *bounds,
307                       Ecore_X_Region     source)
308 {
309 #ifdef ECORE_XCB_FIXES
310    xcb_rectangle_t rect;
311
312    rect.x = bounds->x;
313    rect.y = bounds->y;
314    rect.width = bounds->width;
315    rect.height = bounds->height;
316    xcb_xfixes_invert_region(_ecore_xcb_conn, source, rect, dest);
317 #endif /* ECORE_XCB_FIXES */
318 } /* ecore_x_region_invert */
319
320 /**
321  * Translate a region.
322  * @param region The region to translate.
323  * @param dx     The horizontal translation.
324  * @param dy     The vertical translation.
325  *
326  * The @p region is translated by @p dx and @p dy in place.
327  * @ingroup Ecore_X_Fixes_Group
328  */
329 EAPI void
330 ecore_x_region_translate(Ecore_X_Region region,
331                          int            dx,
332                          int            dy)
333 {
334 #ifdef ECORE_XCB_FIXES
335    xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy);
336 #endif /* ECORE_XCB_FIXES */
337 } /* ecore_x_region_translate */
338
339 /**
340  * Extent a region.
341  * @param dest   The destination region.
342  * @param source The source region.
343  *
344  * The extents of the @p source region are placed in @p dest.
345  * @ingroup Ecore_X_Fixes_Group
346  */
347 EAPI void
348 ecore_x_region_extents(Ecore_X_Region dest,
349                        Ecore_X_Region source)
350 {
351 #ifdef ECORE_XCB_FIXES
352    xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest);
353 #endif /* ECORE_XCB_FIXES */
354 } /* ecore_x_region_extents */
355
356 /**
357  * Sends the XFixesFetchRegion request.
358  * @param region Requested region.
359  * @ingroup Ecore_X_Fixes_Group
360  */
361 EAPI void
362 ecore_x_region_fetch_prefetch(Ecore_X_Region region)
363 {
364 #ifdef ECORE_XCB_FIXES
365    xcb_xfixes_fetch_region_cookie_t cookie;
366
367    cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region);
368    _ecore_xcb_cookie_cache(cookie.sequence);
369 #endif /* ECORE_XCB_FIXES */
370 } /* ecore_x_region_fetch_prefetch */
371
372 /**
373  * Gets the reply of the XFixesFetchRegion request sent by ecore_xcb_region_fetch_prefetch().
374  * @ingroup Ecore_X_Fixes_Group
375  */
376 EAPI void
377 ecore_x_region_fetch_fetch(void)
378 {
379 #ifdef ECORE_XCB_FIXES
380    xcb_xfixes_fetch_region_cookie_t cookie;
381    xcb_xfixes_fetch_region_reply_t *reply;
382
383    cookie.sequence = _ecore_xcb_cookie_get();
384    reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL);
385    _ecore_xcb_reply_cache(reply);
386 #endif /* ECORE_XCB_FIXES */
387 } /* ecore_x_region_fetch_fetch */
388
389 /**
390  * Return the rectangles that compose a region.
391  * @param  region The region (Unused).
392  * @param  num    The number of returned rectangles.
393  * @param  bounds The returned bounds of the region.
394  * @return        The returned rectangles.
395  *
396  * The @p region passed to ecore_xcb_region_fetch_prefetch() is
397  * returned as a list of rectagles in XY-banded order.
398  *
399  * To use this function, you must call before, and in order,
400  * ecore_xcb_region_fetch_prefetch(), which sends the XFixesFetchRegion request,
401  * then ecore_xcb_region_fetch_fetch(), which gets the reply.
402  * @ingroup Ecore_X_Fixes_Group
403  */
404 EAPI Ecore_X_Rectangle *
405 ecore_x_region_fetch(Ecore_X_Region region __UNUSED__,
406                      int                  *num,
407                      Ecore_X_Rectangle    *bounds)
408 {
409    Ecore_X_Rectangle extents = { 0, 0, 0, 0};
410    Ecore_X_Rectangle *rects = NULL;
411 #ifdef ECORE_XCB_FIXES
412    int n;
413    xcb_xfixes_fetch_region_reply_t *reply;
414
415    reply = _ecore_xcb_reply_get();
416    if (!reply)
417      {
418         if (num)
419            *num = 0;
420
421         if (bounds)
422            *bounds = extents;
423
424         return NULL;
425      }
426
427    n = xcb_xfixes_fetch_region_rectangles_length(reply);
428    rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle));
429    if (!rects)
430      {
431         if (num)
432            *num = 0;
433
434         if (bounds)
435            *bounds = extents;
436
437         return NULL;
438      }
439
440    if (num)
441       *num = n;
442
443    if (bounds)
444      {
445         bounds->x = reply->extents.x;
446         bounds->y = reply->extents.y;
447         bounds->width = reply->extents.width;
448         bounds->height = reply->extents.height;
449      }
450
451    memcpy(rects,
452           xcb_xfixes_fetch_region_rectangles(reply),
453           sizeof(Ecore_X_Rectangle) * n);
454
455    return rects;
456 #else /* ifdef ECORE_XCB_FIXES */
457    if (num)
458       *num = 0;
459
460    if (bounds)
461       *bounds = extents;
462
463    return NULL;
464 #endif /* ECORE_XCB_FIXES */
465 } /* ecore_x_region_fetch */
466
467 /**
468  * Expand a region.
469  * @param dest   The destination region.
470  * @param source The source region.
471  * @param left   The number of pixels to add on the left.
472  * @param right  The number of pixels to add on the right.
473  * @param top    The number of pixels to add at the top.
474  * @param bottom The number of pixels to add at the bottom.
475  *
476  * Put in @p dest the area specified by expanding each rectangle in
477  * the @p source  region by the specified number of pixels to the
478  * @p left, @p right, @p top and @p bottom.
479  * @ingroup Ecore_X_Fixes_Group
480  */
481 EAPI void
482 ecore_x_region_expand(Ecore_X_Region dest,
483                       Ecore_X_Region source,
484                       unsigned int   left,
485                       unsigned int   right,
486                       unsigned int   top,
487                       unsigned int   bottom)
488 {
489 #ifdef ECORE_XCB_FIXES
490    xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom);
491 #endif /* ECORE_XCB_FIXES */
492 } /* ecore_x_region_expand */
493
494 /**
495  * Change clip-mask in a graphic context to the specified region.
496  * @param region   The region to change.
497  * @param gc       The clip-mask graphic context.
498  * @param x_origin The horizontal translation.
499  * @param y_origin The vertical translation.
500  *
501  * Changes clip-mask in @p gc to the specified @p region and
502  * sets the clip origin with the values of @p x_origin and @p y_origin.
503  * Output will be clippped to remain contained within the region. The
504  * clip origin is interpreted relative to the origin of whatever
505  * destination drawable is specified in a graphics request. The
506  * region is interpreted relative to the clip origin. Future changes
507  * to region have no effect on the gc clip-mask.
508  * @ingroup Ecore_X_Fixes_Group
509  */
510 EAPI void
511 ecore_x_region_gc_clip_set(Ecore_X_Region region,
512                            Ecore_X_GC     gc,
513                            int            x_origin,
514                            int            y_origin)
515 {
516 #ifdef ECORE_XCB_FIXES
517    xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x_origin, y_origin);
518 #endif /* ECORE_XCB_FIXES */
519 } /* ecore_x_region_gc_clip_set */
520
521 /**
522  * Change the shape extension of a window.
523  * @param region   The region.
524  * @param dest     The window whose shape is changed.
525  * @param type     The kind of shape.
526  * @param x_offset The horizontal offset.
527  * @param y_offset The vertical offset.
528  *
529  * Set the specified Shape extension region of @p window to @p region,
530  * offset by @p x_offset and @p y_offset. Future changes to region
531  * have no effect on the window shape.
532  * @ingroup Ecore_X_Fixes_Group
533  */
534 EAPI void
535 ecore_x_region_window_shape_set(Ecore_X_Region     region,
536                                 Ecore_X_Window     dest,
537                                 Ecore_X_Shape_Type type,
538                                 int                x_offset,
539                                 int                y_offset)
540 {
541 #ifdef ECORE_XCB_FIXES
542    xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x_offset, y_offset, region);
543 #endif /* ECORE_XCB_FIXES */
544 } /* ecore_x_region_window_shape_set */
545
546 /**
547  * Change clip-mask in picture to the specified region.
548  * @param region   The region.
549  * @param picture  The picture.
550  * @param x_origin The X coordinate of the origin.
551  * @param y_origin The Y coordinate of the origin.
552  *
553  * Changes clip-mask in picture to the specified @p region
554  * and sets the clip origin.  Input and output will be clipped to
555  * remain contained within the region.  The clip origin is interpreted
556  * relative to the origin of the drawable associated with @p picture.  The
557  * region is interpreted relative to the clip origin.  Future changes
558  * to region have no effect on the picture clip-mask.
559  * @ingroup Ecore_X_Fixes_Group
560  */
561 EAPI void
562 ecore_x_region_picture_clip_set(Ecore_X_Region  region,
563                                 Ecore_X_Picture picture,
564                                 int             x_origin,
565                                 int             y_origin)
566 {
567 #ifdef ECORE_XCB_FIXES
568    xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x_origin, y_origin);
569 #endif /* ECORE_XCB_FIXES */
570 } /* ecore_x_region_picture_clip_set */
571