~bratsche/ubuntu/maverick/gtk+2.0/menu-activation-fix

« back to all changes in this revision

Viewing changes to gdk/quartz/gdkdrawable-quartz.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-06-13 10:00:13 UTC
  • mto: (72.2.1 lenny) (1.5.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: james.westby@ubuntu.com-20070613100013-qstao3cwpm6xdlxc
Tags: upstream-2.11.2
ImportĀ upstreamĀ versionĀ 2.11.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* gdkdrawable-quartz.c
2
2
 *
3
 
 * Copyright (C) 2005, 2006 Imendio AB
 
3
 * Copyright (C) 2005-2007 Imendio AB
4
4
 *
5
5
 * This library is free software; you can redistribute it and/or
6
6
 * modify it under the terms of the GNU Lesser General Public
19
19
 */
20
20
 
21
21
#include <config.h>
22
 
 
23
22
#include <cairo-quartz.h>
24
23
#include "gdkprivate-quartz.h"
25
24
 
26
25
static gpointer parent_class;
27
26
 
 
27
static cairo_user_data_key_t gdk_quartz_cairo_key;
 
28
 
28
29
typedef struct {
29
 
  GdkDrawable *drawable;
30
 
  CGContextRef context;
31
 
} SurfaceInfo;
32
 
 
33
 
static cairo_user_data_key_t surface_info_key;
 
30
  GdkDrawable  *drawable;
 
31
  CGContextRef  cg_context;
 
32
} GdkQuartzCairoSurfaceData;
34
33
 
35
34
static void
36
 
surface_info_destroy (void *data)
 
35
gdk_quartz_cairo_surface_destroy (void *data)
37
36
{
38
 
  SurfaceInfo *info = data;
39
 
 
40
 
  gdk_quartz_drawable_release_context (info->drawable, info->context);
41
 
 
42
 
  g_free (info);
 
37
  GdkQuartzCairoSurfaceData *surface_data = data;
 
38
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (surface_data->drawable);
 
39
 
 
40
  gdk_quartz_drawable_release_context (surface_data->drawable, 
 
41
                                       surface_data->cg_context);
 
42
 
 
43
  impl->cairo_surface = NULL;
 
44
 
 
45
  g_free (surface_data);
43
46
}
44
47
 
45
48
static cairo_surface_t *
46
49
gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
47
50
{
48
51
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
49
 
  CGContextRef context;
50
 
  int width, height;
51
 
  cairo_surface_t *surface;
52
 
  SurfaceInfo *info;
53
52
 
54
53
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
55
54
      GDK_WINDOW_DESTROYED (impl->wrapper))
56
55
    return NULL;
57
56
 
58
 
  context = gdk_quartz_drawable_get_context (drawable, TRUE);
59
 
  if (!context)
60
 
    return NULL;
61
 
 
62
 
  gdk_drawable_get_size (drawable, &width, &height);
63
 
 
64
 
  surface = cairo_quartz_surface_create (context, width, height, TRUE);
65
 
 
66
 
  info = g_new (SurfaceInfo, 1);
67
 
  info->drawable = drawable;
68
 
  info->context = context;
69
 
 
70
 
  cairo_surface_set_user_data (surface, &surface_info_key,
71
 
                               info, surface_info_destroy);
72
 
  return surface;
 
57
  if (!impl->cairo_surface)
 
58
    {
 
59
      CGContextRef cg_context;
 
60
      int width, height;
 
61
      GdkQuartzCairoSurfaceData *surface_data;
 
62
 
 
63
      cg_context = gdk_quartz_drawable_get_context (drawable, TRUE);
 
64
      if (!cg_context)
 
65
        return NULL;
 
66
 
 
67
      gdk_drawable_get_size (drawable, &width, &height);
 
68
 
 
69
      impl->cairo_surface = cairo_quartz_surface_create_for_cg_context (cg_context, width, height);
 
70
 
 
71
      surface_data = g_new (GdkQuartzCairoSurfaceData, 1);
 
72
      surface_data->drawable = drawable;
 
73
      surface_data->cg_context = cg_context;
 
74
 
 
75
      cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key,
 
76
                                   surface_data, gdk_quartz_cairo_surface_destroy);
 
77
    }
 
78
  else
 
79
    cairo_surface_reference (impl->cairo_surface);
 
80
 
 
81
  return impl->cairo_surface;
