1 // Copyright (c) 2012 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 "ppapi/proxy/ppp_input_event_proxy.h" 6 7 #include "ppapi/c/ppp_input_event.h" 8 #include "ppapi/proxy/host_dispatcher.h" 9 #include "ppapi/proxy/plugin_dispatcher.h" 10 #include "ppapi/proxy/ppapi_messages.h" 11 #include "ppapi/shared_impl/ppb_input_event_shared.h" 12 #include "ppapi/thunk/enter.h" 13 #include "ppapi/thunk/ppb_input_event_api.h" 14 15 using ppapi::thunk::EnterResourceNoLock; 16 using ppapi::thunk::PPB_InputEvent_API; 17 18 namespace ppapi { 19 namespace proxy { 20 21 namespace { 22 23 #if !defined(OS_NACL) 24 PP_Bool HandleInputEvent(PP_Instance instance, PP_Resource input_event) { 25 EnterResourceNoLock<PPB_InputEvent_API> enter(input_event, false); 26 if (enter.failed()) { 27 NOTREACHED(); 28 return PP_FALSE; 29 } 30 const InputEventData& data = enter.object()->GetInputEventData(); 31 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); 32 if (!dispatcher) { 33 NOTREACHED(); 34 return PP_FALSE; 35 } 36 37 // Need to send different messages depending on whether filtering is needed. 38 PP_Bool result = PP_FALSE; 39 if (data.is_filtered) { 40 dispatcher->Send(new PpapiMsg_PPPInputEvent_HandleFilteredInputEvent( 41 API_ID_PPP_INPUT_EVENT, instance, data, &result)); 42 } else { 43 dispatcher->Send(new PpapiMsg_PPPInputEvent_HandleInputEvent( 44 API_ID_PPP_INPUT_EVENT, instance, data)); 45 } 46 return result; 47 } 48 49 static const PPP_InputEvent input_event_interface = { 50 &HandleInputEvent 51 }; 52 #else 53 // The NaCl plugin doesn't need the host side interface - stub it out. 54 static const PPP_InputEvent input_event_interface = {}; 55 #endif // !defined(OS_NACL) 56 57 InterfaceProxy* CreateInputEventProxy(Dispatcher* dispatcher) { 58 return new PPP_InputEvent_Proxy(dispatcher); 59 } 60 61 } // namespace 62 63 PPP_InputEvent_Proxy::PPP_InputEvent_Proxy(Dispatcher* dispatcher) 64 : InterfaceProxy(dispatcher), 65 ppp_input_event_impl_(NULL) { 66 if (dispatcher->IsPlugin()) { 67 ppp_input_event_impl_ = static_cast<const PPP_InputEvent*>( 68 dispatcher->local_get_interface()(PPP_INPUT_EVENT_INTERFACE)); 69 } 70 } 71 72 PPP_InputEvent_Proxy::~PPP_InputEvent_Proxy() { 73 } 74 75 // static 76 const InterfaceProxy::Info* PPP_InputEvent_Proxy::GetInfo() { 77 static const Info info = { 78 &input_event_interface, 79 PPP_INPUT_EVENT_INTERFACE, 80 API_ID_PPP_INPUT_EVENT, 81 false, 82 &CreateInputEventProxy, 83 }; 84 return &info; 85 } 86 87 bool PPP_InputEvent_Proxy::OnMessageReceived(const IPC::Message& msg) { 88 if (!dispatcher()->IsPlugin()) 89 return false; 90 91 bool handled = true; 92 IPC_BEGIN_MESSAGE_MAP(PPP_InputEvent_Proxy, msg) 93 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleInputEvent, 94 OnMsgHandleInputEvent) 95 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent, 96 OnMsgHandleFilteredInputEvent) 97 IPC_MESSAGE_UNHANDLED(handled = false) 98 IPC_END_MESSAGE_MAP() 99 return handled; 100 } 101 102 void PPP_InputEvent_Proxy::OnMsgHandleInputEvent(PP_Instance instance, 103 const InputEventData& data) { 104 scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared( 105 OBJECT_IS_PROXY, instance, data)); 106 CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, 107 instance, 108 resource->pp_resource()); 109 } 110 111 void PPP_InputEvent_Proxy::OnMsgHandleFilteredInputEvent( 112 PP_Instance instance, 113 const InputEventData& data, 114 PP_Bool* result) { 115 scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared( 116 OBJECT_IS_PROXY, instance, data)); 117 *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, 118 instance, 119 resource->pp_resource()); 120 } 121 122 } // namespace proxy 123 } // namespace ppapi 124