Home | History | Annotate | Download | only in ppapi_simple
      1 // Copyright (c) 2013 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 #ifndef PPAPI_SIMPLE_PS_INSTANCE_H_
      6 #define PPAPI_SIMPLE_PS_INSTANCE_H_
      7 
      8 #include <stdarg.h>
      9 
     10 #include "ppapi/c/pp_instance.h"
     11 #include "ppapi/c/pp_stdint.h"
     12 #include "ppapi/c/ppb_core.h"
     13 #include "ppapi/c/ppb_var.h"
     14 #include "ppapi/c/ppb_view.h"
     15 
     16 #include "ppapi/cpp/fullscreen.h"
     17 #include "ppapi/cpp/graphics_3d_client.h"
     18 #include "ppapi/cpp/instance.h"
     19 #include "ppapi/cpp/message_loop.h"
     20 #include "ppapi/cpp/mouse_lock.h"
     21 
     22 #include "ppapi/utility/completion_callback_factory.h"
     23 
     24 #include "ppapi_simple/ps_event.h"
     25 #include "ppapi_simple/ps_main.h"
     26 
     27 #include "sdk_util/thread_safe_queue.h"
     28 
     29 typedef void (*MessageHandler_t)(const pp::Var& key,
     30                                  const pp::Var& value,
     31                                  void* user_data);
     32 
     33 struct MessageHandler {
     34   MessageHandler_t handler;
     35   void* user_data;
     36 };
     37 
     38 // The basic instance class which also inherits the MouseLock and
     39 // Graphics3DClient interfaces.
     40 class PSInstance : public pp::Instance, pp::MouseLock, pp::Graphics3DClient {
     41  public:
     42   // Verbosity levels, ecplicitly numbered since we pass these
     43   // in from html attributes as numberic values.
     44   enum Verbosity {
     45     PSV_SILENT = 0,
     46     PSV_ERROR = 1,
     47     PSV_WARN = 2,
     48     PSV_LOG = 3,
     49     PSV_TRACE = 4,
     50   };
     51 
     52   // Returns a pointer to the global instance
     53   static PSInstance* GetInstance();
     54 
     55   PSInstance(PP_Instance inst);
     56   virtual ~PSInstance();
     57 
     58   // Set a function which will be called on a new thread once initialized.
     59   // NOTE:  This must be called by the Factory, once Init is called, this
     60   // function will have no effect.
     61   void SetMain(PSMainFunc_t func);
     62 
     63   // Started on Init, a thread which can be safely blocked.
     64   virtual int MainThread(int argc, char* argv[]);
     65 
     66   // Logging Functions
     67   void SetVerbosity(Verbosity verbosity);
     68   void Trace(const char *fmt, ...);
     69   void Log(const char *fmt, ...);
     70   void Warn(const char *fmt, ...);
     71   void Error(const char *fmt, ...);
     72 
     73   // Event Functions
     74   void SetEnabledEvents(uint32_t mask);
     75   void PostEvent(PSEventType type);
     76   void PostEvent(PSEventType type, PP_Bool bool_value);
     77   void PostEvent(PSEventType type, PP_Resource resource);
     78   void PostEvent(PSEventType type, const PP_Var& var);
     79 
     80   PSEvent* TryAcquireEvent();
     81   PSEvent* WaitAcquireEvent();
     82   void ReleaseEvent(PSEvent* event);
     83 
     84   // Register a message handler for messages that arrive
     85   // from JavaScript with a give names.  Messages are of the
     86   // form:  { message_name : <value> }.
     87   //
     88   // PSInstance will then not generate events but instead
     89   // cause the handler to be called upon message arrival.
     90   // If handler is NULL then the current handler will be
     91   // removed. Example usage:
     92   //
     93   // JavaScript:
     94   //   nacl_module.postMessage({'foo': 123});
     95   //
     96   // C++:
     97   //   void MyMessageHandler(const pp::Var& key,
     98   //                         const pp::Var& value,
     99   //                         void* user_data) {
    100   //     assert(key.is_string());
    101   //     assert(key.AsString() == "foo");
    102   //     assert(value.is_int());
    103   //     assert(value.AsInt() == 123);
    104   //   }
    105   //   ...
    106   //   instance_->RegisterMessageHandler("foo", &MyMessageHandler, NULL);
    107   //
    108   void RegisterMessageHandler(std::string message_name,
    109                               MessageHandler_t handler,
    110                               void* user_data);
    111 
    112   // Perform exit handshake with JavaScript.
    113   // This is called by _exit before the process is terminated to ensure
    114   // that all messages sent prior to _exit arrive at the JavaScript side.
    115   void ExitHandshake(int status);
    116 
    117  protected:
    118   typedef std::map<std::string, MessageHandler> MessageHandlerMap;
    119 
    120   // Callback functions triggered by Pepper
    121   //
    122   // These functions are called on the main pepper thread, so they must
    123   // not block.
    124   //
    125   // Called by the browser when the NaCl module is loaded and all ready to go.
    126   // This function will create a new thread which will run the pseudo main.
    127   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
    128 
    129   // Output log message to stderr if the current verbosity is set
    130   // at or above the given verbosity.
    131   void VALog(Verbosity verbosity, const char *fmt, va_list args);
    132 
    133   // Called whenever the in-browser window changes size, it will pass a
    134   // context change request to whichever thread is handling rendering.
    135   virtual void DidChangeView(const pp::View& view);
    136 
    137   // Called by the browser when the NaCl canvas gets or loses focus.
    138   virtual void DidChangeFocus(bool has_focus);
    139 
    140   // Called by the browser to handle the postMessage() call in Javascript.
    141   virtual void HandleMessage(const pp::Var& message);
    142 
    143   // Called by the browser to handle incoming input events.  Events are Q'd
    144   // and can later be processed on a sperate processing thread.
    145   virtual bool HandleInputEvent(const pp::InputEvent& event);
    146 
    147   // Called by the browser when the 3D context is lost.
    148   virtual void Graphics3DContextLost();
    149 
    150   // Called by the browser when the mouselock is lost.
    151   virtual void MouseLockLost();
    152 
    153   // Called by Init to processes default and embed tag arguments prior to
    154   // launching the 'ppapi_main' thread.
    155   virtual bool ProcessProperties();
    156 
    157  private:
    158   static void* MainThreadThunk(void *start_info);
    159   ssize_t TtyOutputHandler(const char* buf, size_t count);
    160   void MessageHandlerExit(const pp::Var& message);
    161   void MessageHandlerInput(const pp::Var& key, const pp::Var& message);
    162   void MessageHandlerResize(const pp::Var& message);
    163   void HandleResize(int width, int height);
    164 
    165   static void HandleExitStatic(int status, void* user_data);
    166 
    167   static ssize_t TtyOutputHandlerStatic(const char* buf, size_t count,
    168                                         void* user_data);
    169 
    170   /// Handle exit confirmation message from JavaScript.
    171   static void MessageHandlerExitStatic(const pp::Var& key,
    172                                        const pp::Var& message,
    173                                        void* user_data);
    174 
    175   /// Handle input message from JavaScript.  The value is
    176   /// expected to be of type string.
    177   static void MessageHandlerInputStatic(const pp::Var& key,
    178                                         const pp::Var& message,
    179                                         void* user_data);
    180 
    181 
    182   /// Handle resizs message from JavaScript.  The value is
    183   /// expected to be an array of 2 integers representing the
    184   /// number of columns and rows in the TTY.
    185   static void MessageHandlerResizeStatic(const pp::Var& key,
    186                                          const pp::Var& message,
    187                                          void* user_data);
    188 
    189  protected:
    190   pp::MessageLoop* main_loop_;
    191 
    192   sdk_util::ThreadSafeQueue<PSEvent> event_queue_;
    193   uint32_t events_enabled_;
    194   Verbosity verbosity_;
    195 
    196   // TTY handling
    197   int tty_fd_;
    198   const char* tty_prefix_;
    199   MessageHandlerMap message_handlers_;
    200 
    201   PSMainFunc_t main_cb_;
    202 
    203   const PPB_Core* ppb_core_;
    204   const PPB_Var* ppb_var_;
    205   const PPB_View* ppb_view_;
    206 
    207   // Condition variable and lock used to wait for exit confirmation from
    208   // JavaScript.
    209   pthread_cond_t exit_cond_;
    210   pthread_mutex_t exit_lock_;
    211 
    212   // A message to Post to JavaScript instead of exiting, or NULL if exit()
    213   // should be called instead.
    214   char* exit_message_;
    215 };
    216 
    217 #endif  // PPAPI_SIMPLE_PS_INSTANCE_H_
    218