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     if (pScreen->SourceValidate)
325         (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
326                                     subWindowMode);
327     VGAPut();
328     SCREEN_EPILOG(SourceValidate, VGAarbiterSourceValidate);
329 }
330 
331 static void
VGAarbiterCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc)332 VGAarbiterCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
333 {
334     ScreenPtr pScreen = pWin->drawable.pScreen;
335 
336     SCREEN_PROLOG(CopyWindow);
337     VGAGet(pScreen);
338     (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
339     VGAPut();
340     SCREEN_EPILOG(CopyWindow, VGAarbiterCopyWindow);
341 }
342 
343 static void
VGAarbiterClearToBackground(WindowPtr pWin,int x,int y,int w,int h,Bool generateExposures)344 VGAarbiterClearToBackground(WindowPtr pWin,
345                             int x, int y, int w, int h, Bool generateExposures)
346 {
347     ScreenPtr pScreen = pWin->drawable.pScreen;
348 
349     SCREEN_PROLOG(ClearToBackground);
350     VGAGet(pScreen);
351     (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
352     VGAPut();
353     SCREEN_EPILOG(ClearToBackground, VGAarbiterClearToBackground);
354 }
355 
356 static PixmapPtr
VGAarbiterCreatePixmap(ScreenPtr pScreen,int w,int h,int depth,unsigned usage_hint)357 VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
358                        unsigned usage_hint)
359 {
360     PixmapPtr pPix;
361 
362     SCREEN_PROLOG(CreatePixmap);
363     VGAGet(pScreen);
364     pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
365     VGAPut();
366     SCREEN_EPILOG(CreatePixmap, VGAarbiterCreatePixmap);
367 
368     return pPix;
369 }
370 
371 static Bool
VGAarbiterSaveScreen(ScreenPtr pScreen,Bool unblank)372 VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
373 {
374     Bool val;
375 
376     SCREEN_PROLOG(SaveScreen);
377     VGAGet(pScreen);
378     val = (*pScreen->SaveScreen) (pScreen, unblank);
379     VGAPut();
380     SCREEN_EPILOG(SaveScreen, VGAarbiterSaveScreen);
381 
382     return val;
383 }
384 
385 static void
VGAarbiterStoreColors(ColormapPtr pmap,int ndef,xColorItem * pdefs)386 VGAarbiterStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
387 {
388     ScreenPtr pScreen = pmap->pScreen;
389 
390     SCREEN_PROLOG(StoreColors);
391     VGAGet(pScreen);
392     (*pScreen->StoreColors) (pmap, ndef, pdefs);
393     VGAPut();
394     SCREEN_EPILOG(StoreColors, VGAarbiterStoreColors);
395 }
396 
397 static void
VGAarbiterRecolorCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCurs,Bool displayed)398 VGAarbiterRecolorCursor(DeviceIntPtr pDev,
399                         ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
400 {
401     SCREEN_PROLOG(RecolorCursor);
402     VGAGet(pScreen);
403     (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
404     VGAPut();
405     SCREEN_EPILOG(RecolorCursor, VGAarbiterRecolorCursor);
406 }
407 
408 static Bool
VGAarbiterRealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)409 VGAarbiterRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
410 {
411     Bool val;
412 
413     SCREEN_PROLOG(RealizeCursor);
414     VGAGet(pScreen);
415     val = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor);
416     VGAPut();
417     SCREEN_EPILOG(RealizeCursor, VGAarbiterRealizeCursor);
418     return val;
419 }
420 
421 static Bool
VGAarbiterUnrealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)422 VGAarbiterUnrealizeCursor(DeviceIntPtr pDev,
423                           ScreenPtr pScreen, CursorPtr pCursor)
424 {
425     Bool val;
426 
427     SCREEN_PROLOG(UnrealizeCursor);
428     VGAGet(pScreen);
429     val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
430     VGAPut();
431     SCREEN_EPILOG(UnrealizeCursor, VGAarbiterUnrealizeCursor);
432     return val;
433 }
434 
435 static Bool
VGAarbiterDisplayCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)436 VGAarbiterDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
437 {
438     Bool val;
439 
440     SCREEN_PROLOG(DisplayCursor);
441     VGAGet(pScreen);
442     val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
443     VGAPut();
444     SCREEN_EPILOG(DisplayCursor, VGAarbiterDisplayCursor);
445     return val;
446 }
447 
448 static Bool
VGAarbiterSetCursorPosition(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y,Bool generateEvent)449 VGAarbiterSetCursorPosition(DeviceIntPtr pDev,
450                             ScreenPtr pScreen, int x, int y, Bool generateEvent)
451 {
452     Bool val;
453 
454     SCREEN_PROLOG(SetCursorPosition);
455     VGAGet(pScreen);
456     val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
457     VGAPut();
458     SCREEN_EPILOG(SetCursorPosition, VGAarbiterSetCursorPosition);
459     return val;
460 }
461 
462 static void
VGAarbiterAdjustFrame(ScrnInfoPtr pScrn,int x,int y)463 VGAarbiterAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
464 {
465     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
466     VGAarbiterScreenPtr pScreenPriv =
467         (VGAarbiterScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
468                                                VGAarbiterScreenKey);
469 
470     VGAGet(pScreen);
471     (*pScreenPriv->AdjustFrame) (pScrn, x, y);
472     VGAPut();
473 }
474 
475 static Bool
VGAarbiterSwitchMode(ScrnInfoPtr pScrn,DisplayModePtr mode)476 VGAarbiterSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
477 {
478     Bool val;
479     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
480     VGAarbiterScreenPtr pScreenPriv =
481         (VGAarbiterScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
482                                                VGAarbiterScreenKey);
483 
484     VGAGet(pScreen);
485     val = (*pScreenPriv->SwitchMode) (pScrn, mode);
486     VGAPut();
487     return val;
488 }
489 
490 static Bool
VGAarbiterEnterVT(ScrnInfoPtr pScrn)491 VGAarbiterEnterVT(ScrnInfoPtr pScrn)
492 {
493     Bool val;
494     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
495     VGAarbiterScreenPtr pScreenPriv =
496         (VGAarbiterScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
497                                                VGAarbiterScreenKey);
498 
499     VGAGet(pScreen);
500     pScrn->EnterVT = pScreenPriv->EnterVT;
501     val = (*pScrn->EnterVT) (pScrn);
502     pScreenPriv->EnterVT = pScrn->EnterVT;
503     pScrn->EnterVT = VGAarbiterEnterVT;
504     VGAPut();
505     return val;
506 }
507 
508 static void
VGAarbiterLeaveVT(ScrnInfoPtr pScrn)509 VGAarbiterLeaveVT(ScrnInfoPtr pScrn)
510 {
511     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
512     VGAarbiterScreenPtr pScreenPriv =
513         (VGAarbiterScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
514                                                VGAarbiterScreenKey);
515 
516     VGAGet(pScreen);
517     pScrn->LeaveVT = pScreenPriv->LeaveVT;
518     (*pScreenPriv->LeaveVT) (pScrn);
519     pScreenPriv->LeaveVT = pScrn->LeaveVT;
520     pScrn->LeaveVT = VGAarbiterLeaveVT;
521     VGAPut();
522 }
523 
524 static void
VGAarbiterFreeScreen(ScrnInfoPtr pScrn)525 VGAarbiterFreeScreen(ScrnInfoPtr pScrn)
526 {
527     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
528     VGAarbiterScreenPtr pScreenPriv =
529         (VGAarbiterScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
530                                                VGAarbiterScreenKey);
531 
532     VGAGet(pScreen);
533     (*pScreenPriv->FreeScreen) (pScrn);
534     VGAPut();
535 }
536 
537 static Bool
VGAarbiterCreateGC(GCPtr pGC)538 VGAarbiterCreateGC(GCPtr pGC)
539 {
540     ScreenPtr pScreen = pGC->pScreen;
541     VGAarbiterGCPtr pGCPriv =
542         (VGAarbiterGCPtr) dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
543     Bool ret;
544 
545     SCREEN_PROLOG(CreateGC);
546     ret = (*pScreen->CreateGC) (pGC);
547     GC_WRAP(pGC);
548     SCREEN_EPILOG(CreateGC, VGAarbiterCreateGC);
549 
550     return ret;
551 }
552 
553 /* GC funcs */
554 static void
VGAarbiterValidateGC(GCPtr pGC,unsigned long changes,DrawablePtr pDraw)555 VGAarbiterValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw)
556 {
557     GC_UNWRAP(pGC);
558     (*pGC->funcs->ValidateGC) (pGC, changes, pDraw);
559     GC_WRAP(pGC);
560 }
561 
562 static void
VGAarbiterDestroyGC(GCPtr pGC)563 VGAarbiterDestroyGC(GCPtr pGC)
564 {
565     GC_UNWRAP(pGC);
566     (*pGC->funcs->DestroyGC) (pGC);
567     GC_WRAP(pGC);
568 }
569 
570 static void
VGAarbiterChangeGC(GCPtr pGC,unsigned long mask)571 VGAarbiterChangeGC(GCPtr pGC, unsigned long mask)
572 {
573     GC_UNWRAP(pGC);
574     (*pGC->funcs->ChangeGC) (pGC, mask);
575     GC_WRAP(pGC);
576 }
577 
578 static void
VGAarbiterCopyGC(GCPtr pGCSrc,unsigned long mask,GCPtr pGCDst)579 VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
580 {
581     GC_UNWRAP(pGCDst);
582     (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
583     GC_WRAP(pGCDst);
584 }
585 
586 static void
VGAarbiterChangeClip(GCPtr pGC,int type,void * pvalue,int nrects)587 VGAarbiterChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
588 {
589     GC_UNWRAP(pGC);
590     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
591     GC_WRAP(pGC);
592 }
593 
594 static void
VGAarbiterCopyClip(GCPtr pgcDst,GCPtr pgcSrc)595 VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
596 {
597     GC_UNWRAP(pgcDst);
598     (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc);
599     GC_WRAP(pgcDst);
600 }
601 
602 static void
VGAarbiterDestroyClip(GCPtr pGC)603 VGAarbiterDestroyClip(GCPtr pGC)
604 {
605     GC_UNWRAP(pGC);
606     (*pGC->funcs->DestroyClip) (pGC);
607     GC_WRAP(pGC);
608 }
609 
610 /* GC Ops */
611 static void
VGAarbiterFillSpans(DrawablePtr pDraw,GC * pGC,int nInit,DDXPointPtr pptInit,int * pwidthInit,int fSorted)612 VGAarbiterFillSpans(DrawablePtr pDraw,
613                     GC * pGC,
614                     int nInit,
615                     DDXPointPtr pptInit, int *pwidthInit, int fSorted)
616 {
617     ScreenPtr pScreen = pGC->pScreen;
618 
619     GC_UNWRAP(pGC);
620     VGAGet(pScreen);
621     (*pGC->ops->FillSpans) (pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
622     VGAPut();
623     GC_WRAP(pGC);
624 }
625 
626 static void
VGAarbiterSetSpans(DrawablePtr pDraw,GCPtr pGC,char * pcharsrc,register DDXPointPtr ppt,int * pwidth,int nspans,int fSorted)627 VGAarbiterSetSpans(DrawablePtr pDraw,
628                    GCPtr pGC,
629                    char *pcharsrc,
630                    register DDXPointPtr ppt,
631                    int *pwidth, int nspans, int fSorted)
632 {
633     ScreenPtr pScreen = pGC->pScreen;
634 
635     GC_UNWRAP(pGC);
636     VGAGet(pScreen);
637     (*pGC->ops->SetSpans) (pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
638     VGAPut();
639     GC_WRAP(pGC);
640 }
641 
642 static void
VGAarbiterPutImage(DrawablePtr pDraw,GCPtr pGC,int depth,int x,int y,int w,int h,int leftPad,int format,char * pImage)643 VGAarbiterPutImage(DrawablePtr pDraw,
644                    GCPtr pGC,
645                    int depth,
646                    int x, int y, int w, int h,
647                    int leftPad, int format, char *pImage)
648 {
649     ScreenPtr pScreen = pGC->pScreen;
650 
651     GC_UNWRAP(pGC);
652     VGAGet(pScreen);
653     (*pGC->ops->PutImage) (pDraw, pGC, depth, x, y, w, h,
654                            leftPad, format, pImage);
655     VGAPut();
656     GC_WRAP(pGC);
657 }
658 
659 static RegionPtr
VGAarbiterCopyArea(DrawablePtr pSrc,DrawablePtr pDst,GC * pGC,int srcx,int srcy,int width,int height,int dstx,int dsty)660 VGAarbiterCopyArea(DrawablePtr pSrc,
661                    DrawablePtr pDst,
662                    GC * pGC,
663                    int srcx, int srcy,
664                    int width, int height, int dstx, int dsty)
665 {
666     RegionPtr ret;
667     ScreenPtr pScreen = pGC->pScreen;
668 
669     GC_UNWRAP(pGC);
670     VGAGet(pScreen);
671     ret = (*pGC->ops->CopyArea) (pSrc, pDst,
672                                  pGC, srcx, srcy, width, height, dstx, dsty);
673     VGAPut();
674     GC_WRAP(pGC);
675     return ret;
676 }
677 
678 static RegionPtr
VGAarbiterCopyPlane(DrawablePtr pSrc,DrawablePtr pDst,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty,unsigned long bitPlane)679 VGAarbiterCopyPlane(DrawablePtr pSrc,
680                     DrawablePtr pDst,
681                     GCPtr pGC,
682                     int srcx, int srcy,
683                     int width, int height,
684                     int dstx, int dsty, unsigned long bitPlane)
685 {
686     RegionPtr ret;
687     ScreenPtr pScreen = pGC->pScreen;
688 
689     GC_UNWRAP(pGC);
690     VGAGet(pScreen);
691     ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy,
692                                   width, height, dstx, dsty, bitPlane);
693     VGAPut();
694     GC_WRAP(pGC);
695     return ret;
696 }
697 
698 static void
VGAarbiterPolyPoint(DrawablePtr pDraw,GCPtr pGC,int mode,int npt,xPoint * pptInit)699 VGAarbiterPolyPoint(DrawablePtr pDraw,
700                     GCPtr pGC, int mode, int npt, xPoint * pptInit)
701 {
702     ScreenPtr pScreen = pGC->pScreen;
703 
704     GC_UNWRAP(pGC);
705     VGAGet(pScreen);
706     (*pGC->ops->PolyPoint) (pDraw, pGC, mode, npt, pptInit);
707     VGAPut();
708     GC_WRAP(pGC);
709 }
710 
711 static void
VGAarbiterPolylines(DrawablePtr pDraw,GCPtr pGC,int mode,int npt,DDXPointPtr pptInit)712 VGAarbiterPolylines(DrawablePtr pDraw,
713                     GCPtr pGC, int mode, int npt, DDXPointPtr pptInit)
714 {
715     ScreenPtr pScreen = pGC->pScreen;
716 
717     GC_UNWRAP(pGC);
718     VGAGet(pScreen);
719     (*pGC->ops->Polylines) (pDraw, pGC, mode, npt, pptInit);
720     VGAPut();
721     GC_WRAP(pGC);
722 }
723 
724 static void
VGAarbiterPolySegment(DrawablePtr pDraw,GCPtr pGC,int nseg,xSegment * pSeg)725 VGAarbiterPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment * pSeg)
726 {
727     ScreenPtr pScreen = pGC->pScreen;
728 
729     GC_UNWRAP(pGC);
730     VGAGet(pScreen);
731     (*pGC->ops->PolySegment) (pDraw, pGC, nseg, pSeg);
732     VGAPut();
733     GC_WRAP(pGC);
734 }
735 
736 static void
VGAarbiterPolyRectangle(DrawablePtr pDraw,GCPtr pGC,int nRectsInit,xRectangle * pRectsInit)737 VGAarbiterPolyRectangle(DrawablePtr pDraw,
738                         GCPtr pGC, int nRectsInit, xRectangle *pRectsInit)
739 {
740     ScreenPtr pScreen = pGC->pScreen;
741 
742     GC_UNWRAP(pGC);
743     VGAGet(pScreen);
744     (*pGC->ops->PolyRectangle) (pDraw, pGC, nRectsInit, pRectsInit);
745     VGAPut();
746     GC_WRAP(pGC);
747 }
748 
749 static void
VGAarbiterPolyArc(DrawablePtr pDraw,GCPtr pGC,int narcs,xArc * parcs)750 VGAarbiterPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
751 {
752     ScreenPtr pScreen = pGC->pScreen;
753 
754     GC_UNWRAP(pGC);
755     VGAGet(pScreen);
756     (*pGC->ops->PolyArc) (pDraw, pGC, narcs, parcs);
757     VGAPut();
758     GC_WRAP(pGC);
759 }
760 
761 static void
VGAarbiterFillPolygon(DrawablePtr pDraw,GCPtr pGC,int shape,int mode,int count,DDXPointPtr ptsIn)762 VGAarbiterFillPolygon(DrawablePtr pDraw,
763                       GCPtr pGC,
764                       int shape, int mode, int count, DDXPointPtr ptsIn)
765 {
766     ScreenPtr pScreen = pGC->pScreen;
767 
768     GC_UNWRAP(pGC);
769     VGAGet(pScreen);
770     (*pGC->ops->FillPolygon) (pDraw, pGC, shape, mode, count, ptsIn);
771     VGAPut();
772     GC_WRAP(pGC);
773 }
774 
775 static void
VGAarbiterPolyFillRect(DrawablePtr pDraw,GCPtr pGC,int nrectFill,xRectangle * prectInit)776 VGAarbiterPolyFillRect(DrawablePtr pDraw,
777                        GCPtr pGC, int nrectFill, xRectangle *prectInit)
778 {
779     ScreenPtr pScreen = pGC->pScreen;
780 
781     GC_UNWRAP(pGC);
782     VGAGet(pScreen);
783     (*pGC->ops->PolyFillRect) (pDraw, pGC, nrectFill, prectInit);
784     VGAPut();
785     GC_WRAP(pGC);
786 }
787 
788 static void
VGAarbiterPolyFillArc(DrawablePtr pDraw,GCPtr pGC,int narcs,xArc * parcs)789 VGAarbiterPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
790 {
791     ScreenPtr pScreen = pGC->pScreen;
792 
793     GC_UNWRAP(pGC);
794     VGAGet(pScreen);
795     (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, parcs);
796     VGAPut();
797     GC_WRAP(pGC);
798 }
799 
800 static int
VGAarbiterPolyText8(DrawablePtr pDraw,GCPtr pGC,int x,int y,int count,char * chars)801 VGAarbiterPolyText8(DrawablePtr pDraw,
802                     GCPtr pGC, int x, int y, int count, char *chars)
803 {
804     int ret;
805     ScreenPtr pScreen = pGC->pScreen;
806 
807     GC_UNWRAP(pGC);
808     VGAGet(pScreen);
809     ret = (*pGC->ops->PolyText8) (pDraw, pGC, x, y, count, chars);
810     VGAPut();
811     GC_WRAP(pGC);
812     return ret;
813 }
814 
815 static int
VGAarbiterPolyText16(DrawablePtr pDraw,GCPtr pGC,int x,int y,int count,unsigned short * chars)816 VGAarbiterPolyText16(DrawablePtr pDraw,
817                      GCPtr pGC, int x, int y, int count, unsigned short *chars)
818 {
819     int ret;
820     ScreenPtr pScreen = pGC->pScreen;
821 
822     GC_UNWRAP(pGC);
823     VGAGet(pScreen);
824     ret = (*pGC->ops->PolyText16) (pDraw, pGC, x, y, count, chars);
825     VGAPut();
826     GC_WRAP(pGC);
827     return ret;
828 }
829 
830 static void
VGAarbiterImageText8(DrawablePtr pDraw,GCPtr pGC,int x,int y,int count,char * chars)831 VGAarbiterImageText8(DrawablePtr pDraw,
832                      GCPtr pGC, int x, int y, int count, char *chars)
833 {
834     ScreenPtr pScreen = pGC->pScreen;
835 
836     GC_UNWRAP(pGC);
837     VGAGet(pScreen);
838     (*pGC->ops->ImageText8) (pDraw, pGC, x, y, count, chars);
839     VGAPut();
840     GC_WRAP(pGC);
841 }
842 
843 static void
VGAarbiterImageText16(DrawablePtr pDraw,GCPtr pGC,int x,int y,int count,unsigned short * chars)844 VGAarbiterImageText16(DrawablePtr pDraw,
845                       GCPtr pGC, int x, int y, int count, unsigned short *chars)
846 {
847     ScreenPtr pScreen = pGC->pScreen;
848 
849     GC_UNWRAP(pGC);
850     VGAGet(pScreen);
851     (*pGC->ops->ImageText16) (pDraw, pGC, x, y, count, chars);
852     VGAPut();
853     GC_WRAP(pGC);
854 }
855 
856 static void
VGAarbiterImageGlyphBlt(DrawablePtr pDraw,GCPtr pGC,int xInit,int yInit,unsigned int nglyph,CharInfoPtr * ppci,void * pglyphBase)857 VGAarbiterImageGlyphBlt(DrawablePtr pDraw,
858                         GCPtr pGC,
859                         int xInit, int yInit,
860                         unsigned int nglyph,
861                         CharInfoPtr * ppci, void *pglyphBase)
862 {
863     ScreenPtr pScreen = pGC->pScreen;
864 
865     GC_UNWRAP(pGC);
866     VGAGet(pScreen);
867     (*pGC->ops->ImageGlyphBlt) (pDraw, pGC, xInit, yInit,
868                                 nglyph, ppci, pglyphBase);
869     VGAPut();
870     GC_WRAP(pGC);
871 }
872 
873 static void
VGAarbiterPolyGlyphBlt(DrawablePtr pDraw,GCPtr pGC,int xInit,int yInit,unsigned int nglyph,CharInfoPtr * ppci,void * pglyphBase)874 VGAarbiterPolyGlyphBlt(DrawablePtr pDraw,
875                        GCPtr pGC,
876                        int xInit, int yInit,
877                        unsigned int nglyph,
878                        CharInfoPtr * ppci, void *pglyphBase)
879 {
880     ScreenPtr pScreen = pGC->pScreen;
881 
882     GC_UNWRAP(pGC);
883     VGAGet(pScreen);
884     (*pGC->ops->PolyGlyphBlt) (pDraw, pGC, xInit, yInit,
885                                nglyph, ppci, pglyphBase);
886     VGAPut();
887     GC_WRAP(pGC);
888 }
889 
890 static void
VGAarbiterPushPixels(GCPtr pGC,PixmapPtr pBitMap,DrawablePtr pDraw,int dx,int dy,int xOrg,int yOrg)891 VGAarbiterPushPixels(GCPtr pGC,
892                      PixmapPtr pBitMap,
893                      DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg)
894 {
895     ScreenPtr pScreen = pGC->pScreen;
896 
897     GC_UNWRAP(pGC);
898     VGAGet(pScreen);
899     (*pGC->ops->PushPixels) (pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
900     VGAPut();
901     GC_WRAP(pGC);
902 }
903 
904 /* miSpriteFuncs */
905 static Bool
VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCur)906 VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
907                               CursorPtr pCur)
908 {
909     Bool val;
910 
911     SPRITE_PROLOG;
912     VGAGet(pScreen);
913     val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
914     VGAPut();
915     SPRITE_EPILOG;
916     return val;
917 }
918 
919 static Bool
VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCur)920 VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
921                                 CursorPtr pCur)
922 {
923     Bool val;
924 
925     SPRITE_PROLOG;
926     VGAGet(pScreen);
927     val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
928     VGAPut();
929     SPRITE_EPILOG;
930     return val;
931 }
932 
933 static void
VGAarbiterSpriteSetCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCur,int x,int y)934 VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur,
935                           int x, int y)
936 {
937     SPRITE_PROLOG;
938     VGAGet(pScreen);
939     PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
940     VGAPut();
941     SPRITE_EPILOG;
942 }
943 
944 static void
VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y)945 VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
946 {
947     SPRITE_PROLOG;
948     VGAGet(pScreen);
949     PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
950     VGAPut();
951     SPRITE_EPILOG;
952 }
953 
954 static Bool
VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev,ScreenPtr pScreen)955 VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
956 {
957     Bool val;
958 
959     SPRITE_PROLOG;
960     VGAGet(pScreen);
961     val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
962     VGAPut();
963     SPRITE_EPILOG;
964     return val;
965 }
966 
967 static void
VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev,ScreenPtr pScreen)968 VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
969 {
970     SPRITE_PROLOG;
971     VGAGet(pScreen);
972     PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
973     VGAPut();
974     SPRITE_EPILOG;
975 }
976 
977 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)978 VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
979                     PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
980                     INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
981                     CARD16 height)
982 {
983     ScreenPtr pScreen = pDst->pDrawable->pScreen;
984     PictureScreenPtr ps = GetPictureScreen(pScreen);
985 
986     PICTURE_PROLOGUE(Composite);
987 
988     VGAGet(pScreen);
989     (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
990                       yDst, width, height);
991     VGAPut();
992     PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
993 }
994 
995 static void
VGAarbiterGlyphs(CARD8 op,PicturePtr pSrc,PicturePtr pDst,PictFormatPtr maskFormat,INT16 xSrc,INT16 ySrc,int nlist,GlyphListPtr list,GlyphPtr * glyphs)996 VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
997                  PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
998                  GlyphListPtr list, GlyphPtr * glyphs)
999 {
1000     ScreenPtr pScreen = pDst->pDrawable->pScreen;
1001     PictureScreenPtr ps = GetPictureScreen(pScreen);
1002 
1003     PICTURE_PROLOGUE(Glyphs);
1004 
1005     VGAGet(pScreen);
1006     (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
1007     VGAPut();
1008     PICTURE_EPILOGUE(Glyphs, VGAarbiterGlyphs);
1009 }
1010 
1011 static void
VGAarbiterCompositeRects(CARD8 op,PicturePtr pDst,xRenderColor * color,int nRect,xRectangle * rects)1012 VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor * color,
1013                          int nRect, xRectangle *rects)
1014 {
1015     ScreenPtr pScreen = pDst->pDrawable->pScreen;
1016     PictureScreenPtr ps = GetPictureScreen(pScreen);
1017 
1018     PICTURE_PROLOGUE(CompositeRects);
1019 
1020     VGAGet(pScreen);
1021     (*ps->CompositeRects) (op, pDst, color, nRect, rects);
1022     VGAPut();
1023     PICTURE_EPILOGUE(CompositeRects, VGAarbiterCompositeRects);
1024 }
1025