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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.
23  */
24 
25 /*
26  * GTK+ DirectFB backend
27  * Copyright (C) 2001-2002  convergence integrated media GmbH
28  * Copyright (C) 2002-2004  convergence GmbH
29  * Written by Denis Oliver Kropp <dok@convergence.de> and
30  *            Sven Neumann <sven@convergence.de>
31  */
32 
33 #include "config.h"
34 #include "gdk.h"        /* For gdk_rectangle_intersect */
35 
36 #include "gdkdirectfb.h"
37 #include "gdkprivate-directfb.h"
38 
39 #include "gdkinternals.h"
40 #include "gdkalias.h"
41 
42 
43 void
_gdk_directfb_window_get_offsets(GdkWindow * window,gint * x_offset,gint * y_offset)44 _gdk_directfb_window_get_offsets (GdkWindow *window,
45                                   gint      *x_offset,
46                                   gint      *y_offset)
47 {
48   if (x_offset)
49     *x_offset = 0;
50   if (y_offset)
51     *y_offset = 0;
52 }
53 
54 gboolean
_gdk_windowing_window_queue_antiexpose(GdkWindow * window,GdkRegion * area)55 _gdk_windowing_window_queue_antiexpose (GdkWindow *window,
56                                         GdkRegion *area)
57 {
58   return FALSE;
59 }
60 
61 /**
62  * gdk_window_scroll:
63  * @window: a #GdkWindow
64  * @dx: Amount to scroll in the X direction
65  * @dy: Amount to scroll in the Y direction
66  *
67  * Scroll the contents of its window, both pixels and children, by
68  * the given amount. Portions of the window that the scroll operation
69  * brings in from offscreen areas are invalidated.
70  **/
71 void
_gdk_directfb_window_scroll(GdkWindow * window,gint dx,gint dy)72 _gdk_directfb_window_scroll (GdkWindow *window,
73                              gint       dx,
74                              gint       dy)
75 {
76   GdkWindowObject         *private;
77   GdkDrawableImplDirectFB *impl;
78   GdkRegion               *invalidate_region = NULL;
79   GList                   *list;
80 
81   g_return_if_fail (GDK_IS_WINDOW (window));
82 
83   if (GDK_WINDOW_DESTROYED (window))
84     return;
85 
86   private = GDK_WINDOW_OBJECT (window);
87   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
88 
89   if (dx == 0 && dy == 0)
90     return;
91 
92   /* Move the current invalid region */
93   if (private->update_area)
94     gdk_region_offset (private->update_area, dx, dy);
95 
96   if (GDK_WINDOW_IS_MAPPED (window))
97     {
98       GdkRectangle  clip_rect = {  0,  0, impl->width, impl->height };
99       GdkRectangle  rect      = { dx, dy, impl->width, impl->height };
100 
101       invalidate_region = gdk_region_rectangle (&clip_rect);
102 
103       if (gdk_rectangle_intersect (&rect, &clip_rect, &rect) &&
104           (!private->update_area ||
105            !gdk_region_rect_in (private->update_area, &rect)))
106         {
107           GdkRegion *region;
108 
109           region = gdk_region_rectangle (&rect);
110           gdk_region_subtract (invalidate_region, region);
111           gdk_region_destroy (region);
112 
113           if (impl->surface)
114             {
115               DFBRegion update = { rect.x, rect.y,
116                                    rect.x + rect.width  - 1,
117                                    rect.y + rect.height - 1 };
118 
119               impl->surface->SetClip (impl->surface, &update);
120               impl->surface->Blit (impl->surface, impl->surface, NULL, dx, dy);
121               impl->surface->SetClip (impl->surface, NULL);
122               impl->surface->Flip (impl->surface, &update, 0);
123             }
124         }
125     }
126 
127   for (list = private->children; list; list = list->next)
128     {
129       GdkWindowObject         *obj      = GDK_WINDOW_OBJECT (list->data);
130       GdkDrawableImplDirectFB *obj_impl = GDK_DRAWABLE_IMPL_DIRECTFB (obj->impl);
131 
132       _gdk_directfb_move_resize_child (list->data,
133                                        obj->x + dx,
134                                        obj->y + dy,
135                                        obj_impl->width,
136                                        obj_impl->height);
137     }
138 
139   if (invalidate_region)
140     {
141       gdk_window_invalidate_region (window, invalidate_region, TRUE);
142       gdk_region_destroy (invalidate_region);
143     }
144 }
145 
146 /**
147  * gdk_window_move_region:
148  * @window: a #GdkWindow
149  * @region: The #GdkRegion to move
150  * @dx: Amount to move in the X direction
151  * @dy: Amount to move in the Y direction
152  *
153  * Move the part of @window indicated by @region by @dy pixels in the Y
154  * direction and @dx pixels in the X direction. The portions of @region
155  * that not covered by the new position of @region are invalidated.
156  *
157  * Child windows are not moved.
158  *
159  * Since: 2.8
160  **/
161 void
_gdk_directfb_window_move_region(GdkWindow * window,const GdkRegion * region,gint dx,gint dy)162 _gdk_directfb_window_move_region (GdkWindow       *window,
163                                   const GdkRegion *region,
164                                   gint             dx,
165                                   gint             dy)
166 {
167   GdkWindowObject         *private;
168   GdkDrawableImplDirectFB *impl;
169   GdkRegion               *window_clip;
170   GdkRegion               *src_region;
171   GdkRegion               *brought_in;
172   GdkRegion               *dest_region;
173   GdkRegion               *moving_invalid_region;
174   GdkRectangle             dest_extents;
175 
176   g_return_if_fail (GDK_IS_WINDOW (window));
177   g_return_if_fail (region != NULL);
178 
179   if (GDK_WINDOW_DESTROYED (window))
180     return;
181 
182   private = GDK_WINDOW_OBJECT (window);
183   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
184 
185   if (dx == 0 && dy == 0)
186     return;
187 
188   GdkRectangle  clip_rect = {  0,  0, impl->width, impl->height };
189   window_clip = gdk_region_rectangle (&clip_rect);
190 
191   /* compute source regions */
192   src_region = gdk_region_copy (region);
193   brought_in = gdk_region_copy (region);
194   gdk_region_intersect (src_region, window_clip);
195 
196   gdk_region_subtract (brought_in, src_region);
197   gdk_region_offset (brought_in, dx, dy);
198 
199   /* compute destination regions */
200   dest_region = gdk_region_copy (src_region);
201   gdk_region_offset (dest_region, dx, dy);
202   gdk_region_intersect (dest_region, window_clip);
203   gdk_region_get_clipbox (dest_region, &dest_extents);
204 
205   gdk_region_destroy (window_clip);
206 
207   /* calculating moving part of current invalid area */
208   moving_invalid_region = NULL;
209   if (private->update_area)
210     {
211       moving_invalid_region = gdk_region_copy (private->update_area);
212       gdk_region_intersect (moving_invalid_region, src_region);
213       gdk_region_offset (moving_invalid_region, dx, dy);
214     }
215 
216   /* invalidate all of the src region */
217   gdk_window_invalidate_region (window, src_region, FALSE);
218 
219   /* un-invalidate destination region */
220   if (private->update_area)
221     gdk_region_subtract (private->update_area, dest_region);
222 
223   /* invalidate moving parts of existing update area */
224   if (moving_invalid_region)
225     {
226       gdk_window_invalidate_region (window, moving_invalid_region, FALSE);
227       gdk_region_destroy (moving_invalid_region);
228     }
229 
230   /* invalidate area brought in from off-screen */
231   gdk_window_invalidate_region (window, brought_in, FALSE);
232   gdk_region_destroy (brought_in);
233 
234   /* Actually do the moving */
235   if (impl->surface)
236     {
237       DFBRectangle source = { dest_extents.x - dx,
238                               dest_extents.y - dy,
239                               dest_extents.width,
240                               dest_extents.height};
241       DFBRegion destination = { dest_extents.x,
242                                 dest_extents.y,
243                                 dest_extents.x + dest_extents.width - 1,
244                                 dest_extents.y + dest_extents.height - 1};
245 
246       impl->surface->SetClip (impl->surface, &destination);
247       impl->surface->Blit (impl->surface, impl->surface, &source, dx, dy);
248       impl->surface->SetClip (impl->surface, NULL);
249       impl->surface->Flip (impl->surface, &destination, 0);
250     }
251   gdk_region_destroy (src_region);
252   gdk_region_destroy (dest_region);
253 }
254 
255 #define __GDK_GEOMETRY_X11_C__
256 #include "gdkaliasdef.c"
257