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