73
82
}
74
83
 
75
84
static void
128
137
  if (!context)
129
138
    return;
130
139
 
131
 
  gdk_quartz_update_context_from_gc (context, gc);
 
140
  _gdk_quartz_gc_update_cg_context (gc, 
 
141
                                    drawable,
 
142
                                    context,
 
143
                                    filled ?
 
144
                                    GDK_QUARTZ_CONTEXT_FILL : 
 
145
                                    GDK_QUARTZ_CONTEXT_STROKE);
132
146
 
133
147
  if (filled)
134
148
    {
135
149
      CGRect rect = CGRectMake (x, y, width, height);
136
150
 
137
 
      gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
138
 
                                                    _gdk_gc_get_fg_pixel (gc));
139
151
      CGContextFillRect (context, rect);
140
152
    }
141
153
  else
142
154
    {
143
155
      CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height);
144
156
 
145
 
      gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
146
 
                                                      _gdk_gc_get_fg_pixel (gc));
147
157
      CGContextStrokeRect (context, rect);
148
158
    }
149
159
 
167
177
  if (!context)
168
178
    return;
169
179
 
170
 
  gdk_quartz_update_context_from_gc (context, gc);
 
180
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
181
                                    filled ?
 
182
                                    GDK_QUARTZ_CONTEXT_FILL :
 
183
                                    GDK_QUARTZ_CONTEXT_STROKE);
171
184
 
172
185
  CGContextSaveGState (context);
173
186
 
176
189
 
177
190
  if (filled)
178
191
    {
179
 
      gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
180
 
                                                    _gdk_gc_get_fg_pixel (gc));
181
 
 
182
192
      CGContextTranslateCTM (context,
183
193
                             x + width / 2.0,
184
194
                             y + height / 2.0);
193
203
    }
194
204
  else
195
205
    {
196
 
      gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
197
 
                                                      _gdk_gc_get_fg_pixel (gc));
198
 
 
199
206
      CGContextTranslateCTM (context,
200
207
                             x + width / 2.0 + 0.5,
201
208
                             y + height / 2.0 + 0.5);
225
232
  if (!context)
226
233
    return;
227
234
 
228
 
  gdk_quartz_update_context_from_gc (context, gc);
 
235
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
236
                                    filled ?
 
237
                                    GDK_QUARTZ_CONTEXT_FILL :
 
238
                                    GDK_QUARTZ_CONTEXT_STROKE);
229
239
 
230
240
  if (filled)
231
241
    {
232
 
      gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
233
 
                                                    _gdk_gc_get_fg_pixel (gc));
234
 
 
235
242
      CGContextMoveToPoint (context, points[0].x, points[0].y);
236
243
      for (i = 1; i < npoints; i++)
237
244
        CGContextAddLineToPoint (context, points[i].x, points[i].y);
241
248
    }
242
249
  else
243
250
    {
244
 
      gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
245
 
                                                      _gdk_gc_get_fg_pixel (gc));
246
 
 
247
251
      CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5);
248
252
      for (i = 1; i < npoints; i++)
249
253
        CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
318
322
      if (!context)
319
323
        return;
320
324
 
321
 
      gdk_quartz_update_context_from_gc (context, gc);
322
 
 
323
 
      CGContextSetBlendMode (context, kCGBlendModeNormal);
 
325
      _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
326
                                        GDK_QUARTZ_CONTEXT_STROKE);
324
327
 
325
328
      CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
326
329
      CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc);
349
352
  if (!context)
350
353
    return;
351
354
 
352
 
  gdk_quartz_update_context_from_gc (context, gc);
353
 
  gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
354
 
                                                _gdk_gc_get_fg_pixel (gc));
 
355
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
356
                                    GDK_QUARTZ_CONTEXT_STROKE |
 
357
                                    GDK_QUARTZ_CONTEXT_FILL);
355
358
 
356
359
  /* Just draw 1x1 rectangles */
357
360
  for (i = 0; i < npoints; i++) 
375
378
  if (!context)
376
379
    return;
377
380
 
378
 
  gdk_quartz_update_context_from_gc (context, gc);
379
 
  gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
380
 
                                                  _gdk_gc_get_fg_pixel (gc));
 
381
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
382
                                    GDK_QUARTZ_CONTEXT_STROKE);
381
383
 
382
384
  for (i = 0; i < nsegs; i++)
