First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / ramdac / xf86Cursor.c
blob4578076986c867555935167f6af80aa1fe4941d2
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include "xf86.h"
7 #include "xf86CursorPriv.h"
8 #include "colormapst.h"
9 #include "cursorstr.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,
24 xf86CursorSetCursor,
25 xf86CursorMoveCursor
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*,
34 ScreenPtr);
36 /* ScrnInfoRec functions */
38 static void xf86CursorEnableDisableFBAccess(int, Bool);
39 static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
41 Bool
42 xf86InitCursor(
43 ScreenPtr pScreen,
44 xf86CursorInfoPtr infoPtr
47 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
48 xf86CursorScreenPtr ScreenPriv;
49 miPointerScreenPtr PointPriv;
51 if (xf86CursorGeneration != serverGeneration) {
52 if ((xf86CursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
53 return FALSE;
54 xf86CursorGeneration = serverGeneration;
57 if (!xf86InitHardwareCursor(pScreen, infoPtr))
58 return FALSE;
60 ScreenPriv = xcalloc(1, sizeof(xf86CursorScreenRec));
61 if (!ScreenPriv)
62 return FALSE;
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;
92 else
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;
107 return TRUE;
110 /***** Screen functions *****/
112 static Bool
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);
137 xfree(ScreenPriv);
139 return (*pScreen->CloseScreen)(i, pScreen);
142 static void
143 xf86CursorQueryBestSize(
144 int class,
145 unsigned short *width,
146 unsigned short *height,
147 ScreenPtr pScreen)
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;
157 } else
158 (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
161 static void
162 xf86CursorInstallColormap(ColormapPtr pMap)
164 xf86CursorScreenPtr ScreenPriv =
165 pMap->pScreen->devPrivates[xf86CursorScreenIndex].ptr;
167 ScreenPriv->pInstalledMap = pMap;
169 (*ScreenPriv->InstallColormap)(pMap);
172 static void
173 xf86CursorRecolorCursor(
174 ScreenPtr pScreen,
175 CursorPtr pCurs,
176 Bool displayed)
178 xf86CursorScreenPtr ScreenPriv =
179 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
181 if (!displayed)
182 return;
184 if (ScreenPriv->SWCursor)
185 (*ScreenPriv->RecolorCursor)(pScreen, pCurs, displayed);
186 else
187 xf86RecolorCursor(pScreen, pCurs, displayed);
190 /***** ScrnInfoRec functions *********/
192 static void
193 xf86CursorEnableDisableFBAccess(
194 int index,
195 Bool enable)
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;
224 static Bool
225 xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
227 Bool ret;
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 */
249 return ret;
252 /****** miPointerSpriteFunctions *******/
254 static Bool
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);
266 static Bool
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);
280 static void
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;
289 ScreenPriv->x = x;
290 ScreenPriv->y = y;
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;
303 return;
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 || ((
312 #ifdef ARGB_CURSOR
313 pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
314 (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
315 pCurs->bits->argb == 0 &&
316 #endif
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;
329 return;
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);
338 } else {
339 xf86SetCursor(pScreen, NullCursor, x, y);
340 ScreenPriv->isUp = FALSE;
344 ScreenPriv->SWCursor = TRUE;
346 if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
347 pCurs = NullCursor;
348 (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y);
351 static void
352 xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y)
354 xf86CursorScreenPtr ScreenPriv =
355 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
357 ScreenPriv->x = x;
358 ScreenPriv->y = y;
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);
369 void
370 xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
372 xf86CursorScreenPtr ScreenPriv =
373 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
375 if (on)
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);
385 else
386 ScreenPriv->HWCursorForced = FALSE;
389 else
391 if (--ScreenPriv->ForceHWCursorCount == 0)
393 if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
394 xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor,
395 ScreenPriv->x, ScreenPriv->y);
400 xf86CursorInfoPtr
401 xf86CreateCursorInfoRec(void)
403 return xcalloc(1, sizeof(xf86CursorInfoRec));
406 void
407 xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
409 xfree(infoPtr);