FreeWRL / FreeX3D 4.3.0
cdllFreeWRL.c
1/* dllFreeWRL.cpp : Defines the exported functions for the DLL application.
2 general notes:
3 Your main program -or html page- defines a single process and main thread.
4 If you want to have more than one instance of freewrl (separate window and content)
5 in the same process, then you need to connect the 'context' to the thread
6 functionality. But your main program is all in one thread. So you can't just use
7 your main thread to select a context.
8 Here we'll use a pointer to iglobal as a context handle.
9
10*/
11#include "cdllFreeWRL.h"
12
13#include <config.h>
14#include "system.h"
15#include "libFreeWRL.h"
16// a few function prototypes from around libfreewrl
17void fwl_setConsole_writePrimitive(int ibool);
18void statusbar_set_window_size(int width, int height);
19int statusbar_handle_mouse(int mev, int butnum, int mouseX, int mouseY);
20int getCursorStyle();
21void *fwl_frontenditem_dequeue();
22char* fwl_resitem_getURL(void *res);
23int fwl_resitem_getStatus(void *res);
24void fwl_resitem_setStatus(void *resp, int status);
25int fwl_resitem_getType(void *res);
26int fwl_resitem_getMediaType(void *res);
27void fwl_resitem_enqueuNextMulti(void *res);
28void fwl_resitem_setLocalPath(void *res, char* path);
29void fwl_resitem_enqueue(void *res);
30int file2blob(void *res);
31void frontend_dequeue_get_enqueue(void *fwctx);
32int fv_parseCommandLine (int argc, char **argv, freewrl_params_t *, int *url_index);
33#ifdef SSR_SERVER
34//SSR (Server-side rendering)
35void SSRserver_enqueue_request_and_wait(void *fwctx, void *request);
36#endif //SSR_SERVER
37
38#include <malloc.h>
39
40
41// This is the constructor of a class that has been exported.
42// see dllFreeWRL.h for the class definition
43DLLFREEWRL_API void * dllFreeWRL_dllFreeWRL()
44{
45 /*STA -single threaded app- frontends -like web pages in a browser, .net forms, xaml apps-
46 can have multiple freewrl instances in different sub-windows, all running
47 in the same frontend thread. But then we can't rely on thread-lookup
48 to find which freewrl instance. But the frontend developer will have
49 a pointer to each instance. Then we look up the freewrl instance from that,
50 using this->globalcontexthandle, fwl_setCurrentHandle(), fwl_clearCurrentHandle(),
51 for the frontend-thread-synchronized part (functions called from the STA), and then
52 worker threads within libfreewrl can use thread lookup to get the global instance
53 for the backend parts. No thread locking is needed in the frontend-thread-sync part
54 -like here in dllfreewrl.cpp- because the frontend developer will program against
55 one dllfreewrl instance at a time due to it being STA.
56 If converting this cdllfreewrl C++ to flat C interface, then add an extra
57 parameter void* fwglobal to all the functions, do fwl_init_instance in the constructor
58 and have it return the gglobal as void *, and the frontend programmer will hold
59 the fwglobal pointer between calls.
60 */
61 //this->globalcontexthandle = 0;
62 return fwl_init_instance(); //before setting any structs we need a struct allocated
63}
64DLLFREEWRL_API void dllFreeWRL_setDensityFactor(void *fwctx, float density_factor){
65 fwl_setCurrentHandle(fwctx, __FILE__, __LINE__);
66 fwl_setDensityFactor(density_factor);
67 fwl_clearCurrentHandle();
68 return;
69}
70
71// handle - window handle or null
72// - if you have a window already created, you should pass in the handle,
73// - else pass null and a window will be created for you
74DLLFREEWRL_API void dllFreeWRL_onInit(void *fwctx, int width, int height, void* windowhandle, int bEai, int frontend_handles_display_thread)
75{
76 int ok;
77 struct freewrl_params *params;
78 //if( !fwl_setCurrentHandle(handle) ){
79 //this->globalcontexthandle = fwl_init_instance(); //before setting any structs we need a struct allocated
80 fwl_setCurrentHandle(fwctx, __FILE__, __LINE__);
81 /* Before we parse the command line, setup the FreeWRL default parameters */
82 params = (freewrl_params_t*) malloc( sizeof(freewrl_params_t));
83 memset(params,0,sizeof(freewrl_params_t));
84 /* Default values */
85 params->width = width; //600;
86 params->height = height; //400;
87 //params->eai = bEai;
88 params->fullscreen = 0;
89 params->winToEmbedInto = (long)windowhandle;
90 params->frontend_handles_display_thread = frontend_handles_display_thread;
91 ok = fwl_initFreeWRL(params);
92#ifndef FRONTEND_HANDLES_DISPLAY_THREAD
93 if(ok)
94 if(!frontend_handles_display_thread)
95 fwl_initializeDisplayThread();
96#endif
97//#ifdef STATUSBAR_HUD
98// statusbar_set_window_size(width, height);
99//#else
100 fwl_setScreenDim(width, height);
101//#endif
102 fwl_clearCurrentHandle();
103 return;
104}
105
106DLLFREEWRL_API void dllFreeWRL_onInitArgv(void *fwctx, int argc, char **argv, int frontend_handles_display_thread)
107{
108 int ok;
109 struct freewrl_params *params;
110 char *start_url = NULL;
111 int url_index;
112 fwl_setCurrentHandle(fwctx, __FILE__, __LINE__);
113 /* Before we parse the command line, setup the FreeWRL default parameters */
114 params = (freewrl_params_t*) malloc( sizeof(freewrl_params_t));
115 memset(params,0,sizeof(freewrl_params_t));
116 /* Default values */
117 params->width = 600;
118 params->height = 400;
119 fv_parseCommandLine(argc, argv,params, &url_index);
120 if(url_index > -1)
121 start_url = argv[url_index];
122 params->frontend_handles_display_thread = frontend_handles_display_thread;
123 ok = fwl_initFreeWRL(params);
124
125#ifndef FRONTEND_HANDLES_DISPLAY_THREAD
126 if(ok)
127 if(!frontend_handles_display_thread)
128 fwl_initializeDisplayThread();
129#endif
130 fwl_setScreenDim(params->width, params->height);
131 if(start_url)
132 fwl_replaceWorldNeeded(start_url);
133
134 fwl_clearCurrentHandle();
135 return;
136}
137
138DLLFREEWRL_API void dllFreeWRL_setTempFolder(void *fwctx, char *tmpFolder)
139{
140 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
141 fwl_tmpFileLocation(tmpFolder);
142 }
143 fwl_clearCurrentHandle();
144}
145DLLFREEWRL_API void dllFreeWRL_setFontFolder(void *fwctx,char *fontFolder)
146{
147 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
148 fwl_fontFileLocation(fontFolder);
149 }
150 fwl_clearCurrentHandle();
151}
152DLLFREEWRL_API void * dllFreeWRL_dllFreeWRL1(int width, int height, void* windowhandle, int bEai)
153{
154 void *fwctx;
155 fwctx = fwl_init_instance(); //before setting any structs we need a struct allocated
156 dllFreeWRL_onInit(fwctx, width, height, windowhandle, bEai, FALSE);
157 return fwctx;
158}
159DLLFREEWRL_API void *dllFreeWRL_dllFreeWRL2(char* scene_url, int width, int height, void* windowhandle, int bEai)
160{
161 void *fwctx;
162 fwctx = fwl_init_instance(); //before setting any structs we need a struct allocated
163 dllFreeWRL_onInit(fwctx, width, height, windowhandle, bEai, FALSE);
164 dllFreeWRL_onLoad(fwctx,scene_url);
165 return fwctx;
166}
167
168DLLFREEWRL_API void dllFreeWRL_onLoad(void *fwctx, char* scene_url)
169{
170 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
171 fwl_replaceWorldNeeded(scene_url);
172 }
173 fwl_clearCurrentHandle();
174}
175
176DLLFREEWRL_API void dllFreeWRL_onResize(void *fwctx, int width,int height){
177 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
178//#ifdef STATUSBAR_HUD
179// statusbar_set_window_size(width,height);
180//#else
181 fwl_setScreenDim(width,height);
182//#endif
183 }
184 fwl_clearCurrentHandle();
185}
186
187DLLFREEWRL_API int dllFreeWRL_onMouse(void *fwctx, int mouseAction,int mouseButton,int x, int y){
188
189 /*void fwl_handle_aqua(const int mev, const unsigned int button, int x, int y);*/
190 /* butnum=1 left butnum=3 right (butnum=2 middle, not used by freewrl) */
191 int cursorStyle = 0;
192 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
193 cursorStyle = fwl_handle_mouse(mouseAction,mouseButton,x,y,0);
194 }
195 fwl_clearCurrentHandle();
196 return cursorStyle;
197}
198DLLFREEWRL_API int dllFreeWRL_onTouch(void *fwctx, int touchAction, unsigned int ID, int x, int y) {
199
200 /*void fwl_handle_aqua(const int mev, const unsigned int button, int x, int y);*/
201 /* butnum=1 left butnum=3 right (butnum=2 middle, not used by freewrl) */
202 int cursorStyle = 0;
203 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
204 cursorStyle = fwl_handle_touch(touchAction, ID, x, y, 0);
205 }
206 fwl_clearCurrentHandle();
207 return cursorStyle;
208}
209DLLFREEWRL_API void dllFreeWRL_onGyro(void *fwctx, float rx, float ry, float rz) {
210
211 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
212 fwl_handle_gyro(rx, ry, rz);
213 }
214 fwl_clearCurrentHandle();
215 return ;
216}
217DLLFREEWRL_API void dllFreeWRL_onAccelerometer(void *fwctx, float ax, float ay, float az) {
218
219 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
220 fwl_handle_accelerometer(ax, ay, az);
221 }
222 fwl_clearCurrentHandle();
223 return;
224}
225DLLFREEWRL_API void dllFreeWRL_onMagnetic(void *fwctx, float azimuth, float pitch, float roll) {
226
227 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
228 fwl_handle_magnetic(azimuth, pitch, roll);
229 }
230 fwl_clearCurrentHandle();
231 return;
232}
233DLLFREEWRL_API void dllFreeWRL_onKey(void *fwctx, int keyAction,int keyValue){
234 int kp = keyValue;
235 int ka = keyAction;
236 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
237 switch(keyAction)
238 {
239 case KEYDOWN:
240 if(kp & 1 << 30)
241 break; //ignor - its an auto-repeat
242 case KEYUP:
243 //switch (kp)
244 //{
245 // case VK_OEM_1:
246 // kp = ';'; //could be : or ; but tolower won't lowercase it, but returns same character if it can't
247 // break;
248 // default:
249 // break;
250 //}
251 fwl_do_keyPress(kp, ka);
252 break;
253
254 case KEYPRESS: //WM_CHAR:
255 fwl_do_keyPress(kp,ka);
256 break;
257 }
258 }
259 fwl_clearCurrentHandle();
260}
261DLLFREEWRL_API void dllFreeWRL_onClose(void *fwctx)
262{
263
264 /* when finished: as of early 2014 dug9 changed the _displayThread so now fwl_doQuit() is asynchronous meaning
265 it returns here immediately, but it takes a while for libfreewrl to finish parking threads, deleting resources
266 */
267 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
268 //fwl_doQuit();
269 fwl_doQuitAndWait();
270 }
271 fwl_clearCurrentHandle();
272}
273DLLFREEWRL_API void dllFreeWRL_print(void *fwctx, char *str)
274{
275 if(fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
276 ConsoleMessage(str);
277 }
278 fwl_clearCurrentHandle();
279}
280DLLFREEWRL_API void dllFreeWRL_onDraw(void *fwctx)
281{
282 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
283#ifndef FRONTEND_GETS_FILES
284 //build with desktop.c? but frontend does displaythread? then you need the queue processor
285 frontend_dequeue_get_enqueue(fwctx);
286#endif //FRONTEND_GETS_FILES
287 fwl_draw();
288 }
289 fwl_clearCurrentHandle();
290}
291
292DLLFREEWRL_API int dllFreeWRL_getUpdatedCursorStyle(void *fwctx)
293{
294 int cstyle = 0;
295 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
296 cstyle = getCursorStyle();
297 }
298 fwl_clearCurrentHandle();
299 return cstyle;
300}
301#if !defined(NULL)
302#define NULL (char*)0
303#endif
304DLLFREEWRL_API void* dllFreeWRL_frontenditem_dequeue(void *fwctx)
305{
306 void *item = NULL;
307 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
308 item = fwl_frontenditem_dequeue();
309 }
310 fwl_clearCurrentHandle();
311 return item;
312}
313DLLFREEWRL_API char* dllFreeWRL_resitem_getURL(void *fwctx, void *res){
314 char *url = NULL;
315 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
316 url = fwl_resitem_getURL(res);
317 }
318 fwl_clearCurrentHandle();
319 return url;
320}
321DLLFREEWRL_API int dllFreeWRL_resitem_getStatus(void *fwctx, void *res){
322 int status;
323 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
324 status = fwl_resitem_getStatus(res);
325 }
326 fwl_clearCurrentHandle();
327 return status;
328}
329DLLFREEWRL_API void dllFreeWRL_resitem_setStatus(void *fwctx, void *res, int status){
330 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
331 fwl_resitem_setStatus(res, status);
332 }
333 fwl_clearCurrentHandle();
334
335}
336DLLFREEWRL_API int dllFreeWRL_resitem_getType(void *fwctx, void *res){
337 int status;
338 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
339 status = fwl_resitem_getType(res);
340 }
341 fwl_clearCurrentHandle();
342 return status;
343}
344DLLFREEWRL_API int dllFreeWRL_resitem_getMediaType(void *fwctx, void *res) {
345 int status;
346 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)) {
347 status = fwl_resitem_getMediaType(res);
348 }
349 fwl_clearCurrentHandle();
350 return status;
351}
352
353DLLFREEWRL_API void dllFreeWRL_resitem_enqueuNextMulti(void *fwctx, void *res){
354 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
355 fwl_resitem_enqueuNextMulti(res);
356 }
357 fwl_clearCurrentHandle();
358}
359DLLFREEWRL_API void dllFreeWRL_resitem_setLocalPath(void *fwctx, void *res, char* path){
360 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
361 fwl_resitem_setLocalPath(res,path);
362 }
363 fwl_clearCurrentHandle();
364}
365DLLFREEWRL_API void dllFreeWRL_resitem_load(void *fwctx, void *res){
366 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
367 if (file2blob(res))
368 fwl_resitem_enqueue(res);
369 }
370 fwl_clearCurrentHandle();
371}
372DLLFREEWRL_API void dllFreeWRL_resitem_enqueue(void *fwctx, void *res){
373 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
374 fwl_resitem_enqueue(res);
375 }
376 fwl_clearCurrentHandle();
377}
378
379#ifdef SSR_SERVER
380DLLFREEWRL_API void dllFreeWRL_SSRserver_enqueue_request_and_wait(void *fwctx, void *request){
381 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
382 SSRserver_enqueue_request_and_wait(fwctx, request);
383 }
384 fwl_clearCurrentHandle();
385}
386#endif //SSR_SERVER
387
388DLLFREEWRL_API void dllFreeWRL_commandline(void *fwctx, char *cmdline){
389 if (fwl_setCurrentHandle(fwctx, __FILE__, __LINE__)){
390 fwl_commandline(cmdline);
391 }
392 fwl_clearCurrentHandle();
393}
394
Initialization.
Definition libFreeWRL.h:72