~ubuntu-branches/ubuntu/raring/gnustep-back/raring

« back to all changes in this revision

Viewing changes to Source/cairo/XGCairoModernSurface.m

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2012-11-21 22:57:37 UTC
  • mfrom: (1.2.9) (15.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121121225737-rme3qx928vtesqo7
Tags: 0.22.0-1ubuntu1
* Merge from Debian experimental. Remaining change:
  - debian/rules (build-arch) Depend on debian/build-indep-stamp to build
    the docs files included in every package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2011 Free Software Foundation, Inc.
 
3
 
 
4
   Author: Eric Wasylishen <ewasylishen@gmail.com>
 
5
 
 
6
   This file is part of GNUstep.
 
7
 
 
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.
 
12
 
 
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.
 
17
 
 
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.
 
23
*/
 
24
 
 
25
#include "config.h"
 
26
#include "x11/XGServer.h"
 
27
#include "x11/XGServerWindow.h"
 
28
#include "cairo/XGCairoModernSurface.h"
 
29
#include <cairo-xlib.h>
 
30
 
 
31
#define GSWINDEVICE ((gswindow_device_t *)gsDevice)
 
32
 
 
33
@implementation XGCairoModernSurface
 
34
 
 
35
- (id) initWithDevice: (void *)device
 
36
{
 
37
  cairo_surface_t *windowsurface;
 
38
 
 
39
  gsDevice = device;
 
40
 
 
41
  // Create a cairo xlib surface for the window
 
42
  {
 
43
    Display *dpy = GSWINDEVICE->display;
 
44
    Visual *visual;
 
45
    XWindowAttributes attributes;
 
46
    
 
47
    if (!XGetWindowAttributes(dpy, GSWINDEVICE->ident, &attributes))
 
48
      {
 
49
        visual = DefaultVisual(dpy, DefaultScreen(dpy));
 
50
      }
 
51
    else
 
52
      {
 
53
        visual = attributes.visual;
 
54
      }
 
55
    
 
56
    windowsurface = cairo_xlib_surface_create(GSWINDEVICE->display,
 
57
                                              GSWINDEVICE->ident,
 
58
                                              visual,
 
59
                                              GSWINDEVICE->xframe.size.width,
 
60
                                              GSWINDEVICE->xframe.size.height);
 
61
  }
 
62
 
 
63
 
 
64
  if (GSWINDEVICE->type == NSBackingStoreNonretained)
 
65
    {
 
66
      // Don't double-buffer:
 
67
      // use the window surface as the drawing destination.
 
68
 
 
69
      _surface = windowsurface;
 
70
    }
 
71
  else
 
72
    {
 
73
      // Do double-buffer:
 
74
      // Create a similar surface to the window which supports alpha
 
75
 
 
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;
 
80
 
 
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);
 
86
 
 
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);
 
92
      */
 
93
    }
 
94
  
 
95
  return self;
 
96
}
 
97
 
 
98
- (void) dealloc
 
99
{
 
100
  if (_windowSurface != NULL)
 
101
    {
 
102
      cairo_surface_destroy(_windowSurface);
 
103
    }
 
104
  [super dealloc];
 
105
}
 
106
 
 
107
- (NSSize) size
 
108
{
 
109
  return GSWINDEVICE->xframe.size;
 
110
}
 
111
 
 
112
- (void) handleExposeRect: (NSRect)rect
 
113
{
 
114
  cairo_t *windowCtx = cairo_create(_windowSurface);
 
115
 
 
116
  double backupOffsetX, backupOffsetY;
 
117
 
 
118
  // Temporairly cancel the device offset on the back buffer since
 
119
  // we want to work with raw X11 pixel coordinates
 
120
 
 
121
  cairo_surface_get_device_offset(_surface, &backupOffsetX, &backupOffsetY);
 
122
  cairo_surface_set_device_offset(_surface, 0, 0);
 
123
 
 
124
  // Copy the desired rectangle from the back buffer to the
 
125
  // front buffer
 
126
 
 
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);
 
133
 
 
134
  // Debugging
 
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)));
 
140
 
 
141
  cairo_destroy(windowCtx);
 
142
  
 
143
  // Restore device offset
 
144
  cairo_surface_set_device_offset(_surface, backupOffsetX, backupOffsetY);
 
145
}
 
146
 
 
147
@end
 
148