383
385
    {
402
404
  if (!context)
403
405
    return;
404
406
 
405
 
  gdk_quartz_update_context_from_gc (context, gc);
406
 
  gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
407
 
                                                  _gdk_gc_get_fg_pixel (gc));
408
 
  
 
407
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
408
                                     GDK_QUARTZ_CONTEXT_STROKE);
 
409
 
 
410
  CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5);
 
411
 
409
412
  for (i = 1; i < npoints; i++)
410
 
    {
411
 
      CGContextMoveToPoint (context, points[i - 1].x + 0.5, points[i - 1].y + 0.5);
412
 
      CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
413
 
    }
414
 
  
 
413
    CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
 
414
 
415
415
  CGContextStrokePath (context);
416
416
 
417
417
  gdk_quartz_drawable_release_context (drawable, context);
462
462
  CGDataProviderRelease (data_provider);
463
463
  CGColorSpaceRelease (colorspace);
464
464
 
465
 
  gdk_quartz_update_context_from_gc (context, gc);
466
 
 
467
 
  CGContextSetBlendMode (context, kCGBlendModeNormal);
 
465
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
466
                                    GDK_QUARTZ_CONTEXT_STROKE);
468
467
 
469
468
  CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height));
470
469
  CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height);
509
508
  CGDataProviderRelease (data_provider);
510
509
  CGColorSpaceRelease (colorspace);
511
510
 
512
 
  gdk_quartz_update_context_from_gc (context, gc);
513
 
 
514
 
  CGContextSetBlendMode (context, kCGBlendModeNormal);
 
511
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
 
512
                                    GDK_QUARTZ_CONTEXT_STROKE);
515
513
 
516
514
  CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
517
515
  CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height);
566
564
  drawable_class->get_screen = gdk_quartz_get_screen;
567
565
  drawable_class->get_visual = gdk_quartz_get_visual;
568
566
 
569
 
  drawable_class->_copy_to_image = _gdk_quartz_copy_to_image;
 
567
  drawable_class->_copy_to_image = _gdk_quartz_image_copy_to_image;
570
568
}
571
569
 
572
570
GType
601
599
gdk_quartz_drawable_get_context (GdkDrawable *drawable,
602
600
                                 gboolean     antialias)
