257c61763d91138b63949891e8b91b5ee606dda5
[platform/upstream/efl.git] / src / lib / ecore_x / xcb / ecore_xcb_xfixes.c
1 #include "ecore_xcb_private.h"
2 # ifdef ECORE_XCB_XFIXES
3 #  include <xcb/xfixes.h>
4 # endif
5
6 /* local function prototypes */
7 static xcb_rectangle_t   *_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects,
8                                                  int                num);
9 static Ecore_X_Rectangle *_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects,
10                                                    int              num);
11
12 /* local variables */
13 static Eina_Bool _xfixes_avail = EINA_FALSE;
14
15 /* external variables */
16 int _ecore_xcb_event_xfixes = -1;
17
18 void
19 _ecore_xcb_xfixes_init(void)
20 {
21    LOGFN(__FILE__, __LINE__, __FUNCTION__);
22
23 #ifdef ECORE_XCB_XFIXES
24    xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
25 #endif
26 }
27
28 void
29 _ecore_xcb_xfixes_finalize(void)
30 {
31 #ifdef ECORE_XCB_XFIXES
32    const xcb_query_extension_reply_t *ext_reply;
33 #endif
34
35    LOGFN(__FILE__, __LINE__, __FUNCTION__);
36
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))
40      {
41         xcb_xfixes_query_version_cookie_t cookie;
42         xcb_xfixes_query_version_reply_t *reply;
43
44         cookie =
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);
49         if (reply)
50           {
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 */
55
56      /* if (reply->major_version >= 3) */
57                 _xfixes_avail = EINA_TRUE;
58                 free(reply);
59           }
60
61         if (_xfixes_avail)
62           _ecore_xcb_event_xfixes = ext_reply->first_event;
63      }
64 #endif
65 }
66
67 EAPI Eina_Bool
68 ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
69 {
70 #ifdef ECORE_XCB_XFIXES
71    Ecore_X_Window root = 0;
72    xcb_void_cookie_t cookie;
73    xcb_generic_error_t *err;
74    int mask = 0;
75 #endif
76
77    CHECK_XCB_CONN;
78
79    if (!_xfixes_avail) return EINA_FALSE;
80
81 #ifdef ECORE_XCB_XFIXES
82    root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
83
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);
87
88    cookie =
89      xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn, root,
90                                                selection, mask);
91    err = xcb_request_check(_ecore_xcb_conn, cookie);
92    if (err)
93      {
94         free(err);
95         return EINA_FALSE;
96      }
97
98    return EINA_TRUE;
99 #endif
100    return EINA_FALSE;
101 }
102
103 Eina_Bool
104 _ecore_xcb_xfixes_avail_get(void)
105 {
106    return _xfixes_avail;
107 }
108
109 /**
110  * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions
111  * @ingroup Ecore_X_Group
112  *
113  * Functions related to the X Fixes extension.
114  */
115
116 /**
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.
121  *
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
126  */
127 EAPI Ecore_X_Region
128 ecore_x_region_new(Ecore_X_Rectangle *rects,
129                    int                num)
130 {
131    Ecore_X_Region region = 0;
132 #ifdef ECORE_XCB_XFIXES
133    xcb_rectangle_t *xrects;
134 #endif
135
136    LOGFN(__FILE__, __LINE__, __FUNCTION__);
137    CHECK_XCB_CONN;
138
139    if (!_xfixes_avail) return 0;
140
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);
145    free(xrects);
146 //   ecore_x_flush();
147 #endif
148
149    return region;
150 }
151
152 /**
153  * Create a region from a pixmap.
154  * @param bitmap The bitmap used to initialize the region.
155  * @return       The newly created region.
156  *
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
160  */
161 EAPI Ecore_X_Region
162 ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
163 {
164    Ecore_X_Region region = 0;
165
166    LOGFN(__FILE__, __LINE__, __FUNCTION__);
167    CHECK_XCB_CONN;
168
169    if (!_xfixes_avail) return 0;
170
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);
174 //   ecore_x_flush();
175 #endif
176
177    return region;
178 }
179
180 /**
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.
185  *
186  * Creates a region initialized to the specified @p window region. See
187  * the Shape extension for the definition of Bounding and Clip
188  * regions.
189  * @ingroup Ecore_X_Fixes_Group
190  */
191 EAPI Ecore_X_Region
192 ecore_x_region_new_from_window(Ecore_X_Window      win,
193                                Ecore_X_Region_Type type)
194 {
195    Ecore_X_Region region = 0;
196
197    LOGFN(__FILE__, __LINE__, __FUNCTION__);
198    CHECK_XCB_CONN;
199
200    if (!_xfixes_avail) return 0;
201
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);
205 //   ecore_x_flush();
206 #endif
207
208    return region;
209 }
210
211 /**
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.
215  *
216  * Creates a region initialized from the clip list of @p gc.
217  * @ingroup Ecore_X_Fixes_Group
218  */
219 EAPI Ecore_X_Region
220 ecore_x_region_new_from_gc(Ecore_X_GC gc)
221 {
222    Ecore_X_Region region = 0;
223
224    LOGFN(__FILE__, __LINE__, __FUNCTION__);
225    CHECK_XCB_CONN;
226
227    if (!_xfixes_avail) return 0;
228
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);
232 //   ecore_x_flush();
233 #endif
234
235    return region;
236 }
237
238 /**
239  * Create a region from a picture.
240  * @param picture The picture used to initialize the region.
241  * @return        The newly created region.
242  *
243  * Creates a region initialized from the clip list of @p picture.
244  * @ingroup Ecore_X_Fixes_Group
245  */
246 EAPI Ecore_X_Region
247 ecore_x_region_new_from_picture(Ecore_X_Picture picture)
248 {
249    Ecore_X_Region region = 0;
250
251    LOGFN(__FILE__, __LINE__, __FUNCTION__);
252    CHECK_XCB_CONN;
253
254    if (!_xfixes_avail) return 0;
255
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);
259 //   ecore_x_flush();
260 #endif
261
262    return region;
263 }
264
265 /**
266  * Destroy a region.
267  * @param region The region to destroy.
268  *
269  * Destroy the specified @p region.
270  * @ingroup Ecore_X_Fixes_Group
271  */
272 EAPI void
273 ecore_x_region_free(Ecore_X_Region region)
274 {
275    LOGFN(__FILE__, __LINE__, __FUNCTION__);
276    CHECK_XCB_CONN;
277
278    if (!_xfixes_avail) return;
279
280 #ifdef ECORE_XCB_XFIXES
281    xcb_xfixes_destroy_region(_ecore_xcb_conn, region);
282 //   ecore_x_flush();
283 #endif
284 }
285
286 /**
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.
291  *
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
295  */
296 EAPI void
297 ecore_x_region_set(Ecore_X_Region     region,
298                    Ecore_X_Rectangle *rects,
299                    int                num)
300 {
301 #ifdef ECORE_XCB_XFIXES
302    xcb_rectangle_t *xrects;
303 #endif
304
305    LOGFN(__FILE__, __LINE__, __FUNCTION__);
306    CHECK_XCB_CONN;
307
308    if (!_xfixes_avail) return;
309
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);
313    free(xrects);
314 //   ecore_x_flush();
315 #endif
316 }
317
318 /**
319  * Copy the content of a region.
320  * @param dest   The destination region.
321  * @param source The source region.
322  *
323  * Replace the contents of @p dest with the contents of @p source.
324  * @ingroup Ecore_X_Fixes_Group
325  */
326 EAPI void
327 ecore_x_region_copy(Ecore_X_Region dest,
328                     Ecore_X_Region source)
329 {
330    LOGFN(__FILE__, __LINE__, __FUNCTION__);
331    CHECK_XCB_CONN;
332
333    if (!_xfixes_avail) return;
334
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);
338 //   ecore_x_flush();
339 #endif
340 }
341
342 /**
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.
347  *
348  * Replace the contents of @p dest with the union of @p source1 and
349  * @p source2.
350  * @ingroup Ecore_X_Fixes_Group
351  */
352 EAPI void
353 ecore_x_region_combine(Ecore_X_Region dest,
354                        Ecore_X_Region source1,
355                        Ecore_X_Region source2)
356 {
357    LOGFN(__FILE__, __LINE__, __FUNCTION__);
358    CHECK_XCB_CONN;
359
360    if (!_xfixes_avail) return;
361
362 #ifdef ECORE_XCB_XFIXES
363    xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest);
364 //   ecore_x_flush();
365 #endif
366 }
367
368 /**
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.
373  *
374  * Replace the contents of @p dest with the intersection of @p source1 and
375  * @p source2.
376  * @ingroup Ecore_X_Fixes_Group
377  */
378 EAPI void
379 ecore_x_region_intersect(Ecore_X_Region dest,
380                          Ecore_X_Region source1,
381                          Ecore_X_Region source2)
382 {
383    LOGFN(__FILE__, __LINE__, __FUNCTION__);
384    CHECK_XCB_CONN;
385
386    if (!_xfixes_avail) return;
387
388 #ifdef ECORE_XCB_XFIXES
389    xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest);
390 //   ecore_x_flush();
391 #endif
392 }
393
394 /**
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.
399  *
400  * Replace the contents of @p dest with the subtraction of @p source1 by
401  * @p source2.
402  * @ingroup Ecore_X_Fixes_Group
403  */
404 EAPI void
405 ecore_x_region_subtract(Ecore_X_Region dest,
406                         Ecore_X_Region source1,
407                         Ecore_X_Region source2)
408 {
409    LOGFN(__FILE__, __LINE__, __FUNCTION__);
410    CHECK_XCB_CONN;
411
412    if (!_xfixes_avail) return;
413
414 #ifdef ECORE_XCB_XFIXES
415    xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest);
416 //   ecore_x_flush();
417 #endif
418 }
419
420 /**
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.
425  *
426  * The @p source region is subtracted from the region specified by
427  * @p bounds.  The result is placed in @p dest, replacing its
428  * contents.
429  * @ingroup Ecore_X_Fixes_Group
430  */
431 EAPI void
432 ecore_x_region_invert(Ecore_X_Region     dest,
433                       Ecore_X_Rectangle *bounds,
434                       Ecore_X_Region     source)
435 {
436 #ifdef ECORE_XCB_XFIXES
437    xcb_rectangle_t xrects;
438 #endif
439
440    LOGFN(__FILE__, __LINE__, __FUNCTION__);
441    CHECK_XCB_CONN;
442
443    if (!_xfixes_avail) return;
444
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;
450
451    xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest);
452 //   ecore_x_flush();
453 #endif
454 }
455
456 /**
457  * Translate a region.
458  * @param region The region to translate.
459  * @param dx     The horizontal translation.
460  * @param dy     The vertical translation.
461  *
462  * The @p region is translated by @p dx and @p dy in place.
463  * @ingroup Ecore_X_Fixes_Group
464  */
465 EAPI void
466 ecore_x_region_translate(Ecore_X_Region region,
467                          int            dx,
468                          int            dy)
469 {
470    LOGFN(__FILE__, __LINE__, __FUNCTION__);
471    CHECK_XCB_CONN;
472
473    if (!_xfixes_avail) return;
474
475 #ifdef ECORE_XCB_XFIXES
476    xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy);
477 //   ecore_x_flush();
478 #endif
479 }
480
481 /**
482  * Extent a region.
483  * @param dest   The destination region.
484  * @param source The source region.
485  *
486  * The extents of the @p source region are placed in @p dest.
487  * @ingroup Ecore_X_Fixes_Group
488  */
489 EAPI void
490 ecore_x_region_extents(Ecore_X_Region dest,
491                        Ecore_X_Region source)
492 {
493    LOGFN(__FILE__, __LINE__, __FUNCTION__);
494    CHECK_XCB_CONN;
495
496    if (!_xfixes_avail) return;
497
498 #ifdef ECORE_XCB_XFIXES
499    xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest);
500 //   ecore_x_flush();
501 #endif
502 }
503
504 /**
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.
510  *
511  * @ingroup Ecore_X_Fixes_Group
512  */
513 EAPI Ecore_X_Rectangle *
514 ecore_x_region_fetch(Ecore_X_Region     region,
515                      int               *num,
516                      Ecore_X_Rectangle *bounds)
517 {
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;
523    xcb_rectangle_t *r;
524    int n = 0;
525 #endif
526
527    LOGFN(__FILE__, __LINE__, __FUNCTION__);
528    CHECK_XCB_CONN;
529
530    if (num) *num = 0;
531    if (bounds) *bounds = extents;
532    if (!_xfixes_avail) return NULL;
533
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;
538
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);
542    if (num) *num = n;
543
544    /* rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle)); */
545    /* if (!rects)  */
546    /*   { */
547    /*      free(reply); */
548    /*      return NULL; */
549    /*   } */
550
551    /* for (i = 0; i < n; i++)  */
552    /*   { */
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; */
557    /*   } */
558
559    (*bounds).x = reply->extents.x;
560    (*bounds).y = reply->extents.y;
561    (*bounds).width = reply->extents.width;
562    (*bounds).height = reply->extents.height;
563
564    free(reply);
565 #endif
566
567    return rects;
568 }
569
570 /**
571  * Expand a region.
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.
578  *
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
583  */
584 EAPI void
585 ecore_x_region_expand(Ecore_X_Region dest,
586                       Ecore_X_Region source,
587                       unsigned int   left,
588                       unsigned int   right,
589                       unsigned int   top,
590                       unsigned int   bottom)
591 {
592    LOGFN(__FILE__, __LINE__, __FUNCTION__);
593    CHECK_XCB_CONN;
594
595    if (!_xfixes_avail) return;
596
597 #ifdef ECORE_XCB_XFIXES
598    xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom);
599 //   ecore_x_flush();
600 #endif
601 }
602
603 /**
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.
609  *
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
618  */
619 EAPI void
620 ecore_x_region_gc_clip_set(Ecore_X_Region region,
621                            Ecore_X_GC     gc,
622                            int            x,
623                            int            y)
624 {
625    LOGFN(__FILE__, __LINE__, __FUNCTION__);
626    CHECK_XCB_CONN;
627
628    if (!_xfixes_avail) return;
629
630 #ifdef ECORE_XCB_XFIXES
631    xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y);
632 //   ecore_x_flush();
633 #endif
634 }
635
636 /**
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.
643  *
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
648  */
649 EAPI void
650 ecore_x_region_window_shape_set(Ecore_X_Region     region,
651                                 Ecore_X_Window     dest,
652                                 Ecore_X_Shape_Type type,
653                                 int                x,
654                                 int                y)
655 {
656    LOGFN(__FILE__, __LINE__, __FUNCTION__);
657    CHECK_XCB_CONN;
658
659    if (!_xfixes_avail) return;
660
661 #ifdef ECORE_XCB_XFIXES
662    xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region);
663 //   ecore_x_flush();
664 #endif
665 }
666
667 /**
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.
673  *
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
681  */
682 EAPI void
683 ecore_x_region_picture_clip_set(Ecore_X_Region  region,
684                                 Ecore_X_Picture picture,
685                                 int             x,
686                                 int             y)
687 {
688    LOGFN(__FILE__, __LINE__, __FUNCTION__);
689    CHECK_XCB_CONN;
690
691    if (!_xfixes_avail) return;
692
693 #ifdef ECORE_XCB_XFIXES
694    xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y);
695 //   ecore_x_flush();
696 #endif
697 }
698
699 /* local function prototypes */
700 static xcb_rectangle_t *
701 _ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects,
702                        int                num)
703 {
704    xcb_rectangle_t *xrect;
705    int i = 0;
706
707    if (!num) return NULL;
708
709    xrect = malloc(sizeof(xcb_rectangle_t) * num);
710    if (!xrect) return NULL;
711
712    for (i = 0; i < num; i++)
713      {
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;
718      }
719
720    return xrect;
721 }
722
723 static Ecore_X_Rectangle *
724 _ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects,
725                          int              num)
726 {
727    Ecore_X_Rectangle *erect;
728    int i = 0;
729
730    if (!num) return NULL;
731
732    erect = malloc(sizeof(Ecore_X_Rectangle) * num);
733    if (!erect) return NULL;
734
735    for (i = 0; i < num; i++)
736      {
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;
741      }
742
743    return erect;
744 }
745