]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkregion-x11.c
When actually returning expose events, make sure to set the count field
[~andy/gtk] / gdk / x11 / gdkregion-x11.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29 #include "gdkprivate-x11.h"
30
31 GdkRegion*
32 gdk_region_new (void)
33 {
34   GdkRegionPrivate *private;
35   GdkRegion *region;
36   Region xregion;
37
38   xregion = XCreateRegion();
39   private = g_new (GdkRegionPrivate, 1);
40   private->xregion = xregion;
41   region = (GdkRegion*) private;
42   region->user_data = NULL;
43
44   return region;
45 }
46
47 void
48 gdk_region_destroy (GdkRegion *region)
49 {
50   GdkRegionPrivate *private;
51
52   g_return_if_fail (region != NULL);
53
54   private = (GdkRegionPrivate *) region;
55   XDestroyRegion (private->xregion);
56
57   g_free (private);
58 }
59
60 gboolean
61 gdk_region_empty (GdkRegion      *region)
62 {
63   GdkRegionPrivate *private;
64
65   g_return_val_if_fail (region != NULL, 0);
66
67   private = (GdkRegionPrivate *) region;
68   
69   return XEmptyRegion (private->xregion);
70 }
71
72 gboolean
73 gdk_region_equal (GdkRegion      *region1,
74                   GdkRegion      *region2)
75 {
76   GdkRegionPrivate *private1;
77   GdkRegionPrivate *private2;
78
79   g_return_val_if_fail (region1 != NULL, 0);
80   g_return_val_if_fail (region2 != NULL, 0);
81
82   private1 = (GdkRegionPrivate *) region1;
83   private2 = (GdkRegionPrivate *) region2;
84   
85   return XEqualRegion (private1->xregion, private2->xregion);
86 }
87
88 void
89 gdk_region_get_clipbox(GdkRegion    *region,
90                        GdkRectangle *rectangle)
91 {
92   GdkRegionPrivate *rp;
93   XRectangle r;
94   
95   g_return_if_fail(region != NULL);
96   g_return_if_fail(rectangle != NULL);
97   
98   rp = (GdkRegionPrivate *)region;
99   XClipBox(rp->xregion, &r);
100   
101   rectangle->x = r.x;
102   rectangle->y = r.y;   
103   rectangle->width = r.width;
104   rectangle->height = r.height;
105 }
106
107 gboolean
108 gdk_region_point_in (GdkRegion      *region,
109                      gint           x,
110                      gint           y)
111 {
112   GdkRegionPrivate *private;
113
114   g_return_val_if_fail (region != NULL, 0);
115
116   private = (GdkRegionPrivate *) region;
117   
118   return XPointInRegion (private->xregion, x, y);
119 }
120
121 GdkOverlapType
122 gdk_region_rect_in (GdkRegion      *region,
123                     GdkRectangle   *rect)
124 {
125   GdkRegionPrivate *private;
126   int res;
127
128   g_return_val_if_fail (region != NULL, 0);
129
130   private = (GdkRegionPrivate *) region;
131   
132   res = XRectInRegion (private->xregion, rect->x, rect->y, rect->width, rect->height);
133   
134   switch (res)
135   {
136     case RectangleIn:   return GDK_OVERLAP_RECTANGLE_IN;
137     case RectangleOut:  return GDK_OVERLAP_RECTANGLE_OUT;
138     case RectanglePart: return GDK_OVERLAP_RECTANGLE_PART;
139   }
140   
141   return GDK_OVERLAP_RECTANGLE_OUT;  /*what else ? */
142 }
143                                     
144 GdkRegion *
145 gdk_region_polygon (GdkPoint    *points,
146                     gint         npoints,
147                     GdkFillRule  fill_rule)
148 {
149   GdkRegionPrivate *private;
150   GdkRegion *region;
151   Region xregion;
152   gint xfill_rule = EvenOddRule;
153
154   g_return_val_if_fail (points != NULL, NULL);
155   g_return_val_if_fail (npoints != 0, NULL); /* maybe we should check for at least three points */
156
157   switch (fill_rule)
158     {
159     case GDK_EVEN_ODD_RULE:
160       xfill_rule = EvenOddRule;
161       break;
162
163     case GDK_WINDING_RULE:
164       xfill_rule = WindingRule;
165       break;
166     }
167
168   xregion = XPolygonRegion ((XPoint *) points, npoints, xfill_rule);
169   private = g_new (GdkRegionPrivate, 1);
170   private->xregion = xregion;
171   region = (GdkRegion *) private;
172   region->user_data = NULL;
173
174   return region;
175 }
176
177 void          
178 gdk_region_offset (GdkRegion      *region,
179                    gint           dx,
180                    gint           dy)
181 {
182   GdkRegionPrivate *private;
183
184   g_return_if_fail (region != NULL);
185
186   private = (GdkRegionPrivate *) region;
187   
188   XOffsetRegion (private->xregion, dx, dy);
189 }
190
191 void
192 gdk_region_shrink (GdkRegion      *region,
193                    gint           dx,
194                    gint           dy)
195 {
196   GdkRegionPrivate *private;
197
198   g_return_if_fail (region != NULL);
199
200   private = (GdkRegionPrivate *) region;
201   
202   XShrinkRegion (private->xregion, dx, dy);
203 }
204
205 GdkRegion*    
206 gdk_region_union_with_rect (GdkRegion      *region,
207                             GdkRectangle   *rect)
208 {
209   GdkRegionPrivate *private;
210   GdkRegion *res;
211   GdkRegionPrivate *res_private;
212   XRectangle xrect;
213
214   g_return_val_if_fail (region != NULL, NULL);
215
216   private = (GdkRegionPrivate *) region;
217   
218   xrect.x = rect->x;
219   xrect.y = rect->y;
220   xrect.width = rect->width;
221   xrect.height = rect->height;
222   
223   res = gdk_region_new ();
224   res_private = (GdkRegionPrivate *) res;
225   
226   XUnionRectWithRegion (&xrect, private->xregion, res_private->xregion);
227   
228   return res;
229 }
230
231 GdkRegion*    
232 gdk_regions_intersect (GdkRegion      *source1,
233                        GdkRegion      *source2)
234 {
235   GdkRegionPrivate *private1;
236   GdkRegionPrivate *private2;
237   GdkRegion *res;
238   GdkRegionPrivate *res_private;
239
240   g_return_val_if_fail (source1 != NULL, NULL);
241   g_return_val_if_fail (source2 != NULL, NULL);
242
243   private1 = (GdkRegionPrivate *) source1;
244   private2 = (GdkRegionPrivate *) source2;
245
246   res = gdk_region_new ();
247   res_private = (GdkRegionPrivate *) res;
248   
249   XIntersectRegion (private1->xregion, private2->xregion, res_private->xregion);
250   
251   return res;
252 }
253
254 GdkRegion* 
255 gdk_regions_union (GdkRegion      *source1,
256                    GdkRegion      *source2)
257 {
258   GdkRegionPrivate *private1;
259   GdkRegionPrivate *private2;
260   GdkRegion *res;
261   GdkRegionPrivate *res_private;
262
263   g_return_val_if_fail (source1 != NULL, NULL);
264   g_return_val_if_fail (source2 != NULL, NULL);
265
266   private1 = (GdkRegionPrivate *) source1;
267   private2 = (GdkRegionPrivate *) source2;
268
269   res = gdk_region_new ();
270   res_private = (GdkRegionPrivate *) res;
271   
272   XUnionRegion (private1->xregion, private2->xregion, res_private->xregion);
273   
274   return res;
275 }
276
277 GdkRegion*    
278 gdk_regions_subtract (GdkRegion      *source1,
279                       GdkRegion      *source2)
280 {
281   GdkRegionPrivate *private1;
282   GdkRegionPrivate *private2;
283   GdkRegion *res;
284   GdkRegionPrivate *res_private;
285
286   g_return_val_if_fail (source1 != NULL, NULL);
287   g_return_val_if_fail (source2 != NULL, NULL);
288
289   private1 = (GdkRegionPrivate *) source1;
290   private2 = (GdkRegionPrivate *) source2;
291
292   res = gdk_region_new ();
293   res_private = (GdkRegionPrivate *) res;
294   
295   XSubtractRegion (private1->xregion, private2->xregion, res_private->xregion);
296   
297   return res;
298 }
299
300 GdkRegion*    
301 gdk_regions_xor (GdkRegion      *source1,
302                  GdkRegion      *source2)
303 {
304   GdkRegionPrivate *private1;
305   GdkRegionPrivate *private2;
306   GdkRegion *res;
307   GdkRegionPrivate *res_private;
308
309   g_return_val_if_fail (source1 != NULL, NULL);
310   g_return_val_if_fail (source2 != NULL, NULL);
311
312   private1 = (GdkRegionPrivate *) source1;
313   private2 = (GdkRegionPrivate *) source2;
314
315   res = gdk_region_new ();
316   res_private = (GdkRegionPrivate *) res;
317   
318   XXorRegion (private1->xregion, private2->xregion, res_private->xregion);
319   
320   return res;
321 }
322
323
324