------------------------------------------------------------------------

r4219 | acceptthis | 2013-02-21 04:54:35 +0000 (Thu, 21 Feb 2013) | 1 line

npapi support on linux too.
------------------------------------------------------------------------


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4216 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-03-12 23:03:46 +00:00
parent 91a23d8c96
commit 6567fe92dd
6 changed files with 454 additions and 255 deletions

View file

@ -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)"

View file

@ -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;

View file

@ -6,9 +6,14 @@
#ifndef _WINDOWS
#define _WINDOWS //stupid GCC
#endif
#else
#define XP_UNIX
#define MOZ_X11
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#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"
;
}

View file

@ -2,6 +2,9 @@
#include "winquake.h"
#include "sys_plugfte.h"
#include "../http/iweb.h"
#ifndef _WIN32
#include <sys/stat.h>
#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 <wspiapi.h>
#define pgetaddrinfo getaddrinfo
@ -158,6 +175,7 @@ int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...
#else
#include <ws2tcpip.h>
#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
};

View file

@ -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);

View file

@ -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