2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // NaCl-NPAPI Interface
35 #include "native_client/tools/npapi_runtime/npnavigator.h"
39 #include "native_client/tools/npapi_runtime/nacl_npapi.h"
43 NPNavigator::NPNavigator(NPP npp
, int* argc
, char* argv
[])
49 bitmap_shm_(kInvalidHtpHandle
) {
51 // The last two arguments are the handle number for the connection to the
52 // plungin, and for the size of NPVariant in the plugin.
54 set_channel(reinterpret_cast<Handle
>(_strtoui64(argv
[*argc
- 2],
56 set_peer_npvariant_size(strtol(argv
[*argc
- 1], NULL
, 10));
58 set_channel(static_cast<Handle
>(strtol(argv
[*argc
- 2], NULL
, 10)));
59 set_peer_npvariant_size(strtol(argv
[*argc
- 1], NULL
, 10));
65 NPNavigator::~NPNavigator() {
66 std::set
<const NPUTF8
*, StringCompare
>::iterator i
;
67 for (i
= string_set_
.begin(); i
!= string_set_
.end(); ++i
) {
68 free(const_cast<char*>(*i
));
73 int NPNavigator::Dispatch(RpcHeader
* request
, int len
) {
75 switch (request
->type
) {
77 result
= New(request
, len
);
80 result
= Destroy(request
, len
);
83 return URLNotify(request
, len
);
86 return NPBridge::Dispatch(request
, len
);
92 int NPNavigator::New(RpcHeader
* request
, int len
) {
93 RpcArg
arg(this, request
, len
);
94 arg
.Step(sizeof(RpcHeader
));
95 NPSize
* window_size
= arg
.GetSize();
96 if (0 < arg
.GetHandleCount()) {
97 bitmap_shm_
= arg
.GetHandle();
98 arg
.CloseUnusedHandles();
101 set_peer_pid(request
->pid
);
104 vecp
->base
= request
;
105 vecp
->length
= sizeof(RpcHeader
);
108 char* argn
[kMaxArg
/ 2];
109 char* argv
[kMaxArg
/ 2];
110 for (int i
= 1; i
< *argc_
; ++argc
) {
111 argn
[argc
] = argv_
[i
++];
112 argv
[argc
] = argv_
[i
++];
114 request
->error_code
= NPP_New(
115 const_cast<char *>("application/nacl-npapi-plugin"),
121 if (request
->error_code
== NPERR_NO_ERROR
) {
122 NPObject
* object
= NPP_GetScriptableInstance(npp());
124 NPCapability capability
;
125 CreateStub(object
, &capability
);
126 vecp
->base
= &capability
;
127 vecp
->length
= sizeof capability
;
131 if (bitmap_shm_
!= kInvalidHtpHandle
&&
132 0 < window_size
->width
&& window_size
->height
) {
133 window_
.window
= reinterpret_cast<void*>(bitmap_shm_
);
136 window_
.width
= window_size
->width
;
137 window_
.height
= window_size
->height
;
138 window_
.clipRect
.top
= 0;
139 window_
.clipRect
.left
= 0;
140 window_
.clipRect
.right
= window_
.width
;
141 window_
.clipRect
.bottom
= window_
.height
;
142 window_
.type
= NPWindowTypeDrawable
;
143 NPP_SetWindow(npp(), &window_
);
147 return Respond(request
, vecv
, vecp
- vecv
);
150 int NPNavigator::Destroy(RpcHeader
* request
, int len
) {
153 vecp
->base
= request
;
154 vecp
->length
= sizeof(RpcHeader
);
156 request
->error_code
= NPP_Destroy(npp(), NULL
);
157 return Respond(request
, vecv
, vecp
- vecv
);
160 int NPNavigator::GetPluginScriptableObject(RpcHeader
* request
, int len
) {
163 vecp
->base
= request
;
164 vecp
->length
= sizeof(RpcHeader
);
166 return Respond(request
, vecv
, vecp
- vecv
);
169 void NPNavigator::SetStatus(const char* message
) {
171 request
.type
= RPC_SET_STATUS
;
174 vecp
->base
= &request
;
175 vecp
->length
= sizeof request
;
177 vecp
->base
= const_cast<char*>(message
);
178 vecp
->length
= strlen(message
) + 1;
180 Request(&request
, vecv
, vecp
- vecv
, NULL
);
183 NPError
NPNavigator::GetValue(nacl::RpcType type
, void* value
) {
188 vecp
->base
= &request
;
189 vecp
->length
= sizeof request
;
192 RpcHeader
* reply
= Request(&request
, vecv
, vecp
- vecv
, &length
);
194 return NPERR_GENERIC_ERROR
;
196 RpcArg
result(this, reply
, length
);
197 result
.Step(sizeof(RpcHeader
));
198 if (reply
->error_code
== NPERR_NO_ERROR
) {
199 *static_cast<NPObject
**>(value
) = result
.GetObject();
201 return reply
->error_code
;
204 void NPNavigator::InvalidateRect(NPRect
* invalid_rect
) {
206 request
.type
= RPC_INVALIDATE_RECT
;
209 vecp
->base
= &request
;
210 vecp
->length
= sizeof request
;
212 vecp
->base
= invalid_rect
;
213 vecp
->length
= sizeof(*invalid_rect
);
216 Request(&request
, vecv
, vecp
- vecv
, &length
);
219 void NPNavigator::ForceRedraw() {
221 request
.type
= RPC_FORCE_REDRAW
;
224 vecp
->base
= &request
;
225 vecp
->length
= sizeof request
;
228 Request(&request
, vecv
, vecp
- vecv
, &length
);
231 NPObject
* NPNavigator::CreateArray() {
233 request
.type
= RPC_CREATE_ARRAY
;
236 vecp
->base
= &request
;
237 vecp
->length
= sizeof request
;
240 RpcHeader
* reply
= Request(&request
, vecv
, vecp
- vecv
, &length
);
244 RpcArg
result(this, reply
, length
);
245 result
.Step(sizeof request
);
246 return result
.GetObject();
249 NPError
NPNavigator::OpenURL(const char* url
, void* notify_data
,
250 void (*notify
)(const char* url
, void* notify_data
,
252 if (notify_
!= NULL
|| url
== NULL
|| notify
== NULL
) {
253 return NPERR_GENERIC_ERROR
;
257 request
.type
= RPC_OPEN_URL
;
260 vecp
->base
= &request
;
261 vecp
->length
= sizeof request
;
263 vecp
->base
= const_cast<char*>(url
);
264 vecp
->length
= strlen(url
) + 1;
267 RpcHeader
* reply
= Request(&request
, vecv
, vecp
- vecv
, &length
);
269 return NPERR_GENERIC_ERROR
;
271 NPError nperr
= static_cast<NPError
>(reply
->error_code
);
272 if (nperr
== NPERR_NO_ERROR
) {
274 notify_data_
= notify_data
;
279 #endif // NACL_WINDOWS
284 int NPNavigator::URLNotify(RpcHeader
* request
, int len
) {
287 vecp
->base
= request
;
288 vecp
->length
= sizeof(RpcHeader
);
291 RpcArg
arg(this, request
, len
);
292 HtpHandle received_handle
= kInvalidHtpHandle
;
293 if (0 < arg
.GetHandleCount()) {
294 received_handle
= arg
.GetHandle();
295 arg
.CloseUnusedHandles();
297 arg
.Step(sizeof(RpcHeader
));
298 uint32_t reason
= request
->error_code
;
299 if (reason
!= NPRES_DONE
) {
300 Close(received_handle
);
301 HtpHandle received_handle
= kInvalidHtpHandle
;
304 notify_(url_
, notify_data_
, received_handle
);
310 clear_handle_count();
311 return Respond(request
, vecv
, vecp
- vecv
);
314 const NPUTF8
* NPNavigator::GetStringIdentifier(const NPUTF8
* name
) {
315 std::set
<const NPUTF8
*, StringCompare
>::iterator i
;
316 i
= string_set_
.find(name
);
317 if (i
!= string_set_
.end()) {
321 name
= _strdup(name
);
324 #endif // NACL_WINDOWS
328 std::pair
<std::set
<const NPUTF8
*, StringCompare
>::iterator
, bool> result
;
329 result
= string_set_
.insert(name
);
330 return *result
.first
;