Gecko: added ability to call back into a QC entry point (Gecko_Entry) from JS inside...
authorres <res@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 22 Jan 2008 22:57:45 +0000 (22:57 +0000)
committerres <res@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 22 Jan 2008 22:57:45 +0000 (22:57 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8002 d7cf8633-e32d-0410-b094-e92efae38249

cl_gecko.c
cl_gecko.h
progsvm.h
prvm_cmds.c
prvm_edict.c

index 59d63a6..43ba96e 100644 (file)
@@ -232,17 +232,17 @@ typedef enum OSGK_AntiAliasType
 static void (*osgk_browser_resize) (OSGK_Browser* browser,
   int width, int height);
 
-/*static int (*osgk_browser_set_user_data) (OSGK_Browser* browser,
-  unsigned int key, void* data, int overrideData);*/
-/*static int (*osgk_browser_get_user_data) (OSGK_Browser* browser,
-  unsigned int key, void** data);*/
+static int (*osgk_browser_set_user_data) (OSGK_Browser* browser,
+  unsigned int key, void* data, int overrideData);
+static int (*osgk_browser_get_user_data) (OSGK_Browser* browser,
+  unsigned int key, void** data);
 
 /* OffscreenGecko/string.h */
 OSGK_DERIVEDTYPE(OSGK_String);
 
-/*static const char* (*osgk_string_get) (OSGK_String* str);*/
+static const char* (*osgk_string_get) (OSGK_String* str);
 
-/*static OSGK_String* (*osgk_string_create) (const char* str);*/
+static OSGK_String* (*osgk_string_create) (const char* str);
 
 /* OffscreenGecko/scriptvariant.h */
 
@@ -267,8 +267,8 @@ typedef enum OSGK_ScriptVariantType
 
 /*static OSGK_ScriptVariantType (*osgk_variant_get_type) (
   OSGK_ScriptVariant* variant);*/
-/*static OSGK_ScriptVariant* (*osgk_variant_convert) (
-  OSGK_ScriptVariant* variant, OSGK_ScriptVariantType newType);*/
+static OSGK_ScriptVariant* (*osgk_variant_convert) (
+  OSGK_ScriptVariant* variant, OSGK_ScriptVariantType newType);
 
 /*static int (*osgk_variant_get_int) (OSGK_ScriptVariant* variant,
   int* val);*/
@@ -282,9 +282,9 @@ typedef enum OSGK_ScriptVariantType
   int* val);*/
 /*static int (*osgk_variant_get_char) (OSGK_ScriptVariant* variant,
   unsigned int* val);*/
-/*// Does not increase ref count
+// Does not increase ref count
 static int (*osgk_variant_get_string) (OSGK_ScriptVariant* variant,
-  OSGK_String** val);*/
+  OSGK_String** val);
 /*// Does not increase ref count
 static int (*osgk_variant_get_isupports) (OSGK_ScriptVariant* variant,
   OSGK_CLASSTYPE_REF nsISupports** val);*/
@@ -309,8 +309,8 @@ static int (*osgk_variant_get_isupports) (OSGK_ScriptVariant* variant,
   OSGK_Embedding* embedding, int val);*/
 /*static OSGK_ScriptVariant* (*osgk_variant_create_char) (
   OSGK_Embedding* embedding, unsigned int val);*/
-/*static OSGK_ScriptVariant* (*osgk_variant_create_string) (
-  OSGK_Embedding* embedding, OSGK_String* val);*/
+static OSGK_ScriptVariant* (*osgk_variant_create_string) (
+  OSGK_Embedding* embedding, OSGK_String* val);
 /*static OSGK_ScriptVariant* (*osgk_variant_create_isupports) (
   OSGK_Embedding* embedding, OSGK_CLASSTYPE_REF nsISupports* val);*/
 /*static OSGK_ScriptVariant* (*osgk_variant_create_script_object) (
@@ -338,10 +338,10 @@ typedef OSGK_ScriptResult (*OSGK_CreateObjFunc) (
   OSGK_ScriptObjectCreateParams* params, void** objTag);
 typedef void (*OSGK_DestroyObjFunc) (void* objTag);
 
-/*static OSGK_ScriptObjectTemplate* (*osgk_sot_create) (
+static OSGK_ScriptObjectTemplate* (*osgk_sot_create) (
   OSGK_Embedding* embedding,
   OSGK_CreateObjFunc createFunc, OSGK_DestroyObjFunc destroyFunc,
-  void* createParam);*/
+  void* createParam);
 
 typedef OSGK_ScriptVariant* (*OSGK_GetPropertyFunc) (void* objTag,
   void* propTag);
