diff --git a/engine/Makefile b/engine/Makefile index d0d46bc32..851cc1ed7 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -289,6 +289,7 @@ endif #DO_ECHO=@echo $< && DO_ECHO=@ +#DO_ECHO= DO_CC=$(DO_ECHO) $(CC) $(LTO_CC) $(ALL_CFLAGS) -o $@ -c $< ifeq ($(FTE_TARGET),vc) @@ -340,7 +341,7 @@ else GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp endif -BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I$(BOTLIB_DIR) -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex -DBOTLIB $(SVNREVISION) +BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I$(BOTLIB_DIR) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex -DBOTLIB $(SVNREVISION) CLIENT_ONLY_CFLAGS=-DCLIENTONLY SERVER_ONLY_CFLAGS=-DSERVERONLY JOINT_CFLAGS= @@ -895,7 +896,7 @@ ifeq ($(FTE_TARGET),bsd) SV_DIR=sv_linux SV_LDFLAGS=-lz -ldl - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o GL_EXE_NAME=../fteqw.gl GLCL_EXE_NAME=../fteqwcl.gl GL_LDFLAGS= -L/usr/local/lib $(GLLDFLAGS) $(GLXLDFLAGS) -lpthread @@ -903,7 +904,7 @@ ifeq ($(FTE_TARGET),bsd) GLB_DIR=gl_bsd GLCL_DIR=glcl_bsd - MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o + MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o M_EXE_NAME=../fteqw MCL_EXE_NAME=../fteqwcl M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lpthread @@ -919,8 +920,14 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) SV_DIR=sv_linux$(BITS) SV_LDFLAGS=-lz SV_EXE_NAME=../fteqw.sv$(BITS) + + 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=$(IMAGELDFLAGS) -shared + NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD -fPIC + NPFTEB_DIR=npfte_linux$(BITS) - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o gl_videgl.o snd_alsa.o snd_linux.o cd_linux.o sys_linux.o + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o gl_videgl.o snd_alsa.o snd_linux.o cd_linux.o sys_linux.o sys_linux_threads.o GL_EXE_NAME=../fteqw.gl$(BITS) GLCL_EXE_NAME=../fteqwcl.gl$(BITS) GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) $(OGGVORBISLDFLAGS) -lz @@ -928,7 +935,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep linux),) GLB_DIR=gl_linux$(BITS) GLCL_DIR=glcl_linux$(BITS) - MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o snd_alsa.o cd_linux.o sys_linux.o + MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o snd_alsa.o cd_linux.o sys_linux.o sys_linux_threads.o M_EXE_NAME=../fteqw$(BITS) MCL_EXE_NAME=../fteqwcl$(BITS) M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) $(OGGVORBISLDFLAGS) -lz @@ -962,7 +969,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep macosx),) endif GL_LDFLAGS=-framework AGL -framework OpenGL -framework Cocoa -framework AudioUnit -lz -lpng -ljpeg - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o cd_null.o snd_macos.o + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o cd_null.o snd_macos.o sys_linux_threads.o GL_EXE_NAME=../macosx_fteqw.gl$(EXTENSION)$(BITS) GLCL_EXE_NAME=../macosx_fteqwcl.gl$(EXTENSION)$(BITS) @@ -1023,7 +1030,7 @@ ifeq ($(FTE_TARGET),cygwin) SV_DIR=sv_cygwin SV_LDFLAGS=-lz - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o GL_EXE_NAME=../fteqwglcyg.exe GLCL_EXE_NAME=../fteqwclglcyg.exe GL_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) $(OGGVORBISLDFLAGS) @@ -1031,7 +1038,7 @@ ifeq ($(FTE_TARGET),cygwin) GLB_DIR=gl_cygwin GLCL_DIR=glcl_cygwin - MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o + MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o M_EXE_NAME=../fteqwcyg.exe MCL_EXE_NAME=../fteqwclcyg.exe M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) $(OGGVORBISLDFLAGS) @@ -1235,12 +1242,18 @@ d3d-profile: -npfte-tmp: reldir - @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS)" OBJS="NPFTE_OBJS" +npfte-tmprel: reldir + @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="NPFTE_OBJS" +npfte-tmpdbg: debugdir + @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)" OBJS="NPFTE_OBJS" npfte-rel: - @$(MAKE) npfte-tmp OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)" EXE_NAME="$(NPFTE_DLL_NAME)" PRECOMPHEADERS= + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 cp $(RELEASE_DIR)/npfte.dll npfte/plugins - cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) install.rdf plugins/npfte.dll + cp $(RELEASE_DIR)/npfte32.so npfte/plugins + cp $(RELEASE_DIR)/npfte64.so npfte/plugins + cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) install.rdf plugins/npfte.dll plugins/npfte32.so plugins/npfte64.so rm -rf /tmp/npfte mkdir /tmp/npfte cp $(RELEASE_DIR)/npfte.dll /tmp/npfte @@ -1248,7 +1261,9 @@ npfte-rel: -cd $(RELEASE_DIR)/ && ../npfte/crxmake.sh /tmp/npfte ../npfte/chrome.pem rm -rf /tmp/npfte npfte-dbg: - @$(MAKE) npfte-tmp TYPE=_npfte-dbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)" + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 npfte-profile: @$(MAKE) npfte-tmp TYPE=_npfte-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTEB_DIR)" diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index b9e081bfa..42da96048 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -58,6 +58,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int noconinput = 0; int nostdout = 0; +qboolean isPlugin; +int sys_parentleft; +int sys_parenttop; +int sys_parentwidth; +int sys_parentheight; +long sys_parentwindow; + + char *basedir = "."; qboolean Sys_InitTerminal (void) //we either have one or we don't. @@ -611,6 +619,18 @@ char *Sys_ConsoleInput(void) text[len-1] = 0; // rip off the /n and terminate +//Con_Printf("console input: %s\n", text); + + if (!strncmp(text, "vid_recenter ", 13)) + { + Cmd_TokenizeString(text, false, false); + sys_parentleft = strtoul(Cmd_Argv(1), NULL, 0); + sys_parenttop = strtoul(Cmd_Argv(2), NULL, 0); + sys_parentwidth = strtoul(Cmd_Argv(3), NULL, 0); + sys_parentheight = strtoul(Cmd_Argv(4), NULL, 0); + sys_parentwindow = strtoul(Cmd_Argv(5), NULL, 16); + } + return text; } #endif @@ -645,6 +665,15 @@ int main (int c, const char **v) parms.basedir = basedir; + isPlugin = !!COM_CheckParm("-plugin"); + if (isPlugin) + { + printf("status Starting up!\n"); + fflush(stdout); + nostdout = true; + } + + noconinput = COM_CheckParm("-noconinput"); if (!noconinput) fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); @@ -758,163 +787,6 @@ void Sys_SaveClipboard(char *text) { } #endif -#ifdef MULTITHREAD -/* Thread creation calls */ -typedef void *(*pfunction_t)(void *); - -void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize) -{ - pthread_t *thread; - pthread_attr_t attr; - - thread = (pthread_t *)malloc(sizeof(pthread_t)); - if (!thread) - return NULL; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - if (stacksize < PTHREAD_STACK_MIN) - stacksize = PTHREAD_STACK_MIN; - pthread_attr_setstacksize(&attr, stacksize); - if (pthread_create(thread, &attr, (pfunction_t)func, args)) - { - free(thread); - thread = NULL; - } - pthread_attr_destroy(&attr); - - return (void *)thread; -} - -void Sys_WaitOnThread(void *thread) -{ - pthread_join((pthread_t *)thread, NULL); - free(thread); -} - -/* Mutex calls */ -void *Sys_CreateMutex(void) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - - if (mutex && !pthread_mutex_init(mutex, NULL)) - return mutex; - return NULL; -} - -qboolean Sys_TryLockMutex(void *mutex) -{ - return !pthread_mutex_trylock(mutex); -} - -qboolean Sys_LockMutex(void *mutex) -{ - return !pthread_mutex_lock(mutex); -} - -qboolean Sys_UnlockMutex(void *mutex) -{ - return !pthread_mutex_unlock(mutex); -} - -void Sys_DestroyMutex(void *mutex) -{ - pthread_mutex_destroy(mutex); - free(mutex); -} - -/* Conditional wait calls */ -typedef struct condvar_s -{ - pthread_mutex_t *mutex; - pthread_cond_t *cond; -} condvar_t; - -void *Sys_CreateConditional(void) -{ - condvar_t *condv; - pthread_mutex_t *mutex; - pthread_cond_t *cond; - - condv = (condvar_t *)malloc(sizeof(condvar_t)); - if (!condv) - return NULL; - - mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - if (!mutex) - return NULL; - - cond = (pthread_cond_t *)malloc(sizeof(pthread_cond_t)); - if (!cond) - return NULL; - - if (!pthread_mutex_init(mutex, NULL)) - { - if (!pthread_cond_init(cond, NULL)) - { - condv->cond = cond; - condv->mutex = mutex; - - return (void *)condv; - } - else - pthread_mutex_destroy(mutex); - } - - free(cond); - free(mutex); - free(condv); - return NULL; -} - -qboolean Sys_LockConditional(void *condv) -{ - return !pthread_mutex_lock(((condvar_t *)condv)->mutex); -} - -qboolean Sys_UnlockConditional(void *condv) -{ - return !pthread_mutex_unlock(((condvar_t *)condv)->mutex); -} - -qboolean Sys_ConditionWait(void *condv) -{ - return !pthread_cond_wait(((condvar_t *)condv)->cond, ((condvar_t *)condv)->mutex); -} - -qboolean Sys_ConditionSignal(void *condv) -{ - return !pthread_cond_signal(((condvar_t *)condv)->cond); -} - -qboolean Sys_ConditionBroadcast(void *condv) -{ - return !pthread_cond_broadcast(((condvar_t *)condv)->cond); -} - -void Sys_DestroyConditional(void *condv) -{ - condvar_t *cv = (condvar_t *)condv; - - pthread_cond_destroy(cv->cond); - pthread_mutex_destroy(cv->mutex); - free(cv->cond); - free(cv->mutex); - free(cv); -} -#endif - -void Sys_Sleep (double seconds) -{ - struct timespec ts; - - ts.tv_sec = (time_t)seconds; - seconds -= ts.tv_sec; - ts.tv_nsec = seconds * 1000000000.0; - - nanosleep(&ts, NULL); -} - qboolean Sys_RandomBytes(qbyte *string, int len) { qboolean res; diff --git a/engine/client/sys_npfte.c b/engine/client/sys_npfte.c index a1a96a227..bfc440d36 100644 --- a/engine/client/sys_npfte.c +++ b/engine/client/sys_npfte.c @@ -6,9 +6,14 @@ #ifndef _WINDOWS #define _WINDOWS //stupid GCC #endif +#else +#define XP_UNIX +#define MOZ_X11 +#include +#include #endif -#include "npapi/npupp.h" +#include "libs/npapi/npupp.h" #include "sys_plugfte.h" /*work around absolute crapness in the npapi headers*/ @@ -59,8 +64,6 @@ NPNetscapeFuncs *browserfuncs; - - qboolean NPFTE_BeginDownload(void *ctx, struct pipetype *ftype, char *url) { return NPERR_NO_ERROR==browserfuncs->geturlnotify(ctx, url, NULL, ftype); @@ -70,7 +73,9 @@ void NPFTE_StatusChanged(void *sysctx) { //potentially called from another thread NPP instance = sysctx; struct contextpublic *pub = instance->pdata; +#ifdef _WIN32 InvalidateRgn(pub->oldwnd, NULL, FALSE); +#endif } #ifdef _WIN32 @@ -234,6 +239,9 @@ NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, return NPERR_INVALID_PLUGIN_ERROR; } +// browserfuncs->setvalue(instance, NPPVpluginWindowBool, (void*)FALSE); +// browserfuncs->setvalue(instance, NPPVpluginTransparentBool, (void*)TRUE); + ctx = Plug_CreateContext(instance, &npfte_browserfuncs); instance->pdata = ctx; if (!ctx) @@ -271,6 +279,29 @@ NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save) return NPERR_NO_ERROR; } + +#ifdef MOZ_X11 +static void myxteventcallback (Widget w, XtPointer closure, XEvent *event, Boolean *cont) +{ + switch(event->type) + { + case MotionNotify: +// Con_Printf("Motion Mouse event\n"); + break; + case ButtonPress: + if (event->xbutton.button == 1) + { + if (!Plug_StartContext(closure)) + Plug_StopContext(NULL, false); + } + break; + default: +// Con_Printf("other event (%i)\n", event->type); + break; + } +} +#endif + NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window) { struct context *ctx = instance->pdata; @@ -302,6 +333,17 @@ NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window) } InvalidateRgn(window->window, NULL, FALSE); +#endif +#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); + + if (Plug_ChangeWindow(ctx, window->window, 0, 0, window->width, window->height)) + { + } #endif return NPERR_NO_ERROR; } @@ -414,7 +456,7 @@ int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream) int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer) { - return NPERR_NO_ERROR; + return len; /* int bytes = NPP_WriteReady(instance, stream); struct context *ctx = instance->pdata; struct qstream *qstr = stream->pdata; @@ -523,7 +565,7 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) NPUTF8 *pname; int prop; bool success = false; - char *strval; + const char *strval; int intval; float floatval; pname = browserfuncs->utf8fromidentifier(name); @@ -628,18 +670,18 @@ NPClass npscript_class = { NP_CLASS_STRUCT_VERSION, - npscript_allocate, - npscript_deallocate, - npscript_invalidate, - npscript_hasMethod, - npscript_invoke, - npscript_invokeDefault, - npscript_hasProperty, - npscript_getProperty, - npscript_setProperty, - npscript_removeProperty, - npscript_enumerate, - npscript_construct + npscript_allocate, + npscript_deallocate, + npscript_invalidate, + npscript_hasMethod, + npscript_invoke, + npscript_invokeDefault, + npscript_hasProperty, + npscript_getProperty, + npscript_setProperty, + npscript_removeProperty, + npscript_enumerate, + npscript_construct }; NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value) @@ -665,12 +707,6 @@ NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value) return NPERR_NO_ERROR; } -NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs) -{ - browserfuncs = pFuncs; - return NPERR_NO_ERROR; -} - NPError OSCALL NP_Shutdown(void) { /* if (contextlist) @@ -706,27 +742,50 @@ NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* pFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; pFuncs->size = sizeof(NPPluginFuncs); - pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; - pFuncs->newp = NPP_New; - pFuncs->destroy = NPP_Destroy; - pFuncs->setwindow = NPP_SetWindow; - pFuncs->newstream = NPP_NewStream; - pFuncs->destroystream = NPP_DestroyStream; - pFuncs->asfile = NPP_StreamAsFile; - pFuncs->writeready = NPP_WriteReady; - pFuncs->write = NPP_Write; - pFuncs->print = NPP_Print; - pFuncs->event = NPP_HandleEvent; - pFuncs->urlnotify = NPP_URLNotify; - pFuncs->javaClass = NULL; - pFuncs->getvalue = NPP_GetValue; - pFuncs->setvalue = NPP_SetValue; + pFuncs->newp = NPP_New; + pFuncs->destroy = NPP_Destroy; + pFuncs->setwindow = NPP_SetWindow; + pFuncs->newstream = NPP_NewStream; + pFuncs->destroystream = NPP_DestroyStream; + pFuncs->asfile = NPP_StreamAsFile; + pFuncs->writeready = NPP_WriteReady; + pFuncs->write = NPP_Write; + pFuncs->print = NPP_Print; + pFuncs->event = NPP_HandleEvent; + pFuncs->urlnotify = NPP_URLNotify; + pFuncs->javaClass = NULL; + pFuncs->getvalue = NPP_GetValue; + pFuncs->setvalue = NPP_SetValue; return NPERR_NO_ERROR; } +#ifdef _WIN32 +NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs) +{ + Plug_GetFuncs(1); + browserfuncs = pFuncs; + return NPERR_NO_ERROR; +} +#else +NPError OSCALL NP_Initialize(NPNetscapeFuncs *aNPNFuncs, NPPluginFuncs *aNPPFuncs) +{ + Plug_GetFuncs(1); + browserfuncs = aNPNFuncs; + + return NP_GetEntryPoints(aNPPFuncs); +} +#endif + char *NP_GetMIMEDescription(void) { - return "test/x-qtv:qtv:QTV Stream Description"; + return + "text/x-quaketvident:qtv:QTV Stream Description" + ";" + "application/x-multiviewdemo:mvd:Multiview Demo" + ";" + "application/x-fteplugin:fmf:FTE Engine Plugin" + ; } diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index 68068a5fb..c4d144037 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -2,6 +2,9 @@ #include "winquake.h" #include "sys_plugfte.h" #include "../http/iweb.h" +#ifndef _WIN32 +#include +#endif static void UnpackAndExtractPakFiles_Complete(struct dl_download *dl); static void pscript_property_splash_sets(struct context *ctx, const char *val); @@ -95,7 +98,17 @@ void VARGS Con_Printf (const char *fmt, ...) Q_vsnprintfz(dest, sizeof(dest), fmt, argptr); va_end (argptr); +#ifdef _WIN32 OutputDebugString(dest); +#else + FILE *f = fopen("/tmp/ftelog", "a"); + if (f) + { + fputs(dest, f); + fclose(f); + } + write(2, dest, strlen(dest)); +#endif } #ifdef _WIN32 // don't use these functions in MSVC8 @@ -151,6 +164,10 @@ int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ... #endif #include "netinc.h" +#ifndef _WIN32 +#define pgetaddrinfo getaddrinfo +#define pfreeaddrinfo freeaddrinfo +#else #if 0//def _MSC_VER #include #define pgetaddrinfo getaddrinfo @@ -158,6 +175,7 @@ int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ... #else #include #endif +#endif qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize) { struct addrinfo *addrinfo = NULL; @@ -389,7 +407,7 @@ unsigned long VFSPIPE_Tell(vfsfile_t *f) } qboolean VFSPIPE_Seek(vfsfile_t *f, unsigned long offset) { - OutputDebugStringA("Seeking is a bad plan, mmkay?\n"); + Con_Printf("Seeking is a bad plan, mmkay?\n"); return false; } int VFSPIPE_ReadBytes(vfsfile_t *f, void *buffer, int len) @@ -457,13 +475,24 @@ vfsfile_t *VFSPIPE_Open(void) #define BUILDTYPE "test" #define UPDATE_URL "http://triptohell.info/moodles/" #define UPDATE_URL_VERSION UPDATE_URL "version.txt" - #ifdef _WIN64 - #define UPDATE_URL_BUILD UPDATE_URL "win64/fte" EXETYPE ".exe" + + //we should perhaps use the uname stuff instead. + #ifdef _WIN32 + #ifdef _WIN64 + #define UPDATE_URL_BUILD UPDATE_URL "win64/fte" EXETYPE ".exe" + #else + #define UPDATE_URL_BUILD UPDATE_URL "win32/fte" EXETYPE ".exe" + #endif #else - #define UPDATE_URL_BUILD UPDATE_URL "win32/fte" EXETYPE ".exe" + #if defined(__amd64__) + #define UPDATE_URL_BUILD UPDATE_URL "linux_amd64/fteqw." EXETYPE "64" + #else + #define UPDATE_URL_BUILD UPDATE_URL "linux_x86/fteqw." EXETYPE "32" + #endif #endif #endif +#ifdef _WIN32 //#if defined(GLQUAKE) && defined(D3DQUAKE) // #define EXETYPE "qw" //#elif defined(GLQUAKE) @@ -479,12 +508,14 @@ vfsfile_t *VFSPIPE_Open(void) //#else //erm... // #define EXETYPE "qw" //#endif +#else + #define EXETYPE "gl" +#endif - +#ifdef _WIN32 qboolean MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, DWORD datalen) { qboolean result = false; - DWORD resultlen = datalen - 1; HKEY subkey; DWORD type = REG_NONE; if (RegOpenKeyEx(base, keyname, 0, KEY_READ, &subkey) == ERROR_SUCCESS) @@ -546,6 +577,20 @@ void Sys_mkdir (char *path) { CreateDirectory (path, NULL); } +#else +qboolean Update_GetHomeDirectory(char *homedir, int homedirsize) +{ + qboolean result = false; + char *val = getenv("HOME"); + if (!val) val = "."; + else result = true; + + Q_strncpyz(homedir, val, homedirsize); + Q_strncatz(homedir, "/.fte/", homedirsize); + + return result; +} +#endif static void Update_CreatePath (char *path) { char *ofs; @@ -591,7 +636,11 @@ void Update_Version_Updated(struct dl_download *dl) fclose(pending); if (fullsize == size) { +#ifdef _WIN32 MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1); +#else + chmod(pendingname, S_IRUSR|S_IXUSR); +#endif } else { @@ -607,6 +656,7 @@ void Update_Version_Updated(struct dl_download *dl) } qboolean Plug_GetDownloadedName(char *updatedpath, int updatedpathlen) { +#ifdef _WIN32 char pendingpath[MAX_OSPATH]; char temppath[MAX_OSPATH]; @@ -648,7 +698,60 @@ qboolean Plug_GetDownloadedName(char *updatedpath, int updatedpathlen) } Sys_UnlockMutex(globalmutex); +#else + char pendingpath[MAX_OSPATH]; + char currentpath[MAX_OSPATH]; + struct stat st; + + Update_GetHomeDirectory(currentpath, sizeof(currentpath)); + Q_strncatz(currentpath, "cur" BUILDTYPE EXETYPE, sizeof(currentpath)); + Update_GetHomeDirectory(pendingpath, sizeof(pendingpath)); + Q_strncatz(pendingpath, "pending" BUILDTYPE EXETYPE, sizeof(pendingpath)); + + //truncated to be the same string? :s + if (!strcmp(currentpath, pendingpath)) + return false; + + Sys_LockMutex(globalmutex); + + if (!enginedownloadactive || (enginedownloadactive->status == DL_FINISHED || enginedownloadactive->status == DL_FAILED)) + { + //make sure the download is cleaned up properly. + if (enginedownloadactive) + DL_Close(enginedownloadactive); + enginedownloadactive = NULL; + + //if the engine wrote a new version to use, copy it over to the proper path now (two paths means we're less likely to be trying to write a file that is already open). + if (!stat(pendingpath, &st)) + { + //rename supposedly overwrites automagically. I'm paranoid. + unlink(currentpath); + rename(pendingpath, currentpath); + } + + if (!stat(currentpath, &st)) + { + //there's a current file, yay. + Q_strncpyz(updatedpath, pendingpath, updatedpathlen); + } + else + { //no engine available to run. we'll have to download one (we only need to do it in this case because the engine itself autoupdates, + //and we can't because we don't actually know what version we have, only the binary that's running knows its version. + //that's the theory anyway. + Con_Printf("downloading %s\n", UPDATE_URL_BUILD); + enginedownloadactive = DL_Create(UPDATE_URL_BUILD); + if (enginedownloadactive) + { + enginedownloadactive->user_ctx = NULL; + DL_CreateThread(enginedownloadactive, VFSPIPE_Open(), Update_Version_Updated); + } + + } + } + Sys_UnlockMutex(globalmutex); + +#endif return !!*updatedpath; } @@ -708,6 +811,10 @@ struct context HANDLE pipetoengine; HANDLE pipefromengine; HANDLE engineprocess; +#else + int pipetoengine; + int pipefromengine; + pid_t engineprocess; #endif }; @@ -777,8 +884,7 @@ char *cleanarg(char *arg) return strdup("\"\""); } -qboolean Plug_GetBinaryName(char *exe, int exelen, - char *basedir, int basedirlen) +qboolean Plug_GetBinaryName(char *exe, int exelen, char *basedir, int basedirlen) { // char buffer[1024]; // char cmd[64]; @@ -832,7 +938,10 @@ int Plug_GenCommandline(struct context *ctx, char **argv, int maxargs) autoupdate = Plug_GetBinaryName(exe, sizeof(exe), basedir, sizeof(basedir)); if (!*exe) + { + Con_Printf("Unable to determine what to run\n"); return 0; //error + } argv[0] = strdup(exe); argc = 1; @@ -947,17 +1056,24 @@ void Plug_ExecuteCommand(struct context *ctx, char *message, ...) va_list va; char finalmessage[1024]; - DWORD written = 0; va_start (va, message); vsnprintf (finalmessage, sizeof(finalmessage)-1, message, va); va_end (va); - WriteFile(ctx->pipetoengine, finalmessage, strlen(finalmessage), &written, NULL); +#ifdef _WIN32 + { + DWORD written = 0; + WriteFile(ctx->pipetoengine, finalmessage, strlen(finalmessage), &written, NULL); + } +#else + write(ctx->pipetoengine, finalmessage, strlen(finalmessage)); +#endif } qboolean Plug_CreatePluginProcess(struct context *ctx) { +#ifdef _WIN32 char cmdline[8192]; PROCESS_INFORMATION childinfo; STARTUPINFO startinfo; @@ -988,8 +1104,77 @@ qboolean Plug_CreatePluginProcess(struct context *ctx) CloseHandle(startinfo.hStdInput); return true; +#else + int in[2]; + int out[2]; + char *argv[64] = {NULL}; + int i; + + i = Plug_GenCommandline(ctx, argv, sizeof(argv) / sizeof(argv[0])); + if (!i) + return false; + + argv[i] = NULL; + +/* char buf[512]; + snprintf(buf, sizeof(buf), "%i args\n", i); + write(2, buf, strlen(buf)); + for (i = 0; argv[i]; i++) + { + snprintf(buf, sizeof(buf), "argv[%i] = %s\n", i, argv[i]); + write(2, buf, strlen(buf)); + } +*/ + pipe(in); + pipe(out); + + ctx->pipefromengine = in[0]; + ctx->pipetoengine = out[1]; + + Plug_ExecuteCommand(ctx, "vid_recenter %i %i %i %i %#p\n", ctx->windowleft, ctx->windowtop, ctx->windowwidth, ctx->windowheight, (void*)ctx->windowhnd); + + ctx->engineprocess = fork(); + if (ctx->engineprocess == 0) + { + //close the ends we don't care about + close(in[0]); + close(out[1]); + + //dupe them to the stdin/stdout, for ease of use, and clean up the extra handles + dup2(out[0], 0); + dup2(in[1], 1); + //dup2(in[1], 2); + close(in[1]); + close(out[0]); + + //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); + exit(1); + } + close(in[1]); + close(out[0]); + + if (ctx->engineprocess == -1) + return false; + + return true; +#endif } +void Plug_LockPlugin(struct context *ctx, qboolean lockstate) +{ + if (!ctx || !ctx->mutex) + return; + + if (lockstate) + Sys_LockMutex(ctx->mutex); + else + Sys_UnlockMutex(ctx->mutex); +} +//#define Plug_LockPlugin(c,s) do{Plug_LockPlugin(c,s);VS_DebugLocation(__FILE__, __LINE__, s?"Lock":"Unlock"); }while(0) + int Plug_PluginThread(void *ctxptr) { char buffer[1024]; @@ -1131,7 +1316,11 @@ int Plug_PluginThread(void *ctxptr) Sys_UnlockMutex(globalmutex); if (os == -2) break; +#ifdef _WIN32 Sleep(1000); +#else + sleep(1); +#endif } } } @@ -1142,6 +1331,7 @@ int Plug_PluginThread(void *ctxptr) if (ctx->pub.running) while(1) { +#ifdef _WIN32 DWORD avail; //use Peek so we can read exactly how much there is without blocking, so we don't have to read byte-by-byte. PeekNamedPipe(ctx->pipefromengine, NULL, 0, NULL, &avail, NULL); @@ -1155,6 +1345,33 @@ int Plug_PluginThread(void *ctxptr) *ctx->pub.statusmessage = 0; break; } +#else + int avail; +// Con_Printf("Attempting to read from pipe...\n"); + if (bufoffs == sizeof(buffer)) + { + Con_Printf("ERROR: Pipe full!\n"); + bufoffs = 0; //not much we can really do + } + avail = read(ctx->pipefromengine, buffer + bufoffs, 1); + if (!avail) + { + Con_Printf("eof on pipe\n"); + //broken pipe, client died? + *ctx->pub.statusmessage = 0; + break; + } + if (avail < 0) + { + int err = errno; + if (err == EAGAIN) + continue; + perror("hello moo\n"); + //broken pipe, client died? + Q_strncpyz(ctx->pub.statusmessage, "pipe error", sizeof(ctx->pub.statusmessage)); + break; + } +#endif bufoffs += avail; while(1) { @@ -1183,6 +1400,7 @@ int Plug_PluginThread(void *ctxptr) *ctx->pub.statusmessage = 0; if (ctx->bfuncs.StatusChanged) ctx->bfuncs.StatusChanged(ctx->hostinstance); + Con_Printf("Status changed to \"%s\"\n", buffer+6); } else if (!strcmp(buffer, "curserver")) { @@ -1194,9 +1412,7 @@ int Plug_PluginThread(void *ctxptr) else { //handle anything else we need to handle here - OutputDebugStringA("Unknown command from engine \""); - OutputDebugStringA(buffer); - OutputDebugStringA("\"\n"); + Con_Printf("Unknown command from engine \"%s\"\n", buffer); } } else @@ -1212,35 +1428,34 @@ int Plug_PluginThread(void *ctxptr) return 0; } -void Plug_LockPlugin(struct context *ctx, qboolean lockstate) -{ - if (!ctx || !ctx->mutex) - return; - - if (lockstate) - Sys_LockMutex(ctx->mutex); - else - Sys_UnlockMutex(ctx->mutex); -} -//#define Plug_LockPlugin(c,s) do{Plug_LockPlugin(c,s);VS_DebugLocation(__FILE__, __LINE__, s?"Lock":"Unlock"); }while(0) - //begins the context, fails if one is already active qboolean Plug_StartContext(struct context *ctx) { if (activecontext && !ctx->multiplecontexts) return false; - if (ctx->pub.running) - return true; - if (ctx->thread) - Plug_StopContext(ctx, true); + Sys_LockMutex(globalmutex); + if (!ctx->pub.running) + { + if (ctx->thread) + { + //make sure the thread is killed properly, so we don't get two threads trying to drive the same context + Sys_UnlockMutex(globalmutex); + Plug_StopContext(ctx, true); + Sys_LockMutex(globalmutex); + } - ctx->pub.running = true; - if (!ctx->multiplecontexts) - activecontext = ctx; - if (!ctx->mutex) - ctx->mutex = Sys_CreateMutex(); - ctx->thread = Sys_CreateThread("pluginctx", Plug_PluginThread, ctx, THREADP_NORMAL, 0); + } + if (!ctx->pub.running && !ctx->thread) + { + ctx->pub.running = true; + if (!ctx->multiplecontexts) + activecontext = ctx; + if (!ctx->mutex) + ctx->mutex = Sys_CreateMutex(); + ctx->thread = Sys_CreateThread("pluginctx", Plug_PluginThread, ctx, THREADP_NORMAL, 0); + } + Sys_UnlockMutex(globalmutex); return true; } @@ -1253,13 +1468,15 @@ void Plug_StopContext(struct context *ctx, qboolean wait) ctx = activecontext; if (!ctx) return; + Plug_ExecuteCommand(ctx, "quit force\n"); thread = ctx->thread; - if (ctx->thread) + if (thread) { if (wait) { +#ifdef _WIN32 while (ctx->pub.running && ctx->windowhnd) { MSG msg; @@ -1270,8 +1487,9 @@ void Plug_StopContext(struct context *ctx, qboolean wait) } Sleep(10); } - Sys_WaitOnThread(ctx->thread); +#endif ctx->thread = NULL; + Sys_WaitOnThread(thread); } } } @@ -1604,7 +1822,6 @@ void pscript_property_startserver_sets(struct context *ctx, const char *val) } char *pscript_property_curserver_gets(struct context *ctx) { - extern char lastdemoname[]; if (!pscript_property_running_getb(ctx)) return pscript_property_startserver_gets(ctx); @@ -1691,6 +1908,7 @@ void pscript_property_splash_sets(struct context *ctx, const char *val) if (val != ctx->qtvf.splashscreen) Q_strncpyz(ctx->qtvf.splashscreen, val, sizeof(ctx->qtvf.splashscreen)); +/* ctx->splashdownload = DL_Create(ctx->qtvf.splashscreen); ctx->splashdownload->user_ctx = ctx; if (!DL_CreateThread(ctx->splashdownload, VFSPIPE_Open(), LoadSplashImage)) @@ -1698,6 +1916,7 @@ void pscript_property_splash_sets(struct context *ctx, const char *val) DL_Close(ctx->splashdownload); ctx->splashdownload = NULL; } +*/ } char *pscript_property_build_gets(struct context *ctx) @@ -1959,8 +2178,10 @@ static const struct plugfuncs exportedplugfuncs_1 = Plug_SetFloat, Plug_GetFloat, +#ifdef _WIN32 Plug_GetSplashBack, Plug_ReleaseSplashBack, +#endif Plug_SetWString }; diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index b5b31ec85..d3ba1f92b 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -80,6 +80,12 @@ static enum extern cvar_t vid_conautoscale; +extern int sys_parentleft; +extern int sys_parenttop; +extern int sys_parentwidth; +extern int sys_parentheight; +extern long sys_parentwindow; + #define KEY_MASK (KeyPressMask | KeyReleaseMask) #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ PointerMotionMask) @@ -1216,13 +1222,14 @@ qboolean X_CheckWMFullscreenAvailable(void) return success; } -Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, unsigned int width, unsigned int height) +Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, unsigned int width, unsigned int height, qboolean fullscreen) { - Window wnd; + Window wnd, parent; XSetWindowAttributes attr; XSizeHints szhints; unsigned int mask; Atom prots[1]; + int x, y; /* window attributes */ attr.background_pixel = 0; @@ -1249,7 +1256,21 @@ Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, unsigned int widt szhints.width = width; szhints.height = height; - wnd = XCreateWindow(vid_dpy, vid_root, 0, 0, width, height, + + if (sys_parentwindow && !fullscreen) + { + x = (sys_parentwidth - width) / 2; + y = (sys_parentheight - height) / 2; + parent = sys_parentwindow; + } + else + { + parent = vid_root; + x = 0; + y = 0; + } + + wnd = XCreateWindow(vid_dpy, parent, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); /*ask the window manager to stop triggering bugs in Xlib*/ @@ -1395,6 +1416,13 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl) else fullscreenflags |= FULLSCREEN_LEGACY; } + else if (sys_parentwindow) + { + if (width < 64 || width > sys_parentwidth) + width = sys_parentwidth; + if (height < 64 || height > sys_parentheight) + height = sys_parentheight; + } switch(currentpsl) { @@ -1424,11 +1452,11 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl) ActiveApp = false; if (fullscreenflags & FULLSCREEN_LEGACY) { - vid_decoywindow = X_CreateWindow(false, visinfo, 640, 480); - vid_window = X_CreateWindow(true, visinfo, width, height); + vid_decoywindow = X_CreateWindow(false, visinfo, 640, 480, false); + vid_window = X_CreateWindow(true, visinfo, width, height, fullscreen); } else - vid_window = X_CreateWindow(false, visinfo, width, height); + vid_window = X_CreateWindow(false, visinfo, width, height, fullscreen); CL_UpdateWindowTitle(); /*make it visible*/ @@ -1562,6 +1590,10 @@ qboolean EGLVID_Init (rendererstate_t *info, unsigned char *palette) void Sys_SendKeyEvents(void) { +#ifndef CLIENTONLY + //this is stupid + SV_GetConsoleCommands(); +#endif if (gracefulexit) { Cbuf_AddText("\nquit\n", RESTRICT_LOCAL); diff --git a/engine/libs/npapi/prcpucfg.h b/engine/libs/npapi/prcpucfg.h index 026258b8c..28e4563b2 100644 --- a/engine/libs/npapi/prcpucfg.h +++ b/engine/libs/npapi/prcpucfg.h @@ -52,7 +52,7 @@ #define PR_AF_INET6 23 /* same as AF_INET6 */ -#if defined(_M_IX86) || defined(_X86_) +#if defined(_M_IX86) || defined(_X86_) || defined(__i386__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN @@ -144,7 +144,7 @@ #define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_POINTER 4 -#elif defined(_AMD64_) +#elif defined(_AMD64_) || defined(__x86_64__) #define IS_LITTLE_ENDIAN 1 #undef IS_BIG_ENDIAN