#ifndef _GLIBMM_WRAP_H
#define _GLIBMM_WRAP_H
/* Copyright (C) 1998-2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#include
#include
#include
namespace Glib
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
class GLIBMM_API ObjectBase;
class GLIBMM_API Object;
// Type of the per-class wrap_new() functions.
using WrapNewFunction = Glib::ObjectBase*(*)(GObject*);
// Setup and free the structures used by wrap_register().
// Both functions might be called more than once.
GLIBMM_API
void wrap_register_init();
GLIBMM_API
void wrap_register_cleanup();
// Register a new type for auto allocation.
GLIBMM_API
void wrap_register(GType type, WrapNewFunction func);
// Return the current C++ wrapper instance of the GObject,
// or automatically generate a new wrapper if there's none.
GLIBMM_API
Glib::ObjectBase* wrap_auto(GObject* object, bool take_copy = false);
/** Create a C++ instance of a known C++ type that is mostly closely associated with the GType of
* the C object.
* @param object The C object which should be placed in a new C++ instance.
* @param interface_gtype The returned instance will implement this interface. Otherwise it will be
* NULL.
*/
GLIBMM_API
Glib::ObjectBase* wrap_create_new_wrapper_for_interface(GObject* object, GType interface_gtype);
// Return the current C++ wrapper instance of the GObject,
// or automatically generate a new wrapper if there's none.
template
TInterface*
wrap_auto_interface(GObject* object, bool take_copy = false)
{
if (!object)
return nullptr;
// Look up current C++ wrapper instance:
ObjectBase* pCppObject = ObjectBase::_get_current_wrapper(object);
if (!pCppObject)
{
// There's not already a wrapper: generate a new C++ instance.
// We use exact_type_only=true avoid creating Glib::Object for interfaces of unknown
// implementation,
// because we do not want a C++ object that does not dynamic_cast to the expected interface
// type.
pCppObject = wrap_create_new_wrapper_for_interface(object, TInterface::get_base_type());
}
// If no exact wrapper was created,
// create an instance of the interface,
// so we at least get the expected type:
TInterface* result = nullptr;
if (pCppObject)
{
result = dynamic_cast(pCppObject);
if (!result)
{
g_warning("Glib::wrap_auto_interface(): The C++ instance (%s) does not dynamic_cast to the "
"interface.\n",
typeid(*pCppObject).name());
}
}
else
result = new TInterface((typename TInterface::BaseObjectType*)object);
// take_copy=true is used where the GTK+ function doesn't do
// an extra ref for us, and always for plain struct members.
if (take_copy && result)
result->reference();
return result;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
// Get a C++ instance that wraps the C instance.
// This always returns the same C++ instance for the same C instance.
// Each wrapper has it's own override of Glib::wrap().
// use take_copy = true when wrapping a struct member.
// TODO: move to object.h ?
/** @relates Glib::Object */
GLIBMM_API
Glib::RefPtr wrap(GObject* object, bool take_copy = false);
/** Get the underlying C instance from the C++ instance. This is just
* like calling gobj(), but it does its own check for a NULL pointer.
*/
template
inline typename T::BaseObjectType*
unwrap(T* ptr)
{
return (ptr) ? ptr->gobj() : nullptr;
}
/** Get the underlying C instance from the C++ instance. This is just
* like calling gobj(), but it does its own check for a NULL pointer.
*/
template
inline const typename T::BaseObjectType*
unwrap(const T* ptr)
{
return (ptr) ? ptr->gobj() : nullptr;
}
/** Get the underlying C instance from the C++ instance. This is just
* like calling gobj(), but it does its own check for a NULL pointer.
*/
template
inline typename T::BaseObjectType*
unwrap(const Glib::RefPtr& ptr)
{
return (ptr) ? ptr->gobj() : nullptr;
}
/** Get the underlying C instance from the C++ instance. This is just
* like calling gobj(), but it does its own check for a NULL pointer.
*/
template
inline const typename T::BaseObjectType*
unwrap(const Glib::RefPtr& ptr)
{
return (ptr) ? ptr->gobj() : nullptr;
}
// This unwrap_copy() overload is intended primarily for classes wrapped as
// _CLASS_BOXEDTYPE, _CLASS_OPAQUE_COPYABLE or _CLASS_OPAQUE_REFCOUNTED,
// where the C++ objects are not stored in Glib::RefPtr<>s. They have a const
// gobj_copy() member that returns a non-const pointer to the underlying C instance.
/** Get the underlying C instance from the C++ instance and acquire a
* reference or copy. This is just like calling gobj_copy(), but it does its own
* check for a NULL pointer to the underlying C instance.
*/
template
inline typename T::BaseObjectType*
unwrap_copy(const T& obj)
{
return obj.gobj() ? obj.gobj_copy() : nullptr;
}
/** Get the underlying C instance from the C++ instance and acquire a
* reference. This is just like calling gobj_copy(), but it does its own
* check for a NULL pointer.
*/
template
inline typename T::BaseObjectType*
unwrap_copy(const Glib::RefPtr& ptr)
{
return (ptr) ? ptr->gobj_copy() : nullptr;
}
/** Get the underlying C instance from the C++ instance and acquire a
* reference. This is just like calling gobj_copy(), but it does its own
* check for a NULL pointer.
*/
template
inline const typename T::BaseObjectType*
unwrap_copy(const Glib::RefPtr& ptr)
{
return (ptr) ? ptr->gobj_copy() : nullptr;
}
} // namespace Glib
#endif /* _GLIBMM_WRAP_H */