@@ -356,16 +356,16 @@ typedef OSGK_ScriptResult (*OSGK_FunctionCallFunc) (void* objTag,
   void* methTag, size_t numParams, OSGK_ScriptVariant** params,
   OSGK_ScriptVariant** returnVal);
 
-/*static int (*osgk_sot_add_function) (
+static int (*osgk_sot_add_function) (
   OSGK_ScriptObjectTemplate* templ, const char* funcName, void* funcTag,
-  OSGK_FunctionCallFunc callFunc);*/
+  OSGK_FunctionCallFunc callFunc);
 
 /*static OSGK_ScriptVariant* (*osgk_sot_instantiate) (
   OSGK_ScriptObjectTemplate* templ, void** objTag);    */
 
-/*static int (*osgk_sot_register) (
+static int (*osgk_sot_register) (
   OSGK_ScriptObjectTemplate* templ, OSGK_Embedding* embedding, 
-  const char* name, unsigned int flags);*/
+  const char* name, unsigned int flags);
 
 /* --- >8 --- >8 --- End OffscreenGecko headers --- 8< --- 8< --- */
 
@@ -382,6 +382,7 @@ static OSGK_Embedding *cl_geckoembedding;
 struct clgecko_s {
        qboolean active;
        char name[ MAX_QPATH + 32 ];
+       int ownerProg;
 
        OSGK_Browser *browser;
        int width, height;
@@ -390,10 +391,12 @@ struct clgecko_s {
        rtexture_t *texture;
 };
 
-static clgecko_t cl_geckoinstances[ MAX_GECKO_INSTANCES ];
+#define USERDATAKEY_CL_GECKO_T       0
 
 static dllhandle_t osgk_dll = NULL;
 
+static clgecko_t cl_geckoinstances[ MAX_GECKO_INSTANCES ];
+
 static clgecko_t * cl_gecko_findunusedinstance( void ) {
        int i;
        for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {
@@ -498,6 +501,55 @@ void CL_Gecko_GetTextureExtent( clgecko_t *instance, float* pwidth, float* pheig
        *pheight = (float)instance->height / instance->texHeight;
 }
 
+static OSGK_ScriptResult dpGlobal_create (OSGK_ScriptObjectCreateParams* params, 
+                                         void** objTag)
+{
+  if (!osgk_browser_get_user_data (params->browser, USERDATAKEY_CL_GECKO_T, objTag))
+    return srFailed;
+  return srSuccess;
+}
+
+static OSGK_ScriptResult dpGlobal_query (void* objTag, void* methTag, 
+                                        size_t numParams, 
+                                        OSGK_ScriptVariant** params,
+                                        OSGK_ScriptVariant** returnVal)
+{
+  clgecko_t *instance = objTag;
+  OSGK_ScriptVariant* strVal;
+  OSGK_ScriptResult result = srFailed;
+  prvm_prog_t * saveProg;
+
+  /* Can happen when created from console */
+  if (instance->ownerProg < 0) return srFailed;
+
+  /* Require exactly one param, for now */
+  if (numParams != 1) return srFailed;
+
+  strVal = osgk_variant_convert (params[0], svtString);
+  if (strVal == 0) return srFailed;
+
+  saveProg = prog;
+  PRVM_SetProg(instance->ownerProg);
+
+  if (prog->funcoffsets.Gecko_Query)
+  {
+    OSGK_String* paramStr, *resultStr;
+
+    if (!osgk_variant_get_string (strVal, &paramStr)) return srFailed;
+    *((string_t*)&prog->globals.generic[OFS_PARM0]) = PRVM_SetTempString (osgk_string_get (paramStr));
+    PRVM_ExecuteProgram(prog->funcoffsets.Gecko_Query,"Gecko_Query() required");
+    resultStr = osgk_string_create (PRVM_G_STRING (OFS_RETURN));
+    *returnVal = osgk_variant_create_string (cl_geckoembedding, resultStr);
+    osgk_release (resultStr);
+    
+    result = srSuccess;
+  }
+
+  prog = saveProg;
+  
+  return result;
+}
+
 #if defined(WIN64)
 # define XULRUNNER_DIR_SUFFIX  "win64"
 #elif defined(WIN32)
@@ -506,42 +558,59 @@ void CL_Gecko_GetTextureExtent( clgecko_t *instance, float* pwidth, float* pheig
 # define XULRUNNER_DIR_SUFFIX  DP_OS_STR "-" DP_ARCH_STR
 #endif
 
-clgecko_t * CL_Gecko_CreateBrowser( const char *name ) {
-       clgecko_t *instance;
+static qboolean CL_Gecko_Embedding_Init (void)
+{
+       char profile_path [MAX_OSPATH];
+       OSGK_GeckoResult grc;
+       OSGK_EmbeddingOptions *options;
+       OSGK_ScriptObjectTemplate* dpGlobalTemplate;
 
-       if (!osgk_dll) return NULL;
+       if (!osgk_dll) return false;
 
-       // TODO: verify that we dont use a name twice
-       instance = cl_gecko_findunusedinstance();
-       // TODO: assert != NULL
-       
-       if( cl_geckoembedding == NULL ) {
-               char profile_path [MAX_OSPATH];
-               OSGK_GeckoResult grc;
-               OSGK_EmbeddingOptions *options;
+       if( cl_geckoembedding != NULL ) return true;
 
-               if( developer.integer > 0 ) {
-                       Con_Printf( "CL_Gecko_CreateBrowser: setting up gecko embedding\n" );
-               }
+       if( developer.integer > 0 ) {
+               Con_Printf( "CL_Gecko_Embedding_Init: setting up gecko embedding\n" );
+       }
 
-               options = osgk_embedding_options_create();
-       #ifdef XULRUNNER_DIR_SUFFIX
-               osgk_embedding_options_add_search_path( options, "./xulrunner-" XULRUNNER_DIR_SUFFIX "/" );
-       #endif
-               osgk_embedding_options_add_search_path( options, "./xulrunner/" );
-               dpsnprintf (profile_path, sizeof (profile_path), "%s/xulrunner_profile/", fs_gamedir);
-               osgk_embedding_options_set_profile_dir( options, profile_path, 0 );
-               cl_geckoembedding = osgk_embedding_create_with_options( options, &grc );
-               osgk_release( options );
+       options = osgk_embedding_options_create();
+#ifdef XULRUNNER_DIR_SUFFIX
+       osgk_embedding_options_add_search_path( options, "./xulrunner-" XULRUNNER_DIR_SUFFIX "/" );
+#endif
+       osgk_embedding_options_add_search_path( options, "./xulrunner/" );
+       dpsnprintf (profile_path, sizeof (profile_path), "%s/xulrunner_profile/", fs_gamedir);
+       osgk_embedding_options_set_profile_dir( options, profile_path, 0 );
+       cl_geckoembedding = osgk_embedding_create_with_options( options, &grc );
+       osgk_release( options );
                
-               if( cl_geckoembedding == NULL ) {
-                       Con_Printf( "CL_Gecko_CreateBrowser: Couldn't retrieve gecko embedding object (%.8x)!\n", grc );
-                       return NULL;
-               } else if( developer.integer > 0 ) {
-                       Con_Printf( "CL_Gecko_CreateBrowser: Embedding set up correctly\n" );
-               }
+       if( cl_geckoembedding == NULL ) {
+               Con_Printf( "CL_Gecko_Embedding_Init: Couldn't retrieve gecko embedding object (%.8x)!\n", grc );
+               return false;
+       } 
+       
+       if( developer.integer > 0 ) {
+               Con_Printf( "CL_Gecko_Embedding_Init: Embedding set up correctly\n" );
        }
 
+       dpGlobalTemplate = osgk_sot_create( cl_geckoembedding, dpGlobal_create, NULL, NULL );
+
+       osgk_sot_add_function (dpGlobalTemplate, "query", 0, dpGlobal_query);
+
+       osgk_sot_register (dpGlobalTemplate, cl_geckoembedding, "Darkplaces", 0);
+       osgk_release( dpGlobalTemplate );
+
+       return true;
+}
+
+clgecko_t * CL_Gecko_CreateBrowser( const char *name, int ownerProg ) {
+       clgecko_t *instance;
+
+       if (!CL_Gecko_Embedding_Init ()) return NULL;
+
+       // TODO: verify that we dont use a name twice
+       instance = cl_gecko_findunusedinstance();
+       // TODO: assert != NULL
+
        instance->active = true;
        strlcpy( instance->name, name, sizeof( instance->name ) );
        instance->browser = osgk_browser_create( cl_geckoembedding, DEFAULT_GECKO_SIZE, DEFAULT_GECKO_SIZE );
@@ -549,6 +618,9 @@ clgecko_t * CL_Gecko_CreateBrowser( const char *name ) {
                Con_Printf( "CL_Gecko_CreateBrowser: Browser object creation failed!\n" );
        }
        // TODO: assert != NULL
+       osgk_browser_set_user_data (instance->browser, USERDATAKEY_CL_GECKO_T,
+         instance, 0);
+       instance->ownerProg = ownerProg;
 
        instance->width = instance->texWidth = DEFAULT_GECKO_SIZE;
        instance->height = instance->texHeight = DEFAULT_GECKO_SIZE;
@@ -645,7 +717,7 @@ static void cl_gecko_create_f( void ) {
 
        // TODO: use snprintf instead
        sprintf(name, CLGECKOPREFIX "%s", Cmd_Argv(1));
-       CL_Gecko_CreateBrowser( name );
+       CL_Gecko_CreateBrowser( name, -1 );
 }
 
 static void cl_gecko_destroy_f( void ) {
@@ -763,6 +835,16 @@ static const dllfunction_t osgkFuncs[] =
        {"osgk_browser_event_mouse_button",         (void **) &osgk_browser_event_mouse_button},
        {"osgk_browser_event_mouse_wheel",          (void **) &osgk_browser_event_mouse_wheel},
        {"osgk_browser_event_key",                  (void **) &osgk_browser_event_key},
+       {"osgk_browser_set_user_data",              (void **) &osgk_browser_set_user_data},
+       {"osgk_browser_get_user_data",              (void **) &osgk_browser_get_user_data},
+       {"osgk_sot_create",                         (void **) &osgk_sot_create},
+       {"osgk_sot_register",                       (void **) &osgk_sot_register},
+       {"osgk_sot_add_function",                   (void **) &osgk_sot_add_function},
+       {"osgk_string_get",                         (void **) &osgk_string_get},
+       {"osgk_string_create",                      (void **) &osgk_string_create},
+       {"osgk_variant_convert",                    (void **) &osgk_variant_convert},
+       {"osgk_variant_get_string",                 (void **) &osgk_variant_get_string},
+       {"osgk_variant_create_string",              (void **) &osgk_variant_create_string},
        {NULL, NULL}
 };
 
index 3dd7337..fd12e80 100644 (file)
@@ -22,7 +22,7 @@ void CL_Gecko_Frame( void );
 void CL_Gecko_Init( void );\r
 void CL_Gecko_Shutdown( void );\r
 \r
-clgecko_t * CL_Gecko_CreateBrowser( const char *name );\r
+clgecko_t * CL_Gecko_CreateBrowser( const char *name, int ownerProg );\r
 clgecko_t * CL_Gecko_FindBrowser( const char *name );\r
 void CL_Gecko_DestroyBrowser( clgecko_t *instance );\r
 \r
index 4d8afd0..2033411 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -269,6 +269,7 @@ typedef struct prvm_prog_funcoffsets_s
        func_t CSQC_Parse_TempEntity; // csqc [515]: very helpfull when you want to create your own particles/decals/etc for effects that already exist
        func_t CSQC_Shutdown; // csqc
        func_t CSQC_UpdateView; // csqc
+       func_t Gecko_Query; // csqc, mqc
        func_t EndFrame; // ssqc
        func_t RestoreGame; // ssqc
        func_t SV_ChangeTeam; // ssqc
index a5c944c..bfa74e5 100644 (file)
@@ -3128,7 +3128,7 @@ void VM_gecko_create( void ) {
                        return;
        }
 
-       instance = prog->opengeckoinstances[ i ] = CL_Gecko_CreateBrowser( name );
+       instance = prog->opengeckoinstances[ i ] = CL_Gecko_CreateBrowser( name, PRVM_GetProgNr() );
    if( !instance ) {
                // TODO: error handling [12/3/2007 Black]
                PRVM_G_FLOAT( OFS_RETURN ) = 0;
index 5f16668..092f560 100644 (file)
@@ -1435,6 +1435,7 @@ void PRVM_FindOffsets(void)
        prog->funcoffsets.CSQC_Parse_TempEntity           = PRVM_ED_FindFunctionOffset("CSQC_Parse_TempEntity");
        prog->funcoffsets.CSQC_Shutdown                   = PRVM_ED_FindFunctionOffset("CSQC_Shutdown");
        prog->funcoffsets.CSQC_UpdateView                 = PRVM_ED_FindFunctionOffset("CSQC_UpdateView");
+       prog->funcoffsets.Gecko_Query                     = PRVM_ED_FindFunctionOffset("Gecko_Query");
        prog->funcoffsets.EndFrame                        = PRVM_ED_FindFunctionOffset("EndFrame");
        prog->funcoffsets.RestoreGame                     = PRVM_ED_FindFunctionOffset("RestoreGame");
        prog->funcoffsets.SV_ChangeTeam                   = PRVM_ED_FindFunctionOffset("SV_ChangeTeam");