-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathnacl.cpp
More file actions
355 lines (293 loc) · 11.4 KB
/
Copy pathnacl.cpp
File metadata and controls
355 lines (293 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "naclcontext.h"
#include "naclfile.h"
#include "demo.h"
NaCLContext* psNaCLContext = NULL;
/**
* Creates new string PP_Var from C string. The resulting object will be a
* refcounted string object. It will be AddRef()ed for the caller. When the
* caller is done with it, it should be Release()d.
* @param[in] str C string to be converted to PP_Var
* @return PP_Var containing string.
*/
static struct PP_Var CStrToVar(const char* str) {
if (psNaCLContext->psVarInterface != NULL) {
return psNaCLContext->psVarInterface->VarFromUtf8(str, strlen(str));
}
return PP_MakeUndefined();
}
void SendString(const char* str)
{
psNaCLContext->psMessagingInterface->PostMessage(psNaCLContext->hModule, CStrToVar(str));
}
void SendInteger(int val)
{
psNaCLContext->psMessagingInterface->PostMessage(psNaCLContext->hModule, PP_MakeInt32(val));
}
void DrawFrame(void* user_data, int32_t result)
{
glSetCurrentContextPPAPI(psNaCLContext->hRenderContext);
DemoRender(psNaCLContext);
glSetCurrentContextPPAPI(0);
PP_CompletionCallback cc = PP_MakeCompletionCallback(DrawFrame, 0);
psNaCLContext->psG3D->SwapBuffers(psNaCLContext->hRenderContext, cc);
}
/**
* Called when the NaCl module is instantiated on the web page. The identifier
* of the new instance will be passed in as the first argument (this value is
* generated by the browser and is an opaque handle). This is called for each
* instantiation of the NaCl module, which is each time the <embed> tag for
* this module is encountered.
*
* If this function reports a failure (by returning @a PP_FALSE), the NaCl
* module will be deleted and DidDestroy will be called.
* @param[in] instance The identifier of the new instance representing this
* NaCl module.
* @param[in] argc The number of arguments contained in @a argn and @a argv.
* @param[in] argn An array of argument names. These argument names are
* supplied in the <embed> tag, for example:
* <embed id="nacl_module" dimensions="2">
* will produce two arguments, one named "id" and one named "dimensions".
* @param[in] argv An array of argument values. These are the values of the
* arguments listed in the <embed> tag. In the above example, there will
* be two elements in this array, "nacl_module" and "2". The indices of
* these values match the indices of the corresponding names in @a argn.
* @return @a PP_TRUE on success.
*/
static PP_Bool Instance_DidCreate(PP_Instance instance,
uint32_t argc,
const char* argn[],
const char* argv[])
{
psNaCLContext->hRenderContext = 0;
psNaCLContext->hModule = instance;
psNaCLContext->psInputEventInterface->RequestInputEvents(instance, PP_INPUTEVENT_CLASS_KEYBOARD | PP_INPUTEVENT_CLASS_MOUSE);
return PP_TRUE;
}
/**
* Called when the NaCl module is destroyed. This will always be called,
* even if DidCreate returned failure. This routine should deallocate any data
* associated with the instance.
* @param[in] instance The identifier of the instance representing this NaCl
* module.
*/
static void Instance_DidDestroy(PP_Instance instance) {
psNaCLContext->psCore->ReleaseResource(psNaCLContext->hRenderContext);
psNaCLContext->hRenderContext = 0;
psNaCLContext->hModule = 0;
}
/**
* Called when the position, the size, or the clip rect of the element in the
* browser that corresponds to this NaCl module has changed.
* @param[in] instance The identifier of the instance representing this NaCl
* module.
* @param[in] position The location on the page of this NaCl module. This is
* relative to the top left corner of the viewport, which changes as the
* page is scrolled.
* @param[in] clip The visible region of the NaCl module. This is relative to
* the top left of the plugin's coordinate system (not the page). If the
* plugin is invisible, @a clip will be (0, 0, 0, 0).
*/
static void Instance_DidChangeView(PP_Instance instance,
PP_Resource view_resource) {
struct PP_Rect pos;
int bFirstCall = 0;
psNaCLContext->psView->GetRect(view_resource, &pos);
if (pos.size.width == 0 || pos.size.height == 0)
{
return;
}
psNaCLContext->i32PluginWidth = pos.size.width;
psNaCLContext->i32PluginHeight = pos.size.height;
if(psNaCLContext->hRenderContext == 0)
{
bFirstCall = 1;
}
if(psNaCLContext->hRenderContext == 0)
{
int32_t attribs[] = {
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 16,
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
PP_GRAPHICS3DATTRIB_SAMPLES, 4,
PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 1,
PP_GRAPHICS3DATTRIB_WIDTH, psNaCLContext->i32PluginWidth,
PP_GRAPHICS3DATTRIB_HEIGHT, psNaCLContext->i32PluginHeight,
PP_GRAPHICS3DATTRIB_NONE,
};
psNaCLContext->hRenderContext = psNaCLContext->psG3D->Create(psNaCLContext->hModule, NULL, attribs);
psNaCLContext->psInstanceInterface->BindGraphics(psNaCLContext->hModule, psNaCLContext->hRenderContext);
if(bFirstCall)
{
DemoInit(psNaCLContext, psNaCLContext->i32PluginWidth, psNaCLContext->i32PluginHeight);
}
PP_CompletionCallback cc = PP_MakeCompletionCallback(DrawFrame, 0);
psNaCLContext->psCore->CallOnMainThread(0, cc, PP_OK);
}
else
{
psNaCLContext->psG3D->ResizeBuffers(psNaCLContext->hRenderContext,
psNaCLContext->i32PluginWidth,
psNaCLContext->i32PluginHeight);
}
}
/**
* Notification that the given NaCl module has gained or lost focus.
* Having focus means that keyboard events will be sent to the NaCl module
* represented by @a instance. A NaCl module's default condition is that it
* will not have focus.
*
* Note: clicks on NaCl modules will give focus only if you handle the
* click event. You signal if you handled it by returning @a true from
* HandleInputEvent. Otherwise the browser will bubble the event and give
* focus to the element on the page that actually did end up consuming it.
* If you're not getting focus, check to make sure you're returning true from
* the mouse click in HandleInputEvent.
* @param[in] instance The identifier of the instance representing this NaCl
* module.
* @param[in] has_focus Indicates whether this NaCl module gained or lost
* event focus.
*/
static void Instance_DidChangeFocus(PP_Instance instance,
PP_Bool has_focus) {
}
/**
* Handler that gets called after a full-frame module is instantiated based on
* registered MIME types. This function is not called on NaCl modules. This
* function is essentially a place-holder for the required function pointer in
* the PPP_Instance structure.
* @param[in] instance The identifier of the instance representing this NaCl
* module.
* @param[in] url_loader A PP_Resource an open PPB_URLLoader instance.
* @return PP_FALSE.
*/
static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,
PP_Resource url_loader) {
/* NaCl modules do not need to handle the document load function. */
return PP_FALSE;
}
/**
* Entry points for the module.
* Initialize needed interfaces: PPB_Core, PPB_Messaging and PPB_Var.
* @param[in] a_module_id module ID
* @param[in] get_browser pointer to PPB_GetInterface
* @return PP_OK on success, any other value on failure.
*/
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id,
PPB_GetInterface get_browser)
{
psNaCLContext = (NaCLContext*)malloc(sizeof(NaCLContext));
psNaCLContext->psMessagingInterface =
(PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
psNaCLContext->psVarInterface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
if(!glInitializePPAPI(get_browser))
{
return PP_ERROR_FAILED;
}
psNaCLContext->psGL = (PPB_OpenGLES2*)get_browser(PPB_OPENGLES2_INTERFACE);
psNaCLContext->psG3D = (PPB_Graphics3D*)get_browser(PPB_GRAPHICS_3D_INTERFACE);
psNaCLContext->psInstanceInterface = (PPB_Instance*)get_browser(PPB_INSTANCE_INTERFACE);
psNaCLContext->psView = (PPB_View*)get_browser(PPB_VIEW_INTERFACE);
psNaCLContext->psCore = (PPB_Core*)get_browser(PPB_CORE_INTERFACE);
psNaCLContext->psVar = (PPB_Var*)get_browser(PPB_VAR_INTERFACE);
psNaCLContext->psInputEventInterface = (PPB_InputEvent*)get_browser(PPB_INPUT_EVENT_INTERFACE);
psNaCLContext->psKeyboard = (PPB_KeyboardInputEvent*)get_browser(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
psNaCLContext->psURLRequest = (PPB_URLRequestInfo*) get_browser(PPB_URLREQUESTINFO_INTERFACE);
psNaCLContext->psURLLoader = (PPB_URLLoader*) get_browser(PPB_URLLOADER_INTERFACE);
return PP_OK;
}
void Messaging_HandleMessage(PP_Instance instance, struct PP_Var message)
{
uint32_t ui32MessageLength = 0;
const char* pszMessage = 0;
switch(message.type)
{
case PP_VARTYPE_STRING:
{
pszMessage = psNaCLContext->psVar->VarToUtf8(message, &ui32MessageLength);
DemoHandleString(psNaCLContext, pszMessage, ui32MessageLength);
break;
}
case PP_VARTYPE_NULL:
case PP_VARTYPE_BOOL:
case PP_VARTYPE_INT32:
case PP_VARTYPE_DOUBLE:
case PP_VARTYPE_OBJECT:
case PP_VARTYPE_ARRAY:
case PP_VARTYPE_DICTIONARY:
case PP_VARTYPE_ARRAY_BUFFER:
case PP_VARTYPE_UNDEFINED:
default:
{
break;
}
}
}
PP_Bool InputEvent_HandleEvent(PP_Instance instance_id, PP_Resource input_event)
{
uint32_t ui32KeyCode;
PP_InputEvent_Type eInputEventType =
psNaCLContext->psInputEventInterface->GetType(input_event);
if(eInputEventType == PP_INPUTEVENT_TYPE_KEYDOWN)
{
ui32KeyCode = psNaCLContext->psKeyboard->GetKeyCode(input_event);
DemoHandleKeyDown(ui32KeyCode);
}
else
if(eInputEventType == PP_INPUTEVENT_TYPE_KEYUP)
{
ui32KeyCode = psNaCLContext->psKeyboard->GetKeyCode(input_event);
DemoHandleKeyUp(ui32KeyCode);
}
return PP_TRUE;
}
/**
* Returns an interface pointer for the interface of the given name, or NULL
* if the interface is not supported.
* @param[in] interface_name name of the interface
* @return pointer to the interface
*/
PP_EXPORT const void* PPP_GetInterface(const char* interface_name)
{
static PPP_Instance instance_interface =
{
&Instance_DidCreate,
&Instance_DidDestroy,
&Instance_DidChangeView,
&Instance_DidChangeFocus,
&Instance_HandleDocumentLoad
};
static PPP_InputEvent input_event_interface =
{
&InputEvent_HandleEvent
};
static PPP_Messaging messaging_interface =
{
&Messaging_HandleMessage
};
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
{
return &instance_interface;
}
if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)
{
return &input_event_interface;
}
if(strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0)
{
return &messaging_interface;
}
return NULL;
}
/**
* Called before the plugin module is unloaded.
*/
PP_EXPORT void PPP_ShutdownModule() {
DemoEnd();
glTerminatePPAPI();
}