1
/* Cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright © 2005 Red Hat, Inc.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it either under the terms of the GNU Lesser General Public
7
 * License version 2.1 as published by the Free Software Foundation
8
 * (the "LGPL") or, at your option, under the terms of the Mozilla
9
 * Public License Version 1.1 (the "MPL"). If you do not alter this
10
 * notice, a recipient may use your version of this file under either
11
 * the MPL or the LGPL.
12
 *
13
 * You should have received a copy of the LGPL along with this library
14
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16
 * You should have received a copy of the MPL along with this library
17
 * in the file COPYING-MPL-1.1
18
 *
19
 * The contents of this file are subject to the Mozilla Public License
20
 * Version 1.1 (the "License"); you may not use this file except in
21
 * compliance with the License. You may obtain a copy of the License at
22
 * http://www.mozilla.org/MPL/
23
 *
24
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26
 * the specific language governing rights and limitations.
27
 *
28
 * The Original Code is the cairo graphics library.
29
 *
30
 * The Initial Developer of the Original Code is Red Hat, Inc.
31
 *
32
 * Contributors(s):
33
 *	Chris Wilson <chris@chris-wilson.co.uk>
34
 *	Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
35
 */
36

            
37
#ifndef CAIRO_XLIB_PRIVATE_H
38
#define CAIRO_XLIB_PRIVATE_H
39

            
40
#include "cairo-xlib-xrender-private.h"
41
#include "cairo-xlib.h"
42

            
43
#include "cairo-compiler-private.h"
44
#include "cairo-device-private.h"
45
#include "cairo-freelist-type-private.h"
46
#include "cairo-list-private.h"
47
#include "cairo-reference-count-private.h"
48
#include "cairo-types-private.h"
49
#include "cairo-scaled-font-private.h"
50
#include "cairo-surface-private.h"
51

            
52
#include <pixman.h>
53
#include <string.h>
54

            
55
typedef struct _cairo_xlib_display cairo_xlib_display_t;
56
typedef struct _cairo_xlib_shm_display cairo_xlib_shm_display_t;
57
typedef struct _cairo_xlib_screen cairo_xlib_screen_t;
58
typedef struct _cairo_xlib_source cairo_xlib_source_t;
59
typedef struct _cairo_xlib_proxy cairo_xlib_proxy_t;
60
typedef struct _cairo_xlib_surface cairo_xlib_surface_t;
61

            
62
/* size of color cube */
63
#define CUBE_SIZE 6
64
/* size of gray ramp */
65
#define RAMP_SIZE 16
66
/* maximum number of cached GC's */
67
#define GC_CACHE_SIZE 4
68
/* maximum width/height of an X11 drawable */
69
#define XLIB_COORD_MAX 32767
70

            
71
struct _cairo_xlib_display {
72
    cairo_device_t base;
73

            
74
    cairo_xlib_display_t *next;
75

            
76
    Display *display;
77
    cairo_list_t screens;
78
    cairo_list_t fonts;
79

            
80
    cairo_xlib_shm_display_t *shm;
81

            
82
    const cairo_compositor_t *compositor;
83

            
84
    int render_major;
85
    int render_minor;
86
    XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGBA128F + 1];
87

            
88
    int force_precision;
89

            
90
    cairo_surface_t *white;
91
    cairo_surface_t *alpha[256];
92
    cairo_surface_t *solid[32];
93
    uint32_t solid_cache[32]; /* low 16 are opaque, high 16 transparent */
94
    struct {
95
	uint32_t color;
96
	int index;
97
    } last_solid_cache[2];
98

            
99
    /* TRUE if the server has a bug with repeating pictures
100
     *
101
     *  https://bugs.freedesktop.org/show_bug.cgi?id=3566
102
     *
103
     * We can't test for this because it depends on whether the
104
     * picture is in video memory or not.
105
     *
106
     * We also use this variable as a guard against a second
107
     * independent bug with transformed repeating pictures:
108
     *
109
     * https://lists.freedesktop.org/archives/cairo/2004-September/001839.html
110
     *
111
     * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so
112
     * we can reuse the test for now.
113
     */
114
    unsigned int buggy_gradients : 1;
115
    unsigned int buggy_pad_reflect : 1;
116
    unsigned int buggy_repeat : 1;
117
    unsigned int closed :1;
