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

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: Fix enums 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.
nfullagar1 2013/05/30 18:04:52 small nit: there is some slight inconsistency in t
noelallen1 2013/05/30 21:01:44 Done.
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 //
68 // The default implementation supports running a 'C' main.
69 //
70 int PSInstance::MainThread(int argc, const char *argv[]) {
71 if (main_cb_) {
72 Log("Starting MAIN.\n");
73 int ret = main_cb_(argc, argv);
74 Log("Main thread returned with %d.\n", ret);
75 return ret;
76 }
77
78 Error("No main defined.\n");
79 return 0;
80 }
81
82 PSInstance::PSInstance(PP_Instance instance, const char *argv[])
83 : pp::Instance(instance),
84 main_loop_(NULL),
85 verbosity_(PSV_LOG),
86 events_enabled_(PSE_NONE) {
87 // Set the single Instance object
88 s_InstanceObject = this;
89
90 #ifdef DEBUG
91 SetVerbosity(PSV_LOG);
92 #endif
93
94 // Place PPAPI_MAIN_USE arguments into properties map
95 while (*argv) {
96 std::string key = *argv++;
97 std::string val = *argv++;
98 properties_[key] = val;
99 }
100
101 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
102 PP_INPUTEVENT_CLASS_KEYBOARD |
103 PP_INPUTEVENT_CLASS_WHEEL |
104 PP_INPUTEVENT_CLASS_TOUCH);
105
106 ppb_core_ = static_cast<const PPB_Core*>(
107 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
108
109 ppb_var_ = static_cast<const PPB_Var*>(
110 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
111
112 ppb_view_ = static_cast<const PPB_View*>(
113 pp::Module::Get()->GetBrowserInterface(PPB_VIEW_INTERFACE));
114 }
115
116 PSInstance::~PSInstance() {}
117
118 void PSInstance::SetMain(PSMainFunc_t main) {
119 main_cb_ = main;
120 }
121
122 bool PSInstance::Init(uint32_t arg,
123 const char* argn[],
124 const char* argv[]) {
125 StartInfo* si = new StartInfo;
126
127 si->inst_ = this;
128 si->argc_ = 1;
129 si->argv_ = new const char *[arg*2+1];
130 si->argv_[0] = NULL;
131
132 // Process arguments passed into Module INIT from JavaScript
133 for (uint32_t i=0; i < arg; i++) {
134 if (argv[i]) {
135 Log("ARG %s=%s\n", argn[i], argv[i]);
136 } else {
137 Log("ARG %s\n", argn[i]);
138 }
139
140 // If we start with PM prefix set the instance argument map
141 if (0 == strncmp(argn[i], "ps_", 3)) {
142 std::string key = argn[i];
143 std::string val = argv[i];
144 properties_[key] = val;
145 continue;
146 }
147
148 // If this is the 'src' tag, then get the NMF name.
149 if (!strcmp("src", argn[i])) {
150 char *name = new char[strlen(argv[i]) + 1];
151 strcpy(name, argv[i]);
152 si->argv_[0] = name;
153 }
154 else {
155 // Otherwise turn it into arguments
156 char *key = new char[strlen(argn[i]) + 3];
157 key[0] = '-';
158 key[1] = '-';
159 strcpy(&key[2], argn[i]);
160
161 si->argv_[si->argc_++] = key;
162 if (argv[i] && argv[i][0]) {
163 char *val = new char[strlen(argv[i]) + 1];
164 strcpy(val, argv[i]);
165 si->argv_[si->argc_++] = val;
166 }
167 }
168 }
169
170 // If src was not found, set the first arg to something
171 if (NULL == si->argv_[0]) {
172 char *name = new char[5];
173 strcpy(name, "NMF?");
174 si->argv_[0] = name;
175 }
176
177 if (ProcessProperties()) {
178 pthread_t main_thread;
179 int ret = pthread_create(&main_thread, NULL, MainThreadThunk,
180 static_cast<void*>(si));
binji 2013/05/30 05:07:50 nit: static_cast shouldn't be necessary.
noelallen1 2013/05/30 18:07:19 Done.
181 Log("Created thread: %d.\n", ret);
182 return ret == 0;
183 }
184
185 Log("Skipping create thread.\n");
186 return false;
187 }
188
189 const char* PSInstance::GetProperty(const char* key, const char* def) {
190 PropertyMap_t::iterator it = properties_.find(key);
191 if (it != properties_.end()) {
192 return it->second.c_str();
193 }
194 return def;
195 }
196
197 //
198 // ProcessProperties
199 //
200 // Processes the properties passed fixed at compile time via the
201 // initialization macro, or via dynamicallys set embed attributes
nfullagar1 2013/05/30 18:04:52 dynamically
noelallen1 2013/05/30 21:01:44 Done.
202 // through instance DidCreate.
203 //
204 bool PSInstance::ProcessProperties() {
205 // Get the default values
206 const char* stdin_path = GetProperty("ps_stdin", "/dev/stdin");
207 const char* stdout_path = GetProperty("ps_stdout", "/dev/stdout");
208 const char* stderr_path = GetProperty("ps_stderr", "/dev/console3");
209 const char* verbosity = GetProperty("ps_verbosity", NULL);
210
211 // Reset verbosity if passed in
212 if (verbosity) SetVerbosity(static_cast<Verbosity>(atoi(verbosity)));
213
214 // Enable NaCl IO to map STDIN, STDOUT, and STDERR
215 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);
216 int fd0 = open(stdin_path, O_RDONLY);
217 dup2(fd0, 0);
218
219 int fd1 = open(stdout_path, O_WRONLY);
220 dup2(fd1, 1);
221
222 int fd2 = open(stderr_path, O_WRONLY);
223 dup2(fd2, 2);
224
225 // Set line buffering on stdout and stderr
226 setvbuf(stderr, NULL, _IOLBF, 0);
227 setvbuf(stdout, NULL, _IOLBF, 0);
228 return true;
229 }
230
231 //
232 // Logging Functions
233 //
234 void PSInstance::SetVerbosity(Verbosity verbosity) {
235 verbosity_ = verbosity;
236 }
237
238 void PSInstance::Log(const char *fmt, ...) {
239 if (verbosity_ >= PSV_LOG) {
240 va_list ap;
241 va_start(ap, fmt);
242 vfprintf(stdout, fmt, ap);
243 }
244 }
245
246 void PSInstance::Warn(const char *fmt, ...) {
247 if (verbosity_ >= PSV_WARN) {
248 va_list ap;
249 va_start(ap, fmt);
250 vfprintf(stdout, fmt, ap);
251 }
252 }
253
254 void PSInstance::Error(const char *fmt, ...) {
255 if (verbosity_ >= PSV_ERROR) {
256 va_list ap;
257 va_start(ap, fmt);
258 vfprintf(stderr, fmt, ap);
259 }
260 }
261
262 //
263 // Event Functions
264 //
265 void PSInstance::SetEnabledEvents(uint32_t mask) {
266 events_enabled_ = mask;
267 }
268
269 void PSInstance::PostEvent(PSEventType type) {
270 assert(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST == type ||
271 PSE_MOUSELOCK_MOUSELOCKLOST == type);
272
273 if (events_enabled_ & type) {
274 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
275 memset(env, 0, sizeof(*env));
276 env->type = type;
277 event_queue_.Enqueue(env);
278 }
279 }
280
281 void PSInstance::PostEvent(PSEventType type, PP_Bool bool_value) {
282 assert(PSE_INSTANCE_DIDCHANGEFOCUS == type);
283
284 if (events_enabled_ & type) {
285 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
286 env->type = type;
binji 2013/05/30 05:07:50 memset here and below for consistency?
noelallen1 2013/05/30 18:07:19 Done.
287 env->as_bool = bool_value;
288 event_queue_.Enqueue(env);
289 }
290 }
291
292 void PSInstance::PostEvent(PSEventType type, PP_Resource resource) {
293 assert(PSE_INSTANCE_HANDLEINPUT == type ||
294 PSE_INSTANCE_DIDCHANGEVIEW == type);
295
296 if (events_enabled_ & type) {
297 if (resource) {
298 ppb_core_->AddRefResource(resource);
binji 2013/05/30 05:07:50 nit: indent 1 more space
noelallen1 2013/05/30 18:07:19 Done.
299 }
300 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
301 env->type = type;
302 env->as_resource = resource;
303 event_queue_.Enqueue(env);
304 }
305 }
306
307 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
308 assert(PSE_INSTANCE_HANDLEMESSAGE == type);
309
310 if (events_enabled_ & type) {
311 ppb_var_->AddRef(var);
312 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
313 env->type = type;
314 env->as_var = var;
315 event_queue_.Enqueue(env);
316 }
317 }
318
319 PSEvent* PSInstance::TryAcquireEvent() {
320 return event_queue_.Dequeue(false);
321 }
322
323 PSEvent* PSInstance::WaitAcquireEvent() {
324 return event_queue_.Dequeue(true);
325 }
326
327 void PSInstance::ReleaseEvent(PSEvent* event) {
328 if (event) {
329 switch(event->type) {
330 case PSE_INSTANCE_HANDLEMESSAGE:
331 ppb_var_->Release(event->as_var);
332 break;
333 case PSE_INSTANCE_HANDLEINPUT:
334 case PSE_INSTANCE_DIDCHANGEVIEW:
335 if (event->as_resource) {
336 ppb_core_->ReleaseResource(event->as_resource);
337 }
338 break;
339 default:
340 break;
341 }
342 free(event);
343 }
344 }
345
346 void PSInstance::HandleMessage(const pp::Var& message) {
347 Log("Got Message: \n");
binji 2013/05/30 05:07:50 print message here? Otherwise remove ": " because
noelallen1 2013/05/30 18:07:19 Done.
348 PostEvent(PSE_INSTANCE_HANDLEMESSAGE, message.pp_var());
349 }
350
351 bool PSInstance::HandleInputEvent(const pp::InputEvent& event) {
352 Log("Got Input\n");
353 PostEvent(PSE_INSTANCE_HANDLEINPUT, event.pp_resource());
354 return true;
355 }
356
357 void PSInstance::DidChangeView(const pp::View& view) {
358 pp::Size new_size = view.GetRect().size();
359 Log("Got View change: %d,%d\n", new_size.width(), new_size.height());
360 PostEvent(PSE_INSTANCE_DIDCHANGEVIEW, view.pp_resource());
361 }
362
363 void PSInstance::DidChangeFocus(bool focus) {
364 Log("Got Focus change: %s\n", focus ? "FOCUS ON" : "FOCUS OFF");
365 PostEvent(PSE_INSTANCE_DIDCHANGEFOCUS, focus ? PP_TRUE : PP_FALSE);
366 }
367
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698