xf86HWCurs.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. #ifdef HAVE_XORG_CONFIG_H
  2. #include <xorg-config.h>
  3. #endif
  4. #include <string.h>
  5. #include "misc.h"
  6. #include "xf86.h"
  7. #include "xf86_OSproc.h"
  8. #include <X11/X.h>
  9. #include "scrnintstr.h"
  10. #include "pixmapstr.h"
  11. #include "windowstr.h"
  12. #include "xf86str.h"
  13. #include "cursorstr.h"
  14. #include "mi.h"
  15. #include "mipointer.h"
  16. #include "xf86CursorPriv.h"
  17. #include "servermd.h"
  18. static CARD32
  19. xf86ReverseBitOrder(CARD32 v)
  20. {
  21. return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) |
  22. ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) |
  23. ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) |
  24. ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
  25. }
  26. #if BITMAP_SCANLINE_PAD == 64
  27. #if 1
  28. /* Cursors might be only 32 wide. Give'em a chance */
  29. #define SCANLINE CARD32
  30. #define CUR_BITMAP_SCANLINE_PAD 32
  31. #define CUR_LOG2_BITMAP_PAD 5
  32. #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
  33. #else
  34. #define SCANLINE CARD64
  35. #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
  36. #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
  37. #define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
  38. static CARD64 xf86CARD64ReverseBits(CARD64 w);
  39. static CARD64
  40. xf86CARD64ReverseBits(CARD64 w)
  41. {
  42. unsigned char *p = (unsigned char *) &w;
  43. p[0] = byte_reversed[p[0]];
  44. p[1] = byte_reversed[p[1]];
  45. p[2] = byte_reversed[p[2]];
  46. p[3] = byte_reversed[p[3]];
  47. p[4] = byte_reversed[p[4]];
  48. p[5] = byte_reversed[p[5]];
  49. p[6] = byte_reversed[p[6]];
  50. p[7] = byte_reversed[p[7]];
  51. return w;
  52. }
  53. #endif
  54. #else
  55. #define SCANLINE CARD32
  56. #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
  57. #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
  58. #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
  59. #endif /* BITMAP_SCANLINE_PAD == 64 */
  60. static unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
  61. static unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
  62. static unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
  63. static unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
  64. static unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
  65. static unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
  66. Bool
  67. xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
  68. {
  69. if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
  70. return FALSE;
  71. /* These are required for now */
  72. if (!infoPtr->SetCursorPosition ||
  73. !xf86DriverHasLoadCursorImage(infoPtr) ||
  74. !infoPtr->HideCursor ||
  75. !infoPtr->ShowCursor || !infoPtr->SetCursorColors)
  76. return FALSE;
  77. if (infoPtr->RealizeCursor) {
  78. /* Don't overwrite a driver provided Realize Cursor function */
  79. }
  80. else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
  81. infoPtr->RealizeCursor = RealizeCursorInterleave1;
  82. }
  83. else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
  84. infoPtr->RealizeCursor = RealizeCursorInterleave8;
  85. }
  86. else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
  87. infoPtr->RealizeCursor = RealizeCursorInterleave16;
  88. }
  89. else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
  90. infoPtr->RealizeCursor = RealizeCursorInterleave32;
  91. }
  92. else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
  93. infoPtr->RealizeCursor = RealizeCursorInterleave64;
  94. }
  95. else { /* not interleaved */
  96. infoPtr->RealizeCursor = RealizeCursorInterleave0;
  97. }
  98. infoPtr->pScrn = xf86ScreenToScrn(pScreen);
  99. return TRUE;
  100. }
  101. Bool
  102. xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
  103. {
  104. xf86CursorScreenPtr ScreenPriv =
  105. (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
  106. xf86CursorScreenKey);
  107. xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
  108. unsigned char *bits;
  109. if (pCurs == NullCursor) {
  110. (*infoPtr->HideCursor) (infoPtr->pScrn);
  111. return TRUE;
  112. }
  113. bits =
  114. dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
  115. x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
  116. y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
  117. #ifdef ARGB_CURSOR
  118. if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
  119. #endif
  120. if (!bits) {
  121. bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
  122. dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
  123. bits);
  124. }
  125. if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
  126. (*infoPtr->HideCursor) (infoPtr->pScrn);
  127. #ifdef ARGB_CURSOR
  128. if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
  129. if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
  130. return FALSE;
  131. } else
  132. #endif
  133. if (bits)
  134. if (!xf86DriverLoadCursorImage (infoPtr, bits))
  135. return FALSE;
  136. xf86RecolorCursor(pScreen, pCurs, 1);
  137. (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
  138. (*infoPtr->ShowCursor) (infoPtr->pScrn);
  139. return TRUE;
  140. }
  141. void
  142. xf86SetTransparentCursor(ScreenPtr pScreen)
  143. {
  144. xf86CursorScreenPtr ScreenPriv =
  145. (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
  146. xf86CursorScreenKey);
  147. xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
  148. if (!ScreenPriv->transparentData)
  149. ScreenPriv->transparentData =
  150. (*infoPtr->RealizeCursor) (infoPtr, NullCursor);
  151. if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
  152. (*infoPtr->HideCursor) (infoPtr->pScrn);
  153. if (ScreenPriv->transparentData)
  154. xf86DriverLoadCursorImage (infoPtr,
  155. ScreenPriv->transparentData);
  156. (*infoPtr->ShowCursor) (infoPtr->pScrn);
  157. }
  158. void
  159. xf86MoveCursor(ScreenPtr pScreen, int x, int y)
  160. {
  161. xf86CursorScreenPtr ScreenPriv =
  162. (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
  163. xf86CursorScreenKey);
  164. xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
  165. x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
  166. y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
  167. (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
  168. }
  169. void
  170. xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
  171. {
  172. xf86CursorScreenPtr ScreenPriv =
  173. (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
  174. xf86CursorScreenKey);
  175. xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
  176. #ifdef ARGB_CURSOR
  177. /* recoloring isn't applicable to ARGB cursors and drivers
  178. shouldn't have to ignore SetCursorColors requests */
  179. if (pCurs->bits->argb)
  180. return;
  181. #endif
  182. if (ScreenPriv->PalettedCursor) {
  183. xColorItem sourceColor, maskColor;
  184. ColormapPtr pmap = ScreenPriv->pInstalledMap;
  185. if (!pmap)
  186. return;
  187. sourceColor.red = pCurs->foreRed;
  188. sourceColor.green = pCurs->foreGreen;
  189. sourceColor.blue = pCurs->foreBlue;
  190. FakeAllocColor(pmap, &sourceColor);
  191. maskColor.red = pCurs->backRed;
  192. maskColor.green = pCurs->backGreen;
  193. maskColor.blue = pCurs->backBlue;
  194. FakeAllocColor(pmap, &maskColor);
  195. FakeFreeColor(pmap, sourceColor.pixel);
  196. FakeFreeColor(pmap, maskColor.pixel);
  197. (*infoPtr->SetCursorColors) (infoPtr->pScrn,
  198. maskColor.pixel, sourceColor.pixel);
  199. }
  200. else { /* Pass colors in 8-8-8 RGB format */
  201. (*infoPtr->SetCursorColors) (infoPtr->pScrn,
  202. (pCurs->backBlue >> 8) |
  203. ((pCurs->backGreen >> 8) << 8) |
  204. ((pCurs->backRed >> 8) << 16),
  205. (pCurs->foreBlue >> 8) |
  206. ((pCurs->foreGreen >> 8) << 8) |
  207. ((pCurs->foreRed >> 8) << 16)
  208. );
  209. }
  210. }
  211. /* These functions assume that MaxWidth is a multiple of 32 */
  212. static unsigned char *
  213. RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  214. {
  215. SCANLINE *SrcS, *SrcM, *DstS, *DstM;
  216. SCANLINE *pSrc, *pMsk;
  217. unsigned char *mem;
  218. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  219. int SrcPitch, DstPitch, Pitch, y, x;
  220. /* how many words are in the source or mask */
  221. int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
  222. if (!(mem = calloc(1, size)))
  223. return NULL;
  224. if (pCurs == NullCursor) {
  225. if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
  226. DstM = (SCANLINE *) mem;
  227. if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
  228. DstM += words;
  229. memset(DstM, -1, words * sizeof(SCANLINE));
  230. }
  231. return mem;
  232. }
  233. /* SrcPitch == the number of scanlines wide the cursor image is */
  234. SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
  235. CUR_LOG2_BITMAP_PAD;
  236. /* DstPitch is the width of the hw cursor in scanlines */
  237. DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
  238. Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
  239. SrcS = (SCANLINE *) pCurs->bits->source;
  240. SrcM = (SCANLINE *) pCurs->bits->mask;
  241. DstS = (SCANLINE *) mem;
  242. DstM = DstS + words;
  243. if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
  244. SCANLINE *tmp;
  245. tmp = DstS;
  246. DstS = DstM;
  247. DstM = tmp;
  248. }
  249. if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
  250. for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
  251. y--;
  252. pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
  253. SrcPitch) {
  254. for (x = 0; x < Pitch; x++) {
  255. pSrc[x] = SrcS[x] & SrcM[x];
  256. pMsk[x] = SrcM[x];
  257. }
  258. }
  259. }
  260. else {
  261. for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
  262. y--;
  263. pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
  264. SrcPitch) {
  265. for (x = 0; x < Pitch; x++) {
  266. pSrc[x] = SrcS[x];
  267. pMsk[x] = SrcM[x];
  268. }
  269. }
  270. }
  271. if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
  272. int count = size;
  273. unsigned char *pntr1 = (unsigned char *) DstS;
  274. unsigned char *pntr2 = (unsigned char *) DstM;
  275. unsigned char a, b;
  276. while (count) {
  277. a = *pntr1;
  278. b = *pntr2;
  279. *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
  280. *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
  281. pntr1++;
  282. pntr2++;
  283. count -= 2;
  284. }
  285. }
  286. /*
  287. * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
  288. * out entire source mask.
  289. */
  290. if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
  291. int count = words;
  292. SCANLINE *pntr = DstM;
  293. while (count--) {
  294. *pntr = ~(*pntr);
  295. pntr++;
  296. }
  297. }
  298. if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
  299. for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
  300. y--; pSrc += DstPitch, pMsk += DstPitch) {
  301. for (x = 0; x < Pitch; x++) {
  302. pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
  303. pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
  304. }
  305. }
  306. }
  307. return mem;
  308. }
  309. static unsigned char *
  310. RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  311. {
  312. unsigned char *DstS, *DstM;
  313. unsigned char *pntr;
  314. unsigned char *mem, *mem2;
  315. int count;
  316. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  317. /* Realize the cursor without interleaving */
  318. if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
  319. return NULL;
  320. if (!(mem = calloc(1, size))) {
  321. free(mem2);
  322. return NULL;
  323. }
  324. /* 1 bit interleave */
  325. DstS = mem2;
  326. DstM = DstS + (size >> 1);
  327. pntr = mem;
  328. count = size;
  329. while (count) {
  330. *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) |
  331. ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) |
  332. ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) |
  333. ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4);
  334. *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) |
  335. ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) |
  336. ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) |
  337. ((*DstS & 0x80) >> 1) | ((*DstM & 0x80));
  338. DstS++;
  339. DstM++;
  340. count -= 2;
  341. }
  342. /* Free the uninterleaved cursor */
  343. free(mem2);
  344. return mem;
  345. }
  346. static unsigned char *
  347. RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  348. {
  349. unsigned char *DstS, *DstM;
  350. unsigned char *pntr;
  351. unsigned char *mem, *mem2;
  352. int count;
  353. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  354. /* Realize the cursor without interleaving */
  355. if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
  356. return NULL;
  357. if (!(mem = calloc(1, size))) {
  358. free(mem2);
  359. return NULL;
  360. }
  361. /* 8 bit interleave */
  362. DstS = mem2;
  363. DstM = DstS + (size >> 1);
  364. pntr = mem;
  365. count = size;
  366. while (count) {
  367. *pntr++ = *DstS++;
  368. *pntr++ = *DstM++;
  369. count -= 2;
  370. }
  371. /* Free the uninterleaved cursor */
  372. free(mem2);
  373. return mem;
  374. }
  375. static unsigned char *
  376. RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  377. {
  378. unsigned short *DstS, *DstM;
  379. unsigned short *pntr;
  380. unsigned char *mem, *mem2;
  381. int count;
  382. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  383. /* Realize the cursor without interleaving */
  384. if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
  385. return NULL;
  386. if (!(mem = calloc(1, size))) {
  387. free(mem2);
  388. return NULL;
  389. }
  390. /* 16 bit interleave */
  391. DstS = (void *) mem2;
  392. DstM = DstS + (size >> 2);
  393. pntr = (void *) mem;
  394. count = (size >> 1);
  395. while (count) {
  396. *pntr++ = *DstS++;
  397. *pntr++ = *DstM++;
  398. count -= 2;
  399. }
  400. /* Free the uninterleaved cursor */
  401. free(mem2);
  402. return mem;
  403. }
  404. static unsigned char *
  405. RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  406. {
  407. CARD32 *DstS, *DstM;
  408. CARD32 *pntr;
  409. unsigned char *mem, *mem2;
  410. int count;
  411. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  412. /* Realize the cursor without interleaving */
  413. if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
  414. return NULL;
  415. if (!(mem = calloc(1, size))) {
  416. free(mem2);
  417. return NULL;
  418. }
  419. /* 32 bit interleave */
  420. DstS = (void *) mem2;
  421. DstM = DstS + (size >> 3);
  422. pntr = (void *) mem;
  423. count = (size >> 2);
  424. while (count) {
  425. *pntr++ = *DstS++;
  426. *pntr++ = *DstM++;
  427. count -= 2;
  428. }
  429. /* Free the uninterleaved cursor */
  430. free(mem2);
  431. return mem;
  432. }
  433. static unsigned char *
  434. RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
  435. {
  436. CARD32 *DstS, *DstM;
  437. CARD32 *pntr;
  438. unsigned char *mem, *mem2;
  439. int count;
  440. int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
  441. /* Realize the cursor without interleaving */
  442. if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
  443. return NULL;
  444. if (!(mem = calloc(1, size))) {
  445. free(mem2);
  446. return NULL;
  447. }
  448. /* 64 bit interleave */
  449. DstS = (void *) mem2;
  450. DstM = DstS + (size >> 3);
  451. pntr = (void *) mem;
  452. count = (size >> 2);
  453. while (count) {
  454. *pntr++ = *DstS++;
  455. *pntr++ = *DstS++;
  456. *pntr++ = *DstM++;
  457. *pntr++ = *DstM++;
  458. count -= 4;
  459. }
  460. /* Free the uninterleaved cursor */
  461. free(mem2);
  462. return mem;
  463. }