OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can |
| 3 // be found in the LICENSE file. |
| 4 |
| 5 #include "native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h" |
| 6 |
| 7 #include <stdio.h> |
| 8 #include <string.h> |
| 9 |
| 10 #include "native_client/src/include/nacl_scoped_ptr.h" |
| 11 #include "native_client/src/include/portability.h" |
| 12 #include "native_client/src/shared/ppapi_proxy/object_serialize.h" |
| 13 #include "native_client/src/shared/ppapi_proxy/plugin_globals.h" |
| 14 #include "native_client/src/shared/ppapi_proxy/plugin_resource.h" |
| 15 #include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h" |
| 16 #include "native_client/src/shared/ppapi_proxy/utility.h" |
| 17 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 18 #include "ppapi/c/pp_errors.h" |
| 19 #include "ppapi/c/ppb_input_event.h" |
| 20 |
| 21 namespace { |
| 22 |
| 23 using ppapi_proxy::DebugPrintf; |
| 24 using ppapi_proxy::GetMainSrpcChannel; |
| 25 using ppapi_proxy::kInvalidResourceId; |
| 26 using ppapi_proxy::kMaxVarSize; |
| 27 using ppapi_proxy::PluginInputEvent; |
| 28 using ppapi_proxy::PluginResource; |
| 29 using ppapi_proxy::Serialize; |
| 30 |
| 31 // InputEvent ------------------------------------------------------------------ |
| 32 |
| 33 int32_t RequestInputEvents(PP_Instance instance, uint32_t event_classes) { |
| 34 DebugPrintf("PPB_InputEvent::RequestInputEvents: instance=%"NACL_PRIu32", " |
| 35 "event_classes=%"NACL_PRIu32"\n", |
| 36 instance, event_classes); |
| 37 uint32_t success = 0; |
| 38 NaClSrpcError srpc_result = |
| 39 PpbInputEventRpcClient::PPB_InputEvent_RequestInputEvents( |
| 40 GetMainSrpcChannel(), |
| 41 instance, |
| 42 static_cast<int32_t>(event_classes), |
| 43 false, // false -> Don't filter. |
| 44 reinterpret_cast<int32_t*>(&success)); |
| 45 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 46 return success; |
| 47 } |
| 48 return PP_ERROR_FAILED; |
| 49 } |
| 50 |
| 51 int32_t RequestFilteringInputEvents(PP_Instance instance, |
| 52 uint32_t event_classes) { |
| 53 DebugPrintf("PPB_InputEvent::RequestFilteringInputEvents: instance=" |
| 54 "%"NACL_PRIu32", event_classes=%"NACL_PRIu32"\n", |
| 55 instance, event_classes); |
| 56 uint32_t success = 0; |
| 57 NaClSrpcError srpc_result = |
| 58 PpbInputEventRpcClient::PPB_InputEvent_RequestInputEvents( |
| 59 GetMainSrpcChannel(), |
| 60 instance, |
| 61 static_cast<int32_t>(event_classes), |
| 62 true, // true -> Filter. |
| 63 reinterpret_cast<int32_t*>(&success)); |
| 64 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 65 return success; |
| 66 } |
| 67 return PP_ERROR_FAILED; |
| 68 } |
| 69 |
| 70 void ClearInputEventRequest(PP_Instance instance, |
| 71 uint32_t event_classes) { |
| 72 DebugPrintf("PPB_InputEvent::ClearInputEventRequest: instance=%"NACL_PRIu32 |
| 73 ", event_classes=%"NACL_PRIu32"\n", |
| 74 instance, event_classes); |
| 75 PpbInputEventRpcClient::PPB_InputEvent_ClearInputEventRequest( |
| 76 GetMainSrpcChannel(), |
| 77 instance, |
| 78 static_cast<int32_t>(event_classes)); |
| 79 } |
| 80 |
| 81 // Helper RAII class to get the PluginInputEvent from the PP_Resource and hold |
| 82 // it with a scoped_refptr. Also does a DebugPrintf. |
| 83 class InputEventGetter { |
| 84 public: |
| 85 InputEventGetter(PP_Resource resource, const char* function_name) { |
| 86 DebugPrintf("PPB_InputEvent::%s: resource=%"NACL_PRIu32"\n", |
| 87 function_name, |
| 88 resource); |
| 89 input_event_ = |
| 90 PluginResource::GetAs<PluginInputEvent>(resource); |
| 91 } |
| 92 |
| 93 PluginInputEvent* get() { |
| 94 return input_event_.get(); |
| 95 } |
| 96 |
| 97 private: |
| 98 NACL_DISALLOW_COPY_AND_ASSIGN(InputEventGetter); |
| 99 scoped_refptr<PluginInputEvent> input_event_; |
| 100 }; |
| 101 // This macro is for starting a resource function. It makes sure resource_arg |
| 102 // is of type PluginInputEvent, and returns error_return if it's not. |
| 103 #define BEGIN_RESOURCE_THUNK(function_name, resource_arg, error_return) \ |
| 104 InputEventGetter input_event(resource_arg, function_name); \ |
| 105 if (!input_event.get()) { \ |
| 106 return error_return; \ |
| 107 } \ |
| 108 do {} while(0) |
| 109 |
| 110 PP_Bool IsInputEvent(PP_Resource resource) { |
| 111 BEGIN_RESOURCE_THUNK("IsInputEvent", resource, PP_FALSE); |
| 112 return PP_TRUE; |
| 113 } |
| 114 |
| 115 #define IMPLEMENT_RESOURCE_THUNK(function, resource_arg, error_return) \ |
| 116 BEGIN_RESOURCE_THUNK(#function, resource_arg, error_return); \ |
| 117 return input_event.get()->function() |
| 118 |
| 119 PP_InputEvent_Type GetType(PP_Resource event) { |
| 120 IMPLEMENT_RESOURCE_THUNK(GetType, event, PP_INPUTEVENT_TYPE_UNDEFINED); |
| 121 } |
| 122 |
| 123 PP_TimeTicks GetTimeStamp(PP_Resource event) { |
| 124 IMPLEMENT_RESOURCE_THUNK(GetTimeStamp, event, 0.0); |
| 125 } |
| 126 |
| 127 uint32_t GetModifiers(PP_Resource event) { |
| 128 IMPLEMENT_RESOURCE_THUNK(GetModifiers, event, 0); |
| 129 } |
| 130 |
| 131 // Mouse ----------------------------------------------------------------------- |
| 132 |
| 133 PP_Resource CreateMouseInputEvent(PP_Instance instance, |
| 134 PP_InputEvent_Type type, |
| 135 PP_TimeTicks time_stamp, |
| 136 uint32_t modifiers, |
| 137 PP_InputEvent_MouseButton mouse_button, |
| 138 const PP_Point* mouse_position, |
| 139 int32_t click_count) { |
| 140 DebugPrintf("PPB_InputEvent::CreateMouseInputEvent: instance=" |
| 141 "%"NACL_PRIu32", type=%d, time_stamp=%lf, modifiers=" |
| 142 "%"NACL_PRIu32", mouse_button=%d, x=%"NACL_PRId32", y=" |
| 143 "%"NACL_PRId32", click_count=%d\n", |
| 144 instance, type, time_stamp, modifiers, mouse_button, |
| 145 mouse_position->x, mouse_position->y, click_count); |
| 146 PP_Resource resource_id = kInvalidResourceId; |
| 147 NaClSrpcError srpc_result = |
| 148 PpbInputEventRpcClient::PPB_InputEvent_CreateMouseInputEvent( |
| 149 GetMainSrpcChannel(), |
| 150 instance, |
| 151 static_cast<int32_t>(type), |
| 152 time_stamp, |
| 153 static_cast<int32_t>(modifiers), |
| 154 static_cast<int32_t>(mouse_button), |
| 155 mouse_position->x, |
| 156 mouse_position->y, |
| 157 click_count, |
| 158 &resource_id); |
| 159 if (srpc_result == NACL_SRPC_RESULT_OK) |
| 160 return resource_id; |
| 161 return kInvalidResourceId; |
| 162 } |
| 163 |
| 164 PP_Bool IsMouseInputEvent(PP_Resource resource) { |
| 165 if (!IsInputEvent(resource)) |
| 166 return PP_FALSE; |
| 167 PP_InputEvent_Type type = GetType(resource); |
| 168 return PP_FromBool(type == PP_INPUTEVENT_TYPE_MOUSEDOWN || |
| 169 type == PP_INPUTEVENT_TYPE_MOUSEUP || |
| 170 type == PP_INPUTEVENT_TYPE_MOUSEMOVE || |
| 171 type == PP_INPUTEVENT_TYPE_MOUSEENTER || |
| 172 type == PP_INPUTEVENT_TYPE_MOUSELEAVE || |
| 173 type == PP_INPUTEVENT_TYPE_CONTEXTMENU); |
| 174 } |
| 175 |
| 176 PP_InputEvent_MouseButton GetMouseButton(PP_Resource mouse_event) { |
| 177 IMPLEMENT_RESOURCE_THUNK(GetMouseButton, mouse_event, |
| 178 PP_INPUTEVENT_MOUSEBUTTON_NONE); |
| 179 } |
| 180 |
| 181 PP_Point GetMousePosition(PP_Resource mouse_event) { |
| 182 IMPLEMENT_RESOURCE_THUNK(GetMousePosition, mouse_event, PP_MakePoint(0, 0)); |
| 183 } |
| 184 |
| 185 int32_t GetMouseClickCount(PP_Resource mouse_event) { |
| 186 IMPLEMENT_RESOURCE_THUNK(GetMouseClickCount, mouse_event, 0); |
| 187 } |
| 188 |
| 189 // Wheel ----------------------------------------------------------------------- |
| 190 |
| 191 PP_Resource CreateWheelInputEvent(PP_Instance instance, |
| 192 PP_TimeTicks time_stamp, |
| 193 uint32_t modifiers, |
| 194 const PP_FloatPoint* wheel_delta, |
| 195 const PP_FloatPoint* wheel_ticks, |
| 196 PP_Bool scroll_by_page) { |
| 197 DebugPrintf("PPB_InputEvent::CreateWheelInputEvent: instance=" |
| 198 "%"NACL_PRIu32", time_stamp=%lf, modifiers=" |
| 199 "%"NACL_PRIu32", delta.x=%d, delta.y=%d, ticks.x=%d, ticks.y=%d, " |
| 200 "scroll_by_page=%s\n", |
| 201 instance, time_stamp, modifiers, wheel_delta->x, wheel_delta->y, |
| 202 wheel_ticks->x, wheel_ticks->y, |
| 203 (scroll_by_page ? "true" : "false")); |
| 204 PP_Resource resource_id = kInvalidResourceId; |
| 205 NaClSrpcError srpc_result = |
| 206 PpbInputEventRpcClient::PPB_InputEvent_CreateWheelInputEvent( |
| 207 GetMainSrpcChannel(), |
| 208 instance, |
| 209 static_cast<double>(time_stamp), |
| 210 static_cast<int32_t>(modifiers), |
| 211 wheel_delta->x, |
| 212 wheel_delta->y, |
| 213 wheel_ticks->x, |
| 214 wheel_ticks->y, |
| 215 static_cast<int32_t>(scroll_by_page), |
| 216 &resource_id); |
| 217 if (srpc_result == NACL_SRPC_RESULT_OK) |
| 218 return resource_id; |
| 219 return kInvalidResourceId; |
| 220 } |
| 221 |
| 222 PP_Bool IsWheelInputEvent(PP_Resource resource) { |
| 223 if (!IsInputEvent(resource)) |
| 224 return PP_FALSE; |
| 225 PP_InputEvent_Type type = GetType(resource); |
| 226 return PP_FromBool(type == PP_INPUTEVENT_TYPE_WHEEL); |
| 227 } |
| 228 |
| 229 PP_FloatPoint GetWheelDelta(PP_Resource wheel_event) { |
| 230 IMPLEMENT_RESOURCE_THUNK(GetWheelDelta, wheel_event, PP_MakeFloatPoint(0, 0)); |
| 231 } |
| 232 |
| 233 PP_FloatPoint GetWheelTicks(PP_Resource wheel_event) { |
| 234 IMPLEMENT_RESOURCE_THUNK(GetWheelTicks, wheel_event, PP_MakeFloatPoint(0, 0)); |
| 235 } |
| 236 |
| 237 PP_Bool GetWheelScrollByPage(PP_Resource wheel_event) { |
| 238 IMPLEMENT_RESOURCE_THUNK(GetWheelScrollByPage, wheel_event, PP_FALSE); |
| 239 } |
| 240 |
| 241 PP_Resource CreateKeyboardInputEvent(PP_Instance instance, |
| 242 PP_InputEvent_Type type, |
| 243 PP_TimeTicks time_stamp, |
| 244 uint32_t modifiers, |
| 245 uint32_t key_code, |
| 246 struct PP_Var character_text) { |
| 247 DebugPrintf("PPB_InputEvent::CreateKeyboardInputEvent: instance=" |
| 248 "%"NACL_PRIu32", type=%d, time_stamp=%lf, modifiers=" |
| 249 "%"NACL_PRIu32", key_code=%"NACL_PRIu32"\n", |
| 250 instance, type, time_stamp, modifiers, key_code); |
| 251 // Serialize the character_text Var. |
| 252 uint32_t text_size = kMaxVarSize; |
| 253 nacl::scoped_array<char> text_bytes(Serialize(&character_text, 1, |
| 254 &text_size)); |
| 255 PP_Resource resource_id = kInvalidResourceId; |
| 256 NaClSrpcError srpc_result = |
| 257 PpbInputEventRpcClient::PPB_InputEvent_CreateKeyboardInputEvent( |
| 258 GetMainSrpcChannel(), |
| 259 instance, |
| 260 static_cast<int32_t>(type), |
| 261 static_cast<double>(time_stamp), |
| 262 static_cast<int32_t>(modifiers), |
| 263 static_cast<int32_t>(key_code), |
| 264 text_size, |
| 265 text_bytes.get(), |
| 266 &resource_id); |
| 267 if (srpc_result == NACL_SRPC_RESULT_OK) |
| 268 return resource_id; |
| 269 return kInvalidResourceId; |
| 270 } |
| 271 |
| 272 PP_Bool IsKeyboardInputEvent(PP_Resource resource) { |
| 273 if (!IsInputEvent(resource)) |
| 274 return PP_FALSE; |
| 275 PP_InputEvent_Type type = GetType(resource); |
| 276 return PP_FromBool(type == PP_INPUTEVENT_TYPE_KEYDOWN || |
| 277 type == PP_INPUTEVENT_TYPE_KEYUP || |
| 278 type == PP_INPUTEVENT_TYPE_CHAR); |
| 279 } |
| 280 |
| 281 uint32_t GetKeyCode(PP_Resource key_event) { |
| 282 IMPLEMENT_RESOURCE_THUNK(GetKeyCode, key_event, 0); |
| 283 } |
| 284 |
| 285 PP_Var GetCharacterText(PP_Resource character_event) { |
| 286 IMPLEMENT_RESOURCE_THUNK(GetCharacterText, character_event, |
| 287 PP_MakeUndefined()); |
| 288 } |
| 289 |
| 290 } // namespace |
| 291 |
| 292 namespace ppapi_proxy { |
| 293 |
| 294 // static |
| 295 const PPB_InputEvent* PluginInputEvent::GetInterface() { |
| 296 static const PPB_InputEvent input_event_interface = { |
| 297 RequestInputEvents, |
| 298 RequestFilteringInputEvents, |
| 299 ClearInputEventRequest, |
| 300 IsInputEvent, |
| 301 ::GetType, |
| 302 ::GetTimeStamp, |
| 303 ::GetModifiers |
| 304 }; |
| 305 return &input_event_interface; |
| 306 } |
| 307 |
| 308 // static |
| 309 const PPB_MouseInputEvent* PluginInputEvent::GetMouseInterface() { |
| 310 static const PPB_MouseInputEvent mouse_input_event_interface = { |
| 311 CreateMouseInputEvent, |
| 312 IsMouseInputEvent, |
| 313 ::GetMouseButton, |
| 314 ::GetMousePosition, |
| 315 ::GetMouseClickCount |
| 316 }; |
| 317 return &mouse_input_event_interface; |
| 318 } |
| 319 |
| 320 // static |
| 321 const PPB_WheelInputEvent* PluginInputEvent::GetWheelInterface() { |
| 322 static const PPB_WheelInputEvent wheel_input_event_interface = { |
| 323 CreateWheelInputEvent, |
| 324 IsWheelInputEvent, |
| 325 ::GetWheelDelta, |
| 326 ::GetWheelTicks, |
| 327 ::GetWheelScrollByPage |
| 328 }; |
| 329 return &wheel_input_event_interface; |
| 330 } |
| 331 |
| 332 // static |
| 333 const PPB_KeyboardInputEvent* PluginInputEvent::GetKeyboardInterface() { |
| 334 static const PPB_KeyboardInputEvent keyboard_input_event_interface = { |
| 335 CreateKeyboardInputEvent, |
| 336 IsKeyboardInputEvent, |
| 337 ::GetKeyCode, |
| 338 ::GetCharacterText |
| 339 }; |
| 340 return &keyboard_input_event_interface; |
| 341 } |
| 342 |
| 343 PluginInputEvent::PluginInputEvent() |
| 344 : character_text_(PP_MakeUndefined()) { |
| 345 } |
| 346 |
| 347 void PluginInputEvent::Init(const InputEventData& input_event_data, |
| 348 PP_Var character_text) { |
| 349 input_event_data_ = input_event_data; |
| 350 character_text_ = character_text; |
| 351 } |
| 352 |
| 353 PluginInputEvent::~PluginInputEvent() { |
| 354 // Release the character text. This is a no-op if it's not a string. |
| 355 PPBVarInterface()->Release(character_text_); |
| 356 } |
| 357 |
| 358 PP_InputEvent_Type PluginInputEvent::GetType() const { |
| 359 return input_event_data_.event_type; |
| 360 } |
| 361 |
| 362 PP_TimeTicks PluginInputEvent::GetTimeStamp() const { |
| 363 return input_event_data_.event_time_stamp; |
| 364 } |
| 365 |
| 366 uint32_t PluginInputEvent::GetModifiers() const { |
| 367 return input_event_data_.event_modifiers; |
| 368 } |
| 369 |
| 370 PP_InputEvent_MouseButton PluginInputEvent::GetMouseButton() const { |
| 371 return input_event_data_.mouse_button; |
| 372 } |
| 373 |
| 374 PP_Point PluginInputEvent::GetMousePosition() const { |
| 375 return input_event_data_.mouse_position; |
| 376 } |
| 377 |
| 378 int32_t PluginInputEvent::GetMouseClickCount() const { |
| 379 return input_event_data_.mouse_click_count; |
| 380 } |
| 381 |
| 382 PP_FloatPoint PluginInputEvent::GetWheelDelta() const { |
| 383 return input_event_data_.wheel_delta; |
| 384 } |
| 385 |
| 386 PP_FloatPoint PluginInputEvent::GetWheelTicks() const { |
| 387 return input_event_data_.wheel_ticks; |
| 388 } |
| 389 |
| 390 PP_Bool PluginInputEvent::GetWheelScrollByPage() const { |
| 391 return input_event_data_.wheel_scroll_by_page; |
| 392 } |
| 393 |
| 394 uint32_t PluginInputEvent::GetKeyCode() const { |
| 395 return input_event_data_.key_code; |
| 396 } |
| 397 |
| 398 PP_Var PluginInputEvent::GetCharacterText() const { |
| 399 PPBVarInterface()->AddRef(character_text_); |
| 400 return character_text_; |
| 401 } |
| 402 |
| 403 } // namespace ppapi_proxy |
| 404 |
OLD | NEW |