1 /*
2  * Copyright (c) 2009 Tiago Vignatti
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use,
8  * copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following
11  * conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  *
25  */
26 
27 #ifdef HAVE_XORG_CONFIG_H
28 #include <xorg-config.h>
29 #endif
30 
31 #include "misc.h"
32 #include "xf86.h"
33 #include "xf86_OSproc.h"
34 #include <X11/X.h>
35 #include "colormapst.h"
36 #include "scrnintstr.h"
37 #include "screenint.h"
38 #include "gcstruct.h"
39 #include "pixmapstr.h"
40 #include "pixmap.h"
41 #include "windowstr.h"
42 #include "window.h"
43 #include "xf86str.h"
44 #include "mipointer.h"
45 #include "mipointrst.h"
46 #include "picturestr.h"
47 
48 #define WRAP_SCREEN(x,y) {pScreenPriv->x = pScreen->x; pScreen->x = y;}
49 
50 #define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x
51 
52 #define SCREEN_PRIV()   ((VGAarbiterScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))
53 
54 #define SCREEN_PROLOG(x) (pScreen->x = SCREEN_PRIV()->x)
55 
56 #define SCREEN_EPILOG(x,y) do {                 \
57         SCREEN_PRIV()->x = pScreen->x;          \
58         pScreen->x = y;                         \
59     } while (0)
60 
61 #define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\
62     ps->x = y;}
63 
64 #define UNWRAP_PICT(x) if (ps) {ps->x = pScreenPriv->x;}
65 
66 #define PICTURE_PROLOGUE(field) ps->field = \
67     ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \
68     VGAarbiterScreenKey))->field
69 
70 #define PICTURE_EPILOGUE(field, wrap) ps->field = wrap
71 
72 #define WRAP_SCREEN_INFO(x,y) do {pScreenPriv->x = pScrn->x; pScrn->x = y;} while(0)
73 
74 #define UNWRAP_SCREEN_INFO(x) pScrn->x = pScreenPriv->x
75 
76 #define SPRITE_PROLOG                                           \
77     miPointerScreenPtr PointPriv;                               \
78     VGAarbiterScreenPtr pScreenPriv;                            \
79     input_lock();                                               \
80     PointPriv = dixLookupPrivate(&pScreen->devPrivates,         \
81                                  miPointerScreenKey);           \
82     pScreenPriv = dixLookupPrivate(&(pScreen)->devPrivates,     \
83                                    VGAarbiterScreenKey);        \
84     PointPriv->spriteFuncs = pScreenPriv->miSprite;             \
85 
86 #define SPRITE_EPILOG                                   \
87     pScreenPriv->miSprite = PointPriv->spriteFuncs;     \
88     PointPriv->spriteFuncs  = &VGAarbiterSpriteFuncs;   \
89     input_unlock();
90 
91 #define WRAP_SPRITE do { pScreenPriv->miSprite = PointPriv->spriteFuncs;\
92     	PointPriv->spriteFuncs  = &VGAarbiterSpriteFuncs; 		\
93 	} while (0)
94 
95 #define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite
96 
97 #define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\
98     pGCPriv->wrapFuncs = (x)->funcs; (x)->ops = &VGAarbiterGCOps;\
99     (x)->funcs = &VGAarbiterGCFuncs;
100 
101 #define GC_UNWRAP(x) VGAarbiterGCPtr  pGCPriv = \
102     (VGAarbiterGCPtr)dixLookupPrivate(&(x)->devPrivates, VGAarbiterGCKey);\
103     (x)->ops = pGCPriv->wrapOps; (x)->funcs = pGCPriv->wrapFuncs;
104 
105 static inline void
VGAGet(ScreenPtr pScreen)106 VGAGet(ScreenPtr pScreen)
107 {
108     pci_device_vgaarb_set_target(xf86ScreenToScrn(pScreen)->vgaDev);
109     pci_device_vgaarb_lock();
110 }
111 
112 static inline void
VGAPut(void)113 VGAPut(void)
114 {
115     pci_device_vgaarb_unlock();
116 }
117 
118 typedef struct _VGAarbiterScreen {
119     CreateGCProcPtr CreateGC;
120     CloseScreenProcPtr CloseScreen;
121     ScreenBlockHandlerProcPtr BlockHandler;
122     ScreenWakeupHandlerProcPtr WakeupHandler;
123     GetImageProcPtr GetImage;
124     GetSpansProcPtr GetSpans;
125     SourceValidateProcPtr SourceValidate;
126     CopyWindowProcPtr CopyWindow;
127     ClearToBackgroundProcPtr ClearToBackground;
128     CreatePixmapProcPtr CreatePixmap;
129     SaveScreenProcPtr SaveScreen;
130     /* Colormap */
131     StoreColorsProcPtr StoreColors;
132     /* Cursor */
133     DisplayCursorProcPtr DisplayCursor;
134     RealizeCursorProcPtr RealizeCursor;
135     UnrealizeCursorProcPtr UnrealizeCursor;
136     RecolorCursorProcPtr RecolorCursor;
137     SetCursorPositionProcPtr SetCursorPosition;
138     void (*AdjustFrame) (ScrnInfoPtr, int, int);
139     Bool (*SwitchMode) (ScrnInfoPtr, DisplayModePtr);
140     Bool (*EnterVT) (ScrnInfoPtr);
141     void (*LeaveVT) (ScrnInfoPtr);
142     void (*FreeScreen) (ScrnInfoPtr);
143     miPointerSpriteFuncPtr miSprite;
144     CompositeProcPtr Composite;
145     GlyphsProcPtr Glyphs;
146     CompositeRectsProcPtr CompositeRects;
147 } VGAarbiterScreenRec, *VGAarbiterScreenPtr;
148 
149 typedef struct _VGAarbiterGC {
150     const GCOps *wrapOps;
151     const GCFuncs *wrapFuncs;
152 } VGAarbiterGCRec, *VGAarbiterGCPtr;
153 
154 /* Screen funcs */
155 static void VGAarbiterBlockHandler(ScreenPtr pScreen, void *pTimeout);
156 static void VGAarbiterWakeupHandler(ScreenPtr pScreen, int result);
157 static Bool VGAarbiterCloseScreen(ScreenPtr pScreen);
158 static void VGAarbiterGetImage(DrawablePtr pDrawable, int sx, int sy, int w,
159                                int h, unsigned int format,
160                                unsigned long planemask, char *pdstLine);
161 static void VGAarbiterGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
162                                int *pwidth, int nspans, char *pdstStart);
163 static void VGAarbiterSourceValidate(DrawablePtr pDrawable, int x, int y,
164                                      int width, int height,
165                                      unsigned int subWindowMode);
166 static void VGAarbiterCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
167                                  RegionPtr prgnSrc);
168 static void VGAarbiterClearToBackground(WindowPtr pWin, int x, int y, int w,
169                                         int h, Bool generateExposures);
170 static PixmapPtr VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h,
171                                         int depth, unsigned int usage_hint);
172 static Bool VGAarbiterCreateGC(GCPtr pGC);
173 static Bool VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank);
174 static void VGAarbiterStoreColors(ColormapPtr pmap, int ndef, xColorItem
175                                   * pdefs);
176 static void VGAarbiterRecolorCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
177                                     CursorPtr pCurs, Bool displayed);
178 static Bool VGAarbiterRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
179                                     CursorPtr pCursor);
180 static Bool VGAarbiterUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
181                                       CursorPtr pCursor);
182 static Bool VGAarbiterDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
183                                     CursorPtr pCursor);
184 static Bool VGAarbiterSetCursorPosition(DeviceIntPtr pDev, ScreenPtr
185                                         pScreen, int x, int y,
186                                         Bool generateEvent);
187 static void VGAarbiterAdjustFrame(ScrnInfoPtr pScrn, int x, int y);
188 static Bool VGAarbiterSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
189 static Bool VGAarbiterEnterVT(ScrnInfoPtr pScrn);
190 static void VGAarbiterLeaveVT(ScrnInfoPtr pScrn);
191 static void VGAarbiterFreeScreen(ScrnInfoPtr pScrn);
192 
193 /* GC funcs */
194 static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes,
195                                  DrawablePtr pDraw);
196 static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask);
197 static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
198 static void VGAarbiterDestroyGC(GCPtr pGC);
199 static void VGAarbiterChangeClip(GCPtr pGC, int type, void *pvalue,
200                                  int nrects);
201 static void VGAarbiterDestroyClip(GCPtr pGC);
202 static void VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
203 
204 /* GC ops */
205 static void VGAarbiterFillSpans(DrawablePtr pDraw, GC * pGC, int nInit,
206                                 DDXPointPtr pptInit, int *pwidthInit,
207                                 int fSorted);
208 static void VGAarbiterSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc,
209                                register DDXPointPtr ppt, int *pwidth,
210                                int nspans, int fSorted);
211 static void VGAarbiterPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x,
212                                int y, int w, int h, int leftPad, int format,
213                                char *pImage);
214 static RegionPtr VGAarbiterCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
215                                     GC * pGC, int srcx, int srcy, int width,
216                                     int height, int dstx, int dsty);
217 static RegionPtr VGAarbiterCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
218                                      GCPtr pGC, int srcx, int srcy, int width,
219                                      int height, int dstx, int dsty,
220                                      unsigned long bitPlane);
221 static void VGAarbiterPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode, int npt,
222                                 xPoint * pptInit);
223 static void VGAarbiterPolylines(DrawablePtr pDraw, GCPtr pGC, int mode, int npt,
224                                 DDXPointPtr pptInit);
225 static void VGAarbiterPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg,
226                                   xSegment * pSeg);
227 static void VGAarbiterPolyRectangle(DrawablePtr pDraw, GCPtr pGC,
228                                     int nRectsInit, xRectangle *pRectsInit);
229 static void VGAarbiterPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
230                               xArc * parcs);
231 static void VGAarbiterFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape,
232                                   int mode, int count, DDXPointPtr ptsIn);
233 static void VGAarbiterPolyFillRect(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
234                                    xRectangle *prectInit);
235 static void VGAarbiterPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
236                                   xArc * parcs);
237 static int VGAarbiterPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
238                                int count, char *chars);
239 static int VGAarbiterPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
240                                 int count, unsigned short *chars);
241 static void VGAarbiterImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
242                                  int count, char *chars);
243 static void VGAarbiterImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
244                                   int count, unsigned short *chars);
245 static void VGAarbiterImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
246                                     int yInit, unsigned int nglyph,
247                                     CharInfoPtr * ppci, void *pglyphBase);
248 static void VGAarbiterPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
249                                    int yInit, unsigned int nglyph,
250                                    CharInfoPtr * ppci, void *pglyphBase);
251 static void VGAarbiterPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr
252                                  pDraw, int dx, int dy, int xOrg, int yOrg);
253 
254 /* miSpriteFuncs */
255 static Bool VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr
256                                           pScreen, CursorPtr pCur);
257 static Bool VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr
258                                             pScreen, CursorPtr pCur);
259 static void VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
260                                       CursorPtr pCur, int x, int y);
261 static void VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
262                                        int x, int y);
263 static Bool VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev,
264                                              ScreenPtr pScreen);
265 static void VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
266 
267 static void VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
268                                 PicturePtr pDst, INT16 xSrc, INT16 ySrc,
269                                 INT16 xMask, INT16 yMask, INT16 xDst,
270                                 INT16 yDst, CARD16 width, CARD16 height);
271 static void VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
272                              PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
273                              int nlist, GlyphListPtr list, GlyphPtr * glyphs);
274 static void VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst,
275                                      xRenderColor * color, int nRect,
276                                      xRectangle *rects);
277