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

1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
1
/* gdkdrawable-quartz.c
2
 *
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
3
 * Copyright (C) 2005-2007 Imendio AB
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
 * Boston, MA 02111-1307, USA.
19
 */
20
21
#include <config.h>
22
#include <cairo-quartz.h>
23
#include "gdkprivate-quartz.h"
24
25
static gpointer parent_class;
26
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
27
static cairo_user_data_key_t gdk_quartz_cairo_key;
28
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
29
typedef struct {
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
30
  GdkDrawable  *drawable;
31
  CGContextRef  cg_context;
32
} GdkQuartzCairoSurfaceData;
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
33
34
static void
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
35
gdk_quartz_cairo_surface_destroy (void *data)
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
36
{
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
46
}
47
48
static cairo_surface_t *
49
gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
50
{
51
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
52
53
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
54
      GDK_WINDOW_DESTROYED (impl->wrapper))
55
    return NULL;
56
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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;
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
82
}
83
84
static void
85
gdk_quartz_set_colormap (GdkDrawable *drawable,
86
			 GdkColormap *colormap)
87
{
88
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
89
90
  if (impl->colormap == colormap)
91
    return;
92
  
93
  if (impl->colormap)
94
    g_object_unref (impl->colormap);
95
  impl->colormap = colormap;
96
  if (impl->colormap)
97
    g_object_ref (impl->colormap);
98
}
99
100
static GdkColormap*
101
gdk_quartz_get_colormap (GdkDrawable *drawable)
102
{
103
  return GDK_DRAWABLE_IMPL_QUARTZ (drawable)->colormap;
104
}
105
106
static GdkScreen*
107
gdk_quartz_get_screen (GdkDrawable *drawable)
108
{
109
  return _gdk_screen;
110
}
111
112
static GdkVisual*
113
gdk_quartz_get_visual (GdkDrawable *drawable)
114
{
115
  return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
116
}
117
118
static int
119
gdk_quartz_get_depth (GdkDrawable *drawable)
120
{
121
  /* This is a bit bogus but I'm not sure the other way is better */
122
123
  return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
124
}
125
126
static void
127
gdk_quartz_draw_rectangle (GdkDrawable *drawable,
128
			   GdkGC       *gc,
129
			   gboolean     filled,
130
			   gint         x,
131
			   gint         y,
132
			   gint         width,
133
			   gint         height)
134
{
135
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
136
137
  if (!context)
138
    return;
139
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
140
  _gdk_quartz_gc_update_cg_context (gc, 
141
				    drawable,
142
				    context,
143
				    filled ?
144
				    GDK_QUARTZ_CONTEXT_FILL : 
145
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
146
147
  if (filled)
148
    {
149
      CGRect rect = CGRectMake (x, y, width, height);
150
151
      CGContextFillRect (context, rect);
152
    }
153
  else
154
    {
155
      CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height);
156
157
      CGContextStrokeRect (context, rect);
158
    }
159
160
  gdk_quartz_drawable_release_context (drawable, context);
161
}
162
163
static void
164
gdk_quartz_draw_arc (GdkDrawable *drawable,
165
		     GdkGC       *gc,
166
		     gboolean     filled,
167
		     gint         x,
168
		     gint         y,
169
		     gint         width,
170
		     gint         height,
171
		     gint         angle1,
172
		     gint         angle2)
