1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4 
5 #include <stdlib.h>
6 
7 #include "Ecore.h"
8 #include "ecore_x_private.h"
9 #include "Ecore_X.h"
10 
11 /**
12  * @defgroup Ecore_X_Window_Shape X Window Shape Functions
13  * @ingroup Ecore_X_Group
14  *
15  * These functions use the shape extension of the X server to change
16  * shape of given windows.
17  */
18 
19 /**
20  * Sets the shape of the given window to that given by the pixmap @p mask.
21  * @param   win  The given window.
22  * @param   mask A 2-bit depth pixmap that provides the new shape of the
23  *               window.
24  * @ingroup Ecore_X_Window_Shape
25  */
26 EAPI void
ecore_x_window_shape_mask_set(Ecore_X_Window win,Ecore_X_Pixmap mask)27 ecore_x_window_shape_mask_set(Ecore_X_Window win,
28                               Ecore_X_Pixmap mask)
29 {
30    LOGFN;
31    XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
32    if (_ecore_xlib_sync) ecore_x_sync();
33 }
34 
35 /**
36  * Sets the input shape of the given window to that given by the pixmap @p mask.
37  * @param   win  The given window.
38  * @param   mask A 1-bit depth pixmap that provides the new input shape of the
39  *               window.
40  * @ingroup Ecore_X_Window_Shape
41  */
42 EAPI void
ecore_x_window_shape_input_mask_set(Ecore_X_Window win,Ecore_X_Pixmap mask)43 ecore_x_window_shape_input_mask_set(Ecore_X_Window win,
44                                     Ecore_X_Pixmap mask)
45 {
46    LOGFN;
47 #ifdef ShapeInput
48    XShapeCombineMask(_ecore_x_disp, win, ShapeInput, 0, 0, mask, ShapeSet);
49    if (_ecore_xlib_sync) ecore_x_sync();
50 #else /* ifdef ShapeInput */
51    return;
52    win = mask = 0;
53 #endif /* ifdef ShapeInput */
54 }
55 
56 EAPI void
ecore_x_window_shape_window_set(Ecore_X_Window win,Ecore_X_Window shape_win)57 ecore_x_window_shape_window_set(Ecore_X_Window win,
58                                 Ecore_X_Window shape_win)
59 {
60    LOGFN;
61    XShapeCombineShape(_ecore_x_disp,
62                       win,
63                       ShapeBounding,
64                       0,
65                       0,
66                       shape_win,
67                       ShapeBounding,
68                       ShapeSet);
69    if (_ecore_xlib_sync) ecore_x_sync();
70 }
71 
72 EAPI void
ecore_x_window_shape_input_window_set(Ecore_X_Window win,Ecore_X_Window shape_win)73 ecore_x_window_shape_input_window_set(Ecore_X_Window win,
74                                       Ecore_X_Window shape_win)
75 {
76 #ifdef ShapeInput
77    LOGFN;
78    XShapeCombineShape(_ecore_x_disp,
79                       win,
80                       ShapeInput,
81                       0,
82                       0,
83                       shape_win,
84                       ShapeInput,
85                       ShapeSet);
86    if (_ecore_xlib_sync) ecore_x_sync();
87 #else
88    return;
89    win = shape_win = 0;
90 #endif
91 }
92 
93 EAPI void
ecore_x_window_shape_window_set_xy(Ecore_X_Window win,Ecore_X_Window shape_win,int x,int y)94 ecore_x_window_shape_window_set_xy(Ecore_X_Window win,
95                                    Ecore_X_Window shape_win,
96                                    int x,
97                                    int y)
98 {
99    LOGFN;
100    XShapeCombineShape(_ecore_x_disp,
101                       win,
102                       ShapeBounding,
103                       x,
104                       y,
105                       shape_win,
106                       ShapeBounding,
107                       ShapeSet);
108    if (_ecore_xlib_sync) ecore_x_sync();
109 }
110 
111 EAPI void
ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win,Ecore_X_Window shape_win,int x,int y)112 ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win,
113                                          Ecore_X_Window shape_win,
114                                          int x,
115                                          int y)
116 {
117 #ifdef ShapeInput
118    LOGFN;
119    XShapeCombineShape(_ecore_x_disp,
120                       win,
121                       ShapeInput,
122                       x,
123                       y,
124                       shape_win,
125                       ShapeInput,
126                       ShapeSet);
127    if (_ecore_xlib_sync) ecore_x_sync();
128 #else
129    return;
130    win = shape_win = x = y = 0;
131 #endif
132 }
133 
134 EAPI void
ecore_x_window_shape_rectangle_set(Ecore_X_Window win,int x,int y,int w,int h)135 ecore_x_window_shape_rectangle_set(Ecore_X_Window win,
136                                    int x,
137                                    int y,
138                                    int w,
139                                    int h)
140 {
141    XRectangle rect;
142 
143    LOGFN;
144    rect.x = x;
145    rect.y = y;
146    rect.width = w;
147    rect.height = h;
148    XShapeCombineRectangles(_ecore_x_disp,
149                            win,
150                            ShapeBounding,
151                            0,
152                            0,
153                            &rect,
154                            1,
155                            ShapeSet,
156                            Unsorted);
157    if (_ecore_xlib_sync) ecore_x_sync();
158 }
159 
160 EAPI void
ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win,int x,int y,int w,int h)161 ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win,
162                                          int x,
163                                          int y,
164                                          int w,
165                                          int h)
166 {
167 #ifdef ShapeInput
168    XRectangle rect;
169 
170    LOGFN;
171    rect.x = x;
172    rect.y = y;
173    rect.width = w;
174    rect.height = h;
175    XShapeCombineRectangles(_ecore_x_disp,
176                            win,
177                            ShapeInput,
178                            0,
179                            0,
180                            &rect,
181                            1,
182                            ShapeSet,
183                            Unsorted);
184    if (_ecore_xlib_sync) ecore_x_sync();
185 #else
186    return;
187    win = x = y = w = h = 0;
188 #endif
189 }
190 
191 EAPI void
ecore_x_window_shape_rectangles_set(Ecore_X_Window win,Ecore_X_Rectangle * rects,int num)192 ecore_x_window_shape_rectangles_set(Ecore_X_Window win,
193                                     Ecore_X_Rectangle *rects,
194                                     int num)
195 {
196 #ifdef ShapeInput
197    XRectangle *rect = NULL;
198    int i;
199 
200    LOGFN;
201    if (!rects) return;
202    if (num > 0)
203      {
204         rect = malloc(sizeof(XRectangle) * num);
205         if (!rect) return;
206         for (i = 0; i < num; i++)
207           {
208              rect[i].x = rects[i].x;
209              rect[i].y = rects[i].y;
210              rect[i].width = rects[i].width;
211              rect[i].height = rects[i].height;
212           }
213      }
214    XShapeCombineRectangles(_ecore_x_disp,
215                            win,
216                            ShapeBounding,
217                            0,
218                            0,
219                            rect,
220                            num,
221                            ShapeSet,
222                            Unsorted);
223    if (_ecore_xlib_sync) ecore_x_sync();
224    if (rect) free(rect);
225 #else
226    return;
227    win = rects = num = 0;
228 #endif
229 }
230 
231 EAPI void
ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win,Ecore_X_Rectangle * rects,int num)232 ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win,
233                                           Ecore_X_Rectangle *rects,
234                                           int num)
235 {
236 #ifdef ShapeInput
237    XRectangle *rect = NULL;
238    int i;
239 
240    LOGFN;
241    if (!rects) return;
242    if (num > 0)
243      {
244         rect = malloc(sizeof(XRectangle) * num);
245         if (!rect) return;
246         for (i = 0; i < num; i++)
247           {
248              rect[i].x = rects[i].x;
249              rect[i].y = rects[i].y;
250              rect[i].width = rects[i].width;
251              rect[i].height = rects[i].height;
252           }
253      }
254    XShapeCombineRectangles(_ecore_x_disp,
255                            win,
256                            ShapeInput,
257                            0,
258                            0,
259                            rect,
260                            num,
261                            ShapeSet,
262                            Unsorted);
263    if (_ecore_xlib_sync) ecore_x_sync();
264    if (rect) free(rect);
265 #else
266    return;
267    win = rects = num = 0;
268 #endif
269 }
270 
271 EAPI void
ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win,int x,int y,int w,int h)272 ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win,
273                                         int x,
274                                         int y,
275                                         int w,
276                                         int h)
277 {
278    XRectangle rect;
279 
280    LOGFN;
281    rect.x = x;
282    rect.y = y;
283    rect.width = w;
284    rect.height = h;
285    XShapeCombineRectangles(_ecore_x_disp,
286                            win,
287                            ShapeBounding,
288                            0,
289                            0,
290                            &rect,
291                            1,
292                            ShapeSubtract,
293                            Unsorted);
294    if (_ecore_xlib_sync) ecore_x_sync();
295 }
296 
297 EAPI void
ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win,int x,int y,int w,int h)298 ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win,
299                                               int x,
300                                               int y,
301                                               int w,
302                                               int h)
303 {
304 #ifdef ShapeInput
305    XRectangle rect;
306 
307    LOGFN;
308    rect.x = x;
309    rect.y = y;
310    rect.width = w;
311    rect.height = h;
312    XShapeCombineRectangles(_ecore_x_disp,
313                            win,
314                            ShapeInput,
315                            0,
316                            0,
317                            &rect,
318                            1,
319                            ShapeSubtract,
320                            Unsorted);
321    if (_ecore_xlib_sync) ecore_x_sync();
322 #else
323    return;
324    win = x = y = w = h = 0;
325 #endif
326 }
327 
328 EAPI void
ecore_x_window_shape_window_add(Ecore_X_Window win,Ecore_X_Window shape_win)329 ecore_x_window_shape_window_add(Ecore_X_Window win,
330                                 Ecore_X_Window shape_win)
331 {
332    LOGFN;
333    XShapeCombineShape(_ecore_x_disp,
334                       win,
335                       ShapeBounding,
336                       0,
337                       0,
338                       shape_win,
339                       ShapeBounding,
340                       ShapeUnion);
341    if (_ecore_xlib_sync) ecore_x_sync();
342 }
343 
344 EAPI void
ecore_x_window_shape_window_add_xy(Ecore_X_Window win,Ecore_X_Window shape_win,int x,int y)345 ecore_x_window_shape_window_add_xy(Ecore_X_Window win,
346                                    Ecore_X_Window shape_win,
347                                    int x,
348                                    int y)
349 {
350    LOGFN;
351    XShapeCombineShape(_ecore_x_disp,
352                       win,
353                       ShapeBounding,
354                       x,
355                       y,
356                       shape_win,
357                       ShapeBounding,
358                       ShapeUnion);
359    if (_ecore_xlib_sync) ecore_x_sync();
360 }
361 
362 EAPI void
ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win,Ecore_X_Window shape_win,int x,int y)363 ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win,
364                                          Ecore_X_Window shape_win,
365                                          int x,
366                                          int y)
367 {
368 #ifdef ShapeInput
369    LOGFN;
370    XShapeCombineShape(_ecore_x_disp,
371                       win,
372                       ShapeInput,
373                       x,
374                       y,
375                       shape_win,
376                       ShapeInput,
377                       ShapeUnion);
378    if (_ecore_xlib_sync) ecore_x_sync();
379 #else
380    return;
381    win = shape_win = x = y = 0;
382 #endif
383 }
384 
385 EAPI void
ecore_x_window_shape_rectangle_add(Ecore_X_Window win,int x,int y,int w,int h)386 ecore_x_window_shape_rectangle_add(Ecore_X_Window win,
387                                    int x,
388                                    int y,
389                                    int w,
390                                    int h)
391 {
392    XRectangle rect;
393 
394    LOGFN;
395    rect.x = x;
396    rect.y = y;
397    rect.width = w;
398    rect.height = h;
399    XShapeCombineRectangles(_ecore_x_disp,
400                            win,
401                            ShapeBounding,
402                            0,
403                            0,
404                            &rect,
405                            1,
406                            ShapeUnion,
407                            Unsorted);
408    if (_ecore_xlib_sync) ecore_x_sync();
409 }
410 
411 EAPI void
ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win,int x,int y,int w,int h)412 ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win,
413                                          int x,
414                                          int y,
415                                          int w,
416                                          int h)
417 {
418 #ifdef ShapeInput
419    XRectangle rect;
420 
421    LOGFN;
422    rect.x = x;
423    rect.y = y;
424    rect.width = w;
425    rect.height = h;
426    XShapeCombineRectangles(_ecore_x_disp,
427                            win,
428                            ShapeInput,
429                            0,
430                            0,
431                            &rect,
432                            1,
433                            ShapeUnion,
434                            Unsorted);
435    if (_ecore_xlib_sync) ecore_x_sync();
436 #else
437    return;
438    win = x = y = w = h = 0;
439 #endif
440 }
441 
442 EAPI void
ecore_x_window_shape_rectangle_clip(Ecore_X_Window win,int x,int y,int w,int h)443 ecore_x_window_shape_rectangle_clip(Ecore_X_Window win,
444                                     int x,
445                                     int y,
446                                     int w,
447                                     int h)
448 {
449    XRectangle rect;
450 
451    LOGFN;
452    rect.x = x;
453    rect.y = y;
454    rect.width = w;
455    rect.height = h;
456    XShapeCombineRectangles(_ecore_x_disp,
457                            win,
458                            ShapeBounding,
459                            0,
460                            0,
461                            &rect,
462                            1,
463                            ShapeIntersect,
464                            Unsorted);
465    if (_ecore_xlib_sync) ecore_x_sync();
466 }
467 
468 EAPI void
ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win,int x,int y,int w,int h)469 ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win,
470                                           int x,
471                                           int y,
472                                           int w,
473                                           int h)
474 {
475 #ifdef ShapeInput
476    XRectangle rect;
477 
478    LOGFN;
479    rect.x = x;
480    rect.y = y;
481    rect.width = w;
482    rect.height = h;
483    XShapeCombineRectangles(_ecore_x_disp,
484                            win,
485                            ShapeInput,
486                            0,
487                            0,
488                            &rect,
489                            1,
490                            ShapeIntersect,
491                            Unsorted);
492    if (_ecore_xlib_sync) ecore_x_sync();
493 #else
494    return;
495    win = x = y = w = h = 0;
496 #endif
497 }
498 
499 EAPI void
ecore_x_window_shape_rectangles_add(Ecore_X_Window win,Ecore_X_Rectangle * rects,int num)500 ecore_x_window_shape_rectangles_add(Ecore_X_Window win,
501                                     Ecore_X_Rectangle *rects,
502                                     int num)
503 {
504    XRectangle *rect = NULL;
505    int i;
506 
507    LOGFN;
508    if (num > 0)
509      {
510         rect = malloc(sizeof(XRectangle) * num);
511         if (!rect) return;
512         for (i = 0; i < num; i++)
513           {
514              rect[i].x = rects[i].x;
515              rect[i].y = rects[i].y;
516              rect[i].width = rects[i].width;
517              rect[i].height = rects[i].height;
518           }
519      }
520 
521    XShapeCombineRectangles(_ecore_x_disp,
522                            win,
523                            ShapeBounding,
524                            0,
525                            0,
526                            rect,
527                            num,
528                            ShapeUnion,
529                            Unsorted);
530    if (_ecore_xlib_sync) ecore_x_sync();
531    if (rect) free(rect);
532 }
533 
534 EAPI void
ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win,Ecore_X_Rectangle * rects,int num)535 ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win,
536                                           Ecore_X_Rectangle *rects,
537                                           int num)
538 {
539 #ifdef ShapeInput
540    XRectangle *rect = NULL;
541    int i;
542 
543    LOGFN;
544    if (num > 0)
545      {
546         rect = malloc(sizeof(XRectangle) * num);
547         if (!rect) return;
548         for (i = 0; i < num; i++)
549           {
550              rect[i].x = rects[i].x;
551              rect[i].y = rects[i].y;
552              rect[i].width = rects[i].width;
553              rect[i].height = rects[i].height;
554           }
555      }
556 
557    XShapeCombineRectangles(_ecore_x_disp,
558                            win,
559                            ShapeInput,
560                            0,
561                            0,
562                            rect,
563                            num,
564                            ShapeUnion,
565                            Unsorted);
566    if (_ecore_xlib_sync) ecore_x_sync();
567    if (rect) free(rect);
568 #else
569    return;
570    win = rects = num = 0;
571 #endif
572 }
573 
574 EAPI Ecore_X_Rectangle *
ecore_x_window_shape_rectangles_get(Ecore_X_Window win,int * num_ret)575 ecore_x_window_shape_rectangles_get(Ecore_X_Window win,
576                                     int *num_ret)
577 {
578    XRectangle *rect;
579    Ecore_X_Rectangle *rects = NULL;
580    int i, num = 0, ord;
581 
582    LOGFN;
583    rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeBounding, &num, &ord);
584    if (_ecore_xlib_sync) ecore_x_sync();
585    if (rect)
586      {
587         if (num < 1)
588           {
589              XFree(rect);
590              if (num_ret) *num_ret = 0;
591              return NULL;
592           }
593         rects = malloc(sizeof(Ecore_X_Rectangle) * num);
594         if (!rects)
595           {
596              XFree(rect);
597              if (num_ret) *num_ret = 0;
598              return NULL;
599           }
600         for (i = 0; i < num; i++)
601           {
602              rects[i].x = rect[i].x;
603              rects[i].y = rect[i].y;
604              rects[i].width = rect[i].width;
605              rects[i].height = rect[i].height;
606           }
607         XFree(rect);
608      }
609    if (num_ret) *num_ret = num;
610    return rects;
611 }
612 
613 EAPI Ecore_X_Rectangle *
ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win,int * num_ret)614 ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win,
615                                           int *num_ret)
616 {
617    Ecore_X_Rectangle *rects = NULL;
618 #ifdef ShapeInput
619    XRectangle *rect;
620    int i, num = 0, ord;
621 
622    LOGFN;
623    rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeInput, &num, &ord);
624    if (_ecore_xlib_sync) ecore_x_sync();
625    if (rect)
626      {
627         if (num < 1)
628           {
629              XFree(rect);
630              if (num_ret) *num_ret = 0;
631              return NULL;
632           }
633         rects = malloc(sizeof(Ecore_X_Rectangle) * num);
634         if (!rects)
635           {
636              XFree(rect);
637              if (num_ret) *num_ret = 0;
638              return NULL;
639           }
640         for (i = 0; i < num; i++)
641           {
642              rects[i].x = rect[i].x;
643              rects[i].y = rect[i].y;
644              rects[i].width = rect[i].width;
645              rects[i].height = rect[i].height;
646           }
647         XFree(rect);
648      }
649    if (num_ret) *num_ret = num;
650    return rects;
651 #else
652    // have to return fake shape input rect of size of window
653    Window dw;
654    unsigned int di;
655 
656    if (num_ret) *num_ret = 0;
657    rects = malloc(sizeof(Ecore_X_Rectangle));
658    if (!rects) return NULL;
659    if (!XGetGeometry(_ecore_x_disp, win, &dw,
660                      &(rects[0].x), &(rects[0].y),
661                      &(rects[0].width), &(rects[0].height),
662                      &di, &di))
663      {
664         if (_ecore_xlib_sync) ecore_x_sync();
665         free(rects);
666         return NULL;
667      }
668       if (_ecore_xlib_sync) ecore_x_sync();
669    if (num_ret) *num_ret = 1;
670    return rects;
671 #endif
672 }
673 
674 EAPI void
ecore_x_window_shape_events_select(Ecore_X_Window win,Eina_Bool on)675 ecore_x_window_shape_events_select(Ecore_X_Window win,
676                                    Eina_Bool on)
677 {
678    LOGFN;
679    if (on)
680      XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
681    else
682      XShapeSelectInput(_ecore_x_disp, win, 0);
683       if (_ecore_xlib_sync) ecore_x_sync();
684 }
685 
686