Have GdkWindowImplQuartz implement GdkPaintable.

2006-04-11  Anders Carlsson  <andersca@mac.imendio.com>

        * gdk/quartz/GdkQuartzView.c:
        (-[GdkQuartzView drawRect:]):
        * gdk/quartz/gdkdrawable-quartz.c:
        (gdk_quartz_ref_cairo_surface):
        (_gdk_quartz_drawable_get_context):
        (_gdk_quartz_drawable_release_context):
        * gdk/quartz/gdkwindow-quartz.c:
        (gdk_window_impl_quartz_finalize):
        (gdk_window_impl_quartz_class_init):
        (gdk_window_impl_quartz_begin_paint_region):
        (gdk_window_impl_quartz_end_paint):
        (gdk_window_impl_quartz_invalidate_maybe_recurse):
        (gdk_window_impl_quartz_process_updates):
        (gdk_window_impl_quartz_paintable_init):
        (_gdk_window_impl_quartz_get_type):
        * gdk/quartz/gdkwindow-quartz.h:
        Have GdkWindowImplQuartz implement GdkPaintable.
This commit is contained in:
Anders Carlsson 2006-04-10 23:17:26 +00:00 committed by Anders Carlsson
parent 99722bec2c
commit 1e3d722024
6 changed files with 204 additions and 24 deletions

View File

@ -1,3 +1,23 @@
2006-04-11 Anders Carlsson <andersca@mac.imendio.com>
* gdk/quartz/GdkQuartzView.c:
(-[GdkQuartzView drawRect:]):
* gdk/quartz/gdkdrawable-quartz.c:
(gdk_quartz_ref_cairo_surface):
(_gdk_quartz_drawable_get_context):
(_gdk_quartz_drawable_release_context):
* gdk/quartz/gdkwindow-quartz.c:
(gdk_window_impl_quartz_finalize):
(gdk_window_impl_quartz_class_init):
(gdk_window_impl_quartz_begin_paint_region):
(gdk_window_impl_quartz_end_paint):
(gdk_window_impl_quartz_invalidate_maybe_recurse):
(gdk_window_impl_quartz_process_updates):
(gdk_window_impl_quartz_paintable_init):
(_gdk_window_impl_quartz_get_type):
* gdk/quartz/gdkwindow-quartz.h:
Have GdkWindowImplQuartz implement GdkPaintable.
2006-04-10 Michael Natterer <mitch@imendio.com>
* gtk/gtktextbufferrichtext.c (gtk_text_buffer_deserialize):

View File

@ -1,3 +1,23 @@
2006-04-11 Anders Carlsson <andersca@mac.imendio.com>
* gdk/quartz/GdkQuartzView.c:
(-[GdkQuartzView drawRect:]):
* gdk/quartz/gdkdrawable-quartz.c:
(gdk_quartz_ref_cairo_surface):
(_gdk_quartz_drawable_get_context):
(_gdk_quartz_drawable_release_context):
* gdk/quartz/gdkwindow-quartz.c:
(gdk_window_impl_quartz_finalize):
(gdk_window_impl_quartz_class_init):
(gdk_window_impl_quartz_begin_paint_region):
(gdk_window_impl_quartz_end_paint):
(gdk_window_impl_quartz_invalidate_maybe_recurse):
(gdk_window_impl_quartz_process_updates):
(gdk_window_impl_quartz_paintable_init):
(_gdk_window_impl_quartz_get_type):
* gdk/quartz/gdkwindow-quartz.h:
Have GdkWindowImplQuartz implement GdkPaintable.
2006-04-10 Michael Natterer <mitch@imendio.com>
* gtk/gtktextbufferrichtext.c (gtk_text_buffer_deserialize):

View File

@ -50,33 +50,37 @@
{
NSRect bounds = [self bounds];
GdkRectangle gdk_rect;
GdkWindowObject *private = GDK_WINDOW_OBJECT (gdk_window);
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
GDK_QUARTZ_ALLOC_POOL;
/* Draw background */
if (GDK_WINDOW_OBJECT (gdk_window)->bg_pixmap == NULL)
gdk_rect.x = rect.origin.x;
gdk_rect.y = rect.origin.y;
gdk_rect.width = rect.size.width;
gdk_rect.height = rect.size.height;
if (private->event_mask & GDK_EXPOSURE_MASK)
{
CGContextRef context;
GdkEvent event;
context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState (context);
event.expose.type = GDK_EXPOSE;
event.expose.window = g_object_ref (gdk_window);
event.expose.send_event = FALSE;
event.expose.count = 0;
event.expose.region = gdk_region_rectangle (&gdk_rect);
event.expose.area = gdk_rect;
_gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (gdk_window),
GDK_WINDOW_OBJECT (gdk_window)->bg_color.pixel);
impl->in_paint_rect_count ++;
CGContextFillRect (context, CGRectMake (bounds.origin.x, bounds.origin.y,
bounds.size.width, bounds.size.height));
CGContextRestoreGState (context);
(*_gdk_event_func) (&event, _gdk_event_data);
impl->in_paint_rect_count --;
g_object_unref (gdk_window);
gdk_region_destroy (event.expose.region);
}
gdk_rect.x = bounds.origin.x;
gdk_rect.y = bounds.origin.y;
gdk_rect.width = bounds.size.width;
gdk_rect.height = bounds.size.height;
gdk_window_invalidate_rect (gdk_window, &gdk_rect, FALSE);
gdk_window_process_updates (gdk_window, FALSE);
GDK_QUARTZ_RELEASE_POOL;
}

