mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
Add physical_scancode
(keyboard layout independent keycodes) to InputEventKey and InputMap.
Fix non-latin keyboard layout keycodes on Linux/X11 (fallback to physical keycodes).
This commit is contained in:
parent
63391f645c
commit
dab4cf3ed6
@ -216,6 +216,13 @@ uint32_t InputEventKey::get_scancode() const {
|
||||
return scancode;
|
||||
}
|
||||
|
||||
void InputEventKey::set_physical_scancode(uint32_t p_scancode) {
|
||||
physical_scancode = p_scancode;
|
||||
}
|
||||
uint32_t InputEventKey::get_physical_scancode() const {
|
||||
return physical_scancode;
|
||||
}
|
||||
|
||||
void InputEventKey::set_unicode(uint32_t p_unicode) {
|
||||
unicode = p_unicode;
|
||||
}
|
||||
@ -248,6 +255,20 @@ uint32_t InputEventKey::get_scancode_with_modifiers() const {
|
||||
return sc;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_physical_scancode_with_modifiers() const {
|
||||
uint32_t sc = physical_scancode;
|
||||
if (get_control())
|
||||
sc |= KEY_MASK_CTRL;
|
||||
if (get_alt())
|
||||
sc |= KEY_MASK_ALT;
|
||||
if (get_shift())
|
||||
sc |= KEY_MASK_SHIFT;
|
||||
if (get_metakey())
|
||||
sc |= KEY_MASK_META;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
String InputEventKey::as_text() const {
|
||||
String kc = keycode_get_string(scancode);
|
||||
if (kc == String()) {
|
||||
@ -275,10 +296,19 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t code = get_scancode_with_modifiers();
|
||||
uint32_t event_code = key->get_scancode_with_modifiers();
|
||||
bool match = false;
|
||||
if (get_scancode() == 0) {
|
||||
uint32_t code = get_physical_scancode_with_modifiers();
|
||||
uint32_t event_code = key->get_physical_scancode_with_modifiers();
|
||||
|
||||
match = get_physical_scancode() == key->get_physical_scancode() && (!key->is_pressed() || (code & event_code) == code);
|
||||
} else {
|
||||
uint32_t code = get_scancode_with_modifiers();
|
||||
uint32_t event_code = key->get_scancode_with_modifiers();
|
||||
|
||||
match = get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code);
|
||||
}
|
||||
|
||||
bool match = get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code);
|
||||
if (match) {
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = key->is_pressed();
|
||||
@ -308,15 +338,20 @@ void InputEventKey::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_scancode", "scancode"), &InputEventKey::set_scancode);
|
||||
ClassDB::bind_method(D_METHOD("get_scancode"), &InputEventKey::get_scancode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_physical_scancode", "scancode"), &InputEventKey::set_physical_scancode);
|
||||
ClassDB::bind_method(D_METHOD("get_physical_scancode"), &InputEventKey::get_physical_scancode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_unicode", "unicode"), &InputEventKey::set_unicode);
|
||||
ClassDB::bind_method(D_METHOD("get_unicode"), &InputEventKey::get_unicode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_scancode_with_modifiers"), &InputEventKey::get_scancode_with_modifiers);
|
||||
ClassDB::bind_method(D_METHOD("get_physical_scancode_with_modifiers"), &InputEventKey::get_physical_scancode_with_modifiers);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "scancode"), "set_scancode", "get_scancode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "physical_scancode"), "set_physical_scancode", "get_physical_scancode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "echo"), "set_echo", "is_echo");
|
||||
}
|
||||
@ -324,6 +359,7 @@ void InputEventKey::_bind_methods() {
|
||||
InputEventKey::InputEventKey() {
|
||||
pressed = false;
|
||||
scancode = 0;
|
||||
physical_scancode = 0;
|
||||
unicode = 0; ///unicode
|
||||
echo = false;
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ class InputEventKey : public InputEventWithModifiers {
|
||||
bool pressed; /// otherwise release
|
||||
|
||||
uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks
|
||||
uint32_t physical_scancode;
|
||||
uint32_t unicode; ///unicode
|
||||
|
||||
bool echo; /// true if this is an echo key
|
||||
@ -283,6 +284,9 @@ public:
|
||||
void set_scancode(uint32_t p_scancode);
|
||||
uint32_t get_scancode() const;
|
||||
|
||||
void set_physical_scancode(uint32_t p_scancode);
|
||||
uint32_t get_physical_scancode() const;
|
||||
|
||||
void set_unicode(uint32_t p_unicode);
|
||||
uint32_t get_unicode() const;
|
||||
|
||||
@ -290,6 +294,7 @@ public:
|
||||
virtual bool is_echo() const;
|
||||
|
||||
uint32_t get_scancode_with_modifiers() const;
|
||||
uint32_t get_physical_scancode_with_modifiers() const;
|
||||
|
||||
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const;
|
||||
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
|
||||
|
@ -10,6 +10,14 @@
|
||||
<link>https://docs.godotengine.org/en/3.3/tutorials/inputs/inputevent.html</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="get_physical_scancode_with_modifiers" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
Returns the physical scancode combined with modifier keys such as [code]Shift[/code] or [code]Alt[/code]. See also [InputEventWithModifiers].
|
||||
To get a human-readable representation of the [InputEventKey] with modifiers, use [code]OS.get_scancode_string(event.get_physical_scancode_with_modifiers())[/code] where [code]event[/code] is the [InputEventKey].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_scancode_with_modifiers" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
@ -23,11 +31,15 @@
|
||||
<member name="echo" type="bool" setter="set_echo" getter="is_echo" default="false">
|
||||
If [code]true[/code], the key was already pressed before this event. It means the user is holding the key down.
|
||||
</member>
|
||||
<member name="physical_scancode" type="int" setter="set_physical_scancode" getter="get_physical_scancode" default="0">
|
||||
Key physical scancode, which corresponds to one of the [enum KeyList] constants. Represent the physical location of a key on the 101/102-key US QWERTY keyboard.
|
||||
To get a human-readable representation of the [InputEventKey], use [code]OS.get_scancode_string(event.physical_scancode)[/code] where [code]event[/code] is the [InputEventKey].
|
||||
</member>
|
||||
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false">
|
||||
If [code]true[/code], the key's state is pressed. If [code]false[/code], the key's state is released.
|
||||
</member>
|
||||
<member name="scancode" type="int" setter="set_scancode" getter="get_scancode" default="0">
|
||||
The key scancode, which corresponds to one of the [enum KeyList] constants.
|
||||
The key scancode, which corresponds to one of the [enum KeyList] constants. Represent key in the current keyboard layout.
|
||||
To get a human-readable representation of the [InputEventKey], use [code]OS.get_scancode_string(event.scancode)[/code] where [code]event[/code] is the [InputEventKey].
|
||||
</member>
|
||||
<member name="unicode" type="int" setter="set_unicode" getter="get_unicode" default="0">
|
||||
|
@ -1 +1 @@
|
||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m4 2a1 1 0 0 0 -1 1v9.084a1 .91667 0 0 0 1 .91602h8a1 .91667 0 0 0 1-.91602v-9.084a1 1 0 0 0 -1-1zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a.99998.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9zm4 0h2v3l2-3h2l-2 3 2 4h-2l-2-4v4h-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m27 1038.4h7v14h-7z" fill="#fff"/></g></svg>
|
||||
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm1.543 1.139h1.393l1.834 4.199h1.295v.437c.708.052 1.246.239 1.61.559.368.316.55.747.55 1.295 0 .552-.182.99-.55 1.314-.368.32-.906.505-1.61.553v.467h-1.294v-.473c-.708-.06-1.247-.248-1.615-.564-.364-.316-.545-.75-.545-1.297 0-.548.181-.977.545-1.29.368-.315.907-.504 1.615-.564v-.437h-1.464l-.282-.733h-1.595l-.284.733h-1.439l1.836-4.2zm.684 1.39-.409 1.057h.817zm3.84 4.338v1.526c.28-.04.483-.12.607-.24.124-.125.185-.302.185-.53 0-.224-.063-.396-.191-.516-.124-.12-.326-.2-.602-.24zm-1.296.006c-.284.04-.487.12-.61.24-.12.116-.182.288-.182.516 0 .22.065.392.193.512.132.12.331.202.6.246v-1.514z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 482 B After Width: | Height: | Size: 961 B |
1
editor/icons/icon_keyboard_physical.svg
Normal file
1
editor/icons/icon_keyboard_physical.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm2.762 1.768h2.476l3.264 7.464h-2.604l-.502-1.3h-2.835l-.502 1.3h-2.561zm1.217 2.474-.725 1.878h1.45z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg>
|
After Width: | Height: | Size: 465 B |
@ -114,6 +114,7 @@ void ProjectSettingsEditor::_notification(int p_what) {
|
||||
translation_list->connect("button_pressed", this, "_translation_delete");
|
||||
_update_actions();
|
||||
popup_add->add_icon_item(get_icon("Keyboard", "EditorIcons"), TTR("Key "), INPUT_KEY); //"Key " - because the word 'key' has already been used as a key animation
|
||||
popup_add->add_icon_item(get_icon("KeyboardPhysical", "EditorIcons"), TTR("Physical Key"), INPUT_KEY_PHYSICAL);
|
||||
popup_add->add_icon_item(get_icon("JoyButton", "EditorIcons"), TTR("Joy Button"), INPUT_JOY_BUTTON);
|
||||
popup_add->add_icon_item(get_icon("JoyAxis", "EditorIcons"), TTR("Joy Axis"), INPUT_JOY_MOTION);
|
||||
popup_add->add_icon_item(get_icon("Mouse", "EditorIcons"), TTR("Mouse Button"), INPUT_MOUSE_BUTTON);
|
||||
@ -147,6 +148,7 @@ void ProjectSettingsEditor::_notification(int p_what) {
|
||||
search_box->set_clear_button_enabled(true);
|
||||
action_add_error->add_color_override("font_color", get_color("error_color", "Editor"));
|
||||
popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY), get_icon("Keyboard", "EditorIcons"));
|
||||
popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY_PHYSICAL), get_icon("KeyboardPhysical", "EditorIcons"));
|
||||
popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_BUTTON), get_icon("JoyButton", "EditorIcons"));
|
||||
popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_MOTION), get_icon("JoyAxis", "EditorIcons"));
|
||||
popup_add->set_item_icon(popup_add->get_item_index(INPUT_MOUSE_BUTTON), get_icon("Mouse", "EditorIcons"));
|
||||
@ -357,7 +359,14 @@ void ProjectSettingsEditor::_press_a_key_confirm() {
|
||||
|
||||
Ref<InputEventKey> ie;
|
||||
ie.instance();
|
||||
ie->set_scancode(last_wait_for_key->get_scancode());
|
||||
if (press_a_key_physical) {
|
||||
ie->set_physical_scancode(last_wait_for_key->get_physical_scancode());
|
||||
ie->set_scancode(0);
|
||||
} else {
|
||||
ie->set_physical_scancode(0);
|
||||
ie->set_scancode(last_wait_for_key->get_scancode());
|
||||
}
|
||||
|
||||
ie->set_shift(last_wait_for_key->get_shift());
|
||||
ie->set_alt(last_wait_for_key->get_alt());
|
||||
ie->set_control(last_wait_for_key->get_control());
|
||||
@ -375,8 +384,14 @@ void ProjectSettingsEditor::_press_a_key_confirm() {
|
||||
if (aie.is_null()) {
|
||||
continue;
|
||||
}
|
||||
if (aie->get_scancode_with_modifiers() == ie->get_scancode_with_modifiers()) {
|
||||
return;
|
||||
if (!press_a_key_physical) {
|
||||
if (aie->get_scancode_with_modifiers() == ie->get_scancode_with_modifiers()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (aie->get_physical_scancode_with_modifiers() == ie->get_physical_scancode_with_modifiers()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,7 +459,7 @@ void ProjectSettingsEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
|
||||
|
||||
if (k.is_valid() && k->is_pressed() && k->get_scancode() != 0) {
|
||||
last_wait_for_key = p_event;
|
||||
const String str = keycode_get_string(k->get_scancode_with_modifiers());
|
||||
const String str = (press_a_key_physical) ? keycode_get_string(k->get_physical_scancode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_scancode_with_modifiers());
|
||||
|
||||
press_a_key_label->set_text(str);
|
||||
press_a_key->get_ok()->set_disabled(false);
|
||||
@ -457,12 +472,20 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
|
||||
|
||||
switch (add_type) {
|
||||
case INPUT_KEY: {
|
||||
press_a_key_physical = false;
|
||||
press_a_key_label->set_text(TTR("Press a Key..."));
|
||||
press_a_key->get_ok()->set_disabled(true);
|
||||
last_wait_for_key = Ref<InputEvent>();
|
||||
press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
|
||||
press_a_key->grab_focus();
|
||||
} break;
|
||||
case INPUT_KEY_PHYSICAL: {
|
||||
press_a_key_physical = true;
|
||||
press_a_key_label->set_text(TTR("Press a Key..."));
|
||||
press_a_key->get_ok()->set_disabled(true);
|
||||
last_wait_for_key = Ref<InputEvent>();
|
||||
press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
|
||||
press_a_key->grab_focus();
|
||||
|
||||
} break;
|
||||
case INPUT_MOUSE_BUTTON: {
|
||||
device_index_label->set_text(TTR("Mouse Button Index:"));
|
||||
@ -538,7 +561,11 @@ void ProjectSettingsEditor::_edit_item(Ref<InputEvent> p_exiting_event) {
|
||||
InputType ie_type;
|
||||
|
||||
if ((Ref<InputEventKey>(p_exiting_event)).is_valid()) {
|
||||
ie_type = INPUT_KEY;
|
||||
if ((Ref<InputEventKey>(p_exiting_event))->get_scancode() != 0) {
|
||||
ie_type = INPUT_KEY;
|
||||
} else {
|
||||
ie_type = INPUT_KEY_PHYSICAL;
|
||||
}
|
||||
|
||||
} else if ((Ref<InputEventJoypadButton>(p_exiting_event)).is_valid()) {
|
||||
ie_type = INPUT_JOY_BUTTON;
|
||||
@ -729,10 +756,13 @@ void ProjectSettingsEditor::_update_actions() {
|
||||
|
||||
Ref<InputEventKey> k = event;
|
||||
if (k.is_valid()) {
|
||||
const String str = keycode_get_string(k->get_scancode_with_modifiers());
|
||||
|
||||
const String str = (k->get_scancode() == 0) ? keycode_get_string(k->get_physical_scancode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_scancode_with_modifiers());
|
||||
action2->set_text(0, str);
|
||||
action2->set_icon(0, get_icon("Keyboard", "EditorIcons"));
|
||||
if ((k->get_scancode() != 0)) {
|
||||
action2->set_icon(0, get_icon("Keyboard", "EditorIcons"));
|
||||
} else {
|
||||
action2->set_icon(0, get_icon("KeyboardPhysical", "EditorIcons"));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventJoypadButton> jb = event;
|
||||
@ -1925,6 +1955,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
||||
add_child(popup_add);
|
||||
popup_add->connect("id_pressed", this, "_add_item");
|
||||
|
||||
press_a_key_physical = false;
|
||||
|
||||
press_a_key = memnew(ConfirmationDialog);
|
||||
press_a_key->set_focus_mode(FOCUS_ALL);
|
||||
add_child(press_a_key);
|
||||
|
@ -45,6 +45,7 @@ class ProjectSettingsEditor : public AcceptDialog {
|
||||
|
||||
enum InputType {
|
||||
INPUT_KEY,
|
||||
INPUT_KEY_PHYSICAL,
|
||||
INPUT_JOY_BUTTON,
|
||||
INPUT_JOY_MOTION,
|
||||
INPUT_MOUSE_BUTTON
|
||||
@ -76,6 +77,7 @@ class ProjectSettingsEditor : public AcceptDialog {
|
||||
OptionButton *type;
|
||||
PopupMenu *popup_add;
|
||||
ConfirmationDialog *press_a_key;
|
||||
bool press_a_key_physical;
|
||||
Label *press_a_key_label;
|
||||
ConfirmationDialog *device_input;
|
||||
OptionButton *device_id;
|
||||
|
@ -1056,8 +1056,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||
int keyCode;
|
||||
if ((keyCode = cc[i]) != 0) {
|
||||
// Simulate key down and up...
|
||||
GodotLib.key(0, keyCode, true);
|
||||
GodotLib.key(0, keyCode, false);
|
||||
GodotLib.key(0, 0, keyCode, true);
|
||||
GodotLib.key(0, 0, keyCode, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ public class GodotLib {
|
||||
/**
|
||||
* Forward regular key events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
|
||||
public static native void key(int p_keycode, int p_scancode, int p_unicode_char, boolean p_pressed);
|
||||
|
||||
/**
|
||||
* Forward game device's key events from the main thread to the GL thread.
|
||||
|
@ -109,11 +109,12 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
final int scanCode = event.getScanCode();
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.key(keyCode, chr, false);
|
||||
GodotLib.key(keyCode, scanCode, chr, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -154,11 +155,12 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
final int scanCode = event.getScanCode();
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.key(keyCode, chr, true);
|
||||
GodotLib.key(keyCode, scanCode, chr, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
|
||||
|
||||
if (mHasSelection) {
|
||||
mHasSelection = false;
|
||||
@ -127,8 +127,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
// Return keys are handled through action events
|
||||
continue;
|
||||
}
|
||||
GodotLib.key(0, key, true);
|
||||
GodotLib.key(0, key, false);
|
||||
GodotLib.key(0, 0, key, true);
|
||||
GodotLib.key(0, 0, key, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -144,8 +144,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
public void run() {
|
||||
for (int i = 0; i < characters.length(); i++) {
|
||||
final int ch = characters.codePointAt(i);
|
||||
GodotLib.key(0, ch, true);
|
||||
GodotLib.key(0, ch, false);
|
||||
GodotLib.key(0, 0, ch, true);
|
||||
GodotLib.key(0, 0, ch, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -153,8 +153,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
|
||||
if (pActionID == EditorInfo.IME_ACTION_DONE) {
|
||||
// Enter key has been pressed
|
||||
GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, false);
|
||||
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
|
||||
|
||||
this.mView.requestFocus();
|
||||
return true;
|
||||
|
@ -376,11 +376,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
os_android->process_key_event(p_scancode, p_unicode_char, p_pressed);
|
||||
os_android->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) {
|
||||
|
@ -51,7 +51,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNI
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y);
|
||||
|
@ -340,11 +340,12 @@ void OS_Android::process_event(Ref<InputEvent> p_event) {
|
||||
input->parse_input_event(p_event);
|
||||
}
|
||||
|
||||
void OS_Android::process_key_event(int p_scancode, int p_unicode_char, bool p_pressed) {
|
||||
void OS_Android::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
|
||||
Ref<InputEventKey> ev;
|
||||
ev.instance();
|
||||
int val = p_unicode_char;
|
||||
unsigned int scancode = android_get_keysym(p_scancode);
|
||||
unsigned int scancode = android_get_keysym(p_keycode);
|
||||
unsigned int phy_scancode = android_get_keysym(p_scancode);
|
||||
|
||||
switch (scancode) {
|
||||
case KEY_SHIFT: {
|
||||
@ -362,6 +363,8 @@ void OS_Android::process_key_event(int p_scancode, int p_unicode_char, bool p_pr
|
||||
}
|
||||
|
||||
ev->set_scancode(scancode);
|
||||
ev->set_physical_scancode(phy_scancode);
|
||||
|
||||
ev->set_unicode(val);
|
||||
ev->set_pressed(p_pressed);
|
||||
|
||||
|
@ -208,7 +208,7 @@ public:
|
||||
void process_double_tap(int event_android_button_mask, Point2 p_pos);
|
||||
void process_scroll(Point2 p_pos);
|
||||
void process_joy_event(JoypadEvent p_event);
|
||||
void process_key_event(int p_scancode, int p_unicode_char, bool p_pressed);
|
||||
void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
|
||||
void process_event(Ref<InputEvent> p_event);
|
||||
void init_video_mode(int p_video_width, int p_video_height);
|
||||
|
||||
|
@ -213,6 +213,7 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) {
|
||||
ev->set_echo(false);
|
||||
ev->set_pressed(p_pressed);
|
||||
ev->set_scancode(p_key);
|
||||
ev->set_physical_scancode(p_key);
|
||||
ev->set_unicode(p_key);
|
||||
perform_event(ev);
|
||||
};
|
||||
|
@ -241,6 +241,7 @@ static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscrip
|
||||
ev->set_echo(emscripten_event->repeat);
|
||||
dom2godot_mod(emscripten_event, ev);
|
||||
ev->set_scancode(dom_code2godot_scancode(emscripten_event->code, emscripten_event->key));
|
||||
ev->set_physical_scancode(dom_code2godot_scancode(emscripten_event->code, emscripten_event->key));
|
||||
|
||||
String unicode = String::utf8(emscripten_event->key);
|
||||
// Check if empty or multi-character (e.g. `CapsLock`).
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
bool echo;
|
||||
bool raw;
|
||||
uint32_t scancode;
|
||||
uint32_t physical_scancode;
|
||||
uint32_t unicode;
|
||||
};
|
||||
|
||||
|
@ -143,6 +143,7 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
|
||||
get_key_modifier_state([event modifierFlags], k);
|
||||
k->set_pressed(true);
|
||||
k->set_scancode(KEY_PERIOD);
|
||||
k->set_physical_scancode(KEY_PERIOD);
|
||||
k->set_echo([event isARepeat]);
|
||||
|
||||
OS_OSX::singleton->push_input(k);
|
||||
@ -612,6 +613,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
ke.echo = false;
|
||||
ke.raw = false; // IME input event
|
||||
ke.scancode = 0;
|
||||
ke.physical_scancode = 0;
|
||||
ke.unicode = codepoint;
|
||||
|
||||
push_to_key_event_buffer(ke);
|
||||
@ -1192,6 +1194,7 @@ static int remapKey(unsigned int key, unsigned int state) {
|
||||
ke.pressed = true;
|
||||
ke.echo = [event isARepeat];
|
||||
ke.scancode = remapKey([event keyCode], [event modifierFlags]);
|
||||
ke.physical_scancode = translateKey([event keyCode]);
|
||||
ke.raw = true;
|
||||
ke.unicode = [characters characterAtIndex:i];
|
||||
|
||||
@ -1204,6 +1207,7 @@ static int remapKey(unsigned int key, unsigned int state) {
|
||||
ke.pressed = true;
|
||||
ke.echo = [event isARepeat];
|
||||
ke.scancode = remapKey([event keyCode], [event modifierFlags]);
|
||||
ke.physical_scancode = translateKey([event keyCode]);
|
||||
ke.raw = false;
|
||||
ke.unicode = 0;
|
||||
|
||||
@ -1263,6 +1267,7 @@ static int remapKey(unsigned int key, unsigned int state) {
|
||||
|
||||
ke.osx_state = mod;
|
||||
ke.scancode = remapKey(key, mod);
|
||||
ke.physical_scancode = translateKey(key);
|
||||
ke.unicode = 0;
|
||||
|
||||
push_to_key_event_buffer(ke);
|
||||
@ -1284,6 +1289,7 @@ static int remapKey(unsigned int key, unsigned int state) {
|
||||
ke.pressed = false;
|
||||
ke.echo = [event isARepeat];
|
||||
ke.scancode = remapKey([event keyCode], [event modifierFlags]);
|
||||
ke.physical_scancode = translateKey([event keyCode]);
|
||||
ke.raw = true;
|
||||
ke.unicode = [characters characterAtIndex:i];
|
||||
|
||||
@ -1296,6 +1302,7 @@ static int remapKey(unsigned int key, unsigned int state) {
|
||||
ke.pressed = false;
|
||||
ke.echo = [event isARepeat];
|
||||
ke.scancode = remapKey([event keyCode], [event modifierFlags]);
|
||||
ke.physical_scancode = translateKey([event keyCode]);
|
||||
ke.raw = true;
|
||||
ke.unicode = 0;
|
||||
|
||||
@ -3146,6 +3153,7 @@ void OS_OSX::process_key_events() {
|
||||
k->set_pressed(ke.pressed);
|
||||
k->set_echo(ke.echo);
|
||||
k->set_scancode(ke.scancode);
|
||||
k->set_physical_scancode(ke.physical_scancode);
|
||||
k->set_unicode(ke.unicode);
|
||||
|
||||
push_input(k);
|
||||
@ -3158,6 +3166,7 @@ void OS_OSX::process_key_events() {
|
||||
k->set_pressed(ke.pressed);
|
||||
k->set_echo(ke.echo);
|
||||
k->set_scancode(0);
|
||||
k->set_physical_scancode(0);
|
||||
k->set_unicode(ke.unicode);
|
||||
|
||||
push_input(k);
|
||||
@ -3169,6 +3178,7 @@ void OS_OSX::process_key_events() {
|
||||
k->set_pressed(ke.pressed);
|
||||
k->set_echo(ke.echo);
|
||||
k->set_scancode(ke.scancode);
|
||||
k->set_physical_scancode(ke.physical_scancode);
|
||||
|
||||
if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) {
|
||||
k->set_unicode(key_event_buffer[i + 1].unicode);
|
||||
|
@ -393,12 +393,14 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind
|
||||
ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE;
|
||||
ke.unicode = 0;
|
||||
ke.scancode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey);
|
||||
ke.physical_scancode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode);
|
||||
ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown);
|
||||
|
||||
} else {
|
||||
ke.type = OS_UWP::KeyEvent::MessageType::CHAR_EVENT_MESSAGE;
|
||||
ke.unicode = char_args->KeyCode;
|
||||
ke.scancode = 0;
|
||||
ke.physical_scancode = 0;
|
||||
ke.echo = (!p_pressed && !char_args->KeyStatus.IsKeyReleased) || (p_pressed && char_args->KeyStatus.WasKeyDown);
|
||||
}
|
||||
|
||||
|
@ -607,6 +607,7 @@ void OS_UWP::process_key_events() {
|
||||
key_event->set_control(kev.control);
|
||||
key_event->set_echo(kev.echo);
|
||||
key_event->set_scancode(kev.scancode);
|
||||
key_event->set_physical_scancode(kev.physical_scancode);
|
||||
key_event->set_unicode(kev.unicode);
|
||||
key_event->set_pressed(kev.pressed);
|
||||
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
MessageType type;
|
||||
bool pressed;
|
||||
unsigned int scancode;
|
||||
unsigned int physical_scancode;
|
||||
unsigned int unicode;
|
||||
bool echo;
|
||||
CorePhysicalKeyStatus status;
|
||||
|
@ -237,6 +237,104 @@ VK_PA1 (0xFD)
|
||||
VK_OEM_CLEAR (0xFE)
|
||||
*/
|
||||
|
||||
static _WinTranslatePair _scancode_to_keycode[] = {
|
||||
|
||||
{ KEY_ESCAPE, 0x01 },
|
||||
{ KEY_1, 0x02 },
|
||||
{ KEY_2, 0x03 },
|
||||
{ KEY_3, 0x04 },
|
||||
{ KEY_4, 0x05 },
|
||||
{ KEY_5, 0x06 },
|
||||
{ KEY_6, 0x07 },
|
||||
{ KEY_7, 0x08 },
|
||||
{ KEY_8, 0x09 },
|
||||
{ KEY_9, 0x0A },
|
||||
{ KEY_0, 0x0B },
|
||||
{ KEY_MINUS, 0x0C },
|
||||
{ KEY_EQUAL, 0x0D },
|
||||
{ KEY_BACKSPACE, 0x0E },
|
||||
{ KEY_TAB, 0x0F },
|
||||
{ KEY_Q, 0x10 },
|
||||
{ KEY_W, 0x11 },
|
||||
{ KEY_E, 0x12 },
|
||||
{ KEY_R, 0x13 },
|
||||
{ KEY_T, 0x14 },
|
||||
{ KEY_Y, 0x15 },
|
||||
{ KEY_U, 0x16 },
|
||||
{ KEY_I, 0x17 },
|
||||
{ KEY_O, 0x18 },
|
||||
{ KEY_P, 0x19 },
|
||||
{ KEY_BRACELEFT, 0x1A },
|
||||
{ KEY_BRACERIGHT, 0x1B },
|
||||
{ KEY_ENTER, 0x1C },
|
||||
{ KEY_CONTROL, 0x1D },
|
||||
{ KEY_A, 0x1E },
|
||||
{ KEY_S, 0x1F },
|
||||
{ KEY_D, 0x20 },
|
||||
{ KEY_F, 0x21 },
|
||||
{ KEY_G, 0x22 },
|
||||
{ KEY_H, 0x23 },
|
||||
{ KEY_J, 0x24 },
|
||||
{ KEY_K, 0x25 },
|
||||
{ KEY_L, 0x26 },
|
||||
{ KEY_SEMICOLON, 0x27 },
|
||||
{ KEY_APOSTROPHE, 0x28 },
|
||||
{ KEY_QUOTELEFT, 0x29 },
|
||||
{ KEY_SHIFT, 0x2A },
|
||||
{ KEY_BACKSLASH, 0x2B },
|
||||
{ KEY_Z, 0x2C },
|
||||
{ KEY_X, 0x2D },
|
||||
{ KEY_C, 0x2E },
|
||||
{ KEY_V, 0x2F },
|
||||
{ KEY_B, 0x30 },
|
||||
{ KEY_N, 0x31 },
|
||||
{ KEY_M, 0x32 },
|
||||
{ KEY_COMMA, 0x33 },
|
||||
{ KEY_PERIOD, 0x34 },
|
||||
{ KEY_SLASH, 0x35 },
|
||||
{ KEY_SHIFT, 0x36 },
|
||||
{ KEY_PRINT, 0x37 },
|
||||
{ KEY_ALT, 0x38 },
|
||||
{ KEY_SPACE, 0x39 },
|
||||
{ KEY_CAPSLOCK, 0x3A },
|
||||
{ KEY_F1, 0x3B },
|
||||
{ KEY_F2, 0x3C },
|
||||
{ KEY_F3, 0x3D },
|
||||
{ KEY_F4, 0x3E },
|
||||
{ KEY_F5, 0x3F },
|
||||
{ KEY_F6, 0x40 },
|
||||
{ KEY_F7, 0x41 },
|
||||
{ KEY_F8, 0x42 },
|
||||
{ KEY_F9, 0x43 },
|
||||
{ KEY_F10, 0x44 },
|
||||
{ KEY_NUMLOCK, 0x45 },
|
||||
{ KEY_SCROLLLOCK, 0x46 },
|
||||
{ KEY_HOME, 0x47 },
|
||||
{ KEY_UP, 0x48 },
|
||||
{ KEY_PAGEUP, 0x49 },
|
||||
{ KEY_KP_SUBTRACT, 0x4A },
|
||||
{ KEY_LEFT, 0x4B },
|
||||
{ KEY_KP_5, 0x4C },
|
||||
{ KEY_RIGHT, 0x4D },
|
||||
{ KEY_KP_ADD, 0x4E },
|
||||
{ KEY_END, 0x4F },
|
||||
{ KEY_DOWN, 0x50 },
|
||||
{ KEY_PAGEDOWN, 0x51 },
|
||||
{ KEY_INSERT, 0x52 },
|
||||
{ KEY_DELETE, 0x53 },
|
||||
//{ KEY_???, 0x56 }, //NON US BACKSLASH
|
||||
{ KEY_F11, 0x57 },
|
||||
{ KEY_F12, 0x58 },
|
||||
{ KEY_META, 0x5B },
|
||||
{ KEY_META, 0x5C },
|
||||
{ KEY_MENU, 0x5D },
|
||||
{ KEY_F13, 0x64 },
|
||||
{ KEY_F14, 0x65 },
|
||||
{ KEY_F15, 0x66 },
|
||||
{ KEY_F16, 0x67 },
|
||||
{ KEY_UNKNOWN, 0 }
|
||||
};
|
||||
|
||||
unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
|
||||
for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
|
||||
if (_vk_to_keycode[i].keycode == p_code) {
|
||||
@ -249,6 +347,71 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
|
||||
return KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) {
|
||||
unsigned int keycode = KEY_UNKNOWN;
|
||||
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
|
||||
if (_scancode_to_keycode[i].keycode == p_code) {
|
||||
keycode = _scancode_to_keycode[i].keysym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_extended) {
|
||||
switch (keycode) {
|
||||
case KEY_ENTER: {
|
||||
keycode = KEY_KP_ENTER;
|
||||
} break;
|
||||
case KEY_SLASH: {
|
||||
keycode = KEY_KP_DIVIDE;
|
||||
} break;
|
||||
case KEY_CAPSLOCK: {
|
||||
keycode = KEY_KP_ADD;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
switch (keycode) {
|
||||
case KEY_NUMLOCK: {
|
||||
keycode = KEY_PAUSE;
|
||||
} break;
|
||||
case KEY_HOME: {
|
||||
keycode = KEY_KP_7;
|
||||
} break;
|
||||
case KEY_UP: {
|
||||
keycode = KEY_KP_8;
|
||||
} break;
|
||||
case KEY_PAGEUP: {
|
||||
keycode = KEY_KP_9;
|
||||
} break;
|
||||
case KEY_LEFT: {
|
||||
keycode = KEY_KP_4;
|
||||
} break;
|
||||
case KEY_RIGHT: {
|
||||
keycode = KEY_KP_6;
|
||||
} break;
|
||||
case KEY_END: {
|
||||
keycode = KEY_KP_1;
|
||||
} break;
|
||||
case KEY_DOWN: {
|
||||
keycode = KEY_KP_2;
|
||||
} break;
|
||||
case KEY_PAGEDOWN: {
|
||||
keycode = KEY_KP_3;
|
||||
} break;
|
||||
case KEY_INSERT: {
|
||||
keycode = KEY_KP_0;
|
||||
} break;
|
||||
case KEY_DELETE: {
|
||||
keycode = KEY_KP_PERIOD;
|
||||
} break;
|
||||
case KEY_PRINT: {
|
||||
keycode = KEY_KP_MULTIPLY;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
return keycode;
|
||||
}
|
||||
|
||||
bool KeyMappingWindows::is_extended_key(unsigned int p_code) {
|
||||
return p_code == VK_INSERT ||
|
||||
p_code == VK_DELETE ||
|
||||
|
@ -42,6 +42,7 @@ class KeyMappingWindows {
|
||||
|
||||
public:
|
||||
static unsigned int get_keysym(unsigned int p_code);
|
||||
static unsigned int get_scansym(unsigned int p_code, bool p_extended);
|
||||
static bool is_extended_key(unsigned int p_code);
|
||||
};
|
||||
|
||||
|
@ -1212,6 +1212,7 @@ void OS_Windows::process_key_events() {
|
||||
k->set_metakey(ke.meta);
|
||||
k->set_pressed(true);
|
||||
k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
|
||||
k->set_physical_scancode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)));
|
||||
k->set_unicode(ke.wParam);
|
||||
if (k->get_unicode() && gr_mem) {
|
||||
k->set_alt(false);
|
||||
@ -1245,6 +1246,8 @@ void OS_Windows::process_key_events() {
|
||||
k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
|
||||
}
|
||||
|
||||
k->set_physical_scancode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)));
|
||||
|
||||
if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) {
|
||||
k->set_unicode(key_event_buffer[i + 1].wParam);
|
||||
}
|
||||
|
@ -179,6 +179,137 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
struct _TranslatePair {
|
||||
unsigned int keysym;
|
||||
unsigned int keycode;
|
||||
};
|
||||
|
||||
static _TranslatePair _scancode_to_keycode[] = {
|
||||
|
||||
{ KEY_ESCAPE, 0x09 },
|
||||
{ KEY_1, 0x0A },
|
||||
{ KEY_2, 0x0B },
|
||||
{ KEY_3, 0x0C },
|
||||
{ KEY_4, 0x0D },
|
||||
{ KEY_5, 0x0E },
|
||||
{ KEY_6, 0x0F },
|
||||
{ KEY_7, 0x10 },
|
||||
{ KEY_8, 0x11 },
|
||||
{ KEY_9, 0x12 },
|
||||
{ KEY_0, 0x13 },
|
||||
{ KEY_MINUS, 0x14 },
|
||||
{ KEY_EQUAL, 0x15 },
|
||||
{ KEY_BACKSPACE, 0x16 },
|
||||
{ KEY_TAB, 0x17 },
|
||||
{ KEY_Q, 0x18 },
|
||||
{ KEY_W, 0x19 },
|
||||
{ KEY_E, 0x1A },
|
||||
{ KEY_R, 0x1B },
|
||||
{ KEY_T, 0x1C },
|
||||
{ KEY_Y, 0x1D },
|
||||
{ KEY_U, 0x1E },
|
||||
{ KEY_I, 0x1F },
|
||||
{ KEY_O, 0x20 },
|
||||
{ KEY_P, 0x21 },
|
||||
{ KEY_BRACELEFT, 0x22 },
|
||||
{ KEY_BRACERIGHT, 0x23 },
|
||||
{ KEY_ENTER, 0x24 },
|
||||
{ KEY_CONTROL, 0x25 },
|
||||
{ KEY_A, 0x26 },
|
||||
{ KEY_S, 0x27 },
|
||||
{ KEY_D, 0x28 },
|
||||
{ KEY_F, 0x29 },
|
||||
{ KEY_G, 0x2A },
|
||||
{ KEY_H, 0x2B },
|
||||
{ KEY_J, 0x2C },
|
||||
{ KEY_K, 0x2D },
|
||||
{ KEY_L, 0x2E },
|
||||
{ KEY_SEMICOLON, 0x2F },
|
||||
{ KEY_APOSTROPHE, 0x30 },
|
||||
{ KEY_QUOTELEFT, 0x31 },
|
||||
{ KEY_SHIFT, 0x32 },
|
||||
{ KEY_BACKSLASH, 0x33 },
|
||||
{ KEY_Z, 0x34 },
|
||||
{ KEY_X, 0x35 },
|
||||
{ KEY_C, 0x36 },
|
||||
{ KEY_V, 0x37 },
|
||||
{ KEY_B, 0x38 },
|
||||
{ KEY_N, 0x39 },
|
||||
{ KEY_M, 0x3A },
|
||||
{ KEY_COMMA, 0x3B },
|
||||
{ KEY_PERIOD, 0x3C },
|
||||
{ KEY_SLASH, 0x3D },
|
||||
{ KEY_SHIFT, 0x3E },
|
||||
{ KEY_KP_MULTIPLY, 0x3F },
|
||||
{ KEY_ALT, 0x40 },
|
||||
{ KEY_SPACE, 0x41 },
|
||||
{ KEY_CAPSLOCK, 0x42 },
|
||||
{ KEY_F1, 0x43 },
|
||||
{ KEY_F2, 0x44 },
|
||||
{ KEY_F3, 0x45 },
|
||||
{ KEY_F4, 0x46 },
|
||||
{ KEY_F5, 0x47 },
|
||||
{ KEY_F6, 0x48 },
|
||||
{ KEY_F7, 0x49 },
|
||||
{ KEY_F8, 0x4A },
|
||||
{ KEY_F9, 0x4B },
|
||||
{ KEY_F10, 0x4C },
|
||||
{ KEY_NUMLOCK, 0x4D },
|
||||
{ KEY_SCROLLLOCK, 0x4E },
|
||||
{ KEY_KP_7, 0x4F },
|
||||
{ KEY_KP_8, 0x50 },
|
||||
{ KEY_KP_9, 0x51 },
|
||||
{ KEY_KP_SUBTRACT, 0x52 },
|
||||
{ KEY_KP_4, 0x53 },
|
||||
{ KEY_KP_5, 0x54 },
|
||||
{ KEY_KP_6, 0x55 },
|
||||
{ KEY_KP_ADD, 0x56 },
|
||||
{ KEY_KP_1, 0x57 },
|
||||
{ KEY_KP_2, 0x58 },
|
||||
{ KEY_KP_3, 0x59 },
|
||||
{ KEY_KP_0, 0x5A },
|
||||
{ KEY_KP_PERIOD, 0x5B },
|
||||
//{ KEY_???, 0x5E }, //NON US BACKSLASH
|
||||
{ KEY_F11, 0x5F },
|
||||
{ KEY_F12, 0x60 },
|
||||
{ KEY_KP_ENTER, 0x68 },
|
||||
{ KEY_CONTROL, 0x69 },
|
||||
{ KEY_KP_DIVIDE, 0x6A },
|
||||
{ KEY_PRINT, 0x6B },
|
||||
{ KEY_ALT, 0x6C },
|
||||
{ KEY_ENTER, 0x6D },
|
||||
{ KEY_HOME, 0x6E },
|
||||
{ KEY_UP, 0x6F },
|
||||
{ KEY_PAGEUP, 0x70 },
|
||||
{ KEY_LEFT, 0x71 },
|
||||
{ KEY_RIGHT, 0x72 },
|
||||
{ KEY_END, 0x73 },
|
||||
{ KEY_DOWN, 0x74 },
|
||||
{ KEY_PAGEDOWN, 0x75 },
|
||||
{ KEY_INSERT, 0x76 },
|
||||
{ KEY_DELETE, 0x77 },
|
||||
{ KEY_VOLUMEMUTE, 0x79 },
|
||||
{ KEY_VOLUMEDOWN, 0x7A },
|
||||
{ KEY_VOLUMEUP, 0x7B },
|
||||
{ KEY_PAUSE, 0x7F },
|
||||
{ KEY_SUPER_L, 0x85 },
|
||||
{ KEY_SUPER_R, 0x86 },
|
||||
{ KEY_MENU, 0x87 },
|
||||
{ KEY_UNKNOWN, 0 }
|
||||
};
|
||||
|
||||
unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
|
||||
unsigned int keycode = KEY_UNKNOWN;
|
||||
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
|
||||
if (_scancode_to_keycode[i].keycode == p_code) {
|
||||
keycode = _scancode_to_keycode[i].keysym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return keycode;
|
||||
}
|
||||
|
||||
unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
|
||||
// kinda bruteforce.. could optimize.
|
||||
|
||||
|
@ -45,6 +45,7 @@ class KeyMappingX11 {
|
||||
|
||||
public:
|
||||
static unsigned int get_keycode(KeySym p_keysym);
|
||||
static unsigned int get_scancode(unsigned int p_code);
|
||||
static KeySym get_keysym(unsigned int p_code);
|
||||
static unsigned int get_unicode_from_keysym(KeySym p_keysym);
|
||||
static KeySym get_keysym_from_unicode(unsigned int p_unicode);
|
||||
|
@ -1890,6 +1890,7 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
if (status == XLookupChars) {
|
||||
bool keypress = xkeyevent->type == KeyPress;
|
||||
unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
|
||||
unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
|
||||
if (keycode >= 'a' && keycode <= 'z') {
|
||||
keycode -= 'a' - 'A';
|
||||
}
|
||||
@ -1899,10 +1900,14 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
for (int i = 0; i < tmp.length(); i++) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instance();
|
||||
if (keycode == 0 && tmp[i] == 0) {
|
||||
if (physical_keycode == 0 && keycode == 0 && tmp[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keycode == 0) {
|
||||
keycode = physical_keycode;
|
||||
}
|
||||
|
||||
get_key_modifier_state(xkeyevent->state, k);
|
||||
|
||||
k->set_unicode(tmp[i]);
|
||||
@ -1910,12 +1915,14 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
k->set_pressed(keypress);
|
||||
|
||||
k->set_scancode(keycode);
|
||||
k->set_physical_scancode(physical_keycode);
|
||||
|
||||
k->set_echo(false);
|
||||
|
||||
if (k->get_scancode() == KEY_BACKTAB) {
|
||||
//make it consistent across platforms.
|
||||
k->set_scancode(KEY_TAB);
|
||||
k->set_physical_scancode(KEY_TAB);
|
||||
k->set_shift(true);
|
||||
}
|
||||
|
||||
@ -1944,6 +1951,7 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
// keysym, so it works in all platforms the same.
|
||||
|
||||
unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
|
||||
unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
|
||||
|
||||
/* Phase 3, obtain a unicode character from the keysym */
|
||||
|
||||
@ -1963,10 +1971,14 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
|
||||
bool keypress = xkeyevent->type == KeyPress;
|
||||
|
||||
if (keycode == 0 && unicode == 0) {
|
||||
if (physical_keycode == 0 && keycode == 0 && unicode == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 0) {
|
||||
keycode = physical_keycode;
|
||||
}
|
||||
|
||||
/* Phase 5, determine modifier mask */
|
||||
|
||||
// No problems here, except I had no way to
|
||||
@ -2028,12 +2040,14 @@ void OS_X11::_handle_key_event(XKeyEvent *p_event, LocalVector<XEvent> &p_events
|
||||
}
|
||||
|
||||
k->set_scancode(keycode);
|
||||
k->set_physical_scancode(physical_keycode);
|
||||
k->set_unicode(unicode);
|
||||
k->set_echo(p_echo);
|
||||
|
||||
if (k->get_scancode() == KEY_BACKTAB) {
|
||||
//make it consistent across platforms.
|
||||
k->set_scancode(KEY_TAB);
|
||||
k->set_physical_scancode(KEY_TAB);
|
||||
k->set_shift(true);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user