]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkoffscreenwindow.c
gdk: Implement end_implicit_paint() with Cairo
[~andy/gtk] / gdk / gdkoffscreenwindow.c
index 26222357f2fe9a5421d81f84a1f8275af436e637..a21ad163a0097b4e2f7b4c88bad8ed78711ddce4 100644 (file)
@@ -37,7 +37,7 @@
 #include "gdkgc.h"
 #include "gdkcolor.h"
 #include "gdkcursor.h"
-#include "gdkalias.h"
+
 
 /* LIMITATIONS:
  *
@@ -151,26 +151,6 @@ gdk_offscreen_window_create_gc (GdkDrawable     *drawable,
   return gdk_gc_new_with_values (offscreen->pixmap, values, values_mask);
 }
 
-static GdkImage*
-gdk_offscreen_window_copy_to_image (GdkDrawable    *drawable,
-                                   GdkImage       *image,
-                                   gint            src_x,
-                                   gint            src_y,
-                                   gint            dest_x,
-                                   gint            dest_y,
-                                   gint            width,
-                                   gint            height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  return gdk_drawable_copy_to_image (offscreen->pixmap,
-                                    image,
-                                    src_x,
-                                    src_y,
-                                    dest_x, dest_y,
-                                    width, height);
-}
-
 static cairo_surface_t *
 gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
 {
@@ -257,19 +237,40 @@ gdk_offscreen_window_get_visual (GdkDrawable    *drawable)
 static void
 add_damage (GdkOffscreenWindow *offscreen,
            int x, int y,
-           int w, int h)
+           int w, int h,
+           gboolean is_line)
 {
   GdkRectangle rect;
-  GdkRegion *damage;
+  cairo_region_t *damage;
 
   rect.x = x;
   rect.y = y;
   rect.width = w;
   rect.height = h;
 
-  damage = gdk_region_rectangle (&rect);
+  if (is_line)
+    {
+      /* This should really take into account line width, line
+       * joins (and miter) and line caps. But these are hard
+       * to compute, rarely used and generally a pain. And in
+       * the end a snug damage rectangle is not that important
+       * as multiple damages are generally created anyway.
+       *
+       * So, we just add some padding around the rect.
+       * We use a padding of 3 pixels, plus an extra row
+       * below and on the right for the normal line size. I.E.
+       * line from (0,0) to (2,0) gets h=0 but is really
+       * at least one pixel tall.
+       */
+      rect.x -= 3;
+      rect.y -= 3;
+      rect.width += 7;
+      rect.height += 7;
+    }
+
+  damage = cairo_region_create_rectangle (&rect);
   _gdk_window_add_damage (offscreen->wrapper, damage);
-  gdk_region_destroy (damage);
+  cairo_region_destroy (damage);
 }
 
 static GdkDrawable *
@@ -300,298 +301,7 @@ gdk_offscreen_window_draw_drawable (GdkDrawable *drawable,
                     xdest, ydest,
                     width, height);
 