View File

@ -61,7 +61,7 @@ gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
gdk_drawable_get_size (drawable, &width, &height);
surface = cairo_quartz_surface_create (context, TRUE, width, height);
surface = cairo_quartz_surface_create (context, width, height, TRUE);
info = g_new (SurfaceInfo, 1);
info->drawable = drawable;
@ -586,6 +586,37 @@ _gdk_quartz_drawable_get_context (GdkDrawable *drawable, gboolean antialias)
CGContextSaveGState (context);
CGContextSetAllowsAntialiasing (context, antialias);
/* We'll emulate the clipping caused by double buffering here */
if (impl->begin_paint_count != 0)
{
CGRect rect;
CGRect *cg_rects;
GdkRectangle *rects;
gint n_rects, i;
gdk_region_get_rectangles (impl->paint_clip_region,
&rects, &n_rects);
if (n_rects == 1)
cg_rects = &rect;
else
cg_rects = g_new (CGRect, n_rects);
for (i = 0; i < n_rects; i++)
{
cg_rects[i].origin.x = rects[i].x;
cg_rects[i].origin.y = rects[i].y;
cg_rects[i].size.width = rects[i].width;
cg_rects[i].size.height = rects[i].height;
}
CGContextClipToRects (context, cg_rects, n_rects);
g_free (rects);
if (cg_rects != &rect)
g_free (cg_rects);
}
return context;
}
else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
@ -623,7 +654,9 @@ _gdk_quartz_drawable_release_context (GdkDrawable *drawable, CGContextRef contex
CGContextRestoreGState (context);
CGContextSetAllowsAntialiasing (context, TRUE);
[[NSGraphicsContext currentContext] flushGraphics];
if (impl->in_paint_rect_count == 0)
CGContextFlush (context);
[impl->view unlockFocus];
[impl->pool release];
}

View File

@ -105,6 +105,9 @@ gdk_window_impl_quartz_finalize (GObject *object)
if (impl->nscursor)
[impl->nscursor release];
if (impl->paint_clip_region)
gdk_region_destroy (impl->paint_clip_region);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -112,9 +115,12 @@ static void
gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
{
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gdk_window_impl_quartz_finalize;
drawable_class->get_size = gdk_window_impl_quartz_get_size;
/* Visible and clip regions are the same */
@ -130,6 +136,89 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
impl->height = 1;
}
static void
gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
GdkRegion *region)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
CGContextRef context = _gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
int i, n_rects;
GdkRectangle *rects;
if (impl->begin_paint_count == 0)
impl->paint_clip_region = gdk_region_copy (region);
else
gdk_region_union (impl->paint_clip_region, region);
impl->begin_paint_count ++;
gdk_region_get_rectangles (region, &rects, &n_rects);
for (i = 0; i < n_rects; i++)
{
_gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper),
GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_color.pixel);
CGContextFillRect (context, CGRectMake (rects[i].x, rects[i].y, rects[i].width, rects[i].height));
}
g_free (rects);
_gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), context);
}
static void
gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
impl->begin_paint_count --;
}
static void
gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable,
GdkRegion *region,
gboolean (*child_func) (GdkWindow *, gpointer),
gpointer user_data)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
int i, n_rects;
GdkRectangle *rects;
gdk_region_get_rectangles (region, &rects, &n_rects);
for (i = 0; i < n_rects; i++)
{
[impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y,
rects[i].width, rects[i].height)];
}
g_free (rects);
/* FIXME: Check if we need to traverse the children */
}
static void
gdk_window_impl_quartz_process_updates (GdkPaintable *paintable,
gboolean update_children)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
[impl->view display];
/* FIXME: Check if display actually updates the children too */
}
static void
gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
{
iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
iface->end_paint = gdk_window_impl_quartz_end_paint;
iface->invalidate_maybe_recurse = gdk_window_impl_quartz_invalidate_maybe_recurse;
iface->process_updates = gdk_window_impl_quartz_process_updates;
}
GType
_gdk_window_impl_quartz_get_type (void)
{
@ -150,9 +239,19 @@ _gdk_window_impl_quartz_get_type (void)
(GInstanceInitFunc) gdk_window_impl_quartz_init,
};
static const GInterfaceInfo paintable_info =
{
(GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
NULL,
NULL
};
object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
"GdkWindowImplQuartz",
&object_info, 0);
g_type_add_interface_static (object_type,
GDK_TYPE_PAINTABLE,
&paintable_info);
}
return object_type;

View File

@ -58,6 +58,10 @@ struct _GdkWindowImplQuartz
NSAutoreleasePool *pool;
NSCursor *nscursor;
GdkRegion *paint_clip_region;
gint begin_paint_count;
gint in_paint_rect_count;
};
struct _GdkWindowImplQuartzClass