Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc

Issue 15011003: ppapi_simple (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Copyright Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 <fcntl.h>
6 #include <pthread.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12
13 #include <cstdlib>
14 #include <cstring>
15 #include <map>
16 #include <string>
17 #include <vector>
18
19 #include "nacl_io/kernel_wrap.h"
20 #include "nacl_io/nacl_io.h"
21
22 #include "ppapi/c/ppb_var.h"
23
24 #include "ppapi/cpp/input_event.h"
25 #include "ppapi/cpp/message_loop.h"
26 #include "ppapi/cpp/module.h"
27 #include "ppapi/cpp/rect.h"
28 #include "ppapi/cpp/size.h"
29 #include "ppapi/cpp/touch_point.h"
30 #include "ppapi/cpp/var.h"
31
32 #include "ppapi_simple/ps_event.h"
33 #include "ppapi_simple/ps_instance.h"
34 #include "ppapi_simple/ps_main.h"
35
36 static PSInstance* s_InstanceObject = NULL;
37
38 PSInstance* PSInstance::GetInstance() {
39 return s_InstanceObject;
40 }
41
42 struct StartInfo {
43 PSInstance* inst_;
44 uint32_t argc_;
45 const char** argv_;
46 };
47
48
49 // The starting point for 'main'. We create this thread to hide the real
50 // main pepper thread which must never be blocked.
51 void* PSInstance::MainThreadThunk(void *info) {
52 s_InstanceObject->Log("Got MainThreadThunk.\n");
53 StartInfo* si = static_cast<StartInfo*>(info);
54 si->inst_->main_loop_ = new pp::MessageLoop(si->inst_);
55 si->inst_->main_loop_->AttachToCurrentThread();
56
57 int ret = si->inst_->MainThread(si->argc_, si->argv_);
58 for (uint32_t i = 0; i < si->argc_; i++) {
59 delete[] si->argv_[i];
60 }
61 delete[] si->argv_;
62 delete si;
63
64 return NULL;
65 }
66
67 // The default implementation supports running a 'C' main.
68 int PSInstance::MainThread(int argc, const char *argv[]) {
69 if (main_cb_) {
70 Log("Starting MAIN.\n");
71 int ret = main_cb_(argc, argv);
72 Log("Main thread returned with %d.\n", ret);
73 return ret;
74 }
75
76 Error("No main defined.\n");
77 return 0;
78 }
79
80 PSInstance::PSInstance(PP_Instance instance, const char *argv[])
81 : pp::Instance(instance),
82 main_loop_(NULL),
83 verbosity_(PSV_LOG),
84 events_enabled_(PSE_NONE) {
85 // Set the single Instance object
86 s_InstanceObject = this;
87
88 #ifdef DEBUG
89 SetVerbosity(PSV_LOG);
90 #endif
91
92 // Place PPAPI_MAIN_USE arguments into properties map
93 while (*argv) {
94 std::string key = *argv++;
95 std::string val = *argv++;
96 properties_[key] = val;
97 }
98
99 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
100 PP_INPUTEVENT_CLASS_KEYBOARD |
101 PP_INPUTEVENT_CLASS_WHEEL |
102 PP_INPUTEVENT_CLASS_TOUCH);
103
104 ppb_core_ = static_cast<const PPB_Core*>(
105 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
106
107 ppb_var_ = static_cast<const PPB_Var*>(
108 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
109
110 ppb_view_ = static_cast<const PPB_View*>(
111 pp::Module::Get()->GetBrowserInterface(PPB_VIEW_INTERFACE));
112 }
113
114 PSInstance::~PSInstance() {}
115
116 void PSInstance::SetMain(PSMainFunc_t main) {
117 main_cb_ = main;
118 }
119
120 bool PSInstance::Init(uint32_t arg,
121 const char* argn[],
122 const char* argv[]) {
123 StartInfo* si = new StartInfo;
124
125 si->inst_ = this;
126 si->argc_ = 1;
127 si->argv_ = new const char *[arg*2+1];
128 si->argv_[0] = NULL;
129
130 // Process arguments passed into Module INIT from JavaScript
131 for (uint32_t i=0; i < arg; i++) {
132 if (argv[i]) {
133 Log("ARG %s=%s\n", argn[i], argv[i]);
134 } else {
135 Log("ARG %s\n", argn[i]);
136 }
137
138 // If we start with PM prefix set the instance argument map
139 if (0 == strncmp(argn[i], "ps_", 3)) {
140 std::string key = argn[i];
141 std::string val = argv[i];
142 properties_[key] = val;
143 continue;
144 }
145
146 // If this is the 'src' tag, then get the NMF name.
147 if (!strcmp("src", argn[i])) {
148 char *name = new char[strlen(argv[i]) + 1];
149 strcpy(name, argv[i]);
150 si->argv_[0] = name;
151 }
152 else {
153 // Otherwise turn it into arguments
154 char *key = new char[strlen(argn[i]) + 3];
155 key[0] = '-';
156 key[1] = '-';
157 strcpy(&key[2], argn[i]);
158
159 si->argv_[si->argc_++] = key;
160 if (argv[i] && argv[i][0]) {
161 char *val = new char[strlen(argv[i]) + 1];
162 strcpy(val, argv[i]);
163 si->argv_[si->argc_++] = val;
164 }
165 }
166 }
167
168 // If src was not found, set the first arg to something
169 if (NULL == si->argv_[0]) {
170 char *name = new char[5];
171 strcpy(name, "NMF?");
172 si->argv_[0] = name;
173 }
174
175 if (ProcessProperties()) {
176 pthread_t main_thread;
177 int ret = pthread_create(&main_thread, NULL, MainThreadThunk, si);
178 Log("Created thread: %d.\n", ret);
179 return ret == 0;
180 }
181
182 Log("Skipping create thread.\n");
183 return false;
184 }
185
186 const char* PSInstance::GetProperty(const char* key, const char* def) {
187 PropertyMap_t::iterator it = properties_.find(key);
188 if (it != properties_.end()) {
189 return it->second.c_str();
190 }
191 return def;
192 }
193
194 // Processes the properties passed fixed at compile time via the
195 // initialization macro, or via dynamically set embed attributes
196 // through instance DidCreate.
197 bool PSInstance::ProcessProperties() {
198 // Get the default values
199 const char* stdin_path = GetProperty("ps_stdin", "/dev/stdin");
200 const char* stdout_path = GetProperty("ps_stdout", "/dev/stdout");
201 const char* stderr_path = GetProperty("ps_stderr", "/dev/console3");
202 const char* verbosity = GetProperty("ps_verbosity", NULL);
203
204 // Reset verbosity if passed in
205 if (verbosity) SetVerbosity(static_cast<Verbosity>(atoi(verbosity)));
206
207 // Enable NaCl IO to map STDIN, STDOUT, and STDERR
208 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);
209 int fd0 = open(stdin_path, O_RDONLY);
210 dup2(fd0, 0);
211
212 int fd1 = open(stdout_path, O_WRONLY);
213 dup2(fd1, 1);
214
215 int fd2 = open(stderr_path, O_WRONLY);
216 dup2(fd2, 2);
217
218 // Set line buffering on stdout and stderr
219 setvbuf(stderr, NULL, _IOLBF, 0);
220 setvbuf(stdout, NULL, _IOLBF, 0);
221 return true;
222 }
223
224 void PSInstance::SetVerbosity(Verbosity verbosity) {
225 verbosity_ = verbosity;
226 }
227
228 void PSInstance::Log(const char *fmt, ...) {
229 if (verbosity_ >= PSV_LOG) {
230 va_list ap;
231 va_start(ap, fmt);
232 vfprintf(stdout, fmt, ap);
233 }
234 }
235
236 void PSInstance::Warn(const char *fmt, ...) {
237 if (verbosity_ >= PSV_WARN) {
238 va_list ap;
239 va_start(ap, fmt);
240 vfprintf(stdout, fmt, ap);
241 }
242 }
243
244 void PSInstance::Error(const char *fmt, ...) {
245 if (verbosity_ >= PSV_ERROR) {
246 va_list ap;
247 va_start(ap, fmt);
248 vfprintf(stderr, fmt, ap);
249 }
250 }
251
252 void PSInstance::SetEnabledEvents(uint32_t mask) {
253 events_enabled_ = mask;
254 }
255
256 void PSInstance::PostEvent(PSEventType type) {
257 assert(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST == type ||
258 PSE_MOUSELOCK_MOUSELOCKLOST == type);
259
260 if (events_enabled_ & type) {
261 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
262 memset(env, 0, sizeof(*env));
263 env->type = type;
264 event_queue_.Enqueue(env);
265 }
266 }
267
268 void PSInstance::PostEvent(PSEventType type, PP_Bool bool_value) {
269 assert(PSE_INSTANCE_DIDCHANGEFOCUS == type);
270
271 if (events_enabled_ & type) {
272 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
273 memset(env, 0, sizeof(*env));
274 env->type = type;
275 env->as_bool = bool_value;
276 event_queue_.Enqueue(env);
277 }
278 }
279
280 void PSInstance::PostEvent(PSEventType type, PP_Resource resource) {
281 assert(PSE_INSTANCE_HANDLEINPUT == type ||
282 PSE_INSTANCE_DIDCHANGEVIEW == type);
283
284 if (events_enabled_ & type) {
285 if (resource) {
286 ppb_core_->AddRefResource(resource);
287 }
288 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
289 memset(env, 0, sizeof(*env));
290 env->type = type;
291 env->as_resource = resource;
292 event_queue_.Enqueue(env);
293 }
294 }
295
296 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
297 assert(PSE_INSTANCE_HANDLEMESSAGE == type);
298
299 if (events_enabled_ & type) {
300 ppb_var_->AddRef(var);
301 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
302 memset(env, 0, sizeof(*env));
303 env->type = type;
304 env->as_var = var;
305 event_queue_.Enqueue(env);
306 }
307 }
308
309 PSEvent* PSInstance::TryAcquireEvent() {
310 return event_queue_.Dequeue(false);
311 }
312
313 PSEvent* PSInstance::WaitAcquireEvent() {
314 return event_queue_.Dequeue(true);
315 }
316
317 void PSInstance::ReleaseEvent(PSEvent* event) {
318 if (event) {
319 switch(event->type) {
320 case PSE_INSTANCE_HANDLEMESSAGE:
321 ppb_var_->Release(event->as_var);
322 break;
323 case PSE_INSTANCE_HANDLEINPUT:
324 case PSE_INSTANCE_DIDCHANGEVIEW:
325 if (event->as_resource) {
326 ppb_core_->ReleaseResource(event->as_resource);
327 }
328 break;
329 default:
330 break;
331 }
332 free(event);
333 }
334 }
335
336 void PSInstance::HandleMessage(const pp::Var& message) {
337 Log("Got Message\n");
338 PostEvent(PSE_INSTANCE_HANDLEMESSAGE, message.pp_var());
339 }
340
341 bool PSInstance::HandleInputEvent(const pp::InputEvent& event) {
342 Log("Got Input\n");
343 PostEvent(PSE_INSTANCE_HANDLEINPUT, event.pp_resource());
344 return true;
345 }
346
347 void PSInstance::DidChangeView(const pp::View& view) {
348 pp::Size new_size = view.GetRect().size();
349 Log("Got View change: %d,%d\n", new_size.width(), new_size.height());
350 PostEvent(PSE_INSTANCE_DIDCHANGEVIEW, view.pp_resource());
351 }
352
353 void PSInstance::DidChangeFocus(bool focus) {
354 Log("Got Focus change: %s\n", focus ? "FOCUS ON" : "FOCUS OFF");
355 PostEvent(PSE_INSTANCE_DIDCHANGEFOCUS, focus ? PP_TRUE : PP_FALSE);
356 }
357
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/ppapi_simple/ps_instance.h ('k') | native_client_sdk/src/libraries/ppapi_simple/ps_main.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698