2
Copyright (C) 2011 Free Software Foundation, Inc.
4
Author: Eric Wasylishen <ewasylishen@gmail.com>
6
This file is part of GNUstep.
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Lesser General Public
10
License as published by the Free Software Foundation; either
11
version 2 of the License, or (at your option) any later version.
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
18
You should have received a copy of the GNU Lesser General Public
19
License along with this library; see the file COPYING.LIB.
20
If not, see <http://www.gnu.org/licenses/> or write to the
21
Free Software Foundation, 51 Franklin Street, Fifth Floor,
22
Boston, MA 02110-1301, USA.
26
#include "x11/XGServer.h"
27
#include "x11/XGServerWindow.h"
28
#include "cairo/XGCairoModernSurface.h"
29
#include <cairo-xlib.h>
31
#define GSWINDEVICE ((gswindow_device_t *)gsDevice)
33
@implementation XGCairoModernSurface
35
- (id) initWithDevice: (void *)device
37
cairo_surface_t *windowsurface;
41
// Create a cairo xlib surface for the window
43
Display *dpy = GSWINDEVICE->display;
45
XWindowAttributes attributes;
47
if (!XGetWindowAttributes(dpy, GSWINDEVICE->ident, &attributes))
49
visual = DefaultVisual(dpy, DefaultScreen(dpy));
53
visual = attributes.visual;
56
windowsurface = cairo_xlib_surface_create(GSWINDEVICE->display,
59
GSWINDEVICE->xframe.size.width,
60
GSWINDEVICE->xframe.size.height);
64
if (GSWINDEVICE->type == NSBackingStoreNonretained)
66
// Don't double-buffer:
67
// use the window surface as the drawing destination.
69
_surface = windowsurface;
74
// Create a similar surface to the window which supports alpha
76
// Ask XGServerWindow to call +[CairoContext handleExposeRect:forDriver:]
77
// to let us handle the back buffer -> front buffer copy using cairo.
78
GSWINDEVICE->gdriverProtocol |= GDriverHandlesExpose | GDriverHandlesBacking;
79
GSWINDEVICE->gdriver = self;
81
_windowSurface = windowsurface;
82
_surface = cairo_surface_create_similar(windowsurface,
83
CAIRO_CONTENT_COLOR_ALPHA,
84
GSWINDEVICE->xframe.size.width,
85
GSWINDEVICE->xframe.size.height);
87
/*NSLog(@"Window surface type %d, back buffer type %d, w %d h %d",
88
(int) cairo_surface_get_type(_windowSurface),
89
(int) cairo_surface_get_type(_surface),
90
(int) GSWINDEVICE->xframe.size.width,
91
(int) GSWINDEVICE->xframe.size.height);
100
if (_windowSurface != NULL)
102
cairo_surface_destroy(_windowSurface);
109
return GSWINDEVICE->xframe.size;
112
- (void) handleExposeRect: (NSRect)rect
114
cairo_t *windowCtx = cairo_create(_windowSurface);
116
double backupOffsetX, backupOffsetY;
118
// Temporairly cancel the device offset on the back buffer since
119
// we want to work with raw X11 pixel coordinates
121
cairo_surface_get_device_offset(_surface, &backupOffsetX, &backupOffsetY);
122
cairo_surface_set_device_offset(_surface, 0, 0);
124
// Copy the desired rectangle from the back buffer to the
127
// FIXME: should round
128
cairo_rectangle(windowCtx, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
129
cairo_clip(windowCtx);
130
cairo_set_source_surface(windowCtx, _surface, 0, 0);
131
cairo_set_operator(windowCtx, CAIRO_OPERATOR_SOURCE);
132
cairo_paint(windowCtx);
135
// cairo_reset_clip(windowCtx);
136
// cairo_set_source_rgba(windowCtx, 1.0, 0.0, 0.0, 0.5);
137
// cairo_rectangle(windowCtx, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
138
// cairo_stroke(windowCtx);
139
// NSLog(@"Exposing rect %@ with cairo. Status: '%s'", NSStringFromRect(rect), cairo_status_to_string(cairo_status(windowCtx)));
141
cairo_destroy(windowCtx);
143
// Restore device offset
144
cairo_surface_set_device_offset(_surface, backupOffsetX, backupOffsetY);