173
{
174
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
175
  float start_angle, end_angle;
176
177
  if (!context)
178
    return;
179
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
180
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
181
				    filled ?
182
				    GDK_QUARTZ_CONTEXT_FILL :
183
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
184
185
  CGContextSaveGState (context);
186
187
  start_angle = (2 - (angle1 / (180.0 * 64.0))) * G_PI;
188
  end_angle = start_angle - (angle2 / (180.0 * 64.0)) * G_PI;
189
190
  if (filled)
191
    {
192
      CGContextTranslateCTM (context,
193
                             x + width / 2.0,
194
                             y + height / 2.0);
195
      CGContextScaleCTM (context, 1.0, (double)height / (double)width);
196
197
      CGContextMoveToPoint (context, 0, 0);
198
      CGContextAddArc (context, 0, 0, width / 2.0,
199
		       start_angle, end_angle,
200
		       TRUE);
201
      CGContextClosePath (context);
202
      CGContextFillPath (context);
203
    }
204
  else
205
    {
206
      CGContextTranslateCTM (context,
207
                             x + width / 2.0 + 0.5,
208
                             y + height / 2.0 + 0.5);
209
      CGContextScaleCTM (context, 1.0, (double)height / (double)width);
210
211
      CGContextAddArc (context, 0, 0, width / 2.0,
212
		       start_angle, end_angle,
213
		       TRUE);
214
      CGContextStrokePath (context);
215
    }
216
217
  CGContextRestoreGState (context);
218
219
  gdk_quartz_drawable_release_context (drawable, context);
220
}
221
222
static void
223
gdk_quartz_draw_polygon (GdkDrawable *drawable,
224
			 GdkGC       *gc,
225
			 gboolean     filled,
226
			 GdkPoint    *points,
227
			 gint         npoints)
228
{
229
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
230
  int i;
231
232
  if (!context)
233
    return;
234
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
235
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
236
				    filled ?
237
				    GDK_QUARTZ_CONTEXT_FILL :
238
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
239
240
  if (filled)
241
    {
242
      CGContextMoveToPoint (context, points[0].x, points[0].y);
243
      for (i = 1; i < npoints; i++)
244
	CGContextAddLineToPoint (context, points[i].x, points[i].y);
245
246
      CGContextClosePath (context);
247
      CGContextFillPath (context);
248
    }
249
  else
250
    {
251
      CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5);
252
      for (i = 1; i < npoints; i++)
253
	CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
254
255
      CGContextClosePath (context);
256
      CGContextStrokePath (context);
257
    }
258
259
  gdk_quartz_drawable_release_context (drawable, context);
260
}
261
262
static void
263
gdk_quartz_draw_text (GdkDrawable *drawable,
264
		      GdkFont     *font,
265
		      GdkGC       *gc,
266
		      gint         x,
267
		      gint         y,
268
		      const gchar *text,
269
		      gint         text_length)
270
{
271
  /* FIXME: Implement */
272
}
273
274
static void
275
gdk_quartz_draw_text_wc (GdkDrawable    *drawable,
276
			 GdkFont	*font,
277
			 GdkGC	        *gc,
278
			 gint	         x,
279
			 gint	         y,
280
			 const GdkWChar *text,
281
			 gint	         text_length)
282
{
283
  /* FIXME: Implement */
284
}
285
286
static void
287
gdk_quartz_draw_drawable (GdkDrawable *drawable,
288
			  GdkGC       *gc,
289
			  GdkPixmap   *src,
290
			  gint         xsrc,
291
			  gint         ysrc,
292
			  gint         xdest,
293
			  gint         ydest,
294
			  gint         width,
295
			  gint         height)
296
{
297
  int src_depth = gdk_drawable_get_depth (src);
298
  int dest_depth = gdk_drawable_get_depth (drawable);
299
  GdkDrawableImplQuartz *src_impl;
300
301
  if (GDK_IS_DRAWABLE_IMPL_QUARTZ (src))
302
    src_impl = GDK_DRAWABLE_IMPL_QUARTZ (src);
303
  else if (GDK_IS_PIXMAP (src))
304
    src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (src)->impl);
305
  else if (GDK_IS_WINDOW (src))
306
    {
307
      src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_WINDOW_OBJECT (src)->impl);
308
      /* FIXME: Implement drawing a window. */
309
      return;
310
    }
311
  else
312
    g_assert_not_reached ();
313
  
314
  if (src_depth == 1)
315
    {
316
      /* FIXME: src depth 1 is not supported yet */
317
    }
