OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "views/events/event.h" | |
6 | |
7 #include <gdk/gdk.h> | |
8 #include <gdk/gdkx.h> | |
9 #include <X11/extensions/XInput2.h> | |
10 #include <X11/Xlib.h> | |
11 | |
12 #include "base/logging.h" | |
13 #include "base/utf_string_conversions.h" | |
14 #include "ui/base/events.h" | |
15 #include "ui/base/keycodes/keyboard_code_conversion.h" | |
16 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | |
17 #include "ui/base/touch/touch_factory.h" | |
18 #include "views/widget/root_view.h" | |
19 | |
20 namespace views { | |
21 | |
22 namespace { | |
23 | |
24 // The following two functions are copied from event_gtk.cc. These will be | |
25 // removed when GTK dependency is removed. | |
26 #if defined(TOOLKIT_USES_GTK) | |
27 uint16 GetCharacterFromGdkKeyval(guint keyval) { | |
28 guint32 ch = gdk_keyval_to_unicode(keyval); | |
29 | |
30 // We only support BMP characters. | |
31 return ch < 0xFFFE ? static_cast<uint16>(ch) : 0; | |
32 } | |
33 | |
34 GdkEventKey* GetGdkEventKeyFromNative(GdkEvent* gdk_event) { | |
35 DCHECK(gdk_event->type == GDK_KEY_PRESS || | |
36 gdk_event->type == GDK_KEY_RELEASE); | |
37 return &gdk_event->key; | |
38 } | |
39 #endif | |
40 | |
41 } // namespace | |
42 | |
43 //////////////////////////////////////////////////////////////////////////////// | |
44 // KeyEvent, public: | |
45 | |
46 uint16 KeyEvent::GetCharacter() const { | |
47 if (character_) | |
48 return character_; | |
49 | |
50 if (!native_event()) { | |
51 #if defined(TOOLKIT_USES_GTK) | |
52 // This event may have been created from a Gdk event. | |
53 if (!IsControlDown() && gdk_event()) { | |
54 uint16 ch = GetCharacterFromGdkKeyval( | |
55 GetGdkEventKeyFromNative(gdk_event())->keyval); | |
56 if (ch) | |
57 return ch; | |
58 } | |
59 #endif | |
60 return ui::GetCharacterFromKeyCode(key_code_, flags()); | |
61 } | |
62 | |
63 DCHECK(native_event()->type == KeyPress || | |
64 native_event()->type == KeyRelease); | |
65 | |
66 uint16 ch = ui::DefaultSymbolFromXEvent(native_event()); | |
67 return ch ? ch : ui::GetCharacterFromKeyCode(key_code_, flags()); | |
68 } | |
69 | |
70 uint16 KeyEvent::GetUnmodifiedCharacter() const { | |
71 if (unmodified_character_) | |
72 return unmodified_character_; | |
73 | |
74 if (!native_event()) { | |
75 #if defined(TOOLKIT_USES_GTK) | |
76 // This event may have been created from a Gdk event. | |
77 if (gdk_event()) { | |
78 GdkEventKey* key = GetGdkEventKeyFromNative(gdk_event()); | |
79 | |
80 static const guint kIgnoredModifiers = | |
81 GDK_CONTROL_MASK | GDK_LOCK_MASK | GDK_MOD1_MASK | GDK_MOD2_MASK | | |
82 GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK | GDK_SUPER_MASK | | |
83 GDK_HYPER_MASK | GDK_META_MASK; | |
84 | |
85 // We can't use things like (key->state & GDK_SHIFT_MASK), as it may mask | |
86 // out bits used by X11 or Gtk internally. | |
87 GdkModifierType modifiers = | |
88 static_cast<GdkModifierType>(key->state & ~kIgnoredModifiers); | |
89 guint keyval = 0; | |
90 if (gdk_keymap_translate_keyboard_state(NULL, key->hardware_keycode, | |
91 modifiers, key->group, &keyval, NULL, NULL, NULL)) { | |
92 uint16 ch = GetCharacterFromGdkKeyval(keyval); | |
93 if (ch) | |
94 return ch; | |
95 } | |
96 } | |
97 #endif | |
98 return ui::GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN); | |
99 } | |
100 | |
101 DCHECK(native_event()->type == KeyPress || | |
102 native_event()->type == KeyRelease); | |
103 | |
104 XKeyEvent *key = &native_event()->xkey; | |
105 | |
106 static const unsigned int kIgnoredModifiers = ControlMask | LockMask | | |
107 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask; | |
108 | |
109 // We can't use things like (key.state & ShiftMask), as it may mask out bits | |
110 // used by X11 internally. | |
111 key->state &= ~kIgnoredModifiers; | |
112 uint16 ch = ui::DefaultSymbolFromXEvent(native_event()); | |
113 return ch ? ch : | |
114 ui::GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN); | |
115 } | |
116 | |
117 //////////////////////////////////////////////////////////////////////////////// | |
118 // TouchEvent, public: | |
119 | |
120 TouchEvent::TouchEvent(const base::NativeEvent& native_event) | |
121 : LocatedEvent(native_event), | |
122 touch_id_(ui::GetTouchId(native_event)), | |
123 radius_x_(ui::GetTouchRadiusX(native_event)), | |
124 radius_y_(ui::GetTouchRadiusY(native_event)), | |
125 rotation_angle_(ui::GetTouchAngle(native_event)), | |
126 force_(ui::GetTouchForce(native_event)) { | |
127 #if defined(USE_XI2_MT) | |
128 if (type() == ui::ET_TOUCH_RELEASED) { | |
129 // NOTE: The slot is allocated by TouchFactory for each XI_TouchBegin | |
130 // event, which carries a new tracking ID to identify a new touch | |
131 // sequence. | |
132 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | |
133 float tracking_id; | |
134 if (factory->ExtractTouchParam(*native_event, | |
135 ui::TouchFactory::TP_TRACKING_ID, | |
136 &tracking_id)) { | |
137 factory->ReleaseSlotForTrackingID(tracking_id); | |
138 } | |
139 } | |
140 #else | |
141 if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) { | |
142 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | |
143 float slot; | |
144 if (factory->ExtractTouchParam(*native_event, | |
145 ui::TouchFactory::TP_SLOT_ID, &slot)) { | |
146 factory->SetSlotUsed(slot, type() == ui::ET_TOUCH_PRESSED); | |
147 } | |
148 } | |
149 #endif | |
150 } | |
151 | |
152 } // namespace views | |
OLD | NEW |