Fixed bug with unallowed characters
[ArenaLive.git] / ns-unix.c
blobd32a14eda9cd30e8d6e70c272af8512901ef756b
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
18 * Based on GLugin http://exa.czweb.org/repos/glugin.tar.bz2
19 * Big thanks for "exa"
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sys/types.h>
29 #include <signal.h>
31 #include <GL/glx.h>
33 #include "glugin.h"
35 static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
37 /* prototypes */
38 void plugin_process_handler (pluginData *, Window, Visual *);
41 NPError NP_Initialize (NPNetscapeFuncs *nsTable, NPPluginFuncs *pluginFuncs)
43 Log ("init");
45 /* this is respectfully taken from mplayerplug-in, as it was observed
46 * and proved to be extremely useful. */
47 if ((nsTable == NULL) || (pluginFuncs == NULL))
48 return NPERR_INVALID_FUNCTABLE_ERROR;
50 Log ("table ok");
52 if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
53 return NPERR_INCOMPATIBLE_VERSION_ERROR;
55 Log ("table version ok");
57 /*check for table size removed, probable alignment or such problems.
60 if (nsTable->size < sizeof(NPNetscapeFuncs))
61 return NPERR_INVALID_FUNCTABLE_ERROR;
62 Log("table size ok");
66 if (pluginFuncs->size < sizeof (NPPluginFuncs))
67 return NPERR_INVALID_FUNCTABLE_ERROR;
69 Log ("ok pluginfuncs size check");
71 Log ("ok initing");
73 gNetscapeFuncs.version = nsTable->version;
74 gNetscapeFuncs.size = nsTable->size;
75 gNetscapeFuncs.posturl = nsTable->posturl;
76 gNetscapeFuncs.geturl = nsTable->geturl;
77 gNetscapeFuncs.requestread = nsTable->requestread;
78 gNetscapeFuncs.newstream = nsTable->newstream;
79 gNetscapeFuncs.write = nsTable->write;
80 gNetscapeFuncs.destroystream = nsTable->destroystream;
81 gNetscapeFuncs.status = nsTable->status;
82 gNetscapeFuncs.uagent = nsTable->uagent;
83 gNetscapeFuncs.memalloc = nsTable->memalloc;
84 gNetscapeFuncs.memfree = nsTable->memfree;
85 gNetscapeFuncs.memflush = nsTable->memflush;
86 gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
87 gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
88 gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
89 gNetscapeFuncs.getvalue = nsTable->getvalue;
90 gNetscapeFuncs.setvalue = nsTable->setvalue;
92 pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
93 pluginFuncs->size = sizeof (NPPluginFuncs);
94 pluginFuncs->newp = NPP_New;
95 pluginFuncs->destroy = NPP_Destroy;
96 pluginFuncs->event = NPP_HandleEvent;
97 pluginFuncs->setwindow = NPP_SetWindow;
98 pluginFuncs->print = NPP_Print;
99 pluginFuncs->newstream = NPP_NewStream;
100 pluginFuncs->destroystream = NPP_DestroyStream;
101 pluginFuncs->asfile = NPP_StreamAsFile;
102 pluginFuncs->writeready = NPP_WriteReady;
103 pluginFuncs->write = NPP_Write;
105 return NPERR_NO_ERROR;
108 NPError NP_Shutdown ()
110 Log ("shutdown");
112 /* prevent before multiple instances */
113 system ("killall arenalive-linux -s9");
115 return NPERR_NO_ERROR;
119 char *NP_GetMIMEDescription ()
121 Log ("get mime");
122 return "x-application/glugin:gln:Glugin;";
125 NPError NP_GetValue (void *instance, NPPVariable variable, void *value)
127 Log ("get value");
129 switch (variable) {
130 case NPPVpluginNameString:
131 (*(char **) value) = "Arena Live";
132 break;
133 case NPPVpluginDescriptionString:
134 (*(char **) value) = "Arena Live plugin";
135 break;
136 default:
137 return NPERR_INVALID_PARAM;
140 return NPERR_NO_ERROR;
143 NPError NPP_New (
144 NPMIMEType mime,
145 NPP instance,
146 uint16 mode,
147 int16 argc, char *argn[], char *argv[],
148 NPSavedData *saved)
150 int i;
151 pluginData *pd;
153 Log ("new p");
155 gNetscapeFuncs.setvalue (instance, NPPVpluginTransparentBool, false);
157 instance->pdata = gNetscapeFuncs.memalloc (sizeof (pluginData));
159 Log ("allocated");
161 pd = pdof (instance);
163 pd->exit_request = 0;
164 pd->exit_ack = 0;
165 pd->has_window = 0;
167 pd->conparam = 0;
168 pd->action = -1;
170 for (i = 0; i < argc; ++ i) {
171 if (!strcmp (argn[i], "conparam")) {
172 Log ("html tag parameter - conparam");
174 pd->conparam = strdup (argv[i]);
175 } else
176 if (!strcmp (argn[i], "action")) {
177 Log ("html tag parameter - action");
179 pd->action = atoi (argv[i]);
184 return NPERR_NO_ERROR;
187 void set_nonblock (int fd)
189 long flags = fcntl (fd, F_GETFL, 0);
191 flags |= (O_NONBLOCK | O_NDELAY);
193 fcntl (fd, F_SETFL, flags);
196 NPError NPP_SetWindow (NPP instance, NPWindow *w)
198 pluginData *pd = pdof (instance);
199 pid_t child;
200 int pw[2], pr[2];
202 if (!w) {
203 Log ("setwindow: destroyed");
204 return NPERR_NO_ERROR;
207 if (!pd->has_window) {
208 pd->has_window = 1;
210 pipe (pw);
211 pipe (pr);
213 set_nonblock (pr[0]);
214 set_nonblock (pr[1]);
215 set_nonblock (pw[0]);
216 set_nonblock (pw[1]);
218 child = fork ();
220 if (child == -1)
221 return NPERR_MODULE_LOAD_FAILED_ERROR;
223 if (!child) {
224 Log ("in new process!");
226 close (pw[1]);
227 close (pr[0]);
229 pd->pw = fdopen (pr[1], "w");
230 pd->pr = fdopen (pw[0], "r");
232 /* TODO check if setsid is needed here */
234 plugin_process_handler (pd, pd->win = (Window) (w->window), ((NPSetWindowCallbackStruct *) (w->ws_info))->visual);
236 _exit (0);
237 } else {
238 pd->child = child;
240 close (pw[0]);
241 close (pr[1]);
243 pd->pw = fdopen (pw[1], "w");
244 pd->pr = fdopen (pr[0], "r");
248 // we don't really care about window resize events, as long as
249 // it can catch them by native methods
251 return NPERR_NO_ERROR;
255 int16 NPP_HandleEvent (NPP instance, void *event)
257 Log ("event");
259 return true;
262 NPError NPP_Destroy (NPP instance, NPSavedData **saved)
264 pluginData *pd = pdof (instance);
266 Log ("killing child...");
268 kill (pd->child, SIGUSR1);
270 fclose (pd->pw);
271 fclose (pd->pr);
273 usleep (10000);
275 //TODO
276 //wait until the child really terminates. Mutexes?
278 gNetscapeFuncs.memfree (instance->pdata);
279 Log ("deleted ok");
281 return NPERR_NO_ERROR;
284 void NPP_Print (NPP instance, NPPrint *printInfo)
286 Log ("attempt to print");
289 NPError NPP_NewStream (NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16* stype)
291 Log ("new stream");
293 host_newstream (pdof (instance), stream);
295 return NPERR_NO_ERROR;
298 NPError NPP_DestroyStream (NPP instance, NPStream *stream, NPReason reason)
300 Log ("destroy stream");
302 host_destroystream (pdof (instance), stream);
304 return NPERR_NO_ERROR;
307 int32 NPP_Write (NPP instance, NPStream *stream, int32 offset, int32 len, void *buf)
309 Log ("write %d",len);
311 host_write (pdof (instance), stream, offset, len, buf);
313 return len;
316 void NPP_StreamAsFile (NPP instance, NPStream* stream, const char* fname)
318 Log ("as file:");
319 Log (fname);
322 int32 NPP_WriteReady (NPP instance, NPStream *stream)
324 Log("write ready");
326 return 1024; //ooh replace.
329 void resize (Display *dpy, Window win)
331 XWindowAttributes wa;
333 XGetWindowAttributes (dpy, win, &wa);
335 glViewport (0,0,wa.width, wa.height);
339 static pluginData *g_pd;
341 void sig_usr1 (int i)
343 g_pd->exit_request = 1;
346 void swapbuffers (pluginData *pd)
348 glXSwapBuffers (pd->dpy, pd->win);
351 void plugin_process_handler (pluginData *pd, Window win, Visual *vis)
353 g_pd = pd;
355 pd->win = win;
357 signal (SIGUSR1, sig_usr1);
359 /* call action function */
360 plugin_action (pd);
362 Log ("plugin killed, cleaning up.");
364 fclose (pd->pw);
365 fclose (pd->pr);
367 //glXMakeCurrent(dpy, None, 0);
368 //glXDestroyContext(dpy,ctx);
370 if (pd->conparam)
371 free (pd->conparam);
374 void writedata (FILE *f, void *x, unsigned len)
376 fwrite (x, len, sizeof (char), f);
379 void host_newstream (pluginData *pd, NPStream *s)
381 writedata (pd->pw, (void *) gln_new_stream, sizeof (int));
382 writedata (pd->pw, (void *) &s, sizeof (NPStream));
384 fflush (pd->pw);
387 void host_destroystream (pluginData*pd, NPStream*s)
389 writedata (pd->pw, (void *) gln_destroy_stream, sizeof (int));
390 writedata (pd->pw, (void *) s, sizeof (NPStream));
392 fflush (pd->pw);
395 void host_write (pluginData *pd, NPStream *s, int32 off, int32 siz, void *data)
397 writedata (pd->pw, (void *) gln_stream_data, sizeof (int));
398 writedata (pd->pw, (void *) s, sizeof (NPStream));
399 writedata (pd->pw, (void *) &off, sizeof (off));
400 writedata (pd->pw, (void *) &siz, sizeof (off));
402 fwrite (data, siz, sizeof (char), pd->pw);
404 fflush (pd->pw);
407 void host_read_guest_requests (pluginData *pd)
409 Log ("Reading guest requests");