Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / ozone / platform / caca / caca_event_source.cc
blob78d33442ac4ad21bd8bccebde6ad8df354c8bfd0
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_source.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/event_utils.h"
13 #include "ui/events/keycodes/keyboard_codes.h"
14 #include "ui/ozone/platform/caca/caca_window.h"
16 namespace ui {
18 namespace {
20 ui::KeyboardCode GetKeyboardCode(const caca_event_t& event) {
21 // List of special mappings the Caca provides.
22 static const ui::KeyboardCode kCacaKeyMap[] = {
23 ui::VKEY_UNKNOWN,
24 ui::VKEY_A,
25 ui::VKEY_B,
26 ui::VKEY_C,
27 ui::VKEY_D,
28 ui::VKEY_E,
29 ui::VKEY_F,
30 ui::VKEY_G,
31 ui::VKEY_BACK,
32 ui::VKEY_TAB,
33 ui::VKEY_J,
34 ui::VKEY_K,
35 ui::VKEY_L,
36 ui::VKEY_RETURN,
37 ui::VKEY_N,
38 ui::VKEY_O,
39 ui::VKEY_P,
40 ui::VKEY_Q,
41 ui::VKEY_R,
42 ui::VKEY_PAUSE,
43 ui::VKEY_T,
44 ui::VKEY_U,
45 ui::VKEY_V,
46 ui::VKEY_W,
47 ui::VKEY_X,
48 ui::VKEY_Y,
49 ui::VKEY_Z,
50 ui::VKEY_ESCAPE,
51 ui::VKEY_DELETE,
52 ui::VKEY_UP,
53 ui::VKEY_DOWN,
54 ui::VKEY_LEFT,
55 ui::VKEY_RIGHT,
56 ui::VKEY_INSERT,
57 ui::VKEY_HOME,
58 ui::VKEY_END,
59 ui::VKEY_PRIOR,
60 ui::VKEY_NEXT,
61 ui::VKEY_F1,
62 ui::VKEY_F2,
63 ui::VKEY_F3,
64 ui::VKEY_F4,
65 ui::VKEY_F5,
66 ui::VKEY_F6,
67 ui::VKEY_F7,
68 ui::VKEY_F8,
69 ui::VKEY_F9,
70 ui::VKEY_F10,
71 ui::VKEY_F11,
72 ui::VKEY_F12,
75 int key_code = caca_get_event_key_ch(&event);
76 if (key_code >= 'a' && key_code <= 'z')
77 return static_cast<ui::KeyboardCode>(key_code - ('a' - 'A'));
78 if (key_code >= '0' && key_code <= 'Z')
79 return static_cast<ui::KeyboardCode>(key_code);
80 if (static_cast<unsigned int>(key_code) < arraysize(kCacaKeyMap))
81 return kCacaKeyMap[key_code];
83 return ui::VKEY_UNKNOWN;
86 int ModifierFromKey(const caca_event_t& event) {
87 int key_code = caca_get_event_key_ch(&event);
88 if (key_code >= 'A' && key_code <= 'Z')
89 return ui::EF_SHIFT_DOWN;
90 if ((key_code >= CACA_KEY_CTRL_A && key_code <= CACA_KEY_CTRL_G) ||
91 (key_code >= CACA_KEY_CTRL_J && key_code <= CACA_KEY_CTRL_L) ||
92 (key_code >= CACA_KEY_CTRL_N && key_code <= CACA_KEY_CTRL_R) ||
93 (key_code >= CACA_KEY_CTRL_T && key_code <= CACA_KEY_CTRL_Z))
94 return ui::EF_CONTROL_DOWN;
96 return ui::EF_NONE;
99 int ModifierFromButton(const caca_event_t& event) {
100 switch (caca_get_event_mouse_button(&event)) {
101 case 1:
102 return ui::EF_LEFT_MOUSE_BUTTON;
103 case 2:
104 return ui::EF_RIGHT_MOUSE_BUTTON;
105 case 3:
106 return ui::EF_MIDDLE_MOUSE_BUTTON;
108 return 0;
111 // Translate coordinates to bitmap coordinates.
112 gfx::PointF TranslateLocation(const gfx::PointF& location, CacaWindow* window) {
113 gfx::Size physical_size = window->physical_size();
114 gfx::Size bitmap_size = window->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 CacaEventSource::CacaEventSource() {
142 CacaEventSource::~CacaEventSource() {
145 void CacaEventSource::TryProcessingEvent(CacaWindow* window) {
146 if (!window->display())
147 return;
149 caca_event_t event;
150 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE |
151 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE |
152 CACA_EVENT_MOUSE_MOTION | CACA_EVENT_RESIZE |
153 CACA_EVENT_QUIT;
155 if (!caca_get_event(window->display(), event_mask, &event, 0))
156 return;
158 switch (caca_get_event_type(&event)) {
159 case CACA_EVENT_KEY_PRESS:
160 case CACA_EVENT_KEY_RELEASE:
161 case CACA_EVENT_MOUSE_PRESS:
162 case CACA_EVENT_MOUSE_RELEASE:
163 case CACA_EVENT_MOUSE_MOTION:
164 OnInputEvent(&event, window);
165 break;
166 case CACA_EVENT_RESIZE:
167 window->OnCacaResize();
168 break;
169 case CACA_EVENT_QUIT:
170 window->OnCacaQuit();
171 break;
172 default:
173 NOTIMPLEMENTED();
177 void CacaEventSource::OnInputEvent(caca_event_t* event, CacaWindow* window) {
178 ui::EventType type = GetEventTypeFromNative(*event);
179 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED;
181 switch (type) {
182 case ui::ET_KEY_PRESSED:
183 case ui::ET_KEY_RELEASED: {
184 if (pressed)
185 modifier_flags_ |= ModifierFromKey(*event);
186 else
187 modifier_flags_ &= ~ModifierFromKey(*event);
189 ui::KeyEvent key_event(
190 type, GetKeyboardCode(*event), modifier_flags_);
191 window->OnCacaEvent(&key_event);
192 break;
194 case ui::ET_MOUSE_MOVED:
195 last_cursor_location_.SetPoint(caca_get_event_mouse_x(event),
196 caca_get_event_mouse_y(event));
197 // Update cursor location.
198 caca_gotoxy(caca_get_canvas(window->display()),
199 last_cursor_location_.x(),
200 last_cursor_location_.y());
202 // fallthrough
203 case ui::ET_MOUSE_PRESSED:
204 case ui::ET_MOUSE_RELEASED: {
205 int flags = 0;
206 int changed_flags = 0;
207 if (type != ui::ET_MOUSE_MOVED) {
208 if (pressed) {
209 changed_flags = ModifierFromButton(*event);
210 modifier_flags_ |= changed_flags;
211 } else {
212 modifier_flags_ &= ~changed_flags;
214 // On release the button pressed is removed from |modifier_flags_|,
215 // but sending the event needs it set.
216 flags = modifier_flags_ | changed_flags;
218 gfx::PointF location = TranslateLocation(last_cursor_location_, window);
219 ui::MouseEvent mouse_event(type, location, location, EventTimeForNow(),
220 flags, changed_flags);
221 window->OnCacaEvent(&mouse_event);
222 break;
224 default:
225 NOTIMPLEMENTED();
226 break;
230 } // namespace ui