118
};
119

            
120
typedef struct _cairo_xlib_visual_info {
121
    cairo_list_t link;
122
    VisualID visualid;
123
    struct { uint8_t a, r, g, b; } colors[256];
124
    uint8_t cube_to_pseudocolor[CUBE_SIZE][CUBE_SIZE][CUBE_SIZE];
125
    uint8_t field8_to_cube[256];
126
    int8_t  dither8_to_cube[256];
127
    uint8_t gray8_to_pseudocolor[256];
128
} cairo_xlib_visual_info_t;
129

            
130
struct _cairo_xlib_screen {
131
    cairo_list_t link;
132

            
133
    cairo_device_t *device;
134
    Screen *screen;
135

            
136
    cairo_list_t surfaces;
137

            
138
    cairo_bool_t has_font_options;
139
    cairo_font_options_t font_options;
140

            
141
    GC gc[GC_CACHE_SIZE];
142
    uint8_t gc_depths[GC_CACHE_SIZE];
143

            
144
    cairo_list_t visuals;
145
};
146

            
147
enum {
148
    GLYPHSET_INDEX_ARGB32,
149
    GLYPHSET_INDEX_A8,
150
    GLYPHSET_INDEX_A1,
151
    NUM_GLYPHSETS
152
};
153

            
154
typedef struct _cairo_xlib_font_glyphset {
155
    GlyphSet		glyphset;
156
    cairo_format_t	format;
157
    XRenderPictFormat	*xrender_format;
158
    struct _cairo_xlib_font_glyphset_free_glyphs {
159
	int		count;
160
	unsigned long	indices[128];
161
    } to_free;
162
} cairo_xlib_font_glyphset_t;
163

            
164
typedef struct _cairo_xlib_font {
165
    cairo_scaled_font_private_t		base;
166
    cairo_scaled_font_t			*font;
167
    cairo_device_t			*device;
168
    cairo_list_t			link;
169
    cairo_xlib_font_glyphset_t		glyphset[NUM_GLYPHSETS];
170
} cairo_xlib_font_t;
171

            
172
struct _cairo_xlib_surface {
173
    cairo_surface_t base;
174

            
175
    Picture picture;
176
    Drawable drawable;
177

            
178
    const cairo_compositor_t *compositor;
179
    cairo_surface_t *shm;
180
    int fallback;
181

            
182
    cairo_xlib_display_t *display;
183
    cairo_xlib_screen_t *screen;
184
    cairo_list_t link;
185

            
186
    Display *dpy; /* only valid between acquire/release */
187
    cairo_bool_t owns_pixmap;
188
    Visual *visual;
189

            
190
    int use_pixmap;
191

            
192
    int width;
193
    int height;
194
    int depth;
195

            
196
    int precision;
197
    XRenderPictFormat *xrender_format;
198
    /* XXX pixman_format instead of masks? */
199
    uint32_t a_mask;
200
    uint32_t r_mask;
201
    uint32_t g_mask;
202
    uint32_t b_mask;
203

            
204
    struct _cairo_xlib_source {
205
	cairo_surface_t base;
206

            
207
	Picture picture;
208
	Pixmap pixmap;
209
	Display *dpy;
210

            
211
	unsigned int filter:3;
212
	unsigned int extend:3;
213
	unsigned int has_matrix:1;
214
	unsigned int has_component_alpha:1;
215
    } embedded_source;
216
};
217

            
218
struct _cairo_xlib_proxy {
219
    struct _cairo_xlib_source source;
220
    cairo_surface_t *owner;
221
};
222

            
223
inline static cairo_bool_t
224
8
_cairo_xlib_vendor_is_xorg (Display *dpy)
225
{
226
8
    const char *const vendor = ServerVendor (dpy);
227
8
    return strstr (vendor, "X.Org") || strstr (vendor, "Xorg");
228
}
229

            
230
cairo_private cairo_status_t
231
_cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
232
                            cairo_xlib_surface_t *surface,
233
                            GC                   *gc);
234

            
235
cairo_private cairo_device_t *
236
_cairo_xlib_device_create (Display *display);
237

            
238
cairo_private void
239
_cairo_xlib_display_init_shm (cairo_xlib_display_t *display);
240

            
241
cairo_private void
242
_cairo_xlib_display_fini_shm (cairo_xlib_display_t *display);
243

            
244
cairo_private cairo_xlib_screen_t *
245
_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
246
				Screen *screen);
247

            
248
cairo_private cairo_status_t
249
_cairo_xlib_display_acquire (cairo_device_t *device,
250
                             cairo_xlib_display_t **display);
251

            
252
cairo_private cairo_bool_t
253
_cairo_xlib_display_has_repeat (cairo_device_t *device);
254

            
255
cairo_private cairo_bool_t
256
_cairo_xlib_display_has_reflect (cairo_device_t *device);
257

            
258
cairo_private cairo_bool_t
259
_cairo_xlib_display_has_gradients (cairo_device_t *device);
260

            
261
cairo_private void
262
_cairo_xlib_display_set_precision(cairo_device_t *device,
263
				  int precision);
