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