14 #define pdof(x) ((pluginData*)(x->pdata))
16 static NPNetscapeFuncs gNetscapeFuncs
; /* Netscape Function table */
18 NPError
NP_Initialize(NPNetscapeFuncs
* nsTable
, NPPluginFuncs
* pluginFuncs
)
22 /* this is respectfully taken from mplayerplug-in, as it was observed
23 * and proved to be extremely useful. */
24 if ((nsTable
== NULL
) || (pluginFuncs
== NULL
))
25 return NPERR_INVALID_FUNCTABLE_ERROR
;
26 if ((nsTable
->version
>> 8) > NP_VERSION_MAJOR
)
27 return NPERR_INCOMPATIBLE_VERSION_ERROR
;
28 if (nsTable
->size
< sizeof(NPNetscapeFuncs
))
29 return NPERR_INVALID_FUNCTABLE_ERROR
;
30 if (pluginFuncs
->size
< sizeof(NPPluginFuncs
))
31 return NPERR_INVALID_FUNCTABLE_ERROR
;
33 gNetscapeFuncs
.version
= nsTable
->version
;
34 gNetscapeFuncs
.size
= nsTable
->size
;
35 gNetscapeFuncs
.posturl
= nsTable
->posturl
;
36 gNetscapeFuncs
.geturl
= nsTable
->geturl
;
37 gNetscapeFuncs
.requestread
= nsTable
->requestread
;
38 gNetscapeFuncs
.newstream
= nsTable
->newstream
;
39 gNetscapeFuncs
.write
= nsTable
->write
;
40 gNetscapeFuncs
.destroystream
= nsTable
->destroystream
;
41 gNetscapeFuncs
.status
= nsTable
->status
;
42 gNetscapeFuncs
.uagent
= nsTable
->uagent
;
43 gNetscapeFuncs
.memalloc
= nsTable
->memalloc
;
44 gNetscapeFuncs
.memfree
= nsTable
->memfree
;
45 gNetscapeFuncs
.memflush
= nsTable
->memflush
;
46 gNetscapeFuncs
.reloadplugins
= nsTable
->reloadplugins
;
47 gNetscapeFuncs
.getJavaEnv
= nsTable
->getJavaEnv
;
48 gNetscapeFuncs
.getJavaPeer
= nsTable
->getJavaPeer
;
49 gNetscapeFuncs
.getvalue
= nsTable
->getvalue
;
50 gNetscapeFuncs
.setvalue
= nsTable
->setvalue
;
52 pluginFuncs
->version
= (NP_VERSION_MAJOR
<< 8) | NP_VERSION_MINOR
;
53 pluginFuncs
->size
= sizeof(NPPluginFuncs
);
54 pluginFuncs
->newp
= NPP_New
;
55 pluginFuncs
->destroy
= NPP_Destroy
;
56 pluginFuncs
->event
= NPP_HandleEvent
;
57 pluginFuncs
->setwindow
= NPP_SetWindow
;
58 pluginFuncs
->print
= NPP_Print
;
59 pluginFuncs
->newstream
= NPP_NewStream
;
60 pluginFuncs
->destroystream
= NPP_DestroyStream
;
61 pluginFuncs
->asfile
= NPP_StreamAsFile
;
62 pluginFuncs
->writeready
= NPP_WriteReady
;
63 pluginFuncs
->write
= NPP_Write
;
65 return NPERR_NO_ERROR
;
68 NPError
NP_Shutdown() {
70 return NPERR_NO_ERROR
;
74 char* NP_GetMIMEDescription() {
76 return "x-application/glugin:gln:Glugin;";
86 case NPPVpluginNameString
:
87 (*(char**)value
)="Glugin";
89 case NPPVpluginDescriptionString
:
90 (*(char**)value
)="the GL plugin";
93 return NPERR_INVALID_PARAM
;
95 return NPERR_NO_ERROR
;
98 bool read_color(char* str
, int*r
, int*g
, int*b
)
101 if(!((len
==3)||(len
==6)))return false;
104 if(!sscanf(str
,"%x",&color
))return false;
107 *r
=(color
/65536)%256;
111 *r
=255*((color
/256)%16)/15;
112 *g
=255*((color
/16)%16)/15;
113 *b
=255*(color
%16)/15;
115 Log("Read color: %d %d %d\n",*r
,*g
,*b
);
123 int16 argc
, char*argn
[], char*argv
[],
130 gNetscapeFuncs
.setvalue(instance
, NPPVpluginTransparentBool
, false);
133 instance
->pdata
=gNetscapeFuncs
.memalloc(sizeof(pluginData
));
138 pd
->exit_request
=pd
->exit_ack
=pd
->has_window
=
140 pd
->br
=pd
->bg
=pd
->bb
=255;
142 for(i
=0;i
<argc
;++i
){ Log(argn
[i
]);Log(argv
[i
]);Log("--");
143 if(!strcmp(argn
[i
],"gln-color")) {
149 else if(!strcmp(argn
[i
],"gln-bgcolor")) {
158 return NPERR_NO_ERROR
;
161 void set_nonblock(int fd
)
165 flags
=fcntl(fd
, F_GETFL
, 0);
166 flags
|=O_NONBLOCK
|O_NDELAY
;
167 fcntl(fd
, F_SETFL
, flags
);
170 void plugin_process_handler(pluginData
*, Window
, Visual
*);
172 NPError
NPP_SetWindow(
176 pluginData
*pd
=pdof(instance
);
181 Log("setwindow: destroyed");
182 return NPERR_NO_ERROR
;
198 if(child
==-1) return NPERR_MODULE_LOAD_FAILED_ERROR
;
201 Log("in new process!");
206 pd
->pw
=fdopen(pr
[1],"w");
207 pd
->pr
=fdopen(pw
[0],"r");
209 //TODO check if setsid is needed here
211 plugin_process_handler(pd
, pd
->win
=(Window
)(w
->window
),
212 ((NPSetWindowCallbackStruct
*)
213 (w
->ws_info
))->visual
);
221 pd
->pw
=fdopen(pw
[1],"w");
222 pd
->pr
=fdopen(pr
[0],"r");
226 //we don't really care about window resize events, as long as
227 //it can catch them by native methods
229 return NPERR_NO_ERROR
;
233 int16
NPP_HandleEvent(
249 Log("killing child...");
251 kill(pd
->child
,SIGUSR1
);
257 //wait until the child really terminates. Mutexes?
259 gNetscapeFuncs
.memfree(instance
->pdata
);
262 return NPERR_NO_ERROR
;
265 void NPP_Print(NPP instance
, NPPrint
*printInfo
)
267 Log("attempt to print");
270 NPError
NPP_NewStream(
278 host_newstream(pdof(instance
),stream
);
279 return NPERR_NO_ERROR
;
282 NPError
NPP_DestroyStream(
287 Log("destroy stream");
288 host_destroystream(pdof(instance
),stream
);
289 return NPERR_NO_ERROR
;
292 int32
NPP_Write(NPP instance
,
299 host_write(pdof(instance
),stream
,offset
,len
,buf
);
303 void NPP_StreamAsFile(
312 int32
NPP_WriteReady(NPP instance
, NPStream
* stream
)
315 return 1024; //ooh replace.
318 void resize(Display
* dpy
, Window win
)
320 XWindowAttributes wa
;
321 XGetWindowAttributes (dpy
, win
, &wa
);
322 glViewport(0,0,wa
.width
, wa
.height
);
326 static pluginData
*g_pd
;
328 void sig_usr1(int i
) {
329 g_pd
->exit_request
=1;
332 void swapbuffers(pluginData
*pd
)
334 glXSwapBuffers(pd
->dpy
,pd
->win
);
337 void plugin_process_handler(pluginData
*pd
, Window win
, Visual
*vis
)
340 Display
*dpy
=XOpenDisplay(0);
346 signal(SIGUSR1
, sig_usr1
);
348 Log("in plugin process...");
349 xvi
.visualid
=vis
->visualid
;
350 ctx
=glXCreateContext(dpy
,
351 XGetVisualInfo(dpy
,VisualIDMask
,&(xvi
),&i
),
353 glXMakeCurrent(dpy
,win
,ctx
);
355 if(glXIsDirect(dpy
,ctx
))
356 Log("+++ Direct rendering");
357 else Log("!!! Indirect rendering");
359 pd
->swapbuffers
=swapbuffers
;
365 Log("plugin killed, cleaning up.");
370 glXMakeCurrent(dpy
, None
, 0);
371 glXDestroyContext(dpy
,ctx
);
374 template <class T
> void writedata(FILE*f
, T x
)
376 fwrite(&x
,sizeof(T
),1,f
);
379 void host_newstream(pluginData
* pd
, NPStream
* s
){
380 writedata(pd
->pw
,(int)gln_new_stream
);
385 void host_destroystream(pluginData
*pd
, NPStream
*s
){
386 writedata(pd
->pw
,(int)gln_destroy_stream
);
391 void host_write(pluginData
*pd
,NPStream
*s
,int32 off
, int32 siz
, void*data
){
392 writedata(pd
->pw
,(int)gln_stream_data
);
394 writedata(pd
->pw
,off
);
395 writedata(pd
->pw
,siz
);
396 fwrite(data
,siz
,1,pd
->pw
);
400 void host_read_guest_requests(pluginData
*){
402 Log("Reading guest requests");