BsLinuxMouse.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Input/BsMouse.h"
  4. #include "Input/BsInput.h"
  5. #include "Linux/BsLinuxInput.h"
  6. #include <fcntl.h>
  7. #include <linux/input.h>
  8. namespace bs
  9. {
  10. constexpr UINT32 MAX_DEVICES = 8;
  11. /** Contains private data for the Linux Mouse implementation. */
  12. struct Mouse::Pimpl
  13. {
  14. INT32 fileHandles[MAX_DEVICES];
  15. };
  16. Mouse::Mouse(const String& name, Input* owner)
  17. : mName(name), mOwner(owner)
  18. {
  19. InputPrivateData* pvtData = owner->_getPrivateData();
  20. m = bs_new<Pimpl>();
  21. for(UINT32 i = 0; i < MAX_DEVICES; i++)
  22. m->fileHandles[i] = -1;
  23. UINT32 idx = 0;
  24. for(auto& entry : pvtData->mice)
  25. {
  26. String eventPath = "/dev/input/event" + toString(entry);
  27. m->fileHandles[idx] = open(eventPath.c_str(), O_RDWR | O_NONBLOCK);
  28. if(m->fileHandles[idx] == -1)
  29. LOGERR("Failed to open input event file handle for device: " + mName);
  30. idx++;
  31. if(idx >= MAX_DEVICES)
  32. break;
  33. }
  34. }
  35. Mouse::~Mouse()
  36. {
  37. for(UINT32 i = 0; i < MAX_DEVICES; i++)
  38. {
  39. if(m->fileHandles[i] != -1)
  40. close(m->fileHandles[i]);
  41. }
  42. bs_delete(m);
  43. }
  44. void Mouse::capture()
  45. {
  46. INT32 relX = 0;
  47. INT32 relY = 0;
  48. INT32 relZ = 0;
  49. input_event events[BUFFER_SIZE_MOUSE];
  50. for(UINT32 i = 0; i < MAX_DEVICES; i++)
  51. {
  52. if(m->fileHandles[i] == -1)
  53. continue;
  54. while(true)
  55. {
  56. ssize_t numReadBytes = read(m->fileHandles[i], &events, sizeof(events));
  57. if(numReadBytes < 0)
  58. break;
  59. UINT32 numEvents = numReadBytes / sizeof(input_event);
  60. for(UINT32 j = 0; j < numEvents; ++j)
  61. {
  62. switch(events[j].type)
  63. {
  64. case EV_KEY:
  65. {
  66. ButtonCode bc = BC_UNASSIGNED;
  67. // Unnamed mouse buttons
  68. if(events[j].code >= BTN_MISC && events[j].code < BTN_MOUSE)
  69. bc = (ButtonCode)((INT32)BC_MOUSE_BTN4 + (events[j].code - BTN_MISC));
  70. // Named mouse buttons
  71. else if(events[j].code >= BTN_MOUSE && events[j].code < BTN_JOYSTICK)
  72. {
  73. switch (events[j].code)
  74. {
  75. case BTN_LEFT:
  76. bc = BC_MOUSE_LEFT;
  77. break;
  78. case BTN_MIDDLE:
  79. bc = BC_MOUSE_MIDDLE;
  80. break;
  81. case BTN_RIGHT:
  82. bc = BC_MOUSE_RIGHT;
  83. break;
  84. case BTN_SIDE:
  85. bc = BC_MOUSE_BTN15;
  86. break;
  87. case BTN_EXTRA:
  88. bc = BC_MOUSE_BTN16;
  89. break;
  90. case BTN_FORWARD:
  91. bc = BC_MOUSE_BTN17;
  92. break;
  93. case BTN_BACK:
  94. bc = BC_MOUSE_BTN18;
  95. break;
  96. case BTN_TASK:
  97. bc = BC_MOUSE_BTN19;
  98. break;
  99. default:
  100. break;
  101. }
  102. }
  103. if(bc != BC_UNASSIGNED)
  104. {
  105. if (events[j].value)
  106. mOwner->_notifyButtonPressed(0, bc, (UINT64) events[j].time.tv_usec);
  107. else
  108. mOwner->_notifyButtonReleased(0, bc, (UINT64) events[j].time.tv_usec);
  109. }
  110. }
  111. break;
  112. case EV_REL:
  113. {
  114. switch(events[j].code)
  115. {
  116. case REL_X:
  117. relX += events[j].value;
  118. break;
  119. case REL_Y:
  120. relY += events[j].value;
  121. break;
  122. case REL_WHEEL:
  123. relZ += events[j].value;
  124. break;
  125. default:
  126. break;
  127. }
  128. break;
  129. }
  130. default: break;
  131. }
  132. }
  133. }
  134. }
  135. if(relX != 0 || relY != 0 || relZ != 0)
  136. mOwner->_notifyMouseMoved(relX, relY, relZ);
  137. }
  138. void Mouse::changeCaptureContext(UINT64 windowHandle)
  139. {
  140. // Do nothing
  141. }
  142. }