1
2/*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "ppapi/cpp/completion_callback.h"
10#include "ppapi/cpp/graphics_2d.h"
11#include "ppapi/cpp/image_data.h"
12#include "ppapi/cpp/instance.h"
13#include "ppapi/cpp/module.h"
14#include "ppapi/cpp/var.h"
15
16#include "SkCanvas.h"
17#include "SkBitmap.h"
18#include "SkString.h"
19#include "SkThreadUtils.h"
20
21class SkiaInstance;
22
23// Used by SkDebugf
24SkiaInstance* gPluginInstance;
25
26// Main entry point for the app we're linked into
27extern int test_main();
28
29// Tokenize a command line and store it in argc and argv.
30void SkStringToProgramArgs(const SkString commandLine, int* argc, char*** argv) {
31    int numBreaks = 0;
32    const char* commandChars = commandLine.c_str();
33    for (size_t i = 0; i < strlen(commandChars); i++) {
34        if (isspace(commandChars[i])) {
35            numBreaks++;
36        }
37    }
38    int numArgs;
39    if (strlen(commandChars) > 0) {
40        numArgs = numBreaks + 1;
41    } else {
42        numArgs = 0;
43    }
44    *argc = numArgs;
45    *argv = new char*[numArgs + 1];
46    (*argv)[numArgs] = NULL;
47    char* start = (char*) commandChars;
48    int length = 0;
49    int argIndex = 0;
50    for (size_t i = 0; i < strlen(commandChars) + 1; i++) {
51        if (isspace(commandChars[i]) || '\0' == commandChars[i]) {
52            if (length > 0) {
53                char* argument = new char[length + 1];
54                memcpy(argument, start, length);
55                argument[length] = '\0';
56                (*argv)[argIndex++] = argument;
57            }
58            start = (char*) commandChars + i + 1;
59            length = 0;
60        } else {
61            length++;
62        }
63    }
64}
65
66// Run the program with the given command line.
67void RunProgram(const SkString& commandLine) {
68    int argc;
69    char** argv;
70    SkStringToProgramArgs(commandLine, &argc, &argv);
71    test_main();
72}
73
74
75// Skia's subclass of pp::Instance, our interface with the browser.
76class SkiaInstance : public pp::Instance {
77public:
78    explicit SkiaInstance(PP_Instance instance) : pp::Instance(instance) {
79        gPluginInstance = this;
80    }
81
82    virtual ~SkiaInstance() {
83        gPluginInstance = NULL;
84    }
85
86    virtual void HandleMessage(const pp::Var& var_message) {
87        // Receive a message from javascript.
88        if (var_message.is_string()) {
89            SkString msg(var_message.AsString().c_str());
90            if (msg.startsWith("init")) {
91                RunProgram(msg);
92            }
93        }
94    }
95};
96
97class SkiaModule : public pp::Module {
98public:
99    SkiaModule() : pp::Module() {}
100    virtual ~SkiaModule() {}
101
102    virtual pp::Instance* CreateInstance(PP_Instance instance) {
103        return new SkiaInstance(instance);
104    }
105};
106
107namespace pp {
108Module* CreateModule() {
109    return new SkiaModule();
110}
111}  // namespace pp
112