Add a FrameHostMsg_BeginNavigation IPC
[chromium-blink-merge.git] / ui / ozone / platform / caca / caca_event_factory.cc
blobc17e5a4f9657b0138b1a1267e65bda609246c413
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
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/caca/caca_event_factory.h"
7 #include <caca.h>
9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h"
11 #include "ui/events/event.h"
12 #include "ui/events/keycodes/keyboard_codes.h"
13 #include "ui/ozone/platform/caca/caca_connection.h"
15 namespace ui {
17 namespace {
19 ui::KeyboardCode GetKeyboardCode(const caca_event_t& event) {
20 // List of special mappings the Caca provides.
21 static const ui::KeyboardCode kCacaKeyMap[] = {
22 ui::VKEY_UNKNOWN,
23 ui::VKEY_A,
24 ui::VKEY_B,
25 ui::VKEY_C,
26 ui::VKEY_D,
27 ui::VKEY_E,
28 ui::VKEY_F,
29 ui::VKEY_G,
30 ui::VKEY_BACK,
31 ui::VKEY_TAB,
32 ui::VKEY_J,
33 ui::VKEY_K,
34 ui::VKEY_L,
35 ui::VKEY_RETURN,
36 ui::VKEY_N,
37 ui::VKEY_O,
38 ui::VKEY_P,
39 ui::VKEY_Q,
40 ui::VKEY_R,
41 ui::VKEY_PAUSE,
42 ui::VKEY_T,
43 ui::VKEY_U,
44 ui::VKEY_V,
45 ui::VKEY_W,
46 ui::VKEY_X,
47 ui::VKEY_Y,
48 ui::VKEY_Z,
49 ui::VKEY_ESCAPE,
50 ui::VKEY_DELETE,
51 ui::VKEY_UP,
52 ui::VKEY_DOWN,
53 ui::VKEY_LEFT,
54 ui::VKEY_RIGHT,
55 ui::VKEY_INSERT,
56 ui::VKEY_HOME,
57 ui::VKEY_END,
58 ui::VKEY_PRIOR,
59 ui::VKEY_NEXT,
60 ui::VKEY_F1,
61 ui::VKEY_F2,
62 ui::VKEY_F3,
63 ui::VKEY_F4,
64 ui::VKEY_F5,
65 ui::VKEY_F6,
66 ui::VKEY_F7,
67 ui::VKEY_F8,
68 ui::VKEY_F9,
69 ui::VKEY_F10,
70 ui::VKEY_F11,
71 ui::VKEY_F12,
74 int key_code = caca_get_event_key_ch(&event);
75 if (key_code >= 'a' && key_code <= 'z')
76 return static_cast<ui::KeyboardCode>(key_code - ('a' - 'A'));
77 if (key_code >= '0' && key_code <= 'Z')
78 return static_cast<ui::KeyboardCode>(key_code);
79 if (static_cast<unsigned int>(key_code) < arraysize(kCacaKeyMap))
80 return kCacaKeyMap[key_code];
82 return ui::VKEY_UNKNOWN;
85 int ModifierFromKey(const caca_event_t& event) {
86 int key_code = caca_get_event_key_ch(&event);
87 if (key_code >= 'A' && key_code <= 'Z')
88 return ui::EF_SHIFT_DOWN;
89 if ((key_code >= CACA_KEY_CTRL_A && key_code <= CACA_KEY_CTRL_G) ||
90 (key_code >= CACA_KEY_CTRL_J && key_code <= CACA_KEY_CTRL_L) ||
91 (key_code >= CACA_KEY_CTRL_N && key_code <= CACA_KEY_CTRL_R) ||
92 (key_code >= CACA_KEY_CTRL_T && key_code <= CACA_KEY_CTRL_Z))
93 return ui::EF_CONTROL_DOWN;
95 return ui::EF_NONE;
98 int ModifierFromButton(const caca_event_t& event) {
99 switch (caca_get_event_mouse_button(&event)) {
100 case 1:
101 return ui::EF_LEFT_MOUSE_BUTTON;
102 case 2:
103 return ui::EF_RIGHT_MOUSE_BUTTON;
104 case 3:
105 return ui::EF_MIDDLE_MOUSE_BUTTON;
107 return 0;
110 // Translate coordinates to bitmap coordinates.
111 gfx::PointF TranslateLocation(const gfx::PointF& location,
112 CacaConnection* connection) {
113 gfx::Size physical_size = connection->physical_size();
114 gfx::Size bitmap_size = connection->bitmap_size();
115 return gfx::PointF(
116 location.x() * bitmap_size.width() / physical_size.width(),
117 location.y() * bitmap_size.height() / physical_size.height());
120 ui::EventType GetEventTypeFromNative(const caca_event_t& event) {
121 switch (caca_get_event_type(&event)) {
122 case CACA_EVENT_KEY_PRESS:
123 return ui::ET_KEY_PRESSED;
124 case CACA_EVENT_KEY_RELEASE:
125 return ui::ET_KEY_RELEASED;
126 case CACA_EVENT_MOUSE_PRESS:
127 return ui::ET_MOUSE_PRESSED;
128 case CACA_EVENT_MOUSE_RELEASE:
129 return ui::ET_MOUSE_RELEASED;
130 case CACA_EVENT_MOUSE_MOTION:
131 return ui::ET_MOUSE_MOVED;
132 default:
133 return ui::ET_UNKNOWN;
137 } // namespace
139 CacaEventFactory::CacaEventFactory(CacaConnection* connection)
140 : connection_(connection),
141 weak_ptr_factory_(this),
142 delay_(base::TimeDelta::FromMilliseconds(10)),
143 modifier_flags_(0) {
146 CacaEventFactory::~CacaEventFactory() {
149 void CacaEventFactory::WarpCursorTo(gfx::AcceleratedWidget widget,
150 const gfx::PointF& location) {
151 NOTIMPLEMENTED();
154 void CacaEventFactory::OnDispatcherListChanged() {
155 ScheduleEventProcessing();
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_);
169 void CacaEventFactory::TryProcessingEvent() {
170 caca_event_t event;
171 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE |
172 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE |
173 CACA_EVENT_MOUSE_MOTION;
174 if (connection_->display() &&
175 caca_get_event(connection_->display(), event_mask, &event, 0)) {
177 ui::EventType type = GetEventTypeFromNative(event);
178 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED;
180 switch (type) {
181 case ui::ET_KEY_PRESSED:
182 case ui::ET_KEY_RELEASED: {
183 if (pressed)
184 modifier_flags_ |= ModifierFromKey(event);
185 else
186 modifier_flags_ &= ~ModifierFromKey(event);
188 ui::KeyEvent key_event(
189 type, GetKeyboardCode(event), modifier_flags_, true);
190 DispatchEvent(&key_event);
191 break;
193 case ui::ET_MOUSE_MOVED:
194 last_cursor_location_.SetPoint(caca_get_event_mouse_x(&event),
195 caca_get_event_mouse_y(&event));
196 // Update cursor location.
197 caca_gotoxy(caca_get_canvas(connection_->display()),
198 last_cursor_location_.x(),
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;
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;
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;
223 default:
224 NOTIMPLEMENTED();
225 break;
229 ScheduleEventProcessing();
232 } // namespace ui