fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / canvas / source / cairo / cairo_xlib_cairo.cxx
blobbae6943a47bc15e9b2d7bcb96d36901e33e6418b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <utility>
22 #include <prex.h>
23 #include <X11/extensions/Xrender.h>
24 #include <X11/Xlib.h>
25 #include <postx.h>
27 #include "cairo_xlib_cairo.hxx"
29 #include <vcl/sysdata.hxx>
30 #include <vcl/bitmap.hxx>
31 #include <vcl/virdev.hxx>
32 #include <basegfx/vector/b2isize.hxx>
34 namespace
36 Pixmap limitXCreatePixmap(Display *display, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
38 // The X protocol request CreatePixmap puts an upper bound
39 // of 16 bit to the size.
41 // see, e.g. moz#424333, fdo#48961
42 // we've a duplicate of this in vcl :-(
43 if (width > SAL_MAX_INT16 || height > SAL_MAX_INT16)
45 SAL_WARN("canvas", "overlarge pixmap: " << width << " x " << height);
46 return None;
48 return XCreatePixmap(display, d, width, height, depth);
52 namespace cairo
55 #include <cairo-xlib.h>
56 #include <cairo-xlib-xrender.h>
58 // TODO(F3): svp headless case!
60 bool IsCairoWorking( OutputDevice* pOutDev )
62 if( !pOutDev )
63 return false;
65 Display* pDisplay = (Display*)pOutDev->GetSystemGfxData().pDisplay;
66 if( !pDisplay )
67 return false;
69 int nDummy;
70 return XQueryExtension( pDisplay, "RENDER", &nDummy, &nDummy, &nDummy );
73 X11SysData::X11SysData() :
74 pDisplay(NULL),
75 hDrawable(0),
76 pVisual(NULL),
77 nScreen(0),
78 nDepth(-1),
79 aColormap(-1),
80 pRenderFormat(NULL)
83 X11SysData::X11SysData( const SystemGraphicsData& pSysDat ) :
84 pDisplay(pSysDat.pDisplay),
85 hDrawable(pSysDat.hDrawable),
86 pVisual(pSysDat.pVisual),
87 nScreen(pSysDat.nScreen),
88 nDepth(pSysDat.nDepth),
89 aColormap(pSysDat.aColormap),
90 pRenderFormat(pSysDat.pXRenderFormat)
93 X11SysData::X11SysData( const SystemEnvData& pSysDat ) :
94 pDisplay(pSysDat.pDisplay),
95 hDrawable(pSysDat.aWindow),
96 pVisual(pSysDat.pVisual),
97 nScreen(pSysDat.nScreen),
98 nDepth(pSysDat.nDepth),
99 aColormap(pSysDat.aColormap),
100 pRenderFormat(NULL)
103 X11Pixmap::~X11Pixmap()
105 if( mpDisplay && mhDrawable )
106 XFreePixmap( (Display*)mpDisplay, mhDrawable );
110 * Surface::Surface: Create Canvas surface with existing data
111 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
112 * @param pSurface Cairo surface
114 * pSysData contains the platform native Drawable reference
115 * This constructor only stores data, it does no processing.
116 * It is used by e.g. Surface::getSimilar()
118 * Set the mpSurface as pSurface
120 X11Surface::X11Surface( const X11SysData& rSysData,
121 const X11PixmapSharedPtr& rPixmap,
122 const CairoSurfaceSharedPtr& pSurface ) :
123 maSysData(rSysData),
124 mpPixmap(rPixmap),
125 mpSurface(pSurface)
129 * Surface::Surface: Create generic Canvas surface using given Cairo Surface
131 * @param pSurface Cairo Surface
133 * This constructor only stores data, it does no processing.
134 * It is used with e.g. cairo_image_surface_create_for_data()
135 * Unlike other constructors, mpSysData is set to NULL
137 * Set the mpSurface as pSurface
139 X11Surface::X11Surface( const CairoSurfaceSharedPtr& pSurface ) :
140 maSysData(),
141 mpPixmap(),
142 mpSurface(pSurface)
146 * Surface::Surface: Create Canvas surface from Window reference.
147 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
148 * @param x horizontal location of the new surface
149 * @param y vertical location of the new surface
150 * @param width width of the new surface
151 * @param height height of the new surface
153 * pSysData contains the platform native Window reference.
155 * pSysData is used to create a surface on the Window
157 * Set the mpSurface to the new surface or NULL
159 X11Surface::X11Surface( const X11SysData& rSysData, int x, int y, int width, int height ) :
160 maSysData(rSysData),
161 mpPixmap(),
162 mpSurface(
163 cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
164 rSysData.hDrawable,
165 (Visual*)rSysData.pVisual,
166 width + x, height + y ),
167 &cairo_surface_destroy)
169 cairo_surface_set_device_offset(mpSurface.get(), x, y );
173 * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData
174 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
175 * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
176 * @param width width of the new surface
177 * @param height height of the new surface
179 * The pBmpData provides the imagedata that the created surface should contain.
181 * Set the mpSurface to the new surface or NULL
183 X11Surface::X11Surface( const X11SysData& rSysData,
184 const BitmapSystemData& rData ) :
185 maSysData( rSysData ),
186 mpPixmap(),
187 mpSurface(
188 cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
189 (Drawable)rData.aPixmap,
190 (Visual*) rSysData.pVisual,
191 rData.mnWidth, rData.mnHeight ),
192 &cairo_surface_destroy)
197 * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
199 * @return new Cairo or NULL
201 CairoSharedPtr X11Surface::getCairo() const
203 return CairoSharedPtr( cairo_create(mpSurface.get()),
204 &cairo_destroy );
208 * Surface::getSimilar: Create new similar Canvas surface
209 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
210 * @param width width of the new surface
211 * @param height height of the new surface
213 * Creates a new Canvas surface. This normally creates platform native surface, even though
214 * generic function is used.
216 * Cairo surface from aContent (cairo_content_t)
218 * @return new surface or NULL
220 SurfaceSharedPtr X11Surface::getSimilar( Content aContent, int width, int height ) const
222 Pixmap hPixmap;
224 if( maSysData.pDisplay && maSysData.hDrawable )
226 XRenderPictFormat* pFormat;
227 int nFormat;
229 switch (aContent)
231 case CAIRO_CONTENT_ALPHA:
232 nFormat = PictStandardA8;
233 break;
234 case CAIRO_CONTENT_COLOR:
235 nFormat = PictStandardRGB24;
236 break;
237 case CAIRO_CONTENT_COLOR_ALPHA:
238 default:
239 nFormat = PictStandardARGB32;
240 break;
243 pFormat = XRenderFindStandardFormat( (Display*)maSysData.pDisplay, nFormat );
244 hPixmap = limitXCreatePixmap( (Display*)maSysData.pDisplay, maSysData.hDrawable,
245 width > 0 ? width : 1, height > 0 ? height : 1,
246 pFormat->depth );
248 X11SysData aSysData(maSysData);
249 aSysData.pRenderFormat = pFormat;
250 return SurfaceSharedPtr(
251 new X11Surface( aSysData,
252 X11PixmapSharedPtr(
253 new X11Pixmap(hPixmap, maSysData.pDisplay)),
254 CairoSurfaceSharedPtr(
255 cairo_xlib_surface_create_with_xrender_format(
256 (Display*)maSysData.pDisplay,
257 hPixmap,
258 ScreenOfDisplay((Display *)maSysData.pDisplay, maSysData.nScreen),
259 pFormat, width, height ),
260 &cairo_surface_destroy) ));
262 else
263 return SurfaceSharedPtr(
264 new X11Surface( maSysData,
265 X11PixmapSharedPtr(),
266 CairoSurfaceSharedPtr(
267 cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
268 &cairo_surface_destroy )));
271 boost::shared_ptr<VirtualDevice> X11Surface::createVirtualDevice() const
273 SystemGraphicsData aSystemGraphicsData;
275 aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
276 aSystemGraphicsData.hDrawable = getDrawable();
277 aSystemGraphicsData.pXRenderFormat = getRenderFormat();
279 return boost::shared_ptr<VirtualDevice>(
280 new VirtualDevice( &aSystemGraphicsData, std::max( getDepth(), 0 ) ));
284 * Surface::Resize: Resizes the Canvas surface.
285 * @param width new width of the surface
286 * @param height new height of the surface
288 * Only used on X11.
290 * @return The new surface or NULL
292 void X11Surface::Resize( int width, int height )
294 cairo_xlib_surface_set_size( mpSurface.get(), width, height );
297 void X11Surface::flush() const
299 XSync( (Display*)maSysData.pDisplay, false );
303 * Surface::getDepth: Get the color depth of the Canvas surface.
305 * @return color depth
307 int X11Surface::getDepth() const
309 if( maSysData.pRenderFormat )
310 return ((XRenderPictFormat*) maSysData.pRenderFormat)->depth;
312 return -1;
315 SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
317 return SurfaceSharedPtr(new X11Surface(rSurface));
320 static X11SysData getSysData( const Window& rWindow )
322 const SystemEnvData* pSysData = GetSysData(&rWindow);
324 if( !pSysData )
325 return X11SysData();
326 else
327 return X11SysData(*pSysData);
330 static X11SysData getSysData( const VirtualDevice& rVirDev )
332 return X11SysData( rVirDev.GetSystemGfxData() );
335 SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice,
336 int x, int y, int width, int height )
338 if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
339 return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice),
340 x,y,width,height));
341 else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
342 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice),
343 x,y,width,height));
344 else
345 return SurfaceSharedPtr();
348 SurfaceSharedPtr createBitmapSurface( const OutputDevice& rRefDevice,
349 const BitmapSystemData& rData,
350 const Size& rSize )
352 OSL_TRACE( "requested size: %d x %d available size: %d x %d",
353 rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
354 if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
356 if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
357 return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice), rData ));
358 else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
359 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice), rData ));
362 return SurfaceSharedPtr();
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */