Raw button event support, with X11 implementation (untransformed QWERTY)

This commit is contained in:
rdb 2014-03-07 12:52:15 +00:00
parent aa2c240336
commit 85a5be984f
10 changed files with 285 additions and 18 deletions

View File

@ -365,3 +365,25 @@ focus_lost(double time) {
}
_buttons_held.clear();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::raw_button_down
// Access: Public
// Description: Records that the indicated button has been depressed.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
raw_button_down(ButtonHandle button, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_down, time));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::raw_button_up
// Access: Public
// Description: Records that the indicated button has been released.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
raw_button_up(ButtonHandle button, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_up, time));
}

View File

@ -45,27 +45,27 @@ public:
static GraphicsWindowInputDevice pointer_only(GraphicsWindow *host, const string &name);
static GraphicsWindowInputDevice keyboard_only(GraphicsWindow *host, const string &name);
static GraphicsWindowInputDevice pointer_and_keyboard(GraphicsWindow *host, const string &name);
INLINE GraphicsWindowInputDevice();
GraphicsWindowInputDevice(const GraphicsWindowInputDevice &copy);
void operator = (const GraphicsWindowInputDevice &copy);
~GraphicsWindowInputDevice();
INLINE string get_name() const;
INLINE bool has_pointer() const;
INLINE bool has_keyboard() const;
INLINE void set_device_index(int index);
INLINE MouseData get_pointer() const;
INLINE MouseData get_raw_pointer() const;
INLINE void enable_pointer_events();
INLINE void disable_pointer_events();
void enable_pointer_mode(double speed);
void disable_pointer_mode();
bool has_button_event() const;
ButtonEvent get_button_event();
bool has_pointer_event() const;
@ -81,6 +81,8 @@ PUBLISHED:
void candidate(const wstring &candidate_string, size_t highlight_start,
size_t highlight_end, size_t cursor_pos);
void focus_lost(double time = ClockObject::get_global_clock()->get_frame_time());
void raw_button_down(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
void raw_button_up(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
INLINE void set_pointer_in_window(double x, double y, double time = ClockObject::get_global_clock()->get_frame_time());
INLINE void set_pointer_out_of_window(double time = ClockObject::get_global_clock()->get_frame_time());
@ -102,17 +104,17 @@ private:
typedef pdeque<ButtonEvent> ButtonEvents;
LightMutex _lock;
GraphicsWindow *_host;
string _name;
int _flags;
int _device_index;
int _event_sequence;
bool _pointer_mode_enable;
double _pointer_speed;
bool _enable_pointer_events;
MouseData _mouse_data;
MouseData _true_mouse_data;

View File

@ -55,6 +55,14 @@ output(ostream &out) const {
case T_move:
out << "move";
break;
case T_raw_down:
out << "raw button " << _button << " down";
break;
case T_raw_up:
out << "raw button " << _button << " up";
break;
}
}

View File

@ -81,10 +81,17 @@ public:
// from a menu.
T_candidate,
// T_move is used to indicate that the mouse has moved within the
// T_move is used to indicate that the mouse has moved within the
// current region. Button drag mode needs this, others may ignore
// this event
T_move,
// T_raw_down is usually sent together with T_down, except that
// this is the original, untransformed scan key sent by the keyboard.
// It is not altered by modifier keys and acts as if the user is
// using the US (qwerty) keyboard layout.
T_raw_down,
T_raw_up,
};
INLINE ButtonEvent();

View File

