From 5cb6c9f190c073a914df00a30d2f37c9bb18b852 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 12 Mar 2013 23:06:15 +0000 Subject: [PATCH] ------------------------------------------------------------------------ r4225 | acceptthis | 2013-02-22 10:59:41 +0000 (Fri, 22 Feb 2013) | 1 line Make npfte link dynamically to X11+Xt so we can print something meaningful and avoid random crashes if those libraries are missing. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4222 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 2 +- engine/client/sys_npfte.c | 55 ++++++++++++++++++++++++++++++++++--- engine/client/sys_plugfte.c | 49 ++++++++++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 1b124652f..062f327f1 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -923,7 +923,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) NPFTE_OBJS=httpclient.o image.o sys_linux_threads.o sys_npfte.o sys_axfte.o sys_plugfte.o NPFTE_DLL_NAME=../npfte$(BITS).so - NPFTE_LDFLAGS=-shared -Wl,-z,defs -lX11 -lXt + NPFTE_LDFLAGS=-shared -Wl,-z,defs NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD -fPIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG NPFTEB_DIR=npfte_linux$(BITS) diff --git a/engine/client/sys_npfte.c b/engine/client/sys_npfte.c index bfc440d36..e14f397cb 100644 --- a/engine/client/sys_npfte.c +++ b/engine/client/sys_npfte.c @@ -214,7 +214,48 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar //I would call the previous wndproc... but that crashes firefox return DefWindowProc(hWnd, msg, wParam, lParam); } +#else +static struct +{ + void *x11; + void *xt; + //X11 funcs + int (*XSelectInput)(Display *display, Window w, long event_mask); + + //Xt funcs + Widget (*XtWindowToWidget)(Display *display, Window window); + void (*XtAddEventHandler)(Widget w, EventMask event_mask, Boolean nonmaskable, XtEventHandler proc, XtPointer client_data); +} x; +qboolean x_initlibs(void) +{ + static dllfunction_t xt_funcs[] = + { + {(void**)&x.XtWindowToWidget, "XtWindowToWidget"}, + {(void**)&x.XtAddEventHandler, "XtAddEventHandler"}, + {NULL, NULL} + }; + static dllfunction_t x11_funcs[] = + { + {(void**)&x.XSelectInput, "XSelectInput"}, + {NULL, NULL} + }; + if (!x.xt) + x.xt = Sys_LoadLibrary("libXt", xt_funcs); + if (!x.xt) + { + Con_Printf("Please install the appropriate libXt for your browser's cpu archetecture\n"); + return false; + } + if (!x.x11) + x.x11 = Sys_LoadLibrary("libX11", x11_funcs); + if (!x.x11) + { + Con_Printf("Please install the appropriate libX11 for your browser's cpu archetecture\n"); + return false; + } + return true; +} #endif static const struct browserfuncs npfte_browserfuncs = @@ -337,9 +378,9 @@ NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window) #ifdef MOZ_X11 Window wnd = (Window)window->window; NPSetWindowCallbackStruct *ws = window->ws_info; - Widget xtw = XtWindowToWidget (ws->display, wnd); - XSelectInput(ws->display, wnd, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|EnterWindowMask); - XtAddEventHandler(xtw, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, FALSE, myxteventcallback, ctx); + Widget xtw = x.XtWindowToWidget (ws->display, wnd); + x.XSelectInput(ws->display, wnd, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|EnterWindowMask); + x.XtAddEventHandler(xtw, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, FALSE, myxteventcallback, ctx); if (Plug_ChangeWindow(ctx, window->window, 0, 0, window->width, window->height)) { @@ -772,10 +813,16 @@ NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs) #else NPError OSCALL NP_Initialize(NPNetscapeFuncs *aNPNFuncs, NPPluginFuncs *aNPPFuncs) { + NPError err; Plug_GetFuncs(1); browserfuncs = aNPNFuncs; - return NP_GetEntryPoints(aNPPFuncs); + err = NP_GetEntryPoints(aNPPFuncs); + if (err != NPERR_NO_ERROR) + return err; + if (!x_initlibs()) + return NPERR_MODULE_LOAD_FAILED_ERROR; + return NPERR_NO_ERROR; } #endif diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index e9c153845..ca507d2fd 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -18,10 +18,57 @@ void *globalmutex; # endif #endif +#ifdef _WIN32 dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) { return NULL; } +#else +#include +void Sys_CloseLibrary(dllhandle_t *lib) +{ + if (lib) + dlclose(lib); +} +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) +{ + char soname[MAX_OSPATH]; + int i; + dllhandle_t lib; + + lib = NULL; + if (!lib) + { + Q_snprintfz(soname, sizeof(soname), "%s.so", name); + lib = dlopen (soname, RTLD_LAZY); + } + if (!lib) + lib = dlopen (name, RTLD_LAZY); + if (!lib) + { + Con_Printf("%s\n", dlerror()); + return NULL; + } + + if (funcs) + { + for (i = 0; funcs[i].name; i++) + { + *funcs[i].funcptr = dlsym(lib, funcs[i].name); + if (!*funcs[i].funcptr) + break; + } + if (funcs[i].name) + { + Con_Printf("Unable to find symbol \"%s\" in \"%s\"\n", funcs[i].name, name); + Sys_CloseLibrary((dllhandle_t*)lib); + lib = NULL; + } + } + + return (dllhandle_t*)lib; +} +#endif void BZ_Free(void *ptr) { @@ -1155,7 +1202,7 @@ qboolean Plug_CreatePluginProcess(struct context *ctx) //invoke the child and kill ourselves if that failed. write(2, "invoking engine\n", 16); execv(argv[0], argv); - write(2, "execv failed\n", 13); + fprintf(stderr, "execv failed: %s\n", argv[0]); exit(1); } close(in[1]);