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