-  add_damage (offscreen, xdest, ydest, width, height);
-}
-
-static void
-gdk_offscreen_window_draw_rectangle (GdkDrawable  *drawable,
-                                    GdkGC        *gc,
-                                    gboolean      filled,
-                                    gint          x,
-                                    gint          y,
-                                    gint          width,
-                                    gint          height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_rectangle (real_drawable,
-                     gc, filled, x, y, width, height);
-
-  add_damage (offscreen, x, y, width, height);
-
-}
-
-static void
-gdk_offscreen_window_draw_arc (GdkDrawable  *drawable,
-                              GdkGC           *gc,
-                              gboolean filled,
-                              gint             x,
-                              gint             y,
-                              gint             width,
-                              gint             height,
-                              gint             angle1,
-                              gint             angle2)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_arc (real_drawable,
-               gc,
-               filled,
-               x,
-               y,
-               width,
-               height,
-               angle1,
-               angle2);
-  add_damage (offscreen, x, y, width, height);
-}
-
-static void
-gdk_offscreen_window_draw_polygon (GdkDrawable  *drawable,
-                                  GdkGC               *gc,
-                                  gboolean     filled,
-                                  GdkPoint     *points,
-                                  gint         npoints)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_polygon (real_drawable,
-                   gc,
-                   filled,
-                   points,
-                   npoints);
-
-  if (npoints > 0)
-    {
-      int min_x, min_y, max_x, max_y, i;
-
-      min_x = max_x = points[0].x;
-      min_y = max_y = points[0].y;
-
-       for (i = 1; i < npoints; i++)
-         {
-           min_x = MIN (min_x, points[i].x);
-           max_x = MAX (max_x, points[i].x);
-           min_y = MIN (min_y, points[i].y);
-           max_y = MAX (max_y, points[i].y);
-         }
-
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
-}
-
-static void
-gdk_offscreen_window_draw_text (GdkDrawable  *drawable,
-                               GdkFont      *font,
-                               GdkGC          *gc,
-                               gint            x,
-                               gint            y,
-                               const gchar  *text,
-                               gint            text_length)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_text (real_drawable,
-                font,
-                gc,
-                x,
-                y,
-                text,
-                text_length);
-
-  /* Hard to compute the minimal size, not that often used anyway. */
-  add_damage (offscreen, 0, 0, private->width, private->height);
-}
-
-static void
-gdk_offscreen_window_draw_text_wc (GdkDrawable  *drawable,
-                                  GdkFont       *font,
-                                  GdkGC                 *gc,
-                                  gint           x,
-                                  gint           y,
-                                  const GdkWChar *text,
-                                  gint           text_length)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_text_wc (real_drawable,
-                   font,
-                   gc,
-                   x,
-                   y,
-                   text,
-                   text_length);
-
-  /* Hard to compute the minimal size, not that often used anyway. */
-  add_damage (offscreen, 0, 0, private->width, private->height);
-}
-
-static void
-gdk_offscreen_window_draw_points (GdkDrawable  *drawable,
-                                 GdkGC        *gc,
-                                 GdkPoint     *points,
-                                 gint          npoints)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_points (real_drawable,
-                  gc,
-                  points,
-                  npoints);
-
-
-  if (npoints > 0)
-    {
-      int min_x, min_y, max_x, max_y, i;
-
-      min_x = max_x = points[0].x;
-      min_y = max_y = points[0].y;
-
-       for (i = 1; i < npoints; i++)
-         {
-           min_x = MIN (min_x, points[i].x);
-           max_x = MAX (max_x, points[i].x);
-           min_y = MIN (min_y, points[i].y);
-           max_y = MAX (max_y, points[i].y);
-         }
-
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
-}
-
-static void
-gdk_offscreen_window_draw_segments (GdkDrawable  *drawable,
-                                   GdkGC        *gc,
-                                   GdkSegment   *segs,
-                                   gint          nsegs)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_segments (real_drawable,
-                    gc,
-                    segs,
-                    nsegs);
-
-  if (nsegs > 0)
-    {
-      int min_x, min_y, max_x, max_y, i;
-
-      min_x = max_x = segs[0].x1;
-      min_y = max_y = segs[0].y1;
-
-       for (i = 1; i < nsegs; i++)
-         {
-           min_x = MIN (min_x, segs[i].x1);
-           max_x = MAX (max_x, segs[i].x1);
-           min_x = MIN (min_x, segs[i].x2);
-           max_x = MAX (max_x, segs[i].x2);
-           min_y = MIN (min_y, segs[i].y1);
-           max_y = MAX (max_y, segs[i].y1);
-           min_y = MIN (min_y, segs[i].y2);
-           max_y = MAX (max_y, segs[i].y2);
-         }
-
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
-
-}
-
-static void
-gdk_offscreen_window_draw_lines (GdkDrawable  *drawable,
-                                GdkGC        *gc,
-                                GdkPoint     *points,
-                                gint          npoints)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_lines (real_drawable,
-                 gc,
-                 points,
-                 npoints);
-
-  /* Hard to compute the minimal size, as we don't know the line
-     width, and since joins are hard to calculate.
-     Its not that often used anyway, damage it all */
-  add_damage (offscreen, 0, 0, private->width, private->height);
-}
-
-static void
-gdk_offscreen_window_draw_image (GdkDrawable *drawable,
-                                GdkGC        *gc,
-                                GdkImage    *image,
-                                gint          xsrc,
-                                gint          ysrc,
-                                gint          xdest,
-                                gint          ydest,
-                                gint          width,
-                                gint          height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_image (real_drawable,
-                 gc,
-                 image,
-                 xsrc,
-                 ysrc,
-                 xdest,
-                 ydest,
-                 width,
-                 height);
-
-  add_damage (offscreen, xdest, ydest, width, height);
-}
-
-
-static void
-gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable,
-                                 GdkGC       *gc,
-                                 GdkPixbuf   *pixbuf,
-                                 gint         src_x,
-                                 gint         src_y,
-                                 gint         dest_x,
-                                 gint         dest_y,
-                                 gint         width,
-                                 gint         height,
-                                 GdkRgbDither dither,
-                                 gint         x_dither,
-                                 gint         y_dither)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_pixbuf (real_drawable,
-                  gc,
-                  pixbuf,
-                  src_x,
-                  src_y,
-                  dest_x,
-                  dest_y,
-                  width,
-                  height,
-                  dither,
-                  x_dither,
-                  y_dither);
-
-  add_damage (offscreen, dest_x, dest_y, width, height);
-
+  add_damage (offscreen, xdest, ydest, width, height, FALSE);
 }
 
 void