264

            
265
cairo_private XRenderPictFormat *
266
_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
267
	                                cairo_format_t		 format);
268

            
269
cairo_private XRenderPictFormat *
270
_cairo_xlib_display_get_xrender_format_for_pixman (cairo_xlib_display_t *display,
271
						   pixman_format_code_t format);
272

            
273
cairo_private cairo_status_t
274
_cairo_xlib_screen_get (Display *dpy,
275
			Screen *screen,
276
			cairo_xlib_screen_t **out);
277

            
278
cairo_private void
279
_cairo_xlib_screen_destroy (cairo_xlib_display_t *display,
280
			    cairo_xlib_screen_t *info);
281

            
282
cairo_private GC
283
_cairo_xlib_screen_get_gc (cairo_xlib_display_t *display,
284
                           cairo_xlib_screen_t *info,
285
			   int depth,
286
			   Drawable drawable);
287
cairo_private void
288
_cairo_xlib_screen_put_gc (cairo_xlib_display_t *display,
289
			   cairo_xlib_screen_t *info,
290
			   int depth,
291
			   GC gc);
292

            
293
cairo_private cairo_font_options_t *
294
_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info);
295

            
296
cairo_private cairo_status_t
297
_cairo_xlib_screen_get_visual_info (cairo_xlib_display_t *display,
298
                                    cairo_xlib_screen_t *info,
299
				    Visual *visual,
300
				    cairo_xlib_visual_info_t **out);
301

            
302
cairo_private cairo_status_t
303
_cairo_xlib_visual_info_create (Display *dpy,
304
	                        int screen,
305
				VisualID visualid,
306
				cairo_xlib_visual_info_t **out);
307

            
308
cairo_private void
309
_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info);
310

            
311
cairo_private const cairo_compositor_t *
312
_cairo_xlib_core_compositor_get (void);
313

            
314
cairo_private const cairo_compositor_t *
315
_cairo_xlib_fallback_compositor_get (void);
316

            
317
cairo_private const cairo_compositor_t *
318
_cairo_xlib_mask_compositor_get (void);
319

            
320
cairo_private const cairo_compositor_t *
321
_cairo_xlib_traps_compositor_get (void);
322

            
323
cairo_private void
324
_cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t    *surface);
325

            
326
cairo_private void
327
_cairo_xlib_surface_set_precision (cairo_xlib_surface_t	*surface,
328
				   cairo_antialias_t	 antialias);
329

            
330
cairo_private cairo_int_status_t
331
_cairo_xlib_surface_set_attributes (cairo_xlib_display_t       *display,
332
                                    cairo_xlib_surface_t       *surface,
333
				    cairo_surface_attributes_t *attributes,
334
				    double			xc,
335
				    double			yc);
336

            
337
cairo_private cairo_status_t
338
_cairo_xlib_surface_draw_image (cairo_xlib_surface_t   *surface,
339
				cairo_image_surface_t  *image,
340
				int                    src_x,
341
				int                    src_y,
342
				int                    width,
343
				int                    height,
344
				int                    dst_x,
345
				int                    dst_y);
346

            
347
cairo_private cairo_surface_t *
348
_cairo_xlib_source_create_for_pattern (cairo_surface_t *dst,
349
				       const cairo_pattern_t *pattern,
350
				       cairo_bool_t is_mask,
351
				       const cairo_rectangle_int_t *extents,
352
				       const cairo_rectangle_int_t *sample,
353
				       int *src_x, int *src_y);
354

            
355
cairo_private void
356
_cairo_xlib_font_close (cairo_xlib_font_t *font);
357

            
358
#define CAIRO_RENDER_AT_LEAST(surface, major, minor)	\
359
	(((surface)->render_major > major) ||			\
360
	 (((surface)->render_major == major) && ((surface)->render_minor >= minor)))
