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

Side by Side Diff: native_client_sdk/src/libraries/ppapi_main/ppapi_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 <stdio.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11
12 #include <cstdlib>
13 #include <cstring>
14 #include <map>
15 #include <string>
16 #include <vector>
17
18 #include "nacl_io/kernel_wrap.h"
19 #include "nacl_io/nacl_io.h"
20
21 #include "ppapi/cpp/input_event.h"
22 #include "ppapi/cpp/message_loop.h"
23 #include "ppapi/cpp/rect.h"
24 #include "ppapi/cpp/size.h"
25 #include "ppapi/cpp/touch_point.h"
26 #include "ppapi/cpp/var.h"
27
28 #include "ppapi_main/ppapi_event.h"
29 #include "ppapi_main/ppapi_instance.h"
30 #include "ppapi_main/ppapi_main.h"
31
32
33 PPAPIInstance* PPAPI_GetInstance() {
34 return static_cast<PPAPIInstance*>(PPAPI_GetInstanceObject());
35 }
36
37 struct StartInfo {
38 PPAPIInstance* inst_;
39 uint32_t argc_;
40 const char** argv_;
41 };
42
43
44 //
45 // The starting point for 'main'. We create this thread to hide the real
46 // main pepper thread which must never be blocked.
47 //
48 void* PPAPIInstance::MainThreadThunk(void *info) {
49 StartInfo* si = static_cast<StartInfo*>(info);
50 int ret = si->inst_->MainThread(si->argc_, si->argv_);
51
52 printf("Main thread returned with %d.\n", ret);
53 for (uint32_t i = 0; i < si->argc_; i++) {
54 delete[] si->argv_[i];
55 }
56 delete[] si->argv_;
57 delete si;
58
59 return NULL;
60 }
61
62 //
63 // Enabled with pm_use_main=False this creates a second thread where we
64 // send all input, view change, buffer swap, etc... messages. This allows us
65 // avoid blocking the main pepper thread which would otherwise recieves these
66 // messages, and may need to lock to act on them.
67 //
68 void *PPAPIInstance::EventThreadThunk(void *this_ptr) {
69 PPAPIInstance *pInst = static_cast<PPAPIInstance*>(this_ptr);
70 return pInst->EventThread();
71 }
72
73
74 //
75 // The default implementation supports running a 'C' main.
76 //
77 int PPAPIInstance::MainThread(int argc, const char *argv[]) {
78 return ppapi_main(argc, argv);
79 }
80
81
82 //
83 // The default implementation just waits to processes forwarded events.
84 //
85 void* PPAPIInstance::EventThread() {
86 render_loop_.AttachToCurrentThread();
87 render_loop_.Run();
88 printf("Event thread exiting.\n");
89 return NULL;
90 }
91
92
93 PPAPIInstance::PPAPIInstance(PP_Instance instance, const char *args[])
94 : pp::Instance(instance),
95 main_loop_(this),
96 has_focus_(false),
97 fullscreen_(this),
98 is_context_bound_(false),
99 callback_factory_(this),
100 use_main_thread_(true),
101 render_loop_(this) {
102
103 // Place PPAPI_MAIN_USE arguments into properties map
104 while (*args) {
105 std::string key = *args++;
106 std::string val = *args++;
107 properties_[key] = val;
108 }
109
110 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
111 PP_INPUTEVENT_CLASS_KEYBOARD |
112 PP_INPUTEVENT_CLASS_WHEEL |
113 PP_INPUTEVENT_CLASS_TOUCH);
114 }
115
116 PPAPIInstance::~PPAPIInstance() {}
117
118
119 bool PPAPIInstance::Init(uint32_t arg,
120 const char* argn[],
121 const char* argv[]) {
122 StartInfo* si = new StartInfo;
123
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 printf("ARG %s=%s\n", argn[i], argv[i]);
134 } else {
135 printf("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], "pm_", 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
176 if (ProcessProperties()) {
177 pthread_t main_thread;
178 int ret = pthread_create(&main_thread, NULL, MainThreadThunk,
179 static_cast<void*>(si));
180 return ret == 0;
181 }
182
183 return false;
184 }
185
186 const char* PPAPIInstance::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 bool PPAPIInstance::ProcessProperties() {
195 const char* stdin_path = GetProperty("pm_stdin", "/dev/stdin");
196 const char* stdout_path = GetProperty("pm_stdout", "/dev/stdout");
197 const char* stderr_path = GetProperty("pm_stderr", "/dev/console3");
198 const char* queue_size = GetProperty("pm_queue_size", "1024");
199
200 // Build the event Queue with a minimum size of 4
201 uint32_t queue_size_int = atoi(queue_size);
202 if (queue_size_int < 4) queue_size_int = 4;
203 event_queue_.SetSize(queue_size_int);
204
205 // Enable NaCl IO to map STDIN, STDOUT, and STDERR
206 nacl_io_init_ppapi(PPAPI_GetInstanceId(), PPAPI_GetInterface);
207 int fd0 = open(stdin_path, O_RDONLY);
208 dup2(fd0, 0);
209
210 int fd1 = open(stdout_path, O_WRONLY);
211 dup2(fd1, 1);
212
213 int fd2 = open(stderr_path, O_WRONLY);
214 dup2(fd2, 2);
215
216 setvbuf(stderr, NULL, _IOLBF, 0);
217 setvbuf(stdout, NULL, _IOLBF, 0);
218
219 const char *use_main_str = GetProperty("pm_use_main", "true");
220 use_main_thread_ = !strcasecmp(use_main_str, "true");
221
222 // Create seperate thread for processing events.
223 printf("Events on main thread = %s.\n", use_main_str);
224 if (!use_main_thread_) {
225 pthread_t event_thread;
226 int ret = pthread_create(&event_thread, NULL, EventThreadThunk,
227 static_cast<void*>(this));
228 return ret == 0;
229 }
230 return true;
231 }
232
233 void PPAPIInstance::HandleMessage(const pp::Var& message) {
234 }
235
236 bool PPAPIInstance::HandleInputEvent(const pp::InputEvent& event) {
237 PPAPIEvent* event_ptr;
238
239 // Remove a stale message if one is available
240 event_ptr = static_cast<PPAPIEvent*>(event_queue_.RemoveStaleMessage());
241 delete event_ptr;
242
243 switch (event.GetType()) {
244 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
245 case PP_INPUTEVENT_TYPE_MOUSEUP:
246 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
247 case PP_INPUTEVENT_TYPE_MOUSEENTER:
248 case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
249 pp::MouseInputEvent mouse_event(event);
250 PPAPIMouseEvent* mouse_ptr = new PPAPIMouseEvent;
251 mouse_ptr->button = mouse_event.GetButton();
252 mouse_ptr->location = mouse_event.GetPosition().pp_point();
253 mouse_ptr->delta = mouse_event.GetMovement().pp_point();
254 event_ptr = &mouse_ptr->event;
255 break;
256 }
257
258 case PP_INPUTEVENT_TYPE_WHEEL: {
259 pp::WheelInputEvent wheel_event(event);
260 PPAPIWheelEvent* wheel_ptr = new PPAPIWheelEvent;
261 wheel_ptr->by_page =
262 static_cast<uint32_t>(wheel_event.GetScrollByPage());
263 wheel_ptr->delta = wheel_event.GetDelta().pp_float_point();
264 event_ptr = &wheel_ptr->event;
265 break;
266 }
267
268 case PP_INPUTEVENT_TYPE_CHAR: {
269 pp::KeyboardInputEvent key_event(event);
270 PPAPICharEvent* char_ptr = new PPAPICharEvent;
271 strncpy(char_ptr->text,
272 key_event.GetCharacterText().DebugString().c_str(),
273 sizeof(char_ptr->text));
274 event_ptr = &char_ptr->event;
275 break;
276 }
277
278 case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
279 case PP_INPUTEVENT_TYPE_KEYDOWN:
280 case PP_INPUTEVENT_TYPE_KEYUP: {
281 pp::KeyboardInputEvent key_event(event);
282 PPAPIKeyEvent* key_ptr = new PPAPIKeyEvent;
283 key_ptr->key_code = key_event.GetKeyCode();
284 event_ptr = &key_ptr->event;
285 break;
286 }
287
288 case PP_INPUTEVENT_TYPE_TOUCHSTART:
289 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
290 case PP_INPUTEVENT_TYPE_TOUCHEND:
291 case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
292 pp::TouchInputEvent touch_event(event);
293 PPAPITouchEvent* touch_ptr = new PPAPITouchEvent;
294 touch_ptr->point_count =
295 touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_TOUCHES);
296 for (uint32_t cnt = 0; cnt < touch_ptr->point_count; cnt++) {
297 pp::TouchPoint *pnt = (pp::TouchPoint*) &touch_ptr->points[cnt];
298 *pnt = touch_event.GetTouchByIndex(PP_TOUCHLIST_TYPE_TOUCHES ,cnt);
299 }
300 event_ptr = &touch_ptr->event;
301 break;
302 }
303
304 default:
305 fprintf(stderr, "Unhandled event type %d\n", event.GetType());
306 return false;
307 }
308
309 event_ptr->event_type = event.GetType();
310 event_ptr->time_ticks = event.GetTimeStamp();
311 event_ptr->modifiers = event.GetModifiers();
312 if (!event_queue_.AddNewMessage(event_ptr)) {
313 printf("Warning: Event Queue is full, dropping message.\n");
314 }
315 return true;
316 }
317
318 PPAPIEvent* PPAPIInstance::AcquireInputEvent() {
319 return static_cast<PPAPIEvent*>(event_queue_.AcquireTopMessage());
320 }
321
322 void PPAPIInstance::ReleaseInputEvent(PPAPIEvent* event) {
323 event_queue_.ReleaseTopMessage(event);
324 }
325
326 void PPAPIInstance::DidChangeView(const pp::View& view) {
327 pp::Size new_size = view.GetRect().size();
328 printf("View changed: %dx%d\n", new_size.width(), new_size.height());
329
330 // Build or update the 3D context when the view changes.
331 if (use_main_thread_) {
332 // If using the main thread, update the context immediately
333 BuildContext(0, new_size);
334 } else {
335 // If using a seperate thread, then post the message so we can build the
336 // context on the correct thread.
337 render_loop_.PostWork(callback_factory_.NewCallback(
338 &PPAPIInstance::BuildContext, new_size));
339 }
340 }
341
342 void PPAPIInstance::DidChangeFocus(bool focus) {
343 has_focus_ = focus;
344 }
345
346 bool PPAPIInstance::ToggleFullscreen() {
347 // Ignore switch if in transition
348 if (!is_context_bound_)
349 return false;
350
351 if (fullscreen_.IsFullscreen()) {
352 if (!fullscreen_.SetFullscreen(false)) {
353 printf("Could not leave fullscreen mode\n");
354 return false;
355 }
356 } else {
357 if (!fullscreen_.SetFullscreen(true)) {
358 printf("Could not enter fullscreen mode\n");
359 return false;
360 }
361 }
362 return true;
363 }
364
365 // The default implementation calls the 'C' render function.
366 void PPAPIInstance::Render(PP_Resource ctx, uint32_t width, uint32_t height) {
367 }
368
369 void PPAPIInstance::Flushed(int32_t result) {
370 }
371
372 void PPAPIInstance::BuildContext(int32_t result, const pp::Size& new_size) {
373 size_ = new_size;
374 printf("Resized: %dx%d.\n", size_.width(), size_.height());
375 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698