mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
Add ButtonMap class / window.get_button_map() for querying keyboard layout + X11 implementation thereof
This commit is contained in:
parent
98ffa974ac
commit
b1e95feb3b
@ -77,8 +77,8 @@ GraphicsWindow::
|
||||
// Clean up python event handlers.
|
||||
#ifdef HAVE_PYTHON
|
||||
PythonWinProcClasses::iterator iter;
|
||||
for (iter = _python_window_proc_classes.begin();
|
||||
iter != _python_window_proc_classes.end();
|
||||
for (iter = _python_window_proc_classes.begin();
|
||||
iter != _python_window_proc_classes.end();
|
||||
++iter) {
|
||||
delete *iter;
|
||||
}
|
||||
@ -340,6 +340,17 @@ has_keyboard(int device) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::get_keyboard_map
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a ButtonMap containing the association
|
||||
// between raw buttons and virtual buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonMap *GraphicsWindow::
|
||||
get_keyboard_map() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::enable_pointer_events
|
||||
// Access: Published
|
||||
@ -391,8 +402,10 @@ disable_pointer_mode(int device) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer
|
||||
// Access: Published
|
||||
// Description: Returns the MouseData associated with the nth input
|
||||
// device's pointer.
|
||||
// Description: Returns the MouseData associated with the nth
|
||||
// input device's pointer. This is deprecated; use
|
||||
// get_pointer_device().get_pointer() instead, or for
|
||||
// raw mice, use the InputDeviceManager interface.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MouseData GraphicsWindow::
|
||||
get_pointer(int device) const {
|
||||
@ -409,7 +422,7 @@ get_pointer(int device) const {
|
||||
// Function: GraphicsWindow::move_pointer
|
||||
// Access: Published, Virtual
|
||||
// Description: Forces the pointer to the indicated position within
|
||||
// the window, if possible.
|
||||
// the window, if possible.
|
||||
//
|
||||
// Returns true if successful, false on failure. This
|
||||
// may fail if the mouse is not currently within the
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "modifierButtons.h"
|
||||
#include "buttonEvent.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "buttonMap.h"
|
||||
#include "pnotify.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
@ -82,7 +83,7 @@ PUBLISHED:
|
||||
MAKE_SEQ(get_input_device_names, get_num_input_devices, get_input_device_name);
|
||||
bool has_pointer(int device) const;
|
||||
bool has_keyboard(int device) const;
|
||||
|
||||
virtual ButtonMap *get_keyboard_map() const;
|
||||
|
||||
void enable_pointer_events(int device);
|
||||
void disable_pointer_events(int device);
|
||||
|
@ -21,8 +21,9 @@
|
||||
bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
buttonHandle.I \
|
||||
buttonHandle.h buttonRegistry.I buttonRegistry.h \
|
||||
buttonHandle.I buttonHandle.h \
|
||||
buttonMap.I buttonMap.h \
|
||||
buttonRegistry.I buttonRegistry.h \
|
||||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
callbackData.h callbackData.I \
|
||||
callbackObject.h callbackObject.I \
|
||||
@ -84,7 +85,7 @@
|
||||
bamWriter.cxx \
|
||||
bitArray.cxx \
|
||||
bitMask.cxx \
|
||||
buttonHandle.cxx buttonRegistry.cxx \
|
||||
buttonHandle.cxx buttonMap.cxx buttonRegistry.cxx \
|
||||
cachedTypedWritableReferenceCount.cxx \
|
||||
callbackData.cxx \
|
||||
callbackObject.cxx \
|
||||
@ -132,8 +133,9 @@
|
||||
bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
buttonHandle.I buttonHandle.h buttonRegistry.I \
|
||||
buttonRegistry.h \
|
||||
buttonHandle.I buttonHandle.h \
|
||||
buttonMap.I buttonMap.h \
|
||||
buttonRegistry.I buttonRegistry.h \
|
||||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
callbackData.h callbackData.I \
|
||||
callbackObject.h callbackObject.I \
|
||||
|
141
panda/src/putil/buttonMap.I
Normal file
141
panda/src/putil/buttonMap.I
Normal file
@ -0,0 +1,141 @@
|
||||
// Filename: buttonMap.I
|
||||
// Created by: rdb (09Mar14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_num_buttons
|
||||
// Access: Published
|
||||
// Description: Returns the number of buttons that this button
|
||||
// mapping specifies.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ButtonMap::
|
||||
get_num_buttons() const {
|
||||
return _buttons.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_raw_button
|
||||
// Access: Published
|
||||
// Description: Returns the underlying raw button associated with
|
||||
// the nth button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonMap::
|
||||
get_raw_button(int i) const {
|
||||
return _buttons[i]->_raw;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_mapped_button
|
||||
// Access: Published
|
||||
// Description: Returns the nth mapped button, meaning the button
|
||||
// that the nth raw button is mapped to.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonMap::
|
||||
get_mapped_button(int i) const {
|
||||
return _buttons[i]->_mapped;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_mapped_button_text
|
||||
// Access: Published
|
||||
// Description: Returns the text associated with the nth mapped
|
||||
// button, meaning the button that the nth raw
|
||||
// button is mapped to.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &ButtonMap::
|
||||
get_mapped_button_text(int i) const {
|
||||
return _buttons[i]->_text;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_mapped_button
|
||||
// Access: Published
|
||||
// Description: Returns the button that the given button is mapped
|
||||
// to, or ButtonHandle::none() if this map does not
|
||||
// specify a mapped button for the given raw button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonMap::
|
||||
get_mapped_button(ButtonHandle raw) const {
|
||||
pmap<int, ButtonNode>::const_iterator it;
|
||||
it = _button_map.find(raw.get_index());
|
||||
if (it == _button_map.end()) {
|
||||
return ButtonHandle::none();
|
||||
} else {
|
||||
return it->second._mapped;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::get_mapped_button
|
||||
// Access: Published
|
||||
// Description: Returns the button that the given button is mapped
|
||||
// to, or ButtonHandle::none() if this map does not
|
||||
// specify a mapped button for the given raw button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonMap::
|
||||
get_mapped_button(const string &raw_name) const {
|
||||
ButtonHandle raw_button = ButtonRegistry::ptr()->find_button(raw_name);
|
||||
if (raw_button == ButtonHandle::none()) {
|
||||
return ButtonHandle::none();
|
||||
} else {
|
||||
return get_mapped_button(raw_button);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtoMap::get_mapped_button_text
|
||||
// Access: Published
|
||||
// Description: If the button map specifies a special name for the
|
||||
// button (eg. if the operating system or keyboard
|
||||
// device has a localized name describing the key),
|
||||
// returns it, or the empty string otherwise.
|
||||
//
|
||||
// Note that this is not the same as
|
||||
// get_mapped_button().get_name(), which returns the
|
||||
// name of the Panda event associated with the button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &ButtonMap::
|
||||
get_mapped_button_text(ButtonHandle raw) const {
|
||||
pmap<int, ButtonNode>::const_iterator it;
|
||||
it = _button_map.find(raw.get_index());
|
||||
if (it == _button_map.end()) {
|
||||
static const string empty = "";
|
||||
return empty;
|
||||
} else {
|
||||
return it->second._text;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtoMap::get_mapped_button_text
|
||||
// Access: Published
|
||||
// Description: If the button map specifies a special name for the
|
||||
// button (eg. if the operating system or keyboard
|
||||
// device has a localized name describing the key),
|
||||
// returns it, or the empty string otherwise.
|
||||
//
|
||||
// Note that this is not the same as
|
||||
// get_mapped_button().get_name(), which returns the
|
||||
// name of the Panda event associated with the button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &ButtonMap::
|
||||
get_mapped_button_text(const string &raw_name) const {
|
||||
ButtonHandle raw_button = ButtonRegistry::ptr()->find_button(raw_name);
|
||||
if (raw_button == ButtonHandle::none()) {
|
||||
static const string empty = "";
|
||||
return empty;
|
||||
} else {
|
||||
return get_mapped_button_text(raw_button);
|
||||
}
|
||||
}
|
33
panda/src/putil/buttonMap.cxx
Normal file
33
panda/src/putil/buttonMap.cxx
Normal file
@ -0,0 +1,33 @@
|
||||
// Filename: buttonMap.cxx
|
||||
// Created by: rdb (09Mar14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "buttonMap.h"
|
||||
|
||||
TypeHandle ButtonMap::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonMap::map_button
|
||||
// Access: Public
|
||||
// Description: Registers a new button mapping.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ButtonMap::
|
||||
map_button(ButtonHandle raw_button, ButtonHandle button, const string &text) {
|
||||
int index = raw_button.get_index();
|
||||
ButtonNode bnode;
|
||||
bnode._raw = raw_button;
|
||||
bnode._mapped = button;
|
||||
bnode._text = text;
|
||||
_button_map[index] = bnode;
|
||||
_buttons.push_back(&_button_map[index]);
|
||||
}
|
78
panda/src/putil/buttonMap.h
Normal file
78
panda/src/putil/buttonMap.h
Normal file
@ -0,0 +1,78 @@
|
||||
// Filename: buttonMap.h
|
||||
// Created by: rdb (07Mar14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BUTTONMAP_H
|
||||
#define BUTTONMAP_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "buttonHandle.h"
|
||||
#include "buttonRegistry.h"
|
||||
#include "pmap.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ButtonMap
|
||||
// Description : This class represents a map containing all of the
|
||||
// buttons of a (keyboard) device, though it can also
|
||||
// be used as a generic mapping between ButtonHandles.
|
||||
// It maps an underlying 'raw' button to a 'virtual'
|
||||
// button, which may optionally be associated with an
|
||||
// appropriate platform-specific name for the button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ButtonMap : public TypedReferenceCount {
|
||||
PUBLISHED:
|
||||
INLINE int get_num_buttons() const;
|
||||
INLINE ButtonHandle get_raw_button(int i) const;
|
||||
INLINE ButtonHandle get_mapped_button(int i) const;
|
||||
INLINE const string &get_mapped_button_text(int i) const;
|
||||
|
||||
INLINE ButtonHandle get_mapped_button(ButtonHandle raw) const;
|
||||
INLINE ButtonHandle get_mapped_button(const string &raw_name) const;
|
||||
INLINE const string &get_mapped_button_text(ButtonHandle raw) const;
|
||||
INLINE const string &get_mapped_button_text(const string &raw_name) const;
|
||||
|
||||
public:
|
||||
void map_button(ButtonHandle raw_button, ButtonHandle button, const string &text = "");
|
||||
|
||||
private:
|
||||
struct ButtonNode {
|
||||
ButtonHandle _raw;
|
||||
ButtonHandle _mapped;
|
||||
string _text;
|
||||
};
|
||||
|
||||
pmap<int, ButtonNode> _button_map;
|
||||
pvector<ButtonNode*> _buttons;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "ButtonMap",
|
||||
TypedReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "buttonMap.I"
|
||||
|
||||
#endif
|
@ -131,6 +131,25 @@ get_button(const string &name) {
|
||||
return button;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::find_button
|
||||
// Access: Published
|
||||
// Description: Finds a ButtonHandle in the registry matching the
|
||||
// indicated name. If there is no such ButtonHandle,
|
||||
// returns ButtonHandle::none().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle ButtonRegistry::
|
||||
find_button(const string &name) {
|
||||
NameRegistry::const_iterator ri;
|
||||
ri = _name_registry.find(name);
|
||||
|
||||
if (ri != _name_registry.end()) {
|
||||
return (*ri).second->_handle;
|
||||
}
|
||||
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::find_ascii_button
|
||||
// Access: Published
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
|
||||
PUBLISHED:
|
||||
ButtonHandle get_button(const string &name);
|
||||
ButtonHandle find_button(const string &name);
|
||||
ButtonHandle find_ascii_button(char ascii_equivalent) const;
|
||||
|
||||
void write(ostream &out) const;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "bitArray.h"
|
||||
#include "bitMask.h"
|
||||
#include "buttonHandle.h"
|
||||
#include "buttonMap.h"
|
||||
#include "cachedTypedWritableReferenceCount.h"
|
||||
#include "callbackData.h"
|
||||
#include "callbackObject.h"
|
||||
@ -186,6 +187,7 @@ init_libputil() {
|
||||
BitMask32::init_type();
|
||||
BitMask64::init_type();
|
||||
ButtonHandle::init_type();
|
||||
ButtonMap::init_type();
|
||||
CPointerCallbackObject::init_type();
|
||||
CachedTypedWritableReferenceCount::init_type();
|
||||
CallbackData::init_type();
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "bitArray.cxx"
|
||||
#include "bitMask.cxx"
|
||||
#include "buttonHandle.cxx"
|
||||
#include "buttonMap.cxx"
|
||||
#include "buttonRegistry.cxx"
|
||||
#include "cachedTypedWritableReferenceCount.cxx"
|
||||
#include "callbackData.cxx"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "graphicsPipe.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "mouseButton.h"
|
||||
#include "buttonMap.h"
|
||||
#include "clockObject.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "textEncoder.h"
|
||||
@ -1545,8 +1546,10 @@ get_button(XKeyEvent &key_event, bool allow_shift) {
|
||||
// Called by get_button(), above.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle x11GraphicsWindow::
|
||||
map_button(KeySym key) {
|
||||
map_button(KeySym key) const {
|
||||
switch (key) {
|
||||
case NoSymbol:
|
||||
return ButtonHandle::none();
|
||||
case XK_BackSpace:
|
||||
return KeyboardButton::backspace();
|
||||
case XK_Tab:
|
||||
@ -1864,7 +1867,7 @@ map_button(KeySym key) {
|
||||
// Description: Maps from a single X keycode to Panda's ButtonHandle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle x11GraphicsWindow::
|
||||
map_raw_button(KeyCode key) {
|
||||
map_raw_button(KeyCode key) const {
|
||||
switch (key) {
|
||||
case 9: return KeyboardButton::escape();
|
||||
case 10: return KeyboardButton::ascii_key('1');
|
||||
@ -2001,6 +2004,36 @@ get_mouse_button(XButtonEvent &button_event) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::get_keyboard_map
|
||||
// Access: Private, Virtual
|
||||
// Description: Returns a ButtonMap containing the association
|
||||
// between raw buttons and virtual buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonMap *x11GraphicsWindow::
|
||||
get_keyboard_map() const {
|
||||
// NB. This could be improved by using the Xkb API.
|
||||
//XkbDescPtr desc = XkbGetMap(_display, XkbAllMapComponentsMask, XkbUseCoreKbd);
|
||||
ButtonMap *map = new ButtonMap;
|
||||
|
||||
for (int k = 9; k <= 135; ++k) {
|
||||
ButtonHandle raw_button = map_raw_button(k);
|
||||
if (raw_button == ButtonHandle::none()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KeySym sym = XKeycodeToKeysym(_display, k, 0);
|
||||
ButtonHandle button = map_button(sym);
|
||||
if (button == ButtonHandle::none()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
map->map_button(raw_button, button, name);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::check_event
|
||||
// Access: Private, Static
|
||||
|
@ -66,9 +66,10 @@ protected:
|
||||
void handle_keyrelease(XKeyEvent &event);
|
||||
|
||||
ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift);
|
||||
ButtonHandle map_button(KeySym key);
|
||||
ButtonHandle map_raw_button(KeyCode key);
|
||||
ButtonHandle map_button(KeySym key) const;
|
||||
ButtonHandle map_raw_button(KeyCode key) const;
|
||||
ButtonHandle get_mouse_button(XButtonEvent &button_event);
|
||||
virtual ButtonMap *get_keyboard_map() const;
|
||||
|
||||
static Bool check_event(X11_Display *display, XEvent *event, char *arg);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user