@@ -637,6 +347,7 @@ _gdk_offscreen_window_new (GdkWindow     *window,
                                      private->width,
                                      private->height,
                                      private->depth);
+  gdk_drawable_set_colormap (offscreen->pixmap, offscreen->colormap);
 }
 
 static gboolean
@@ -788,10 +499,11 @@ gdk_offscreen_window_get_deskrelative_origin (GdkWindow *window,
 }
 
 static gboolean
-gdk_offscreen_window_get_pointer (GdkWindow       *window,
-                                 gint            *x,
-                                 gint            *y,
-                                 GdkModifierType *mask)
+gdk_offscreen_window_get_device_state (GdkWindow       *window,
+                                       GdkDevice       *device,
+                                       gint            *x,
+                                       gint            *y,
+                                       GdkModifierType *mask)
 {
   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
   GdkOffscreenWindow *offscreen;
@@ -806,7 +518,7 @@ gdk_offscreen_window_get_pointer (GdkWindow       *window,
   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
   if (offscreen->embedder != NULL)
     {
-      gdk_window_get_pointer (offscreen->embedder, &tmpx, &tmpy, &tmpmask);
+      gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
       from_embedder (window,
                     tmpx, tmpy,
                     &dtmpx, &dtmpy);
@@ -899,6 +611,8 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
   if (private->width != width ||
       private->height != height)
     {
+      cairo_t *cr;
+
       private->width = width;
       private->height = height;
 
@@ -908,13 +622,10 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
                                          height,
                                          private->depth);
 
-      gc = _gdk_drawable_get_scratch_gc (offscreen->pixmap, FALSE);
-      gdk_draw_drawable (offscreen->pixmap,
-                        gc,
-                        old_pixmap,
-                        0,0, 0, 0,
-                        -1, -1);
-      g_object_unref (old_pixmap);
+      cr = gdk_cairo_create (offscreen->pixmap);
+      gdk_cairo_set_source_pixmap (cr, old_pixmap, 0, 0);
+      cairo_paint (cr);
+      cairo_destroy (cr);
     }
 
   if (GDK_WINDOW_IS_MAPPED (private))
@@ -1065,7 +776,7 @@ gdk_offscreen_window_set_back_pixmap (GdkWindow *window,
 
 static void
 gdk_offscreen_window_shape_combine_region (GdkWindow       *window,
-                                          const GdkRegion *shape_region,
+                                          const cairo_region_t *shape_region,
                                           gint             offset_x,
                                           gint             offset_y)
 {
@@ -1073,7 +784,7 @@ gdk_offscreen_window_shape_combine_region (GdkWindow       *window,
 
 static void
 gdk_offscreen_window_input_shape_combine_region (GdkWindow       *window,
-                                                const GdkRegion *shape_region,
+                                                const cairo_region_t *shape_region,
                                                 gint             offset_x,
                                                 gint             offset_y)
 {
@@ -1086,27 +797,6 @@ gdk_offscreen_window_set_static_gravities (GdkWindow *window,
   return TRUE;
 }
 
-static void
-gdk_offscreen_window_set_cursor (GdkWindow *window,
-                                GdkCursor *cursor)
-{
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkOffscreenWindow *offscreen;
-
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-
-  if (offscreen->cursor)
-    {
-      gdk_cursor_unref (offscreen->cursor);
-      offscreen->cursor = NULL;
-    }
-
-  if (cursor)
-    offscreen->cursor = gdk_cursor_ref (cursor);
-
-  /* TODO: The cursor is never actually used... */
-}
-
 static void
 gdk_offscreen_window_get_geometry (GdkWindow *window,
                                   gint      *x,
@@ -1136,7 +826,7 @@ gdk_offscreen_window_get_geometry (GdkWindow *window,
 
 static gboolean
 gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
-                                      GdkRegion *area)
+                                      cairo_region_t *area)
 {
   return FALSE;
 }
@@ -1144,7 +834,7 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
 static void
 gdk_offscreen_window_queue_translation (GdkWindow *window,
                                        GdkGC     *gc,
-                                       GdkRegion *area,
+                                       cairo_region_t *area,
                                        gint       dx,
                                        gint       dy)
 {
@@ -1229,7 +919,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
   object_class->finalize = gdk_offscreen_window_finalize;
 
   drawable_class->create_gc = gdk_offscreen_window_create_gc;
-  drawable_class->_copy_to_image = gdk_offscreen_window_copy_to_image;
   drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface;
   drawable_class->set_colormap = gdk_offscreen_window_set_colormap;
   drawable_class->get_colormap = gdk_offscreen_window_get_colormap;
@@ -1239,17 +928,7 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
   drawable_class->get_source_drawable = gdk_offscreen_window_get_source_drawable;
   drawable_class->get_composite_drawable = gdk_offscreen_window_get_composite_drawable;
 
-  drawable_class->draw_rectangle = gdk_offscreen_window_draw_rectangle;
-  drawable_class->draw_arc = gdk_offscreen_window_draw_arc;
-  drawable_class->draw_polygon = gdk_offscreen_window_draw_polygon;
-  drawable_class->draw_text = gdk_offscreen_window_draw_text;
-  drawable_class->draw_text_wc = gdk_offscreen_window_draw_text_wc;
   drawable_class->draw_drawable_with_src = gdk_offscreen_window_draw_drawable;
-  drawable_class->draw_points = gdk_offscreen_window_draw_points;
-  drawable_class->draw_segments = gdk_offscreen_window_draw_segments;
-  drawable_class->draw_lines = gdk_offscreen_window_draw_lines;
-  drawable_class->draw_image = gdk_offscreen_window_draw_image;
-  drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf;
 }
 
 static void
@@ -1266,7 +945,6 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->get_events = gdk_offscreen_window_get_events;
   iface->set_events = gdk_offscreen_window_set_events;
   iface->reparent = gdk_offscreen_window_reparent;
-  iface->set_cursor = gdk_offscreen_window_set_cursor;
   iface->get_geometry = gdk_offscreen_window_get_geometry;
   iface->shape_combine_region = gdk_offscreen_window_shape_combine_region;
   iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
@@ -1275,9 +953,6 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->queue_translation = gdk_offscreen_window_queue_translation;
   iface->get_root_coords = gdk_offscreen_window_get_root_coords;
   iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin;
-  iface->get_pointer = gdk_offscreen_window_get_pointer;
+  iface->get_device_state = gdk_offscreen_window_get_device_state;
   iface->destroy = gdk_offscreen_window_destroy;
 }
-
-#define __GDK_OFFSCREEN_WINDOW_C__
-#include "gdkaliasdef.c"