@ -200,6 +200,53 @@ get_move_event() const {
return _move_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_raw_button_down_event
// Access: Published
// Description: Like set_button_down_event, but uses the raw,
// untransformed scan key from the operating system.
// This uses buttons that are independent of the
// user's selected keyboard layout.
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_raw_button_down_event(const string &raw_button_down_event) {
_raw_button_down_event = raw_button_down_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_raw_button_down_event
// Access: Published
// Description: Returns the raw_button_down_event that has been set on
// this ButtonThrower. See set_raw_button_down_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_raw_button_down_event() const {
return _raw_button_down_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_raw_button_up_event
// Access: Published
// Description: Specifies the generic event that is generated (if
// any) each time a key or button is released. See
// set_raw_button_down_event().
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_raw_button_up_event(const string &raw_button_up_event) {
_raw_button_up_event = raw_button_up_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_raw_button_up_event
// Access: Published
// Description: Returns the raw_button_up_event that has been set on
// this ButtonThrower. See set_raw_button_up_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_raw_button_up_event() const {
return _raw_button_up_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_prefix
// Access: Published

View File

@ -268,16 +268,16 @@ void ButtonThrower::
do_specific_event(const string &event_name, double time) {
if (_specific_flag) {
PT(Event) event = new Event(_prefix + event_name);
if (_time_flag) {
event->add_parameter(time);
}
ParameterList::const_iterator pi;
for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
event->add_parameter(*pi);
}
throw_event(event);
}
}
@ -318,6 +318,14 @@ do_general_event(const ButtonEvent &button_event, const string &button_name) {
case ButtonEvent::T_move:
event_name = _move_event;
break;
case ButtonEvent::T_raw_down:
event_name = _raw_button_down_event;
break;
case ButtonEvent::T_raw_up:
event_name = _raw_button_up_event;
break;
}
if (event_name.empty()) {
// This general event is not configured.
@ -336,6 +344,8 @@ do_general_event(const ButtonEvent &button_event, const string &button_name) {
case ButtonEvent::T_resume_down:
case ButtonEvent::T_up:
case ButtonEvent::T_repeat:
case ButtonEvent::T_raw_down:
case ButtonEvent::T_raw_up:
event->add_parameter(button_name);
break;
@ -405,7 +415,7 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
do_specific_event(event_name, be._time);
}
do_general_event(be, event_name);
} else {
// Don't process this button; instead, pass it down to future
// generations.
@ -418,7 +428,7 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
// throw an event now (since we already missed it), but do
// make sure our modifiers are up-to-date.
_mods.button_down(be._button);
} else if (be._type == ButtonEvent::T_up) {
// Button up.
_mods.button_up(be._button);
@ -438,6 +448,34 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
_button_events->add_event(be);
}
} else if (be._type == ButtonEvent::T_raw_down) {
// Raw button down.
if (!_throw_buttons_active || has_throw_button(be._button)) {
// Process this button.
do_specific_event("raw-" + event_name, be._time);
do_general_event(be, event_name);
} else {
// Don't process this button; instead, pass it down to future
// generations.
_button_events->add_event(be);
}
} else if (be._type == ButtonEvent::T_raw_up) {
// Raw button up.
if (!_throw_buttons_active || has_throw_button(be._button)) {
// Process this button.
do_specific_event("raw-" + event_name + "-up", be._time);
do_general_event(be, event_name);
}
if (_throw_buttons_active) {
// Now pass the event on to future generations. We always
// pass "up" events, even if we are intercepting this
// particular button; unless we're processing all buttons in
// which case it doesn't matter.
_button_events->add_event(be);
}
} else {
// Some other kind of button event (e.g. keypress). Don't
// throw an event for this, but do pass it down.

View File

@ -53,6 +53,10 @@ PUBLISHED:
INLINE const string &get_candidate_event() const;
INLINE void set_move_event(const string &move_event);
INLINE const string &get_move_event() const;
INLINE void set_raw_button_down_event(const string &raw_button_down_event);
INLINE const string &get_raw_button_down_event() const;
INLINE void set_raw_button_up_event(const string &raw_button_up_event);
INLINE const string &get_raw_button_up_event() const;
INLINE void set_prefix(const string &prefix);
INLINE const string &get_prefix() const;
@ -61,7 +65,6 @@ PUBLISHED:
INLINE void set_time_flag(bool time_flag);
INLINE bool get_time_flag() const;
void add_parameter(const EventParameter &obj);
int get_num_parameters() const;
@ -85,7 +88,7 @@ public:
private:
void do_specific_event(const string &event_name, double time);
void do_general_event(const ButtonEvent &button_event,
void do_general_event(const ButtonEvent &button_event,
const string &event_name);
private:
@ -95,6 +98,8 @@ private:
string _keystroke_event;
string _candidate_event;
string _move_event;
string _raw_button_up_event;
string _raw_button_down_event;
bool _specific_flag;
string _prefix;
bool _time_flag;

View File

@ -1539,6 +1539,12 @@ do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
case ButtonEvent::T_move:
// This is handled below.
break;
case ButtonEvent::T_raw_down:
case ButtonEvent::T_raw_up:
// These are passed through.
new_button_events.add_event(be);
break;
}
}
}

