gdkgeometry-directfb.c 8.16 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GTK+ Team.
 */

/*
 * GTK+ DirectFB backend
 * Copyright (C) 2001-2002  convergence integrated media GmbH
 * Copyright (C) 2002-2004  convergence GmbH
 * Written by Denis Oliver Kropp <dok@convergence.de> and
 *            Sven Neumann <sven@convergence.de>
 */

#include "config.h"
#include "gdk.h"        /* For gdk_rectangle_intersect */

#include "gdkdirectfb.h"
#include "gdkprivate-directfb.h"

#include "gdkinternals.h"
#include "gdkalias.h"


void
44 45 46
_gdk_directfb_window_get_offsets (GdkWindow *window,
                                  gint      *x_offset,
                                  gint      *y_offset)
47 48 49 50 51 52 53 54 55
{
  if (x_offset)
    *x_offset = 0;
  if (y_offset)
    *y_offset = 0;
}

gboolean
_gdk_windowing_window_queue_antiexpose (GdkWindow *window,
56
                                        cairo_region_t *area)
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
{
  return FALSE;
}

/**
 * gdk_window_scroll:
 * @window: a #GdkWindow
 * @dx: Amount to scroll in the X direction
 * @dy: Amount to scroll in the Y direction
 *
 * Scroll the contents of its window, both pixels and children, by
 * the given amount. Portions of the window that the scroll operation
 * brings in from offscreen areas are invalidated.
 **/
void
72 73 74
_gdk_directfb_window_scroll (GdkWindow *window,
                             gint       dx,
                             gint       dy)
75 76 77
{
  GdkWindowObject         *private;
  GdkDrawableImplDirectFB *impl;
78
  cairo_region_t               *invalidate_region = NULL;
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
  GList                   *list;

  g_return_if_fail (GDK_IS_WINDOW (window));

  if (GDK_WINDOW_DESTROYED (window))
    return;

  private = GDK_WINDOW_OBJECT (window);
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);

  if (dx == 0 && dy == 0)
    return;

  /* Move the current invalid region */
  if (private->update_area)
Benjamin Otte's avatar
Benjamin Otte committed
94
    cairo_region_translate (private->update_area, dx, dy);
95 96 97 98 99 100

  if (GDK_WINDOW_IS_MAPPED (window))
    {
      GdkRectangle  clip_rect = {  0,  0, impl->width, impl->height };
      GdkRectangle  rect      = { dx, dy, impl->width, impl->height };

Benjamin Otte's avatar
Benjamin Otte committed
101
      invalidate_region = cairo_region_create_rectangle (&clip_rect);
102 103 104

      if (gdk_rectangle_intersect (&rect, &clip_rect, &rect) &&
          (!private->update_area ||
Benjamin Otte's avatar
Benjamin Otte committed
105
           !cairo_region_contains_rectangle (private->update_area, &rect)))
106
        {
107
          cairo_region_t *region;
108

Benjamin Otte's avatar
Benjamin Otte committed
109 110 111
          region = cairo_region_create_rectangle (&rect);
          cairo_region_subtract (invalidate_region, region);
          cairo_region_destroy (region);
112 113 114 115 116 117 118 119 120 121

          if (impl->surface)
            {
              DFBRegion update = { rect.x, rect.y,
                                   rect.x + rect.width  - 1,
                                   rect.y + rect.height - 1 };

              impl->surface->SetClip (impl->surface, &update);
              impl->surface->Blit (impl->surface, impl->surface, NULL, dx, dy);
              impl->surface->SetClip (impl->surface, NULL);
122
              impl->surface->Flip(impl->surface,&update,0);
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
            }
        }
    }

  for (list = private->children; list; list = list->next)
    {
      GdkWindowObject         *obj      = GDK_WINDOW_OBJECT (list->data);
      GdkDrawableImplDirectFB *obj_impl = GDK_DRAWABLE_IMPL_DIRECTFB (obj->impl);

      _gdk_directfb_move_resize_child (list->data,
                                       obj->x + dx,
                                       obj->y + dy,
                                       obj_impl->width,
                                       obj_impl->height);
    }

  _gdk_directfb_calc_abs (window);

  if (invalidate_region)
    {
      gdk_window_invalidate_region (window, invalidate_region, TRUE);
Benjamin Otte's avatar
Benjamin Otte committed
144
      cairo_region_destroy (invalidate_region);
145 146 147 148 149 150
    }
}

