xf86VGAarbiter.c revision 6747b715
1/*
2 * This code was stolen from RAC and adapted to control the legacy vga
3 * interface.
4 *
5 *
6 * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
7 *
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following
15 * conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 */
30
31#include "xorg-config.h"
32
33#include "xf86VGAarbiter.h"
34
35#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
36#include "xf86VGAarbiterPriv.h"
37#include "xf86Bus.h"
38#include "xf86Priv.h"
39#include "pciaccess.h"
40
41
42static GCFuncs VGAarbiterGCFuncs = {
43    VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
44    VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
45    VGAarbiterCopyClip
46};
47
48static GCOps VGAarbiterGCOps = {
49    VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
50    VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
51    VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
52    VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
53    VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
54    VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
55    VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
56    {NULL}      /* devPrivate */
57};
58
59static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
60    VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
61    VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
62    VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
63};
64
65static DevPrivateKeyRec VGAarbiterScreenKeyRec;
66#define VGAarbiterScreenKey (&VGAarbiterScreenKeyRec)
67static DevPrivateKeyRec VGAarbiterGCKeyRec;
68#define VGAarbiterGCKey (&VGAarbiterGCKeyRec)
69
70static int vga_no_arb = 0;
71void
72xf86VGAarbiterInit(void)
73{
74    if (pci_device_vgaarb_init() != 0) {
75	vga_no_arb = 1;
76        xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
77    }
78}
79
80void
81xf86VGAarbiterFini(void)
82{
83    if (vga_no_arb)
84	return;
85    pci_device_vgaarb_fini();
86}
87
88void
89xf86VGAarbiterLock(ScrnInfoPtr pScrn)
90{
91    if (vga_no_arb)
92	return;
93    pci_device_vgaarb_set_target(pScrn->vgaDev);
94    pci_device_vgaarb_lock();
95}
96
97void
98xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
99{
100    if (vga_no_arb)
101	return;
102    pci_device_vgaarb_unlock();
103}
104
105Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
106{
107    int vga_count;
108    int rsrc_decodes;
109    ScrnInfoPtr         pScrn = xf86Screens[pScreen->myNum];
110
111    if (vga_no_arb)
112	return TRUE;
113
114    pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
115    if (vga_count > 1) {
116        if (rsrc_decodes) {
117            return FALSE;
118        }
119    }
120    return TRUE;
121}
122
123void
124xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
125{
126    struct pci_device *dev;
127    EntityPtr pEnt;
128
129    if (vga_no_arb)
130	return;
131
132    pEnt = xf86Entities[pScrn->entityList[0]];
133    if (pEnt->bus.type != BUS_PCI)
134	return;
135
136    dev = pEnt->bus.id.pci;
137    pScrn->vgaDev = dev;
138}
139
140void
141xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
142{
143    if (vga_no_arb)
144	return;
145    pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
146}
147
148Bool
149xf86VGAarbiterWrapFunctions(void)
150{
151    ScrnInfoPtr pScrn;
152    VGAarbiterScreenPtr pScreenPriv;
153    miPointerScreenPtr PointPriv;
154    PictureScreenPtr    ps;
155    ScreenPtr pScreen;
156    int vga_count, i;
157
158    if (vga_no_arb)
159        return FALSE;
160
161    /*
162     * we need to wrap the arbiter if we have more than
163     * one VGA card - hotplug cries.
164     */
165    pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
166    if (vga_count < 2 || !xf86Screens)
167        return FALSE;
168
169    xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n",
170            vga_count);
171
172    for (i = 0; i < xf86NumScreens; i++) {
173        pScreen = xf86Screens[i]->pScreen;
174        ps = GetPictureScreenIfSet(pScreen);
175        pScrn = xf86Screens[pScreen->myNum];
176        PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
177
178        if (!dixRegisterPrivateKey(&VGAarbiterGCKeyRec, PRIVATE_GC, sizeof(VGAarbiterGCRec)))
179            return FALSE;
180
181	if (!dixRegisterPrivateKey(&VGAarbiterScreenKeyRec, PRIVATE_SCREEN, 0))
182	    return FALSE;
183
184        if (!(pScreenPriv = malloc(sizeof(VGAarbiterScreenRec))))
185            return FALSE;
186
187        dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
188
189        WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
190        WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
191        WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
192        WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
193        WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
194        WRAP_SCREEN(GetImage, VGAarbiterGetImage);
195        WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
196        WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
197        WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
198        WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
199        WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
200        WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
201        WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
202        WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
203        WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
204        WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
205        WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
206        WRAP_PICT(Composite,VGAarbiterComposite);
207        WRAP_PICT(Glyphs,VGAarbiterGlyphs);
208        WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
209        WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
210        WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
211        WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
212        WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
213        WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
214        WRAP_SPRITE;
215    }
216
217    return TRUE;
218}
219
220/* Screen funcs */
221static Bool
222VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
223{
224    Bool val;
225    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
226    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
227        &pScreen->devPrivates, VGAarbiterScreenKey);
228    miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
229        &pScreen->devPrivates, miPointerScreenKey);
230    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
231
232    UNWRAP_SCREEN(CreateGC);
233    UNWRAP_SCREEN(CloseScreen);
234    UNWRAP_SCREEN(GetImage);
235    UNWRAP_SCREEN(GetSpans);
236    UNWRAP_SCREEN(SourceValidate);
237    UNWRAP_SCREEN(CopyWindow);
238    UNWRAP_SCREEN(ClearToBackground);
239    UNWRAP_SCREEN(SaveScreen);
240    UNWRAP_SCREEN(StoreColors);
241    UNWRAP_SCREEN(DisplayCursor);
242    UNWRAP_SCREEN(RealizeCursor);
243    UNWRAP_SCREEN(UnrealizeCursor);
244    UNWRAP_SCREEN(RecolorCursor);
245    UNWRAP_SCREEN(SetCursorPosition);
246    UNWRAP_PICT(Composite);
247    UNWRAP_PICT(Glyphs);
248    UNWRAP_PICT(CompositeRects);
249    UNWRAP_SCREEN_INFO(AdjustFrame);
250    UNWRAP_SCREEN_INFO(SwitchMode);
251    UNWRAP_SCREEN_INFO(EnterVT);
252    UNWRAP_SCREEN_INFO(LeaveVT);
253    UNWRAP_SCREEN_INFO(FreeScreen);
254    UNWRAP_SPRITE;
255
256    free((pointer) pScreenPriv);
257    xf86VGAarbiterLock(xf86Screens[i]);
258    val = (*pScreen->CloseScreen) (i, pScreen);
259    xf86VGAarbiterUnlock(xf86Screens[i]);
260    return val;
261}
262
263static void
264VGAarbiterBlockHandler(int i,
265                       pointer blockData, pointer pTimeout, pointer pReadmask)
266{
267    ScreenPtr pScreen = screenInfo.screens[i];
268    SCREEN_PROLOG(BlockHandler);
269    VGAGet();
270    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
271    VGAPut();
272    SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
273}
274
275static void
276VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
277{
278    ScreenPtr pScreen = screenInfo.screens[i];
279    SCREEN_PROLOG(WakeupHandler);
280    VGAGet();
281    pScreen->WakeupHandler(i, blockData, result, pReadmask);
282    VGAPut();
283    SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
284}
285
286static void
287VGAarbiterGetImage (
288    DrawablePtr pDrawable,
289    int sx, int sy, int w, int h,
290    unsigned int    format,
291    unsigned long   planemask,
292    char        *pdstLine
293    )
294{
295    ScreenPtr pScreen = pDrawable->pScreen;
296    SCREEN_PROLOG(GetImage);
297//    if (xf86Screens[pScreen->myNum]->vtSema) {
298    VGAGet();
299//    }
300    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
301              format, planemask, pdstLine);
302    VGAPut();
303    SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
304}
305
306static void
307VGAarbiterGetSpans (
308    DrawablePtr pDrawable,
309    int     wMax,
310    DDXPointPtr ppt,
311    int     *pwidth,
312    int     nspans,
313    char    *pdstStart
314    )
315{
316    ScreenPtr       pScreen = pDrawable->pScreen;
317
318    SCREEN_PROLOG (GetSpans);
319    VGAGet();
320    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
321    VGAPut();
322    SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
323}
324
325static void
326VGAarbiterSourceValidate (
327    DrawablePtr pDrawable,
328    int x, int y, int width, int height )
329{
330    ScreenPtr   pScreen = pDrawable->pScreen;
331    SCREEN_PROLOG (SourceValidate);
332    VGAGet();
333    if (pScreen->SourceValidate)
334    (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
335    VGAPut();
336    SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
337}
338
339static void
340VGAarbiterCopyWindow(
341    WindowPtr pWin,
342    DDXPointRec ptOldOrg,
343    RegionPtr prgnSrc )
344{
345    ScreenPtr pScreen = pWin->drawable.pScreen;
346
347    SCREEN_PROLOG (CopyWindow);
348    VGAGet();
349    (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
350    VGAPut();
351    SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
352}
353
354static void
355VGAarbiterClearToBackground (
356    WindowPtr pWin,
357    int x, int y,
358    int w, int h,
359    Bool generateExposures )
360{
361    ScreenPtr pScreen = pWin->drawable.pScreen;
362
363    SCREEN_PROLOG ( ClearToBackground);
364    VGAGet();
365    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
366    VGAPut();
367    SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
368}
369
370static PixmapPtr
371VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
372{
373    PixmapPtr pPix;
374
375    SCREEN_PROLOG ( CreatePixmap);
376    VGAGet();
377    pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
378    VGAPut();
379    SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
380
381    return pPix;
382}
383
384static Bool
385VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
386{
387    Bool val;
388
389    SCREEN_PROLOG (SaveScreen);
390    VGAGet();
391    val = (*pScreen->SaveScreen) (pScreen, unblank);
392    VGAPut();
393    SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
394
395    return val;
396}
397
398static void
399VGAarbiterStoreColors (
400    ColormapPtr        pmap,
401    int                ndef,
402    xColorItem         *pdefs)
403{
404    ScreenPtr pScreen = pmap->pScreen;
405
406    SCREEN_PROLOG (StoreColors);
407    VGAGet();
408    (*pScreen->StoreColors) (pmap,ndef,pdefs);
409    VGAPut();
410    SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
411}
412
413static void
414VGAarbiterRecolorCursor (
415    DeviceIntPtr pDev,
416    ScreenPtr pScreen,
417    CursorPtr pCurs,
418    Bool displayed
419    )
420{
421    SCREEN_PROLOG (RecolorCursor);
422    VGAGet();
423    (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
424    VGAPut();
425    SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
426}
427
428static Bool
429VGAarbiterRealizeCursor (
430    DeviceIntPtr pDev,
431    ScreenPtr   pScreen,
432    CursorPtr   pCursor
433    )
434{
435    Bool val;
436
437    SCREEN_PROLOG (RealizeCursor);
438    VGAGet();
439    val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
440    VGAPut();
441    SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
442    return val;
443}
444
445static Bool
446VGAarbiterUnrealizeCursor (
447    DeviceIntPtr pDev,
448    ScreenPtr   pScreen,
449    CursorPtr   pCursor
450    )
451{
452    Bool val;
453
454    SCREEN_PROLOG (UnrealizeCursor);
455    VGAGet();
456    val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
457    VGAPut();
458    SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
459    return val;
460}
461
462static Bool
463VGAarbiterDisplayCursor (
464    DeviceIntPtr pDev,
465    ScreenPtr   pScreen,
466    CursorPtr   pCursor
467    )
468{
469    Bool val;
470
471    SCREEN_PROLOG (DisplayCursor);
472    VGAGet();
473    val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
474    VGAPut();
475    SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
476    return val;
477}
478
479static Bool
480VGAarbiterSetCursorPosition (
481    DeviceIntPtr pDev,
482    ScreenPtr   pScreen,
483    int x, int y,
484    Bool generateEvent)
485{
486    Bool val;
487
488    SCREEN_PROLOG (SetCursorPosition);
489    VGAGet();
490    val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
491    VGAPut();
492    SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
493    return val;
494}
495
496static void
497VGAarbiterAdjustFrame(int index, int x, int y, int flags)
498{
499    ScreenPtr pScreen = screenInfo.screens[index];
500    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
501        &pScreen->devPrivates, VGAarbiterScreenKey);
502
503    VGAGet();
504    (*pScreenPriv->AdjustFrame)(index, x, y, flags);
505    VGAPut();
506}
507
508static Bool
509VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
510{
511    Bool val;
512    ScreenPtr pScreen = screenInfo.screens[index];
513    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
514        &pScreen->devPrivates, VGAarbiterScreenKey);
515
516    VGAGet();
517    val = (*pScreenPriv->SwitchMode)(index, mode, flags);
518    VGAPut();
519    return val;
520}
521
522static Bool
523VGAarbiterEnterVT(int index, int flags)
524{
525    Bool val;
526    ScrnInfoPtr pScrn = xf86Screens[index];
527    ScreenPtr pScreen = screenInfo.screens[index];
528    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
529        &pScreen->devPrivates, VGAarbiterScreenKey);
530
531    VGAGet();
532    pScrn->EnterVT = pScreenPriv->EnterVT;
533    val = (*pScrn->EnterVT)(index, flags);
534    pScreenPriv->EnterVT = pScrn->EnterVT;
535    pScrn->EnterVT = VGAarbiterEnterVT;
536    VGAPut();
537    return val;
538}
539
540static void
541VGAarbiterLeaveVT(int index, int flags)
542{
543    ScrnInfoPtr pScrn = xf86Screens[index];
544    ScreenPtr pScreen = screenInfo.screens[index];
545    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
546        &pScreen->devPrivates, VGAarbiterScreenKey);
547
548    VGAGet();
549    pScrn->LeaveVT = pScreenPriv->LeaveVT;
550    (*pScreenPriv->LeaveVT)(index, flags);
551    pScreenPriv->LeaveVT = pScrn->LeaveVT;
552    pScrn->LeaveVT = VGAarbiterLeaveVT;
553    VGAPut();
554}
555
556static void
557VGAarbiterFreeScreen(int index, int flags)
558{
559    ScreenPtr pScreen = screenInfo.screens[index];
560    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
561        &pScreen->devPrivates, VGAarbiterScreenKey);
562
563    VGAGet();
564    (*pScreenPriv->FreeScreen)(index, flags);
565    VGAPut();
566}
567
568static Bool
569VGAarbiterCreateGC(GCPtr pGC)
570{
571    ScreenPtr    pScreen = pGC->pScreen;
572    VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
573    Bool         ret;
574
575    SCREEN_PROLOG(CreateGC);
576    VGAGet();
577    ret = (*pScreen->CreateGC)(pGC);
578    VGAPut();
579    GC_WRAP(pGC);
580    SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
581
582    return ret;
583}
584
585/* GC funcs */
586static void
587VGAarbiterValidateGC(
588   GCPtr         pGC,
589   unsigned long changes,
590   DrawablePtr   pDraw )
591{
592    GC_UNWRAP(pGC);
593    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
594    GC_WRAP(pGC);
595}
596
597
598static void
599VGAarbiterDestroyGC(GCPtr pGC)
600{
601    GC_UNWRAP (pGC);
602    (*pGC->funcs->DestroyGC)(pGC);
603    GC_WRAP (pGC);
604}
605
606static void
607VGAarbiterChangeGC (
608    GCPtr       pGC,
609    unsigned long   mask)
610{
611    GC_UNWRAP (pGC);
612    (*pGC->funcs->ChangeGC) (pGC, mask);
613    GC_WRAP (pGC);
614}
615
616static void
617VGAarbiterCopyGC (
618    GCPtr       pGCSrc,
619    unsigned long   mask,
620    GCPtr       pGCDst)
621{
622    GC_UNWRAP (pGCDst);
623    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
624    GC_WRAP (pGCDst);
625}
626
627static void
628VGAarbiterChangeClip (
629    GCPtr   pGC,
630    int     type,
631    pointer pvalue,
632    int     nrects )
633{
634    GC_UNWRAP (pGC);
635    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
636    GC_WRAP (pGC);
637}
638
639static void
640VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
641{
642    GC_UNWRAP (pgcDst);
643    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
644    GC_WRAP (pgcDst);
645}
646
647static void
648VGAarbiterDestroyClip(GCPtr pGC)
649{
650    GC_UNWRAP (pGC);
651    (* pGC->funcs->DestroyClip)(pGC);
652    GC_WRAP (pGC);
653}
654
655/* GC Ops */
656static void
657VGAarbiterFillSpans(
658    DrawablePtr pDraw,
659    GC      *pGC,
660    int     nInit,
661    DDXPointPtr pptInit,
662    int *pwidthInit,
663    int fSorted )
664{
665    GC_UNWRAP(pGC);
666    VGAGet_GC();
667    (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
668    VGAPut_GC();
669    GC_WRAP(pGC);
670}
671
672static void
673VGAarbiterSetSpans(
674    DrawablePtr     pDraw,
675    GCPtr       pGC,
676    char        *pcharsrc,
677    register DDXPointPtr ppt,
678    int         *pwidth,
679    int         nspans,
680    int         fSorted )
681{
682    GC_UNWRAP(pGC);
683    VGAGet_GC();
684    (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
685    VGAPut_GC();
686    GC_WRAP(pGC);
687}
688
689static void
690VGAarbiterPutImage(
691    DrawablePtr pDraw,
692    GCPtr   pGC,
693    int     depth,
694    int x, int y, int w, int h,
695    int     leftPad,
696    int     format,
697    char    *pImage )
698{
699    GC_UNWRAP(pGC);
700    VGAGet_GC();
701    (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
702              leftPad, format, pImage);
703    VGAPut_GC();
704    GC_WRAP(pGC);
705}
706
707static RegionPtr
708VGAarbiterCopyArea(
709    DrawablePtr pSrc,
710    DrawablePtr pDst,
711    GC *pGC,
712    int srcx, int srcy,
713    int width, int height,
714    int dstx, int dsty )
715{
716    RegionPtr ret;
717
718    GC_UNWRAP(pGC);
719    VGAGet_GC();
720    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
721                pGC, srcx, srcy, width, height, dstx, dsty);
722    VGAPut_GC();
723    GC_WRAP(pGC);
724    return ret;
725}
726
727static RegionPtr
728VGAarbiterCopyPlane(
729    DrawablePtr pSrc,
730    DrawablePtr pDst,
731    GCPtr pGC,
732    int srcx, int srcy,
733    int width, int height,
734    int dstx, int dsty,
735    unsigned long bitPlane )
736{
737    RegionPtr ret;
738
739    GC_UNWRAP(pGC);
740    VGAGet_GC();
741    ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
742                 width, height, dstx, dsty, bitPlane);
743    VGAPut_GC();
744    GC_WRAP(pGC);
745    return ret;
746}
747
748static void
749VGAarbiterPolyPoint(
750    DrawablePtr pDraw,
751    GCPtr pGC,
752    int mode,
753    int npt,
754    xPoint *pptInit )
755{
756    GC_UNWRAP(pGC);
757    VGAGet_GC();
758    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
759    VGAPut_GC();
760    GC_WRAP(pGC);
761}
762
763
764static void
765VGAarbiterPolylines(
766    DrawablePtr pDraw,
767    GCPtr   pGC,
768    int     mode,
769    int     npt,
770    DDXPointPtr pptInit )
771{
772    GC_UNWRAP(pGC);
773    VGAGet_GC();
774    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
775    VGAPut_GC();
776    GC_WRAP(pGC);
777}
778
779static void
780VGAarbiterPolySegment(
781    DrawablePtr pDraw,
782    GCPtr   pGC,
783    int     nseg,
784    xSegment    *pSeg )
785{
786    GC_UNWRAP(pGC);
787    VGAGet_GC();
788    (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
789    VGAPut_GC();
790    GC_WRAP(pGC);
791}
792
793static void
794VGAarbiterPolyRectangle(
795    DrawablePtr  pDraw,
796    GCPtr        pGC,
797    int          nRectsInit,
798    xRectangle  *pRectsInit )
799{
800    GC_UNWRAP(pGC);
801    VGAGet_GC();
802    (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
803    VGAPut_GC();
804    GC_WRAP(pGC);
805}
806
807static void
808VGAarbiterPolyArc(
809    DrawablePtr pDraw,
810    GCPtr   pGC,
811    int     narcs,
812    xArc    *parcs )
813{
814    GC_UNWRAP(pGC);
815    VGAGet_GC();
816    (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
817    VGAPut_GC();
818    GC_WRAP(pGC);
819}
820
821static void
822VGAarbiterFillPolygon(
823    DrawablePtr pDraw,
824    GCPtr   pGC,
825    int     shape,
826    int     mode,
827    int     count,
828    DDXPointPtr ptsIn )
829{
830    GC_UNWRAP(pGC);
831    VGAGet_GC();
832    (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
833    VGAPut_GC();
834    GC_WRAP(pGC);
835}
836
837static void
838VGAarbiterPolyFillRect(
839    DrawablePtr pDraw,
840    GCPtr   pGC,
841    int     nrectFill,
842    xRectangle  *prectInit)
843{
844    GC_UNWRAP(pGC);
845    VGAGet_GC();
846    (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
847    VGAPut_GC();
848    GC_WRAP(pGC);
849}
850
851static void
852VGAarbiterPolyFillArc(
853    DrawablePtr pDraw,
854    GCPtr   pGC,
855    int     narcs,
856    xArc    *parcs )
857{
858    GC_UNWRAP(pGC);
859    VGAGet_GC();
860    (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
861    VGAPut_GC();
862    GC_WRAP(pGC);
863}
864
865static int
866VGAarbiterPolyText8(
867    DrawablePtr pDraw,
868    GCPtr   pGC,
869    int     x,
870    int     y,
871    int     count,
872    char    *chars )
873{
874    int ret;
875
876    GC_UNWRAP(pGC);
877    VGAGet_GC();
878    ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
879    VGAPut_GC();
880    GC_WRAP(pGC);
881    return ret;
882}
883
884static int
885VGAarbiterPolyText16(
886    DrawablePtr pDraw,
887    GCPtr   pGC,
888    int     x,
889    int     y,
890    int     count,
891    unsigned short *chars )
892{
893    int ret;
894
895    GC_UNWRAP(pGC);
896    VGAGet_GC();
897    ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
898    VGAPut_GC();
899    GC_WRAP(pGC);
900    return ret;
901}
902
903static void
904VGAarbiterImageText8(
905    DrawablePtr pDraw,
906    GCPtr   pGC,
907    int     x,
908    int     y,
909    int     count,
910    char    *chars )
911{
912    GC_UNWRAP(pGC);
913    VGAGet_GC();
914    (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
915    VGAPut_GC();
916    GC_WRAP(pGC);
917}
918
919static void
920VGAarbiterImageText16(
921    DrawablePtr pDraw,
922    GCPtr   pGC,
923    int     x,
924    int     y,
925    int     count,
926    unsigned short *chars )
927{
928    GC_UNWRAP(pGC);
929    VGAGet_GC();
930    (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
931    VGAPut_GC();
932    GC_WRAP(pGC);
933}
934
935
936static void
937VGAarbiterImageGlyphBlt(
938    DrawablePtr pDraw,
939    GCPtr pGC,
940    int xInit, int yInit,
941    unsigned int nglyph,
942    CharInfoPtr *ppci,
943    pointer pglyphBase )
944{
945    GC_UNWRAP(pGC);
946    VGAGet_GC();
947    (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
948                   nglyph, ppci, pglyphBase);
949    VGAPut_GC();
950    GC_WRAP(pGC);
951}
952
953static void
954VGAarbiterPolyGlyphBlt(
955    DrawablePtr pDraw,
956    GCPtr pGC,
957    int xInit, int yInit,
958    unsigned int nglyph,
959    CharInfoPtr *ppci,
960    pointer pglyphBase )
961{
962    GC_UNWRAP(pGC);
963    VGAGet_GC();
964    (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
965                  nglyph, ppci, pglyphBase);
966    VGAPut_GC();
967    GC_WRAP(pGC);
968}
969
970static void
971VGAarbiterPushPixels(
972    GCPtr   pGC,
973    PixmapPtr   pBitMap,
974    DrawablePtr pDraw,
975    int dx, int dy, int xOrg, int yOrg )
976{
977    GC_UNWRAP(pGC);
978    VGAGet_GC();
979    (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
980    VGAPut_GC();
981    GC_WRAP(pGC);
982}
983
984
985/* miSpriteFuncs */
986static Bool
987VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
988{
989    Bool val;
990    SPRITE_PROLOG;
991    VGAGet();
992    val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
993    VGAPut();
994    SPRITE_EPILOG;
995    return val;
996}
997
998static Bool
999VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
1000{
1001    Bool val;
1002    SPRITE_PROLOG;
1003    VGAGet();
1004    val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
1005    VGAPut();
1006    SPRITE_EPILOG;
1007    return val;
1008}
1009
1010static void
1011VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
1012{
1013    SPRITE_PROLOG;
1014    VGAGet();
1015    PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
1016    VGAPut();
1017    SPRITE_EPILOG;
1018}
1019
1020static void
1021VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
1022{
1023    SPRITE_PROLOG;
1024    VGAGet();
1025    PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
1026    VGAPut();
1027    SPRITE_EPILOG;
1028}
1029
1030static Bool
1031VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
1032{
1033    Bool val;
1034    SPRITE_PROLOG;
1035    VGAGet();
1036    val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
1037    VGAPut();
1038    SPRITE_EPILOG;
1039    return val;
1040}
1041
1042static void
1043VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
1044{
1045    SPRITE_PROLOG;
1046    VGAGet();
1047    PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
1048    VGAPut();
1049    SPRITE_EPILOG;
1050}
1051
1052static void
1053VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
1054         PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
1055         INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
1056         CARD16 height)
1057{
1058    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1059    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1060
1061    PICTURE_PROLOGUE(Composite);
1062
1063    VGAGet();
1064    (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
1065              yDst, width, height);
1066    VGAPut();
1067    PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
1068}
1069
1070static void
1071VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
1072      PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
1073      GlyphListPtr list, GlyphPtr *glyphs)
1074{
1075    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1076    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1077
1078    PICTURE_PROLOGUE(Glyphs);
1079
1080    VGAGet();
1081    (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
1082    VGAPut();
1083    PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
1084}
1085
1086static void
1087VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
1088          xRectangle *rects)
1089{
1090    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1091    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1092
1093    PICTURE_PROLOGUE(CompositeRects);
1094
1095    VGAGet();
1096    (*ps->CompositeRects)(op, pDst, color, nRect, rects);
1097    VGAPut();
1098    PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
1099}
1100#else
1101/* dummy functions */
1102void xf86VGAarbiterInit(void) {}
1103void xf86VGAarbiterFini(void) {}
1104
1105void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
1106void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
1107Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
1108void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
1109void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
1110Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
1111
1112#endif
1113