PyXPCOM.h revision 7c6ad5c14eb65fd60fa623546780ba9ea769d8e1
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync/* ***** BEGIN LICENSE BLOCK *****
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Version: MPL 1.1/GPL 2.0/LGPL 2.1
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * The contents of this file are subject to the Mozilla Public License Version
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * 1.1 (the "License"); you may not use this file except in compliance with
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * the License. You may obtain a copy of the License at
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * http://www.mozilla.org/MPL/
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Software distributed under the License is distributed on an "AS IS" basis,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * for the specific language governing rights and limitations under the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * License.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * The Original Code is the Python XPCOM language bindings.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * The Initial Developer of the Original Code is
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * ActiveState Tool Corp.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Portions created by the Initial Developer are Copyright (C) 2000
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * the Initial Developer. All Rights Reserved.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Contributor(s):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Mark Hammond <mhammond@skippinet.com.au> (original author)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * Alternatively, the contents of this file may be used under the terms of
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * either the GNU General Public License Version 2 or later (the "GPL"), or
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * in which case the provisions of the GPL or the LGPL are applicable instead
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * of those above. If you wish to allow use of your version of this file only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * under the terms of either the GPL or the LGPL, and not to allow others to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * use your version of this file under the terms of the MPL, indicate your
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * decision by deleting the provisions above and replace them with the notice
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * and other provisions required by the GPL or the LGPL. If you do not delete
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * the provisions above, a recipient may use your version of this file under
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * the terms of any one of the MPL, the GPL or the LGPL.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync * ***** END LICENSE BLOCK ***** */
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// PyXPCOM.h - the main header file for the Python XPCOM support.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This code is part of the XPCOM extensions for Python.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Written May 2000 by Mark Hammond.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Based heavily on the Python COM support, which is
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// (c) Mark Hammond and Greg Stein.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// (c) 2000, ActiveState corp.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifndef __PYXPCOM_H__
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define __PYXPCOM_H__
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIAllocator.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIWeakReference.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIInterfaceInfoManager.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIClassInfo.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIComponentManager.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIComponentManagerObsolete.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIServiceManager.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIInputStream.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIVariant.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsIModule.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsXPIDLString.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "nsCRT.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "xptcall.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include "xpt_xdr.h"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef HAVE_LONG_LONG
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Mozilla also defines this - we undefine it to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // prevent a compiler warning.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# undef HAVE_LONG_LONG
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // HAVE_LONG_LONG
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef _POSIX_C_SOURCE // Ditto here
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# undef _POSIX_C_SOURCE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // _POSIX_C_SOURCE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef VBOX_PYXPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// unfortunatelly, if SOLARIS is defined Python porting layer
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// defines gethostname() in invalid fashion what kills compilation
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef SOLARIS
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#undef SOLARIS
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define SOLARIS_WAS_DEFINED
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include <Python.h>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef SOLARIS_WAS_DEFINED
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define SOLARIS
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#undef SOLARIS_WAS_DEFINED
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef VBOX_PYXPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#if (PY_VERSION_HEX <= 0x02040000)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// although in more recent versions of Python this type is ssize_t, earlier
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// it was used as int
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynctypedef int Py_ssize_t;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#else
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#include <Python.h>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#if (PY_VERSION_HEX <= 0x02030000)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// this one not defined before
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncinline PyObject *PyBool_FromLong(long ok)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *result;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (ok)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync result = Py_True;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync else
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync result = Py_False;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_INCREF(result);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return result;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync}
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef BUILD_PYXPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync /* We are building the main dll */
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# define PYXPCOM_EXPORT NS_EXPORT
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#else
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync /* This module uses the dll */
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# define PYXPCOM_EXPORT NS_IMPORT
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // BUILD_PYXPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// An IID we treat as NULL when passing as a reference.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT nsIID Py_nsIID_NULL;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass Py_nsISupports;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync/*************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Error and exception related function.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync*************************************************************************/
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define NS_PYXPCOM_NO_SUCH_METHOD \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_PYXPCOM, 0)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// The exception object (loaded from the xpcom .py code)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT PyObject *PyXPCOM_Error;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Client related functions - generally called by interfaces before
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// they return NULL back to Python to indicate the error.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// All these functions return NULL so interfaces can generally
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// just "return PyXPCOM_BuildPyException(hr, punk, IID_IWhatever)"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyXPCOM_BuildPyException(nsresult res);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
7c6ad5c14eb65fd60fa623546780ba9ea769d8e1vboxsync#ifdef VBOX
7c6ad5c14eb65fd60fa623546780ba9ea769d8e1vboxsync// Build human readable error message out of XPCOM error
7c6ad5c14eb65fd60fa623546780ba9ea769d8e1vboxsyncPYXPCOM_EXPORT PyObject *PyXPCOM_BuildErrorMessage(nsresult r);
7c6ad5c14eb65fd60fa623546780ba9ea769d8e1vboxsync#endif
7c6ad5c14eb65fd60fa623546780ba9ea769d8e1vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Used in gateways to handle the current Python exception
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// NOTE: this function assumes it is operating within the Python context
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT nsresult PyXPCOM_SetCOMErrorFromPyException();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Write current exception and traceback to a string.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PRBool PyXPCOM_FormatCurrentException(nsCString &streamout);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Write specified exception and traceback to a string.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PRBool PyXPCOM_FormatGivenException(nsCString &streamout,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *exc_typ, PyObject *exc_val,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *exc_tb);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// A couple of logging/error functions. These probably end up
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// being written to the console service.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Log a warning for the user - something at runtime
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// they may care about, but nothing that prevents us actually
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// working.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// As it's designed for user error/warning, it exists in non-debug builds.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_LogWarning(const char *fmt, ...);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Log an error for the user - something that _has_ prevented
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// us working. This is probably accompanied by a traceback.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// As it's designed for user error/warning, it exists in non-debug builds.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_LogError(const char *fmt, ...);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// The raw one
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_Log(const char *level, const nsCString &msg);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef DEBUG
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Mainly designed for developers of the XPCOM package.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Only enabled in debug builds.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_LogDebug(const char *fmt, ...);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PYXPCOM_LOG_DEBUG PyXPCOM_LogDebug
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#else
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PYXPCOM_LOG_DEBUG()
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // DEBUG
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Some utility converters
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// moz strings to PyObject.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyObject_FromNSString( const nsACString &s,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bAssumeUTF8 = PR_FALSE );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyObject_FromNSString( const nsAString &s );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyObject_FromNSString( const PRUnichar *s,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRUint32 len = (PRUint32)-1);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// PyObjects to moz strings. As per the moz string guide, we pass a reference
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// to an abstract string
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PRBool PyObject_AsNSString( PyObject *ob, nsAString &aStr);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Variants.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT nsresult PyObject_AsVariant( PyObject *ob, nsIVariant **aRet);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyObject_FromVariant( Py_nsISupports *parent,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsIVariant *v);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Interfaces - these are the "official" functions
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bMakeNicePyObject = PR_TRUE);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync/*************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Support for CALLING (ie, using) interfaces.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync*************************************************************************/
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynctypedef Py_nsISupports* (* PyXPCOM_I_CTOR)(nsISupports *, const nsIID &);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//////////////////////////////////////////////////////////////////////////
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// class PyXPCOM_TypeObject
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Base class for (most of) the type objects.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyTypeObject {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_TypeObject(
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const char *name,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_TypeObject *pBaseType,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int typeSize,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync struct PyMethodDef* methodList,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_I_CTOR ctor);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~PyXPCOM_TypeObject();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyMethodChain chain;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_TypeObject *baseType;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_I_CTOR ctor;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool IsType(PyTypeObject *t);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Static methods for the Python type.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void Py_dealloc(PyObject *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *Py_repr(PyObject *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *Py_str(PyObject *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *Py_getattr(PyObject *self, char *name);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static int Py_setattr(PyObject *op, char *name, PyObject *v);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static int Py_cmp(PyObject *ob1, PyObject *ob2);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static long Py_hash(PyObject *self);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//////////////////////////////////////////////////////////////////////////
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// class Py_nsISupports
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This class serves 2 purposes:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// * It is a base class for other interfaces we support "natively"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// * It is instantiated for _all_ other interfaces.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This is different than win32com, where a PyIUnknown only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// ever holds an IUnknown - but here, we could be holding
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// _any_ interface.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT Py_nsISupports : public PyObject
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Check if a Python object can safely be cast to an Py_nsISupports,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // and optionally check that the object is wrapping the specified
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // interface.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool Check( PyObject *ob, const nsIID &checkIID = Py_nsIID_NULL) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports *self = static_cast<Py_nsISupports *>(ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (ob==NULL || !PyXPCOM_TypeObject::IsType(ob->ob_type ))
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return PR_FALSE;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (!checkIID.Equals(Py_nsIID_NULL))
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return self->m_iid.Equals(checkIID) != 0;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return PR_TRUE;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Get the nsISupports interface from the PyObject WITH NO REF COUNT ADDED
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static nsISupports *GetI(PyObject *self, nsIID *ret_iid = NULL);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsCOMPtr<nsISupports> m_obj;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsIID m_iid;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Given an nsISupports and an Interface ID, create and return an object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Does not QI the object - the caller must ensure the nsISupports object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // is really a pointer to an object identified by the IID (although
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // debug builds should check this)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // PRBool bMakeNicePyObject indicates if we should call back into
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Python to wrap the object. This allows Python code to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // see the correct xpcom.client.Interface object even when calling
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // xpcom functions directly from C++.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // NOTE: There used to be a bAddRef param to this as an internal
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // optimization, but since removed. This function *always* takes a
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // reference to the nsISupports.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *PyObjectFromInterface(nsISupports *ps,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bMakeNicePyObject = PR_TRUE,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bIsInternalCall = PR_FALSE);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Given a Python object that is a registered COM type, return a given
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // interface pointer on its underlying object, with a NEW REFERENCE ADDED.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // bTryAutoWrap indicates if a Python instance object should attempt to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // be automatically wrapped in an XPCOM object. This is really only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // provided to stop accidental recursion should the object returned by
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // the wrap process itself be in instance (where it should already be
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // a COM object.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // If |iid|==nsIVariant, then arbitary Python objects will be wrapped
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // in an nsIVariant.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool InterfaceFromPyObject(
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *ob,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsISupports **ppret,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bNoneOK,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bTryAutoWrap = PR_TRUE);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Given a Py_nsISupports, return an interface.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Object *must* be Py_nsISupports - there is no
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // "autowrap", no "None" support, etc
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool InterfaceFromPyISupports(PyObject *ob,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsISupports **ppv);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // The Python methods
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *QueryInterface(PyObject *self, PyObject *args);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Internal (sort-of) objects.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static NS_EXPORT_STATIC_MEMBER_(PyXPCOM_TypeObject) *type;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static NS_EXPORT_STATIC_MEMBER_(PyMethodDef) methods[];
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *mapIIDToType;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void SafeRelease(Py_nsISupports *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void RegisterInterface( const nsIID &iid, PyTypeObject *t);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void InitType();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual ~Py_nsISupports();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual PyObject *getattr(const char *name);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual int setattr(const char *name, PyObject *val);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // A virtual function to sub-classes can customize the way
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // nsISupports objects are returned from their methods.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // ps is a new object just obtained from some operation performed on us
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual PyObject *MakeInterfaceResult(nsISupports *ps, const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool bMakeNicePyObject = PR_TRUE) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return PyObjectFromInterface(ps, iid, bMakeNicePyObject);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // ctor is protected - must create objects via
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // PyObjectFromInterface()
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports(nsISupports *p,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyTypeObject *type);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Make a default wrapper for an ISupports (which is an
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // xpcom.client.Component instance)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *MakeDefaultWrapper(PyObject *pyis, const nsIID &iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Python/XPCOM IID support
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT Py_nsIID : public PyObject
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsIID(const nsIID &riid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsIID m_iid;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync IsEqual(const nsIID &riid) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return m_iid.Equals(riid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync IsEqual(PyObject *ob) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return ob &&
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ob->ob_type== &type &&
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync m_iid.Equals(((Py_nsIID *)ob)->m_iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync IsEqual(Py_nsIID &iid) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return m_iid.Equals(iid.m_iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObjectFromIID(const nsIID &iid) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return new Py_nsIID(iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool IIDFromPyObject(PyObject *ob, nsIID *pRet);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync /* Python support */
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *PyTypeMethod_getattr(PyObject *self, char *name);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static int PyTypeMethod_compare(PyObject *self, PyObject *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *PyTypeMethod_repr(PyObject *self);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static long PyTypeMethod_hash(PyObject *self);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyObject *PyTypeMethod_str(PyObject *self);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void PyTypeMethod_dealloc(PyObject *self);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static NS_EXPORT_STATIC_MEMBER_(PyTypeObject) type;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static NS_EXPORT_STATIC_MEMBER_(PyMethodDef) methods[];
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync///////////////////////////////////////////////////////
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Helper classes for managing arrays of variants.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PythonTypeDescriptor; // Forward declare.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyXPCOM_InterfaceVariantHelper {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_InterfaceVariantHelper(Py_nsISupports *parent, int methodindex);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~PyXPCOM_InterfaceVariantHelper();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool Init(PyObject *obParams);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool FillArray();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *MakePythonResult();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsXPTCVariant *m_var_array;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int m_num_array;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int m_methodindex;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *MakeSinglePythonResult(int index);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool FillInVariant(const PythonTypeDescriptor &, int, int);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool PrepareOutVariant(const PythonTypeDescriptor &td, int value_index);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRUint32 GetSizeIs( int var_index, PRBool is_arg1);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *m_pyparams; // sequence of actual params passed (ie, not including hidden)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *m_typedescs; // desc of _all_ params, including hidden.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PythonTypeDescriptor *m_python_type_desc_array;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync void **m_buffer_array;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports *m_parent;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync/*************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Support for IMPLEMENTING interfaces.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync*************************************************************************/
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define NS_IINTERNALPYTHON_IID_STR "AC7459FC-E8AB-4f2e-9C4F-ADDC53393A20"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define NS_IINTERNALPYTHON_IID \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync { 0xac7459fc, 0xe8ab, 0x4f2e, { 0x9c, 0x4f, 0xad, 0xdc, 0x53, 0x39, 0x3a, 0x20 } }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PyXPCOM_GatewayWeakReference;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This interface is needed primarily to give us a known vtable base.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// If we QI a Python object for this interface, we can safely cast the result
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// to a PyG_Base. Any other interface, we do now know which vtable we will get.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// We also allow the underlying PyObject to be extracted
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass nsIInternalPython : public nsISupports {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_DEFINE_STATIC_IID_ACCESSOR(NS_IINTERNALPYTHON_IID)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Get the underlying Python object with new reference added
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual PyObject *UnwrapPythonObject(void) = 0;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This is roughly equivalent to PyGatewayBase in win32com
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyG_Base : public nsIInternalPython, public nsISupportsWeakReference
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_DECL_ISUPPORTS
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_DECL_NSISUPPORTSWEAKREFERENCE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *UnwrapPythonObject(void);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // A static "constructor" - the real ctor is protected.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static nsresult CreateNew(PyObject *pPyInstance,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync void **ppResult);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // A utility to auto-wrap an arbitary Python instance
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // in a COM gateway.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PRBool AutoWrapPythonInstance(PyObject *ob,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsISupports **ppret);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // A helper that creates objects to be passed for nsISupports
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // objects. See extensive comments in PyG_Base.cpp.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *MakeInterfaceParam(nsISupports *pis,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID *piid,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int methodIndex = -1,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const XPTParamDescriptor *d = NULL,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int paramIndex = -1);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // A helper that ensures all casting and vtable offsetting etc
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // done against this object happens in the one spot!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual void *ThisAsIID( const nsIID &iid ) = 0;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Helpers for "native" interfaces.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Not used by the generic stub interface.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult HandleNativeGatewayError(const char *szMethodName);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // These data members used by the converter helper functions - hence public
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsIID m_iid;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject * m_pPyObject;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // We keep a reference count on this object, and the object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // itself uses normal refcount rules - thus, it will only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // die when we die, and all external references are removed.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // This means that once we have created it (and while we
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // are alive) it will never die.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsCOMPtr<nsIWeakReference> m_pWeakRef;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef NS_BUILD_REFCNT_LOGGING
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync char refcntLogRepr[64]; // sigh - I wish I knew how to use the Moz string classes :( OK for debug only tho.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyG_Base(PyObject *instance, const nsIID &iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual ~PyG_Base();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyG_Base *m_pBaseObject; // A chain to implement identity rules.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult InvokeNativeViaPolicy( const char *szMethodName,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject **ppResult = NULL,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const char *szFormat = NULL,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ...
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult InvokeNativeViaPolicyInternal( const char *szMethodName,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject **ppResult,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const char *szFormat,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync va_list va);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult InvokeNativeGetViaPolicy(const char *szPropertyName,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject **ppResult = NULL
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult InvokeNativeSetViaPolicy(const char *szPropertyName,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ...);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyXPCOM_XPTStub : public PyG_Base, public nsXPTCStubBase
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncfriend class PyG_Base;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync {return PyG_Base::QueryInterface(aIID, aInstancePtr);} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD_(nsrefcnt) AddRef(void) {return PyG_Base::AddRef();} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD_(nsrefcnt) Release(void) {return PyG_Base::Release();} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // call this method and return result
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD CallMethod(PRUint16 methodIndex,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsXPTMethodInfo* info,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsXPTCMiniVariant* params);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual void *ThisAsIID(const nsIID &iid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_XPTStub(PyObject *instance, const nsIID &iid) : PyG_Base(instance, iid) {;}
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprivate:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// For the Gateways we manually implement.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PYGATEWAY_BASE_SUPPORT(INTERFACE, GATEWAY_BASE) \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync {return PyG_Base::QueryInterface(aIID, aInstancePtr);} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD_(nsrefcnt) AddRef(void) {return PyG_Base::AddRef();} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_IMETHOD_(nsrefcnt) Release(void) {return PyG_Base::Release();} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual void *ThisAsIID(const nsIID &iid) { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (iid.Equals(NS_GET_IID(INTERFACE))) return (INTERFACE *)this; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return GATEWAY_BASE::ThisAsIID(iid); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetGatewayCount(void);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetInterfaceCount(void);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Weak Reference class. This is a true COM object, representing
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// a weak reference to a Python object. For each Python XPCOM object,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// there is exactly zero or one corresponding weak reference instance.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// When both are alive, each holds a pointer to the other. When the main
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// object dies due to XPCOM reference counting, it zaps the pointer
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// in its corresponding weak reference object. Thus, the weak-reference
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// can live beyond the object (possibly with a NULL pointer back to the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// "real" object, but as implemented, the weak reference will never be
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// destroyed before the object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyXPCOM_GatewayWeakReference : public nsIWeakReference {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_GatewayWeakReference(PyG_Base *base);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual ~PyXPCOM_GatewayWeakReference();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_DECL_ISUPPORTS
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_DECL_NSIWEAKREFERENCE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyG_Base *m_pBase; // NO REF COUNT!!!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef NS_BUILD_REFCNT_LOGGING
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync char refcntLogRepr[41];
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Helpers classes for our gateways.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PYXPCOM_EXPORT PyXPCOM_GatewayVariantHelper
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_GatewayVariantHelper( PyG_Base *gateway,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int methodIndex,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsXPTMethodInfo *info,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsXPTCMiniVariant* params );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~PyXPCOM_GatewayVariantHelper();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *MakePyArgs();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult ProcessPythonResult(PyObject *ob);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyG_Base *m_gateway;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprivate:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult BackFillVariant( PyObject *ob, int index);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyObject *MakeSingleParam(int index, PythonTypeDescriptor &td);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool GetIIDForINTERFACE_ID(int index, const nsIID **ppret);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsresult GetArrayType(PRUint8 index, PRUint8 *ret, nsIID **ppiid);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRUint32 GetSizeIs( int var_index, PRBool is_arg1);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool CanSetSizeIs( int var_index, PRBool is_arg1 );
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsIInterfaceInfo *GetInterfaceInfo(); // NOTE: no ref count on result.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsXPTCMiniVariant* m_params;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsXPTMethodInfo *m_info;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int m_method_index;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PythonTypeDescriptor *m_python_type_desc_array;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync int m_num_type_descs;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsCOMPtr<nsIInterfaceInfo> m_interface_info;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Misc converters.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyObject *PyObject_FromXPTType( const nsXPTType *d);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyObject *PyObject_FromXPTTypeDescriptor( const XPTTypeDescriptor *d);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyObject *PyObject_FromXPTParamDescriptor( const XPTParamDescriptor *d);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyObject *PyObject_FromXPTMethodDescriptor( const XPTMethodDescriptor *d);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyObject *PyObject_FromXPTConstant( const XPTConstDescriptor *d);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// DLL reference counting functions.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Although we maintain the count, we never actually
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// finalize Python when it hits zero!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncvoid PyXPCOM_DLLAddRef();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncvoid PyXPCOM_DLLRelease();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync/*************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync LOCKING AND THREADING
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync**************************************************************************
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync*************************************************************************/
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// We have 2 discrete locks in use (when no free-threaded is used, anyway).
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// The first type of lock is the global Python lock. This is the standard lock
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// in use by Python, and must be used as documented by Python. Specifically, no
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// 2 threads may _ever_ call _any_ Python code (including INCREF/DECREF) without
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// first having this thread lock.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// The second type of lock is a "global framework lock", and used whenever 2 threads
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// of C code need access to global data. This is different than the Python
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// lock - this lock is used when no Python code can ever be called by the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// threads, but the C code still needs thread-safety.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// We also supply helper classes which make the usage of these locks a one-liner.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// The "framework" lock, implemented as a PRLock
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_AcquireGlobalLock(void);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_ReleaseGlobalLock(void);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Helper class for the DLL global lock.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This class magically waits for PyXPCOM framework global lock, and releases it
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// when finished.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// NEVER new one of these objects - only use on the stack!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass CEnterLeaveXPCOMFramework {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync CEnterLeaveXPCOMFramework() {PyXPCOM_AcquireGlobalLock();}
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~CEnterLeaveXPCOMFramework() {PyXPCOM_ReleaseGlobalLock();}
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Python thread-lock stuff. Free-threading patches use different semantics, but
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// these are abstracted away here...
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//#include <threadstate.h>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Helper class for Enter/Leave Python
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync//
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// This class magically waits for the Python global lock, and releases it
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// when finished.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Nested invocations will deadlock, so be careful.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// NEVER new one of these objects - only use on the stack!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_MakePendingCalls();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PRBool PyXPCOM_Globals_Ensure();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// For 2.3, use the PyGILState_ calls
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#if (PY_VERSION_HEX >= 0x02030000)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PYXPCOM_USE_PYGILSTATE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#ifdef PYXPCOM_USE_PYGILSTATE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass CEnterLeavePython {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync CEnterLeavePython() {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync state = PyGILState_Ensure();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // See "pending calls" comment below. We reach into the Python
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // implementation to see if we are the first call on the stack.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (PyThreadState_Get()->gilstate_counter==1) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_MakePendingCalls();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~CEnterLeavePython() {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyGILState_Release(state);
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyGILState_STATE state;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#else
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern PYXPCOM_EXPORT PyInterpreterState *PyXPCOM_InterpreterState;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT PRBool PyXPCOM_ThreadState_Ensure();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_ThreadState_Free();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_ThreadState_Clear();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Acquire();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Release();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Pre 2.3 thread-state dances.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass CEnterLeavePython {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync CEnterLeavePython() {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync created = PyXPCOM_ThreadState_Ensure();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_InterpreterLock_Acquire();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if (created) {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // If pending python calls are waiting as we enter Python,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // it will generally mean an asynch signal handler, etc.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // We can either call it here, or wait for Python to call it
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // as part of its "even 'n' opcodes" check. If we wait for
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Python to check it and the pending call raises an exception,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // then it is _our_ code that will fail - this is unfair,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // as the signal was raised before we were entered - indeed,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // we may be directly responding to the signal!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // Thus, we flush all the pending calls here, and report any
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // exceptions via our normal exception reporting mechanism.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // We can then execute our code in the knowledge that only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // signals raised _while_ we are executing will cause exceptions.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_MakePendingCalls();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ~CEnterLeavePython() {
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // The interpreter state must be cleared
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // _before_ we release the lock, as some of
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // the sys. attributes cleared (eg, the current exception)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // may need the lock to invoke their destructors -
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // specifically, when exc_value is a class instance, and
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync // the exception holds the last reference!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if ( created )
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_ThreadState_Clear();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_InterpreterLock_Release();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync if ( created )
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PyXPCOM_ThreadState_Free();
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync }
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprivate:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync PRBool created;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync};
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // PYXPCOM_USE_PYGILSTATE
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Our classes.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// Hrm - So we can't have templates, eh??
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// preprocessor to the rescue, I guess.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PyXPCOM_INTERFACE_DECLARE(ClassName, InterfaceName, Methods ) \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern struct PyMethodDef Methods[]; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass ClassName : public Py_nsISupports \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{ \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic: \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PYXPCOM_EXPORT PyXPCOM_TypeObject *type; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return new ClassName(pInitObj, iid); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void InitType() { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync type = new PyXPCOM_TypeObject( \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync #InterfaceName, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports::type, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync sizeof(ClassName), \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Methods, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Constructor); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid = NS_GET_IID(InterfaceName); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync RegisterInterface(iid, type); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected: \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ClassName(nsISupports *p, const nsIID &iid) : \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports(p, iid, type) { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync /* The IID _must_ be the IID of the interface we are wrapping! */ \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync}; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// End of PyXPCOM_INTERFACE_DECLARE macro
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PyXPCOM_ATTR_INTERFACE_DECLARE(ClassName, InterfaceName, Methods )\
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncextern struct PyMethodDef Methods[]; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass ClassName : public Py_nsISupports \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync{ \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncpublic: \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static PyXPCOM_TypeObject *type; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return new ClassName(pInitObj, iid); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync static void InitType() { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync type = new PyXPCOM_TypeObject( \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync #InterfaceName, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports::type, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync sizeof(ClassName), \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Methods, \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Constructor); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync const nsIID &iid = NS_GET_IID(InterfaceName); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync RegisterInterface(iid, type); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync} \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual PyObject *getattr(const char *name); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync virtual int setattr(const char *name, PyObject *val); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprotected: \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ClassName(nsISupports *p, const nsIID &iid) : \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Py_nsISupports(p, iid, type) { \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync /* The IID _must_ be the IID of the interface we are wrapping! */ \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync } \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync}; \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// End of PyXPCOM_ATTR_INTERFACE_DECLARE macro
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#define PyXPCOM_INTERFACE_DEFINE(ClassName, InterfaceName, Methods ) \
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_TypeObject *ClassName::type = NULL;
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// And the classes
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync// deprecated, but retained for backward compatibility:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync#endif // __PYXPCOM_H__