Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xquartz / xpr / driWrap.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
3 *
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:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
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.
23 *
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.
28 */
29
30#ifdef HAVE_DIX_CONFIG_H
31#include <dix-config.h>
32#endif
33
34#include <stddef.h>
35#include "mi.h"
36#include "scrnintstr.h"
37#include "gcstruct.h"
38#include "pixmapstr.h"
39#include "windowstr.h"
40#include "dixfontstr.h"
41#include "mivalidate.h"
42#include "driWrap.h"
43#include "dri.h"
44
45#include <OpenGL/OpenGL.h>
46
47typedef struct {
48 GCOps *originalOps;
49} DRIGCRec;
50
51typedef struct {
52 GCOps *originalOps;
53 CreateGCProcPtr CreateGC;
54} DRIWrapScreenRec;
55
56typedef struct {
57 Bool didSave;
58 int devKind;
59 DevUnion devPrivate;
60} DRISavedDrawableState;
61
62static DevPrivateKeyRec driGCKeyRec;
63#define driGCKey (&driGCKeyRec)
64
65static DevPrivateKeyRec driWrapScreenKeyRec;
66#define driWrapScreenKey (&driWrapScreenKeyRec)
67
68static GCOps driGCOps;
69
70#define wrap(priv, real, member, func) { \
71 priv->member = real->member; \
72 real->member = func; \
73}
74
75#define unwrap(priv, real, member) { \
76 real->member = priv->member; \
77}
78
79static DRIGCRec *
80DRIGetGCPriv(GCPtr pGC)
81{
82 return dixLookupPrivate(&pGC->devPrivates, driGCKey);
83}
84
85static void
86DRIUnwrapGC(GCPtr pGC)
87{
88 DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
89
90 pGC->ops = pGCPriv->originalOps;
91}
92
93static void
94DRIWrapGC(GCPtr pGC)
95{
96 pGC->ops = &driGCOps;
97}
98
99static void
100DRISurfaceSetDrawable(DrawablePtr pDraw,
101 DRISavedDrawableState *saved)
102{
103 saved->didSave = FALSE;
104
105 if (pDraw->type == DRAWABLE_PIXMAP) {
106 int pitch, width, height, bpp;
107 void *buffer;
108
109 if (DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp,
110 &buffer)) {
111 PixmapPtr pPix = (PixmapPtr)pDraw;
112
113 saved->devKind = pPix->devKind;
114 saved->devPrivate.ptr = pPix->devPrivate.ptr;
115 saved->didSave = TRUE;
116
117 pPix->devKind = pitch;
118 pPix->devPrivate.ptr = buffer;
119 }
120 }
121}
122
123static void
124DRISurfaceRestoreDrawable(DrawablePtr pDraw,
125 DRISavedDrawableState *saved)
126{
127 PixmapPtr pPix = (PixmapPtr)pDraw;
128
129 if (!saved->didSave)
130 return;
131
132 pPix->devKind = saved->devKind;
133 pPix->devPrivate.ptr = saved->devPrivate.ptr;
134}
135
136static void
137DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
138 DDXPointPtr pptInit, int *pwidthInit,
139 int sorted)
140{
141 DRISavedDrawableState saved;
142
143 DRISurfaceSetDrawable(dst, &saved);
144
145 DRIUnwrapGC(pGC);
146
147 pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
148
149 DRIWrapGC(pGC);
150
151 DRISurfaceRestoreDrawable(dst, &saved);
152}
153
154static void
155DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
156 DDXPointPtr pptInit, int *pwidthInit,
157 int nspans, int sorted)
158{
159 DRISavedDrawableState saved;
160
161 DRISurfaceSetDrawable(dst, &saved);
162
163 DRIUnwrapGC(pGC);
164
165 pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted);
166
167 DRIWrapGC(pGC);
168
169 DRISurfaceRestoreDrawable(dst, &saved);
170}
171
172static void
173DRIPutImage(DrawablePtr dst, GCPtr pGC,
174 int depth, int x, int y, int w, int h,
175 int leftPad, int format, char *pBits)
176{
177 DRISavedDrawableState saved;
178
179 DRISurfaceSetDrawable(dst, &saved);
180
181 DRIUnwrapGC(pGC);
182
183 pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits);
184
185 DRIWrapGC(pGC);
186
187 DRISurfaceRestoreDrawable(dst, &saved);
188}
189
190static RegionPtr
191DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
192 int srcx, int srcy, int w, int h,
193 int dstx, int dsty)
194{
195 RegionPtr pReg;
196 DRISavedDrawableState pSrcSaved, dstSaved;
197
198 DRISurfaceSetDrawable(pSrc, &pSrcSaved);
199 DRISurfaceSetDrawable(dst, &dstSaved);
200
201 DRIUnwrapGC(pGC);
202
203 pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
204
205 DRIWrapGC(pGC);
206
207 DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
208 DRISurfaceRestoreDrawable(dst, &dstSaved);
209
210 return pReg;
211}
212
213static RegionPtr
214DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst,
215 GCPtr pGC, int srcx, int srcy,
216 int w, int h, int dstx, int dsty,
217 unsigned long plane)
218{
219 RegionPtr pReg;
220 DRISavedDrawableState pSrcSaved, dstSaved;
221
222 DRISurfaceSetDrawable(pSrc, &pSrcSaved);
223 DRISurfaceSetDrawable(dst, &dstSaved);
224
225 DRIUnwrapGC(pGC);
226
227 pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty,
228 plane);
229
230 DRIWrapGC(pGC);
231
232 DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
233 DRISurfaceRestoreDrawable(dst, &dstSaved);
234
235 return pReg;
236}
237
238static void
239DRIPolyPoint(DrawablePtr dst, GCPtr pGC,
240 int mode, int npt, DDXPointPtr pptInit)
241{
242 DRISavedDrawableState saved;
243
244 DRISurfaceSetDrawable(dst, &saved);
245
246 DRIUnwrapGC(pGC);
247
248 pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
249
250 DRIWrapGC(pGC);
251
252 DRISurfaceRestoreDrawable(dst, &saved);
253}
254
255static void
256DRIPolylines(DrawablePtr dst, GCPtr pGC,
257 int mode, int npt, DDXPointPtr pptInit)
258{
259 DRISavedDrawableState saved;
260
261 DRISurfaceSetDrawable(dst, &saved);
262
263 DRIUnwrapGC(pGC);
264
265 pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
266
267 DRIWrapGC(pGC);
268
269 DRISurfaceRestoreDrawable(dst, &saved);
270}
271
272static void
273DRIPolySegment(DrawablePtr dst, GCPtr pGC,
274 int nseg, xSegment *pSeg)
275{
276 DRISavedDrawableState saved;
277
278 DRISurfaceSetDrawable(dst, &saved);
279
280 DRIUnwrapGC(pGC);
281
282 pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
283
284 DRIWrapGC(pGC);
285
286 DRISurfaceRestoreDrawable(dst, &saved);
287}
288
289static void
290DRIPolyRectangle(DrawablePtr dst, GCPtr pGC,
291 int nRects, xRectangle *pRects)
292{
293 DRISavedDrawableState saved;
294
295 DRISurfaceSetDrawable(dst, &saved);
296
297 DRIUnwrapGC(pGC);
298
299 pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
300
301 DRIWrapGC(pGC);
302
303 DRISurfaceRestoreDrawable(dst, &saved);
304}
305static void
306DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs)
307{
308 DRISavedDrawableState saved;
309
310 DRISurfaceSetDrawable(dst, &saved);
311
312 DRIUnwrapGC(pGC);
313
314 pGC->ops->PolyArc(dst, pGC, narcs, parcs);
315
316 DRIWrapGC(pGC);
317
318 DRISurfaceRestoreDrawable(dst, &saved);
319}
320
321static void
322DRIFillPolygon(DrawablePtr dst, GCPtr pGC,
323 int shape, int mode, int count,
324 DDXPointPtr pptInit)
325{
326 DRISavedDrawableState saved;
327
328 DRISurfaceSetDrawable(dst, &saved);
329
330 DRIUnwrapGC(pGC);
331
332 pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
333
334 DRIWrapGC(pGC);
335
336 DRISurfaceRestoreDrawable(dst, &saved);
337}
338
339static void
340DRIPolyFillRect(DrawablePtr dst, GCPtr pGC,
341 int nRectsInit, xRectangle *pRectsInit)
342{
343 DRISavedDrawableState saved;
344
345 DRISurfaceSetDrawable(dst, &saved);
346
347 DRIUnwrapGC(pGC);
348
349 pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
350
351 DRIWrapGC(pGC);
352
353 DRISurfaceRestoreDrawable(dst, &saved);
354}
355
356static void
357DRIPolyFillArc(DrawablePtr dst, GCPtr pGC,
358 int narcsInit, xArc *parcsInit)
359{
360 DRISavedDrawableState saved;
361
362 DRISurfaceSetDrawable(dst, &saved);
363
364 DRIUnwrapGC(pGC);
365
366 pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
367
368 DRIWrapGC(pGC);
369
370 DRISurfaceRestoreDrawable(dst, &saved);
371}
372
373static int
374DRIPolyText8(DrawablePtr dst, GCPtr pGC,
375 int x, int y, int count, char *chars)
376{
377 int ret;
378 DRISavedDrawableState saved;
379
380 DRISurfaceSetDrawable(dst, &saved);
381
382 DRIUnwrapGC(pGC);
383
384 ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
385
386 DRIWrapGC(pGC);
387
388 DRISurfaceRestoreDrawable(dst, &saved);
389
390 return ret;
391}
392
393static int
394DRIPolyText16(DrawablePtr dst, GCPtr pGC,
395 int x, int y, int count, unsigned short *chars)
396{
397 int ret;
398 DRISavedDrawableState saved;
399
400 DRISurfaceSetDrawable(dst, &saved);
401
402 DRIUnwrapGC(pGC);
403
404 ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
405
406 DRIWrapGC(pGC);
407
408 DRISurfaceRestoreDrawable(dst, &saved);
409
410 return ret;
411}
412
413static void
414DRIImageText8(DrawablePtr dst, GCPtr pGC,
415 int x, int y, int count, char *chars)
416{
417 DRISavedDrawableState saved;
418
419 DRISurfaceSetDrawable(dst, &saved);
420
421 DRIUnwrapGC(pGC);
422
423 pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
424
425 DRIWrapGC(pGC);
426
427 DRISurfaceRestoreDrawable(dst, &saved);
428}
429
430static void
431DRIImageText16(DrawablePtr dst, GCPtr pGC,
432 int x, int y, int count, unsigned short *chars)
433{
434 DRISavedDrawableState saved;
435
436 DRISurfaceSetDrawable(dst, &saved);
437
438 DRIUnwrapGC(pGC);
439
440 pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
441
442 DRIWrapGC(pGC);
443
444 DRISurfaceRestoreDrawable(dst, &saved);
445}
446
447static void
448DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
449 int x, int y, unsigned int nglyphInit,
450 CharInfoPtr *ppciInit, pointer unused)
451{
452 DRISavedDrawableState saved;
453
454 DRISurfaceSetDrawable(dst, &saved);
455
456 DRIUnwrapGC(pGC);
457
458 pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
459
460 DRIWrapGC(pGC);
461
462 DRISurfaceRestoreDrawable(dst, &saved);
463}
464
465static void
466DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
467 int x, int y, unsigned int nglyph,
468 CharInfoPtr *ppci, pointer pglyphBase)
469{
470 DRISavedDrawableState saved;
471
472 DRISurfaceSetDrawable(dst, &saved);
473
474 DRIUnwrapGC(pGC);
475
476 pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
477
478 DRIWrapGC(pGC);
479
480 DRISurfaceRestoreDrawable(dst, &saved);
481}
482
483static void
484DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
485 int dx, int dy, int xOrg, int yOrg)
486{
487 DRISavedDrawableState bitMapSaved, dstSaved;
488
489 DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved);
490 DRISurfaceSetDrawable(dst, &dstSaved);
491
492 DRIUnwrapGC(pGC);
493
494 pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
495
496 DRIWrapGC(pGC);
497
498 DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved);
499 DRISurfaceRestoreDrawable(dst, &dstSaved);
500}
501
502static GCOps driGCOps = {
503 DRIFillSpans,
504 DRISetSpans,
505 DRIPutImage,
506 DRICopyArea,
507 DRICopyPlane,
508 DRIPolyPoint,
509 DRIPolylines,
510 DRIPolySegment,
511 DRIPolyRectangle,
512 DRIPolyArc,
513 DRIFillPolygon,
514 DRIPolyFillRect,
515 DRIPolyFillArc,
516 DRIPolyText8,
517 DRIPolyText16,
518 DRIImageText8,
519 DRIImageText16,
520 DRIImageGlyphBlt,
521 DRIPolyGlyphBlt,
522 DRIPushPixels
523};
524
525static Bool
526DRICreateGC(GCPtr pGC)
527{
528 ScreenPtr pScreen = pGC->pScreen;
529 DRIWrapScreenRec *pScreenPriv;
530 DRIGCRec *pGCPriv;
531 Bool ret;
532
533 pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey);
534
535 pGCPriv = DRIGetGCPriv(pGC);
536
537 unwrap(pScreenPriv, pScreen, CreateGC);
538 ret = pScreen->CreateGC(pGC);
539
540 if (ret) {
541 pGCPriv->originalOps = pGC->ops;
542 pGC->ops = &driGCOps;
543 }
544
545 wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC);
546
547 return ret;
548}
549
550/* Return false if an error occurred. */
551Bool
552DRIWrapInit(ScreenPtr pScreen)
553{
554 DRIWrapScreenRec *pScreenPriv;
555
556 if (!dixRegisterPrivateKey(&driGCKeyRec, PRIVATE_GC, sizeof(DRIGCRec)))
557 return FALSE;
558
559 if (!dixRegisterPrivateKey(&driWrapScreenKeyRec, PRIVATE_SCREEN,
560 sizeof(DRIWrapScreenRec)))
561 return FALSE;
562
563 pScreenPriv = dixGetPrivateAddr(&pScreen->devPrivates,
564 &driWrapScreenKeyRec);
565 pScreenPriv->CreateGC = pScreen->CreateGC;
566 pScreen->CreateGC = DRICreateGC;
567
568 return TRUE;
569}