Added LICENSE; Added GPL2 header to all source code files
[ArenaLive.git] / ns-unix.c
blobb617da70cf4a97c5fc4ea8353d5830282b60daf3
1 /*
2 * (C) Copyright 2009 ZeXx86 (zexx86@gmail.com)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <signal.h>
29 #include <GL/glx.h>
31 #include "glugin.h"
33 static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
35 /* prototypes */
36 void plugin_process_handler (pluginData *, Window, Visual *);
39 NPError NP_Initialize (NPNetscapeFuncs *nsTable, NPPluginFuncs *pluginFuncs)
41 Log ("init");
43 /* this is respectfully taken from mplayerplug-in, as it was observed
44 * and proved to be extremely useful. */
45 if ((nsTable == NULL) || (pluginFuncs == NULL))
46 return NPERR_INVALID_FUNCTABLE_ERROR;
48 Log ("table ok");
50 if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
51 return NPERR_INCOMPATIBLE_VERSION_ERROR;
53 Log ("table version ok");
55 /*check for table size removed, probable alignment or such problems.
58 if (nsTable->size < sizeof(NPNetscapeFuncs))
59 return NPERR_INVALID_FUNCTABLE_ERROR;
60 Log("table size ok");
64 if (pluginFuncs->size < sizeof (NPPluginFuncs))
65 return NPERR_INVALID_FUNCTABLE_ERROR;
67 Log ("ok pluginfuncs size check");
69 Log ("ok initing");
71 gNetscapeFuncs.version = nsTable->version;
72 gNetscapeFuncs.size = nsTable->size;
73 gNetscapeFuncs.posturl = nsTable->posturl;
74 gNetscapeFuncs.geturl = nsTable->geturl;
75 gNetscapeFuncs.requestread = nsTable->requestread;
76 gNetscapeFuncs.newstream = nsTable->newstream;
77 gNetscapeFuncs.write = nsTable->write;
78 gNetscapeFuncs.destroystream = nsTable->destroystream;
79 gNetscapeFuncs.status = nsTable->status;
80 gNetscapeFuncs.uagent = nsTable->uagent;
81 gNetscapeFuncs.memalloc = nsTable->memalloc;
82 gNetscapeFuncs.memfree = nsTable->memfree;
83 gNetscapeFuncs.memflush = nsTable->memflush;
84 gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
85 gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
86 gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
87 gNetscapeFuncs.getvalue = nsTable->getvalue;
88 gNetscapeFuncs.setvalue = nsTable->setvalue;
90 pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
91 pluginFuncs->size = sizeof (NPPluginFuncs);
92 pluginFuncs->newp = NPP_New;
93 pluginFuncs->destroy = NPP_Destroy;
94 pluginFuncs->event = NPP_HandleEvent;
95 pluginFuncs->setwindow = NPP_SetWindow;
96 pluginFuncs->print = NPP_Print;
97 pluginFuncs->newstream = NPP_NewStream;
98 pluginFuncs->destroystream = NPP_DestroyStream;
99 pluginFuncs->asfile = NPP_StreamAsFile;
100 pluginFuncs->writeready = NPP_WriteReady;
101 pluginFuncs->write = NPP_Write;
103 return NPERR_NO_ERROR;
106 NPError NP_Shutdown ()
108 Log ("shutdown");
110 return NPERR_NO_ERROR;
114 char *NP_GetMIMEDescription ()
116 Log ("get mime");
117 return "x-application/glugin:gln:Glugin;";
120 NPError NP_GetValue (void *instance, NPPVariable variable, void *value)
122 Log ("get value");
124 switch (variable) {
125 case NPPVpluginNameString:
126 (*(char **) value) = "Arena Live";
127 break;
128 case NPPVpluginDescriptionString:
129 (*(char **) value) = "Arena Live plugin";
130 break;
131 default:
132 return NPERR_INVALID_PARAM;
135 return NPERR_NO_ERROR;
138 NPError NPP_New (
139 NPMIMEType mime,
140 NPP instance,
141 uint16 mode,
142 int16 argc, char *argn[], char *argv[],
143 NPSavedData *saved)
145 int i;
146 pluginData *pd;
148 Log ("new p");
150 gNetscapeFuncs.setvalue (instance, NPPVpluginTransparentBool, false);
152 instance->pdata = gNetscapeFuncs.memalloc (sizeof (pluginData));
154 Log ("allocated");
156 pd = pdof (instance);
158 pd->exit_request = 0;
159 pd->exit_ack = 0;
160 pd->has_window = 0;
162 pd->conparam = 0;
163 pd->action = -1;
165 for (i = 0; i < argc; ++ i) {
166 if (!strcmp (argn[i], "conparam")) {
167 Log ("html tag parameter - conparam");
169 pd->conparam = strdup (argv[i]);
170 } else
171 if (!strcmp (argn[i], "action")) {
172 Log ("html tag parameter - action");
174 pd->action = atoi (argv[i]);
179 return NPERR_NO_ERROR;
182 void set_nonblock (int fd)
184 long flags = fcntl (fd, F_GETFL, 0);
186 flags |= (O_NONBLOCK | O_NDELAY);
188 fcntl (fd, F_SETFL, flags);
191 NPError NPP_SetWindow (NPP instance, NPWindow *w)
193 pluginData *pd = pdof (instance);
194 pid_t child;
195 int pw[2], pr[2];
197 if (!w) {
198 Log ("setwindow: destroyed");
199 return NPERR_NO_ERROR;
202 if (!pd->has_window) {
203 pd->has_window = 1;
205 pipe (pw);
206 pipe (pr);
208 set_nonblock (pr[0]);
209 set_nonblock (pr[1]);
210 set_nonblock (pw[0]);
211 set_nonblock (pw[1]);
213 child = fork ();
215 if (child == -1)
216 return NPERR_MODULE_LOAD_FAILED_ERROR;
218 if (!child) {
219 Log ("in new process!");
221 close (pw[1]);
222 close (pr[0]);
224 pd->pw = fdopen (pr[1], "w");
225 pd->pr = fdopen (pw[0], "r");
227 /* TODO check if setsid is needed here */
229 plugin_process_handler (pd, pd->win = (Window) (w->window), ((NPSetWindowCallbackStruct *) (w->ws_info))->visual);
231 _exit (0);
232 } else {
233 pd->child = child;
235 close (pw[0]);
236 close (pr[1]);
238 pd->pw = fdopen (pw[1], "w");
239 pd->pr = fdopen (pr[0], "r");
243 // we don't really care about window resize events, as long as
244 // it can catch them by native methods
246 return NPERR_NO_ERROR;
250 int16 NPP_HandleEvent (NPP instance, void *event)
252 Log ("event");
254 return true;
257 NPError NPP_Destroy (NPP instance, NPSavedData **saved)
259 pluginData *pd = pdof (instance);
261 Log ("killing child...");
263 kill (pd->child, SIGUSR1);
265 fclose (pd->pw);
266 fclose (pd->pr);
268 usleep (10000);
270 //TODO
271 //wait until the child really terminates. Mutexes?
273 gNetscapeFuncs.memfree (instance->pdata);
274 Log ("deleted ok");
276 return NPERR_NO_ERROR;
279 void NPP_Print (NPP instance, NPPrint *printInfo)
281 Log ("attempt to print");
284 NPError NPP_NewStream (NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16* stype)
286 Log ("new stream");
288 host_newstream (pdof (instance), stream);
290 return NPERR_NO_ERROR;
293 NPError NPP_DestroyStream (NPP instance, NPStream *stream, NPReason reason)
295 Log ("destroy stream");
297 host_destroystream (pdof (instance), stream);
299 return NPERR_NO_ERROR;
302 int32 NPP_Write (NPP instance, NPStream *stream, int32 offset, int32 len, void *buf)
304 Log ("write %d",len);
306 host_write (pdof (instance), stream, offset, len, buf);
308 return len;
311 void NPP_StreamAsFile (NPP instance, NPStream* stream, const char* fname)
313 Log ("as file:");
314 Log (fname);
317 int32 NPP_WriteReady (NPP instance, NPStream *stream)
319 Log("write ready");
321 return 1024; //ooh replace.
324 void resize (Display *dpy, Window win)
326 XWindowAttributes wa;
328 XGetWindowAttributes (dpy, win, &wa);
330 glViewport (0,0,wa.width, wa.height);
334 static pluginData *g_pd;
336 void sig_usr1 (int i)
338 g_pd->exit_request = 1;
341 void swapbuffers (pluginData *pd)
343 glXSwapBuffers (pd->dpy, pd->win);
346 void plugin_process_handler (pluginData *pd, Window win, Visual *vis)
348 g_pd = pd;
350 pd->win = win;
352 signal (SIGUSR1, sig_usr1);
354 /* call action function */
355 plugin_action (pd);
357 Log ("plugin killed, cleaning up.");
359 fclose (pd->pw);
360 fclose (pd->pr);
362 //glXMakeCurrent(dpy, None, 0);
363 //glXDestroyContext(dpy,ctx);
365 if (pd->conparam)
366 free (pd->conparam);
369 void writedata (FILE *f, void *x, unsigned len)
371 fwrite (x, len, sizeof (char), f);
374 void host_newstream (pluginData *pd, NPStream *s)
376 writedata (pd->pw, (void *) gln_new_stream, sizeof (int));
377 writedata (pd->pw, (void *) &s, sizeof (NPStream));
379 fflush (pd->pw);
382 void host_destroystream (pluginData*pd, NPStream*s)
384 writedata (pd->pw, (void *) gln_destroy_stream, sizeof (int));
385 writedata (pd->pw, (void *) s, sizeof (NPStream));
387 fflush (pd->pw);
390 void host_write (pluginData *pd, NPStream *s, int32 off, int32 siz, void *data)
392 writedata (pd->pw, (void *) gln_stream_data, sizeof (int));
393 writedata (pd->pw, (void *) s, sizeof (NPStream));
394 writedata (pd->pw, (void *) &off, sizeof (off));
395 writedata (pd->pw, (void *) &siz, sizeof (off));
397 fwrite (data, siz, sizeof (char), pd->pw);
399 fflush (pd->pw);
402 void host_read_guest_requests (pluginData *pd)
404 Log ("Reading guest requests");