OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/caca/caca_event_factory.h" | 5 #include "ui/ozone/platform/caca/caca_event_factory.h" |
6 | 6 |
7 #include <caca.h> | 7 #include <caca.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "ui/events/event.h" | 11 #include "ui/events/event.h" |
12 #include "ui/events/keycodes/keyboard_codes.h" | 12 #include "ui/events/keycodes/keyboard_codes.h" |
13 #include "ui/ozone/platform/caca/caca_connection.h" | 13 #include "ui/ozone/platform/caca/caca_window.h" |
14 | 14 |
15 namespace ui { | 15 namespace ui { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 ui::KeyboardCode GetKeyboardCode(const caca_event_t& event) { | 19 ui::KeyboardCode GetKeyboardCode(const caca_event_t& event) { |
20 // List of special mappings the Caca provides. | 20 // List of special mappings the Caca provides. |
21 static const ui::KeyboardCode kCacaKeyMap[] = { | 21 static const ui::KeyboardCode kCacaKeyMap[] = { |
22 ui::VKEY_UNKNOWN, | 22 ui::VKEY_UNKNOWN, |
23 ui::VKEY_A, | 23 ui::VKEY_A, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 return ui::EF_LEFT_MOUSE_BUTTON; | 101 return ui::EF_LEFT_MOUSE_BUTTON; |
102 case 2: | 102 case 2: |
103 return ui::EF_RIGHT_MOUSE_BUTTON; | 103 return ui::EF_RIGHT_MOUSE_BUTTON; |
104 case 3: | 104 case 3: |
105 return ui::EF_MIDDLE_MOUSE_BUTTON; | 105 return ui::EF_MIDDLE_MOUSE_BUTTON; |
106 } | 106 } |
107 return 0; | 107 return 0; |
108 } | 108 } |
109 | 109 |
110 // Translate coordinates to bitmap coordinates. | 110 // Translate coordinates to bitmap coordinates. |
111 gfx::PointF TranslateLocation(const gfx::PointF& location, | 111 gfx::PointF TranslateLocation(const gfx::PointF& location, CacaWindow* window) { |
112 CacaConnection* connection) { | 112 gfx::Size physical_size = window->physical_size(); |
113 gfx::Size physical_size = connection->physical_size(); | 113 gfx::Size bitmap_size = window->bitmap_size(); |
114 gfx::Size bitmap_size = connection->bitmap_size(); | |
115 return gfx::PointF( | 114 return gfx::PointF( |
116 location.x() * bitmap_size.width() / physical_size.width(), | 115 location.x() * bitmap_size.width() / physical_size.width(), |
117 location.y() * bitmap_size.height() / physical_size.height()); | 116 location.y() * bitmap_size.height() / physical_size.height()); |
118 } | 117 } |
119 | 118 |
120 ui::EventType GetEventTypeFromNative(const caca_event_t& event) { | 119 ui::EventType GetEventTypeFromNative(const caca_event_t& event) { |
121 switch (caca_get_event_type(&event)) { | 120 switch (caca_get_event_type(&event)) { |
122 case CACA_EVENT_KEY_PRESS: | 121 case CACA_EVENT_KEY_PRESS: |
123 return ui::ET_KEY_PRESSED; | 122 return ui::ET_KEY_PRESSED; |
124 case CACA_EVENT_KEY_RELEASE: | 123 case CACA_EVENT_KEY_RELEASE: |
125 return ui::ET_KEY_RELEASED; | 124 return ui::ET_KEY_RELEASED; |
126 case CACA_EVENT_MOUSE_PRESS: | 125 case CACA_EVENT_MOUSE_PRESS: |
127 return ui::ET_MOUSE_PRESSED; | 126 return ui::ET_MOUSE_PRESSED; |
128 case CACA_EVENT_MOUSE_RELEASE: | 127 case CACA_EVENT_MOUSE_RELEASE: |
129 return ui::ET_MOUSE_RELEASED; | 128 return ui::ET_MOUSE_RELEASED; |
130 case CACA_EVENT_MOUSE_MOTION: | 129 case CACA_EVENT_MOUSE_MOTION: |
131 return ui::ET_MOUSE_MOVED; | 130 return ui::ET_MOUSE_MOVED; |
132 default: | 131 default: |
133 return ui::ET_UNKNOWN; | 132 return ui::ET_UNKNOWN; |
134 } | 133 } |
135 } | 134 } |
136 | 135 |
137 } // namespace | 136 } // namespace |
138 | 137 |
139 CacaEventFactory::CacaEventFactory(CacaConnection* connection) | 138 CacaEventFactory::CacaEventFactory() : modifier_flags_(0) { |
140 : connection_(connection), | |
141 weak_ptr_factory_(this), | |
142 delay_(base::TimeDelta::FromMilliseconds(10)), | |
143 modifier_flags_(0) { | |
144 } | 139 } |
145 | 140 |
146 CacaEventFactory::~CacaEventFactory() { | 141 CacaEventFactory::~CacaEventFactory() { |
147 } | 142 } |
148 | 143 |
149 void CacaEventFactory::WarpCursorTo(gfx::AcceleratedWidget widget, | 144 void CacaEventFactory::WarpCursorTo(gfx::AcceleratedWidget widget, |
150 const gfx::PointF& location) { | 145 const gfx::PointF& location) { |
151 NOTIMPLEMENTED(); | 146 NOTIMPLEMENTED(); |
152 } | 147 } |
153 | 148 |
154 void CacaEventFactory::OnDispatcherListChanged() { | 149 void CacaEventFactory::TryProcessingEvent(CacaWindow* window) { |
155 ScheduleEventProcessing(); | 150 if (!window->display()) |
156 } | 151 return; |
157 | 152 |
158 void CacaEventFactory::ScheduleEventProcessing() { | |
159 // Caca uses a poll based event retrieval. Since we don't want to block we'd | |
160 // either need to spin up a new thread or just poll. For simplicity just poll | |
161 // for a message every |delay_| time delta. | |
162 base::MessageLoop::current()->PostDelayedTask( | |
163 FROM_HERE, | |
164 base::Bind(&CacaEventFactory::TryProcessingEvent, | |
165 weak_ptr_factory_.GetWeakPtr()), | |
166 delay_); | |
167 } | |
168 | |
169 void CacaEventFactory::TryProcessingEvent() { | |
170 caca_event_t event; | 153 caca_event_t event; |
171 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE | | 154 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE | |
172 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE | | 155 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE | |
173 CACA_EVENT_MOUSE_MOTION; | 156 CACA_EVENT_MOUSE_MOTION | CACA_EVENT_RESIZE | |
174 if (connection_->display() && | 157 CACA_EVENT_QUIT; |
175 caca_get_event(connection_->display(), event_mask, &event, 0)) { | |
176 | 158 |
177 ui::EventType type = GetEventTypeFromNative(event); | 159 if (!caca_get_event(window->display(), event_mask, &event, 0)) |
178 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; | 160 return; |
179 | 161 |
180 switch (type) { | 162 switch (caca_get_event_type(&event)) { |
181 case ui::ET_KEY_PRESSED: | 163 case CACA_EVENT_KEY_PRESS: |
182 case ui::ET_KEY_RELEASED: { | 164 case CACA_EVENT_KEY_RELEASE: |
183 if (pressed) | 165 case CACA_EVENT_MOUSE_PRESS: |
184 modifier_flags_ |= ModifierFromKey(event); | 166 case CACA_EVENT_MOUSE_RELEASE: |
185 else | 167 case CACA_EVENT_MOUSE_MOTION: |
186 modifier_flags_ &= ~ModifierFromKey(event); | 168 OnInputEvent(&event, window); |
| 169 break; |
| 170 case CACA_EVENT_RESIZE: |
| 171 window->OnCacaResize(); |
| 172 break; |
| 173 case CACA_EVENT_QUIT: |
| 174 window->OnCacaQuit(); |
| 175 break; |
| 176 default: |
| 177 NOTIMPLEMENTED(); |
| 178 } |
| 179 } |
187 | 180 |
188 ui::KeyEvent key_event( | 181 void CacaEventFactory::OnInputEvent(caca_event_t* event, CacaWindow* window) { |
189 type, GetKeyboardCode(event), modifier_flags_, true); | 182 ui::EventType type = GetEventTypeFromNative(*event); |
190 DispatchEvent(&key_event); | 183 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; |
191 break; | 184 |
| 185 switch (type) { |
| 186 case ui::ET_KEY_PRESSED: |
| 187 case ui::ET_KEY_RELEASED: { |
| 188 if (pressed) |
| 189 modifier_flags_ |= ModifierFromKey(*event); |
| 190 else |
| 191 modifier_flags_ &= ~ModifierFromKey(*event); |
| 192 |
| 193 ui::KeyEvent key_event( |
| 194 type, GetKeyboardCode(*event), modifier_flags_, false); |
| 195 window->OnCacaEvent(&key_event); |
| 196 break; |
| 197 } |
| 198 case ui::ET_MOUSE_MOVED: |
| 199 last_cursor_location_.SetPoint(caca_get_event_mouse_x(event), |
| 200 caca_get_event_mouse_y(event)); |
| 201 // Update cursor location. |
| 202 caca_gotoxy(caca_get_canvas(window->display()), |
| 203 last_cursor_location_.x(), |
| 204 last_cursor_location_.y()); |
| 205 |
| 206 // fallthrough |
| 207 case ui::ET_MOUSE_PRESSED: |
| 208 case ui::ET_MOUSE_RELEASED: { |
| 209 int flags = 0; |
| 210 int changed_flags = 0; |
| 211 if (type != ui::ET_MOUSE_MOVED) { |
| 212 if (pressed) { |
| 213 changed_flags = ModifierFromButton(*event); |
| 214 modifier_flags_ |= changed_flags; |
| 215 } else { |
| 216 modifier_flags_ &= ~changed_flags; |
| 217 } |
| 218 // On release the button pressed is removed from |modifier_flags_|, |
| 219 // but sending the event needs it set. |
| 220 flags = modifier_flags_ | changed_flags; |
192 } | 221 } |
193 case ui::ET_MOUSE_MOVED: | 222 gfx::PointF location = TranslateLocation(last_cursor_location_, window); |
194 last_cursor_location_.SetPoint(caca_get_event_mouse_x(&event), | 223 ui::MouseEvent mouse_event( |
195 caca_get_event_mouse_y(&event)); | 224 type, location, location, flags, changed_flags); |
196 // Update cursor location. | 225 ui::MouseEvent mouse_event2(&mouse_event); |
197 caca_gotoxy(caca_get_canvas(connection_->display()), | 226 window->OnCacaEvent(&mouse_event2); |
198 last_cursor_location_.x(), | 227 break; |
199 last_cursor_location_.y()); | |
200 // fallthrough | |
201 case ui::ET_MOUSE_PRESSED: | |
202 case ui::ET_MOUSE_RELEASED: { | |
203 int flags = 0; | |
204 int changed_flags = 0; | |
205 if (type != ui::ET_MOUSE_MOVED) { | |
206 if (pressed) { | |
207 changed_flags = ModifierFromButton(event); | |
208 modifier_flags_ |= changed_flags; | |
209 } else { | |
210 modifier_flags_ &= ~changed_flags; | |
211 } | |
212 // On release the button pressed is removed from |modifier_flags_|, | |
213 // but sending the event needs it set. | |
214 flags = modifier_flags_ | changed_flags; | |
215 } | |
216 gfx::PointF location = TranslateLocation(last_cursor_location_, | |
217 connection_); | |
218 ui::MouseEvent mouse_event( | |
219 type, location, location, flags, changed_flags); | |
220 DispatchEvent(&mouse_event); | |
221 break; | |
222 } | |
223 default: | |
224 NOTIMPLEMENTED(); | |
225 break; | |
226 } | 228 } |
| 229 default: |
| 230 NOTIMPLEMENTED(); |
| 231 break; |
227 } | 232 } |
228 | |
229 ScheduleEventProcessing(); | |
230 } | 233 } |
231 | 234 |
232 } // namespace ui | 235 } // namespace ui |
OLD | NEW |