Add interface flattening to Python XPCOM bindings.
Not part of the build, but a=drivers@mozilla.org anyway! git-svn-id: svn://10.0.0.236/trunk@95969 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -171,7 +171,7 @@ PyG_Base::AutoWrapPythonInstance(PyObject *ob, const nsIID &iid, nsISupports **p
|
||||
|
||||
obIID = Py_nsIID::PyObjectFromIID(iid);
|
||||
if (obIID==NULL) goto done;
|
||||
args = Py_BuildValue("OO", ob, obIID);
|
||||
args = Py_BuildValue("OOzi", ob, obIID, NULL, 0);
|
||||
if (args==NULL) goto done;
|
||||
wrap_ret = PyEval_CallObject(func, args);
|
||||
if (wrap_ret==NULL) goto done;
|
||||
|
||||
159
mozilla/extensions/python/xpcom/src/PyIClassInfo.cpp
Normal file
159
mozilla/extensions/python/xpcom/src/PyIClassInfo.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
* the specific language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Python XPCOM language bindings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is ActiveState Tool Corp.
|
||||
* Portions created by ActiveState Tool Corp. are Copyright (C) 2001
|
||||
* ActiveState Tool Corp. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Mark Hammond <MarkH@ActiveState.com> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// This code is part of the XPCOM extensions for Python.
|
||||
//
|
||||
// Written May 2001 by Mark Hammond.
|
||||
//
|
||||
// Based heavily on the Python COM support, which is
|
||||
// (c) Mark Hammond and Greg Stein.
|
||||
//
|
||||
// (c) 2001, ActiveState corp.
|
||||
|
||||
#include "PyXPCOM_std.h"
|
||||
#include "nsIClassInfo.h"
|
||||
|
||||
static nsIClassInfo *_GetI(PyObject *self) {
|
||||
nsIID iid = NS_GET_IID(nsIClassInfo);
|
||||
|
||||
if (!Py_nsISupports::Check(self, iid)) {
|
||||
PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
|
||||
return NULL;
|
||||
}
|
||||
return (nsIClassInfo *)Py_nsISupports::GetI(self);
|
||||
}
|
||||
|
||||
static PyObject *PyGetInterfaces(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
nsIClassInfo *pI = _GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIID** iidArray = nsnull;
|
||||
PRUint32 iidCount = 0;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->GetInterfaces(&iidCount, &iidArray);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
PyObject *ret = PyTuple_New(iidCount);
|
||||
if (ret==NULL)
|
||||
return NULL;
|
||||
for (PRUint32 i=0;i<iidCount;i++)
|
||||
PyTuple_SET_ITEM( ret, i, Py_nsIID::PyObjectFromIID(*(iidArray[i])) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *PyGetHelperForLanguage(PyObject *self, PyObject *args)
|
||||
{
|
||||
PRUint32 language = nsIProgrammingLanguage::PYTHON;
|
||||
if (!PyArg_ParseTuple(args, "|i", &language))
|
||||
return NULL;
|
||||
nsIClassInfo *pI = _GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsresult r;
|
||||
nsISupports *pi;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->GetHelperForLanguage(language, &pi);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(pi, NS_GET_IID(nsISupports), PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *MakeStringOrNone(char *v)
|
||||
{
|
||||
if (v)
|
||||
return PyString_FromString(v);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
#define GETATTR_CHECK_RESULT(nr) if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr)
|
||||
|
||||
PyObject *
|
||||
Py_nsIClassInfo::getattr(const char *name)
|
||||
{
|
||||
nsIClassInfo *pI = _GetI(this);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsresult nr;
|
||||
PyObject *ret = NULL;
|
||||
if (strcmp(name, "contractID")==0) {
|
||||
char *str_ret;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
nr = pI->GetContractID(&str_ret);
|
||||
Py_END_ALLOW_THREADS;
|
||||
GETATTR_CHECK_RESULT(nr);
|
||||
ret = MakeStringOrNone(str_ret);
|
||||
nsAllocator::Free(str_ret);
|
||||
} else if (strcmp(name, "classDescription")==0) {
|
||||
char *str_ret;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
nr = pI->GetClassDescription(&str_ret);
|
||||
Py_END_ALLOW_THREADS;
|
||||
GETATTR_CHECK_RESULT(nr);
|
||||
ret = MakeStringOrNone(str_ret);
|
||||
nsAllocator::Free(str_ret);
|
||||
} else if (strcmp(name, "classID")==0) {
|
||||
nsIID *iid;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
nr = pI->GetClassID(&iid);
|
||||
Py_END_ALLOW_THREADS;
|
||||
GETATTR_CHECK_RESULT(nr);
|
||||
ret = Py_nsIID::PyObjectFromIID(*iid);
|
||||
nsAllocator::Free(iid);
|
||||
} else if (strcmp(name, "implementationLanguage")==0) {
|
||||
PRUint32 i;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
nr = pI->GetImplementationLanguage(&i);
|
||||
Py_END_ALLOW_THREADS;
|
||||
GETATTR_CHECK_RESULT(nr);
|
||||
ret = PyInt_FromLong(i);
|
||||
} else {
|
||||
ret = Py_nsISupports::getattr(name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
Py_nsIClassInfo::setattr(const char *name, PyObject *v)
|
||||
{
|
||||
return Py_nsISupports::setattr(name, v);
|
||||
|
||||
}
|
||||
|
||||
struct PyMethodDef
|
||||
PyMethods_IClassInfo[] =
|
||||
{
|
||||
{ "getInterfaces", PyGetInterfaces, 1},
|
||||
{ "GetInterfaces", PyGetInterfaces, 1},
|
||||
{ "getHelperForLanguage", PyGetHelperForLanguage, 1},
|
||||
{ "GetHelperForLanguage", PyGetHelperForLanguage, 1},
|
||||
{NULL}
|
||||
};
|
||||
@@ -70,7 +70,7 @@ static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
/* Return a type based on the IID (with no extra ref) */
|
||||
return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE);
|
||||
return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyContractIDToClassID(PyObject *self, PyObject *args)
|
||||
|
||||
@@ -117,7 +117,7 @@ static PyObject *PyGetParent(PyObject *self, PyObject *args)
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIInterfaceInfo), PR_FALSE);
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIInterfaceInfo), PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyGetMethodCount(PyObject *self, PyObject *args)
|
||||
|
||||
@@ -93,6 +93,25 @@ Py_nsISupports::SafeRelease(Py_nsISupports *ob)
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ PyObject *
|
||||
Py_nsISupports::getattr(const char *name)
|
||||
{
|
||||
if (strcmp(name, "IID")==0)
|
||||
return Py_nsIID::PyObjectFromIID( m_iid );
|
||||
|
||||
PyXPCOM_TypeObject *this_type = (PyXPCOM_TypeObject *)ob_type;
|
||||
return Py_FindMethodInChain(&this_type->chain, this, (char *)name);
|
||||
}
|
||||
|
||||
/* virtual */ int
|
||||
Py_nsISupports::setattr(const char *name, PyObject *v)
|
||||
{
|
||||
char buf[128];
|
||||
sprintf(buf, "%s has read-only attributes", ob_type->tp_name );
|
||||
PyErr_SetString(PyExc_TypeError, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*static*/ Py_nsISupports *
|
||||
Py_nsISupports::Constructor(nsISupports *pInitObj, const nsIID &iid)
|
||||
{
|
||||
@@ -287,7 +306,7 @@ Py_nsISupports::MakeInterfaceResult(PyObject *pyis,
|
||||
done:
|
||||
if (PyErr_Occurred()) {
|
||||
NS_ABORT_IF_FALSE(ret==NULL, "Have an error, but also a return val!");
|
||||
PyXPCOM_LogError("Creating an interface object to be used as a parameter failed\n");
|
||||
PyXPCOM_LogError("Creating an interface object to be used as a result failed\n");
|
||||
PyErr_Clear();
|
||||
}
|
||||
Py_XDECREF(mod);
|
||||
|
||||
@@ -206,7 +206,9 @@ public:
|
||||
static void RegisterInterface( const nsIID &iid, PyTypeObject *t);
|
||||
static void InitType();
|
||||
|
||||
~Py_nsISupports();
|
||||
virtual ~Py_nsISupports();
|
||||
virtual PyObject *getattr(const char *name);
|
||||
virtual int setattr(const char *name, PyObject *val);
|
||||
protected:
|
||||
// ctor is protected - must create objects via
|
||||
// PyObjectFromInterface()
|
||||
@@ -398,7 +400,7 @@ protected:
|
||||
private:
|
||||
};
|
||||
|
||||
// For the Gateways me manually implement.
|
||||
// For the Gateways we manually implement.
|
||||
#define PYGATEWAY_BASE_SUPPORT(INTERFACE, GATEWAY_BASE) \
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
||||
{return PyG_Base::QueryInterface(aIID, aInstancePtr);} \
|
||||
@@ -570,4 +572,91 @@ private:
|
||||
PRBool created;
|
||||
};
|
||||
|
||||
// Our classes.
|
||||
// Hrm - So we can't have templates, eh??
|
||||
// preprocessor to the rescue, I guess.
|
||||
#define PyXPCOM_INTERFACE_DECLARE(ClassName, InterfaceName, Methods ) \
|
||||
\
|
||||
extern struct PyMethodDef Methods[]; \
|
||||
\
|
||||
class ClassName : public Py_nsISupports \
|
||||
{ \
|
||||
public: \
|
||||
static PyXPCOM_TypeObject *type; \
|
||||
static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
|
||||
return new ClassName(pInitObj, iid); \
|
||||
} \
|
||||
static void InitType(PyObject *iidNameDict) { \
|
||||
type = new PyXPCOM_TypeObject( \
|
||||
#InterfaceName, \
|
||||
Py_nsISupports::type, \
|
||||
sizeof(ClassName), \
|
||||
Methods, \
|
||||
Constructor); \
|
||||
const nsIID &iid = NS_GET_IID(InterfaceName); \
|
||||
RegisterInterface(iid, type); \
|
||||
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(iid); \
|
||||
PyDict_SetItemString(iidNameDict, "IID_"#InterfaceName, iid_ob); \
|
||||
Py_DECREF(iid_ob); \
|
||||
} \
|
||||
protected: \
|
||||
ClassName(nsISupports *p, const nsIID &iid) : \
|
||||
Py_nsISupports(p, iid, type) { \
|
||||
/* The IID _must_ be the IID of the interface we are wrapping! */ \
|
||||
NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
// End of PyXPCOM_INTERFACE_DECLARE macro
|
||||
|
||||
#define PyXPCOM_ATTR_INTERFACE_DECLARE(ClassName, InterfaceName, Methods )\
|
||||
\
|
||||
extern struct PyMethodDef Methods[]; \
|
||||
\
|
||||
class ClassName : public Py_nsISupports \
|
||||
{ \
|
||||
public: \
|
||||
static PyXPCOM_TypeObject *type; \
|
||||
static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
|
||||
return new ClassName(pInitObj, iid); \
|
||||
} \
|
||||
static void InitType(PyObject *iidNameDict) { \
|
||||
type = new PyXPCOM_TypeObject( \
|
||||
#InterfaceName, \
|
||||
Py_nsISupports::type, \
|
||||
sizeof(ClassName), \
|
||||
Methods, \
|
||||
Constructor); \
|
||||
const nsIID &iid = NS_GET_IID(InterfaceName); \
|
||||
RegisterInterface(iid, type); \
|
||||
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(iid); \
|
||||
PyDict_SetItemString(iidNameDict, "IID_"#InterfaceName, iid_ob); \
|
||||
Py_DECREF(iid_ob); \
|
||||
} \
|
||||
virtual PyObject *getattr(const char *name); \
|
||||
virtual int setattr(const char *name, PyObject *val); \
|
||||
protected: \
|
||||
ClassName(nsISupports *p, const nsIID &iid) : \
|
||||
Py_nsISupports(p, iid, type) { \
|
||||
/* The IID _must_ be the IID of the interface we are wrapping! */ \
|
||||
NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
// End of PyXPCOM_ATTR_INTERFACE_DECLARE macro
|
||||
|
||||
#define PyXPCOM_INTERFACE_DEFINE(ClassName, InterfaceName, Methods ) \
|
||||
PyXPCOM_TypeObject *ClassName::type = NULL;
|
||||
|
||||
|
||||
// And the classes
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIServiceManager, nsIServiceManager, PyMethods_IServiceManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
|
||||
PyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
|
||||
|
||||
#endif // __PYXPCOM_H__
|
||||
|
||||
@@ -34,12 +34,19 @@
|
||||
// Main Mozilla cross-platform declarations.
|
||||
#include "xp_core.h"
|
||||
|
||||
#include <nsIAllocator.h>
|
||||
#include <nsIWeakReference.h>
|
||||
#include <nsXPIDLString.h>
|
||||
#include <nsCRT.h>
|
||||
#include <xptcall.h>
|
||||
#include <xpt_xdr.h>
|
||||
#include "nsIAllocator.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "xptcall.h"
|
||||
#include "xpt_xdr.h"
|
||||
|
||||
// This header is considered internal - hence
|
||||
// we can use it to trigger "exports"
|
||||
|
||||
@@ -70,20 +70,13 @@ PyXPCOM_TypeObject::IsType(PyTypeObject *t)
|
||||
/*static*/PyObject *
|
||||
PyXPCOM_TypeObject::Py_getattr(PyObject *self, char *name)
|
||||
{
|
||||
if (strcmp(name, "IID")==0)
|
||||
return Py_nsIID::PyObjectFromIID( ((Py_nsISupports *)self)->m_iid );
|
||||
|
||||
PyXPCOM_TypeObject *this_type = (PyXPCOM_TypeObject *)self->ob_type;
|
||||
return Py_FindMethodInChain(&this_type->chain, self, name);
|
||||
return ((Py_nsISupports *)self)->getattr(name);
|
||||
}
|
||||
|
||||
/*static*/int
|
||||
PyXPCOM_TypeObject::Py_setattr(PyObject *op, char *name, PyObject *v)
|
||||
{
|
||||
char buf[128];
|
||||
sprintf(buf, "%s has read-only attributes", op->ob_type->tp_name );
|
||||
PyErr_SetString(PyExc_TypeError, buf);
|
||||
return -1;
|
||||
return ((Py_nsISupports *)op)->setattr(name, v);
|
||||
}
|
||||
|
||||
// @pymethod int|Py_nsISupports|__cmp__|Implements XPCOM rules for object identity.
|
||||
|
||||
@@ -129,6 +129,9 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
|
||||
LogError("Python initialization failed!\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#ifndef NS_DEBUG
|
||||
Py_OptimizeFlag = 1;
|
||||
#endif
|
||||
AddStandardPaths();
|
||||
PyObject *mod = PyImport_ImportModule("xpcom._xpcom");
|
||||
if (mod==NULL) {
|
||||
|
||||
@@ -40,6 +40,7 @@ CPP_OBJS= \
|
||||
.\$(OBJDIR)\PyGStub.obj \
|
||||
.\$(OBJDIR)\PyGInputStream.obj \
|
||||
.\$(OBJDIR)\PyGWeakReference.obj \
|
||||
.\$(OBJDIR)\PyIClassInfo.obj \
|
||||
.\$(OBJDIR)\PyIComponentManager.obj \
|
||||
.\$(OBJDIR)\PyIInputStream.obj \
|
||||
.\$(OBJDIR)\PyIEnumerator.obj \
|
||||
@@ -64,6 +65,7 @@ CPPSRCS = \
|
||||
PyGStub.cpp \
|
||||
PyGInputStream.cpp \
|
||||
PyGWeakReference.cpp \
|
||||
PyIClassInfo.cpp \
|
||||
PyIComponentManager.cpp \
|
||||
PyIInputStream.cpp \
|
||||
PyIEnumerator.cpp \
|
||||
|
||||
@@ -28,21 +28,19 @@
|
||||
// (c) 2000, ActiveState corp.
|
||||
|
||||
#include "PyXPCOM_std.h"
|
||||
#include <nsIInterfaceInfoManager.h>
|
||||
#include <nsIFileSpec.h>
|
||||
#include <nsSpecialSystemDirectory.h>
|
||||
#include <nsIThread.h>
|
||||
#include <nsISupportsPrimitives.h>
|
||||
#include <nsIModule.h>
|
||||
#include <nsIInputStream.h>
|
||||
#include "nsIFileSpec.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
#include <nsIEventQueue.h>
|
||||
#include <nsIProxyObjectManager.h>
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
|
||||
PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL;
|
||||
extern void PyXPCOM_InterpreterState_Ensure();
|
||||
@@ -58,6 +56,15 @@ extern void PyXPCOM_InterpreterState_Ensure();
|
||||
|
||||
#endif // XP_WIN
|
||||
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIServiceManager, nsIServiceManager, PyMethods_IServiceManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// This is the main entry point called by the Python component
|
||||
// loader.
|
||||
@@ -114,53 +121,6 @@ done:
|
||||
return nr;
|
||||
}
|
||||
|
||||
// Hrm - So we can't have templates, eh??
|
||||
// preprocessor to the rescue, I guess.
|
||||
#define PyXPCOM_INTERFACE_DEFINE(ClassName, InterfaceName, Methods ) \
|
||||
\
|
||||
extern struct PyMethodDef Methods[]; \
|
||||
\
|
||||
class ClassName : public Py_nsISupports \
|
||||
{ \
|
||||
public: \
|
||||
static PyXPCOM_TypeObject *type; \
|
||||
static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
|
||||
return new ClassName(pInitObj, iid); \
|
||||
} \
|
||||
static void InitType(PyObject *iidNameDict) { \
|
||||
type = new PyXPCOM_TypeObject( \
|
||||
#InterfaceName, \
|
||||
Py_nsISupports::type, \
|
||||
sizeof(ClassName), \
|
||||
Methods, \
|
||||
Constructor); \
|
||||
const nsIID &iid = NS_GET_IID(InterfaceName); \
|
||||
RegisterInterface(iid, type); \
|
||||
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(iid); \
|
||||
PyDict_SetItemString(iidNameDict, "IID_"#InterfaceName, iid_ob); \
|
||||
Py_DECREF(iid_ob); \
|
||||
} \
|
||||
protected: \
|
||||
ClassName(nsISupports *p, const nsIID &iid) : \
|
||||
Py_nsISupports(p, iid, type) { \
|
||||
/* The IID _must_ be the IID of the interface we are wrapping! */ \
|
||||
NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
PyXPCOM_TypeObject *ClassName::type = NULL; \
|
||||
\
|
||||
// End of PyXPCOM_INTERFACE_DEFINE macro
|
||||
|
||||
// And the classes
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIServiceManager, nsIServiceManager, PyMethods_IServiceManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
|
||||
|
||||
// "boot-strap" methods - interfaces we need to get the base
|
||||
// interface support!
|
||||
|
||||
@@ -302,7 +262,8 @@ static PyObject *
|
||||
PyXPCOMMethod_WrapObject(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *ob, *obIID;
|
||||
if (!PyArg_ParseTuple(args, "OO", &ob, &obIID))
|
||||
int bWrapClient = 1;
|
||||
if (!PyArg_ParseTuple(args, "OO|i", &ob, &obIID, &bWrapClient))
|
||||
return NULL;
|
||||
|
||||
nsIID iid;
|
||||
@@ -319,7 +280,7 @@ PyXPCOMMethod_WrapObject(PyObject *self, PyObject *args)
|
||||
AddDefaultGateway(ob, ret); // inject a weak reference to myself into the instance.
|
||||
|
||||
// Now wrap it in an interface.
|
||||
return Py_nsISupports::PyObjectFromInterface(ret, iid, PR_FALSE);
|
||||
return Py_nsISupports::PyObjectFromInterface(ret, iid, PR_FALSE, bWrapClient);
|
||||
}
|
||||
|
||||
// @pymethod int|pythoncom|_GetInterfaceCount|Retrieves the number of interface objects currently in existance
|
||||
@@ -600,6 +561,7 @@ init_xpcom() {
|
||||
REGISTER_IID(nsIFactory);
|
||||
REGISTER_IID(nsIWeakReference);
|
||||
REGISTER_IID(nsISupportsWeakReference);
|
||||
REGISTER_IID(nsIClassInfo);
|
||||
// Register our custom interfaces.
|
||||
|
||||
Py_nsISupports::InitType();
|
||||
@@ -610,6 +572,7 @@ init_xpcom() {
|
||||
Py_nsIInterfaceInfo::InitType(dict);
|
||||
Py_nsIServiceManager::InitType(dict);
|
||||
Py_nsIInputStream::InitType(dict);
|
||||
Py_nsIClassInfo::InitType(dict);
|
||||
|
||||
// We have special support for proxies - may as well add their constants!
|
||||
REGISTER_INT(PROXY_SYNC);
|
||||
|
||||
Reference in New Issue
Block a user