/**
 * gdk_window_move_region:
 * @window: a #GdkWindow
151
 * @region: The #cairo_region_t to move
152 153 154 155 156 157 158 159 160 161 162 163
 * @dx: Amount to move in the X direction
 * @dy: Amount to move in the Y direction
 * 
 * Move the part of @window indicated by @region by @dy pixels in the Y 
 * direction and @dx pixels in the X direction. The portions of @region 
 * that not covered by the new position of @region are invalidated.
 * 
 * Child windows are not moved.
 * 
 * Since: 2.8
 **/
void
164
_gdk_directfb_window_move_region (GdkWindow       *window,
165
                                  const cairo_region_t *region,
166 167
                                  gint             dx,
                                  gint             dy)
168 169 170
{
  GdkWindowObject         *private;
  GdkDrawableImplDirectFB *impl;
171 172 173 174 175
  cairo_region_t *window_clip;
  cairo_region_t *src_region;
  cairo_region_t *brought_in;
  cairo_region_t *dest_region;
  cairo_region_t *moving_invalid_region;
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
  GdkRectangle dest_extents;
  
  g_return_if_fail (GDK_IS_WINDOW (window));
  g_return_if_fail (region != NULL);
  
  if (GDK_WINDOW_DESTROYED (window))
    return;
  
  private = GDK_WINDOW_OBJECT (window);
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);  

  if (dx == 0 && dy == 0)
    return;

  GdkRectangle  clip_rect = {  0,  0, impl->width, impl->height };
Benjamin Otte's avatar
Benjamin Otte committed
191
  window_clip = cairo_region_create_rectangle (&clip_rect);
192 193

  /* compute source regions */
Benjamin Otte's avatar
Benjamin Otte committed
194 195 196
  src_region = cairo_region_copy (region);
  brought_in = cairo_region_copy (region);
  cairo_region_intersect (src_region, window_clip);
197

Benjamin Otte's avatar
Benjamin Otte committed
198 199
  cairo_region_subtract (brought_in, src_region);
  cairo_region_translate (brought_in, dx, dy);
200 201

  /* compute destination regions */
Benjamin Otte's avatar
Benjamin Otte committed
202 203 204 205
  dest_region = cairo_region_copy (src_region);
  cairo_region_translate (dest_region, dx, dy);
  cairo_region_intersect (dest_region, window_clip);
  cairo_region_get_extents (dest_region, &dest_extents);
206

Benjamin Otte's avatar
Benjamin Otte committed
207
  cairo_region_destroy (window_clip);
208 209 210 211 212

  /* calculating moving part of current invalid area */
  moving_invalid_region = NULL;
  if (private->update_area)
    {
Benjamin Otte's avatar
Benjamin Otte committed
213 214 215
      moving_invalid_region = cairo_region_copy (private->update_area);
      cairo_region_intersect (moving_invalid_region, src_region);
      cairo_region_translate (moving_invalid_region, dx, dy);
216 217 218 219 220 221 222
    }
  
  /* invalidate all of the src region */
  gdk_window_invalidate_region (window, src_region, FALSE);

  /* un-invalidate destination region */
  if (private->update_area)
Benjamin Otte's avatar
Benjamin Otte committed
223
    cairo_region_subtract (private->update_area, dest_region);
224 225 226 227 228
  
  /* invalidate moving parts of existing update area */
  if (moving_invalid_region)
    {
      gdk_window_invalidate_region (window, moving_invalid_region, FALSE);
Benjamin Otte's avatar
Benjamin Otte committed
229
      cairo_region_destroy (moving_invalid_region);
230 231 232 233
    }

  /* invalidate area brought in from off-screen */
  gdk_window_invalidate_region (window, brought_in, FALSE);
Benjamin Otte's avatar
Benjamin Otte committed
234
  cairo_region_destroy (brought_in);
235 236 237 238 239

  /* Actually do the moving */
	if (impl->surface)
	{
    	DFBRectangle source = { dest_extents.x - dx, 
240
					    dest_extents.y - dy,
241 242 243
                             dest_extents.width,
                             dest_extents.height};
    	DFBRegion destination = { dest_extents.x, 
244 245 246
						 dest_extents.y,
                             	 dest_extents.x+dest_extents.width-1,
                             	 dest_extents.y+dest_extents.height-1};
247 248 249 250

              impl->surface->SetClip (impl->surface, &destination);
              impl->surface->Blit (impl->surface, impl->surface,&source,dx,dy);
              impl->surface->SetClip (impl->surface, NULL);
251
              impl->surface->Flip(impl->surface,&destination,0);
252
	}
Benjamin Otte's avatar
Benjamin Otte committed
253 254
  cairo_region_destroy (src_region);
  cairo_region_destroy (dest_region);
255 256 257 258
}

#define __GDK_GEOMETRY_X11_C__
#include "gdkaliasdef.c"