Reimplement HTML5 mouse input without GLUT
Fixes inverted scrolling on Chromium
(cherry picked from commit a99b6b2063
)
This commit is contained in:
parent
73e3947493
commit
9b07e32656
3 changed files with 113 additions and 92 deletions
|
@ -43,74 +43,6 @@ static void _gfx_init(void *ud, bool gl2, int w, int h, bool fs) {
|
||||||
glutCreateWindow("godot");
|
glutCreateWindow("godot");
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _mouse_button_mask = 0;
|
|
||||||
|
|
||||||
static void _glut_mouse_button(int button, int state, int x, int y) {
|
|
||||||
|
|
||||||
InputEvent ev;
|
|
||||||
ev.type = InputEvent::MOUSE_BUTTON;
|
|
||||||
switch (button) {
|
|
||||||
case GLUT_LEFT_BUTTON: ev.mouse_button.button_index = BUTTON_LEFT; break;
|
|
||||||
case GLUT_MIDDLE_BUTTON: ev.mouse_button.button_index = BUTTON_MIDDLE; break;
|
|
||||||
case GLUT_RIGHT_BUTTON: ev.mouse_button.button_index = BUTTON_RIGHT; break;
|
|
||||||
case 3: ev.mouse_button.button_index = BUTTON_WHEEL_UP; break;
|
|
||||||
case 4: ev.mouse_button.button_index = BUTTON_WHEEL_DOWN; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ev.mouse_button.pressed = state == GLUT_DOWN;
|
|
||||||
ev.mouse_button.x = x;
|
|
||||||
ev.mouse_button.y = y;
|
|
||||||
ev.mouse_button.global_x = x;
|
|
||||||
ev.mouse_button.global_y = y;
|
|
||||||
|
|
||||||
if (ev.mouse_button.button_index < 4) {
|
|
||||||
if (ev.mouse_button.pressed) {
|
|
||||||
_mouse_button_mask |= 1 << (ev.mouse_button.button_index - 1);
|
|
||||||
} else {
|
|
||||||
_mouse_button_mask &= ~(1 << (ev.mouse_button.button_index - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev.mouse_button.button_mask = _mouse_button_mask;
|
|
||||||
|
|
||||||
uint32_t m = glutGetModifiers();
|
|
||||||
ev.mouse_button.mod.alt = (m & GLUT_ACTIVE_ALT) != 0;
|
|
||||||
ev.mouse_button.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0;
|
|
||||||
ev.mouse_button.mod.control = (m & GLUT_ACTIVE_CTRL) != 0;
|
|
||||||
|
|
||||||
os->push_input(ev);
|
|
||||||
|
|
||||||
if (ev.mouse_button.button_index == BUTTON_WHEEL_UP || ev.mouse_button.button_index == BUTTON_WHEEL_DOWN) {
|
|
||||||
// GLUT doesn't send release events for mouse wheel, so send manually
|
|
||||||
ev.mouse_button.pressed = false;
|
|
||||||
os->push_input(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _glut_prev_x = 0;
|
|
||||||
static int _glut_prev_y = 0;
|
|
||||||
|
|
||||||
static void _glut_mouse_motion(int x, int y) {
|
|
||||||
|
|
||||||
InputEvent ev;
|
|
||||||
ev.type = InputEvent::MOUSE_MOTION;
|
|
||||||
ev.mouse_motion.button_mask = _mouse_button_mask;
|
|
||||||
ev.mouse_motion.x = x;
|
|
||||||
ev.mouse_motion.y = y;
|
|
||||||
ev.mouse_motion.global_x = x;
|
|
||||||
ev.mouse_motion.global_y = y;
|
|
||||||
ev.mouse_motion.relative_x = x - _glut_prev_x;
|
|
||||||
ev.mouse_motion.relative_y = y - _glut_prev_y;
|
|
||||||
_glut_prev_x = x;
|
|
||||||
_glut_prev_y = y;
|
|
||||||
|
|
||||||
uint32_t m = glutGetModifiers();
|
|
||||||
ev.mouse_motion.mod.alt = (m & GLUT_ACTIVE_ALT) != 0;
|
|
||||||
ev.mouse_motion.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0;
|
|
||||||
ev.mouse_motion.mod.control = (m & GLUT_ACTIVE_CTRL) != 0;
|
|
||||||
|
|
||||||
os->push_input(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _gfx_idle() {
|
static void _gfx_idle() {
|
||||||
|
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
|
@ -159,10 +91,6 @@ int main(int argc, char *argv[]) {
|
||||||
#endif
|
#endif
|
||||||
ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility
|
ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility
|
||||||
|
|
||||||
glutMouseFunc(_glut_mouse_button);
|
|
||||||
glutMotionFunc(_glut_mouse_motion);
|
|
||||||
glutPassiveMotionFunc(_glut_mouse_motion);
|
|
||||||
|
|
||||||
/* Set up glut callback functions */
|
/* Set up glut callback functions */
|
||||||
glutIdleFunc(_gfx_idle);
|
glutIdleFunc(_gfx_idle);
|
||||||
// glutReshapeFunc(gears_reshape);
|
// glutReshapeFunc(gears_reshape);
|
||||||
|
|
|
@ -42,6 +42,21 @@
|
||||||
#include "emscripten.h"
|
#include "emscripten.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
#define DOM_BUTTON_LEFT 0
|
||||||
|
#define DOM_BUTTON_MIDDLE 1
|
||||||
|
#define DOM_BUTTON_RIGHT 2
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static InputModifierState dom2godot_mod(T emscripten_event_ptr) {
|
||||||
|
|
||||||
|
InputModifierState mod;
|
||||||
|
mod.shift = emscripten_event_ptr->shiftKey;
|
||||||
|
mod.alt = emscripten_event_ptr->altKey;
|
||||||
|
mod.control = emscripten_event_ptr->ctrlKey;
|
||||||
|
mod.meta = emscripten_event_ptr->metaKey;
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
int OS_JavaScript::get_video_driver_count() const {
|
int OS_JavaScript::get_video_driver_count() const {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -130,15 +145,101 @@ static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFulls
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static InputDefault *_input;
|
||||||
|
static int last_button_mask;
|
||||||
|
|
||||||
|
static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEDOWN && event_type != EMSCRIPTEN_EVENT_MOUSEUP, false);
|
||||||
|
|
||||||
|
InputEvent ev;
|
||||||
|
ev.type = InputEvent::MOUSE_BUTTON;
|
||||||
|
ev.mouse_button.pressed = event_type == EMSCRIPTEN_EVENT_MOUSEDOWN;
|
||||||
|
ev.mouse_button.global_x = ev.mouse_button.x = mouse_event->canvasX;
|
||||||
|
ev.mouse_button.global_y = ev.mouse_button.y = mouse_event->canvasY;
|
||||||
|
ev.mouse_button.mod = dom2godot_mod(mouse_event);
|
||||||
|
|
||||||
|
switch (mouse_event->button) {
|
||||||
|
case DOM_BUTTON_LEFT: ev.mouse_button.button_index = BUTTON_LEFT; break;
|
||||||
|
case DOM_BUTTON_MIDDLE: ev.mouse_button.button_index = BUTTON_MIDDLE; break;
|
||||||
|
case DOM_BUTTON_RIGHT: ev.mouse_button.button_index = BUTTON_RIGHT; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ev.mouse_button.button_mask = last_button_mask;
|
||||||
|
if (ev.mouse_button.pressed)
|
||||||
|
ev.mouse_button.button_mask |= 1 << (ev.mouse_button.button_index - 1);
|
||||||
|
else
|
||||||
|
ev.mouse_button.button_mask &= ~(1 << (ev.mouse_button.button_index - 1));
|
||||||
|
last_button_mask = ev.mouse_button.button_mask;
|
||||||
|
|
||||||
|
_input->parse_input_event(ev);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEMOVE, false);
|
||||||
|
|
||||||
|
InputEvent ev;
|
||||||
|
ev.type = InputEvent::MOUSE_MOTION;
|
||||||
|
ev.mouse_motion.mod = dom2godot_mod(mouse_event);
|
||||||
|
ev.mouse_motion.button_mask = last_button_mask;
|
||||||
|
|
||||||
|
ev.mouse_motion.global_x = ev.mouse_motion.x = mouse_event->canvasX;
|
||||||
|
ev.mouse_motion.global_y = ev.mouse_motion.y = mouse_event->canvasY;
|
||||||
|
|
||||||
|
ev.mouse_motion.relative_x = _input->get_mouse_pos().x - ev.mouse_motion.x;
|
||||||
|
ev.mouse_motion.relative_y = _input->get_mouse_pos().y - ev.mouse_motion.y;
|
||||||
|
|
||||||
|
_input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
|
||||||
|
ev.mouse_motion.speed_x = _input->get_mouse_speed().x;
|
||||||
|
ev.mouse_motion.speed_y = _input->get_mouse_speed().y;
|
||||||
|
|
||||||
|
_input->parse_input_event(ev);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel_event, void *user_data) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false);
|
||||||
|
|
||||||
|
InputEvent ev;
|
||||||
|
ev.type = InputEvent::MOUSE_BUTTON;
|
||||||
|
ev.mouse_button.button_mask = last_button_mask;
|
||||||
|
ev.mouse_button.global_x = ev.mouse_button.x = _input->get_mouse_pos().x;
|
||||||
|
ev.mouse_button.global_y = ev.mouse_button.y = _input->get_mouse_pos().y;
|
||||||
|
ev.mouse_button.mod.shift = _input->is_key_pressed(KEY_SHIFT);
|
||||||
|
ev.mouse_button.mod.alt = _input->is_key_pressed(KEY_ALT);
|
||||||
|
ev.mouse_button.mod.control = _input->is_key_pressed(KEY_CONTROL);
|
||||||
|
ev.mouse_button.mod.meta = _input->is_key_pressed(KEY_META);
|
||||||
|
|
||||||
|
if (wheel_event->deltaY < 0)
|
||||||
|
ev.mouse_button.button_index = BUTTON_WHEEL_UP;
|
||||||
|
else if (wheel_event->deltaY > 0)
|
||||||
|
ev.mouse_button.button_index = BUTTON_WHEEL_DOWN;
|
||||||
|
else if (wheel_event->deltaX > 0)
|
||||||
|
ev.mouse_button.button_index = BUTTON_WHEEL_LEFT;
|
||||||
|
else if (wheel_event->deltaX < 0)
|
||||||
|
ev.mouse_button.button_index = BUTTON_WHEEL_RIGHT;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ev.mouse_button.pressed = true;
|
||||||
|
_input->parse_input_event(ev);
|
||||||
|
|
||||||
|
ev.mouse_button.pressed = false;
|
||||||
|
_input->parse_input_event(ev);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
|
static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
|
||||||
|
|
||||||
InputEvent ev;
|
InputEvent ev;
|
||||||
ev.type = InputEvent::KEY;
|
ev.type = InputEvent::KEY;
|
||||||
ev.key.echo = emscripten_event->repeat;
|
ev.key.echo = emscripten_event->repeat;
|
||||||
ev.key.mod.alt = emscripten_event->altKey;
|
ev.key.mod = dom2godot_mod(emscripten_event);
|
||||||
ev.key.mod.shift = emscripten_event->shiftKey;
|
|
||||||
ev.key.mod.control = emscripten_event->ctrlKey;
|
|
||||||
ev.key.mod.meta = emscripten_event->metaKey;
|
|
||||||
ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode);
|
ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode);
|
||||||
|
|
||||||
String unicode = String::utf8(emscripten_event->key);
|
String unicode = String::utf8(emscripten_event->key);
|
||||||
|
@ -167,7 +268,7 @@ static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *
|
||||||
deferred_key_event = ev;
|
deferred_key_event = ev;
|
||||||
return false; // do not suppress keypress event
|
return false; // do not suppress keypress event
|
||||||
}
|
}
|
||||||
static_cast<OS_JavaScript *>(user_data)->push_input(ev);
|
_input->parse_input_event(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +277,7 @@ static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent
|
||||||
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false);
|
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false);
|
||||||
|
|
||||||
deferred_key_event.key.unicode = key_event->charCode;
|
deferred_key_event.key.unicode = key_event->charCode;
|
||||||
static_cast<OS_JavaScript *>(user_data)->push_input(deferred_key_event);
|
_input->parse_input_event(deferred_key_event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +287,7 @@ static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *ke
|
||||||
|
|
||||||
InputEvent ev = _setup_key_event(key_event);
|
InputEvent ev = _setup_key_event(key_event);
|
||||||
ev.key.pressed = false;
|
ev.key.pressed = false;
|
||||||
static_cast<OS_JavaScript *>(user_data)->push_input(ev);
|
_input->parse_input_event(ev);
|
||||||
return ev.key.scancode != KEY_UNKNOWN && ev.key.scancode != 0;
|
return ev.key.scancode != KEY_UNKNOWN && ev.key.scancode != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +389,7 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
|
||||||
physics_2d_server->init();
|
physics_2d_server->init();
|
||||||
|
|
||||||
input = memnew(InputDefault);
|
input = memnew(InputDefault);
|
||||||
|
_input = input;
|
||||||
|
|
||||||
#define EM_CHECK(ev) \
|
#define EM_CHECK(ev) \
|
||||||
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
|
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
|
||||||
|
@ -300,6 +402,10 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
|
||||||
EM_CHECK(ev)
|
EM_CHECK(ev)
|
||||||
|
|
||||||
EMSCRIPTEN_RESULT result;
|
EMSCRIPTEN_RESULT result;
|
||||||
|
SET_EM_CALLBACK(mousemove, _mousemove_callback)
|
||||||
|
SET_EM_CALLBACK(mousedown, _mousebutton_callback)
|
||||||
|
SET_EM_CALLBACK(mouseup, _mousebutton_callback)
|
||||||
|
SET_EM_CALLBACK(wheel, _wheel_callback)
|
||||||
SET_EM_CALLBACK(keydown, _keydown_callback)
|
SET_EM_CALLBACK(keydown, _keydown_callback)
|
||||||
SET_EM_CALLBACK(keypress, _keypress_callback)
|
SET_EM_CALLBACK(keypress, _keypress_callback)
|
||||||
SET_EM_CALLBACK(keyup, _keyup_callback)
|
SET_EM_CALLBACK(keyup, _keyup_callback)
|
||||||
|
@ -544,18 +650,6 @@ void OS_JavaScript::main_loop_focusin() {
|
||||||
//audio_driver_javascript.set_pause(false);
|
//audio_driver_javascript.set_pause(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_JavaScript::push_input(const InputEvent &p_ev) {
|
|
||||||
|
|
||||||
InputEvent ev = p_ev;
|
|
||||||
ev.ID = last_id++;
|
|
||||||
if (ev.type == InputEvent::MOUSE_MOTION) {
|
|
||||||
input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
|
|
||||||
} else if (ev.type == InputEvent::MOUSE_BUTTON) {
|
|
||||||
last_button_mask = ev.mouse_button.button_mask;
|
|
||||||
}
|
|
||||||
input->parse_input_event(p_ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_JavaScript::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
|
void OS_JavaScript::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
|
||||||
|
|
||||||
// print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
|
// print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
|
||||||
|
|
|
@ -57,7 +57,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Vector<TouchPos> touch;
|
Vector<TouchPos> touch;
|
||||||
Point2 last_mouse;
|
Point2 last_mouse;
|
||||||
int last_button_mask;
|
|
||||||
unsigned int last_id;
|
unsigned int last_id;
|
||||||
GFXInitFunc gfx_init_func;
|
GFXInitFunc gfx_init_func;
|
||||||
void *gfx_init_ud;
|
void *gfx_init_ud;
|
||||||
|
|
Loading…
Reference in a new issue