| 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 PlatformEventDispatcher* dispatcher) { |
| 156 } | 151 scoped_ptr<ScopedEventDispatcher> dispatch_override = |
| 152 OverrideDispatcher(dispatcher); |
| 157 | 153 |
| 158 void CacaEventFactory::ScheduleEventProcessing() { | 154 if (!window->display()) |
| 159 // Caca uses a poll based event retrieval. Since we don't want to block we'd | 155 return; |
| 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 | 156 |
| 169 void CacaEventFactory::TryProcessingEvent() { | |
| 170 caca_event_t event; | 157 caca_event_t event; |
| 171 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE | | 158 int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE | |
| 172 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE | | 159 CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE | |
| 173 CACA_EVENT_MOUSE_MOTION; | 160 CACA_EVENT_MOUSE_MOTION | CACA_EVENT_RESIZE | |
| 174 if (connection_->display() && | 161 CACA_EVENT_QUIT; |
| 175 caca_get_event(connection_->display(), event_mask, &event, 0)) { | |
| 176 | 162 |
| 177 ui::EventType type = GetEventTypeFromNative(event); | 163 if (!caca_get_event(window->display(), event_mask, &event, 0)) |
| 178 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; | 164 return; |
| 179 | 165 |
| 180 switch (type) { | 166 switch (caca_get_event_type(&event)) { |
| 181 case ui::ET_KEY_PRESSED: | 167 case CACA_EVENT_KEY_PRESS: |
| 182 case ui::ET_KEY_RELEASED: { | 168 case CACA_EVENT_KEY_RELEASE: |
| 183 if (pressed) | 169 case CACA_EVENT_MOUSE_PRESS: |
| 184 modifier_flags_ |= ModifierFromKey(event); | 170 case CACA_EVENT_MOUSE_RELEASE: |
| 185 else | 171 case CACA_EVENT_MOUSE_MOTION: |
| 186 modifier_flags_ &= ~ModifierFromKey(event); | 172 OnInputEvent(&event, window); |
| 173 break; |
| 174 case CACA_EVENT_RESIZE: |
| 175 window->OnCacaResize(); |
| 176 break; |
| 177 case CACA_EVENT_QUIT: |
| 178 window->OnCacaQuit(); |
| 179 break; |
| 180 default: |
| 181 NOTIMPLEMENTED(); |
| 182 } |
| 183 } |
| 187 | 184 |
| 188 ui::KeyEvent key_event( | 185 void CacaEventFactory::OnInputEvent(caca_event_t* event, CacaWindow* window) { |
| 189 type, GetKeyboardCode(event), modifier_flags_, true); | 186 ui::EventType type = GetEventTypeFromNative(*event); |
| 190 DispatchEvent(&key_event); | 187 bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; |
| 191 break; | 188 |
| 189 switch (type) { |
| 190 case ui::ET_KEY_PRESSED: |
| 191 case ui::ET_KEY_RELEASED: { |
| 192 if (pressed) |
| 193 modifier_flags_ |= ModifierFromKey(*event); |
| 194 else |
| 195 modifier_flags_ &= ~ModifierFromKey(*event); |
| 196 |
| 197 ui::KeyEvent key_event( |
| 198 type, GetKeyboardCode(*event), modifier_flags_, false); |
| 199 DispatchEvent(&key_event); |
| 200 break; |
| 201 } |
| 202 case ui::ET_MOUSE_MOVED: |
| 203 last_cursor_location_.SetPoint(caca_get_event_mouse_x(event), |
| 204 caca_get_event_mouse_y(event)); |
| 205 // Update cursor location. |
| 206 caca_gotoxy(caca_get_canvas(window->display()), |
| 207 last_cursor_location_.x(), |
| 208 last_cursor_location_.y()); |
| 209 |
| 210 // fallthrough |
| 211 case ui::ET_MOUSE_PRESSED: |
| 212 case ui::ET_MOUSE_RELEASED: { |
| 213 int flags = 0; |
| 214 int changed_flags = 0; |
| 215 if (type != ui::ET_MOUSE_MOVED) { |
| 216 if (pressed) { |
| 217 changed_flags = ModifierFromButton(*event); |
| 218 modifier_flags_ |= changed_flags; |
| 219 } else { |
| 220 modifier_flags_ &= ~changed_flags; |
| 221 } |
| 222 // On release the button pressed is removed from |modifier_flags_|, |
| 223 // but sending the event needs it set. |
| 224 flags = modifier_flags_ | changed_flags; |
| 192 } | 225 } |
| 193 case ui::ET_MOUSE_MOVED: | 226 gfx::PointF location = TranslateLocation(last_cursor_location_, window); |
| 194 last_cursor_location_.SetPoint(caca_get_event_mouse_x(&event), | 227 ui::MouseEvent mouse_event( |
| 195 caca_get_event_mouse_y(&event)); | 228 type, location, location, flags, changed_flags); |
| 196 // Update cursor location. | 229 ui::MouseEvent mouse_event2(&mouse_event); |
| 197 caca_gotoxy(caca_get_canvas(connection_->display()), | 230 DispatchEvent(&mouse_event2); |
| 198 last_cursor_location_.x(), | 231 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 } | 232 } |
| 233 default: |
| 234 NOTIMPLEMENTED(); |
| 235 break; |
| 227 } | 236 } |
| 228 | |
| 229 ScheduleEventProcessing(); | |
| 230 } | 237 } |
| 231 | 238 |
| 232 } // namespace ui | 239 } // namespace ui |
| OLD | NEW |