Support the construct hook on NPClass

Not yet tested, but the signature is identical to invokeDefault.
This commit is contained in:
David Benjamin 2011-03-26 00:11:33 -04:00
parent 51cf8ba27f
commit 17846fe51d
6 changed files with 108 additions and 3 deletions

View File

@ -54,6 +54,7 @@ extern int npclass_handle_SetProperty(rpc_connection_t *connection) attribute_hi
extern int npclass_handle_RemoveProperty(rpc_connection_t *connection) attribute_hidden;
extern int npclass_handle_Invalidate(rpc_connection_t *connection) attribute_hidden;
extern int npclass_handle_Enumerate(rpc_connection_t *connection) attribute_hidden;
extern int npclass_handle_Construct(rpc_connection_t *connection) attribute_hidden;
struct _NPVariant;
extern void npvariant_clear(struct _NPVariant *variant) attribute_hidden;

View File

@ -95,6 +95,7 @@ static bool g_NPClass_GetProperty(NPObject *npobj, NPIdentifier name, NPVariant
static bool g_NPClass_SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
static bool g_NPClass_RemoveProperty(NPObject *npobj, NPIdentifier name);
static bool g_NPClass_Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
static bool g_NPClass_Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
NPClass npclass_bridge = {
NPW_NP_CLASS_STRUCT_VERSION,
@ -108,7 +109,8 @@ NPClass npclass_bridge = {
g_NPClass_GetProperty,
g_NPClass_SetProperty,
g_NPClass_RemoveProperty,
g_NPClass_Enumerate
g_NPClass_Enumerate,
g_NPClass_Construct
};
static inline bool is_valid_npobject_class(NPObject *npobj)
@ -883,6 +885,105 @@ bool g_NPClass_Enumerate(NPObject *npobj,
return ret;
}
// NPClass::Construct
int npclass_handle_Construct(rpc_connection_t *connection)
{
D(bug("npclass_handle_Construct\n"));
NPObject *npobj;
uint32_t argCount;
NPVariant *args;
int error = rpc_method_get_args(connection,
RPC_TYPE_NP_OBJECT, &npobj,
RPC_TYPE_ARRAY, RPC_TYPE_NP_VARIANT, &argCount, &args,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPClass::Construct() get args", error);
return error;
}
uint32_t ret = false;
NPVariant result;
VOID_TO_NPVARIANT(result);
if (npobj && is_valid_npobject_class(npobj) && npobj->_class->construct) {
D(bugiI("NPClass::Construct(npobj %p)\n", npobj));
print_npvariant_args(args, argCount);
ret = npobj->_class->construct(npobj, args, argCount, &result);
gchar *result_str = string_of_NPVariant(&result);
D(bugiD("NPClass::Construct return: %d (%s)\n", ret, result_str));
g_free(result_str);
}
int rpc_ret = rpc_method_send_reply(connection,
RPC_TYPE_UINT32, ret,
RPC_TYPE_NP_VARIANT, &result,
RPC_TYPE_INVALID);
if (args) {
for (int i = 0; i < argCount; i++)
NPN_ReleaseVariantValue(&args[i]);
free(args);
}
NPN_ReleaseVariantValue(&result);
return rpc_ret;
}
static bool npclass_invoke_Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
NPVariant *result)
{
npw_return_val_if_fail(rpc_method_invoke_possible(g_rpc_connection), false);
int error = rpc_method_invoke(g_rpc_connection,
RPC_METHOD_NPCLASS_CONSTRUCT,
RPC_TYPE_NP_OBJECT, npobj,
RPC_TYPE_ARRAY, RPC_TYPE_NP_VARIANT, argCount, args,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPClass::Construct() invoke", error);
return false;
}
uint32_t ret;
error = rpc_method_wait_for_reply(g_rpc_connection,
RPC_TYPE_UINT32, &ret,
RPC_TYPE_NP_VARIANT, result,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPClass::Construct() wait for reply", error);
return false;
}
return ret;
}
bool g_NPClass_Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
NPVariant *result)
{
if (result == NULL)
return false;
VOID_TO_NPVARIANT(*result);
if (!is_valid_npobject_class(npobj))
return false;
if (!thread_check()) {
npw_printf("WARNING: NPClass::Construct not called from the main thread\n");
return false;
}
D(bugiI("NPClass::Construct(npobj %p)\n", npobj));
print_npvariant_args(args, argCount);
bool ret = npclass_invoke_Construct(npobj, args, argCount, result);
gchar *result_str = string_of_NPVariant(result);
D(bugiD("NPClass::Construct return: %d (%s)\n", ret, result_str));
g_free(result_str);
return ret;
}
/* ====================================================================== */
/* === NPObjectInfo === */

View File

@ -35,7 +35,7 @@
/* Supported NPAPI interfaces */
#define NPW_NPAPI_VERSION 18
#define NPW_NP_CLASS_STRUCT_VERSION 2
#define NPW_NP_CLASS_STRUCT_VERSION 3
#define NPW_TOOLKIT NPNVGtk2
/* What are we building? */

View File

@ -95,7 +95,8 @@ enum {
RPC_METHOD_NPCLASS_GET_PROPERTY,
RPC_METHOD_NPCLASS_SET_PROPERTY,
RPC_METHOD_NPCLASS_REMOVE_PROPERTY,
RPC_METHOD_NPCLASS_ENUMERATE
RPC_METHOD_NPCLASS_ENUMERATE,
RPC_METHOD_NPCLASS_CONSTRUCT
};
// NPAPI data types

View File

@ -4632,6 +4632,7 @@ static int do_main(int argc, char **argv, const char *connection_path)
{ RPC_METHOD_NPCLASS_SET_PROPERTY, npclass_handle_SetProperty },
{ RPC_METHOD_NPCLASS_REMOVE_PROPERTY, npclass_handle_RemoveProperty },
{ RPC_METHOD_NPCLASS_ENUMERATE, npclass_handle_Enumerate },
{ RPC_METHOD_NPCLASS_CONSTRUCT, npclass_handle_Construct },
};
if (rpc_connection_add_method_descriptors(g_rpc_connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
npw_printf("ERROR: failed to setup NPP method callbacks\n");

View File

@ -3520,6 +3520,7 @@ static void plugin_init(int is_NP_Initialize)
{ RPC_METHOD_NPCLASS_SET_PROPERTY, npclass_handle_SetProperty },
{ RPC_METHOD_NPCLASS_REMOVE_PROPERTY, npclass_handle_RemoveProperty },
{ RPC_METHOD_NPCLASS_ENUMERATE, npclass_handle_Enumerate },
{ RPC_METHOD_NPCLASS_CONSTRUCT, npclass_handle_Construct },
};
if (rpc_connection_add_method_descriptors(g_rpc_connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
npw_printf("ERROR: failed to setup NPN method callbacks\n");