ps_instance.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
1c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// Use of this source code is governed by a BSD-style license that can be 3c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// found in the LICENSE file. 4c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 5c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <errno.h> 6c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <fcntl.h> 7c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <pthread.h> 8c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <stdio.h> 9c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <stdlib.h> 10c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <sys/types.h> 11c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <sys/stat.h> 12c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 13c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <algorithm> 14c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <cstdlib> 15c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <cstring> 16c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <sstream> 17c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <string> 18c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include <vector> 19c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 20c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "nacl_io/ioctl.h" 21c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "nacl_io/kernel_wrap.h" 22c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "nacl_io/nacl_io.h" 23c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 24c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/c/ppb_var.h" 25c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 26c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/input_event.h" 27c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/message_loop.h" 28c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/module.h" 29c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/rect.h" 30c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/size.h" 31c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi/cpp/touch_point.h" 32f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "ppapi/cpp/var.h" 33c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 34c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi_simple/ps_event.h" 35c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi_simple/ps_instance.h" 36c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi_simple/ps_interface.h" 37c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#include "ppapi_simple/ps_main.h" 38c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 39c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#if defined(WIN32) 40c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#define open _open 41c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#define dup2 _dup2 42c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#endif 43c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 44c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulstatic PSInstance* s_InstanceObject = NULL; 45c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 46c9e5671691289006e9b1152d6ce20200a83010c2Brian PaulPSInstance* PSInstance::GetInstance() { 47c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return s_InstanceObject; 4834a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell} 49c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 5034a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwellstruct StartInfo { 515ab1d0aceaffbf872d7f8ebea2a6655e25bf2390Brian Paul PSInstance* inst_; 52c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul uint32_t argc_; 53c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul char** argv_; 54ff3a52643d323626f32a9f1c14464a9501e6494dBrian Paul}; 55c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 56c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 57c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// The starting point for 'main'. We create this thread to hide the real 58c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// main pepper thread which must never be blocked. 59c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid* PSInstance::MainThreadThunk(void *info) { 60d25080074f2da1ebc47cdfb5c3491740a57ec03fChia-I Wu s_InstanceObject->Trace("Got MainThreadThunk.\n"); 61c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul StartInfo* si = static_cast<StartInfo*>(info); 62c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul si->inst_->main_loop_ = new pp::MessageLoop(si->inst_); 63c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul si->inst_->main_loop_->AttachToCurrentThread(); 64c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 65c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int ret = si->inst_->MainThread(si->argc_, si->argv_); 66c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul for (uint32_t i = 0; i < si->argc_; i++) { 67c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul delete[] si->argv_[i]; 68c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 69c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul delete[] si->argv_; 70c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul delete si; 71c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 72c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Exit the entire process once the 'main' thread returns. 73c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // The error code will be available to javascript via 74c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // the exitcode paramater of the crash event. 75c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul exit(ret); 76c132e2b1db855b3c33d8b879c4a986011d631d43Brian Paul return NULL; 77c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 78c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 79c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// The default implementation supports running a 'C' main. 80c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulint PSInstance::MainThread(int argc, char *argv[]) { 81c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (!main_cb_) { 82c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Error("No main defined.\n"); 8355e341c4c2e5a6f3475a8a3e6389b904f99a6d1aBrian Paul return 0; 84c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 8511ebfd22bb451f86a492254b77c90aeb011f8d9aBrian Paul 86ba2a55ccd61d9fa5565640faefb64fd6fb0e70abBrian Paul Trace("Starting MAIN.\n"); 87c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int ret = main_cb_(argc, argv); 8810db6c2d81506bb8cc5165d07b01e93d3830978dBrian Paul Log("Main thread returned with %d.\n", ret); 89c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return ret; 90ae1fdc15238498bf025d0f0be7337e2f9dda455fBrian Paul} 91c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 92808c424b673de109babc608ec74b34f0738ed906Brian PaulPSInstance::PSInstance(PP_Instance instance) 93c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul : pp::Instance(instance), 94c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul pp::MouseLock(this), 952c3785159574e6c8640b6af3ce2ef561d095f324Brian Paul pp::Graphics3DClient(this), 96c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul main_loop_(NULL), 97c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul events_enabled_(PSE_NONE), 98c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul verbosity_(PSV_WARN), 99c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul fd_tty_(-1) { 100c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Set the single Instance object 101c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul s_InstanceObject = this; 102c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 103c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#ifdef NACL_SDK_DEBUG 104c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul SetVerbosity(PSV_LOG); 105f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#endif 106f37070bab6af350caec905ea7658e9241042b6ccIan Romanick 107f37070bab6af350caec905ea7658e9241042b6ccIan Romanick RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | 1082cf44390d1e819f23e1d7ceb3199276c9148c647Chia-I Wu PP_INPUTEVENT_CLASS_KEYBOARD | 109c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PP_INPUTEVENT_CLASS_WHEEL | 110cc289e22213c5f5fe72602ce81db992bc8f7b1adChia-I Wu PP_INPUTEVENT_CLASS_TOUCH); 111cc289e22213c5f5fe72602ce81db992bc8f7b1adChia-I Wu} 112cc289e22213c5f5fe72602ce81db992bc8f7b1adChia-I Wu 113cc289e22213c5f5fe72602ce81db992bc8f7b1adChia-I WuPSInstance::~PSInstance() {} 114559d124ed3f2070c73c5cb9c3b506ddd9cfaeb02José Fonseca 115559d124ed3f2070c73c5cb9c3b506ddd9cfaeb02José Fonsecavoid PSInstance::SetMain(PSMainFunc_t main) { 1161741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg main_cb_ = main; 1171741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg} 1181741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg 1191741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsbergbool PSInstance::Init(uint32_t arg, 1201741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg const char* argn[], 1211741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg const char* argv[]) { 1221741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg StartInfo* si = new StartInfo; 1231741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg 1241741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg si->inst_ = this; 1251741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg si->argc_ = 1; 1261741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg si->argv_ = new char *[arg+1]; 1271741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg si->argv_[0] = NULL; 1281741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg 1291741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // Process embed attributes into the environment. 1301741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // Converted the attribute names to uppercase as environment variables are 1311741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // case sensitive but are almost universally uppercase in practice. 1321741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg for (uint32_t i = 0; i < arg; i++) { 1331741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg std::string key = argn[i]; 1341741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg std::transform(key.begin(), key.end(), key.begin(), toupper); 1351741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg setenv(key.c_str(), argv[i], 1); 1361741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg } 1371741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg 1381741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // Set a default value for SRC. 1391741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg setenv("SRC", "NMF?", 0); 1401741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // Use the src tag name if ARG0 is not explicitly specified. 1411741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg setenv("ARG0", getenv("SRC"), 0); 1421741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg 1431741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg // Walk ARG0..ARGn populating argv until an argument is missing. 1441741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg for (;;) { 1451741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg std::ostringstream arg_stream; 1461741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg arg_stream << "ARG" << si->argc_; 1471741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg std::string arg_name = arg_stream.str(); 1481741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg const char* next_arg = getenv(arg_name.c_str()); 1491741ddb747ca0be284315adb4b6fe67ddf292d03Kristian Høgsberg if (NULL == next_arg) 150c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul break; 151559d124ed3f2070c73c5cb9c3b506ddd9cfaeb02José Fonseca 152559d124ed3f2070c73c5cb9c3b506ddd9cfaeb02José Fonseca char* value = new char[strlen(next_arg) + 1]; 153c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul strcpy(value, next_arg); 154c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul si->argv_[si->argc_++] = value; 155c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 156c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 157c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSInterfaceInit(); 158c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul bool props_processed = ProcessProperties(); 159c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 160c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Log arg values only once ProcessProperties has been 161c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // called so that the ps_verbosity attribute will be in 162c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // effect. 163c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul for (uint32_t i = 0; i < arg; i++) { 164fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg if (argv[i]) { 165fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg Trace("attribs[%d] '%s=%s'\n", i, argn[i], argv[i]); 166c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } else { 167fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg Trace("attribs[%d] '%s'\n", i, argn[i]); 168fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg } 169fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg } 170fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg 171fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg for (uint32_t i = 0; i < si->argc_; i++) { 172fa416106307dc193e2133aa6a29b9bcfc91f8b39Kristian Høgsberg Trace("argv[%d] '%s'\n", i, si->argv_[i]); 173c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 174c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 175c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (!props_processed) { 176c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Warn("Skipping create thread.\n"); 177c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return false; 178c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 179c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 180c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul pthread_t main_thread; 181c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int ret = pthread_create(&main_thread, NULL, MainThreadThunk, si); 182c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Trace("Created thread: %d.\n", ret); 183c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return ret == 0; 184c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 185c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 18634a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell// Processes the properties set at compile time via the 187c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul// initialization macro, or via dynamically set embed attributes 18834a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell// through instance DidCreate. 18934a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwellbool PSInstance::ProcessProperties() { 190c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Set default values 191c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul setenv("PS_STDIN", "/dev/stdin", 0); 192c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul setenv("PS_STDOUT", "/dev/stdout", 0); 193c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul setenv("PS_STDERR", "/dev/console3", 0); 194c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 195c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Reset verbosity if passed in 196c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul const char* verbosity = getenv("PS_VERBOSITY"); 197c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (verbosity) SetVerbosity(static_cast<Verbosity>(atoi(verbosity))); 198c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 199c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Enable NaCl IO to map STDIN, STDOUT, and STDERR 200c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface); 201c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int fd0 = open(getenv("PS_STDIN"), O_RDONLY); 202c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul dup2(fd0, 0); 203c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 204c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int fd1 = open(getenv("PS_STDOUT"), O_WRONLY); 205c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul dup2(fd1, 1); 206c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 207c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int fd2 = open(getenv("PS_STDERR"), O_WRONLY); 208c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul dup2(fd2, 2); 209c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 210c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul const char* tty_prefix = getenv("PS_TTY_PREFIX"); 211c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (tty_prefix) { 212c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul fd_tty_ = open("/dev/tty", O_WRONLY); 213c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (fd_tty_ >= 0) { 214c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul ioctl(fd_tty_, TIOCNACLPREFIX, const_cast<char*>(tty_prefix)); 215c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } else { 216c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Error("Failed to open /dev/tty.\n"); 217c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 218c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 219c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 220c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Set line buffering on stdout and stderr 221c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul#if !defined(WIN32) 222a833ff0f53da6e365d917bb0081d909a809b6ec1Chia-I Wu setvbuf(stderr, NULL, _IOLBF, 0); 223a833ff0f53da6e365d917bb0081d909a809b6ec1Chia-I Wu setvbuf(stdout, NULL, _IOLBF, 0); 224a73ba2d31b87e974f6846a8aaced704634f6f657Chia-I Wu#endif 225a833ff0f53da6e365d917bb0081d909a809b6ec1Chia-I Wu return true; 226c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 227c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 228c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::SetVerbosity(Verbosity verbosity) { 229c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul verbosity_ = verbosity; 230c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 231c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 232c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::VALog(Verbosity verbosity, const char *fmt, va_list args) { 233c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (verbosity <= verbosity_) { 234c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul fprintf(stderr, "ps: "); 23567a2a4e901367418a5c28e7b0963bf9c0c4762baChia-I Wu vfprintf(stderr, fmt, args); 23667a2a4e901367418a5c28e7b0963bf9c0c4762baChia-I Wu } 237301a510092859d2e214d64f4ac2ebe03d591c64bChia-I Wu} 23867a2a4e901367418a5c28e7b0963bf9c0c4762baChia-I Wu 239c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::Trace(const char *fmt, ...) { 240c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_list ap; 241c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_start(ap, fmt); 242c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul VALog(PSV_TRACE, fmt, ap); 243c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_end(ap); 244c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 245c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 246c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::Log(const char *fmt, ...) { 247c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_list ap; 248c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_start(ap, fmt); 249c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul VALog(PSV_LOG, fmt, ap); 250c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_end(ap); 251c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 252c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 253c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::Warn(const char *fmt, ...) { 254c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_list ap; 255c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_start(ap, fmt); 256c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul VALog(PSV_WARN, fmt, ap); 257c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_end(ap); 258c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 259c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 260c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::Error(const char *fmt, ...) { 261c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_list ap; 262c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_start(ap, fmt); 263c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul VALog(PSV_ERROR, fmt, ap); 264c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul va_end(ap); 265c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 266c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 267c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::SetEnabledEvents(uint32_t mask) { 268c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul events_enabled_ = mask; 269c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 270c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 271c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::PostEvent(PSEventType type) { 272aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu assert(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST == type || 273aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu PSE_MOUSELOCK_MOUSELOCKLOST == type); 274aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu 275c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (events_enabled_ & type) { 276dbb8fb8de9a9deca0ae22015e4680f4e631d6d32Chia-I Wu PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 277dbb8fb8de9a9deca0ae22015e4680f4e631d6d32Chia-I Wu memset(env, 0, sizeof(*env)); 278dbb8fb8de9a9deca0ae22015e4680f4e631d6d32Chia-I Wu env->type = type; 27934a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell event_queue_.Enqueue(env); 280c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 281c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 282c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 283c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::PostEvent(PSEventType type, PP_Bool bool_value) { 2842b36db496d34c60a3f987fa88d52bf5684713240Chia-I Wu assert(PSE_INSTANCE_DIDCHANGEFOCUS == type); 2852b36db496d34c60a3f987fa88d52bf5684713240Chia-I Wu 286d25080074f2da1ebc47cdfb5c3491740a57ec03fChia-I Wu if (events_enabled_ & type) { 2872b36db496d34c60a3f987fa88d52bf5684713240Chia-I Wu PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 288c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul memset(env, 0, sizeof(*env)); 289c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul env->type = type; 290c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul env->as_bool = bool_value; 291c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul event_queue_.Enqueue(env); 292c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 293c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 29434a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell 295cc95de82e5939586771d478e662cb458bbc42c20Chia-I Wuvoid PSInstance::PostEvent(PSEventType type, PP_Resource resource) { 29634a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell assert(PSE_INSTANCE_HANDLEINPUT == type || 297c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSE_INSTANCE_DIDCHANGEVIEW == type); 298c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 299c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (events_enabled_ & type) { 300c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (resource) { 301c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSInterfaceCore()->AddRefResource(resource); 302c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 303c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 304c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul memset(env, 0, sizeof(*env)); 305c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul env->type = type; 306c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul env->as_resource = resource; 307c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul event_queue_.Enqueue(env); 308c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 309c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 310c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 311c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::PostEvent(PSEventType type, const PP_Var& var) { 312c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul assert(PSE_INSTANCE_HANDLEMESSAGE == type); 313c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 314c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // If the user has specified a tty_prefix_ (using ioctl), then we'll give the 315c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // tty node a chance to vacuum up any messages beginning with that prefix. If 316c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // the message does not start with the prefix, the ioctl call will return 317c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // ENOENT and we'll pass the message through to the event queue. 318c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (fd_tty_ >= 0 && var.type == PP_VARTYPE_STRING) { 319c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul uint32_t message_len; 320c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul const char* message = PSInterfaceVar()->VarToUtf8(var, &message_len); 321c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul std::string message_str(message, message + message_len); 322c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 323c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // Since our message may contain null characters, we can't send it as a 324c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // naked C string, so we package it up in this struct before sending it 325c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul // to the ioctl. 326c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul struct tioc_nacl_input_string ioctl_message; 327c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul ioctl_message.length = message_len; 328c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul ioctl_message.buffer = message_str.data(); 329c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul int ret = 330c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul ioctl(fd_tty_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message)); 331c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (ret != 0 && errno != ENOTTY) { 332c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Error("ioctl returned unexpected error: %d.\n", ret); 333c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 334c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 335c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return; 336c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 337c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 338c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (events_enabled_ & type) { 339c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSInterfaceVar()->AddRef(var); 34034a61c66fd1b625a5606b795d192a49632ff1787Keith Whitwell PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 341cb4f24e51d0f4f4b867b2c01ed26d2a5ce73aeabChia-I Wu memset(env, 0, sizeof(*env)); 3425a1e25afac8eac5df1c0c9d3165b9812f54909a6Chia-I Wu env->type = type; 343cab7ea03688ec73dd71c0b969f2db30cabeb713cChia-I Wu env->as_var = var; 344c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul event_queue_.Enqueue(env); 345c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 346c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 347c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 348c9e5671691289006e9b1152d6ce20200a83010c2Brian PaulPSEvent* PSInstance::TryAcquireEvent() { 349c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return event_queue_.Dequeue(false); 350c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 351c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 352c9e5671691289006e9b1152d6ce20200a83010c2Brian PaulPSEvent* PSInstance::WaitAcquireEvent() { 353c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return event_queue_.Dequeue(true); 354c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 355c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 356c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::ReleaseEvent(PSEvent* event) { 357c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (event) { 358c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul switch(event->type) { 359c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul case PSE_INSTANCE_HANDLEMESSAGE: 360c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSInterfaceVar()->Release(event->as_var); 361c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul break; 362c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul case PSE_INSTANCE_HANDLEINPUT: 363c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul case PSE_INSTANCE_DIDCHANGEVIEW: 364c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul if (event->as_resource) { 365c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PSInterfaceCore()->ReleaseResource(event->as_resource); 366c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 367c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul break; 368c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul default: 369c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul break; 370c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 371c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul free(event); 372c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul } 373c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 374c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 375c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::HandleMessage(const pp::Var& message) { 376c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Trace("Got Message\n"); 377c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_INSTANCE_HANDLEMESSAGE, message.pp_var()); 378c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 379c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 380c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulbool PSInstance::HandleInputEvent(const pp::InputEvent& event) { 381c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_INSTANCE_HANDLEINPUT, event.pp_resource()); 382c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul return true; 383c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 384c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 385c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::DidChangeView(const pp::View& view) { 386c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul pp::Size new_size = view.GetRect().size(); 387c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Log("Got View change: %d,%d\n", new_size.width(), new_size.height()); 388c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_INSTANCE_DIDCHANGEVIEW, view.pp_resource()); 389c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 390c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 391c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::DidChangeFocus(bool focus) { 392c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Log("Got Focus change: %s\n", focus ? "FOCUS ON" : "FOCUS OFF"); 393c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_INSTANCE_DIDCHANGEFOCUS, focus ? PP_TRUE : PP_FALSE); 394c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 395c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 396c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::Graphics3DContextLost() { 397c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Log("Graphics3DContextLost\n"); 398c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST); 399c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 400c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul 401c9e5671691289006e9b1152d6ce20200a83010c2Brian Paulvoid PSInstance::MouseLockLost() { 402c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul Log("MouseLockLost\n"); 403c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul PostEvent(PSE_MOUSELOCK_MOUSELOCKLOST); 404c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul} 405c9e5671691289006e9b1152d6ce20200a83010c2Brian Paul