603
601
{
 
602
  GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
 
603
  CGContextRef           cg_context;
 
604
 
 
605
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
 
606
      GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
 
607
    return NULL;
 
608
 
604
609
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
605
610
    {
606
 
      GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
607
 
      CGContextRef context;
608
 
 
609
 
      impl->pool = [[NSAutoreleasePool alloc] init];
610
 
 
611
 
      if (![impl->view lockFocusIfCanDraw])
 
611
      GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
 
612
 
 
613
      /* Lock focus when not called as part of a drawRect call. This
 
614
       * is needed when called from outside "real" expose events, for
 
615
       * example for synthesized expose events when realizing windows
 
616
       * and for widgets that send fake expose events like the arrow
 
617
       * buttons in spinbuttons.
 
618
       */
 
619
      if (window_impl->in_paint_rect_count == 0)
612
620
        {
613
 
          [impl->pool release];
614
 
          return NULL;
 
621
          window_impl->pool = [[NSAutoreleasePool alloc] init];
 
622
          if (![window_impl->view lockFocusIfCanDraw])
 
623
            {
 
624
              [window_impl->pool release];
 
625
              window_impl->pool = NULL;
 
626
 
 
627
              return NULL;
 
628
            }
615
629
        }
616
630
 
617
 
      context = [[NSGraphicsContext currentContext] graphicsPort];
618
 
 
619
 
      CGContextSaveGState (context);
620
 
      CGContextSetAllowsAntialiasing (context, antialias);
621
 
 
 
631
      cg_context = [[NSGraphicsContext currentContext] graphicsPort];
 
632
      CGContextSaveGState (cg_context);
 
633
      CGContextSetAllowsAntialiasing (cg_context, antialias);
 
634
          
622
635
      /* We'll emulate the clipping caused by double buffering here */
623
 
      if (impl->begin_paint_count != 0)
 
636
      if (window_impl->begin_paint_count != 0)
624
637
        {
625
638
          CGRect rect;
626
639
          CGRect *cg_rects;
627
640
          GdkRectangle *rects;
628
641
          gint n_rects, i;
629
642
          
630
 
          gdk_region_get_rectangles (impl->paint_clip_region,
 
643
          gdk_region_get_rectangles (window_impl->paint_clip_region,
631
644
                                     &rects, &n_rects);
632
645
          
633
646
          if (n_rects == 1)
643
656
              cg_rects[i].size.height = rects[i].height;
644
657
            }
645
658
          
646
 
          CGContextClipToRects (context, cg_rects, n_rects);
 
659
          CGContextClipToRects (cg_context, cg_rects, n_rects);
647
660
          
648
661
          g_free (rects);
649
662
          if (cg_rects != &rect)
650
663
            g_free (cg_rects);
651
664
        }
652
 
      
653
 
      return context;
654
665
    }
655
666
  else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
656
667
    {
657
668
      GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
658
 
      CGContextRef context;
659
 
 
660
 
      context = CGBitmapContextCreate (impl->data,
661
 
                                       CGImageGetWidth (impl->image),
662
 
                                       CGImageGetHeight (impl->image),
663
 
                                       CGImageGetBitsPerComponent (impl->image),
664
 
                                       CGImageGetBytesPerRow (impl->image),
665
 
                                       CGImageGetColorSpace (impl->image),
666
 
                                       CGImageGetBitmapInfo (impl->image));
667
 
      CGContextSetAllowsAntialiasing (context, antialias);
668
669
      
669
 
      return context;
670
 
    }
671
 
 
672
 
  g_assert_not_reached ();
673
 
 
674
 
  return NULL;
 
670
      cg_context = CGBitmapContextCreate (impl->data,
 
671
                                          CGImageGetWidth (impl->image),
 
672
                                          CGImageGetHeight (impl->image),
 
673
                                          CGImageGetBitsPerComponent (impl->image),
 
674
                                          CGImageGetBytesPerRow (impl->image),
 
675
                                          CGImageGetColorSpace (impl->image),
 
676
                                          CGImageGetBitmapInfo (impl->image));
 
677
      CGContextSetAllowsAntialiasing (cg_context, antialias);
 
678
    }
 
679
  else 
 
680
    {
 
681
      g_warning ("Tried to create CGContext for something not a quartz window or pixmap");
 
682
      cg_context = NULL;
 
683
    }
 
684
 
 
685
  return cg_context;
675
686
}
676
687
 
677
688
void
678
 
gdk_quartz_drawable_release_context (GdkDrawable  *drawable,
679
 
                                     CGContextRef  context)
 
689
gdk_quartz_drawable_release_context (GdkDrawable  *drawable, 
 
690
                                     CGContextRef  cg_context)
680
691
{
681
 
  if (!context)
682
 
    return;
683
 
 
684
692
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
685
693
    {
686
 
      GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
687
 
 
688
 
      CGContextRestoreGState (context);
689
 
      CGContextSetAllowsAntialiasing (context, TRUE);
690
 
 
691
 
      if (impl->in_paint_rect_count == 0 &&
692
 
          impl->begin_paint_count == 0)
693
 
        CGContextFlush (context);
694
 
 
695
 
      [impl->view unlockFocus];
696
 
      [impl->pool release];
 
694
      GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
 
695
 
 
696
      CGContextRestoreGState (cg_context);
 
697
      CGContextSetAllowsAntialiasing (cg_context, TRUE);
 
698
 
 
699
      /* See comment in gdk_quartz_drawable_get_context(). */
 
700
      if (window_impl->in_paint_rect_count == 0)
 
701
        {
 
702
          [window_impl->view unlockFocus];
 
703
 
 
704
          if (window_impl->pool)
 
705
            {
 
706
              [window_impl->pool release];
 
707
              window_impl->pool = NULL;
 
708
            }
 
709
        }
697
710
    }
698
711
  else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
 
712
    CGContextRelease (cg_context);
 
713
}
 
714
 
 
715
void
 
716
_gdk_quartz_drawable_finish (GdkDrawable *drawable)
 
717
{
 
718
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
 
719
 
 
720
  if (impl->cairo_surface)
699
721
    {
700
 
      CGContextRelease (context);
 
722
      cairo_surface_finish (impl->cairo_surface);
 
723
      cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key,
 
724
                                   NULL, NULL);
 
725
      impl->cairo_surface = NULL;
701
726
    }
702
 
}
 
727
}