xf86Cursors.c revision f7df2e56
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 * Wrappers to deal with API compatibility with drivers that don't expose 213 * load_cursor_*_check 214 */ 215static inline Bool 216xf86_driver_has_load_cursor_image(xf86CrtcPtr crtc) 217{ 218 return crtc->funcs->load_cursor_image_check || crtc->funcs->load_cursor_image; 219} 220 221static inline Bool 222xf86_driver_has_load_cursor_argb(xf86CrtcPtr crtc) 223{ 224 return crtc->funcs->load_cursor_argb_check || crtc->funcs->load_cursor_argb; 225} 226 227static inline Bool 228xf86_driver_load_cursor_image(xf86CrtcPtr crtc, CARD8 *cursor_image) 229{ 230 if (crtc->funcs->load_cursor_image_check) 231 return crtc->funcs->load_cursor_image_check(crtc, cursor_image); 232 crtc->funcs->load_cursor_image(crtc, cursor_image); 233 return TRUE; 234} 235 236static inline Bool 237xf86_driver_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *cursor_argb) 238{ 239 if (crtc->funcs->load_cursor_argb_check) 240 return crtc->funcs->load_cursor_argb_check(crtc, cursor_argb); 241 crtc->funcs->load_cursor_argb(crtc, cursor_argb); 242 return TRUE; 243} 244 245/* 246 * Load a two color cursor into a driver that supports only ARGB cursors 247 */ 248static Bool 249xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src) 250{ 251 ScrnInfoPtr scrn = crtc->scrn; 252 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 253 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 254 CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; 255 int x, y; 256 int xin, yin; 257 int flags = cursor_info->Flags; 258 CARD32 bits; 259 const Rotation rotation = xf86_crtc_cursor_rotation(crtc); 260 261 crtc->cursor_argb = FALSE; 262 263 for (y = 0; y < cursor_info->MaxHeight; y++) 264 for (x = 0; x < cursor_info->MaxWidth; x++) { 265 xf86_crtc_rotate_coord(rotation, 266 cursor_info->MaxWidth, 267 cursor_info->MaxHeight, x, y, &xin, &yin); 268 if (get_bit(src, cursor_info, xin, yin, TRUE) == 269 ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0)) { 270 if (get_bit(src, cursor_info, xin, yin, FALSE)) 271 bits = xf86_config->cursor_fg; 272 else 273 bits = xf86_config->cursor_bg; 274 } 275 else 276 bits = 0; 277 cursor_image[y * cursor_info->MaxWidth + x] = bits; 278 } 279 return xf86_driver_load_cursor_argb(crtc, cursor_image); 280} 281 282/* 283 * Set the colors for a two-color cursor (ignore for ARGB cursors) 284 */ 285static void 286xf86_set_cursor_colors(ScrnInfoPtr scrn, int bg, int fg) 287{ 288 ScreenPtr screen = scrn->pScreen; 289 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 290 CursorPtr cursor = xf86_config->cursor; 291 int c; 292 CARD8 *bits = cursor ? 293 dixLookupScreenPrivate(&cursor->devPrivates, CursorScreenKey, screen) 294 : NULL; 295 296 /* Save ARGB versions of these colors */ 297 xf86_config->cursor_fg = (CARD32) fg | 0xff000000; 298 xf86_config->cursor_bg = (CARD32) bg | 0xff000000; 299 300 for (c = 0; c < xf86_config->num_crtc; c++) { 301 xf86CrtcPtr crtc = xf86_config->crtc[c]; 302 303 if (crtc->enabled && !crtc->cursor_argb) { 304 if (xf86_driver_has_load_cursor_image(crtc)) 305 crtc->funcs->set_cursor_colors(crtc, bg, fg); 306 else if (bits) 307 xf86_crtc_convert_cursor_to_argb(crtc, bits); 308 } 309 } 310} 311 312static void 313xf86_crtc_hide_cursor(xf86CrtcPtr crtc) 314{ 315 if (crtc->cursor_shown) { 316 crtc->funcs->hide_cursor(crtc); 317 crtc->cursor_shown = FALSE; 318 } 319} 320 321void 322xf86_hide_cursors(ScrnInfoPtr scrn) 323{ 324 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 325 int c; 326 327 xf86_config->cursor_on = FALSE; 328 for (c = 0; c < xf86_config->num_crtc; c++) { 329 xf86CrtcPtr crtc = xf86_config->crtc[c]; 330 331 if (crtc->enabled) 332 xf86_crtc_hide_cursor(crtc); 333 } 334} 335 336static void 337xf86_crtc_show_cursor(xf86CrtcPtr crtc) 338{ 339 if (!crtc->cursor_shown && crtc->cursor_in_range) { 340 crtc->funcs->show_cursor(crtc); 341 crtc->cursor_shown = TRUE; 342 } 343} 344 345void 346xf86_show_cursors(ScrnInfoPtr scrn) 347{ 348 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 349 int c; 350 351 xf86_config->cursor_on = TRUE; 352 for (c = 0; c < xf86_config->num_crtc; c++) { 353 xf86CrtcPtr crtc = xf86_config->crtc[c]; 354 355 if (crtc->enabled) 356 xf86_crtc_show_cursor(crtc); 357 } 358} 359 360void 361xf86CrtcTransformCursorPos(xf86CrtcPtr crtc, int *x, int *y) 362{ 363 ScrnInfoPtr scrn = crtc->scrn; 364 ScreenPtr screen = scrn->pScreen; 365 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 366 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 367 xf86CursorScreenPtr ScreenPriv = 368 (xf86CursorScreenPtr) dixLookupPrivate(&screen->devPrivates, 369 xf86CursorScreenKey); 370 struct pict_f_vector v; 371 int dx, dy; 372 373 v.v[0] = (*x + ScreenPriv->HotX) + 0.5; 374 v.v[1] = (*y + ScreenPriv->HotY) + 0.5; 375 v.v[2] = 1; 376 pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v); 377 /* cursor will have 0.5 added to it already so floor is sufficent */ 378 *x = floor(v.v[0]); 379 *y = floor(v.v[1]); 380 /* 381 * Transform position of cursor upper left corner 382 */ 383 xf86_crtc_rotate_coord_back(crtc->rotation, cursor_info->MaxWidth, 384 cursor_info->MaxHeight, ScreenPriv->HotX, 385 ScreenPriv->HotY, &dx, &dy); 386 *x -= dx; 387 *y -= dy; 388} 389 390static void 391xf86_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 392{ 393 ScrnInfoPtr scrn = crtc->scrn; 394 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 395 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 396 DisplayModePtr mode = &crtc->mode; 397 Bool in_range; 398 399 /* 400 * Transform position of cursor on screen 401 */ 402 if (crtc->transform_in_use && !crtc->driverIsPerformingTransform) 403 xf86CrtcTransformCursorPos(crtc, &x, &y); 404 else { 405 x -= crtc->x; 406 y -= crtc->y; 407 } 408 409 /* 410 * Disable the cursor when it is outside the viewport 411 */ 412 in_range = TRUE; 413 if (x >= mode->HDisplay || y >= mode->VDisplay || 414 x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) { 415 in_range = FALSE; 416 x = 0; 417 y = 0; 418 } 419 420 crtc->cursor_in_range = in_range; 421 422 if (in_range) { 423 crtc->funcs->set_cursor_position(crtc, x, y); 424 xf86_crtc_show_cursor(crtc); 425 } 426 else 427 xf86_crtc_hide_cursor(crtc); 428} 429 430static void 431xf86_set_cursor_position(ScrnInfoPtr scrn, int x, int y) 432{ 433 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 434 int c; 435 436 /* undo what xf86HWCurs did to the coordinates */ 437 x += scrn->frameX0; 438 y += scrn->frameY0; 439 for (c = 0; c < xf86_config->num_crtc; c++) { 440 xf86CrtcPtr crtc = xf86_config->crtc[c]; 441 442 if (crtc->enabled) 443 xf86_crtc_set_cursor_position(crtc, x, y); 444 } 445} 446 447/* 448 * Load a two-color cursor into a crtc, performing rotation as needed 449 */ 450static Bool 451xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src) 452{ 453 ScrnInfoPtr scrn = crtc->scrn; 454 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 455 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 456 CARD8 *cursor_image; 457 const Rotation rotation = xf86_crtc_cursor_rotation(crtc); 458 459 crtc->cursor_argb = FALSE; 460 461 if (rotation == RR_Rotate_0) 462 cursor_image = src; 463 else { 464 int x, y; 465 int xin, yin; 466 int stride = cursor_info->MaxWidth >> 2; 467 468 cursor_image = xf86_config->cursor_image; 469 memset(cursor_image, 0, cursor_info->MaxHeight * stride); 470 471 for (y = 0; y < cursor_info->MaxHeight; y++) 472 for (x = 0; x < cursor_info->MaxWidth; x++) { 473 xf86_crtc_rotate_coord(rotation, 474 cursor_info->MaxWidth, 475 cursor_info->MaxHeight, 476 x, y, &xin, &yin); 477 if (get_bit(src, cursor_info, xin, yin, FALSE)) 478 set_bit(cursor_image, cursor_info, x, y, FALSE); 479 if (get_bit(src, cursor_info, xin, yin, TRUE)) 480 set_bit(cursor_image, cursor_info, x, y, TRUE); 481 } 482 } 483 return xf86_driver_load_cursor_image(crtc, cursor_image); 484} 485 486/* 487 * Load a cursor image into all active CRTCs 488 */ 489static Bool 490xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src) 491{ 492 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 493 int c; 494 495 for (c = 0; c < xf86_config->num_crtc; c++) { 496 xf86CrtcPtr crtc = xf86_config->crtc[c]; 497 498 if (crtc->enabled) { 499 if (xf86_driver_has_load_cursor_image(crtc)) { 500 if (!xf86_crtc_load_cursor_image(crtc, src)) 501 return FALSE; 502 } else if (xf86_driver_has_load_cursor_argb(crtc)) { 503 if (!xf86_crtc_convert_cursor_to_argb(crtc, src)) 504 return FALSE; 505 } else 506 return FALSE; 507 } 508 } 509 return TRUE; 510} 511 512static Bool 513xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor) 514{ 515 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 516 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 517 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 518 int c; 519 520 cursor = RefCursor(cursor); 521 if (xf86_config->cursor) 522 FreeCursor(xf86_config->cursor, None); 523 xf86_config->cursor = cursor; 524 525 if (cursor->bits->width > cursor_info->MaxWidth || 526 cursor->bits->height > cursor_info->MaxHeight) 527 return FALSE; 528 529 for (c = 0; c < xf86_config->num_crtc; c++) { 530 xf86CrtcPtr crtc = xf86_config->crtc[c]; 531 532 if (!crtc->enabled) 533 continue; 534 535 if (crtc->transformPresent) 536 return FALSE; 537 } 538 539 return TRUE; 540} 541 542static Bool 543xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor) 544{ 545 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 546 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 547 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 548 549 if (!xf86_use_hw_cursor(screen, cursor)) 550 return FALSE; 551 552 /* Make sure ARGB support is available */ 553 if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0) 554 return FALSE; 555 556 return TRUE; 557} 558 559static Bool 560xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor) 561{ 562 ScrnInfoPtr scrn = crtc->scrn; 563 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 564 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 565 CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image; 566 CARD32 *cursor_source = (CARD32 *) cursor->bits->argb; 567 int x, y; 568 int xin, yin; 569 CARD32 bits; 570 int source_width = cursor->bits->width; 571 int source_height = cursor->bits->height; 572 int image_width = cursor_info->MaxWidth; 573 int image_height = cursor_info->MaxHeight; 574 const Rotation rotation = xf86_crtc_cursor_rotation(crtc); 575 576 for (y = 0; y < image_height; y++) 577 for (x = 0; x < image_width; x++) { 578 xf86_crtc_rotate_coord(rotation, image_width, image_height, x, y, 579 &xin, &yin); 580 if (xin < source_width && yin < source_height) 581 bits = cursor_source[yin * source_width + xin]; 582 else 583 bits = 0; 584 cursor_image[y * image_width + x] = bits; 585 } 586 587 return xf86_driver_load_cursor_argb(crtc, cursor_image); 588} 589 590static Bool 591xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor) 592{ 593 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 594 int c; 595 596 for (c = 0; c < xf86_config->num_crtc; c++) { 597 xf86CrtcPtr crtc = xf86_config->crtc[c]; 598 599 if (crtc->enabled) 600 if (!xf86_crtc_load_cursor_argb(crtc, cursor)) 601 return FALSE; 602 } 603 return TRUE; 604} 605 606Bool 607xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags) 608{ 609 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 610 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 611 xf86CursorInfoPtr cursor_info; 612 613 cursor_info = xf86CreateCursorInfoRec(); 614 if (!cursor_info) 615 return FALSE; 616 617 xf86_config->cursor_image = malloc(max_width * max_height * 4); 618 619 if (!xf86_config->cursor_image) { 620 xf86DestroyCursorInfoRec(cursor_info); 621 return FALSE; 622 } 623 624 xf86_config->cursor_info = cursor_info; 625 626 cursor_info->MaxWidth = max_width; 627 cursor_info->MaxHeight = max_height; 628 cursor_info->Flags = flags; 629 630 cursor_info->SetCursorColors = xf86_set_cursor_colors; 631 cursor_info->SetCursorPosition = xf86_set_cursor_position; 632 cursor_info->LoadCursorImageCheck = xf86_load_cursor_image; 633 cursor_info->HideCursor = xf86_hide_cursors; 634 cursor_info->ShowCursor = xf86_show_cursors; 635 cursor_info->UseHWCursor = xf86_use_hw_cursor; 636 if (flags & HARDWARE_CURSOR_ARGB) { 637 cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb; 638 cursor_info->LoadCursorARGBCheck = xf86_load_cursor_argb; 639 } 640 641 xf86_config->cursor = NULL; 642 xf86_hide_cursors(scrn); 643 644 return xf86InitCursor(screen, cursor_info); 645} 646 647/** 648 * Called when anything on the screen is reconfigured. 649 * 650 * Reloads cursor images as needed, then adjusts cursor positions 651 * @note We assume that all hardware cursors to be loaded have already been 652 * found to be usable by the hardware. 653 */ 654 655void 656xf86_reload_cursors(ScreenPtr screen) 657{ 658 ScrnInfoPtr scrn; 659 xf86CrtcConfigPtr xf86_config; 660 xf86CursorInfoPtr cursor_info; 661 CursorPtr cursor; 662 int x, y; 663 xf86CursorScreenPtr cursor_screen_priv; 664 665 /* initial mode setting will not have set a screen yet. 666 May be called before the devices are initialised. 667 */ 668 if (!screen || !inputInfo.pointer) 669 return; 670 cursor_screen_priv = dixLookupPrivate(&screen->devPrivates, 671 xf86CursorScreenKey); 672 /* return if HW cursor is inactive, to avoid displaying two cursors */ 673 if (!cursor_screen_priv || !cursor_screen_priv->isUp) 674 return; 675 676 scrn = xf86ScreenToScrn(screen); 677 xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 678 679 /* make sure the cursor code has been initialized */ 680 cursor_info = xf86_config->cursor_info; 681 if (!cursor_info) 682 return; 683 684 cursor = xf86_config->cursor; 685 GetSpritePosition(inputInfo.pointer, &x, &y); 686 if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) 687 (*cursor_info->HideCursor) (scrn); 688 689 if (cursor) { 690 void *src = 691 dixLookupScreenPrivate(&cursor->devPrivates, CursorScreenKey, 692 screen); 693 if (cursor->bits->argb && xf86DriverHasLoadCursorARGB(cursor_info)) 694 xf86DriverLoadCursorARGB(cursor_info, cursor); 695 else if (src) 696 xf86DriverLoadCursorImage(cursor_info, src); 697 698 x += scrn->frameX0 + cursor_screen_priv->HotX; 699 y += scrn->frameY0 + cursor_screen_priv->HotY; 700 (*cursor_info->SetCursorPosition) (scrn, x, y); 701 } 702} 703 704/** 705 * Clean up CRTC-based cursor code 706 */ 707void 708xf86_cursors_fini(ScreenPtr screen) 709{ 710 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 711 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 712 713 if (xf86_config->cursor_info) { 714 xf86DestroyCursorInfoRec(xf86_config->cursor_info); 715 xf86_config->cursor_info = NULL; 716 } 717 free(xf86_config->cursor_image); 718 xf86_config->cursor_image = NULL; 719 if (xf86_config->cursor) { 720 FreeCursor(xf86_config->cursor, None); 721 xf86_config->cursor = NULL; 722 } 723} 724