318
  else if (dest_depth != 0 && src_depth == dest_depth)
319
    {
320
      CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
321
322
      if (!context)
323
	return;
324
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
325
      _gdk_quartz_gc_update_cg_context (gc, drawable, context,
326
					GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
327
328
      CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
329
      CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc);
330
      CGContextDrawImage (context, 
331
			  CGRectMake(0, 0, 
332
				     GDK_PIXMAP_IMPL_QUARTZ (src_impl)->width, 
333
				     GDK_PIXMAP_IMPL_QUARTZ (src_impl)->height), 
334
			  GDK_PIXMAP_IMPL_QUARTZ (src_impl)->image);
335
336
      gdk_quartz_drawable_release_context (drawable, context);
337
    }
338
  else
339
    g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d",
340
	       src_depth, dest_depth);
341
}
342
343
static void
344
gdk_quartz_draw_points (GdkDrawable *drawable,
345
			GdkGC       *gc,
346
			GdkPoint    *points,
347
			gint         npoints)
348
{
349
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
350
  int i;
351
352
  if (!context)
353
    return;
354
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
355
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
356
				    GDK_QUARTZ_CONTEXT_STROKE |
357
				    GDK_QUARTZ_CONTEXT_FILL);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
358
359
  /* Just draw 1x1 rectangles */
360
  for (i = 0; i < npoints; i++) 
361
    {
362
      CGRect rect = CGRectMake (points[i].x, points[i].y, 1, 1);
363
      CGContextFillRect (context, rect);
364
    }
365
366
  gdk_quartz_drawable_release_context (drawable, context);
367
}
368
369
static void
370
gdk_quartz_draw_segments (GdkDrawable    *drawable,
371
			  GdkGC          *gc,
372
			  GdkSegment     *segs,
373
			  gint            nsegs)
374
{
375
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
376
  int i;
377
378
  if (!context)
379
    return;
380
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
381
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
382
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
383
384
  for (i = 0; i < nsegs; i++)
385
    {
386
      CGContextMoveToPoint (context, segs[i].x1 + 0.5, segs[i].y1 + 0.5);
387
      CGContextAddLineToPoint (context, segs[i].x2 + 0.5, segs[i].y2 + 0.5);
388
    }
389
  
390
  CGContextStrokePath (context);
391
392
  gdk_quartz_drawable_release_context (drawable, context);
393
}
394
395
static void
396
gdk_quartz_draw_lines (GdkDrawable *drawable,
397
		       GdkGC       *gc,
398
		       GdkPoint    *points,
399
		       gint         npoints)
400
{
401
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
402
  int i;
403
404
  if (!context)
405
    return;
406
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
412
  for (i = 1; i < npoints; i++)
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
413
    CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
414
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
415
  CGContextStrokePath (context);
416
417
  gdk_quartz_drawable_release_context (drawable, context);
418
}
419
420
static void
421
gdk_quartz_draw_pixbuf (GdkDrawable     *drawable,
422
			GdkGC           *gc,
423
			GdkPixbuf       *pixbuf,
424
			gint             src_x,
425
			gint             src_y,
426
			gint             dest_x,
427
			gint             dest_y,
428
			gint             width,
429
			gint             height,
430
			GdkRgbDither     dither,
431
			gint             x_dither,
432
			gint             y_dither)
433
{
434
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
435
  CGColorSpaceRef colorspace;
436
  CGDataProviderRef data_provider;
437
  CGImageRef image;
438
  void *data;
439
  int rowstride, pixbuf_width, pixbuf_height;
440
  gboolean has_alpha;
441
442
  if (!context)
443
    return;
444
445
  pixbuf_width = gdk_pixbuf_get_width (pixbuf);
446
  pixbuf_height = gdk_pixbuf_get_height (pixbuf);
447
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
448
  has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
449
450
  data = gdk_pixbuf_get_pixels (pixbuf);
451
452
  colorspace = CGColorSpaceCreateDeviceRGB ();
453
  data_provider = CGDataProviderCreateWithData (NULL, data, pixbuf_height * rowstride, NULL);
454
455
  image = CGImageCreate (pixbuf_width, pixbuf_height, 8,
456
			 has_alpha ? 32 : 24, rowstride, 
457
			 colorspace, 
458
			 has_alpha ? kCGImageAlphaLast : 0,
459
			 data_provider, NULL, FALSE, 
460
			 kCGRenderingIntentDefault);
461
462
  CGDataProviderRelease (data_provider);
463
  CGColorSpaceRelease (colorspace);
464
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
465
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
466
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
467
468
  CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height));
