rrpointer.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright © 2006 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. #include "randrstr.h"
  23. /*
  24. * When the pointer moves, check to see if the specified position is outside
  25. * any of theavailable CRTCs and move it to a 'sensible' place if so, where
  26. * sensible is the closest monitor to the departing edge.
  27. *
  28. * Returns whether the position was adjusted
  29. */
  30. static Bool
  31. RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
  32. {
  33. RRModePtr mode = crtc->mode;
  34. int scan_width, scan_height;
  35. if (!mode)
  36. return FALSE;
  37. RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
  38. if (crtc->x <= x && x < crtc->x + scan_width &&
  39. crtc->y <= y && y < crtc->y + scan_height)
  40. return TRUE;
  41. return FALSE;
  42. }
  43. /*
  44. * Find the CRTC nearest the specified position, ignoring 'skip'
  45. */
  46. static void
  47. RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
  48. {
  49. rrScrPriv(pScreen);
  50. int c;
  51. RRCrtcPtr nearest = NULL;
  52. int best = 0;
  53. int best_dx = 0, best_dy = 0;
  54. for (c = 0; c < pScrPriv->numCrtcs; c++) {
  55. RRCrtcPtr crtc = pScrPriv->crtcs[c];
  56. RRModePtr mode = crtc->mode;
  57. int dx, dy;
  58. int dist;
  59. int scan_width, scan_height;
  60. if (!mode)
  61. continue;
  62. if (crtc == skip)
  63. continue;
  64. RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
  65. if (x < crtc->x)
  66. dx = crtc->x - x;
  67. else if (x > crtc->x + scan_width)
  68. dx = x - (crtc->x + scan_width);
  69. else
  70. dx = 0;
  71. if (y < crtc->y)
  72. dy = crtc->y - x;
  73. else if (y > crtc->y + scan_height)
  74. dy = y - (crtc->y + scan_height);
  75. else
  76. dy = 0;
  77. dist = dx + dy;
  78. if (!nearest || dist < best) {
  79. nearest = crtc;
  80. best_dx = dx;
  81. best_dy = dy;
  82. }
  83. }
  84. if (best_dx || best_dy)
  85. (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE);
  86. pScrPriv->pointerCrtc = nearest;
  87. }
  88. void
  89. RRPointerMoved(ScreenPtr pScreen, int x, int y)
  90. {
  91. rrScrPriv(pScreen);
  92. RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;;
  93. int c;
  94. /* Check last known CRTC */
  95. if (pointerCrtc && RRCrtcContainsPosition(pointerCrtc, x, y))
  96. return;
  97. /* Check all CRTCs */
  98. for (c = 0; c < pScrPriv->numCrtcs; c++) {
  99. RRCrtcPtr crtc = pScrPriv->crtcs[c];
  100. if (RRCrtcContainsPosition(crtc, x, y)) {
  101. /* Remember containing CRTC */
  102. pScrPriv->pointerCrtc = crtc;
  103. return;
  104. }
  105. }
  106. /* None contain pointer, find nearest */
  107. RRPointerToNearestCrtc(pScreen, x, y, pointerCrtc);
  108. }
  109. /*
  110. * When the screen is reconfigured, move the pointer to the nearest
  111. * CRTC
  112. */
  113. void
  114. RRPointerScreenConfigured(ScreenPtr pScreen)
  115. {
  116. WindowPtr pRoot = GetCurrentRootWindow();
  117. ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
  118. int x, y;
  119. if (pScreen != pCurrentScreen)
  120. return;
  121. GetSpritePosition(&x, &y);
  122. RRPointerToNearestCrtc(pScreen, x, y, NULL);
  123. }