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};
57
58static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
59    VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
60    VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
61    VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
62};
63
64static DevPrivateKeyRec VGAarbiterScreenKeyRec;
65#define VGAarbiterScreenKey (&VGAarbiterScreenKeyRec)
66static DevPrivateKeyRec VGAarbiterGCKeyRec;
67#define VGAarbiterGCKey (&VGAarbiterGCKeyRec)
68
69static int vga_no_arb = 0;
70void
71xf86VGAarbiterInit(void)
72{
73    if (pci_device_vgaarb_init() != 0) {
74	vga_no_arb = 1;
75        xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
76    }
77}
78
79void
80xf86VGAarbiterFini(void)
81{
82    if (vga_no_arb)
83	return;
84    pci_device_vgaarb_fini();
85}
86
87void
88xf86VGAarbiterLock(ScrnInfoPtr pScrn)
89{
90    if (vga_no_arb)
91	return;
92    pci_device_vgaarb_set_target(pScrn->vgaDev);
93    pci_device_vgaarb_lock();
94}
95
96void
97xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
98{
99    if (vga_no_arb)
100	return;
101    pci_device_vgaarb_unlock();
102}
103
104Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
105{
106    int vga_count;
107    int rsrc_decodes;
108    ScrnInfoPtr         pScrn = xf86Screens[pScreen->myNum];
109
110    if (vga_no_arb)
111	return TRUE;
112
113    pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
114    if (vga_count > 1) {
115        if (rsrc_decodes) {
116            return FALSE;
117        }
118    }
119    return TRUE;
120}
121
122void
123xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
124{
125    struct pci_device *dev;
126    EntityPtr pEnt;
127
128    if (vga_no_arb)
129	return;
130
131    pEnt = xf86Entities[pScrn->entityList[0]];
132    if (pEnt->bus.type != BUS_PCI)
133	return;
134
135    dev = pEnt->bus.id.pci;
136    pScrn->vgaDev = dev;
137}
138
139void
140xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc)
141{
142    if (vga_no_arb)
143	return;
144    pci_device_vgaarb_set_target(pScrn->vgaDev);
145    pci_device_vgaarb_decodes(rsrc);
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(pScreen);
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(pScreen);
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(pScreen);
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(pScreen);
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    unsigned int subWindowMode )
330{
331    ScreenPtr   pScreen = pDrawable->pScreen;
332    SCREEN_PROLOG (SourceValidate);
333    VGAGet(pScreen);
334    if (pScreen->SourceValidate)
335    (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode);
336    VGAPut();
337    SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
338}
339
340static void
341VGAarbiterCopyWindow(
342    WindowPtr pWin,
343    DDXPointRec ptOldOrg,
344    RegionPtr prgnSrc )
345{
346    ScreenPtr pScreen = pWin->drawable.pScreen;
347
348    SCREEN_PROLOG (CopyWindow);
349    VGAGet(pScreen);
350    (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
351    VGAPut();
352    SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
353}
354
355static void
356VGAarbiterClearToBackground (
357    WindowPtr pWin,
358    int x, int y,
359    int w, int h,
360    Bool generateExposures )
361{
362    ScreenPtr pScreen = pWin->drawable.pScreen;
363
364    SCREEN_PROLOG ( ClearToBackground);
365    VGAGet(pScreen);
366    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
367    VGAPut();
368    SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
369}
370
371static PixmapPtr
372VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
373{
374    PixmapPtr pPix;
375
376    SCREEN_PROLOG ( CreatePixmap);
377    VGAGet(pScreen);
378    pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
379    VGAPut();
380    SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
381
382    return pPix;
383}
384
385static Bool
386VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
387{
388    Bool val;
389
390    SCREEN_PROLOG (SaveScreen);
391    VGAGet(pScreen);
392    val = (*pScreen->SaveScreen) (pScreen, unblank);
393    VGAPut();
394    SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
395
396    return val;
397}
398
399static void
400VGAarbiterStoreColors (
401    ColormapPtr        pmap,
402    int                ndef,
403    xColorItem         *pdefs)
404{
405    ScreenPtr pScreen = pmap->pScreen;
406
407    SCREEN_PROLOG (StoreColors);
408    VGAGet(pScreen);
409    (*pScreen->StoreColors) (pmap,ndef,pdefs);
410    VGAPut();
411    SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
412}
413
414static void
415VGAarbiterRecolorCursor (
416    DeviceIntPtr pDev,
417    ScreenPtr pScreen,
418    CursorPtr pCurs,
419    Bool displayed
420    )
421{
422    SCREEN_PROLOG (RecolorCursor);
423    VGAGet(pScreen);
424    (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
425    VGAPut();
426    SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
427}
428
429static Bool
430VGAarbiterRealizeCursor (
431    DeviceIntPtr pDev,
432    ScreenPtr   pScreen,
433    CursorPtr   pCursor
434    )
435{
436    Bool val;
437
438    SCREEN_PROLOG (RealizeCursor);
439    VGAGet(pScreen);
440    val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
441    VGAPut();
442    SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
443    return val;
444}
445
446static Bool
447VGAarbiterUnrealizeCursor (
448    DeviceIntPtr pDev,
449    ScreenPtr   pScreen,
450    CursorPtr   pCursor
451    )
452{
453    Bool val;
454
455    SCREEN_PROLOG (UnrealizeCursor);
456    VGAGet(pScreen);
457    val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
458    VGAPut();
459    SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
460    return val;
461}
462
463static Bool
464VGAarbiterDisplayCursor (
465    DeviceIntPtr pDev,
466    ScreenPtr   pScreen,
467    CursorPtr   pCursor
468    )
469{
470    Bool val;
471
472    SCREEN_PROLOG (DisplayCursor);
473    VGAGet(pScreen);
474    val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
475    VGAPut();
476    SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
477    return val;
478}
479
480static Bool
481VGAarbiterSetCursorPosition (
482    DeviceIntPtr pDev,
483    ScreenPtr   pScreen,
484    int x, int y,
485    Bool generateEvent)
486{
487    Bool val;
488
489    SCREEN_PROLOG (SetCursorPosition);
490    VGAGet(pScreen);
491    val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
492    VGAPut();
493    SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
494    return val;
495}
496
497static void
498VGAarbiterAdjustFrame(int index, int x, int y, int flags)
499{
500    ScreenPtr pScreen = screenInfo.screens[index];
501    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
502        &pScreen->devPrivates, VGAarbiterScreenKey);
503
504    VGAGet(pScreen);
505    (*pScreenPriv->AdjustFrame)(index, x, y, flags);
506    VGAPut();
507}
508
509static Bool
510VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
511{
512    Bool val;
513    ScreenPtr pScreen = screenInfo.screens[index];
514    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
515        &pScreen->devPrivates, VGAarbiterScreenKey);
516
517    VGAGet(pScreen);
518    val = (*pScreenPriv->SwitchMode)(index, mode, flags);
519    VGAPut();
520    return val;
521}
522
523static Bool
524VGAarbiterEnterVT(int index, int flags)
525{
526    Bool val;
527    ScrnInfoPtr pScrn = xf86Screens[index];
528    ScreenPtr pScreen = screenInfo.screens[index];
529    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
530        &pScreen->devPrivates, VGAarbiterScreenKey);
531
532    VGAGet(pScreen);
533    pScrn->EnterVT = pScreenPriv->EnterVT;
534    val = (*pScrn->EnterVT)(index, flags);
535    pScreenPriv->EnterVT = pScrn->EnterVT;
536    pScrn->EnterVT = VGAarbiterEnterVT;
537    VGAPut();
538    return val;
539}
540
541static void
542VGAarbiterLeaveVT(int index, int flags)
543{
544    ScrnInfoPtr pScrn = xf86Screens[index];
545    ScreenPtr pScreen = screenInfo.screens[index];
546    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
547        &pScreen->devPrivates, VGAarbiterScreenKey);
548
549    VGAGet(pScreen);
550    pScrn->LeaveVT = pScreenPriv->LeaveVT;
551    (*pScreenPriv->LeaveVT)(index, flags);
552    pScreenPriv->LeaveVT = pScrn->LeaveVT;
553    pScrn->LeaveVT = VGAarbiterLeaveVT;
554    VGAPut();
555}
556
557static void
558VGAarbiterFreeScreen(int index, int flags)
559{
560    ScreenPtr pScreen = screenInfo.screens[index];
561    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
562        &pScreen->devPrivates, VGAarbiterScreenKey);
563
564    VGAGet(pScreen);
565    (*pScreenPriv->FreeScreen)(index, flags);
566    VGAPut();
567}
568
569static Bool
570VGAarbiterCreateGC(GCPtr pGC)
571{
572    ScreenPtr    pScreen = pGC->pScreen;
573    VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
574    Bool         ret;
575
576    SCREEN_PROLOG(CreateGC);
577    ret = (*pScreen->CreateGC)(pGC);
578    GC_WRAP(pGC);
579    SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
580
581    return ret;
582}
583
584/* GC funcs */
585static void
586VGAarbiterValidateGC(
587   GCPtr         pGC,
588   unsigned long changes,
589   DrawablePtr   pDraw )
590{
591    GC_UNWRAP(pGC);
592    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
593    GC_WRAP(pGC);
594}
595
596
597static void
598VGAarbiterDestroyGC(GCPtr pGC)
599{
600    GC_UNWRAP (pGC);
601    (*pGC->funcs->DestroyGC)(pGC);
602    GC_WRAP (pGC);
603}
604
605static void
606VGAarbiterChangeGC (
607    GCPtr       pGC,
608    unsigned long   mask)
609{
610    GC_UNWRAP (pGC);
611    (*pGC->funcs->ChangeGC) (pGC, mask);
612    GC_WRAP (pGC);
613}
614
615static void
616VGAarbiterCopyGC (
617    GCPtr       pGCSrc,
618    unsigned long   mask,
619    GCPtr       pGCDst)
620{
621    GC_UNWRAP (pGCDst);
622    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
623    GC_WRAP (pGCDst);
624}
625
626static void
627VGAarbiterChangeClip (
628    GCPtr   pGC,
629    int     type,
630    pointer pvalue,
631    int     nrects )
632{
633    GC_UNWRAP (pGC);
634    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
635    GC_WRAP (pGC);
636}
637
638static void
639VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
640{
641    GC_UNWRAP (pgcDst);
642    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
643    GC_WRAP (pgcDst);
644}
645
646static void
647VGAarbiterDestroyClip(GCPtr pGC)
648{
649    GC_UNWRAP (pGC);
650    (* pGC->funcs->DestroyClip)(pGC);
651    GC_WRAP (pGC);
652}
653
654/* GC Ops */
655static void
656VGAarbiterFillSpans(
657    DrawablePtr pDraw,
658    GC      *pGC,
659    int     nInit,
660    DDXPointPtr pptInit,
661    int *pwidthInit,
662    int fSorted )
663{
664    ScreenPtr pScreen = pGC->pScreen;
665    GC_UNWRAP(pGC);
666    VGAGet(pScreen);
667    (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
668    VGAPut();
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    ScreenPtr pScreen = pGC->pScreen;
683    GC_UNWRAP(pGC);
684    VGAGet(pScreen);
685    (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
686    VGAPut();
687    GC_WRAP(pGC);
688}
689
690static void
691VGAarbiterPutImage(
692    DrawablePtr pDraw,
693    GCPtr   pGC,
694    int     depth,
695    int x, int y, int w, int h,
696    int     leftPad,
697    int     format,
698    char    *pImage )
699{
700    ScreenPtr pScreen = pGC->pScreen;
701    GC_UNWRAP(pGC);
702    VGAGet(pScreen);
703    (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
704              leftPad, format, pImage);
705    VGAPut();
706    GC_WRAP(pGC);
707}
708
709static RegionPtr
710VGAarbiterCopyArea(
711    DrawablePtr pSrc,
712    DrawablePtr pDst,
713    GC *pGC,
714    int srcx, int srcy,
715    int width, int height,
716    int dstx, int dsty )
717{
718    RegionPtr ret;
719    ScreenPtr pScreen = pGC->pScreen;
720    GC_UNWRAP(pGC);
721    VGAGet(pScreen);
722    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
723                pGC, srcx, srcy, width, height, dstx, dsty);
724    VGAPut();
725    GC_WRAP(pGC);
726    return ret;
727}
728
729static RegionPtr
730VGAarbiterCopyPlane(
731    DrawablePtr pSrc,
732    DrawablePtr pDst,
733    GCPtr pGC,
734    int srcx, int srcy,
735    int width, int height,
736    int dstx, int dsty,
737    unsigned long bitPlane )
738{
739    RegionPtr ret;
740    ScreenPtr pScreen = pGC->pScreen;
741    GC_UNWRAP(pGC);
742    VGAGet(pScreen);
743    ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
744                 width, height, dstx, dsty, bitPlane);
745    VGAPut();
746    GC_WRAP(pGC);
747    return ret;
748}
749
750static void
751VGAarbiterPolyPoint(
752    DrawablePtr pDraw,
753    GCPtr pGC,
754    int mode,
755    int npt,
756    xPoint *pptInit )
757{
758    ScreenPtr pScreen = pGC->pScreen;
759    GC_UNWRAP(pGC);
760    VGAGet(pScreen);
761    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
762    VGAPut();
763    GC_WRAP(pGC);
764}
765
766
767static void
768VGAarbiterPolylines(
769    DrawablePtr pDraw,
770    GCPtr   pGC,
771    int     mode,
772    int     npt,
773    DDXPointPtr pptInit )
774{
775    ScreenPtr pScreen = pGC->pScreen;
776    GC_UNWRAP(pGC);
777    VGAGet(pScreen);
778    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
779    VGAPut();
780    GC_WRAP(pGC);
781}
782
783static void
784VGAarbiterPolySegment(
785    DrawablePtr pDraw,
786    GCPtr   pGC,
787    int     nseg,
788    xSegment    *pSeg )
789{
790    ScreenPtr pScreen = pGC->pScreen;
791    GC_UNWRAP(pGC);
792    VGAGet(pScreen);
793    (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
794    VGAPut();
795    GC_WRAP(pGC);
796}
797
798static void
799VGAarbiterPolyRectangle(
800    DrawablePtr  pDraw,
801    GCPtr        pGC,
802    int          nRectsInit,
803    xRectangle  *pRectsInit )
804{
805    ScreenPtr pScreen = pGC->pScreen;
806    GC_UNWRAP(pGC);
807    VGAGet(pScreen);
808    (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
809    VGAPut();
810    GC_WRAP(pGC);
811}
812
813static void
814VGAarbiterPolyArc(
815    DrawablePtr pDraw,
816    GCPtr   pGC,
817    int     narcs,
818    xArc    *parcs )
819{
820    ScreenPtr pScreen = pGC->pScreen;
821    GC_UNWRAP(pGC);
822    VGAGet(pScreen);
823    (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
824    VGAPut();
825    GC_WRAP(pGC);
826}
827
828static void
829VGAarbiterFillPolygon(
830    DrawablePtr pDraw,
831    GCPtr   pGC,
832    int     shape,
833    int     mode,
834    int     count,
835    DDXPointPtr ptsIn )
836{
837    ScreenPtr pScreen = pGC->pScreen;
838    GC_UNWRAP(pGC);
839    VGAGet(pScreen);
840    (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
841    VGAPut();
842    GC_WRAP(pGC);
843}
844
845static void
846VGAarbiterPolyFillRect(
847    DrawablePtr pDraw,
848    GCPtr   pGC,
849    int     nrectFill,
850    xRectangle  *prectInit)
851{
852    ScreenPtr pScreen = pGC->pScreen;
853    GC_UNWRAP(pGC);
854    VGAGet(pScreen);
855    (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
856    VGAPut();
857    GC_WRAP(pGC);
858}
859
860static void
861VGAarbiterPolyFillArc(
862    DrawablePtr pDraw,
863    GCPtr   pGC,
864    int     narcs,
865    xArc    *parcs )
866{
867    ScreenPtr pScreen = pGC->pScreen;
868    GC_UNWRAP(pGC);
869    VGAGet(pScreen);
870    (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
871    VGAPut();
872    GC_WRAP(pGC);
873}
874
875static int
876VGAarbiterPolyText8(
877    DrawablePtr pDraw,
878    GCPtr   pGC,
879    int     x,
880    int     y,
881    int     count,
882    char    *chars )
883{
884    int ret;
885    ScreenPtr pScreen = pGC->pScreen;
886    GC_UNWRAP(pGC);
887    VGAGet(pScreen);
888    ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
889    VGAPut();
890    GC_WRAP(pGC);
891    return ret;
892}
893
894static int
895VGAarbiterPolyText16(
896    DrawablePtr pDraw,
897    GCPtr   pGC,
898    int     x,
899    int     y,
900    int     count,
901    unsigned short *chars )
902{
903    int ret;
904    ScreenPtr pScreen = pGC->pScreen;
905    GC_UNWRAP(pGC);
906    VGAGet(pScreen);
907    ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
908    VGAPut();
909    GC_WRAP(pGC);
910    return ret;
911}
912
913static void
914VGAarbiterImageText8(
915    DrawablePtr pDraw,
916    GCPtr   pGC,
917    int     x,
918    int     y,
919    int     count,
920    char    *chars )
921{
922    ScreenPtr pScreen = pGC->pScreen;
923    GC_UNWRAP(pGC);
924    VGAGet(pScreen);
925    (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
926    VGAPut();
927    GC_WRAP(pGC);
928}
929
930static void
931VGAarbiterImageText16(
932    DrawablePtr pDraw,
933    GCPtr   pGC,
934    int     x,
935    int     y,
936    int     count,
937    unsigned short *chars )
938{
939    ScreenPtr pScreen = pGC->pScreen;
940    GC_UNWRAP(pGC);
941    VGAGet(pScreen);
942    (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
943    VGAPut();
944    GC_WRAP(pGC);
945}
946
947
948static void
949VGAarbiterImageGlyphBlt(
950    DrawablePtr pDraw,
951    GCPtr pGC,
952    int xInit, int yInit,
953    unsigned int nglyph,
954    CharInfoPtr *ppci,
955    pointer pglyphBase )
956{
957    ScreenPtr pScreen = pGC->pScreen;
958    GC_UNWRAP(pGC);
959    VGAGet(pScreen);
960    (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
961                   nglyph, ppci, pglyphBase);
962    VGAPut();
963    GC_WRAP(pGC);
964}
965
966static void
967VGAarbiterPolyGlyphBlt(
968    DrawablePtr pDraw,
969    GCPtr pGC,
970    int xInit, int yInit,
971    unsigned int nglyph,
972    CharInfoPtr *ppci,
973    pointer pglyphBase )
974{
975    ScreenPtr pScreen = pGC->pScreen;
976    GC_UNWRAP(pGC);
977    VGAGet(pScreen);
978    (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
979                  nglyph, ppci, pglyphBase);
980    VGAPut();
981    GC_WRAP(pGC);
982}
983
984static void
985VGAarbiterPushPixels(
986    GCPtr   pGC,
987    PixmapPtr   pBitMap,
988    DrawablePtr pDraw,
989    int dx, int dy, int xOrg, int yOrg )
990{
991    ScreenPtr pScreen = pGC->pScreen;
992    GC_UNWRAP(pGC);
993    VGAGet(pScreen);
994    (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
995    VGAPut();
996    GC_WRAP(pGC);
997}
998
999
1000/* miSpriteFuncs */
1001static Bool
1002VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
1003{
1004    Bool val;
1005    SPRITE_PROLOG;
1006    VGAGet(pScreen);
1007    val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
1008    VGAPut();
1009    SPRITE_EPILOG;
1010    return val;
1011}
1012
1013static Bool
1014VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
1015{
1016    Bool val;
1017    SPRITE_PROLOG;
1018    VGAGet(pScreen);
1019    val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
1020    VGAPut();
1021    SPRITE_EPILOG;
1022    return val;
1023}
1024
1025static void
1026VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
1027{
1028    SPRITE_PROLOG;
1029    VGAGet(pScreen);
1030    PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
1031    VGAPut();
1032    SPRITE_EPILOG;
1033}
1034
1035static void
1036VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
1037{
1038    SPRITE_PROLOG;
1039    VGAGet(pScreen);
1040    PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
1041    VGAPut();
1042    SPRITE_EPILOG;
1043}
1044
1045static Bool
1046VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
1047{
1048    Bool val;
1049    SPRITE_PROLOG;
1050    VGAGet(pScreen);
1051    val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
1052    VGAPut();
1053    SPRITE_EPILOG;
1054    return val;
1055}
1056
1057static void
1058VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
1059{
1060    SPRITE_PROLOG;
1061    VGAGet(pScreen);
1062    PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
1063    VGAPut();
1064    SPRITE_EPILOG;
1065}
1066
1067static void
1068VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
1069         PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
1070         INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
1071         CARD16 height)
1072{
1073    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1074    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1075
1076    PICTURE_PROLOGUE(Composite);
1077
1078    VGAGet(pScreen);
1079    (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
1080              yDst, width, height);
1081    VGAPut();
1082    PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
1083}
1084
1085static void
1086VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
1087      PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
1088      GlyphListPtr list, GlyphPtr *glyphs)
1089{
1090    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1091    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1092
1093    PICTURE_PROLOGUE(Glyphs);
1094
1095    VGAGet(pScreen);
1096    (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
1097    VGAPut();
1098    PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
1099}
1100
1101static void
1102VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
1103          xRectangle *rects)
1104{
1105    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
1106    PictureScreenPtr    ps = GetPictureScreen(pScreen);
1107
1108    PICTURE_PROLOGUE(CompositeRects);
1109
1110    VGAGet(pScreen);
1111    (*ps->CompositeRects)(op, pDst, color, nRect, rects);
1112    VGAPut();
1113    PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
1114}
1115#else
1116/* dummy functions */
1117void xf86VGAarbiterInit(void) {}
1118void xf86VGAarbiterFini(void) {}
1119
1120void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
1121void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
1122Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
1123void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
1124void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc) {}
1125Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
1126
1127#endif
1128