1/* GDK - The GIMP Drawing Kit
2 *
3 * gdkcairocontext-x11.c: X11 specific Cairo wrappers
4 *
5 * Copyright © 2016 Benjamin Otte
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "config.h"
22
23#include "gdkcairocontext-x11.h"
24
25#include "gdkprivate-x11.h"
26
27#include "gdkcairo.h"
28#include "gdksurfaceprivate.h"
29
30#include <X11/Xlib.h>
31
32G_DEFINE_TYPE (GdkX11CairoContext, gdk_x11_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
33
34static cairo_surface_t *
35create_cairo_surface_for_surface (GdkSurface *surface)
36{
37 GdkDisplay *display;
38 cairo_surface_t *cairo_surface;
39 Visual *visual;
40 int scale;
41
42 display = gdk_surface_get_display (surface);
43 scale = gdk_surface_get_scale_factor (surface);
44
45 visual = gdk_x11_display_get_window_visual (GDK_X11_DISPLAY (display));
46 cairo_surface = cairo_xlib_surface_create (dpy: gdk_x11_display_get_xdisplay (display),
47 GDK_SURFACE_XID (surface),
48 visual,
49 width: gdk_surface_get_width (surface) * scale,
50 height: gdk_surface_get_height (surface) * scale);
51 cairo_surface_set_device_scale (surface: cairo_surface, x_scale: scale, y_scale: scale);
52
53 return cairo_surface;
54}
55
56static void
57gdk_x11_cairo_context_begin_frame (GdkDrawContext *draw_context,
58 gboolean prefers_high_depth,
59 cairo_region_t *region)
60{
61 GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (draw_context);
62 GdkRectangle clip_box;
63 GdkSurface *surface;
64 double sx, sy;
65
66 surface = gdk_draw_context_get_surface (context: draw_context);
67 cairo_region_get_extents (region, extents: &clip_box);
68
69 self->window_surface = create_cairo_surface_for_surface (surface);
70 self->paint_surface = gdk_surface_create_similar_surface (surface,
71 content: cairo_surface_get_content (surface: self->window_surface),
72 MAX (clip_box.width, 1),
73 MAX (clip_box.height, 1));
74
75 sx = sy = 1;
76 cairo_surface_get_device_scale (surface: self->paint_surface, x_scale: &sx, y_scale: &sy);
77 cairo_surface_set_device_offset (surface: self->paint_surface, x_offset: -clip_box.x*sx, y_offset: -clip_box.y*sy);
78}
79
80static void
81gdk_x11_cairo_context_end_frame (GdkDrawContext *draw_context,
82 cairo_region_t *painted)
83{
84 GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (draw_context);
85 cairo_t *cr;
86
87 cr = cairo_create (target: self->window_surface);
88
89 cairo_set_source_surface (cr, surface: self->paint_surface, x: 0, y: 0);
90 gdk_cairo_region (cr, region: painted);
91 cairo_clip (cr);
92
93 cairo_set_operator (cr, op: CAIRO_OPERATOR_SOURCE);
94 cairo_paint (cr);
95
96 cairo_destroy (cr);
97
98 cairo_surface_flush (surface: self->window_surface);
99
100 g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
101 g_clear_pointer (&self->window_surface, cairo_surface_destroy);
102}
103
104static cairo_t *
105gdk_x11_cairo_context_cairo_create (GdkCairoContext *context)
106{
107 GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (context);
108
109 return cairo_create (target: self->paint_surface);
110}
111
112static void
113gdk_x11_cairo_context_class_init (GdkX11CairoContextClass *klass)
114{
115 GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
116 GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
117
118 draw_context_class->begin_frame = gdk_x11_cairo_context_begin_frame;
119 draw_context_class->end_frame = gdk_x11_cairo_context_end_frame;
120
121 cairo_context_class->cairo_create = gdk_x11_cairo_context_cairo_create;
122}
123
124static void
125gdk_x11_cairo_context_init (GdkX11CairoContext *self)
126{
127}
128
129

source code of gtk/gdk/x11/gdkcairocontext-x11.c