| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "chrome/renderer/pepper_scrollbar_widget.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/message_loop.h" | |
| 10 #include "chrome/renderer/pepper_devices.h" | |
| 11 #include "skia/ext/platform_canvas.h" | |
| 12 #include "skia/ext/platform_device.h" | |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScrollbar.h" | |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" | |
| 16 #include "webkit/plugins/npapi/plugin_instance.h" | |
| 17 #include "webkit/glue/webkit_glue.h" | |
| 18 | |
| 19 using WebKit::WebInputEvent; | |
| 20 using WebKit::WebKeyboardEvent; | |
| 21 using WebKit::WebMouseEvent; | |
| 22 using WebKit::WebMouseWheelEvent; | |
| 23 using WebKit::WebRect; | |
| 24 using WebKit::WebScrollbar; | |
| 25 using WebKit::WebVector; | |
| 26 | |
| 27 | |
| 28 // Anonymous namespace for functions converting NPAPI to WebInputEvents types. | |
| 29 namespace { | |
| 30 | |
| 31 WebKeyboardEvent BuildKeyEvent(const NPPepperEvent& event) { | |
| 32 WebKeyboardEvent key_event; | |
| 33 switch (event.type) { | |
| 34 case NPEventType_RawKeyDown: | |
| 35 key_event.type = WebInputEvent::RawKeyDown; | |
| 36 break; | |
| 37 case NPEventType_KeyDown: | |
| 38 key_event.type = WebInputEvent::KeyDown; | |
| 39 break; | |
| 40 case NPEventType_KeyUp: | |
| 41 key_event.type = WebInputEvent::KeyUp; | |
| 42 break; | |
| 43 } | |
| 44 key_event.timeStampSeconds = event.timeStampSeconds; | |
| 45 key_event.modifiers = event.u.key.modifier; | |
| 46 key_event.windowsKeyCode = event.u.key.normalizedKeyCode; | |
| 47 return key_event; | |
| 48 } | |
| 49 | |
| 50 WebKeyboardEvent BuildCharEvent(const NPPepperEvent& event) { | |
| 51 WebKeyboardEvent key_event; | |
| 52 key_event.type = WebInputEvent::Char; | |
| 53 key_event.timeStampSeconds = event.timeStampSeconds; | |
| 54 key_event.modifiers = event.u.character.modifier; | |
| 55 // For consistency, check that the sizes of the texts agree. | |
| 56 DCHECK(sizeof(event.u.character.text) == sizeof(key_event.text)); | |
| 57 DCHECK(sizeof(event.u.character.unmodifiedText) == | |
| 58 sizeof(key_event.unmodifiedText)); | |
| 59 for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) { | |
| 60 key_event.text[i] = event.u.character.text[i]; | |
| 61 key_event.unmodifiedText[i] = event.u.character.unmodifiedText[i]; | |
| 62 } | |
| 63 return key_event; | |
| 64 } | |
| 65 | |
| 66 WebMouseEvent BuildMouseEvent(const NPPepperEvent& event) { | |
| 67 WebMouseEvent mouse_event; | |
| 68 switch (event.type) { | |
| 69 case NPEventType_MouseDown: | |
| 70 mouse_event.type = WebInputEvent::MouseDown; | |
| 71 break; | |
| 72 case NPEventType_MouseUp: | |
| 73 mouse_event.type = WebInputEvent::MouseUp; | |
| 74 break; | |
| 75 case NPEventType_MouseMove: | |
| 76 mouse_event.type = WebInputEvent::MouseMove; | |
| 77 break; | |
| 78 case NPEventType_MouseEnter: | |
| 79 mouse_event.type = WebInputEvent::MouseEnter; | |
| 80 break; | |
| 81 case NPEventType_MouseLeave: | |
| 82 mouse_event.type = WebInputEvent::MouseLeave; | |
| 83 break; | |
| 84 } | |
| 85 mouse_event.timeStampSeconds = event.timeStampSeconds; | |
| 86 mouse_event.modifiers = event.u.mouse.modifier; | |
| 87 mouse_event.button = static_cast<WebMouseEvent::Button>(event.u.mouse.button); | |
| 88 mouse_event.x = event.u.mouse.x; | |
| 89 mouse_event.y = event.u.mouse.y; | |
| 90 mouse_event.clickCount = event.u.mouse.clickCount; | |
| 91 return mouse_event; | |
| 92 } | |
| 93 | |
| 94 WebMouseWheelEvent BuildMouseWheelEvent(const NPPepperEvent& event) { | |
| 95 WebMouseWheelEvent mouse_wheel_event; | |
| 96 mouse_wheel_event.type = WebInputEvent::MouseWheel; | |
| 97 mouse_wheel_event.timeStampSeconds = event.timeStampSeconds; | |
| 98 mouse_wheel_event.modifiers = event.u.wheel.modifier; | |
| 99 mouse_wheel_event.deltaX = event.u.wheel.deltaX; | |
| 100 mouse_wheel_event.deltaY = event.u.wheel.deltaY; | |
| 101 mouse_wheel_event.wheelTicksX = event.u.wheel.wheelTicksX; | |
| 102 mouse_wheel_event.wheelTicksY = event.u.wheel.wheelTicksY; | |
| 103 mouse_wheel_event.scrollByPage = event.u.wheel.scrollByPage; | |
| 104 return mouse_wheel_event; | |
| 105 } | |
| 106 | |
| 107 } // namespace | |
| 108 | |
| 109 PepperScrollbarWidget::PepperScrollbarWidget( | |
| 110 const NPScrollbarCreateParams& params) { | |
| 111 scrollbar_.reset(WebScrollbar::create( | |
| 112 static_cast<WebKit::WebScrollbarClient*>(this), | |
| 113 params.vertical ? WebScrollbar::Vertical : WebScrollbar::Horizontal)); | |
| 114 AddRef(); | |
| 115 } | |
| 116 | |
| 117 PepperScrollbarWidget::~PepperScrollbarWidget() { | |
| 118 } | |
| 119 | |
| 120 void PepperScrollbarWidget::Destroy() { | |
| 121 Release(); | |
| 122 } | |
| 123 | |
| 124 void PepperScrollbarWidget::Paint(Graphics2DDeviceContext* context, | |
| 125 const NPRect& dirty) { | |
| 126 gfx::Rect rect(dirty.left, dirty.top, dirty.right - dirty.left, | |
| 127 dirty.bottom - dirty.top); | |
| 128 scrollbar_->paint(webkit_glue::ToWebCanvas(context->canvas()), rect); | |
| 129 dirty_rect_ = dirty_rect_.Subtract(rect); | |
| 130 } | |
| 131 | |
| 132 bool PepperScrollbarWidget::HandleEvent(const NPPepperEvent& event) { | |
| 133 bool rv = false; | |
| 134 | |
| 135 switch (event.type) { | |
| 136 case NPEventType_Undefined: | |
| 137 return false; | |
| 138 case NPEventType_MouseDown: | |
| 139 case NPEventType_MouseUp: | |
| 140 case NPEventType_MouseMove: | |
| 141 case NPEventType_MouseEnter: | |
| 142 case NPEventType_MouseLeave: | |
| 143 rv = scrollbar_->handleInputEvent(BuildMouseEvent(event)); | |
| 144 break; | |
| 145 case NPEventType_MouseWheel: | |
| 146 rv = scrollbar_->handleInputEvent(BuildMouseWheelEvent(event)); | |
| 147 break; | |
| 148 case NPEventType_RawKeyDown: | |
| 149 case NPEventType_KeyDown: | |
| 150 case NPEventType_KeyUp: | |
| 151 rv = scrollbar_->handleInputEvent(BuildKeyEvent(event)); | |
| 152 break; | |
| 153 case NPEventType_Char: | |
| 154 rv = scrollbar_->handleInputEvent(BuildCharEvent(event)); | |
| 155 break; | |
| 156 case NPEventType_Minimize: | |
| 157 case NPEventType_Focus: | |
| 158 case NPEventType_Device: | |
| 159 // NOTIMPLEMENTED(); | |
| 160 break; | |
| 161 } | |
| 162 | |
| 163 return rv; | |
| 164 } | |
| 165 | |
| 166 void PepperScrollbarWidget::GetProperty( | |
| 167 NPWidgetProperty property, void* value) { | |
| 168 switch (property) { | |
| 169 case NPWidgetPropertyLocation: { | |
| 170 NPRect* rv = static_cast<NPRect*>(value); | |
| 171 rv->left = location_.x(); | |
| 172 rv->top = location_.y(); | |
| 173 rv->right = location_.right(); | |
| 174 rv->bottom = location_.bottom(); | |
| 175 break; | |
| 176 } | |
| 177 case NPWidgetPropertyDirtyRect: { | |
| 178 NPRect* rv = reinterpret_cast<NPRect*>(value); | |
| 179 rv->left = dirty_rect_.x(); | |
| 180 rv->top = dirty_rect_.y(); | |
| 181 rv->right = dirty_rect_.right(); | |
| 182 rv->bottom = dirty_rect_.bottom(); | |
| 183 break; | |
| 184 } | |
| 185 case NPWidgetPropertyScrollbarThickness: { | |
| 186 int32* rv = static_cast<int32*>(value); | |
| 187 *rv = WebScrollbar::defaultThickness(); | |
| 188 break; | |
| 189 } | |
| 190 case NPWidgetPropertyScrollbarValue: { | |
| 191 int32* rv = static_cast<int32*>(value); | |
| 192 *rv = scrollbar_->value(); | |
| 193 break; | |
| 194 } | |
| 195 default: | |
| 196 NOTREACHED(); | |
| 197 break; | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 void PepperScrollbarWidget::SetProperty( | |
| 202 NPWidgetProperty property, void* value) { | |
| 203 switch (property) { | |
| 204 case NPWidgetPropertyLocation: { | |
| 205 NPRect* r = static_cast<NPRect*>(value); | |
| 206 location_ = gfx::Rect( | |
| 207 r->left, r->top, r->right - r->left, r->bottom - r->top); | |
| 208 scrollbar_->setLocation(location_); | |
| 209 break; | |
| 210 } | |
| 211 case NPWidgetPropertyScrollbarValue: { | |
| 212 int32* position = static_cast<int*>(value); | |
| 213 scrollbar_->setValue(*position); | |
| 214 break; | |
| 215 } | |
| 216 case NPWidgetPropertyScrollbarDocumentSize: { | |
| 217 int32* total_length = static_cast<int32*>(value); | |
| 218 scrollbar_->setDocumentSize(*total_length); | |
| 219 break; | |
| 220 } | |
| 221 case NPWidgetPropertyScrollbarTickMarks: { | |
| 222 NPScrollbarTickMarks* tickmarks = | |
| 223 static_cast<NPScrollbarTickMarks*>(value); | |
| 224 tickmarks_.resize(tickmarks->count); | |
| 225 for (uint32 i = 0; i < tickmarks->count; ++i) { | |
| 226 WebRect rect( | |
| 227 tickmarks->tickmarks[i].left, | |
| 228 tickmarks->tickmarks[i].top, | |
| 229 tickmarks->tickmarks[i].right - tickmarks->tickmarks[i].left, | |
| 230 tickmarks->tickmarks[i].bottom - tickmarks->tickmarks[i].top); | |
| 231 tickmarks_[i] = rect; | |
| 232 } | |
| 233 dirty_rect_ = location_; | |
| 234 NotifyInvalidate(); | |
| 235 break; | |
| 236 } | |
| 237 case NPWidgetPropertyScrollbarScrollByLine: | |
| 238 case NPWidgetPropertyScrollbarScrollByPage: | |
| 239 case NPWidgetPropertyScrollbarScrollByDocument: | |
| 240 case NPWidgetPropertyScrollbarScrollByPixels: { | |
| 241 bool forward; | |
| 242 float multiplier = 1.0; | |
| 243 | |
| 244 WebScrollbar::ScrollGranularity granularity; | |
| 245 if (property == NPWidgetPropertyScrollbarScrollByLine) { | |
| 246 forward = *static_cast<bool*>(value); | |
| 247 granularity = WebScrollbar::ScrollByLine; | |
| 248 } else if (property == NPWidgetPropertyScrollbarScrollByPage) { | |
| 249 forward = *static_cast<bool*>(value); | |
| 250 granularity = WebScrollbar::ScrollByPage; | |
| 251 } else if (property == NPWidgetPropertyScrollbarScrollByDocument) { | |
| 252 forward = *static_cast<bool*>(value); | |
| 253 granularity = WebScrollbar::ScrollByDocument; | |
| 254 } else { | |
| 255 multiplier = static_cast<float>(*static_cast<int32*>(value)); | |
| 256 forward = multiplier >= 0; | |
| 257 if (multiplier < 0) | |
| 258 multiplier *= -1; | |
| 259 granularity = WebScrollbar::ScrollByPixel; | |
| 260 } | |
| 261 scrollbar_->scroll( | |
| 262 forward ? WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward, | |
| 263 granularity, multiplier); | |
| 264 break; | |
| 265 } | |
| 266 default: | |
| 267 NOTREACHED(); | |
| 268 break; | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 void PepperScrollbarWidget::valueChanged(WebScrollbar*) { | |
| 273 WidgetPropertyChanged(NPWidgetPropertyScrollbarValue); | |
| 274 } | |
| 275 | |
| 276 void PepperScrollbarWidget::invalidateScrollbarRect(WebScrollbar*, | |
| 277 const WebRect& rect) { | |
| 278 dirty_rect_ = dirty_rect_.Union(rect); | |
| 279 // Can't call into the client to tell them about the invalidate right away, | |
| 280 // since the Scrollbar code is still in the middle of updating its internal | |
| 281 // state. | |
| 282 MessageLoop::current()->PostTask( | |
| 283 FROM_HERE, | |
| 284 NewRunnableMethod(this, &PepperScrollbarWidget::NotifyInvalidate)); | |
| 285 } | |
| 286 | |
| 287 void PepperScrollbarWidget::getTickmarks(WebKit::WebScrollbar*, | |
| 288 WebVector<WebRect>* tickmarks) const { | |
| 289 if (tickmarks_.empty()) { | |
| 290 WebRect* rects = NULL; | |
| 291 tickmarks->assign(rects, 0); | |
| 292 } else { | |
| 293 tickmarks->assign(&tickmarks_[0], tickmarks_.size()); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 void PepperScrollbarWidget::NotifyInvalidate() { | |
| 298 if (!dirty_rect_.IsEmpty()) | |
| 299 WidgetPropertyChanged(NPWidgetPropertyDirtyRect); | |
| 300 } | |
| OLD | NEW |