361

            
362
#define CAIRO_RENDER_HAS_CREATE_PICTURE(surface)		CAIRO_RENDER_AT_LEAST((surface), 0, 0)
363
#define CAIRO_RENDER_HAS_COMPOSITE(surface)		CAIRO_RENDER_AT_LEAST((surface), 0, 0)
364
#define CAIRO_RENDER_HAS_COMPOSITE_TEXT(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 0)
365

            
366
#define CAIRO_RENDER_HAS_FILL_RECTANGLES(surface)		CAIRO_RENDER_AT_LEAST((surface), 0, 1)
367

            
368
#define CAIRO_RENDER_HAS_DISJOINT(surface)			CAIRO_RENDER_AT_LEAST((surface), 0, 2)
369
#define CAIRO_RENDER_HAS_CONJOINT(surface)			CAIRO_RENDER_AT_LEAST((surface), 0, 2)
370

            
371
#define CAIRO_RENDER_HAS_TRAPEZOIDS(surface)		CAIRO_RENDER_AT_LEAST((surface), 0, 4)
372
#define CAIRO_RENDER_HAS_TRIANGLES(surface)		CAIRO_RENDER_AT_LEAST((surface), 0, 4)
373
#define CAIRO_RENDER_HAS_TRISTRIP(surface)			CAIRO_RENDER_AT_LEAST((surface), 0, 4)
374
#define CAIRO_RENDER_HAS_TRIFAN(surface)			CAIRO_RENDER_AT_LEAST((surface), 0, 4)
375

            
376
#define CAIRO_RENDER_HAS_PICTURE_TRANSFORM(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 6)
377
#define CAIRO_RENDER_HAS_FILTERS(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 6)
378
#define CAIRO_RENDER_HAS_FILTER_GOOD(surface) FALSE
379
#define CAIRO_RENDER_HAS_FILTER_BEST(surface) FALSE
380

            
381
#define CAIRO_RENDER_HAS_EXTENDED_REPEAT(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 10)
382
#define CAIRO_RENDER_HAS_GRADIENTS(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 10)
383

            
384
#define CAIRO_RENDER_HAS_PDF_OPERATORS(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 11)
385

            
386
#define CAIRO_RENDER_SUPPORTS_OPERATOR(surface, op)	\
387
     ((op) <= CAIRO_OPERATOR_SATURATE ||			\
388
      (CAIRO_RENDER_HAS_PDF_OPERATORS(surface) &&	\
389
       (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY))
390

            
391
/*
392
 * Return whether two xlib surfaces share the same
393
 * screen.  Both core and Render drawing require this
394
 * when using multiple drawables in an operation.
395
 */
396
static inline cairo_bool_t
397
3
_cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,
398
				 cairo_xlib_surface_t *src)
399
{
400
3
    return dst->screen == src->screen;
401
}
402

            
403
cairo_private cairo_int_status_t
404
_cairo_xlib_core_fill_boxes (cairo_xlib_surface_t    *dst,
405
			     const cairo_color_t     *color,
406
			     cairo_boxes_t	    *boxes);
407

            
408
cairo_private cairo_int_status_t
409
_cairo_xlib_core_fill_rectangles (cairo_xlib_surface_t    *dst,
410
				  const cairo_color_t     *color,
411
				  int num_rects,
412
				  cairo_rectangle_int_t *rects);
413

            
414
static inline void
415
6
_cairo_xlib_surface_put_gc (cairo_xlib_display_t *display,
416
                            cairo_xlib_surface_t *surface,
417
                            GC                    gc)
418
{
419
6
    _cairo_xlib_screen_put_gc (display,
420
                               surface->screen,
421
			       surface->depth,
422
			       gc);
423
6
}
424

            
425
cairo_private cairo_surface_t *
426
_cairo_xlib_surface_create_similar_shm (void *surface,
427
					cairo_format_t format,
428
					int width, int height);
429

            
430
cairo_private cairo_surface_t *
431
_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface,
432
			     cairo_bool_t overwrite);
433

            
434
cairo_private cairo_int_status_t
435
_cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface);
436

            
437
cairo_private cairo_surface_t *
438
_cairo_xlib_surface_create_shm (cairo_xlib_surface_t *other,
439
				pixman_format_code_t format,
440
				int width, int height);
441

            
442
cairo_private cairo_surface_t *
443
_cairo_xlib_surface_create_shm__image (cairo_xlib_surface_t *surface,
444
				       pixman_format_code_t format,
445
				       int width, int height);
446

            
447
cairo_private void
448
_cairo_xlib_shm_surface_get_ximage (cairo_surface_t *surface,
449
				    XImage *ximage);
450

            
451
cairo_private void *
452
_cairo_xlib_shm_surface_get_obdata (cairo_surface_t *surface);
453

            
454
cairo_private void
455
_cairo_xlib_shm_surface_mark_active (cairo_surface_t *shm);
456

            
457
cairo_private cairo_bool_t
458
_cairo_xlib_shm_surface_is_active (cairo_surface_t *surface);
459

            
460
cairo_private cairo_bool_t
461
_cairo_xlib_shm_surface_is_idle (cairo_surface_t *surface);
462

            
463
cairo_private Pixmap
464
_cairo_xlib_shm_surface_get_pixmap (cairo_surface_t *surface);
465

            
466
cairo_private XRenderPictFormat *
467
_cairo_xlib_shm_surface_get_xrender_format (cairo_surface_t *surface);
468

            
469
cairo_private pixman_format_code_t
470
_pixman_format_for_xlib_surface (cairo_xlib_surface_t *surface);
471

            
472
#endif /* CAIRO_XLIB_PRIVATE_H */