2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
7 #include "xf86CursorPriv.h"
8 #include "colormapst.h"
11 int xf86CursorScreenIndex
= -1;
12 static unsigned long xf86CursorGeneration
= 0;
14 /* sprite functions */
16 static Bool
xf86CursorRealizeCursor(ScreenPtr
, CursorPtr
);
17 static Bool
xf86CursorUnrealizeCursor(ScreenPtr
, CursorPtr
);
18 static void xf86CursorSetCursor(ScreenPtr
, CursorPtr
, int, int);
19 static void xf86CursorMoveCursor(ScreenPtr
, int, int);
21 static miPointerSpriteFuncRec xf86CursorSpriteFuncs
= {
22 xf86CursorRealizeCursor
,
23 xf86CursorUnrealizeCursor
,
28 /* Screen functions */
30 static void xf86CursorInstallColormap(ColormapPtr
);
31 static void xf86CursorRecolorCursor(ScreenPtr
, CursorPtr
, Bool
);
32 static Bool
xf86CursorCloseScreen(int, ScreenPtr
);
33 static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
36 /* ScrnInfoRec functions */
38 static void xf86CursorEnableDisableFBAccess(int, Bool
);
39 static Bool
xf86CursorSwitchMode(int, DisplayModePtr
,int);
44 xf86CursorInfoPtr infoPtr
47 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
48 xf86CursorScreenPtr ScreenPriv
;
49 miPointerScreenPtr PointPriv
;
51 if (xf86CursorGeneration
!= serverGeneration
) {
52 if ((xf86CursorScreenIndex
= AllocateScreenPrivateIndex()) < 0)
54 xf86CursorGeneration
= serverGeneration
;
57 if (!xf86InitHardwareCursor(pScreen
, infoPtr
))
60 ScreenPriv
= xcalloc(1, sizeof(xf86CursorScreenRec
));
64 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
= ScreenPriv
;
66 ScreenPriv
->SWCursor
= TRUE
;
67 ScreenPriv
->isUp
= FALSE
;
68 ScreenPriv
->CurrentCursor
= NULL
;
69 ScreenPriv
->CursorInfoPtr
= infoPtr
;
70 ScreenPriv
->PalettedCursor
= FALSE
;
71 ScreenPriv
->pInstalledMap
= NULL
;
73 ScreenPriv
->CloseScreen
= pScreen
->CloseScreen
;
74 pScreen
->CloseScreen
= xf86CursorCloseScreen
;
75 ScreenPriv
->QueryBestSize
= pScreen
->QueryBestSize
;
76 pScreen
->QueryBestSize
= xf86CursorQueryBestSize
;
77 ScreenPriv
->RecolorCursor
= pScreen
->RecolorCursor
;
78 pScreen
->RecolorCursor
= xf86CursorRecolorCursor
;
80 if ((infoPtr
->pScrn
->bitsPerPixel
== 8) &&
81 !(infoPtr
->Flags
& HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
)) {
82 ScreenPriv
->InstallColormap
= pScreen
->InstallColormap
;
83 pScreen
->InstallColormap
= xf86CursorInstallColormap
;
84 ScreenPriv
->PalettedCursor
= TRUE
;
87 PointPriv
= pScreen
->devPrivates
[miPointerScreenIndex
].ptr
;
89 ScreenPriv
->showTransparent
= PointPriv
->showTransparent
;
90 if (infoPtr
->Flags
& HARDWARE_CURSOR_SHOW_TRANSPARENT
)
91 PointPriv
->showTransparent
= TRUE
;
93 PointPriv
->showTransparent
= FALSE
;
94 ScreenPriv
->spriteFuncs
= PointPriv
->spriteFuncs
;
95 PointPriv
->spriteFuncs
= &xf86CursorSpriteFuncs
;
97 ScreenPriv
->EnableDisableFBAccess
= pScrn
->EnableDisableFBAccess
;
98 ScreenPriv
->SwitchMode
= pScrn
->SwitchMode
;
100 ScreenPriv
->ForceHWCursorCount
= 0;
101 ScreenPriv
->HWCursorForced
= FALSE
;
103 pScrn
->EnableDisableFBAccess
= xf86CursorEnableDisableFBAccess
;
104 if (pScrn
->SwitchMode
)
105 pScrn
->SwitchMode
= xf86CursorSwitchMode
;
110 /***** Screen functions *****/
113 xf86CursorCloseScreen(int i
, ScreenPtr pScreen
)
115 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
116 miPointerScreenPtr PointPriv
=
117 pScreen
->devPrivates
[miPointerScreenIndex
].ptr
;
118 xf86CursorScreenPtr ScreenPriv
=
119 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
121 if (ScreenPriv
->isUp
&& pScrn
->vtSema
)
122 xf86SetCursor(pScreen
, NullCursor
, ScreenPriv
->x
, ScreenPriv
->y
);
124 pScreen
->CloseScreen
= ScreenPriv
->CloseScreen
;
125 pScreen
->QueryBestSize
= ScreenPriv
->QueryBestSize
;
126 pScreen
->RecolorCursor
= ScreenPriv
->RecolorCursor
;
127 if (ScreenPriv
->InstallColormap
)
128 pScreen
->InstallColormap
= ScreenPriv
->InstallColormap
;
130 PointPriv
->spriteFuncs
= ScreenPriv
->spriteFuncs
;
131 PointPriv
->showTransparent
= ScreenPriv
->showTransparent
;
133 pScrn
->EnableDisableFBAccess
= ScreenPriv
->EnableDisableFBAccess
;
134 pScrn
->SwitchMode
= ScreenPriv
->SwitchMode
;
136 xfree(ScreenPriv
->transparentData
);
139 return (*pScreen
->CloseScreen
)(i
, pScreen
);
143 xf86CursorQueryBestSize(
145 unsigned short *width
,
146 unsigned short *height
,
149 xf86CursorScreenPtr ScreenPriv
=
150 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
152 if (class == CursorShape
) {
153 if(*width
> ScreenPriv
->CursorInfoPtr
->MaxWidth
)
154 *width
= ScreenPriv
->CursorInfoPtr
->MaxWidth
;
155 if(*height
> ScreenPriv
->CursorInfoPtr
->MaxHeight
)
156 *height
= ScreenPriv
->CursorInfoPtr
->MaxHeight
;
158 (*ScreenPriv
->QueryBestSize
)(class, width
, height
, pScreen
);
162 xf86CursorInstallColormap(ColormapPtr pMap
)
164 xf86CursorScreenPtr ScreenPriv
=
165 pMap
->pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
167 ScreenPriv
->pInstalledMap
= pMap
;
169 (*ScreenPriv
->InstallColormap
)(pMap
);
173 xf86CursorRecolorCursor(
178 xf86CursorScreenPtr ScreenPriv
=
179 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
184 if (ScreenPriv
->SWCursor
)
185 (*ScreenPriv
->RecolorCursor
)(pScreen
, pCurs
, displayed
);
187 xf86RecolorCursor(pScreen
, pCurs
, displayed
);
190 /***** ScrnInfoRec functions *********/
193 xf86CursorEnableDisableFBAccess(
197 ScreenPtr pScreen
= screenInfo
.screens
[index
];
198 xf86CursorScreenPtr ScreenPriv
=
199 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
201 if (!enable
&& ScreenPriv
->CurrentCursor
!= NullCursor
) {
202 CursorPtr currentCursor
= ScreenPriv
->CurrentCursor
;
203 xf86CursorSetCursor(pScreen
, NullCursor
, ScreenPriv
->x
, ScreenPriv
->y
);
204 ScreenPriv
->isUp
= FALSE
;
205 ScreenPriv
->SWCursor
= TRUE
;
206 ScreenPriv
->SavedCursor
= currentCursor
;
209 if (ScreenPriv
->EnableDisableFBAccess
)
210 (*ScreenPriv
->EnableDisableFBAccess
)(index
, enable
);
212 if (enable
&& ScreenPriv
->SavedCursor
)
215 * Re-set current cursor so drivers can react to FB access having been
216 * temporarily disabled.
218 xf86CursorSetCursor(pScreen
, ScreenPriv
->SavedCursor
,
219 ScreenPriv
->x
, ScreenPriv
->y
);
220 ScreenPriv
->SavedCursor
= NULL
;
225 xf86CursorSwitchMode(int index
, DisplayModePtr mode
, int flags
)
228 ScreenPtr pScreen
= screenInfo
.screens
[index
];
229 xf86CursorScreenPtr ScreenPriv
=
230 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
231 miPointerScreenPtr PointPriv
=
232 pScreen
->devPrivates
[miPointerScreenIndex
].ptr
;
234 if (ScreenPriv
->isUp
) {
235 xf86SetCursor(pScreen
, NullCursor
, ScreenPriv
->x
, ScreenPriv
->y
);
236 ScreenPriv
->isUp
= FALSE
;
239 ret
= (*ScreenPriv
->SwitchMode
)(index
, mode
, flags
);
242 * Cannot restore cursor here because the new frame[XY][01] haven't been
243 * calculated yet. However, because the hardware cursor was removed above,
244 * ensure the cursor is repainted by miPointerWarpCursor().
246 ScreenPriv
->CursorToRestore
= ScreenPriv
->CurrentCursor
;
247 PointPriv
->waitForUpdate
= FALSE
; /* Force cursor repaint */
252 /****** miPointerSpriteFunctions *******/
255 xf86CursorRealizeCursor(ScreenPtr pScreen
, CursorPtr pCurs
)
257 xf86CursorScreenPtr ScreenPriv
=
258 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
260 if (pCurs
->refcnt
<= 1)
261 pCurs
->devPriv
[pScreen
->myNum
] = NULL
;
263 return (*ScreenPriv
->spriteFuncs
->RealizeCursor
)(pScreen
, pCurs
);
267 xf86CursorUnrealizeCursor(ScreenPtr pScreen
, CursorPtr pCurs
)
269 xf86CursorScreenPtr ScreenPriv
=
270 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
272 if (pCurs
->refcnt
<= 1) {
273 xfree(pCurs
->devPriv
[pScreen
->myNum
]);
274 pCurs
->devPriv
[pScreen
->myNum
] = NULL
;
277 return (*ScreenPriv
->spriteFuncs
->UnrealizeCursor
)(pScreen
, pCurs
);
281 xf86CursorSetCursor(ScreenPtr pScreen
, CursorPtr pCurs
, int x
, int y
)
283 xf86CursorScreenPtr ScreenPriv
=
284 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
285 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
286 miPointerScreenPtr PointPriv
;
288 ScreenPriv
->CurrentCursor
= pCurs
;
291 ScreenPriv
->CursorToRestore
= NULL
;
293 if (!infoPtr
->pScrn
->vtSema
)
294 ScreenPriv
->SavedCursor
= pCurs
;
296 if (pCurs
== NullCursor
) { /* means we're supposed to remove the cursor */
297 if (ScreenPriv
->SWCursor
)
298 (*ScreenPriv
->spriteFuncs
->SetCursor
)(pScreen
, NullCursor
, x
, y
);
299 else if (ScreenPriv
->isUp
) {
300 xf86SetCursor(pScreen
, NullCursor
, x
, y
);
301 ScreenPriv
->isUp
= FALSE
;
306 ScreenPriv
->HotX
= pCurs
->bits
->xhot
;
307 ScreenPriv
->HotY
= pCurs
->bits
->yhot
;
309 PointPriv
= pScreen
->devPrivates
[miPointerScreenIndex
].ptr
;
311 if (infoPtr
->pScrn
->vtSema
&& (ScreenPriv
->ForceHWCursorCount
|| ((
313 pCurs
->bits
->argb
&& infoPtr
->UseHWCursorARGB
&&
314 (*infoPtr
->UseHWCursorARGB
) (pScreen
, pCurs
) ) || (
315 pCurs
->bits
->argb
== 0 &&
317 (pCurs
->bits
->height
<= infoPtr
->MaxHeight
) &&
318 (pCurs
->bits
->width
<= infoPtr
->MaxWidth
) &&
319 (!infoPtr
->UseHWCursor
|| (*infoPtr
->UseHWCursor
)(pScreen
, pCurs
))))))
322 if (ScreenPriv
->SWCursor
) /* remove the SW cursor */
323 (*ScreenPriv
->spriteFuncs
->SetCursor
)(pScreen
, NullCursor
, x
, y
);
325 xf86SetCursor(pScreen
, pCurs
, x
, y
);
326 ScreenPriv
->SWCursor
= FALSE
;
327 ScreenPriv
->isUp
= TRUE
;
328 PointPriv
->waitForUpdate
= !infoPtr
->pScrn
->silkenMouse
;
332 PointPriv
->waitForUpdate
= TRUE
;
334 if (ScreenPriv
->isUp
) {
335 /* Remove the HW cursor, or make it transparent */
336 if (infoPtr
->Flags
& HARDWARE_CURSOR_SHOW_TRANSPARENT
) {
337 xf86SetTransparentCursor(pScreen
);
339 xf86SetCursor(pScreen
, NullCursor
, x
, y
);
340 ScreenPriv
->isUp
= FALSE
;
344 ScreenPriv
->SWCursor
= TRUE
;
346 if (pCurs
->bits
->emptyMask
&& !ScreenPriv
->showTransparent
)
348 (*ScreenPriv
->spriteFuncs
->SetCursor
)(pScreen
, pCurs
, x
, y
);
352 xf86CursorMoveCursor(ScreenPtr pScreen
, int x
, int y
)
354 xf86CursorScreenPtr ScreenPriv
=
355 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
360 if (ScreenPriv
->CursorToRestore
)
361 xf86CursorSetCursor(pScreen
, ScreenPriv
->CursorToRestore
,
362 ScreenPriv
->x
, ScreenPriv
->y
);
363 else if (ScreenPriv
->SWCursor
)
364 (*ScreenPriv
->spriteFuncs
->MoveCursor
)(pScreen
, x
, y
);
365 else if (ScreenPriv
->isUp
)
366 xf86MoveCursor(pScreen
, x
, y
);
370 xf86ForceHWCursor (ScreenPtr pScreen
, Bool on
)
372 xf86CursorScreenPtr ScreenPriv
=
373 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
377 if (ScreenPriv
->ForceHWCursorCount
++ == 0)
379 if (ScreenPriv
->SWCursor
&& ScreenPriv
->CurrentCursor
)
381 ScreenPriv
->HWCursorForced
= TRUE
;
382 xf86CursorSetCursor (pScreen
, ScreenPriv
->CurrentCursor
,
383 ScreenPriv
->x
, ScreenPriv
->y
);
386 ScreenPriv
->HWCursorForced
= FALSE
;
391 if (--ScreenPriv
->ForceHWCursorCount
== 0)
393 if (ScreenPriv
->HWCursorForced
&& ScreenPriv
->CurrentCursor
)
394 xf86CursorSetCursor (pScreen
, ScreenPriv
->CurrentCursor
,
395 ScreenPriv
->x
, ScreenPriv
->y
);
401 xf86CreateCursorInfoRec(void)
403 return xcalloc(1, sizeof(xf86CursorInfoRec
));
407 xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr
)