- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / examples / 2d / graphics_2d_example.c
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 <stdlib.h>
6 #include <string.h>
7
8 #include "ppapi/c/pp_completion_callback.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_instance.h"
11 #include "ppapi/c/pp_module.h"
12 #include "ppapi/c/pp_rect.h"
13 #include "ppapi/c/pp_var.h"
14 #include "ppapi/c/ppb.h"
15 #include "ppapi/c/ppb_core.h"
16 #include "ppapi/c/ppb_graphics_2d.h"
17 #include "ppapi/c/ppb_image_data.h"
18 #include "ppapi/c/ppb_instance.h"
19 #include "ppapi/c/ppb_view.h"
20 #include "ppapi/c/ppp.h"
21 #include "ppapi/c/ppp_instance.h"
22
23 PPB_GetInterface g_get_browser_interface = NULL;
24
25 const PPB_Core* g_core_interface;
26 const PPB_Graphics2D* g_graphics_2d_interface;
27 const PPB_ImageData* g_image_data_interface;
28 const PPB_Instance* g_instance_interface;
29 const PPB_View* g_view_interface;
30
31 /* PPP_Instance implementation -----------------------------------------------*/
32
33 struct InstanceInfo {
34   PP_Instance pp_instance;
35   struct PP_Size last_size;
36
37   struct InstanceInfo* next;
38 };
39
40 /** Linked list of all live instances. */
41 struct InstanceInfo* all_instances = NULL;
42
43 /** Returns a refed resource corresponding to the created graphics 2d. */
44 PP_Resource MakeAndBindGraphics2D(PP_Instance instance,
45                                   const struct PP_Size* size) {
46   PP_Resource graphics;
47
48   graphics = g_graphics_2d_interface->Create(instance, size, PP_FALSE);
49   if (!graphics)
50     return 0;
51
52   if (!g_instance_interface->BindGraphics(instance, graphics)) {
53     g_core_interface->ReleaseResource(graphics);
54     return 0;
55   }
56   return graphics;
57 }
58
59 void FlushCompletionCallback(void* user_data, int32_t result) {
60   /* Don't need to do anything here. */
61 }
62
63 void Repaint(struct InstanceInfo* instance, const struct PP_Size* size) {
64   PP_Resource image, graphics;
65   struct PP_ImageDataDesc image_desc;
66   uint32_t* image_data;
67   int num_words, i;
68
69   /* Create image data to paint into. */
70   image = g_image_data_interface->Create(
71       instance->pp_instance, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, PP_TRUE);
72   if (!image)
73     return;
74   g_image_data_interface->Describe(image, &image_desc);
75
76   /* Fill the image with blue. */
77   image_data = (uint32_t*)g_image_data_interface->Map(image);
78   if (!image_data) {
79     g_core_interface->ReleaseResource(image);
80     return;
81   }
82   num_words = image_desc.stride * size->height / 4;
83   for (i = 0; i < num_words; i++)
84     image_data[i] = 0xFF0000FF;
85
86   /* Create the graphics 2d and paint the image to it. */
87   graphics = MakeAndBindGraphics2D(instance->pp_instance, size);
88   if (!graphics) {
89     g_core_interface->ReleaseResource(image);
90     return;
91   }
92
93   g_graphics_2d_interface->ReplaceContents(graphics, image);
94   g_graphics_2d_interface->Flush(graphics,
95       PP_MakeCompletionCallback(&FlushCompletionCallback, NULL));
96
97   g_core_interface->ReleaseResource(graphics);
98   g_core_interface->ReleaseResource(image);
99 }
100
101 /** Returns the info for the given instance, or NULL if it's not found. */
102 struct InstanceInfo* FindInstance(PP_Instance instance) {
103   struct InstanceInfo* cur = all_instances;
104   while (cur) {
105     if (cur->pp_instance == instance)
106       return cur;
107     cur = cur->next;
108   }
109   return NULL;
110 }
111
112 PP_Bool Instance_DidCreate(PP_Instance instance,
113                            uint32_t argc,
114                            const char* argn[],
115                            const char* argv[]) {
116   struct InstanceInfo* info =
117       (struct InstanceInfo*)malloc(sizeof(struct InstanceInfo));
118   info->pp_instance = instance;
119   info->last_size.width = 0;
120   info->last_size.height = 0;
121
122   /* Insert into linked list of live instances. */
123   info->next = all_instances;
124   all_instances = info;
125   return PP_TRUE;
126 }
127
128 void Instance_DidDestroy(PP_Instance instance) {
129   /* Find the matching item in the linked list, delete it, and patch the
130    * links.
131    */
132   struct InstanceInfo** prev_ptr = &all_instances;
133   struct InstanceInfo* cur = all_instances;
134   while (cur) {
135     if (instance == cur->pp_instance) {
136       *prev_ptr = cur->next;
137       free(cur);
138       return;
139     }
140     prev_ptr = &cur->next;
141     cur = cur->next;
142   }
143 }
144
145 void Instance_DidChangeView(PP_Instance pp_instance,
146                             PP_Resource view) {
147   struct PP_Rect position;
148   struct InstanceInfo* info = FindInstance(pp_instance);
149   if (!info)
150     return;
151
152   if (g_view_interface->GetRect(view, &position) == PP_FALSE)
153     return;
154
155   if (info->last_size.width != position.size.width ||
156       info->last_size.height != position.size.height) {
157     /* Got a resize, repaint the plugin. */
158     Repaint(info, &position.size);
159     info->last_size.width = position.size.width;
160     info->last_size.height = position.size.height;
161   }
162 }
163
164 void Instance_DidChangeFocus(PP_Instance pp_instance, PP_Bool has_focus) {
165 }
166
167 PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
168                                     PP_Resource pp_url_loader) {
169   return PP_FALSE;
170 }
171
172 static PPP_Instance instance_interface = {
173   &Instance_DidCreate,
174   &Instance_DidDestroy,
175   &Instance_DidChangeView,
176   &Instance_DidChangeFocus,
177   &Instance_HandleDocumentLoad
178 };
179
180
181 /* Global entrypoints --------------------------------------------------------*/
182
183 PP_EXPORT int32_t PPP_InitializeModule(PP_Module module,
184                                        PPB_GetInterface get_browser_interface) {
185   g_get_browser_interface = get_browser_interface;
186
187   g_core_interface = (const PPB_Core*)
188       get_browser_interface(PPB_CORE_INTERFACE);
189   g_instance_interface = (const PPB_Instance*)
190       get_browser_interface(PPB_INSTANCE_INTERFACE);
191   g_image_data_interface = (const PPB_ImageData*)
192       get_browser_interface(PPB_IMAGEDATA_INTERFACE);
193   g_graphics_2d_interface = (const PPB_Graphics2D*)
194       get_browser_interface(PPB_GRAPHICS_2D_INTERFACE);
195   g_view_interface = (const PPB_View*)
196       get_browser_interface(PPB_VIEW_INTERFACE);
197   if (!g_core_interface || !g_instance_interface || !g_image_data_interface ||
198       !g_graphics_2d_interface || !g_view_interface)
199     return -1;
200
201   return PP_OK;
202 }
203
204 PP_EXPORT void PPP_ShutdownModule() {
205 }
206
207 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
208   if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
209     return &instance_interface;
210   return NULL;
211 }