Mouse.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /**
  2. * Copyright (c) 2006-2015 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "Mouse.h"
  22. #include "window/sdl/Window.h"
  23. // SDL
  24. #include <SDL_mouse.h>
  25. namespace love
  26. {
  27. namespace mouse
  28. {
  29. namespace sdl
  30. {
  31. // SDL reports mouse coordinates in the window coordinate system in OS X, but
  32. // we want them in pixel coordinates (may be different with high-DPI enabled.)
  33. static void windowToPixelCoords(double *x, double *y)
  34. {
  35. window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
  36. if (window)
  37. window->windowToPixelCoords(x, y);
  38. }
  39. // And vice versa for setting mouse coordinates.
  40. static void pixelToWindowCoords(double *x, double *y)
  41. {
  42. window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
  43. if (window)
  44. window->pixelToWindowCoords(x, y);
  45. }
  46. const char *Mouse::getName() const
  47. {
  48. return "love.mouse.sdl";
  49. }
  50. Mouse::Mouse()
  51. : curCursor(nullptr)
  52. {
  53. }
  54. Mouse::~Mouse()
  55. {
  56. if (curCursor.get())
  57. setCursor();
  58. for (auto &c : systemCursors)
  59. c.second->release();
  60. }
  61. love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty)
  62. {
  63. return new Cursor(data, hotx, hoty);
  64. }
  65. love::mouse::Cursor *Mouse::getSystemCursor(Cursor::SystemCursor cursortype)
  66. {
  67. Cursor *cursor = nullptr;
  68. auto it = systemCursors.find(cursortype);
  69. if (it != systemCursors.end())
  70. cursor = it->second;
  71. else
  72. {
  73. cursor = new Cursor(cursortype);
  74. systemCursors[cursortype] = cursor;
  75. }
  76. return cursor;
  77. }
  78. void Mouse::setCursor(love::mouse::Cursor *cursor)
  79. {
  80. curCursor.set(cursor);
  81. SDL_SetCursor((SDL_Cursor *) cursor->getHandle());
  82. }
  83. void Mouse::setCursor()
  84. {
  85. curCursor.set(nullptr);
  86. SDL_SetCursor(SDL_GetDefaultCursor());
  87. }
  88. love::mouse::Cursor *Mouse::getCursor() const
  89. {
  90. return curCursor.get();
  91. }
  92. bool Mouse::hasCursor() const
  93. {
  94. return SDL_GetDefaultCursor() != nullptr;
  95. }
  96. double Mouse::getX() const
  97. {
  98. int x;
  99. SDL_GetMouseState(&x, nullptr);
  100. double dx = (double) x;
  101. windowToPixelCoords(&dx, nullptr);
  102. return dx;
  103. }
  104. double Mouse::getY() const
  105. {
  106. int y;
  107. SDL_GetMouseState(nullptr, &y);
  108. double dy = (double) y;
  109. windowToPixelCoords(nullptr, &dy);
  110. return dy;
  111. }
  112. void Mouse::getPosition(double &x, double &y) const
  113. {
  114. int mx, my;
  115. SDL_GetMouseState(&mx, &my);
  116. x = (double) mx;
  117. y = (double) my;
  118. windowToPixelCoords(&x, &y);
  119. }
  120. void Mouse::setPosition(double x, double y)
  121. {
  122. window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
  123. SDL_Window *handle = nullptr;
  124. if (window)
  125. handle = (SDL_Window *) window->getHandle();
  126. pixelToWindowCoords(&x, &y);
  127. SDL_WarpMouseInWindow(handle, (int) x, (int) y);
  128. // SDL_WarpMouse doesn't directly update SDL's internal mouse state in Linux
  129. // and Windows, so we call SDL_PumpEvents now to make sure the next
  130. // getPosition call always returns the updated state.
  131. SDL_PumpEvents();
  132. }
  133. void Mouse::setX(double x)
  134. {
  135. setPosition(x, getY());
  136. }
  137. void Mouse::setY(double y)
  138. {
  139. setPosition(getX(), y);
  140. }
  141. void Mouse::setVisible(bool visible)
  142. {
  143. SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
  144. }
  145. bool Mouse::isDown(const std::vector<int> &buttons) const
  146. {
  147. Uint32 buttonstate = SDL_GetMouseState(nullptr, nullptr);
  148. for (int button : buttons)
  149. {
  150. if (button <= 0)
  151. continue;
  152. // We use button index 2 to represent the right mouse button, but SDL
  153. // uses 2 to represent the middle mouse button.
  154. switch (button)
  155. {
  156. case 2:
  157. button = SDL_BUTTON_RIGHT;
  158. break;
  159. case 3:
  160. button = SDL_BUTTON_MIDDLE;
  161. break;
  162. }
  163. if (buttonstate & SDL_BUTTON(button))
  164. return true;
  165. }
  166. return false;
  167. }
  168. bool Mouse::isVisible() const
  169. {
  170. return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
  171. }
  172. void Mouse::setGrabbed(bool grab)
  173. {
  174. window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
  175. if (window)
  176. window->setMouseGrab(grab);
  177. }
  178. bool Mouse::isGrabbed() const
  179. {
  180. window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
  181. if (window)
  182. return window->isMouseGrabbed();
  183. else
  184. return false;
  185. }
  186. bool Mouse::setRelativeMode(bool relative)
  187. {
  188. return SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
  189. }
  190. bool Mouse::getRelativeMode() const
  191. {
  192. return SDL_GetRelativeMouseMode() != SDL_FALSE;
  193. }
  194. } // sdl
  195. } // mouse
  196. } // love