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