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