1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Oracle Corporation code.
17 * The Initial Developer of the Original Code is Oracle Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
22 * Stuart Parmenter <pavlov@pavlov.net>
23 * Vladimir Vukicevic <vladimir@pobox.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "gfxXlibSurface.h"
42 #include "cairo-xlib.h"
43 #include "cairo-xlib-xrender.h"
45 static cairo_user_data_key_t pixmap_free_key
;
52 static void pixmap_free_func (void *);
54 #define XLIB_IMAGE_SIDE_SIZE_LIMIT 0xffff
56 gfxXlibSurface::gfxXlibSurface(Display
*dpy
, Drawable drawable
, Visual
*visual
)
57 : mPixmapTaken(PR_FALSE
), mDisplay(dpy
), mDrawable(drawable
)
60 cairo_surface_t
*surf
= cairo_xlib_surface_create(dpy
, drawable
, visual
, mSize
.width
, mSize
.height
);
64 gfxXlibSurface::gfxXlibSurface(Display
*dpy
, Drawable drawable
, Visual
*visual
, const gfxIntSize
& size
)
65 : mPixmapTaken(PR_FALSE
), mDisplay(dpy
), mDrawable(drawable
), mSize(size
)
67 if (!CheckSurfaceSize(size
, XLIB_IMAGE_SIDE_SIZE_LIMIT
))
70 cairo_surface_t
*surf
= cairo_xlib_surface_create(dpy
, drawable
, visual
, mSize
.width
, mSize
.height
);
74 gfxXlibSurface::gfxXlibSurface(Display
*dpy
, Visual
*visual
, const gfxIntSize
& size
)
75 : mPixmapTaken(PR_FALSE
), mDisplay(dpy
), mSize(size
)
78 if (!CheckSurfaceSize(size
, XLIB_IMAGE_SIDE_SIZE_LIMIT
))
81 mDrawable
= (Drawable
)XCreatePixmap(dpy
,
82 RootWindow(dpy
, DefaultScreen(dpy
)),
83 mSize
.width
, mSize
.height
,
84 DefaultDepth(dpy
, DefaultScreen(dpy
)));
86 cairo_surface_t
*surf
= cairo_xlib_surface_create(dpy
, mDrawable
, visual
, mSize
.width
, mSize
.height
);
92 gfxXlibSurface::gfxXlibSurface(Display
*dpy
, Drawable drawable
, XRenderPictFormat
*format
,
93 const gfxIntSize
& size
)
94 : mPixmapTaken(PR_FALSE
), mDisplay(dpy
), mDrawable(drawable
), mSize(size
)
96 if (!CheckSurfaceSize(size
, XLIB_IMAGE_SIDE_SIZE_LIMIT
))
99 cairo_surface_t
*surf
= cairo_xlib_surface_create_with_xrender_format(dpy
, drawable
,
100 ScreenOfDisplay(dpy
,DefaultScreen(dpy
)),
101 format
, mSize
.width
, mSize
.height
);
105 gfxXlibSurface::gfxXlibSurface(Display
*dpy
, XRenderPictFormat
*format
, const gfxIntSize
& size
)
106 : mPixmapTaken(PR_FALSE
), mDisplay(dpy
), mSize(size
)
108 mDrawable
= (Drawable
)XCreatePixmap(dpy
,
109 RootWindow(dpy
, DefaultScreen(dpy
)),
110 mSize
.width
, mSize
.height
,
113 cairo_surface_t
*surf
= cairo_xlib_surface_create_with_xrender_format(dpy
, mDrawable
,
114 ScreenOfDisplay(dpy
,DefaultScreen(dpy
)),
115 format
, mSize
.width
, mSize
.height
);
120 gfxXlibSurface::gfxXlibSurface(cairo_surface_t
*csurf
)
121 : mPixmapTaken(PR_FALSE
), mSize(-1.0, -1.0)
123 mDrawable
= cairo_xlib_surface_get_drawable(csurf
);
124 mDisplay
= cairo_xlib_surface_get_display(csurf
);
126 Init(csurf
, PR_TRUE
);
129 gfxXlibSurface::~gfxXlibSurface()
134 gfxXlibSurface::DoSizeQuery()
136 // figure out width/height/depth
138 int x_ignore
, y_ignore
;
139 unsigned int bwidth_ignore
, width
, height
, depth
;
141 XGetGeometry(mDisplay
,
143 &root_ignore
, &x_ignore
, &y_ignore
,
145 &bwidth_ignore
, &depth
);
148 mSize
.height
= height
;
152 gfxXlibSurface::FindRenderFormat(Display
*dpy
, gfxImageFormat format
)
155 case ImageFormatARGB32
:
156 return XRenderFindStandardFormat (dpy
, PictStandardARGB32
);
158 case ImageFormatRGB24
:
159 return XRenderFindStandardFormat (dpy
, PictStandardRGB24
);
162 return XRenderFindStandardFormat (dpy
, PictStandardA8
);
165 return XRenderFindStandardFormat (dpy
, PictStandardA1
);
171 return (XRenderPictFormat
*)NULL
;
175 gfxXlibSurface::TakePixmap()
180 pixmap_free_struct
*pfs
= new pixmap_free_struct
;
182 pfs
->pixmap
= mDrawable
;
184 cairo_surface_set_user_data (CairoSurface(),
189 mPixmapTaken
= PR_TRUE
;
193 pixmap_free_func (void *data
)
195 pixmap_free_struct
*pfs
= (pixmap_free_struct
*) data
;
197 XFreePixmap (pfs
->dpy
, pfs
->pixmap
);