michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFX_XLIBSURFACE_H michael@0: #define GFX_XLIBSURFACE_H michael@0: michael@0: #include "gfxASurface.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #if defined(GL_PROVIDER_GLX) michael@0: #include "GLXLibrary.h" michael@0: #endif michael@0: michael@0: #include "nsSize.h" michael@0: michael@0: class gfxXlibSurface : public gfxASurface { michael@0: public: michael@0: // construct a wrapper around the specified drawable with dpy/visual. michael@0: // Will use XGetGeometry to query the window/pixmap size. michael@0: gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual); michael@0: michael@0: // construct a wrapper around the specified drawable with dpy/visual, michael@0: // and known width/height. michael@0: gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size); michael@0: michael@0: // construct a wrapper around the specified drawable with dpy/format, michael@0: // and known width/height. michael@0: gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFormat *format, michael@0: const gfxIntSize& size); michael@0: michael@0: gfxXlibSurface(cairo_surface_t *csurf); michael@0: michael@0: // create a new Pixmap and wrapper surface. michael@0: // |relatedDrawable| provides a hint to the server for determining whether michael@0: // the pixmap should be in video or system memory. It must be on michael@0: // |screen| (if specified). michael@0: static already_AddRefed michael@0: Create(Screen *screen, Visual *visual, const gfxIntSize& size, michael@0: Drawable relatedDrawable = None); michael@0: static cairo_surface_t * michael@0: CreateCairoSurface(Screen *screen, Visual *visual, const gfxIntSize& size, michael@0: Drawable relatedDrawable = None); michael@0: static already_AddRefed michael@0: Create(Screen* screen, XRenderPictFormat *format, const gfxIntSize& size, michael@0: Drawable relatedDrawable = None); michael@0: michael@0: virtual ~gfxXlibSurface(); michael@0: michael@0: virtual already_AddRefed michael@0: CreateSimilarSurface(gfxContentType aType, const gfxIntSize& aSize); michael@0: virtual void Finish() MOZ_OVERRIDE; michael@0: michael@0: virtual const gfxIntSize GetSize() const; michael@0: michael@0: Display* XDisplay() { return mDisplay; } michael@0: Screen* XScreen(); michael@0: Drawable XDrawable() { return mDrawable; } michael@0: XRenderPictFormat* XRenderFormat(); michael@0: michael@0: static int DepthOfVisual(const Screen* screen, const Visual* visual); michael@0: static Visual* FindVisual(Screen* screen, gfxImageFormat format); michael@0: static XRenderPictFormat *FindRenderFormat(Display *dpy, gfxImageFormat format); michael@0: static bool GetColormapAndVisual(cairo_surface_t* aXlibSurface, Colormap* colormap, Visual **visual); michael@0: michael@0: // take ownership of a passed-in Pixmap, calling XFreePixmap on it michael@0: // when the gfxXlibSurface is destroyed. michael@0: void TakePixmap(); michael@0: michael@0: // Release ownership of this surface's Pixmap. This is only valid michael@0: // on gfxXlibSurfaces for which the user called TakePixmap(), or michael@0: // on those created by a Create() factory method. michael@0: Drawable ReleasePixmap(); michael@0: michael@0: // Find a visual and colormap pair suitable for rendering to this surface. michael@0: bool GetColormapAndVisual(Colormap* colormap, Visual **visual); michael@0: michael@0: // This surface is a wrapper around X pixmaps, which are stored in the X michael@0: // server, not the main application. michael@0: virtual gfxMemoryLocation GetMemoryLocation() const; michael@0: michael@0: #if defined(GL_PROVIDER_GLX) michael@0: GLXPixmap GetGLXPixmap(); michael@0: #endif michael@0: michael@0: // Return true if cairo will take its slow path when this surface is used michael@0: // in a pattern with EXTEND_PAD. As a workaround for XRender's RepeatPad michael@0: // not being implemented correctly on old X servers, cairo avoids XRender michael@0: // and instead reads back to perform EXTEND_PAD with pixman. Cairo does michael@0: // this for servers older than xorg-server 1.7. michael@0: bool IsPadSlow() { michael@0: // The test here matches that for buggy_pad_reflect in michael@0: // _cairo_xlib_device_create. michael@0: return VendorRelease(mDisplay) >= 60700000 || michael@0: VendorRelease(mDisplay) < 10699000; michael@0: } michael@0: michael@0: protected: michael@0: // if TakePixmap() has been called on this michael@0: bool mPixmapTaken; michael@0: michael@0: Display *mDisplay; michael@0: Drawable mDrawable; michael@0: michael@0: const gfxIntSize DoSizeQuery(); michael@0: michael@0: #if defined(GL_PROVIDER_GLX) michael@0: GLXPixmap mGLXPixmap; michael@0: #endif michael@0: }; michael@0: michael@0: #endif /* GFX_XLIBSURFACE_H */