469
  CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height);
470
  CGContextScaleCTM (context, 1, -1);
471
472
  CGContextDrawImage (context, CGRectMake (0, 0, pixbuf_width, pixbuf_height), image);
473
  CGImageRelease (image);
474
475
  gdk_quartz_drawable_release_context (drawable, context);
476
}
477
478
static void
479
gdk_quartz_draw_image (GdkDrawable     *drawable,
480
		       GdkGC           *gc,
481
		       GdkImage        *image,
482
		       gint             xsrc,
483
		       gint             ysrc,
484
		       gint             xdest,
485
		       gint             ydest,
486
		       gint             width,
487
		       gint             height)
488
{
489
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
490
  CGColorSpaceRef colorspace;
491
  CGDataProviderRef data_provider;
492
  CGImageRef cgimage;
493
494
  if (!context)
495
    return;
496
497
  colorspace = CGColorSpaceCreateDeviceRGB ();
498
  data_provider = CGDataProviderCreateWithData (NULL, image->mem, image->height * image->bpl, NULL);
499
500
  /* FIXME: Make sure that this function draws 32-bit images correctly,
501
  * also check endianness wrt kCGImageAlphaNoneSkipFirst */
502
  cgimage = CGImageCreate (image->width, image->height, 8,
503
			   32, image->bpl,
504
			   colorspace,
505
			   kCGImageAlphaNoneSkipFirst, 
506
			   data_provider, NULL, FALSE, kCGRenderingIntentDefault);
507
508
  CGDataProviderRelease (data_provider);
509
  CGColorSpaceRelease (colorspace);
510
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
511
  _gdk_quartz_gc_update_cg_context (gc, drawable, context,
512
				    GDK_QUARTZ_CONTEXT_STROKE);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
513
514
  CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
515
  CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height);
516
  CGContextScaleCTM (context, 1, -1);
517
518
  CGContextDrawImage (context, CGRectMake (0, 0, image->width, image->height), cgimage);
519
  CGImageRelease (cgimage);
520
521
  gdk_quartz_drawable_release_context (drawable, context);
522
}
523
524
static void
525
gdk_drawable_impl_quartz_finalize (GObject *object)
526
{
527
  GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (object);
528
529
  if (impl->colormap)
530
    g_object_unref (impl->colormap);
531
532
  G_OBJECT_CLASS (parent_class)->finalize (object);
533
}
534
535
static void
536
gdk_drawable_impl_quartz_class_init (GdkDrawableImplQuartzClass *klass)
537
{
538
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
539
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
540
541
  parent_class = g_type_class_peek_parent (klass);
542
543
  object_class->finalize = gdk_drawable_impl_quartz_finalize;
544
545
  drawable_class->create_gc = _gdk_quartz_gc_new;
546
  drawable_class->draw_rectangle = gdk_quartz_draw_rectangle;
547
  drawable_class->draw_arc = gdk_quartz_draw_arc;
548
  drawable_class->draw_polygon = gdk_quartz_draw_polygon;
549
  drawable_class->draw_text = gdk_quartz_draw_text;
550
  drawable_class->draw_text_wc = gdk_quartz_draw_text_wc;
551
  drawable_class->draw_drawable = gdk_quartz_draw_drawable;
552
  drawable_class->draw_points = gdk_quartz_draw_points;
553
  drawable_class->draw_segments = gdk_quartz_draw_segments;
554
  drawable_class->draw_lines = gdk_quartz_draw_lines;
555
  drawable_class->draw_image = gdk_quartz_draw_image;
556
  drawable_class->draw_pixbuf = gdk_quartz_draw_pixbuf;
557
558
  drawable_class->ref_cairo_surface = gdk_quartz_ref_cairo_surface;
559
560
  drawable_class->set_colormap = gdk_quartz_set_colormap;
561
  drawable_class->get_colormap = gdk_quartz_get_colormap;
562
563
  drawable_class->get_depth = gdk_quartz_get_depth;
564
  drawable_class->get_screen = gdk_quartz_get_screen;
565
  drawable_class->get_visual = gdk_quartz_get_visual;
566
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
567
  drawable_class->_copy_to_image = _gdk_quartz_image_copy_to_image;
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
568
}
569
570
GType
571
gdk_drawable_impl_quartz_get_type (void)
572
{
573
  static GType object_type = 0;
574
575
  if (!object_type)
576
    {
577
      static const GTypeInfo object_info =
578
      {
579
        sizeof (GdkDrawableImplQuartzClass),
580
        (GBaseInitFunc) NULL,
581
        (GBaseFinalizeFunc) NULL,
582
        (GClassInitFunc) gdk_drawable_impl_quartz_class_init,
583
        NULL,           /* class_finalize */
584
        NULL,           /* class_data */
585
        sizeof (GdkDrawableImplQuartz),
586
        0,              /* n_preallocs */
587
        (GInstanceInitFunc) NULL,
588
      };
589
      
590
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
591
                                            "GdkDrawableImplQuartz",
592
                                            &object_info, 0);
593
    }
594
  
595
  return object_type;
596
}
597
598
CGContextRef 
599
gdk_quartz_drawable_get_context (GdkDrawable *drawable,
600
				 gboolean     antialias)
601
{
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
609
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
610
    {
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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)
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
620
	{
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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
	    }
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
629
	}
630
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
631
      cg_context = [[NSGraphicsContext currentContext] graphicsPort];
632
      CGContextSaveGState (cg_context);
633
      CGContextSetAllowsAntialiasing (cg_context, antialias);
634
	  
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
635
      /* We'll emulate the clipping caused by double buffering here */
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
636
      if (window_impl->begin_paint_count != 0)
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
637
	{
638
	  CGRect rect;
639
	  CGRect *cg_rects;
640
	  GdkRectangle *rects;
641
	  gint n_rects, i;
642
	  
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
643
	  gdk_region_get_rectangles (window_impl->paint_clip_region,
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
644
				     &rects, &n_rects);
645
	  
646
	  if (n_rects == 1)
647
	    cg_rects = &rect;
648
	  else
649
	    cg_rects = g_new (CGRect, n_rects);
650
	  
651
	  for (i = 0; i < n_rects; i++)
652
	    {
653
	      cg_rects[i].origin.x = rects[i].x;
654
	      cg_rects[i].origin.y = rects[i].y;
655
	      cg_rects[i].size.width = rects[i].width;
656
	      cg_rects[i].size.height = rects[i].height;
657
	    }
658
	  
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
659
	  CGContextClipToRects (cg_context, cg_rects, n_rects);
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
660
	  
661
	  g_free (rects);
662
	  if (cg_rects != &rect)
663
	    g_free (cg_rects);
664
	}
665
    }
666
  else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
667
    {
668
      GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
669
      
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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;
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
686
}
687
688
void
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
689
gdk_quartz_drawable_release_context (GdkDrawable  *drawable, 
690
				     CGContextRef  cg_context)
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
691
{
692
  if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
693
    {
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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
	}
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
710
    }
711
  else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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)
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
721
    {
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
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;
1.1.21 by Sebastien Bacher
Import upstream version 2.10.12
726
    }
1.1.22 by Sebastien Bacher
Import upstream version 2.11.2
727
}