haiku_direct_window.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include "main/main.h"
  2. #include "haiku_direct_window.h"
  3. HaikuDirectWindow::HaikuDirectWindow(BRect p_frame)
  4. : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, 0)
  5. {
  6. last_mouse_pos_valid = false;
  7. last_buttons_state = 0;
  8. last_button_mask = 0;
  9. }
  10. HaikuDirectWindow::~HaikuDirectWindow() {
  11. if (update_runner) {
  12. delete update_runner;
  13. }
  14. }
  15. void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) {
  16. view = p_view;
  17. }
  18. void HaikuDirectWindow::StartMessageRunner() {
  19. update_runner = new BMessageRunner(BMessenger(this),
  20. new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);
  21. }
  22. void HaikuDirectWindow::StopMessageRunner() {
  23. delete update_runner;
  24. }
  25. void HaikuDirectWindow::SetInput(InputDefault* p_input) {
  26. input = p_input;
  27. }
  28. bool HaikuDirectWindow::QuitRequested() {
  29. view->EnableDirectMode(false);
  30. be_app->PostMessage(B_QUIT_REQUESTED);
  31. return true;
  32. }
  33. void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) {
  34. view->DirectConnected(info);
  35. view->EnableDirectMode(true);
  36. }
  37. void HaikuDirectWindow::MessageReceived(BMessage* message)
  38. {
  39. switch (message->what) {
  40. case REDRAW_MSG:
  41. //ERR_PRINT("iteration 1");
  42. Main::iteration();
  43. //if (NeedsUpdate()) {
  44. // ERR_PRINT("NEEDS UPDATE");
  45. // Main::force_redraw();
  46. //}
  47. //ERR_PRINT("iteration 2");
  48. break;
  49. case B_INVALIDATE:
  50. ERR_PRINT("WINDOW B_INVALIDATE");
  51. //Main::force_redraw();
  52. break;
  53. default:
  54. BDirectWindow::MessageReceived(message);
  55. }
  56. }
  57. void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) {
  58. switch (message->what) {
  59. case B_MOUSE_DOWN:
  60. case B_MOUSE_UP:
  61. DispatchMouseButton(message);
  62. break;
  63. case B_MOUSE_MOVED:
  64. DispatchMouseMoved(message);
  65. break;
  66. default:
  67. BDirectWindow::DispatchMessage(message, handler);
  68. }
  69. }
  70. void HaikuDirectWindow::DispatchMouseButton(BMessage* message) {
  71. message->PrintToStream();
  72. BPoint where;
  73. if (message->FindPoint("where", &where) != B_OK) {
  74. return;
  75. }
  76. uint32 modifiers = message->FindInt32("modifiers");
  77. uint32 buttons = message->FindInt32("buttons");
  78. uint32 button = buttons ^ last_buttons_state;
  79. last_buttons_state = buttons;
  80. // TODO: implement the mouse_mode checks
  81. //if (mouse_mode == MOUSE_MODE_CAPTURED) {
  82. // event.xbutton.x=last_mouse_pos.x;
  83. // event.xbutton.y=last_mouse_pos.y;
  84. //}
  85. InputEvent mouse_event;
  86. mouse_event.ID = ++event_id;
  87. mouse_event.type = InputEvent::MOUSE_BUTTON;
  88. mouse_event.device = 0;
  89. mouse_event.mouse_button.mod = GetKeyModifierState(modifiers);
  90. mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons);
  91. mouse_event.mouse_button.x = where.x;
  92. mouse_event.mouse_button.y = where.y;
  93. mouse_event.mouse_button.global_x = where.x;
  94. mouse_event.mouse_button.global_y = where.y;
  95. switch (button) {
  96. default:
  97. case B_PRIMARY_MOUSE_BUTTON:
  98. mouse_event.mouse_button.button_index = 1;
  99. break;
  100. case B_SECONDARY_MOUSE_BUTTON:
  101. mouse_event.mouse_button.button_index = 2;
  102. break;
  103. case B_TERTIARY_MOUSE_BUTTON:
  104. mouse_event.mouse_button.button_index = 3;
  105. break;
  106. }
  107. mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
  108. if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
  109. int32 clicks = message->FindInt32("clicks");
  110. if (clicks > 1) {
  111. mouse_event.mouse_button.doubleclick=true;
  112. }
  113. }
  114. input->parse_input_event(mouse_event);
  115. }
  116. void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) {
  117. BPoint where;
  118. if (message->FindPoint("where", &where) != B_OK) {
  119. return;
  120. }
  121. Point2i pos(where.x, where.y);
  122. uint32 modifiers = message->FindInt32("modifiers");
  123. uint32 buttons = message->FindInt32("buttons");
  124. if (!last_mouse_pos_valid) {
  125. last_mouse_position = pos;
  126. last_mouse_pos_valid = true;
  127. }
  128. Point2i rel = pos - last_mouse_position;
  129. InputEvent motion_event;
  130. motion_event.ID = ++event_id;
  131. motion_event.type = InputEvent::MOUSE_MOTION;
  132. motion_event.device = 0;
  133. motion_event.mouse_motion.mod = GetKeyModifierState(modifiers);
  134. motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons);
  135. motion_event.mouse_motion.x = pos.x;
  136. motion_event.mouse_motion.y = pos.y;
  137. input->set_mouse_pos(pos);
  138. motion_event.mouse_motion.global_x = pos.x;
  139. motion_event.mouse_motion.global_y = pos.y;
  140. motion_event.mouse_motion.speed_x = input->get_mouse_speed().x;
  141. motion_event.mouse_motion.speed_y = input->get_mouse_speed().y;
  142. motion_event.mouse_motion.relative_x = rel.x;
  143. motion_event.mouse_motion.relative_y = rel.y;
  144. last_mouse_position = pos;
  145. input->parse_input_event(motion_event);
  146. }
  147. inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) {
  148. InputModifierState state;
  149. state.shift = (p_state & B_SHIFT_KEY) != 0;
  150. state.control = (p_state & B_CONTROL_KEY) != 0;
  151. state.alt = (p_state & B_OPTION_KEY) != 0;
  152. state.meta = (p_state & B_COMMAND_KEY) != 0;
  153. return state;
  154. }
  155. inline int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) {
  156. int state = 0;
  157. if (p_state & B_PRIMARY_MOUSE_BUTTON) {
  158. state |= 1 << 0;
  159. }
  160. if (p_state & B_SECONDARY_MOUSE_BUTTON) {
  161. state |= 1 << 1;
  162. }
  163. if (p_state & B_TERTIARY_MOUSE_BUTTON) {
  164. state |= 1 << 2;
  165. }
  166. last_button_mask = state;
  167. return state;
  168. }