1 #include "ecore_xcb_private.h"
2 # ifdef ECORE_XCB_XFIXES
3 # include <xcb/xfixes.h>
6 /* local function prototypes */
7 static xcb_rectangle_t *_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects,
9 static Ecore_X_Rectangle *_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects,
13 static Eina_Bool _xfixes_avail = EINA_FALSE;
15 /* external variables */
16 int _ecore_xcb_event_xfixes = -1;
19 _ecore_xcb_xfixes_init(void)
21 LOGFN(__FILE__, __LINE__, __FUNCTION__);
23 #ifdef ECORE_XCB_XFIXES
24 xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
29 _ecore_xcb_xfixes_finalize(void)
31 #ifdef ECORE_XCB_XFIXES
32 const xcb_query_extension_reply_t *ext_reply;
35 LOGFN(__FILE__, __LINE__, __FUNCTION__);
37 #ifdef ECORE_XCB_XFIXES
38 ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
39 if ((ext_reply) && (ext_reply->present))
41 xcb_xfixes_query_version_cookie_t cookie;
42 xcb_xfixes_query_version_reply_t *reply;
45 xcb_xfixes_query_version_unchecked(_ecore_xcb_conn,
46 XCB_XFIXES_MAJOR_VERSION,
47 XCB_XFIXES_MINOR_VERSION);
48 reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn, cookie, NULL);
51 /* NB: XFixes Extension >= 3 needed for shape stuff.
52 * for now, I am removing this check so that it matches the
53 * xlib code closer. If the extension version ends up being
54 * that important, then re-enable this */
56 /* if (reply->major_version >= 3) */
57 _xfixes_avail = EINA_TRUE;
62 _ecore_xcb_event_xfixes = ext_reply->first_event;
68 ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
70 #ifdef ECORE_XCB_XFIXES
71 Ecore_X_Window root = 0;
72 xcb_void_cookie_t cookie;
73 xcb_generic_error_t *err;
79 if (!_xfixes_avail) return EINA_FALSE;
81 #ifdef ECORE_XCB_XFIXES
82 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
84 mask = (XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
85 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
86 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
89 xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn, root,
91 err = xcb_request_check(_ecore_xcb_conn, cookie);
104 _ecore_xcb_xfixes_avail_get(void)
106 return _xfixes_avail;
110 * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions
111 * @ingroup Ecore_X_Group
113 * Functions related to the X Fixes extension.
117 * Create a region from rectangles.
118 * @param rects The rectangles used to initialize the region.
119 * @param num The number of rectangles.
120 * @return The newly created region.
122 * Create a region initialized to the specified list of rectangles
123 * @p rects. The rectangles may be specified in any order, their union
124 * becomes the region.
125 * @ingroup Ecore_X_Fixes_Group
128 ecore_x_region_new(Ecore_X_Rectangle *rects,
131 Ecore_X_Region region = 0;
132 #ifdef ECORE_XCB_XFIXES
133 xcb_rectangle_t *xrects;
136 LOGFN(__FILE__, __LINE__, __FUNCTION__);
139 if (!_xfixes_avail) return 0;
141 #ifdef ECORE_XCB_XFIXES
142 xrects = _ecore_xcb_rect_to_xcb(rects, num);
143 region = xcb_generate_id(_ecore_xcb_conn);
144 xcb_xfixes_create_region(_ecore_xcb_conn, region, num, xrects);
153 * Create a region from a pixmap.
154 * @param bitmap The bitmap used to initialize the region.
155 * @return The newly created region.
157 * Creates a region initialized to the set of 'one' pixels in @p bitmap
158 * (which must be of depth 1, else Match error).
159 * @ingroup Ecore_X_Fixes_Group
162 ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
164 Ecore_X_Region region = 0;
166 LOGFN(__FILE__, __LINE__, __FUNCTION__);
169 if (!_xfixes_avail) return 0;
171 #ifdef ECORE_XCB_XFIXES
172 region = xcb_generate_id(_ecore_xcb_conn);
173 xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap);
181 * Create a region from a window.
182 * @param win The window used to initialize the region.
183 * @param type The type of the region.
184 * @return The newly created region.
186 * Creates a region initialized to the specified @p window region. See
187 * the Shape extension for the definition of Bounding and Clip
189 * @ingroup Ecore_X_Fixes_Group
192 ecore_x_region_new_from_window(Ecore_X_Window win,
193 Ecore_X_Region_Type type)
195 Ecore_X_Region region = 0;
197 LOGFN(__FILE__, __LINE__, __FUNCTION__);
200 if (!_xfixes_avail) return 0;
202 #ifdef ECORE_XCB_XFIXES
203 region = xcb_generate_id(_ecore_xcb_conn);
204 xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, win, type);
212 * Create a region from a graphic context.
213 * @param gc The graphic context used to initialize the region.
214 * @return The newly created region.
216 * Creates a region initialized from the clip list of @p gc.
217 * @ingroup Ecore_X_Fixes_Group
220 ecore_x_region_new_from_gc(Ecore_X_GC gc)
222 Ecore_X_Region region = 0;
224 LOGFN(__FILE__, __LINE__, __FUNCTION__);
227 if (!_xfixes_avail) return 0;
229 #ifdef ECORE_XCB_XFIXES
230 region = xcb_generate_id(_ecore_xcb_conn);
231 xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc);
239 * Create a region from a picture.
240 * @param picture The picture used to initialize the region.
241 * @return The newly created region.
243 * Creates a region initialized from the clip list of @p picture.
244 * @ingroup Ecore_X_Fixes_Group
247 ecore_x_region_new_from_picture(Ecore_X_Picture picture)
249 Ecore_X_Region region = 0;
251 LOGFN(__FILE__, __LINE__, __FUNCTION__);
254 if (!_xfixes_avail) return 0;
256 #ifdef ECORE_XCB_XFIXES
257 region = xcb_generate_id(_ecore_xcb_conn);
258 xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture);
267 * @param region The region to destroy.
269 * Destroy the specified @p region.
270 * @ingroup Ecore_X_Fixes_Group
273 ecore_x_region_free(Ecore_X_Region region)
275 LOGFN(__FILE__, __LINE__, __FUNCTION__);
278 if (!_xfixes_avail) return;
280 #ifdef ECORE_XCB_XFIXES
281 xcb_xfixes_destroy_region(_ecore_xcb_conn, region);
287 * Set the content of a region.
288 * @param region The region to destroy.
289 * @param rects The rectangles used to set the region.
290 * @param num The number of rectangles.
292 * Replace the current contents of @p region with the region formed
293 * by the union of the rectangles @p rects.
294 * @ingroup Ecore_X_Fixes_Group
297 ecore_x_region_set(Ecore_X_Region region,
298 Ecore_X_Rectangle *rects,
301 #ifdef ECORE_XCB_XFIXES
302 xcb_rectangle_t *xrects;
305 LOGFN(__FILE__, __LINE__, __FUNCTION__);
308 if (!_xfixes_avail) return;
310 #ifdef ECORE_XCB_XFIXES
311 xrects = _ecore_xcb_rect_to_xcb(rects, num);
312 xcb_xfixes_set_region(_ecore_xcb_conn, region, num, xrects);
319 * Copy the content of a region.
320 * @param dest The destination region.
321 * @param source The source region.
323 * Replace the contents of @p dest with the contents of @p source.
324 * @ingroup Ecore_X_Fixes_Group
327 ecore_x_region_copy(Ecore_X_Region dest,
328 Ecore_X_Region source)
330 LOGFN(__FILE__, __LINE__, __FUNCTION__);
333 if (!_xfixes_avail) return;
335 // NB: Hmmmm...this may need converting to/fro xcb_rectangle_t
336 #ifdef ECORE_XCB_XFIXES
337 xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest);
343 * Make the union of two regions.
344 * @param dest The destination region.
345 * @param source1 The first source region.
346 * @param source2 The second source region.
348 * Replace the contents of @p dest with the union of @p source1 and
350 * @ingroup Ecore_X_Fixes_Group
353 ecore_x_region_combine(Ecore_X_Region dest,
354 Ecore_X_Region source1,
355 Ecore_X_Region source2)
357 LOGFN(__FILE__, __LINE__, __FUNCTION__);
360 if (!_xfixes_avail) return;
362 #ifdef ECORE_XCB_XFIXES
363 xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest);
369 * Make the intersection of two regions.
370 * @param dest The destination region.
371 * @param source1 The first source region.
372 * @param source2 The second source region.
374 * Replace the contents of @p dest with the intersection of @p source1 and
376 * @ingroup Ecore_X_Fixes_Group
379 ecore_x_region_intersect(Ecore_X_Region dest,
380 Ecore_X_Region source1,
381 Ecore_X_Region source2)
383 LOGFN(__FILE__, __LINE__, __FUNCTION__);
386 if (!_xfixes_avail) return;
388 #ifdef ECORE_XCB_XFIXES
389 xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest);
395 * Make the subtraction of two regions.
396 * @param dest The destination region.
397 * @param source1 The first source region.
398 * @param source2 The second source region.
400 * Replace the contents of @p dest with the subtraction of @p source1 by
402 * @ingroup Ecore_X_Fixes_Group
405 ecore_x_region_subtract(Ecore_X_Region dest,
406 Ecore_X_Region source1,
407 Ecore_X_Region source2)
409 LOGFN(__FILE__, __LINE__, __FUNCTION__);
412 if (!_xfixes_avail) return;
414 #ifdef ECORE_XCB_XFIXES
415 xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest);
421 * Make the subtraction of regions by bounds.
422 * @param dest The destination region.
423 * @param bounds The bounds.
424 * @param source The source region.
426 * The @p source region is subtracted from the region specified by
427 * @p bounds. The result is placed in @p dest, replacing its
429 * @ingroup Ecore_X_Fixes_Group
432 ecore_x_region_invert(Ecore_X_Region dest,
433 Ecore_X_Rectangle *bounds,
434 Ecore_X_Region source)
436 #ifdef ECORE_XCB_XFIXES
437 xcb_rectangle_t xrects;
440 LOGFN(__FILE__, __LINE__, __FUNCTION__);
443 if (!_xfixes_avail) return;
445 #ifdef ECORE_XCB_XFIXES
446 xrects.x = bounds->x;
447 xrects.y = bounds->y;
448 xrects.width = bounds->width;
449 xrects.height = bounds->height;
451 xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest);
457 * Translate a region.
458 * @param region The region to translate.
459 * @param dx The horizontal translation.
460 * @param dy The vertical translation.
462 * The @p region is translated by @p dx and @p dy in place.
463 * @ingroup Ecore_X_Fixes_Group
466 ecore_x_region_translate(Ecore_X_Region region,
470 LOGFN(__FILE__, __LINE__, __FUNCTION__);
473 if (!_xfixes_avail) return;
475 #ifdef ECORE_XCB_XFIXES
476 xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy);
483 * @param dest The destination region.
484 * @param source The source region.
486 * The extents of the @p source region are placed in @p dest.
487 * @ingroup Ecore_X_Fixes_Group
490 ecore_x_region_extents(Ecore_X_Region dest,
491 Ecore_X_Region source)
493 LOGFN(__FILE__, __LINE__, __FUNCTION__);
496 if (!_xfixes_avail) return;
498 #ifdef ECORE_XCB_XFIXES
499 xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest);
505 * Return the rectangles that compose a region.
506 * @param region The region (Unused).
507 * @param num The number of returned rectangles.
508 * @param bounds The returned bounds of the region.
509 * @return The returned rectangles.
511 * @ingroup Ecore_X_Fixes_Group
513 EAPI Ecore_X_Rectangle *
514 ecore_x_region_fetch(Ecore_X_Region region,
516 Ecore_X_Rectangle *bounds)
518 Ecore_X_Rectangle extents = { 0, 0, 0, 0 };
519 Ecore_X_Rectangle *rects = NULL;
520 #ifdef ECORE_XCB_XFIXES
521 xcb_xfixes_fetch_region_cookie_t cookie;
522 xcb_xfixes_fetch_region_reply_t *reply;
527 LOGFN(__FILE__, __LINE__, __FUNCTION__);
531 if (bounds) *bounds = extents;
532 if (!_xfixes_avail) return NULL;
534 #ifdef ECORE_XCB_XFIXES
535 cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region);
536 reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL);
537 if (!reply) return NULL;
539 r = xcb_xfixes_fetch_region_rectangles(reply);
540 n = xcb_xfixes_fetch_region_rectangles_length(reply);
541 rects = _ecore_xcb_rect_to_ecore(r, n);
544 /* rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle)); */
551 /* for (i = 0; i < n; i++) */
553 /* rects[i].x = r[i].x; */
554 /* rects[i].y = r[i].y; */
555 /* rects[i].width = r[i].width; */
556 /* rects[i].height = r[i].height; */
559 (*bounds).x = reply->extents.x;
560 (*bounds).y = reply->extents.y;
561 (*bounds).width = reply->extents.width;
562 (*bounds).height = reply->extents.height;
572 * @param dest The destination region.
573 * @param source The source region.
574 * @param left The number of pixels to add on the left.
575 * @param right The number of pixels to add on the right.
576 * @param top The number of pixels to add at the top.
577 * @param bottom The number of pixels to add at the bottom.
579 * Put in @p dest the area specified by expanding each rectangle in
580 * the @p source region by the specified number of pixels to the
581 * @p left, @p right, @p top and @p bottom.
582 * @ingroup Ecore_X_Fixes_Group
585 ecore_x_region_expand(Ecore_X_Region dest,
586 Ecore_X_Region source,
592 LOGFN(__FILE__, __LINE__, __FUNCTION__);
595 if (!_xfixes_avail) return;
597 #ifdef ECORE_XCB_XFIXES
598 xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom);
604 * Change clip-mask in a graphic context to the specified region.
605 * @param region The region to change.
606 * @param gc The clip-mask graphic context.
607 * @param x The horizontal translation.
608 * @param y The vertical translation.
610 * Changes clip-mask in @p gc to the specified @p region and
611 * sets the clip origin with the values of @p x_origin and @p y_origin.
612 * Output will be clippped to remain contained within the region. The
613 * clip origin is interpreted relative to the origin of whatever
614 * destination drawable is specified in a graphics request. The
615 * region is interpreted relative to the clip origin. Future changes
616 * to region have no effect on the gc clip-mask.
617 * @ingroup Ecore_X_Fixes_Group
620 ecore_x_region_gc_clip_set(Ecore_X_Region region,
625 LOGFN(__FILE__, __LINE__, __FUNCTION__);
628 if (!_xfixes_avail) return;
630 #ifdef ECORE_XCB_XFIXES
631 xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y);
637 * Change the shape extension of a window.
638 * @param region The region.
639 * @param dest The window whose shape is changed.
640 * @param type The kind of shape.
641 * @param x The horizontal offset.
642 * @param y The vertical offset.
644 * Set the specified Shape extension region of @p window to @p region,
645 * offset by @p x_offset and @p y_offset. Future changes to region
646 * have no effect on the window shape.
647 * @ingroup Ecore_X_Fixes_Group
650 ecore_x_region_window_shape_set(Ecore_X_Region region,
652 Ecore_X_Shape_Type type,
656 LOGFN(__FILE__, __LINE__, __FUNCTION__);
659 if (!_xfixes_avail) return;
661 #ifdef ECORE_XCB_XFIXES
662 xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region);
668 * Change clip-mask in picture to the specified region.
669 * @param region The region.
670 * @param picture The picture.
671 * @param x The X coordinate of the origin.
672 * @param y The Y coordinate of the origin.
674 * Changes clip-mask in picture to the specified @p region
675 * and sets the clip origin. Input and output will be clipped to
676 * remain contained within the region. The clip origin is interpreted
677 * relative to the origin of the drawable associated with @p picture. The
678 * region is interpreted relative to the clip origin. Future changes
679 * to region have no effect on the picture clip-mask.
680 * @ingroup Ecore_X_Fixes_Group
683 ecore_x_region_picture_clip_set(Ecore_X_Region region,
684 Ecore_X_Picture picture,
688 LOGFN(__FILE__, __LINE__, __FUNCTION__);
691 if (!_xfixes_avail) return;
693 #ifdef ECORE_XCB_XFIXES
694 xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y);
699 /* local function prototypes */
700 static xcb_rectangle_t *
701 _ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects,
704 xcb_rectangle_t *xrect;
707 if (!num) return NULL;
709 xrect = malloc(sizeof(xcb_rectangle_t) * num);
710 if (!xrect) return NULL;
712 for (i = 0; i < num; i++)
714 xrect[i].x = rects[i].x;
715 xrect[i].y = rects[i].y;
716 xrect[i].width = rects[i].width;
717 xrect[i].height = rects[i].height;
723 static Ecore_X_Rectangle *
724 _ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects,
727 Ecore_X_Rectangle *erect;
730 if (!num) return NULL;
732 erect = malloc(sizeof(Ecore_X_Rectangle) * num);
733 if (!erect) return NULL;
735 for (i = 0; i < num; i++)
737 erect[i].x = rects[i].x;
738 erect[i].y = rects[i].y;
739 erect[i].width = rects[i].width;
740 erect[i].height = rects[i].height;