BsLinuxKeyboard.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Input/BsKeyboard.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 Keyboard implementation. */
  12. struct Keyboard::Pimpl
  13. {
  14. INT32 fileHandles[MAX_DEVICES];
  15. };
  16. Keyboard::Keyboard(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->keyboards)
  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. Keyboard::~Keyboard()
  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 Keyboard::capture()
  45. {
  46. input_event events[BUFFER_SIZE_KEYBOARD];
  47. for(UINT32 i = 0; i < MAX_DEVICES; i++)
  48. {
  49. if(m->fileHandles[i] == -1)
  50. continue;
  51. while(true)
  52. {
  53. ssize_t numReadBytes = read(m->fileHandles[i], &events, sizeof(events));
  54. if(numReadBytes < 0)
  55. break;
  56. UINT32 numEvents = numReadBytes / sizeof(input_event);
  57. for(UINT32 j = 0; j < numEvents; ++j)
  58. {
  59. switch(events[j].type)
  60. {
  61. case EV_KEY:
  62. {
  63. ButtonCode bc = (ButtonCode)events[j].code;
  64. if(bc < BC_MOUSE_LEFT)
  65. {
  66. if(events[j].value)
  67. mOwner->_notifyButtonPressed(0, bc, (UINT64)events[j].time.tv_usec);
  68. else
  69. mOwner->_notifyButtonReleased(0, bc, (UINT64)events[j].time.tv_usec);
  70. }
  71. }
  72. break;
  73. default: break;
  74. }
  75. }
  76. }
  77. }
  78. }
  79. void Keyboard::changeCaptureContext(UINT64 windowHandle)
  80. {
  81. // Do nothing
  82. }
  83. }