Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / modes / xf86Cursors.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright © 2007 Keith Packard
3 * Copyright © 2010-2011 Aaron Plattner
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24#ifdef HAVE_XORG_CONFIG_H
25#include <xorg-config.h>
26#else
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#endif
31
32#include <stddef.h>
33#include <string.h>
34#include <stdio.h>
35
36#include <X11/Xarch.h>
37#include "xf86.h"
38#include "xf86DDC.h"
39#include "xf86Crtc.h"
40#include "xf86Modes.h"
41#include "xf86RandR12.h"
42#include "xf86CursorPriv.h"
43#include "X11/extensions/render.h"
44#include "X11/extensions/dpmsconst.h"
45#include "X11/Xatom.h"
46#include "picturestr.h"
47#include "cursorstr.h"
48#include "inputstr.h"
49
50/*
51 * Returns the rotation being performed by the server. If the driver indicates
52 * that it's handling the screen transform, then this returns RR_Rotate_0.
53 */
54static Rotation
55xf86_crtc_cursor_rotation(xf86CrtcPtr crtc)
56{
57 if (crtc->driverIsPerformingTransform)
58 return RR_Rotate_0;
59 return crtc->rotation;
60}
61
62/*
63 * Given a screen coordinate, rotate back to a cursor source coordinate
64 */
65static void
66xf86_crtc_rotate_coord(Rotation rotation,
67 int width,
68 int height, int x_dst, int y_dst, int *x_src, int *y_src)
69{
70 int t;
71
72 switch (rotation & 0xf) {
73 case RR_Rotate_0:
74 break;
75 case RR_Rotate_90:
76 t = x_dst;
77 x_dst = height - y_dst - 1;
78 y_dst = t;
79 break;
80 case RR_Rotate_180:
81 x_dst = width - x_dst - 1;
82 y_dst = height - y_dst - 1;
83 break;
84 case RR_Rotate_270:
85 t = x_dst;
86 x_dst = y_dst;
87 y_dst = width - t - 1;
88 break;
89 }
90 if (rotation & RR_Reflect_X)
91 x_dst = width - x_dst - 1;
92 if (rotation & RR_Reflect_Y)
93 y_dst = height - y_dst - 1;
94 *x_src = x_dst;
95 *y_src = y_dst;
96}
97
98/*
99 * Given a cursor source coordinate, rotate to a screen coordinate
100 */
101static void
102xf86_crtc_rotate_coord_back(Rotation rotation,
103 int width,
104 int height,
105 int x_dst, int y_dst, int *x_src, int *y_src)
106{
107 int t;
108
109 if (rotation & RR_Reflect_X)
110 x_dst = width - x_dst - 1;
111 if (rotation & RR_Reflect_Y)
112 y_dst = height - y_dst - 1;
113
114 switch (rotation & 0xf) {
115 case RR_Rotate_0:
116 break;
117 case RR_Rotate_90:
118 t = x_dst;
119 x_dst = y_dst;
120 y_dst = width - t - 1;
121 break;
122 case RR_Rotate_180:
123 x_dst = width - x_dst - 1;
124 y_dst = height - y_dst - 1;
125 break;
126 case RR_Rotate_270:
127 t = x_dst;
128 x_dst = height - y_dst - 1;
129 y_dst = t;
130 break;
131 }
132 *x_src = x_dst;
133 *y_src = y_dst;
134}
135
136struct cursor_bit {
137 CARD8 *byte;
138 char bitpos;
139};
140
141/*
142 * Convert an x coordinate to a position within the cursor bitmap
143 */
144static struct cursor_bit
145cursor_bitpos(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y,
146 Bool mask)
147{
148 const int flags = cursor_info->Flags;
149 const Bool interleaved =
150 ! !(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
151 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 |
152 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
153 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
154 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
155 const int width = cursor_info->MaxWidth;
156 const int height = cursor_info->MaxHeight;
157 const int stride = interleaved ? width / 4 : width / 8;
158
159 struct cursor_bit ret;
160
161 image += y * stride;
162
163 if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
164 mask = !mask;
165 if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
166 x = (x & ~3) | (3 - (x & 3));
167 if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) ==
168 (X_BYTE_ORDER == X_BIG_ENDIAN))
169 x = (x & ~7) | (7 - (x & 7));
170 if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
171 x = (x << 1) + mask;
172 else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
173 x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
174 else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
175 x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
176 else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
177 x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
178 else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
179 x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
180 else if (mask)
181 image += stride * height;
182
183 ret.byte = image + (x / 8);
184 ret.bitpos = x & 7;
185
186 return ret;
187}
188
189/*
190 * Fetch one bit from a cursor bitmap
191 */
192static CARD8
193get_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
194{
195 struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
196
197 return (*bit.byte >> bit.bitpos) & 1;
198}
199
200/*
201 * Set one bit in a cursor bitmap
202 */
203static void
204set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
205{
206 struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
207
208 *bit.byte |= 1 << bit.bitpos;
209}
210
211/*
212 * Load a two color cursor into a driver that supports only ARGB cursors
213 */
214static void
215xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src)
216{
217 ScrnInfoPtr scrn = crtc->scrn;
218 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
219 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
220 CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
221 int x, y;
222 int xin, yin;
223 int flags = cursor_info->Flags;
224 CARD32 bits;
225 const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
226
227#ifdef ARGB_CURSOR
228 crtc->cursor_argb = FALSE;
229#endif
230
231 for (y = 0; y < cursor_info->MaxHeight; y++)
232 for (x = 0; x < cursor_info->MaxWidth; x++) {
233 xf86_crtc_rotate_coord(rotation,
234 cursor_info->MaxWidth,
235 cursor_info->MaxHeight, x, y, &xin, &yin);
236 if (get_bit(src, cursor_info, xin, yin, TRUE) ==
237 ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0)) {
238 if (get_bit(src, cursor_info, xin, yin, FALSE))
239 bits = xf86_config->cursor_fg;
240 else
241 bits = xf86_config->cursor_bg;
242 }
243 else
244 bits = 0;
245 cursor_image[y * cursor_info->MaxWidth + x] = bits;
246 }
247 crtc->funcs->load_cursor_argb(crtc, cursor_image);
248}
249
250/*
251 * Set the colors for a two-color cursor (ignore for ARGB cursors)
252 */
253static void
254xf86_set_cursor_colors(ScrnInfoPtr scrn, int bg, int fg)
255{
256 ScreenPtr screen = scrn->pScreen;
257 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
258 CursorPtr cursor = xf86_config->cursor;
259 int c;
260 CARD8 *bits = cursor ?
261 dixLookupScreenPrivate(&cursor->devPrivates, CursorScreenKey, screen)
262 : NULL;
263
264 /* Save ARGB versions of these colors */
265 xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
266 xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
267
268 for (c = 0; c < xf86_config->num_crtc; c++) {
269 xf86CrtcPtr crtc = xf86_config->crtc[c];
270
271 if (crtc->enabled && !crtc->cursor_argb) {
272 if (crtc->funcs->load_cursor_image)
273 crtc->funcs->set_cursor_colors(crtc, bg, fg);
274 else if (bits)
275 xf86_crtc_convert_cursor_to_argb(crtc, bits);
276 }
277 }
278}
279
280static void
281xf86_crtc_hide_cursor(xf86CrtcPtr crtc)
282{
283 if (crtc->cursor_shown) {
284 crtc->funcs->hide_cursor(crtc);
285 crtc->cursor_shown = FALSE;
286 }
287}
288
289void
290xf86_hide_cursors(ScrnInfoPtr scrn)
291{
292 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
293 int c;
294
295 xf86_config->cursor_on = FALSE;
296 for (c = 0; c < xf86_config->num_crtc; c++) {
297 xf86CrtcPtr crtc = xf86_config->crtc[c];
298
299 if (crtc->enabled)
300 xf86_crtc_hide_cursor(crtc);
301 }
302}
303
304static void
305xf86_crtc_show_cursor(xf86CrtcPtr crtc)
306{
307 if (!crtc->cursor_shown && crtc->cursor_in_range) {
308 crtc->funcs->show_cursor(crtc);
309 crtc->cursor_shown = TRUE;
310 }
311}
312
313void
314xf86_show_cursors(ScrnInfoPtr scrn)
315{
316 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
317 int c;
318
319 xf86_config->cursor_on = TRUE;
320 for (c = 0; c < xf86_config->num_crtc; c++) {
321 xf86CrtcPtr crtc = xf86_config->crtc[c];
322
323 if (crtc->enabled)
324 xf86_crtc_show_cursor(crtc);
325 }
326}
327
328void
329xf86CrtcTransformCursorPos(xf86CrtcPtr crtc, int *x, int *y)
330{
331 ScrnInfoPtr scrn = crtc->scrn;
332 ScreenPtr screen = scrn->pScreen;
333 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
334 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
335 xf86CursorScreenPtr ScreenPriv =
336 (xf86CursorScreenPtr) dixLookupPrivate(&screen->devPrivates,
337 xf86CursorScreenKey);
338 struct pict_f_vector v;
339 int dx, dy;
340
341 v.v[0] = (*x + ScreenPriv->HotX) + 0.5;
342 v.v[1] = (*y + ScreenPriv->HotY) + 0.5;
343 v.v[2] = 1;
344 pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v);
345 /* cursor will have 0.5 added to it already so floor is sufficent */
346 *x = floor(v.v[0]);
347 *y = floor(v.v[1]);
348 /*
349 * Transform position of cursor upper left corner
350 */
351 xf86_crtc_rotate_coord_back(crtc->rotation, cursor_info->MaxWidth,
352 cursor_info->MaxHeight, ScreenPriv->HotX,
353 ScreenPriv->HotY, &dx, &dy);
354 *x -= dx;
355 *y -= dy;
356}
357
358static void
359xf86_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
360{
361 ScrnInfoPtr scrn = crtc->scrn;
362 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
363 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
364 DisplayModePtr mode = &crtc->mode;
365 Bool in_range;
366
367 /*
368 * Transform position of cursor on screen
369 */
370 if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
371 xf86CrtcTransformCursorPos(crtc, &x, &y);
372 else {
373 x -= crtc->x;
374 y -= crtc->y;
375 }
376
377 /*
378 * Disable the cursor when it is outside the viewport
379 */
380 in_range = TRUE;
381 if (x >= mode->HDisplay || y >= mode->VDisplay ||
382 x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) {
383 in_range = FALSE;
384 x = 0;
385 y = 0;
386 }
387
388 crtc->cursor_in_range = in_range;
389
390 if (in_range) {
391 crtc->funcs->set_cursor_position(crtc, x, y);
392 xf86_crtc_show_cursor(crtc);
393 }
394 else
395 xf86_crtc_hide_cursor(crtc);
396}
397
398static void
399xf86_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
400{
401 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
402 int c;
403
404 /* undo what xf86HWCurs did to the coordinates */
405 x += scrn->frameX0;
406 y += scrn->frameY0;
407 for (c = 0; c < xf86_config->num_crtc; c++) {
408 xf86CrtcPtr crtc = xf86_config->crtc[c];
409
410 if (crtc->enabled)
411 xf86_crtc_set_cursor_position(crtc, x, y);
412 }
413}
414
415/*
416 * Load a two-color cursor into a crtc, performing rotation as needed
417 */
418static void
419xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src)
420{
421 ScrnInfoPtr scrn = crtc->scrn;
422 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
423 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
424 CARD8 *cursor_image;
425 const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
426
427#ifdef ARGB_CURSOR
428 crtc->cursor_argb = FALSE;
429#endif
430
431 if (rotation == RR_Rotate_0)
432 cursor_image = src;
433 else {
434 int x, y;
435 int xin, yin;
436 int stride = cursor_info->MaxWidth >> 2;
437
438 cursor_image = xf86_config->cursor_image;
439 memset(cursor_image, 0, cursor_info->MaxHeight * stride);
440
441 for (y = 0; y < cursor_info->MaxHeight; y++)
442 for (x = 0; x < cursor_info->MaxWidth; x++) {
443 xf86_crtc_rotate_coord(rotation,
444 cursor_info->MaxWidth,
445 cursor_info->MaxHeight,
446 x, y, &xin, &yin);
447 if (get_bit(src, cursor_info, xin, yin, FALSE))
448 set_bit(cursor_image, cursor_info, x, y, FALSE);
449 if (get_bit(src, cursor_info, xin, yin, TRUE))
450 set_bit(cursor_image, cursor_info, x, y, TRUE);
451 }
452 }
453 crtc->funcs->load_cursor_image(crtc, cursor_image);
454}
455
456/*
457 * Load a cursor image into all active CRTCs
458 */
459static void
460xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
461{
462 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
463 int c;
464
465 for (c = 0; c < xf86_config->num_crtc; c++) {
466 xf86CrtcPtr crtc = xf86_config->crtc[c];
467
468 if (crtc->enabled) {
469 if (crtc->funcs->load_cursor_image)
470 xf86_crtc_load_cursor_image(crtc, src);
471 else if (crtc->funcs->load_cursor_argb)
472 xf86_crtc_convert_cursor_to_argb(crtc, src);
473 }
474 }
475}
476
477static Bool
478xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
479{
480 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
481 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
482 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
483
484 cursor = RefCursor(cursor);
485 if (xf86_config->cursor)
486 FreeCursor(xf86_config->cursor, None);
487 xf86_config->cursor = cursor;
488
489 if (cursor->bits->width > cursor_info->MaxWidth ||
490 cursor->bits->height > cursor_info->MaxHeight)
491 return FALSE;
492
493 return TRUE;
494}
495
496static Bool
497xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
498{
499 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
500 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
501 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
502
503 cursor = RefCursor(cursor);
504 if (xf86_config->cursor)
505 FreeCursor(xf86_config->cursor, None);
506 xf86_config->cursor = cursor;
507
508 /* Make sure ARGB support is available */
509 if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
510 return FALSE;
511
512 if (cursor->bits->width > cursor_info->MaxWidth ||
513 cursor->bits->height > cursor_info->MaxHeight)
514 return FALSE;
515
516 return TRUE;
517}
518
519static void
520xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor)
521{
522 ScrnInfoPtr scrn = crtc->scrn;
523 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
524 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
525 CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
526 CARD32 *cursor_source = (CARD32 *) cursor->bits->argb;
527 int x, y;
528 int xin, yin;
529 CARD32 bits;
530 int source_width = cursor->bits->width;
531 int source_height = cursor->bits->height;
532 int image_width = cursor_info->MaxWidth;
533 int image_height = cursor_info->MaxHeight;
534 const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
535
536 for (y = 0; y < image_height; y++)
537 for (x = 0; x < image_width; x++) {
538 xf86_crtc_rotate_coord(rotation, image_width, image_height, x, y,
539 &xin, &yin);
540 if (xin < source_width && yin < source_height)
541 bits = cursor_source[yin * source_width + xin];
542 else
543 bits = 0;
544 cursor_image[y * image_width + x] = bits;
545 }
546
547 crtc->funcs->load_cursor_argb(crtc, cursor_image);
548}
549
550static void
551xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
552{
553 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
554 int c;
555
556 for (c = 0; c < xf86_config->num_crtc; c++) {
557 xf86CrtcPtr crtc = xf86_config->crtc[c];
558
559 if (crtc->enabled)
560 xf86_crtc_load_cursor_argb(crtc, cursor);
561 }
562}
563
564Bool
565xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags)
566{
567 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
568 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
569 xf86CursorInfoPtr cursor_info;
570
571 cursor_info = xf86CreateCursorInfoRec();
572 if (!cursor_info)
573 return FALSE;
574
575 xf86_config->cursor_image = malloc(max_width * max_height * 4);
576
577 if (!xf86_config->cursor_image) {
578 xf86DestroyCursorInfoRec(cursor_info);
579 return FALSE;
580 }
581
582 xf86_config->cursor_info = cursor_info;
583
584 cursor_info->MaxWidth = max_width;
585 cursor_info->MaxHeight = max_height;
586 cursor_info->Flags = flags;
587
588 cursor_info->SetCursorColors = xf86_set_cursor_colors;
589 cursor_info->SetCursorPosition = xf86_set_cursor_position;
590 cursor_info->LoadCursorImage = xf86_load_cursor_image;
591 cursor_info->HideCursor = xf86_hide_cursors;
592 cursor_info->ShowCursor = xf86_show_cursors;
593 cursor_info->UseHWCursor = xf86_use_hw_cursor;
594#ifdef ARGB_CURSOR
595 if (flags & HARDWARE_CURSOR_ARGB) {
596 cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
597 cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
598 }
599#endif
600
601 xf86_config->cursor = NULL;
602 xf86_hide_cursors(scrn);
603
604 return xf86InitCursor(screen, cursor_info);
605}
606
607/**
608 * Called when anything on the screen is reconfigured.
609 *
610 * Reloads cursor images as needed, then adjusts cursor positions
611 */
612
613void
614xf86_reload_cursors(ScreenPtr screen)
615{
616 ScrnInfoPtr scrn;
617 xf86CrtcConfigPtr xf86_config;
618 xf86CursorInfoPtr cursor_info;
619 CursorPtr cursor;
620 int x, y;
621 xf86CursorScreenPtr cursor_screen_priv;
622
623 /* initial mode setting will not have set a screen yet.
624 May be called before the devices are initialised.
625 */
626 if (!screen || !inputInfo.pointer)
627 return;
628 cursor_screen_priv = dixLookupPrivate(&screen->devPrivates,
629 xf86CursorScreenKey);
630 /* return if HW cursor is inactive, to avoid displaying two cursors */
631 if (!cursor_screen_priv || !cursor_screen_priv->isUp)
632 return;
633
634 scrn = xf86ScreenToScrn(screen);
635 xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
636
637 /* make sure the cursor code has been initialized */
638 cursor_info = xf86_config->cursor_info;
639 if (!cursor_info)
640 return;
641
642 cursor = xf86_config->cursor;
643 GetSpritePosition(inputInfo.pointer, &x, &y);
644 if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
645 (*cursor_info->HideCursor) (scrn);
646
647 if (cursor) {
648 void *src =
649 dixLookupScreenPrivate(&cursor->devPrivates, CursorScreenKey,
650 screen);
651#ifdef ARGB_CURSOR
652 if (cursor->bits->argb && cursor_info->LoadCursorARGB)
653 (*cursor_info->LoadCursorARGB) (scrn, cursor);
654 else if (src)
655#endif
656 (*cursor_info->LoadCursorImage) (scrn, src);
657
658 x += scrn->frameX0 + cursor_screen_priv->HotX;
659 y += scrn->frameY0 + cursor_screen_priv->HotY;
660 (*cursor_info->SetCursorPosition) (scrn, x, y);
661 }
662}
663
664/**
665 * Clean up CRTC-based cursor code
666 */
667void
668xf86_cursors_fini(ScreenPtr screen)
669{
670 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
671 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
672
673 if (xf86_config->cursor_info) {
674 xf86DestroyCursorInfoRec(xf86_config->cursor_info);
675 xf86_config->cursor_info = NULL;
676 }
677 free(xf86_config->cursor_image);
678 xf86_config->cursor_image = NULL;
679 if (xf86_config->cursor) {
680 FreeCursor(xf86_config->cursor, None);
681 xf86_config->cursor = NULL;
682 }
683}