View File

@ -1404,6 +1404,11 @@ handle_keypress(XKeyEvent &event) {
if (button != ButtonHandle::none()) {
_input_devices[0].button_down(button);
}
ButtonHandle raw_button = map_raw_button(event.keycode);
if (raw_button != ButtonHandle::none()) {
_input_devices[0].raw_button_down(raw_button);
}
}
////////////////////////////////////////////////////////////////////
@ -1432,6 +1437,11 @@ handle_keyrelease(XKeyEvent &event) {
if (button != ButtonHandle::none()) {
_input_devices[0].button_up(button);
}
ButtonHandle raw_button = map_raw_button(event.keycode);
if (raw_button != ButtonHandle::none()) {
_input_devices[0].raw_button_up(raw_button);
}
}
////////////////////////////////////////////////////////////////////
@ -1839,6 +1849,127 @@ map_button(KeySym key) {
return ButtonHandle::none();
}
////////////////////////////////////////////////////////////////////
// Function: x11GraphicsWindow::map_raw_button
// Access: Private
// Description: Maps from a single X keycode to Panda's ButtonHandle.
////////////////////////////////////////////////////////////////////
ButtonHandle x11GraphicsWindow::
map_raw_button(KeyCode key) {
switch (key) {
case 9: return KeyboardButton::escape();
case 10: return KeyboardButton::ascii_key('1');
case 11: return KeyboardButton::ascii_key('2');
case 12: return KeyboardButton::ascii_key('3');
case 13: return KeyboardButton::ascii_key('4');
case 14: return KeyboardButton::ascii_key('5');
case 15: return KeyboardButton::ascii_key('6');
case 16: return KeyboardButton::ascii_key('7');
case 17: return KeyboardButton::ascii_key('8');
case 18: return KeyboardButton::ascii_key('9');
case 19: return KeyboardButton::ascii_key('0');
case 20: return KeyboardButton::ascii_key('-');
case 21: return KeyboardButton::ascii_key('=');
case 22: return KeyboardButton::backspace();
case 23: return KeyboardButton::tab();
case 24: return KeyboardButton::ascii_key('q');
case 25: return KeyboardButton::ascii_key('w');
case 26: return KeyboardButton::ascii_key('e');
case 27: return KeyboardButton::ascii_key('r');
case 28: return KeyboardButton::ascii_key('t');
case 29: return KeyboardButton::ascii_key('y');
case 30: return KeyboardButton::ascii_key('u');
case 31: return KeyboardButton::ascii_key('i');
case 32: return KeyboardButton::ascii_key('o');
case 33: return KeyboardButton::ascii_key('p');
case 34: return KeyboardButton::ascii_key('[');
case 35: return KeyboardButton::ascii_key(']');
case 36: return KeyboardButton::enter();
case 37: return KeyboardButton::lcontrol();
case 38: return KeyboardButton::ascii_key('a');
case 39: return KeyboardButton::ascii_key('s');
case 40: return KeyboardButton::ascii_key('d');
case 41: return KeyboardButton::ascii_key('f');
case 42: return KeyboardButton::ascii_key('g');
case 43: return KeyboardButton::ascii_key('h');
case 44: return KeyboardButton::ascii_key('j');
case 45: return KeyboardButton::ascii_key('k');
case 46: return KeyboardButton::ascii_key('l');
case 47: return KeyboardButton::ascii_key(';');
case 48: return KeyboardButton::ascii_key('\'');
case 49: return KeyboardButton::ascii_key('`');
case 50: return KeyboardButton::lshift();
case 51: return KeyboardButton::ascii_key('\\');
case 52: return KeyboardButton::ascii_key('z');
case 53: return KeyboardButton::ascii_key('x');
case 54: return KeyboardButton::ascii_key('c');
case 55: return KeyboardButton::ascii_key('v');
case 56: return KeyboardButton::ascii_key('b');
case 57: return KeyboardButton::ascii_key('n');
case 58: return KeyboardButton::ascii_key('m');
case 59: return KeyboardButton::ascii_key(',');
case 60: return KeyboardButton::ascii_key('.');
case 61: return KeyboardButton::ascii_key('/');
case 62: return KeyboardButton::rshift();
case 63: return KeyboardButton::ascii_key('*');
case 64: return KeyboardButton::lalt();
case 65: return KeyboardButton::space();
case 66: return KeyboardButton::caps_lock();
case 67: return KeyboardButton::f1();
case 68: return KeyboardButton::f2();
case 69: return KeyboardButton::f3();
case 70: return KeyboardButton::f4();
case 71: return KeyboardButton::f5();
case 72: return KeyboardButton::f6();
case 73: return KeyboardButton::f7();
case 74: return KeyboardButton::f8();
case 75: return KeyboardButton::f9();
case 76: return KeyboardButton::f10();
case 77: return KeyboardButton::num_lock();
case 78: return KeyboardButton::scroll_lock();
case 79: return KeyboardButton::ascii_key('7');
case 80: return KeyboardButton::ascii_key('8');
case 81: return KeyboardButton::ascii_key('9');
case 82: return KeyboardButton::ascii_key('-');
case 83: return KeyboardButton::ascii_key('4');
case 84: return KeyboardButton::ascii_key('5');
case 85: return KeyboardButton::ascii_key('6');
case 86: return KeyboardButton::ascii_key('+');
case 87: return KeyboardButton::ascii_key('1');
case 88: return KeyboardButton::ascii_key('2');
case 89: return KeyboardButton::ascii_key('3');
case 90: return KeyboardButton::ascii_key('0');
case 91: return KeyboardButton::ascii_key('.');
case 95: return KeyboardButton::f11();
case 96: return KeyboardButton::f12();
case 104: return KeyboardButton::enter();
case 105: return KeyboardButton::rcontrol();
case 106: return KeyboardButton::ascii_key('/');
case 107: return KeyboardButton::print_screen();
case 108: return KeyboardButton::ralt();
case 110: return KeyboardButton::home();
case 111: return KeyboardButton::up();
case 112: return KeyboardButton::page_up();
case 113: return KeyboardButton::left();
case 114: return KeyboardButton::right();
case 115: return KeyboardButton::end();
case 116: return KeyboardButton::down();
case 117: return KeyboardButton::page_down();
case 118: return KeyboardButton::insert();
case 119: return KeyboardButton::del();
case 127: return KeyboardButton::pause();
//case 133: return KeyboardButton::lmeta();
//case 134: return KeyboardButton::rmeta();
//case 135: return KeyboardButton::menu();
}
return ButtonHandle::none();
}
////////////////////////////////////////////////////////////////////
// Function: x11GraphicsWindow::get_mouse_button
// Access: Private

View File

@ -67,6 +67,7 @@ protected:
ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift);
ButtonHandle map_button(KeySym key);
ButtonHandle map_raw_button(KeyCode key);
ButtonHandle get_mouse_button(XButtonEvent &button_event);
static Bool check_event(X11_Display *display, XEvent *event, char *arg);