2 * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19 * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
24 * Except as contained in this notice, the name(s) of the above
25 * copyright holders shall not be used in advertising or otherwise to
26 * promote the sale, use or other dealings in this Software without
27 * prior written authorization.
30 #ifdef HAVE_DIX_CONFIG_H
31 #include <dix-config.h>
36 #include "scrnintstr.h"
38 #include "pixmapstr.h"
39 #include "windowstr.h"
40 #include "dixfontstr.h"
41 #include "mivalidate.h"
45 #include <OpenGL/OpenGL.h>
53 CreateGCProcPtr CreateGC
;
60 } DRISavedDrawableState
;
62 static DevPrivateKeyRec driGCKeyRec
;
63 #define driGCKey (&driGCKeyRec)
65 static DevPrivateKeyRec driWrapScreenKeyRec
;
66 #define driWrapScreenKey (&driWrapScreenKeyRec)
68 static GCOps driGCOps
;
70 #define wrap(priv, real, member, func) { \
71 priv->member = real->member; \
72 real->member = func; \
75 #define unwrap(priv, real, member) { \
76 real->member = priv->member; \
80 DRIGetGCPriv(GCPtr pGC
)
82 return dixLookupPrivate(&pGC
->devPrivates
, driGCKey
);
86 DRIUnwrapGC(GCPtr pGC
)
88 DRIGCRec
*pGCPriv
= DRIGetGCPriv(pGC
);
90 pGC
->ops
= pGCPriv
->originalOps
;
100 DRISurfaceSetDrawable(DrawablePtr pDraw
,
101 DRISavedDrawableState
*saved
)
103 saved
->didSave
= FALSE
;
105 if (pDraw
->type
== DRAWABLE_PIXMAP
) {
106 int pitch
, width
, height
, bpp
;
109 if (DRIGetPixmapData(pDraw
, &width
, &height
, &pitch
, &bpp
,
111 PixmapPtr pPix
= (PixmapPtr
)pDraw
;
113 saved
->devKind
= pPix
->devKind
;
114 saved
->devPrivate
.ptr
= pPix
->devPrivate
.ptr
;
115 saved
->didSave
= TRUE
;
117 pPix
->devKind
= pitch
;
118 pPix
->devPrivate
.ptr
= buffer
;
124 DRISurfaceRestoreDrawable(DrawablePtr pDraw
,
125 DRISavedDrawableState
*saved
)
127 PixmapPtr pPix
= (PixmapPtr
)pDraw
;
132 pPix
->devKind
= saved
->devKind
;
133 pPix
->devPrivate
.ptr
= saved
->devPrivate
.ptr
;
137 DRIFillSpans(DrawablePtr dst
, GCPtr pGC
, int nInit
,
138 DDXPointPtr pptInit
, int *pwidthInit
,
141 DRISavedDrawableState saved
;
143 DRISurfaceSetDrawable(dst
, &saved
);
147 pGC
->ops
->FillSpans(dst
, pGC
, nInit
, pptInit
, pwidthInit
, sorted
);
151 DRISurfaceRestoreDrawable(dst
, &saved
);
155 DRISetSpans(DrawablePtr dst
, GCPtr pGC
, char *pSrc
,
156 DDXPointPtr pptInit
, int *pwidthInit
,
157 int nspans
, int sorted
)
159 DRISavedDrawableState saved
;
161 DRISurfaceSetDrawable(dst
, &saved
);
165 pGC
->ops
->SetSpans(dst
, pGC
, pSrc
, pptInit
, pwidthInit
, nspans
, sorted
);
169 DRISurfaceRestoreDrawable(dst
, &saved
);
173 DRIPutImage(DrawablePtr dst
, GCPtr pGC
,
174 int depth
, int x
, int y
, int w
, int h
,
175 int leftPad
, int format
, char *pBits
)
177 DRISavedDrawableState saved
;
179 DRISurfaceSetDrawable(dst
, &saved
);
183 pGC
->ops
->PutImage(dst
, pGC
, depth
, x
, y
, w
, h
, leftPad
, format
, pBits
);
187 DRISurfaceRestoreDrawable(dst
, &saved
);
191 DRICopyArea(DrawablePtr pSrc
, DrawablePtr dst
, GCPtr pGC
,
192 int srcx
, int srcy
, int w
, int h
,
196 DRISavedDrawableState pSrcSaved
, dstSaved
;
198 DRISurfaceSetDrawable(pSrc
, &pSrcSaved
);
199 DRISurfaceSetDrawable(dst
, &dstSaved
);
203 pReg
= pGC
->ops
->CopyArea(pSrc
, dst
, pGC
, srcx
, srcy
, w
, h
, dstx
, dsty
);
207 DRISurfaceRestoreDrawable(pSrc
, &pSrcSaved
);
208 DRISurfaceRestoreDrawable(dst
, &dstSaved
);
214 DRICopyPlane(DrawablePtr pSrc
, DrawablePtr dst
,
215 GCPtr pGC
, int srcx
, int srcy
,
216 int w
, int h
, int dstx
, int dsty
,
220 DRISavedDrawableState pSrcSaved
, dstSaved
;
222 DRISurfaceSetDrawable(pSrc
, &pSrcSaved
);
223 DRISurfaceSetDrawable(dst
, &dstSaved
);
227 pReg
= pGC
->ops
->CopyPlane(pSrc
, dst
, pGC
, srcx
, srcy
, w
, h
, dstx
, dsty
,
232 DRISurfaceRestoreDrawable(pSrc
, &pSrcSaved
);
233 DRISurfaceRestoreDrawable(dst
, &dstSaved
);
239 DRIPolyPoint(DrawablePtr dst
, GCPtr pGC
,
240 int mode
, int npt
, DDXPointPtr pptInit
)
242 DRISavedDrawableState saved
;
244 DRISurfaceSetDrawable(dst
, &saved
);
248 pGC
->ops
->PolyPoint(dst
, pGC
, mode
, npt
, pptInit
);
252 DRISurfaceRestoreDrawable(dst
, &saved
);
256 DRIPolylines(DrawablePtr dst
, GCPtr pGC
,
257 int mode
, int npt
, DDXPointPtr pptInit
)
259 DRISavedDrawableState saved
;
261 DRISurfaceSetDrawable(dst
, &saved
);
265 pGC
->ops
->Polylines(dst
, pGC
, mode
, npt
, pptInit
);
269 DRISurfaceRestoreDrawable(dst
, &saved
);
273 DRIPolySegment(DrawablePtr dst
, GCPtr pGC
,
274 int nseg
, xSegment
*pSeg
)
276 DRISavedDrawableState saved
;
278 DRISurfaceSetDrawable(dst
, &saved
);
282 pGC
->ops
->PolySegment(dst
, pGC
, nseg
, pSeg
);
286 DRISurfaceRestoreDrawable(dst
, &saved
);
290 DRIPolyRectangle(DrawablePtr dst
, GCPtr pGC
,
291 int nRects
, xRectangle
*pRects
)
293 DRISavedDrawableState saved
;
295 DRISurfaceSetDrawable(dst
, &saved
);
299 pGC
->ops
->PolyRectangle(dst
, pGC
, nRects
, pRects
);
303 DRISurfaceRestoreDrawable(dst
, &saved
);
306 DRIPolyArc(DrawablePtr dst
, GCPtr pGC
, int narcs
, xArc
*parcs
)
308 DRISavedDrawableState saved
;
310 DRISurfaceSetDrawable(dst
, &saved
);
314 pGC
->ops
->PolyArc(dst
, pGC
, narcs
, parcs
);
318 DRISurfaceRestoreDrawable(dst
, &saved
);
322 DRIFillPolygon(DrawablePtr dst
, GCPtr pGC
,
323 int shape
, int mode
, int count
,
326 DRISavedDrawableState saved
;
328 DRISurfaceSetDrawable(dst
, &saved
);
332 pGC
->ops
->FillPolygon(dst
, pGC
, shape
, mode
, count
, pptInit
);
336 DRISurfaceRestoreDrawable(dst
, &saved
);
340 DRIPolyFillRect(DrawablePtr dst
, GCPtr pGC
,
341 int nRectsInit
, xRectangle
*pRectsInit
)
343 DRISavedDrawableState saved
;
345 DRISurfaceSetDrawable(dst
, &saved
);
349 pGC
->ops
->PolyFillRect(dst
, pGC
, nRectsInit
, pRectsInit
);
353 DRISurfaceRestoreDrawable(dst
, &saved
);
357 DRIPolyFillArc(DrawablePtr dst
, GCPtr pGC
,
358 int narcsInit
, xArc
*parcsInit
)
360 DRISavedDrawableState saved
;
362 DRISurfaceSetDrawable(dst
, &saved
);
366 pGC
->ops
->PolyFillArc(dst
, pGC
, narcsInit
, parcsInit
);
370 DRISurfaceRestoreDrawable(dst
, &saved
);
374 DRIPolyText8(DrawablePtr dst
, GCPtr pGC
,
375 int x
, int y
, int count
, char *chars
)
378 DRISavedDrawableState saved
;
380 DRISurfaceSetDrawable(dst
, &saved
);
384 ret
= pGC
->ops
->PolyText8(dst
, pGC
, x
, y
, count
, chars
);
388 DRISurfaceRestoreDrawable(dst
, &saved
);
394 DRIPolyText16(DrawablePtr dst
, GCPtr pGC
,
395 int x
, int y
, int count
, unsigned short *chars
)
398 DRISavedDrawableState saved
;
400 DRISurfaceSetDrawable(dst
, &saved
);
404 ret
= pGC
->ops
->PolyText16(dst
, pGC
, x
, y
, count
, chars
);
408 DRISurfaceRestoreDrawable(dst
, &saved
);
414 DRIImageText8(DrawablePtr dst
, GCPtr pGC
,
415 int x
, int y
, int count
, char *chars
)
417 DRISavedDrawableState saved
;
419 DRISurfaceSetDrawable(dst
, &saved
);
423 pGC
->ops
->ImageText8(dst
, pGC
, x
, y
, count
, chars
);
427 DRISurfaceRestoreDrawable(dst
, &saved
);
431 DRIImageText16(DrawablePtr dst
, GCPtr pGC
,
432 int x
, int y
, int count
, unsigned short *chars
)
434 DRISavedDrawableState saved
;
436 DRISurfaceSetDrawable(dst
, &saved
);
440 pGC
->ops
->ImageText16(dst
, pGC
, x
, y
, count
, chars
);
444 DRISurfaceRestoreDrawable(dst
, &saved
);
448 DRIImageGlyphBlt(DrawablePtr dst
, GCPtr pGC
,
449 int x
, int y
, unsigned int nglyphInit
,
450 CharInfoPtr
*ppciInit
, pointer unused
)
452 DRISavedDrawableState saved
;
454 DRISurfaceSetDrawable(dst
, &saved
);
458 pGC
->ops
->ImageGlyphBlt(dst
, pGC
, x
, y
, nglyphInit
, ppciInit
, unused
);
462 DRISurfaceRestoreDrawable(dst
, &saved
);
466 DRIPolyGlyphBlt(DrawablePtr dst
, GCPtr pGC
,
467 int x
, int y
, unsigned int nglyph
,
468 CharInfoPtr
*ppci
, pointer pglyphBase
)
470 DRISavedDrawableState saved
;
472 DRISurfaceSetDrawable(dst
, &saved
);
476 pGC
->ops
->PolyGlyphBlt(dst
, pGC
, x
, y
, nglyph
, ppci
, pglyphBase
);
480 DRISurfaceRestoreDrawable(dst
, &saved
);
484 DRIPushPixels(GCPtr pGC
, PixmapPtr pBitMap
, DrawablePtr dst
,
485 int dx
, int dy
, int xOrg
, int yOrg
)
487 DRISavedDrawableState bitMapSaved
, dstSaved
;
489 DRISurfaceSetDrawable(&pBitMap
->drawable
, &bitMapSaved
);
490 DRISurfaceSetDrawable(dst
, &dstSaved
);
494 pGC
->ops
->PushPixels(pGC
, pBitMap
, dst
, dx
, dy
, xOrg
, yOrg
);
498 DRISurfaceRestoreDrawable(&pBitMap
->drawable
, &bitMapSaved
);
499 DRISurfaceRestoreDrawable(dst
, &dstSaved
);
502 static GCOps driGCOps
= {
526 DRICreateGC(GCPtr pGC
)
528 ScreenPtr pScreen
= pGC
->pScreen
;
529 DRIWrapScreenRec
*pScreenPriv
;
533 pScreenPriv
= dixLookupPrivate(&pScreen
->devPrivates
, driWrapScreenKey
);
535 pGCPriv
= DRIGetGCPriv(pGC
);
537 unwrap(pScreenPriv
, pScreen
, CreateGC
);
538 ret
= pScreen
->CreateGC(pGC
);
541 pGCPriv
->originalOps
= pGC
->ops
;
542 pGC
->ops
= &driGCOps
;
545 wrap(pScreenPriv
, pScreen
, CreateGC
, DRICreateGC
);
550 /* Return false if an error occurred. */
552 DRIWrapInit(ScreenPtr pScreen
)
554 DRIWrapScreenRec
*pScreenPriv
;
556 if (!dixRegisterPrivateKey(&driGCKeyRec
, PRIVATE_GC
, sizeof(DRIGCRec
)))
559 if (!dixRegisterPrivateKey(&driWrapScreenKeyRec
, PRIVATE_SCREEN
,
560 sizeof(DRIWrapScreenRec
)))
563 pScreenPriv
= dixGetPrivateAddr(&pScreen
->devPrivates
,
564 &driWrapScreenKeyRec
);
565 pScreenPriv
->CreateGC
= pScreen
->CreateGC
;
566 pScreen
->CreateGC
= DRICreateGC
;