Imported Upstream version 2.64.0 upstream/2.64.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:23:33 +0000 (00:23 -0700)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:23:33 +0000 (00:23 -0700)
448 files changed:
.gitignore
MSVC_NMake/Makefile.vc
MSVC_NMake/build-rules-msvc.mak
MSVC_NMake/config-msvc.mak
MSVC_NMake/create-lists-msvc.mak
MSVC_NMake/detectenv-msvc.mak
MSVC_NMake/filelist.am
MSVC_NMake/gendef/gendef.cc [deleted file]
MSVC_NMake/generate-msvc.mak
MSVC_NMake/giomm/meson.build [new file with mode: 0644]
MSVC_NMake/glibmm/meson.build [new file with mode: 0644]
MSVC_NMake/info-msvc.mak
MSVC_NMake/install.mak
Makefile.am
NEWS
README
README.win32
build/c_std.m4 [new file with mode: 0644]
build/cxx.m4
build/cxx_std.m4
build/sun.m4 [new file with mode: 0644]
configure.ac
docs/Makefile_web.am_fragment
docs/reference/Doxyfile.in
docs/reference/meson.build [new file with mode: 0644]
examples/Makefile.am
examples/child_watch/main.cc
examples/dbus/client_bus_listnames.cc
examples/dbus/server_without_bus.cc
examples/dbus/session_bus_service.cc
examples/iochannel_stream/main.cc
examples/keyfile/main.cc
examples/meson.build [new file with mode: 0644]
examples/network/resolver.cc
examples/network/socket-client.cc
examples/network/socket-server.cc
examples/options/main.cc
examples/regex/main.cc
examples/thread/dispatcher.cc
examples/thread/thread.cc [new file with mode: 0644]
examples/thread/threadpool.cc [new file with mode: 0644]
gio/giomm.h
gio/giomm/Makefile.am
gio/giomm/contenttype.cc
gio/giomm/contenttype.h
gio/giomm/filelist.am
gio/giomm/filelist.gmake.am
gio/giomm/init.h
gio/giomm/meson.build [new file with mode: 0644]
gio/giomm/slot_async.cc
gio/giomm/slot_async.h
gio/giomm/socketsource.cc
gio/giomm/socketsource.h
gio/giomm/wrap_init.h
gio/giommconfig.h.in
gio/giommconfig.h.meson [new file with mode: 0644]
gio/meson.build [new file with mode: 0644]
gio/src/action.hg
gio/src/actiongroup.hg
gio/src/actionmap.ccg
gio/src/actionmap.hg
gio/src/appinfo.ccg
gio/src/appinfo.hg
gio/src/applaunchcontext.hg
gio/src/application.ccg
gio/src/application.hg
gio/src/applicationcommandline.hg
gio/src/asyncinitable.hg
gio/src/asyncresult.ccg
gio/src/asyncresult.hg
gio/src/bufferedinputstream.ccg
gio/src/bufferedinputstream.hg
gio/src/bufferedoutputstream.ccg
gio/src/bufferedoutputstream.hg
gio/src/cancellable.hg
gio/src/charsetconverter.ccg
gio/src/charsetconverter.hg
gio/src/converter.ccg
gio/src/converter.hg
gio/src/converterinputstream.hg
gio/src/converteroutputstream.hg
gio/src/credentials.hg
gio/src/datainputstream.ccg
gio/src/datainputstream.hg
gio/src/dataoutputstream.hg
gio/src/dbusactiongroup.hg
gio/src/dbusaddress.hg
gio/src/dbusauthobserver.hg
gio/src/dbusconnection.ccg
gio/src/dbusconnection.hg
gio/src/dbuserror.hg
gio/src/dbuserrorutils.hg
gio/src/dbusinterface.hg
gio/src/dbusinterfaceskeleton.ccg
gio/src/dbusinterfaceskeleton.hg
gio/src/dbusinterfacevtable.hg
gio/src/dbusintrospection.hg
gio/src/dbusmenumodel.hg
gio/src/dbusmessage.hg
gio/src/dbusmethodinvocation.hg
gio/src/dbusobject.hg
gio/src/dbusobjectmanager.hg
gio/src/dbusobjectmanagerclient.ccg
gio/src/dbusobjectmanagerclient.hg
gio/src/dbusobjectmanagerserver.hg
gio/src/dbusobjectproxy.hg
gio/src/dbusobjectskeleton.hg
gio/src/dbusownname.hg
gio/src/dbusproxy.ccg
gio/src/dbusproxy.hg
gio/src/dbusserver.ccg
gio/src/dbusserver.hg
gio/src/dbussubtreevtable.hg
gio/src/dbusutils.hg
gio/src/dbuswatchname.hg
gio/src/desktopappinfo.hg
gio/src/drive.ccg
gio/src/drive.hg
gio/src/emblem.ccg
gio/src/emblem.hg
gio/src/emblemedicon.hg
gio/src/enums.hg
gio/src/error.hg
gio/src/file.ccg
gio/src/file.hg
gio/src/fileattributeinfo.ccg
gio/src/fileattributeinfo.hg
gio/src/fileattributeinfolist.hg
gio/src/filedescriptorbased.hg [deleted file]
gio/src/fileenumerator.hg
gio/src/fileicon.hg
gio/src/fileinfo.ccg
gio/src/fileinfo.hg
gio/src/fileinputstream.hg
gio/src/fileiostream.hg
gio/src/filelist.am
gio/src/filelist.gmake.am
gio/src/filemonitor.ccg
gio/src/filemonitor.hg
gio/src/filenamecompleter.hg
gio/src/fileoutputstream.hg
gio/src/filterinputstream.hg
gio/src/filteroutputstream.hg
gio/src/gio_docs.xml
gio/src/gio_docs_override.xml
gio/src/gio_enums.defs
gio/src/gio_enums.defs.patch
gio/src/gio_methods.defs
gio/src/gio_signals.defs
gio/src/gio_signals.defs.patch
gio/src/gio_vfuncs.defs
gio/src/icon.hg
gio/src/inetaddress.hg
gio/src/inetsocketaddress.hg
gio/src/initable.hg
gio/src/inputstream.hg
gio/src/iostream.ccg
gio/src/iostream.hg
gio/src/listmodel.hg
gio/src/liststore.hg
gio/src/loadableicon.ccg
gio/src/loadableicon.hg
gio/src/memoryinputstream.ccg
gio/src/memoryinputstream.hg
gio/src/memoryoutputstream.hg
gio/src/menu.hg
gio/src/menuattributeiter.hg
gio/src/menuitem.ccg
gio/src/menuitem.hg
gio/src/menulinkiter.hg
gio/src/menumodel.hg
gio/src/mount.ccg
gio/src/mount.hg
gio/src/mountoperation.hg
gio/src/networkaddress.hg
gio/src/networkmonitor.hg
gio/src/networkservice.hg
gio/src/notification.hg
gio/src/outputstream.ccg
gio/src/outputstream.hg
gio/src/permission.hg
gio/src/pollableinputstream.hg
gio/src/pollableoutputstream.hg
gio/src/propertyaction.hg [deleted file]
gio/src/proxy.hg
gio/src/proxyaddress.hg
gio/src/proxyresolver.hg
gio/src/remoteactiongroup.hg
gio/src/resolver.ccg
gio/src/resolver.hg
gio/src/resource.ccg
gio/src/resource.hg
gio/src/seekable.hg
gio/src/settings.ccg
gio/src/settings.hg
gio/src/settingsschema.hg
gio/src/settingsschemakey.hg
gio/src/settingsschemasource.hg
gio/src/simpleaction.hg
gio/src/simpleactiongroup.hg
gio/src/simpleiostream.hg
gio/src/simplepermission.hg
gio/src/socket.ccg
gio/src/socket.hg
gio/src/socketaddress.hg
gio/src/socketaddressenumerator.hg
gio/src/socketclient.hg
gio/src/socketconnectable.hg
gio/src/socketconnection.hg
gio/src/socketcontrolmessage.hg
gio/src/socketlistener.ccg
gio/src/socketlistener.hg
gio/src/socketservice.hg
gio/src/srvtarget.hg
gio/src/tcpconnection.hg
gio/src/tcpwrapperconnection.hg
gio/src/themedicon.ccg
gio/src/themedicon.hg
gio/src/threadedsocketservice.hg
gio/src/tlscertificate.ccg
gio/src/tlscertificate.hg
gio/src/tlsclientconnection.hg
gio/src/tlsconnection.hg
gio/src/tlsdatabase.ccg
gio/src/tlsdatabase.hg
gio/src/tlsfiledatabase.hg
gio/src/tlsinteraction.hg
gio/src/tlspassword.ccg
gio/src/tlspassword.hg
gio/src/tlsserverconnection.hg
gio/src/unixconnection.hg
gio/src/unixcredentialsmessage.hg
gio/src/unixfdlist.ccg
gio/src/unixfdlist.hg
gio/src/unixfdmessage.ccg
gio/src/unixfdmessage.hg
gio/src/unixinputstream.hg
gio/src/unixmount.hg
gio/src/unixoutputstream.hg
gio/src/unixsocketaddress.ccg
gio/src/unixsocketaddress.hg
gio/src/volume.ccg
gio/src/volume.hg
gio/src/volumemonitor.hg
gio/src/zlibcompressor.hg
gio/src/zlibdecompressor.hg
glib/glibmm.h
glib/glibmm.pc.in
glib/glibmm/arrayhandle.cc [new file with mode: 0644]
glib/glibmm/arrayhandle.h [new file with mode: 0644]
glib/glibmm/base64.h
glib/glibmm/class.cc
glib/glibmm/class.h
glib/glibmm/containerhandle_shared.h
glib/glibmm/containers.cc [new file with mode: 0644]
glib/glibmm/containers.h [new file with mode: 0644]
glib/glibmm/dispatcher.cc
glib/glibmm/dispatcher.h
glib/glibmm/error.h
glib/glibmm/exception.h
glib/glibmm/exceptionhandler.cc
glib/glibmm/exceptionhandler.h
glib/glibmm/extraclassinit.h
glib/glibmm/filelist.am
glib/glibmm/filelist.gmake.am
glib/glibmm/helperlist.h [new file with mode: 0644]
glib/glibmm/init.cc
glib/glibmm/init.h
glib/glibmm/interface.cc
glib/glibmm/interface.h
glib/glibmm/listhandle.h [new file with mode: 0644]
glib/glibmm/main.cc
glib/glibmm/main.h
glib/glibmm/meson.build [new file with mode: 0644]
glib/glibmm/object.cc
glib/glibmm/object.h
glib/glibmm/objectbase.cc
glib/glibmm/objectbase.h
glib/glibmm/pattern.h
glib/glibmm/property.cc
glib/glibmm/property.h
glib/glibmm/propertyproxy_base.cc
glib/glibmm/propertyproxy_base.h
glib/glibmm/quark.h
glib/glibmm/random.h
glib/glibmm/refptr.h
glib/glibmm/sarray.cc [moved from gio/src/filedescriptorbased.ccg with 76% similarity]
glib/glibmm/sarray.h [moved from gio/src/propertyaction.ccg with 54% similarity]
glib/glibmm/signalproxy.cc
glib/glibmm/signalproxy.h
glib/glibmm/signalproxy_connectionnode.cc
glib/glibmm/signalproxy_connectionnode.h
glib/glibmm/slisthandle.h [new file with mode: 0644]
glib/glibmm/streamiochannel.cc [new file with mode: 0644]
glib/glibmm/streamiochannel.h [new file with mode: 0644]
glib/glibmm/stringutils.h
glib/glibmm/threadpool.cc [new file with mode: 0644]
glib/glibmm/threadpool.h [new file with mode: 0644]
glib/glibmm/timer.h
glib/glibmm/timeval.cc [new file with mode: 0644]
glib/glibmm/timeval.h [new file with mode: 0644]
glib/glibmm/ustring.cc
glib/glibmm/ustring.h
glib/glibmm/utility.h
glib/glibmm/value.cc
glib/glibmm/value.h
glib/glibmm/value_custom.h
glib/glibmm/variantdbusstring.h
glib/glibmm/vectorutils.h
glib/glibmm/weakref.h [new file with mode: 0644]
glib/glibmm/wrap.cc
glib/glibmm/wrap.h
glib/glibmm/wrap_init.h
glib/glibmmconfig.h.in
glib/glibmmconfig.h.meson [new file with mode: 0644]
glib/meson.build [new file with mode: 0644]
glib/src/balancedtree.hg
glib/src/binding.ccg
glib/src/binding.hg
glib/src/bytearray.ccg
glib/src/bytearray.hg
glib/src/bytes.hg
glib/src/checksum.ccg
glib/src/checksum.hg
glib/src/convert.hg
glib/src/date.ccg
glib/src/date.hg
glib/src/datetime.ccg
glib/src/datetime.hg
glib/src/filelist.am
glib/src/fileutils.hg
glib/src/glib_docs.xml
glib/src/glib_docs_override.xml
glib/src/glib_enums.defs
glib/src/glib_extra_objects.defs
glib/src/glib_functions.defs
glib/src/gobject_functions.defs
glib/src/iochannel.ccg
glib/src/iochannel.hg
glib/src/keyfile.ccg
glib/src/keyfile.hg
glib/src/markup.hg
glib/src/miscutils.ccg
glib/src/miscutils.hg
glib/src/module.ccg
glib/src/module.hg
glib/src/nodetree.hg
glib/src/optioncontext.ccg
glib/src/optioncontext.hg
glib/src/optionentry.ccg
glib/src/optionentry.hg
glib/src/optiongroup.ccg
glib/src/optiongroup.hg
glib/src/regex.ccg
glib/src/regex.hg
glib/src/shell.ccg
glib/src/shell.hg
glib/src/spawn.ccg
glib/src/spawn.hg
glib/src/thread.ccg [new file with mode: 0644]
glib/src/thread.hg [new file with mode: 0644]
glib/src/threads.ccg [new file with mode: 0644]
glib/src/threads.hg [new file with mode: 0644]
glib/src/timezone.ccg
glib/src/timezone.hg
glib/src/uriutils.hg
glib/src/value_basictypes.cc.m4
glib/src/value_basictypes.h.m4
glib/src/valuearray.ccg [new file with mode: 0644]
glib/src/valuearray.hg [new file with mode: 0644]
glib/src/variant.ccg
glib/src/variant.hg
glib/src/variant_basictypes.h.m4
glib/src/variantdict.hg
glib/src/variantiter.ccg
glib/src/variantiter.hg
glib/src/varianttype.hg
meson.build [new file with mode: 0644]
meson_options.txt [new file with mode: 0644]
tests/Makefile.am
tests/giomm_listmodel/main.cc
tests/giomm_memoryinputstream/main.cc
tests/giomm_stream_vfuncs/main.cc [deleted file]
tests/giomm_tls_client/main.cc
tests/glibmm_binding/main.cc [new file with mode: 0644]
tests/glibmm_bool_arrayhandle/main.cc [new file with mode: 0644]
tests/glibmm_date/main.cc
tests/glibmm_interface_move/main.cc
tests/glibmm_nodetree/main.cc
tests/glibmm_null_containerhandle/main.cc [new file with mode: 0644]
tests/glibmm_object/main.cc [deleted file]
tests/glibmm_object/test_derived_object.h [deleted file]
tests/glibmm_object_move/main.cc
tests/glibmm_objectbase/main.cc [deleted file]
tests/glibmm_objectbase/test_derived_objectbase.h [deleted file]
tests/glibmm_objectbase_move/main.cc
tests/glibmm_refptr/main.cc
tests/glibmm_ustring_format/main.cc
tests/glibmm_ustring_sprintf/main.cc
tests/glibmm_value/glibmm_value.cc [new file with mode: 0644]
tests/glibmm_value/main.cc
tests/glibmm_valuearray/main.cc [new file with mode: 0644]
tests/glibmm_variant/main.cc
tests/glibmm_weakref/main.cc [new file with mode: 0644]
tests/meson.build [new file with mode: 0644]
tools/Makefile.am
tools/build_scripts/compile-schemas.py [new file with mode: 0755]
tools/build_scripts/dummy-header.py [new file with mode: 0755]
tools/build_scripts/handle-built-files.py [new file with mode: 0755]
tools/conf_tests/allows_static_inline_npos.cc [new file with mode: 0644]
tools/conf_tests/can_assign_non_extern_c_functions_to_extern_c_cb.cc [new file with mode: 0644]
tools/conf_tests/can_use_dynamic_cast_in_unused_template_wo_def.cc [new file with mode: 0644]
tools/conf_tests/can_use_namespaces_inside_externc.cc [new file with mode: 0644]
tools/conf_tests/can_use_thread_local.cc [new file with mode: 0644]
tools/conf_tests/have_disambiguous_const_template_specializations.cc [new file with mode: 0644]
tools/conf_tests/have_std_iterator_traits.cc [new file with mode: 0644]
tools/conf_tests/have_sun_reverse_iterator.cc [new file with mode: 0644]
tools/conf_tests/have_template_sequence_ctors.cc [new file with mode: 0644]
tools/conf_tests/have_wide_stream.cc [new file with mode: 0644]
tools/conf_tests/member_functions_member_templates.cc [new file with mode: 0644]
tools/conf_tests/std_time_t_is_not_int32.cc [new file with mode: 0644]
tools/extra_defs_gen/generate_extra_defs.h
tools/extra_defs_gen/meson.build [new file with mode: 0644]
tools/gen_scripts/init_generate.sh
tools/generate_wrap_init.pl.in
tools/gmmproc.in
tools/m4/class_boxedtype.m4
tools/m4/class_boxedtype_static.m4
tools/m4/class_gobject.m4
tools/m4/class_interface.m4
tools/m4/class_opaque_copyable.m4
tools/m4/class_opaque_refcounted.m4
tools/m4/convert_base.m4
tools/m4/convert_gio.m4
tools/m4/convert_glib.m4
tools/m4/enum.m4
tools/m4/gerror.m4
tools/m4/method.m4
tools/m4/property.m4
tools/m4/signal.m4
tools/meson.build [new file with mode: 0644]
tools/pm/DocsParser.pm
tools/pm/Enum.pm
tools/pm/Function.pm
tools/pm/Output.pm
tools/pm/WrapParser.pm
tools/test_scripts/testheaders.sh
untracked/README [new file with mode: 0644]

index 83fe09c..bfdb5dd 100644 (file)
@@ -52,8 +52,8 @@ giommconfig.h
 /docs/reference/Doxyfile
 /docs/reference/doxygen.log
 /docs/reference/doxygen*.db
-/docs/reference/glibmm-*.devhelp2
-/docs/reference/glibmm-*.tag
+/docs/reference/glibmm-2.4.devhelp2
+/docs/reference/glibmm-2.4.tag
 /docs/reference/html/
 
 # examples/
@@ -75,6 +75,8 @@ giommconfig.h
 /examples/settings/gschemas.compiled
 /examples/thread/dispatcher
 /examples/thread/dispatcher2
+/examples/thread/thread
+/examples/thread/threadpool
 
 # gio/
 /gio/giomm-*.pc
@@ -137,6 +139,10 @@ giommconfig.h
 /glib/glibmm/shell.h
 /glib/glibmm/spawn.cc
 /glib/glibmm/spawn.h
+/glib/glibmm/thread.cc
+/glib/glibmm/thread.h
+/glib/glibmm/threads.cc
+/glib/glibmm/threads.h
 /glib/glibmm/timezone.cc
 /glib/glibmm/timezone.h
 /glib/glibmm/unicode.cc
@@ -145,6 +151,8 @@ giommconfig.h
 /glib/glibmm/uriutils.h
 /glib/glibmm/value_basictypes.cc
 /glib/glibmm/value_basictypes.h
+/glib/glibmm/valuearray.cc
+/glib/glibmm/valuearray.h
 /glib/glibmm/variant.cc
 /glib/glibmm/variant.h
 /glib/glibmm/variant_basictypes.cc
@@ -171,3 +179,9 @@ giommconfig.h
 /tools/extra_defs_gen/generate_defs_glib
 /tools/generate_wrap_init.pl
 /tools/gmmproc
+
+# untracked/
+untracked/build_scripts/
+untracked/docs/
+untracked/gio/
+untracked/glib/
index adcbd3b..7eeba8f 100644 (file)
 
 !if "$(VALID_CFGSET)" == "TRUE"
 
-# We need Visual Studio 2017 or later
-!if $(VSVER) < 15
+# We need Visual Studio 2015 or later
+!if $(VSVER) < 14
 VALID_MSC = FALSE
 !else
 VALID_MSC = TRUE
 !endif
 
-!if $(VCVERSION) < 1915
-!message Some tests may fail to build for Visual Studio 2017 15.7 or earlier!
-!endif
-
 !if "$(VALID_MSC)" == "TRUE"
 
 # Include the Makefile portion to convert the source and header lists
 # into the lists we need for compilation and introspection
 !include create-lists-msvc.mak
 
-all: $(GIOMM_LIB) $(glibmm_ex) $(giomm_ex) all-build-info
+!ifdef GENERATE_VERSIONED_FILES
+!include pkg-ver.mak
+!endif
+
+all: $(GIOMM_LIB) $(GLIBMM_EXTRA_DEFS_GEN_LIB) $(glibmm_ex) $(giomm_ex) all-build-info
 
 tests: $(glibmm_tests) $(giomm_tests) all-build-info
 
@@ -49,7 +49,7 @@ tests: $(glibmm_tests) $(giomm_tests) all-build-info
 
 !else # "$(VALID_MSC)" == "TRUE"
 all:
-       @echo You need Visual Studio 2017 or later.
+       @echo You need Visual Studio 2015 or later.
 
 !endif # "$(VALID_MSC)" == "TRUE"
 
index 765e150..f3f5cf0 100644 (file)
 #      $(CC)|$(CXX) $(cflags) /Fo$(destdir) /c @<<
 # $<
 # <<
-{..\glib\glibmm\}.cc{$(CFG)\$(PLAT)\glibmm\}.obj::
-       $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(CFG)\$(PLAT)\glibmm\ /c @<<
+{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.obj::
+       $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\ /Fdvs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\ /c @<<
 $<
 <<
 
-{..\gio\giomm\}.cc{$(CFG)\$(PLAT)\giomm\}.obj::
-       $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(CFG)\$(PLAT)\giomm\ /c @<<
+{..\untracked\glib\glibmm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.obj::
+       $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\glibmm\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\glibmm\ /c @<<
 $<
 <<
 
-{.\glibmm\}.rc{$(CFG)\$(PLAT)\glibmm\}.res:
+{..\glib\glibmm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.obj::
+       $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\ /Fdvs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\ /c @<<
+$<
+<<
+
+{..\glib\src\}.cc.m4{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.obj:
+       @if not exist $(@D)\ $(MAKE) /f Makefile.vc CFG=$(CFG) $(@D)
+       @for %%s in ($(<D)\*.cc.m4 $(<D)\*.h.m4) do @if not exist ..\glib\glibmm\%%~ns if not exist ..\untracked\glib\glibmm\%%~ns if not exist $(@D)\%%~ns $(M4) -I$(<D:\=/) %%s $(<D:\=/)/template.macros.m4 > $(@D)\%%~ns
+       @if exist $(@D)\$(<B) $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c $(@D)\$(<B)
+       @if exist ..\glib\glibmm\$(<B) $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c ..\glib\glibmm\$(<B)
+       @if exist ..\untracked\glib\glibmm\$(<B) $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c ..\untracked\glib\glibmm\$(<B)
+
+{..\glib\src\}.ccg{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.obj:
+       @if not exist $(@D)\private\ $(MAKE) /f Makefile.vc CFG=$(CFG) $(@D)\private
+       @for %%s in ($(<D)\*.ccg) do @if not exist ..\glib\glibmm\%%~ns.cc if not exist $(@D)\%%~ns.cc $(PERL) -I ../tools/pm -- ../tools/gmmproc -I ../tools/m4 --defs $(<D:\=/) %%~ns $(<D:\=/) $(@D)
+       @if exist $(@D)\$(<B).cc $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c $(@D)\$(<B).cc
+       @if exist ..\glib\glibmm\$(<B).cc $(CXX) $(LIBGLIBMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c ..\glib\glibmm\$(<B).cc
+
+{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.obj::
+       $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(PDBVER)\$(CFG)\$(PLAT)\giomm\ /Fdvs$(PDBVER)\$(CFG)\$(PLAT)\giomm\ /c @<<
+$<
+<<
+
+{..\untracked\gio\giomm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.obj::
+       $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\giomm\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\giomm\ /c @<<
+$<
+<<
+
+{..\gio\giomm\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.obj::
+       $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fovs$(PDBVER)\$(CFG)\$(PLAT)\giomm\ /Fdvs$(PDBVER)\$(CFG)\$(PLAT)\giomm\ /c @<<
+$<
+<<
+
+{..\gio\src\}.ccg{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.obj:
+       @if not exist $(@D)\private\ $(MAKE) /f Makefile.vc CFG=$(CFG) $(@D)\private
+       @for %%s in ($(<D)\*.ccg) do @if not exist ..\gio\giomm\%%~ns.cc if not exist $(@D)\%%~ns.cc $(PERL) -I ../tools/pm -- ../tools/gmmproc -I ../tools/m4 --defs $(<D:\=/) %%~ns $(<D:\=/) $(@D)
+       @if exist $(@D)\$(<B).cc $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c $(@D)\$(<B).cc
+       @if exist ..\gio\giomm\$(<B).cc $(CXX) $(LIBGIOMM_CFLAGS) $(CFLAGS_NOGL) /Fo$(@D)\ /Fd$(@D)\ /c $(@D)\$(<B).cc
+
+{..\tools\extra_defs_gen\}.cc{vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\}.obj::
+       @if not exist vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\ $(MAKE) /f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen
+       $(CXX) $(GLIBMM_BASE_CFLAGS) /DGLIBMM_GEN_EXTRA_DEFS_BUILD $(GLIBMM_EXTRA_INCLUDES) $(CFLAGS_NOGL) /Fovs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\ /Fdvs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\ /c @<<
+$<
+<<
+
+{.\glibmm\}.rc{vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\}.res:
        rc /fo$@ $<
 
-{.\giomm\}.rc{$(CFG)\$(PLAT)\giomm\}.res:
+{.\giomm\}.rc{vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\}.res:
        rc /fo$@ $<
 
+vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\generate_extra_defs.obj:  ..\tools\extra_defs_gen\generate_extra_defs.cc  ..\tools\extra_defs_gen\generate_extra_defs.h
 # Rules for building .lib files
 $(GLIBMM_LIB): $(GLIBMM_DLL)
 $(GIOMM_LIB): $(GIOMM_DLL)
 
+$(GLIBMM_EXTRA_DEFS_GEN_LIB): $(GLIBMM_EXTRA_DEFS_GEN_DLL)
+$(GLIBMM_EXTRA_DEFS_GEN_DLL): vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\generate_extra_defs.obj
+       link /DLL $(LDFLAGS_NOLTCG) $(GOBJECT_LIBS) /implib:$(GLIBMM_EXTRA_DEFS_GEN_LIB) -out:$@ @<<
+$**
+<<
+       @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2
+
 # Rules for linking DLLs
 # Format is as follows (the mt command is needed for MSVC 2005/2008 builds):
 # $(dll_name_with_path): $(dependent_libs_files_objects_and_items)
@@ -40,14 +93,14 @@ $(GIOMM_LIB): $(GIOMM_DLL)
 # $(dependent_objects)
 # <<
 #      @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2
-$(GLIBMM_DLL): $(CFG)\$(PLAT)\glibmm\glibmm.def $(glibmm_OBJS)
-       link /DLL $(LDFLAGS_NOLTCG) $(GOBJECT_LIBS) $(LIBSIGC_LIB) /implib:$(GLIBMM_LIB) /def:$(CFG)\$(PLAT)\glibmm\glibmm.def -out:$@ @<<
+$(GLIBMM_DLL): vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm $(glibmm_OBJS)
+       link /DLL $(LDFLAGS_NOLTCG) $(GOBJECT_LIBS) $(LIBSIGC_LIB) /implib:$(GLIBMM_LIB) -out:$@ @<<
 $(glibmm_OBJS)
 <<
-
        @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2
-$(GIOMM_DLL): $(GLIBMM_LIB) $(CFG)\$(PLAT)\giomm\giomm.def $(giomm_OBJS)
-       link /DLL $(LDFLAGS_NOLTCG) $(GLIBMM_LIB) $(GIO_LIBS) $(LIBSIGC_LIB) /implib:$(GIOMM_LIB) /def:$(CFG)\$(PLAT)\giomm\giomm.def -out:$@ @<<
+
+$(GIOMM_DLL): vs$(PDBVER)\$(CFG)\$(PLAT)\giomm $(GLIBMM_LIB) $(giomm_OBJS)
+       link /DLL $(LDFLAGS_NOLTCG) $(GLIBMM_LIB) $(GIO_LIBS) $(LIBSIGC_LIB) /implib:$(GIOMM_LIB) -out:$@ @<<
 $(giomm_OBJS)
 <<
        @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2
@@ -60,146 +113,177 @@ $(giomm_OBJS)
 # <<
 #      @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;1
 
-# For the gendef tool
-{.\gendef\}.cc{$(CFG)\$(PLAT)\}.exe:
-       @if not exist $(CFG)\$(PLAT)\gendef\ $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\gendef
-       $(CXX) $(GLIBMM_BASE_CFLAGS) $(CFLAGS) /Fo$(CFG)\$(PLAT)\gendef\ $< /link $(LDFLAGS) /out:$@
-
 # For the buildable glibmm examples
-$(CFG)\$(PLAT)\glibmm-ex-compose.exe: ..\examples\compose\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-dispatcher2.exe: ..\examples\thread\dispatcher2.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-keyfile.exe: ..\examples\keyfile\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-markup.exe: ..\examples\markup\parser.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-options.exe: ..\examples\options\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-properties.exe: ..\examples\properties\properties_example.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\glibmm-ex-regex.exe: ..\examples\regex\main.cc $(GLIBMM_LIB)
-
-$(CFG)\$(PLAT)\glibmm-ex-compose.exe   \
-$(CFG)\$(PLAT)\glibmm-ex-dispatcher2.exe       \
-$(CFG)\$(PLAT)\glibmm-ex-keyfile.exe   \
-$(CFG)\$(PLAT)\glibmm-ex-markup.exe    \
-$(CFG)\$(PLAT)\glibmm-ex-options.exe   \
-$(CFG)\$(PLAT)\glibmm-ex-properties.exe        \
-$(CFG)\$(PLAT)\glibmm-ex-regex.exe:
-       @if not exist $(CFG)\$(PLAT)\glibmm-ex $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\glibmm-ex
-       $(CXX) $(GLIBMM_EX_CFLAGS) $(CFLAGS) /Fo$(CFG)\$(PLAT)\glibmm-ex\ $** /link $(LDFLAGS) $(GLIBMM_EX_LIBS) /out:$@
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-compose.exe: ..\examples\compose\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-dispatcher2.exe: ..\examples\thread\dispatcher2.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-keyfile.exe: ..\examples\keyfile\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-markup.exe: ..\examples\markup\parser.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-options.exe: ..\examples\options\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-properties.exe: ..\examples\properties\properties_example.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-regex.exe: ..\examples\regex\main.cc $(GLIBMM_LIB)
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-compose.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-dispatcher2.exe   \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-keyfile.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-markup.exe        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-options.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-properties.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex-regex.exe:
+       @if not exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex $(MAKE) -f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex
+       $(CXX) $(GLIBMM_EX_CFLAGS) $(CFLAGS) /Fo$(@D)\glibmm-ex\ /Fd$(@D)\glibmm-ex\ $** /link $(LDFLAGS) $(GLIBMM_EX_LIBS) /out:$@
 
 # For the buildable giomm examples
 
-$(CFG)\$(PLAT)\giomm-ex-dbus-client_bus_listnames.exe: ..\examples\dbus\client_bus_listnames.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-dbus-session_bus_service.exe: ..\examples\dbus\session_bus_service.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-dbus-server_without_bus.exe: ..\examples\dbus\server_without_bus.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-network-resolver.exe: ..\examples\network\resolver.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-network-socket-client.exe: ..\examples\network\socket-client.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-network-socket-server.exe: ..\examples\network\socket-server.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\giomm-ex-settings.exe: ..\examples\settings\settings.cc $(GIOMM_LIB)
-
-$(CFG)\$(PLAT)\giomm-ex-dbus-client_bus_listnames.exe  \
-$(CFG)\$(PLAT)\giomm-ex-dbus-session_bus_service.exe   \
-$(CFG)\$(PLAT)\giomm-ex-dbus-server_without_bus.exe    \
-$(CFG)\$(PLAT)\giomm-ex-network-resolver.exe   \
-$(CFG)\$(PLAT)\giomm-ex-network-socket-client.exe      \
-$(CFG)\$(PLAT)\giomm-ex-network-socket-server.exe      \
-$(CFG)\$(PLAT)\giomm-ex-settings.exe:
-       @if not exist $(CFG)\$(PLAT)\giomm-ex $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\giomm-ex
-       @if "$@" == "$(CFG)\$(PLAT)\giomm-ex-settings.exe" $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\gschema.compiled
-       $(CXX) $(GIOMM_EX_CFLAGS) $(CFLAGS) /Fo$(CFG)\$(PLAT)\giomm-ex\ $** /link $(LDFLAGS) $(GIOMM_EX_LIBS) /out:$@
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-client_bus_listnames.exe: ..\examples\dbus\client_bus_listnames.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-session_bus_service.exe: ..\examples\dbus\session_bus_service.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-server_without_bus.exe: ..\examples\dbus\server_without_bus.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-resolver.exe: ..\examples\network\resolver.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-socket-client.exe: ..\examples\network\socket-client.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-socket-server.exe: ..\examples\network\socket-server.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-settings.exe: ..\examples\settings\settings.cc $(GIOMM_LIB)
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-client_bus_listnames.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-session_bus_service.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-dbus-server_without_bus.exe        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-resolver.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-socket-client.exe  \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-network-socket-server.exe  \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-settings.exe:
+       @if not exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex $(MAKE) -f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex
+       @if "$@" == "vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex-settings.exe" $(MAKE) -f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\gschema.compiled
+       $(CXX) $(GIOMM_EX_CFLAGS) $(CFLAGS) /Fo$(@D)\giomm-ex\ /Fd$(@D)\giomm-ex\ $** /link $(LDFLAGS) $(GIOMM_EX_LIBS) /out:$@
 
 # For building the glibmm tests
-$(CFG)\$(PLAT)\test-glibmm_base64.exe: ..\tests\glibmm_base64\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_bool_vector.exe: ..\tests\glibmm_bool_vector\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_btree.exe: ..\tests\glibmm_btree\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_buildfilename.exe: ..\tests\glibmm_buildfilename\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_bytearray.exe: ..\tests\glibmm_bytearray\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_date.exe: ..\tests\glibmm_date\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_mainloop.exe: ..\tests\glibmm_mainloop\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_nodetree.exe: ..\tests\glibmm_nodetree\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_object.exe: ..\tests\glibmm_object\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_objectbase.exe: ..\tests\glibmm_objectbase\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_objectbase_move.exe: ..\tests\glibmm_objectbase_move\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_object_move.exe: ..\tests\glibmm_object_move\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_refptr.exe: ..\tests\glibmm_refptr\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_refptr_sigc_bind.exe: ..\tests\glibmm_refptr_sigc_bind\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_ustring_compose.exe: ..\tests\glibmm_ustring_compose\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_ustring_format.exe: ..\tests\glibmm_ustring_format\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_ustring_make_valid.exe: ..\tests\glibmm_ustring_make_valid\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_value.exe: ..\tests\glibmm_value\main.cc $(GLIBMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_variant.exe: ..\tests\glibmm_variant\main.cc $(GLIBMM_LIB)
-
-$(CFG)\$(PLAT)\test-glibmm_base64.exe  \
-$(CFG)\$(PLAT)\test-glibmm_bool_vector.exe     \
-$(CFG)\$(PLAT)\test-glibmm_btree.exe   \
-$(CFG)\$(PLAT)\test-glibmm_buildfilename.exe   \
-$(CFG)\$(PLAT)\test-glibmm_bytearray.exe       \
-$(CFG)\$(PLAT)\test-glibmm_date.exe    \
-$(CFG)\$(PLAT)\test-glibmm_interface_move.exe  \
-$(CFG)\$(PLAT)\test-glibmm_mainloop.exe        \
-$(CFG)\$(PLAT)\test-glibmm_nodetree.exe        \
-$(CFG)\$(PLAT)\test-glibmm_object.exe  \
-$(CFG)\$(PLAT)\test-glibmm_objectbase.exe      \
-$(CFG)\$(PLAT)\test-glibmm_objectbase_move.exe \
-$(CFG)\$(PLAT)\test-glibmm_object_move.exe     \
-$(CFG)\$(PLAT)\test-glibmm_refptr.exe  \
-$(CFG)\$(PLAT)\test-glibmm_refptr_sigc_bind.exe        \
-$(CFG)\$(PLAT)\test-glibmm_ustring_compose.exe \
-$(CFG)\$(PLAT)\test-glibmm_ustring_format.exe  \
-$(CFG)\$(PLAT)\test-glibmm_ustring_make_valid.exe      \
-$(CFG)\$(PLAT)\test-glibmm_value.exe   \
-$(CFG)\$(PLAT)\test-glibmm_variant.exe:
-       @if not exist $(CFG)\$(PLAT)\glibmm-tests $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\glibmm-tests
-       $(CXX) $(GLIBMM_EX_CFLAGS) $(CFLAGS) /Fo$(CFG)\$(PLAT)\glibmm-tests\ $** /link $(LDFLAGS) $(GLIBMM_EX_LIBS) /out:$@
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_base64.exe: ..\tests\glibmm_base64\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_binding.exe: ..\tests\glibmm_binding\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bool_arrayhandle.exe: ..\tests\glibmm_bool_arrayhandle\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bool_vector.exe: ..\tests\glibmm_bool_vector\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_btree.exe: ..\tests\glibmm_btree\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_buildfilename.exe: ..\tests\glibmm_buildfilename\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bytearray.exe: ..\tests\glibmm_bytearray\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_date.exe: ..\tests\glibmm_date\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_mainloop.exe: ..\tests\glibmm_mainloop\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_nodetree.exe: ..\tests\glibmm_nodetree\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_object.exe: ..\tests\glibmm_object\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_objectbase.exe: ..\tests\glibmm_objectbase\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_objectbase_move.exe: ..\tests\glibmm_objectbase_move\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_object_move.exe: ..\tests\glibmm_object_move\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_refptr.exe: ..\tests\glibmm_refptr\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_refptr_sigc_bind.exe: ..\tests\glibmm_refptr_sigc_bind\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_compose.exe: ..\tests\glibmm_ustring_compose\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_format.exe: ..\tests\glibmm_ustring_format\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_make_valid.exe: ..\tests\glibmm_ustring_make_valid\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_sprintf.exe: ..\tests\glibmm_ustring_sprintf\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_value.exe: ..\tests\glibmm_value\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_valuearray.exe: ..\tests\glibmm_valuearray\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_variant.exe: ..\tests\glibmm_variant\main.cc $(GLIBMM_LIB)
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_base64.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_binding.exe     \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bool_arrayhandle.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bool_vector.exe \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_btree.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_buildfilename.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_bytearray.exe   \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_date.exe        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_interface_move.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_mainloop.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_nodetree.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_object.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_objectbase.exe  \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_objectbase_move.exe     \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_object_move.exe \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_refptr.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_refptr_sigc_bind.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_compose.exe     \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_format.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_make_valid.exe  \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_ustring_sprintf.exe     \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_value.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_valuearray.exe  \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_variant.exe:
+       @if not exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests $(MAKE) -f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests
+       $(CXX) $(GLIBMM_EX_CFLAGS) $(CFLAGS) /Fo$(@D)\glibmm-tests\ /Fd$(@D)\glibmm-tests\ $** /link $(LDFLAGS) $(GLIBMM_EX_LIBS) /out:$@
 
 # For giomm tests
-$(CFG)\$(PLAT)\test-giomm_asyncresult_sourceobject.exe: ..\tests\giomm_asyncresult_sourceobject\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_ioerror.exe: ..\tests\giomm_ioerror\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_ioerror_and_iodbuserror.exe: ..\tests\giomm_ioerror_and_iodbuserror\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_listmodel.exe: ..\tests\giomm_listmodel\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_memoryinputstream.exe: ..\tests\giomm_memoryinputstream\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_simple.exe: ..\tests\giomm_simple\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_stream_vfuncs.exe: ..\tests\giomm_stream_vfuncs\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-giomm_tls_client.exe: ..\tests\giomm_tls_client\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_interface_implementation.exe: ..\tests\glibmm_interface_implementation\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_null_vectorutils.exe: ..\tests\glibmm_null_vectorutils\main.cc $(GIOMM_LIB)
-$(CFG)\$(PLAT)\test-glibmm_vector.exe: ..\tests\glibmm_vector\main.cc $(GIOMM_LIB)
-
-$(CFG)\$(PLAT)\test-giomm_asyncresult_sourceobject.exe \
-$(CFG)\$(PLAT)\test-giomm_ioerror.exe  \
-$(CFG)\$(PLAT)\test-giomm_ioerror_and_iodbuserror.exe  \
-$(CFG)\$(PLAT)\test-giomm_listmodel.exe        \
-$(CFG)\$(PLAT)\test-giomm_memoryinputstream.exe        \
-$(CFG)\$(PLAT)\test-giomm_simple.exe   \
-$(CFG)\$(PLAT)\test-giomm_stream_vfuncs.exe    \
-$(CFG)\$(PLAT)\test-giomm_tls_client.exe       \
-$(CFG)\$(PLAT)\test-glibmm_interface_implementation.exe        \
-$(CFG)\$(PLAT)\test-glibmm_null_vectorutils.exe        \
-$(CFG)\$(PLAT)\test-glibmm_vector.exe:
-       @if not exist $(CFG)\$(PLAT)\giomm-tests $(MAKE) -f Makefile.vc CFG=$(CFG) $(CFG)\$(PLAT)\giomm-tests
-       $(CXX) $(GIOMM_EX_CFLAGS) $(CFLAGS) /Fo$(CFG)\$(PLAT)\giomm-tests\ $** /link $(LDFLAGS) $(GIOMM_EX_LIBS) /out:$@
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_asyncresult_sourceobject.exe: ..\tests\giomm_asyncresult_sourceobject\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_ioerror.exe: ..\tests\giomm_ioerror\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_ioerror_and_iodbuserror.exe: ..\tests\giomm_ioerror_and_iodbuserror\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_listmodel.exe: ..\tests\giomm_listmodel\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_memoryinputstream.exe: ..\tests\giomm_memoryinputstream\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_simple.exe: ..\tests\giomm_simple\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_stream_vfuncs.exe: ..\tests\giomm_stream_vfuncs\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_tls_client.exe: ..\tests\giomm_tls_client\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_interface_implementation.exe: ..\tests\glibmm_interface_implementation\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_null_containerhandle.exe: ..\tests\glibmm_null_containerhandle\main.cc $(GLIBMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_null_vectorutils.exe: ..\tests\glibmm_null_vectorutils\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_vector.exe: ..\tests\glibmm_vector\main.cc $(GIOMM_LIB)
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_weakref.exe: ..\tests\glibmm_weakref\main.cc $(GLIBMM_LIB)
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_asyncresult_sourceobject.exe     \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_ioerror.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_ioerror_and_iodbuserror.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_listmodel.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_memoryinputstream.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_simple.exe       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_stream_vfuncs.exe        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-giomm_tls_client.exe   \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_interface_implementation.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_null_containerhandle.exe        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_null_vectorutils.exe    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_vector.exe      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\test-glibmm_weakref.exe:
+       @if not exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests $(MAKE) -f Makefile.vc CFG=$(CFG) vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests
+       $(CXX) $(GIOMM_EX_CFLAGS) $(CFLAGS) /Fo$(@D)\giomm-tests\ /Fd$(@D)\giomm-tests\ $** /link $(LDFLAGS) $(GIOMM_EX_LIBS) /out:$@
 
 clean:
-       @-del /f /q $(CFG)\$(PLAT)\*.exe
-       @-del /f /q $(CFG)\$(PLAT)\*.dll
-       @-del /f /q $(CFG)\$(PLAT)\*.pdb
-       @-del /f /q $(CFG)\$(PLAT)\*.ilk
-       @-del /f /q $(CFG)\$(PLAT)\*.exp
-       @-del /f /q $(CFG)\$(PLAT)\*.lib
-       @-del /f /q $(CFG)\$(PLAT)\gschemas.compiled
-       @-if exist $(CFG)\$(PLAT)\giomm-tests del /f /q $(CFG)\$(PLAT)\giomm-tests\*.obj
-       @-del /f /q $(CFG)\$(PLAT)\giomm-ex\*.obj
-       @-del /f /q $(CFG)\$(PLAT)\giomm\*.def
-       @-del /f /q $(CFG)\$(PLAT)\giomm\*.res
-       @-del /f /q $(CFG)\$(PLAT)\giomm\*.obj
-       @-if exist $(CFG)\$(PLAT)\glibmm-tests del /f /q $(CFG)\$(PLAT)\glibmm-tests\*.obj
-       @-del /f /q $(CFG)\$(PLAT)\glibmm-ex\*.obj
-       @-del /f /q $(CFG)\$(PLAT)\glibmm\*.def
-       @-del /f /q $(CFG)\$(PLAT)\glibmm\*.res
-       @-del /f /q $(CFG)\$(PLAT)\glibmm\*.obj
-       @-del /f /q $(CFG)\$(PLAT)\gendef\*.obj
-       @-if exist $(CFG)\$(PLAT)\giomm-tests rd $(CFG)\$(PLAT)\giomm-tests
-       @-rd $(CFG)\$(PLAT)\giomm-ex
-       @-rd $(CFG)\$(PLAT)\giomm
-       @-if exist $(CFG)\$(PLAT)\glibmm-tests rd $(CFG)\$(PLAT)\glibmm-tests
-       @-rd $(CFG)\$(PLAT)\glibmm-ex
-       @-rd $(CFG)\$(PLAT)\glibmm
-       @-rd $(CFG)\$(PLAT)\gendef
-       @-del /f /q vc$(PDBVER)0.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.exe
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.dll
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.ilk
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.exp
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\*.lib
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.exe
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.dll
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.pdb
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.ilk
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.exp
+       @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.lib
+       @-del ..\tools\generate_wrap_init.pl
+       @-del ..\tools\gmmproc
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\gschemas.compiled
+       @-del vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\*.pdb
+       @-del vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen\*.obj
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests\*.obj
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex\*.obj
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.def
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.res
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.obj
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.cc
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\private\*.h
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\*.h
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests\*.obj
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex\*.obj
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.def
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.res
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.obj
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.pdb
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.cc
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\private\*.h
+       @-del /f /q vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\*.h
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests rd vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\private
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\giomm
+       @-if exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests rd vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\private
+       @-rd vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm
+
+.SUFFIXES: .cc .h .ccg .hg .obj .cc.m4 .h.m4
index 035e263..93029a0 100644 (file)
@@ -7,9 +7,9 @@ BASE_INCLUDES = /I$(PREFIX)\include
 GLIB_API_VERSION = 2.0
 
 GLIBMM_MAJOR_VERSION = 2
-GLIBMM_MINOR_VERSION = 64
+GLIBMM_MINOR_VERSION = 4
 
-LIBSIGC_MAJOR_VERSION = 3
+LIBSIGC_MAJOR_VERSION = 2
 LIBSIGC_MINOR_VERSION = 0
 
 !if "$(CFG)" == "debug" || "$(CFG)" == "Debug"
@@ -18,12 +18,22 @@ DEBUG_SUFFIX = -d
 DEBUG_SUFFIX =
 !endif
 
+!ifndef M4
+M4 = m4
+!endif
+
 GLIBMM_BASE_CFLAGS =                   \
-       /I..\glib /I.\glibmm            \
-       /wd4530 /std:c++17      \
+       /Ivs$(PDBVER)\$(CFG)\$(PLAT)    \
+       /I..\untracked\glib /I..\untracked\glib\glibmm          \
+       /I..\glib /I..\glib\glibmm /I.\glibmm           \
+       /wd4530 /wd4251 /wd4275 /EHsc   \
        /FImsvc_recommended_pragmas.h
 
-GIOMM_BASE_CFLAGS = /I..\gio /I.\giomm $(GLIBMM_BASE_CFLAGS)
+GIOMM_BASE_CFLAGS =    \
+       /Ivs$(PDBVER)\$(CFG)\$(PLAT)    \
+       /I..\untracked\gio /I..\untracked\gio\giomm     \
+       /I..\gio /I..\gio\giomm /I.\giomm       \
+       $(GLIBMM_BASE_CFLAGS)
 
 GLIBMM_EXTRA_INCLUDES =        \
        /I$(PREFIX)\include\gio-win32-$(GLIB_API_VERSION)       \
@@ -37,27 +47,34 @@ LIBGIOMM_CFLAGS = /DGIOMM_BUILD /DSIZEOF_WCHAR_T=2 $(GIOMM_BASE_CFLAGS) $(GLIBMM
 GLIBMM_EX_CFLAGS = $(GLIBMM_BASE_CFLAGS) $(GLIBMM_EXTRA_INCLUDES)
 GIOMM_EX_CFLAGS = $(GIOMM_BASE_CFLAGS) $(GLIBMM_EXTRA_INCLUDES)
 
-# We build glibmm-vc$(VSVER)0-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll or
-#          glibmm-vc$(VSVER)0-d-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll at least
-#          giomm-vc$(VSVER)0-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll or
-#          giomm-vc$(VSVER)0-d-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll at least
-
-LIBSIGC_LIBNAME = sigc-vc$(VSVER)0$(DEBUG_SUFFIX)-$(LIBSIGC_MAJOR_VERSION)_$(LIBSIGC_MINOR_VERSION)
+# We build glibmm-vc$(PDBVER)0-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll or
+#          glibmm-vc$(PDBVER)0-d-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll at least
+#          giomm-vc$(PDBVER)0-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll or
+#          giomm-vc$(PDBVER)0-d-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION).dll at least
 
+!ifdef USE_MESON_LIBS
+LIBSIGC_LIBNAME = sigc-$(LIBSIGC_MAJOR_VERSION).$(LIBSIGC_MINOR_VERSION)
+LIBSIGC_DLL = $(LIBSIGC_LIBNAME)-0.dll
+!else
+LIBSIGC_LIBNAME = sigc-vc$(PDBVER)0$(DEBUG_SUFFIX)-$(LIBSIGC_MAJOR_VERSION)_$(LIBSIGC_MINOR_VERSION)
 LIBSIGC_DLL = $(LIBSIGC_LIBNAME).dll
+!endif
+
 LIBSIGC_LIB = $(LIBSIGC_LIBNAME).lib
 
-GLIBMM_LIBNAME = glibmm-vc$(VSVER)0$(DEBUG_SUFFIX)-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION)
+GLIBMM_LIBNAME = glibmm-vc$(PDBVER)0$(DEBUG_SUFFIX)-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION)
 
-GLIBMM_DLL = $(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).dll
-GLIBMM_LIB = $(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).lib
+GLIBMM_DLL = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).dll
+GLIBMM_LIB = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).lib
+GLIBMM_EXTRA_DEFS_GEN_LIBNAME = glibmm_generate_extra_defs-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)
+GLIBMM_EXTRA_DEFS_GEN_LIB = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_EXTRA_DEFS_GEN_LIBNAME).lib
+GLIBMM_EXTRA_DEFS_GEN_DLL = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_EXTRA_DEFS_GEN_LIBNAME).dll
 
-GIOMM_LIBNAME = giomm-vc$(VSVER)0$(DEBUG_SUFFIX)-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION)
+GIOMM_LIBNAME = giomm-vc$(PDBVER)0$(DEBUG_SUFFIX)-$(GLIBMM_MAJOR_VERSION)_$(GLIBMM_MINOR_VERSION)
 
-GIOMM_DLL = $(CFG)\$(PLAT)\$(GIOMM_LIBNAME).dll
-GIOMM_LIB = $(CFG)\$(PLAT)\$(GIOMM_LIBNAME).lib
+GIOMM_DLL = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GIOMM_LIBNAME).dll
+GIOMM_LIB = vs$(PDBVER)\$(CFG)\$(PLAT)\$(GIOMM_LIBNAME).lib
 
-GENDEF = $(CFG)\$(PLAT)\gendef.exe
 GOBJECT_LIBS = gobject-2.0.lib gmodule-2.0.lib glib-2.0.lib
 GIO_LIBS = gio-2.0.lib $(GOBJECT_LIBS)
 
index 50f7767..b7eb5f9 100644 (file)
@@ -46,13 +46,22 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 !if [call create-lists.bat header glibmm.mak glibmm_OBJS]
 !endif
 
-!if [for %c in ($(glibmm_files_built_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\glibmm\%~nc.obj]
+!if [for %c in ($(glibmm_files_built_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\glibmm\%~nc.obj]
 !endif
 
-!if [for %c in ($(glibmm_files_extra_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\glibmm\%~nc.obj]
+!if [for %c in ($(glibmm_files_extra_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\glibmm\%~nc.obj]
 !endif
 
-!if [@call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\glibmm\glibmm.res]
+!if [@call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\glibmm\glibmm.res]
+!endif
+
+!if [call create-lists.bat footer glibmm.mak]
+!endif
+
+!if [call create-lists.bat header glibmm.mak glibmm_real_hg]
+!endif
+
+!if [for %c in ($(glibmm_files_used_hg)) do @call create-lists.bat file glibmm.mak ..\glib\src\%c]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
@@ -63,13 +72,22 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 !if [call create-lists.bat header glibmm.mak giomm_OBJS]
 !endif
 
-!if [for %c in ($(giomm_generated_sources)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm\%~nc.obj]
+!if [for %c in ($(giomm_generated_sources)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm\%~nc.obj]
+!endif
+
+!if [for %c in ($(giomm_files_extra_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm\%~nc.obj]
+!endif
+
+!if [@call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm\giomm.res]
+!endif
+
+!if [call create-lists.bat footer glibmm.mak]
 !endif
 
-!if [for %c in ($(giomm_files_extra_cc)) do @if "%~xc" == ".cc" @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm\%~nc.obj]
+!if [call create-lists.bat header glibmm.mak giomm_real_hg]
 !endif
 
-!if [@call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm\giomm.res]
+!if [for %c in ($(giomm_files_any_hg)) do @call create-lists.bat file glibmm.mak ..\gio\src\%c]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
@@ -81,7 +99,7 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 # We skip building the following examples:
 # child_watch, iochannel_stream: Builds on *NIX only
 # thread\dispatcher.cc: Not C++-17 compliant
-!if [for %e in (compose dispatcher2 keyfile markup options properties regex) do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\glibmm-ex-%e.exe]
+!if [for %e in (compose dispatcher2 keyfile markup options properties regex) do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\glibmm-ex-%e.exe]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
@@ -90,13 +108,13 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 !if [call create-lists.bat header glibmm.mak giomm_ex]
 !endif
 
-!if [for %e in (resolver socket-client socket-server) do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm-ex-network-%e.exe]
+!if [for %e in (resolver socket-client socket-server) do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm-ex-network-%e.exe]
 !endif
 
-!if [for %e in (settings) do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm-ex-%e.exe]
+!if [for %e in (settings) do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm-ex-%e.exe]
 !endif
 
-!if [for %e in (client_bus_listnames session_bus_service server_without_bus) do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\giomm-ex-dbus-%e.exe]
+!if [for %e in (client_bus_listnames session_bus_service server_without_bus) do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\giomm-ex-dbus-%e.exe]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
@@ -108,7 +126,7 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 # Skip the following:
 # glibmm_interface_implementation, glibmm_null_vectorutils, glibmm_vector: Are actually using giomm
 # glibmm_interface_move: Relies on g_autoptr_*()
-!if [for /f %d in ('dir /ad /b ..\tests\glibmm_*') do @if not "%d" == "glibmm_interface_implementation" if not "%d" == "glibmm_interface_move" if not "%d" == "glibmm_null_vectorutils" if not "%d" == "glibmm_vector" @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\test-%d.exe]
+!if [for /f %d in ('dir /ad /b ..\tests\glibmm_*') do @if not "%d" == "glibmm_interface_implementation" if not "%d" == "glibmm_interface_move" if not "%d" == "glibmm_null_vectorutils" if not "%d" == "glibmm_vector" @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\test-%d.exe]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
@@ -117,15 +135,18 @@ glibmm_files_extra_ph_int = $(glibmm_files_extra_ph:/=\)
 !if [call create-lists.bat header glibmm.mak giomm_tests]
 !endif
 
-!if [for /f %d in ('dir /ad /b ..\tests\giomm_*') do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\test-%d.exe]
+!if [for /f %d in ('dir /ad /b ..\tests\giomm_*') do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\test-%d.exe]
 !endif
 
-!if [for %d in (interface_implementation null_vectorutils vector) do @call create-lists.bat file glibmm.mak ^$(CFG)\^$(PLAT)\test-glibmm_%d.exe]
+!if [for %d in (interface_implementation null_vectorutils vector) do @call create-lists.bat file glibmm.mak vs^$(PDBVER)\^$(CFG)\^$(PLAT)\test-glibmm_%d.exe]
 !endif
 
 !if [call create-lists.bat footer glibmm.mak]
 !endif
 
+!if [for %d in ($(PREFIX)) do @echo PREFIX_REAL=%~dpnd>>glibmm.mak]
+!endif
+
 !include glibmm.mak
 
 !if [del /f /q glibmm.mak]
index 9a92c11..848887e 100644 (file)
@@ -8,7 +8,7 @@
 # in $(GLIB_PREFIX)\lib.
 
 !if "$(PREFIX)" == ""
-PREFIX = ..\..\vs$(VSVER)\$(PLAT)
+PREFIX = ..\..\vs$(PDBVER)\$(PLAT)
 !endif
 
 # Location of the PERL interpreter, for running glib-mkenums.  glib-mkenums
@@ -122,6 +122,10 @@ CFLAGS_ADD = $(CFLAGS_ADD_NO_GL) /GL
 !if "$(VSVER)" != "9"
 CFLAGS_ADD = $(CFLAGS_ADD) /d2Zi+
 CFLAGS_ADD_NO_GL = $(CFLAGS_ADD_NO_GL) /d2Zi+
+!if $(VSVER) >= 14
+CFLAGS_ADD = $(CFLAGS_ADD) /utf-8
+CFLAGS_ADD_NO_GL = $(CFLAGS_ADD_NO_GL) /utf-8
+!endif
 !endif
 !else
 CFLAGS_ADD = /MDd /Od
index 51cd314..c450c50 100644 (file)
@@ -6,7 +6,6 @@ msvc_nmake_data =               \
        create-lists.bat        \
        create-lists-msvc.mak   \
        detectenv-msvc.mak      \
-       gendef/gendef.cc        \
        generate-msvc.mak       \
        glibmm/glibmmconfig.h   \
        glibmm/glibmm.rc        \
diff --git a/MSVC_NMake/gendef/gendef.cc b/MSVC_NMake/gendef/gendef.cc
deleted file mode 100644 (file)
index d18ac9f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  MICO --- an Open Source CORBA implementation
- *  Copyright (c) 2003 Harald Böhme
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, visit the MICO Home Page at
- *  http://www.mico.org/
- */
-
-/* Modified by Cedric Gustin <cedric.gustin@gmail.com> on 2006/01/13 :
- * Redirect the output of dumpbin to dumpbin.out instead of reading the
- * output stream of popen, as it fails with Visual Studio 2005 in
- * pre-link build events.
- */
-
-#include <fstream>
-#include <iostream>
-#include <stdio.h>
-
-using namespace std;
-
-int
-main(int argc, char** argv)
-{
-  if (argc < 4)
-  {
-    cerr << "Usage: " << argv[0] << " <def-file-name> <dll-base-name> <obj-file> ...." << endl;
-    return 2;
-  }
-
-  // CG : Explicitly redirect stdout to dumpbin.out.
-  string dumpbin = "dumpbin /SYMBOLS /OUT:dumpbin.out";
-  int i = 3;
-
-  for (; i < argc;)
-  {
-    dumpbin += " ";
-    dumpbin += argv[i++];
-  }
-
-  FILE* dump;
-
-  if ((dump = _popen(dumpbin.c_str(), "r")) == NULL)
-  {
-    cerr << "could not popen dumpbin" << endl;
-    return 3;
-  }
-
-  // CG : Wait for the dumpbin process to finish and open dumpbin.out.
-  _pclose(dump);
-  dump = fopen("dumpbin.out", "r");
-
-  ofstream def_file(argv[1]);
-
-  def_file << "LIBRARY " << argv[2] << endl;
-  def_file << "EXPORTS" << endl;
-
-  i = 0;
-  while (!feof(dump))
-  {
-    char buf[65000];
-
-    if (fgets(buf, 64999, dump) != NULL)
-    {
-      if (!strstr(buf, " UNDEF ") && strstr(buf, " External "))
-      {
-        char* s = strchr(buf, '|') + 1;
-        while (*s == ' ' || *s == '\t')
-          s++;
-        char* e = s;
-        while (*e != ' ' && *e != '\t' && *e != '\0' && *e != '\n')
-          e++;
-        *e = '\0';
-
-        if (strchr(s, '?') == 0 && s[0] == '_' &&
-            strchr(s, '@') == 0) // this is a C export type: _fct -> fct
-          def_file << "    " << (s + 1) << endl;
-        else if (strchr(s, '?') != 0 && strncmp(s, "??_G", 4) != 0 && strncmp(s, "??_E", 4) != 0)
-        {
-          def_file << "    " << s << endl;
-        }
-      }
-    }
-  }
-
-  // CG : Close dumpbin.out and delete it.
-  fclose(dump);
-  remove("dumpbin.out");
-
-  cout << dumpbin.c_str() << endl;
-}
index 624e7f8..bd9a9dd 100644 (file)
@@ -4,22 +4,99 @@
 # one is maintaining the NMake build files.
 
 # Create the build directories
-$(CFG)\$(PLAT)\gendef  \
-$(CFG)\$(PLAT)\glibmm  \
-$(CFG)\$(PLAT)\giomm   \
-$(CFG)\$(PLAT)\glibmm-ex       \
-$(CFG)\$(PLAT)\giomm-ex        \
-$(CFG)\$(PLAT)\glibmm-tests    \
-$(CFG)\$(PLAT)\giomm-tests:
-       @-mkdir $@
-
-# Generate .def files
-$(CFG)\$(PLAT)\glibmm\glibmm.def: $(GENDEF) $(CFG)\$(PLAT)\glibmm $(glibmm_OBJS)
-       $(CFG)\$(PLAT)\gendef.exe $@ $(GLIBMM_LIBNAME) $(CFG)\$(PLAT)\glibmm\*.obj
-
-$(CFG)\$(PLAT)\giomm\giomm.def: $(GENDEF) $(CFG)\$(PLAT)\giomm $(giomm_OBJS)
-       $(CFG)\$(PLAT)\gendef.exe $@ $(GIOMM_LIBNAME) $(CFG)\$(PLAT)\giomm\*.obj
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\private      \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\private       \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-ex   \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-ex    \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm-tests        \
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm-tests \
+vs$(PDBVER)\$(CFG)\$(PLAT)\glib-extra-defs-gen:
+       @-md $@
 
 # Compile schema for giomm settings example
-$(CFG)\$(PLAT)\gschema.compiled: ..\examples\settings\org.gtkmm.demo.gschema.xml
-       $(GLIB_COMPILE_SCHEMAS) --targetdir=$(CFG)\$(PLAT) ..\examples\settings
\ No newline at end of file
+vs$(PDBVER)\$(CFG)\$(PLAT)\gschema.compiled: ..\examples\settings\org.gtkmm.demo.gschema.xml
+       $(GLIB_COMPILE_SCHEMAS) --targetdir=vs$(PDBVER)\$(CFG)\$(PLAT) ..\examples\settings
+
+# Generate wrap_init.cc files
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\wrap_init.cc: $(glibmm_real_hg)
+       @if not exist ..\glib\glibmm\wrap_init.cc $(PERL) -- "../tools/generate_wrap_init.pl" --namespace=Glib --parent_dir=glibmm $(glibmm_real_hg:\=/)>$@
+
+vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\wrap_init.cc: $(giomm_real_hg)
+       @if not exist ..\gio\giomm\wrap_init.cc $(PERL) -- "../tools/generate_wrap_init.pl" --namespace=Gio --parent_dir=giomm $(giomm_real_hg:\=/)>$@
+
+# Generate pre-generated resources and configuration headers (builds from GIT)
+prep-git-build: pkg-ver.mak
+
+gen-perl-scripts-real: pkg-ver.mak
+       $(MAKE) /f Makefile.vc CFG=$(CFG) GENERATE_VERSIONED_FILES=1 ..\tools\gmmproc ..\tools\generate_wrap_init.pl
+
+glibmm\glibmm.rc: pkg-ver.mak glibmm\glibmm.rc.in glibmm\glibmmconfig.h
+       @echo Generating $@...
+       @copy $@.in $@
+       @$(PERL) -pi.bak -e "s/\@GLIBMM_MAJOR_VERSION\@/$(PKG_MAJOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GLIBMM_MINOR_VERSION\@/$(PKG_MINOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GLIBMM_MICRO_VERSION\@/$(PKG_MICRO_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@PACKAGE_VERSION\@/$(PKG_MAJOR_VERSION).$(PKG_MINOR_VERSION).$(PKG_MICRO_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GLIBMM_MODULE_NAME\@/glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)/g" $@
+       @del $@.bak
+
+glibmm\glibmmconfig.h: ..\glib\glibmmconfig.h.in
+       @echo Copying $@ from $**...
+       @copy $** $@
+
+giomm\giomm.rc: pkg-ver.mak
+       @echo Generating $@...
+       @copy $@.in $@
+       @$(PERL) -pi.bak -e "s/\@GIOMM_MAJOR_VERSION\@/$(PKG_MAJOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GIOMM_MINOR_VERSION\@/$(PKG_MINOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GIOMM_MICRO_VERSION\@/$(PKG_MICRO_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@PACKAGE_VERSION\@/$(PKG_MAJOR_VERSION).$(PKG_MINOR_VERSION).$(PKG_MICRO_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GIOMM_MODULE_NAME\@/giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)/g" $@
+       @del $@.bak
+
+# You may change GIOMM_DISABLE_DEPRECATED and GIOMM_STATIC_LIB if you know what you are doing
+giomm\giommconfig.h: pkg-ver.mak ..\gio\giommconfig.h.in
+       @echo Generating $@...
+       @copy ..\gio\$(@F).in $@
+       @$(PERL) -pi.bak -e "s/\#undef GIOMM_DISABLE_DEPRECATED/\/\* \#undef GIOMM_DISABLE_DEPRECATED \*\//g" $@
+       @$(PERL) -pi.bak -e "s/\#undef GIOMM_STATIC_LIB/\/\* \#undef GIOMM_STATIC_LIB \*\//g" $@
+       @$(PERL) -pi.bak -e "s/\#undef GIOMM_MAJOR_VERSION/\#define GIOMM_MAJOR_VERSION $(PKG_MAJOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\#undef GIOMM_MINOR_VERSION/\#define GIOMM_MINOR_VERSION $(PKG_MINOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\#undef GIOMM_MICRO_VERSION/\#define GIOMM_MICRO_VERSION $(PKG_MICRO_VERSION)/g" $@
+       @del $@.bak
+
+..\tools\gmmproc: ..\tools\gmmproc.in
+       @echo Generating $@...
+       @copy $** $@
+       @$(PERL) -pi.bak -e "s/\@PERL\@/$(PERL:\=\/)/g" $@
+       @$(PERL) -pi.bak -e "s/\@prefix\@/$(PREFIX_REAL:\=\/)/g" $@
+       @$(PERL) -pi.bak -e "s/\@exec_prefix\@/$(PREFIX_REAL:\=\/)/g" $@
+       @$(PERL) -pi.bak -e "s/\@libdir\@/$(PREFIX_REAL:\=\/)\/share/g" $@
+       @$(PERL) -pi.bak -e "s/\@M4\@/$(M4:\=\/)/g" $@
+       @$(PERL) -pi.bak -e "s/\@GLIBMM_MODULE_NAME\@/glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)/g" $@
+       @$(PERL) -pi.bak -e "s/\@PACKAGE_VERSION\@/$(PKG_MAJOR_VERSION).$(PKG_MINOR_VERSION).$(PKG_MICRO_VERSION)/g" $@
+       @del $@.bak
+
+..\tools\generate_wrap_init.pl: ..\tools\generate_wrap_init.pl.in
+       @echo Generating $@...
+       @copy $** $@
+       @$(PERL) -pi.bak -e "s/\@PERL\@/$(PERL:\=\/)/g" $@
+       @del $@.bak
+
+pkg-ver.mak: ..\configure.ac
+       @echo Generating version info Makefile Snippet...
+       @$(PERL) -00 -ne "print if /AC_INIT\(/" $** |   \
+       $(PERL) -pe "tr/, /\n/s" |      \
+       $(PERL) -ne "print if 2 .. 2" | \
+       $(PERL) -ne "print /\[(.*)\]/" > ver.txt
+       @echo @echo off>pkg-ver.bat
+       @echo.>>pkg-ver.bat
+       @echo set /p glibmm_ver=^<ver.txt>>pkg-ver.bat
+       @echo for /f "tokens=1,2,3 delims=." %%%%a IN ("%glibmm_ver%") do (echo PKG_MAJOR_VERSION=%%%%a^& echo PKG_MINOR_VERSION=%%%%b^& echo PKG_MICRO_VERSION=%%%%c)^>$@>>pkg-ver.bat
+       @pkg-ver.bat
+       @del ver.txt pkg-ver.bat
+       $(MAKE) /f Makefile.vc CFG=$(CFG) GENERATE_VERSIONED_FILES=1 glibmm\glibmm.rc giomm\giomm.rc giomm\giommconfig.h
+       $(MAKE) /f Makefile.vc CFG=$(CFG) gen-perl-scripts-real
diff --git a/MSVC_NMake/giomm/meson.build b/MSVC_NMake/giomm/meson.build
new file mode 100644 (file)
index 0000000..658147d
--- /dev/null
@@ -0,0 +1,17 @@
+# MSVC_NMake/giomm
+
+# Input: pkg_conf_data, giommconfig_h
+# Output: giomm_rc
+
+giomm_rc = configure_file(
+  input: 'giomm.rc.in',
+  output: '@BASENAME@',
+  configuration: pkg_conf_data,
+)
+
+# Copy the generated configuration header into the MSVC project directory.
+configure_file(
+  input: giommconfig_h,
+  output: 'giommconfig.h',
+  copy: true,
+)
diff --git a/MSVC_NMake/glibmm/meson.build b/MSVC_NMake/glibmm/meson.build
new file mode 100644 (file)
index 0000000..5112281
--- /dev/null
@@ -0,0 +1,17 @@
+# MSVC_NMake/glibmm
+
+# Input: pkg_conf_data, glibmmconfig_h
+# Output: glibmm_rc
+
+glibmm_rc = configure_file(
+  input: 'glibmm.rc.in',
+  output: '@BASENAME@',
+  configuration: pkg_conf_data,
+)
+
+# Copy the generated configuration header into the MSVC project directory.
+configure_file(
+  input: glibmmconfig_h,
+  output: 'glibmmconfig.h',
+  copy: true,
+)
index d25f962..6b96310 100644 (file)
@@ -10,9 +10,9 @@ all-build-info:
 help:
        @echo.
        @echo ============================
-       @echo Building cairomm Using NMake
+       @echo Building glibmm Using NMake
        @echo ============================
-       @echo nmake /f Makefile.vc CFG=[release^|debug] ^<PREFIX=PATH^> <option1=xxx option2=xxx>
+       @echo nmake /f Makefile.vc CFG=[release^|debug] ^<PREFIX=PATH^> ^<option1=xxx option2=xxx^>
        @echo.
        @echo Where:
        @echo ------
@@ -30,13 +30,15 @@ help:
        @echo GLIB_COMPILE_SCHEMAS: Location of the glib-compile-schemas tool,
        @echo if it cannot be found in $(PREFIX)\bin.  This tool is needed for the
        @echo giomm settings example program.
+       @echo.
+       @echo USE_MESON_LIBS: Use DLLs and LIBs of C++ dependencies that are built with Meson,
+       @echo as applicable.
        @echo ======
        @echo A 'clean' target is supported to remove all generated files, intermediate
        @echo object files and binaries for the specified configuration.
        @echo.
        @echo An 'install' target is supported to copy the build (DLLs, utility programs,
-       @echo LIBs, along with the introspection files if applicable) to appropriate
-       @echo locations under ^$(PREFIX).
+       @echo LIBs, along with the header files) to appropriate locations under ^$(PREFIX).
        @echo.
        @echo A 'tests' target is supported to build the test programs.
        @echo ======
index cf056eb..5bb2ce3 100644 (file)
@@ -2,23 +2,41 @@
 # a path under $(PREFIX).
 
 install: all
-       @if not exist $(PREFIX)\bin\ mkdir $(PREFIX)\bin
-       @if not exist $(PREFIX)\lib\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\ mkdir $(PREFIX)\lib\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include
-       @if not exist $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\ @mkdir $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private
-       @if not exist $(PREFIX)\lib\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\ mkdir $(PREFIX)\lib\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include
-       @if not exist $(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\ @mkdir $(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private
-       @copy /b $(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).dll $(PREFIX)\bin
-       @copy /b $(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).pdb $(PREFIX)\bin
-       @copy /b $(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).lib $(PREFIX)\lib
-       @copy /b $(CFG)\$(PLAT)\$(GIOMM_LIBNAME).dll $(PREFIX)\bin
-       @copy /b $(CFG)\$(PLAT)\$(GIOMM_LIBNAME).pdb $(PREFIX)\bin
-       @copy /b $(CFG)\$(PLAT)\$(GIOMM_LIBNAME).lib $(PREFIX)\lib
+       @if not exist $(PREFIX)\bin\ md $(PREFIX)\bin
+       @if not exist $(PREFIX)\lib\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\ md $(PREFIX)\lib\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include
+       @if not exist $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\ @md $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private
+       @if not exist $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm_generate_extra_defs\ @md $(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm_generate_extra_defs
+       @if not exist $(PREFIX)\lib\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\ md $(PREFIX)\lib\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include
+       @if not exist $(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\ @md $(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private
+       @-for %d in (m4 pm) do @md $(PREFIX)\share\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\proc\%d
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).dll $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).pdb $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_LIBNAME).lib $(PREFIX)\lib
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GIOMM_LIBNAME).dll $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GIOMM_LIBNAME).pdb $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GIOMM_LIBNAME).lib $(PREFIX)\lib
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_EXTRA_DEFS_GEN_LIBNAME).dll $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_EXTRA_DEFS_GEN_LIBNAME).pdb $(PREFIX)\bin
+       @copy /b vs$(PDBVER)\$(CFG)\$(PLAT)\$(GLIBMM_EXTRA_DEFS_GEN_LIBNAME).lib $(PREFIX)\lib
        @copy ..\glib\glibmm.h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\"
        @copy ..\gio\giomm.h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\"
-       @for %h in ($(glibmm_files_all_h)) do @copy ..\glib\glibmm\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\%h"
-       @for %h in ($(glibmm_generated_private_headers)) do @copy ..\glib\glibmm\private\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\%h"
+       @for %h in ($(glibmm_files_all_h)) do @if exist ..\glib\glibmm\%h copy ..\glib\glibmm\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\%h"
+       @for %h in ($(glibmm_files_all_h)) do @if exist ..\untracked\glib\glibmm\%h copy ..\untracked\glib\glibmm\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\%h"
+       @for %h in ($(glibmm_files_all_h)) do @if exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\%h copy vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\%h"
+       @for %h in ($(glibmm_generated_private_headers)) do @if exist ..\glib\glibmm\private\%h copy ..\glib\glibmm\private\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\%h"
+       @for %h in ($(glibmm_generated_private_headers)) do @if exist ..\untracked\glib\glibmm\private\%h copy ..\untracked\glib\glibmm\private\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\%h"
+       @for %h in ($(glibmm_generated_private_headers)) do @if exist vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\private\%h copy vs$(PDBVER)\$(CFG)\$(PLAT)\glibmm\private\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\private\%h"
        @for %h in ($(glibmm_files_extra_ph_int)) do @copy ..\glib\glibmm\%h "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm\%h"
-       @for %h in ($(giomm_generated_headers) $(giomm_files_extra_h)) do @copy ..\gio\giomm\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\%h"
-       @for %h in ($(giomm_generated_private_headers)) do @copy ..\gio\giomm\private\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\%h"
+       @for %h in ($(giomm_generated_headers) $(giomm_files_extra_h)) do @if exist ..\gio\giomm\%h copy ..\gio\giomm\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\%h"
+       @for %h in ($(giomm_generated_headers) $(giomm_files_extra_h)) do @if exist ..\untracked\gio\giomm\%h copy ..\untracked\gio\giomm\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\%h"
+       @for %h in ($(giomm_generated_headers) $(giomm_files_extra_h)) do @if exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\%h copy vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\%h"
+       @for %h in ($(giomm_generated_private_headers)) do @if exist ..\gio\giomm\private\%h copy ..\gio\giomm\private\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\%h"
+       @for %h in ($(giomm_generated_private_headers)) do @if exist ..\untracked\gio\giomm\private\%h copy ..\untracked\gio\giomm\private\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\%h"
+       @for %h in ($(giomm_generated_private_headers)) do @if exist vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\private\%h copy vs$(PDBVER)\$(CFG)\$(PLAT)\giomm\private\%h "$(PREFIX)\include\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\giomm\private\%h"
        @copy ".\glibmm\glibmmconfig.h" "$(PREFIX)\lib\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\"
        @copy ".\giomm\giommconfig.h" "$(PREFIX)\lib\giomm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\include\"
+       @copy "..\tools\extra_defs_gen\generate_extra_defs.h" "$(PREFIX)\include\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\glibmm_generate_extra_defs\"
+       @for %d in (m4 pm) do copy ..\tools\%d\* $(PREFIX)\share\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\proc\%d
+       @for %f in (gmmproc generate_wrap_init.pl) do @if exist ..\tools\%f copy ..\tools\%f $(PREFIX)\share\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\proc
+       @for %f in (gmmproc generate_wrap_init.pl) do @if not exist ..\tools\%f copy ..\tools\%f.in $(PREFIX)\share\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\proc\%f
+       @echo Please ensure gmmproc and generate_wrap_init.pl in $(PREFIX)\share\glibmm-$(GLIBMM_MAJOR_VERSION).$(GLIBMM_MINOR_VERSION)\proc contain the correct paths
index 1b366b4..31aa241 100644 (file)
@@ -52,6 +52,40 @@ dist_noinst_DATA = $(text_files) $(msvc_files)
 dist_noinst_SCRIPTS = autogen.sh
 
 DISTCLEANFILES = $(filter %mmconfig.h,$(msvc_files))
+# Distribute files needed when building glibmm with Meson.
+
+EXTRA_DIST = \
+  meson.build \
+  meson_options.txt \
+  MSVC_NMake/giomm/meson.build \
+  MSVC_NMake/glibmm/meson.build \
+  docs/reference/meson.build \
+  examples/meson.build \
+  glib/meson.build \
+  glib/glibmmconfig.h.meson \
+  glib/glibmm/meson.build \
+  gio/meson.build \
+  gio/giommconfig.h.meson \
+  gio/giomm/meson.build \
+  tests/meson.build \
+  tools/meson.build \
+  tools/build_scripts/compile-schemas.py \
+  tools/build_scripts/dummy-header.py \
+  tools/build_scripts/handle-built-files.py \
+  tools/conf_tests/allows_static_inline_npos.cc \
+  tools/conf_tests/can_assign_non_extern_c_functions_to_extern_c_cb.cc \
+  tools/conf_tests/can_use_dynamic_cast_in_unused_template_wo_def.cc \
+  tools/conf_tests/can_use_namespaces_inside_externc.cc \
+  tools/conf_tests/can_use_thread_local.cc \
+  tools/conf_tests/have_disambiguous_const_template_specializations.cc \
+  tools/conf_tests/have_std_iterator_traits.cc \
+  tools/conf_tests/have_sun_reverse_iterator.cc \
+  tools/conf_tests/have_template_sequence_ctors.cc \
+  tools/conf_tests/have_wide_stream.cc \
+  tools/conf_tests/member_functions_member_templates.cc \
+  tools/conf_tests/std_time_t_is_not_int32.cc \
+  tools/extra_defs_gen/meson.build \
+  untracked/README
 
 # Auto-generate the ChangeLog file from the git log on make dist
 include $(top_srcdir)/build/dist-changelog.am
diff --git a/NEWS b/NEWS
index 18fb92b..fa45fb0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,15 +1,68 @@
-2.63.1: (unstable):
-Distro packagers should probably not package this yet.
+2.64.0 (stable):
 
 Glib:
-* ustring: Fix memory leak in make_valid()
-  Use convert_return_gchar_ptr_to_*() in a couple of methods
+* Add get_user_runtime_dir()
+  (scx) Issue #57, merge request !14
+* Add get_host_name()
+  (scx) Issue #58, merge request !15
+* MainContext: Add push/pop/get_thread_default()
+  (Kjell Ahlstedt) Issue #56 (Yackie-Yang)
+* Add StdStringView and UStringView
+  Use them in build_filename()
+  (Thomas Holder, Kjell Ahlstedt) Issue #34
+* Regex: match(), match_all(): Deprecate rvalue string references
+  (Thomas Holder, Kjell Ahlstedt) Issue #66, merge request !26
+* Add Glib::canonicalize_filename()
+  (Kjell Ahlstedt) Issue #59 (Patrick Storz)
+* ustring: Fix insert(iterator, In, In)
+  (Thomas Holder) Merge request !19
+
+Gio:
+* DBus::Connection: Make the wrap() function thread-safe
+  (Kjell Ahlstedt) Issue #56 (Yackie-Yang)
+* DBus::Message::get_unix_fd_list(): Add refreturn
+  (Kjell Ahlstedt) Issue #68 (kr.woaini)
+
+gmmproc:
+* Add optional decl_prefix parameter to _CLASS_BOXEDTYPE,
+  _CLASS_BOXEDTYPE_STATIC, _CLASS_GOBJECT, _CLASS_INTERFACE,
+  _CLASS_OPAQUE_COPYABLE, _CLASS_OPAQUE_REFCOUNTED, _WRAP_GERROR
+  Used for adding GLIBMM_API or similar for MS Visual C++
+  (Chun-wei Fan)
+
+Build:
+* Add Meson support
+  (Chun-wei Fan, Kjell Ahlstedt) Merge request !28
+* Drop gendef from Windows builds
+  (Chun-wei Fan) Issue #12 (Mikhail Titov), merge request !30
+
+Documentation:
+* Correct spelling of spawn_async_with_pipes()
+  (Mike Fleetwood) Merge request !16
+* Glib::Binding: Several doc improvements
+  (Daniel Boles) Merge request !17
+* Glib::Binding: Explain why SlotTransform takes GValue*
+  (Kjell Ahlstedt) Issue #61 (Daniel Boles)
+* Regex: Note that Glib::ustring must be used in match methods
+  (Kjell Ahlstedt) Issue #66, merge request !26
+* Gio::AsyncResult: Improve the class description
+  (Kjell Ahlstedt) Issue #27 (Alberto Mardegan)
+
+
+2.62.0 (stable):
+
+Glib:
+* Add ustring::make_valid()
+  (Krzysztof Piecuch) Bug #780075
+  (Martin Ejdestig) Merge request !11
+  Issue #40 (Tanu Kaskinen)
+* Use convert_return_gchar_ptr_to_*() in a couple of ustring methods
   (Martin Ejdestig) Merge request !11
 * Add ustring::sprintf(), wrapping g_strdup_printf()
   (Daniel Boles) Issue #21
 * Fix callback races in glibmm when GSource is destructed
   (Dainis Jonitis) Issue #41
-* Checksum, Datetime, TimeZone: Declare as _CLASS_BOXEDTYPE
+* Checksum, Datetime, TimeZone: Add Glib::Value specializations
   (Kjell Ahlstedt)
 * Property: Add const get_proxy() returning ReadOnly
   Getting Proxy from ReadOnly is const
@@ -18,7 +71,7 @@ Glib:
   (Kjell Ahlstedt)
 * Fix memory leak in Variant<std::tuple<>>::create()
   (Van de Bugger, Kjell Ahlstedt) Issue #48
-* Remove TimeVal
+* Deprecate TimeVal
   (Kjell Ahlstedt)
 
 Gio:
@@ -32,7 +85,7 @@ Gio:
 * Drive, MountOperation, ThemedIcon, TlsDatabase, VolumeMonitor:
   Fix ownership of some lists and arrays (Fixes memory leaks
   and dangling pointers)
-  (Kjell Ahlstedt)
+  (Kjell Ahlstedt) Issue #50 (Gary Wang)
 * Add SocketControlMessage::add_deserialize_func()
   (Kjell Ahlstedt) Issue #52 (Ankur deep jaiswal)
 
@@ -41,12 +94,8 @@ gmmproc:
   (Kjell Ahlstedt)
 
 Build:
-* Doxyfile.in: Remove unused configuration constants
-  (Kjell Ahlstedt) Issue #22
 * Require glib-2.0 >= 2.61.2
   (Kjell Ahlstedt)
-* Change the ABI to glibmm-2.64
-  (Kjell Ahlstedt)
 
 Documentation:
 * Glib::init(), Gio::init(): Improve the documentation
@@ -55,60 +104,52 @@ Documentation:
   (Kjell Ahlstedt) Issue #47 (Patrick Storz)
 
 
-2.61.1: (unstable):
-Distro packagers should probably not package this yet.
+2.60.0 (stable):
 
 Glib:
 * Add DateTime::get_timezone()
   Add KeyFile::get_locale_for_key()
   Add TimeZone::get_identifier()
   (Kjell Ahlstedt)
-* KeyFile: Make it a refcounted class
-  (Kjell Ahlstedt)
 * Add Value_RefPtrBoxed<>
   Add Value<std::vector<string>> specializations and other Value
   specializations that are necessary for _WRAP_PROPERTY
   (Kjell Ahlstedt)
+* Object construction: Add custom class init and instance init functions
+  (Kjell Ahlstedt) Issue #33
 
 Gio:
-* Put _WRAP_VFUNC in protected sections
-  (Kjell Ahlstedt)
 * Add AppInfo::launch_uris_async() and launch_uris_async()
-  Add DBusConnection::get_flags()and property_flags()
+  Add DBusConnection::get_flags() and property_flags()
+  (Kjell Ahlstedt)
+* Settings: Add property_settings_schema()
   (Kjell Ahlstedt)
-* TlsClientConnection: Remove property_accepted_cas()
+* TlsClientConnection: Deprecate property_accepted_cas()
   (Kjell Ahlstedt)
 * ThemedIcon: Add create(const std::vector<Glib::ustring>& iconnames)
   (Kjell Ahlstedt)
 * Remove NO_GTYPE from some _WRAP_ENUMs
   (Kjell Ahlstedt) Issue #37 (Jan Tojnar)
-* TlsConnection: Remove rehandshake API
+* TlsConnection: Deprecate rehandshake API
   (Kjell Ahlstedt)
 * Application: Add signal_name_lost()
   (Kjell Ahlstedt)
 
-Glib and Gio:
-* Use {} for function arguments initialisation
-  (Tapasweni Pathak) Merge request !9
-  Issue #20 (Daniel Boles)
-
 gmmproc:
-* generate_wrap_init.pl.in: Don't exclude any Gtk classes
-  (Kjell Ahlstedt)
-* _WRAP_PROPERTY: generate a static_assert() that checks if
-  the data type is acceptable
-  (Kjell Ahlstedt)
 * Add _IS_REFCOUNTED_BOXEDTYPE
   (Kjell Ahlstedt)
-* _WRAP_ENUM and _WRAP_GERROR: Add gtype_func parameter
-  (Kjell Ahlstedt)
 
 Build:
-* glibmmconfig.h.in: Remove unused configuration constants
-  (Kjell Ahlstedt) Issue #22
 * Require glib-2.0 >= 2.59.2
   (Kjell Ahlstedt)
-* Change the ABI to glibmm-2.62
+
+
+2.58.1 (stable):
+
+gmmproc:
+* _WRAP_ENUM and _WRAP_GERROR: Add gtype_func parameter
+  (Kjell Ahlstedt)
+* docextract_to_xml.py: Add --exclude-file option.
   (Kjell Ahlstedt)
 
 Documentation:
@@ -118,8 +159,12 @@ Documentation:
   (Daniel Boles) Merge request !6
 
 
-2.59.1: (unstable):
-Distro packagers should probably not package this yet.
+2.58.0 (stable):
+
+This release is identical to 2.56.1.
+
+
+2.56.1 (stable):
 
 Glib:
 * ustring: Fix wchar conversion on macOS with libc++
@@ -127,525 +172,205 @@ Glib:
 * Avoid compiler warnings from function pointer conversions
   (Kjell Ahlstedt) Issue libsigcplusplus#1 (sharkcz)
   (Kjell Ahlstedt) Issue libsigcplusplus#8 (db0451)
-* ustring: Simplify format() using C++17 fold expression.
-  (Daniel Boles) Merge request !4
 
 Gio:
-* Application: Add set_option_context_parameter_string(),
-  set_option_context_summary(), set_option_context_description().
-  (Kjell Ahlstedt)
-* DesktopAppInfo: Add get_locale_string()
-  (Kjell Ahlstedt)
 * SocketClient: Take copy in RefPtrs for signal args
   (Daniel Boles) Issue #28 (Jens Mühlenhoff)
-* Make SignalProxy_async_callback() available to e.g. gtkmm
-  (Kjell Ahlstedt)
-
-gmmproc:
-* _WRAP_METHOD: Accept ":" in slot_callback parameter
-  (Kjell Ahlstedt)
 
 Build:
-* Require C++17.
-  (Murray Cumming)
 * Require glib-2.0 >= 2.55.1
   (Kjell Ahlstedt) Issue #29 (Mart Raudsepp)
 * Replace the Visual Studio project files with MSVC NMake project files
-  (Chun-wei Fan) Merge request !2
-* Change the ABI to glibmm-2.60
-  (Kjell Ahlstedt)
+  (Chun-wei Fan) Merge request !5
 
-Documentation:
-* Use libsigc++-3.0.tag for libsigc++ documentation
-  (Kjell Ahlstedt)
 
+2.56.0 (stable):
 
-2.57.1: (unstable):
-Distro packagers should probably not package this yet.
+Glib:
+* Threads::Private: Fix gobj().
+  (Kjell Ahlstedt) Bug #791711 (octoploid)
+* TimeoutSource: Use monotonic time consistently.
+  (Kjell Ahlstedt) Bug #792524 (Dainis Jonitis)
+* Add RefPtr::get().
+  (Kjell Ahlstedt) Bug #495762 (Hubert Figuiere)
 
 Gio:
-* DataOutputStream::put_string(): Don't pass std:string by value
+* TlsClientConnection: Deprecate set/get/property_use_ssl3().
+  (Kjell Ahlstedt)
+* DataInputStream: Deprecate read_until().
+  (Kjell Ahlstedt)
+* Application: Add property_resource_base_path_string().
+  This is a replacement for property_resource_base_path() which can't be
+  fixed without breaking ABI.
+  (Kjell Ahlstedt) Bug #787496 (Daniel Boles)
+* Application: Add three set_option_context_*() methods.
+  (Kjell Ahlstedt)
+* DesktopAppInfo: Add get_locale_string().
   (Kjell Ahlstedt)
 
+Documentation:
+* Slightly elaborate Glib::Variant<Variant> docs.
+  (Daniel Boles) Bug #778219
+
+tests:
+* glibmm_variant: Don't use C++14 features when a C++11 compiler is used.
+  (Kjell Ahlstedt, Jonathan Wakely) Bug #787648 (Armin K.)
+* glibmm_interface_move test: Avoid unused function warnings.
+  (Murray Cumming)
+
 gmmproc:
-* Add _MEMBER_SET_STR() macro
+* _WRAP_METHOD: Accept optional list of exceptions in errthrow.
+  (Kjell Ahlstedt) Bug #787979 (Daniel Boles)
+* _WRAP_METHOD: Suppress the @return section in generated documentation
+  if return type is void.
+  (Kjell Ahlstedt) Bug #787978 (Daniel Boles)
+* Add _MEMBER_SET_STR macro, setter for strings.
   (Pavlo Solntsev) Bug #793778
 
-Build:
-* Change the ABI to glibmm-2.58
-  (Kjell Ahlstedt)
 
+2.54.1 (stable):
 
-2.55.2: (unstable):
-Distro packagers should probably not package this yet.
+Glib:
+* Variant: Don't use std::index_sequence from C++14.
+  (Kjell Ahlstedt, Jonathan Wakely) Bug #787648 (Armin K.)
+
+Documentation:
+* Note that Gio::Application::property_resource_base_path() shall not
+  be used. It has a bug that's hard to fix without breaking ABI.
+  (Kjell Ahlstedt) Bug #787496 (Daniel Boles)
+
+gmmproc:
+* Convert all property documentation to C++.
+  (Kjell Ahlstedt) Bug #787698 (Daniel Boles)
+
+2.54.0 (stable):
 
 Glib:
-* IOCondition: Add an IO_ prefix to the enumerator names
-  (Kjell Ahlstedt)
-* TimeoutSource: Use monotonic time consistently
-  (Kjell Ahlstedt) Bug #792524 (Dainis Jonitis)
-* Source: Remove get_current_time().
-  (Kjell Ahlstedt)
-* KeyFile, OptionContext, Regex: Add exception specs to errthrow.
-  (Kjell Ahlstedt)
-* ustring:
-  - Replace 8×format() with 1 variadic template.
-  - Replace 9×compose() with 1 variadic template.
-  - Use std::initializer_list instead of pointer + size
-  (Daniel Boles) Bug #784211
-* VariantBase:
-  - Add operator==() and operator!=().
-  (Kjell Ahlstedt) Bug #789330 (Daniel Boles)
-  - cast_dynamic(): Remove noexcept(false).
-  (Kjell Ahlstedt)
+* Added DBusObjectPathString and DBusSignatureString, for Variants with D-Bus object paths or D-Bus signatures,
+  and add Variant specializations for Variant<Glib::DBusObjectPathString>,
+  Variant<Glib::DBusSignatureString> and Variant<std::vector<Glib::DBusObjectPathString>>.
+  (Kjell Ahlstedt) Bug #785700
+* Variant: Add template specialization for std::tuple.
+  (Alexander Rössler) Bug #777791
 
-Glib::Gio:
-* AppInfo: Update the name of the AppLaunchContext parameters
-  (Kjell Ahlstedt)
-* Action: Add exception specs to errthrow.
-  (Kjell Ahlstedt)
-* Application: Fix property_resource_base_path()'s type
-  (Kjell Ahlstedt)
-* Credentials, et al.: Add exception specs to errthrow.
-  (Kjell Ahlstedt)
-* DataInputStream:
-  - Remove read_until*().
-  - Fix the documentation of read_line_utf8().
-  (Kjell Ahlstedt)
-* InetSocketAddress, ProxyAddress: No guint16 in _WRAP_PROPERTY().
+Gio:
+* ActionGroup: Add optional action_name parameters to some signals.
   (Kjell Ahlstedt)
-* Settings: set_int() and friends shall return bool.
-  (Kjell Ahlstedt) Bug #784211
-* TlsClientConnection: Remove get/set/property_use_ssl3().
+* Settings: Add optional key parameter to the writable_changed signal.
   (Kjell Ahlstedt)
 
 gmmproc:
-* Warn if parameter lists are not compatible
-  (Kjell Ahlstedt)
-* _WRAP_METHOD: Accept optional list of exceptions in errthrow
-  (Kjell Ahlstedt)
-* _WRAP_METHOD_DOCS_ONLY: Optionally suppress @return section.
-  (Kjell Ahlstedt) Bug #787978
-* docextract_to_xml.py: Add --exclude-file option.
-  (Kjell Ahlstedt)
-* Suppress the @return section if return type is void.
-  (Kjell Ahlstedt)
-* generate_extra_defs.cc:
-  - Write signal flags to .defs files.
-  - Write default values of properties to .defs files.
-  - Write default values of properties to generated documentation.
+* Write signal flags to generated documentation
+  (Kjell Ahlstedt) Bug #785895 (Daniel Boles)
+* Write default values of properties to generated documentation
   (Kjell Ahlstedt) Bug #785895 (Daniel Boles)
 * Warn for unmatched deprecations in signals and properties.
   (Kjell Ahlstedt)
-
-Documentation:
-* Glib::ObjectBase: Don't mention GtkObject in comments.
+* Accept curly braces in default values in _WRAP macros.
+  (Kjell Ahlstedt) Bug #783216 comment #13 (Daniel Boles)
+* Fix _WRAP_ENUM for enumerators with apostrophes.
   (Kjell Ahlstedt)
-* Glib::Variant: Hide namespace Glib::detail from Doxygen
-  (Kjell Ahlstedt) Bug #787698 (Daniel Boles)
-* Glib::Variant: Slightly elaborate Variant<Variant> docs.
-  (Daniel Boles) Bug #778219 (Daniel Boles)
+* Add new elements types for the docs_override:
+  substitute_type_name and substitute_enumerator_name.
+  (Kjell Ahlstedt) Bug #86864
 
 
-2.55.1: (unstable):
-Distro packagers should probably not package this yet.
-
-Glib:
-* Object: Value_Pointer class should take only one template argument.
-  (Marcin Kolny)
-* Variant: Improved support for D-Bus object paths and signatures.
-  (Kjell Ahlstedt) Bug #785700 (Johannes Dohmen)
-* Glib::Value_Flags<>: static_cast to correct type.
-  (Kjell Ahlstedt)
+2.52.1 (stable):
 
 Gio:
-* Derive all interfaces directly from Glib::Interface
-  (Kjell Ahltedt) Bug #776537
-* Application: OptionType: Make this an enum class.
-  (Kjell Ahlstedt)
-* BufferedInputStream, BufferedOutputStream, DataOutputStream:
-  Implement Seekable.
-* CharsetConverter: Implement the Gio::Initable interface.
-  and call Initable::init() from CharsetConverter's constructor.
-  (Kjell Ahlstedt) Bug #776537
-* Add FileDescriptorBased interface and make GUnixInputStream and
-  GUnixOutputStream implement it.
-* MemoryInputStream, UnixInputStream: Implement PollableInputStream.
-  (Kjell Ahlstedt)
-* MemoryOutputStream, UnixOutputStream: Implement PollableOutputStream.
-  (Kjell Ahlstedt)
-* TlsDatabase: create_certificate_handle_vfunc():
-  Fix memory leak, and correctly return nulltpr.
+* TlsDatabase: Fix memory leak in a vfunc.
   (Kjell Ahlstedt) Bug #783360
 
-gmmproc:
-* Accept curly braces in default values in _WRAP macros
-  (Khell Ahlstedt) Bug #783216 comment 13
-* Don't accept unpaired double quotes.
-  (Khell Ahlstedt)
-* gmmproc: Fix _WRAP_ENUM for enumerators with apostrophes.
-  (Khell Ahlstedt)
-* gmmproc, _WRAP_ENUM: Add optional CONV_TO_INT parameter.
-  (Khell Ahlstedt)
-
-Build:
-* Change the ABI to glibmm-2.56.
-  (Murray Cumming)
-* Really exclude DesktopAppInfo from wrap_init.cc on MacOS.
-  (Kjell Ahlstedt) Bug #781947
-
 Documentation:
-* miscutils: Update docs of get_*_name() from GLib.
+* Update docs of get_*_name().
   (Daniel Boles)
-* Fix documentation of enum Glib::IOCondition.
-  (Khell Ahlstedt)
 
+Build:
+* MacOS: Really correct build without gdesktopinfo.
+  (Kjell Ahlstedt) Bug #781947
 
-2.53.2 (unstable):
-Distro packagers should probably not package this yet.
-
-Glib:
-* ConstructParams: Do not increment allocation size twice
-  (Daniel Elstner)
+2.52.0 (stable):
 
 Gio:
-* ActionMap: Really fix add_action_with_parameter().
-  (Daniel Boles) Bug 774444#c31
-* UnixSocketAddress::create(): Remove a default value to avoid ambiguity.
+* UnixSocketAddress::create(): Remove the default value for the type
+  parameter to avoid ambiguity.
   (Kjell Ahlstedt) Bug #782592
 
 Gio::DBus
 * Proxy: Wrap call() and call_sync() methods.
   (Vyacheslav Yurkov) Bug #781818
 
-gmmproc:
-* Use of static_cast<> instead of C-style casts.
-  (Murray Cumming)
-
-Build:
-* Fix the build on MacOS, where glib doesn't have gdesktopinfo.
-  (John Ralls) Bug #781947
-* Really use desktopappinfo.hg to fix the build.
-  (Murray Cumming)
-
 Documentation:
-* Glib, Gio: Update documentation of in-class enums.
-  (Kjell Ahlstedt)
-* ActionMap: Improve add_action_with_parameter docs
+* RefPtr: Clarify comment about undefined behaviour.
   (Daniel Boles)
 
-
-2.53.1.1 (unstable):
+2.51.7 (unstable):
 
 Glib:
-* Use C++11 enum classes instead of old-style enums, and put many enums
-  inside relevant class declarations:
-  - Glib::NodeTree: Move enums into class.
-  - Glib::BindingFlags is now Glib::Binding::Flags.
-  - Glib::KeyfileFlags is now Glib::Keyfile::Flags.
-  - Glib::ModuleFlags is now Glib::Module::Flags.
-  - Glib::ChecksumType is now Glib::Checksum::Type.
-  - Glib::Regex: Move enums inside class.
-  - Glib::Resource: Move enums into class.
-  (Murray Cumming, Kjell Ahlstedt)
-* RefPtr: Make this an alias for std::shared_ptr<> instead.
-  - Use std::dynamic_pointer_cast<>() instead of RefPtr<>::cast_dynamic().
-  - Use std::static_pointer_cast<>() instead of RefPtr<>::cast_static().
-  - Use std::const_pointer_cast<>() instead of RefPtr<>::cast_const().
-  - When creating RefPtr directly, instead of using create() methods,
-    use Glib::make_refptr_for_instance() so the std::shared_ptr<> has the
-    necessary Deleter.
-  (Murray Cumming) Bug #755037
-* Remove Glib::WeakRef. Use std::weak_ref<> instead.
-  (Murray Cumming) Bug #755037
-* Object: Use g_object_new_with_properties() instead of (deprecated)
-  g_object_newv() and (deprecated) GParameter.
-  (Murray Cumming)
-* IOChannel: Avoid creating a RefPtr to this.
-  (Murray Cumming) Bug #755037
-* SignalProxy:
-  connect(): Signals with non-void return values now have no default value
-  for the "after" parameter, forcing application developers to think about
-  whether they should connect before or after already-connected signal
-  handlers, and default signal handlers. This is awkward but necessary.
-  Just provide "true" to get the previous behaviour, or use connect_notify().
-  connect_notify(): Signals with void return values have no connect_notify(),
-  because it is not useful with those signals.
-  (Kjell Ahlstedt) Bug #126213.
-
-Gio:
-* Use C++11 enum classes instead of old-style enums, and put many enums
-  inside relevant class declarations:
-  - Gio::Drive: Move enums into class.
-  - Gio::TlsDatabase: Move enums into class.
-  - Gio::UnixSocketAddressType is now Gio::UnixSocketAddress::Type.
-  - Gio::Mount: Move enums into class.
-  - Gio::TlsPasswordFlags is now Gio::TlsPassword::Flags.
-  - Gio::IOStreamSpliceFlags is now Gio::IOStream::SpliceFlags.
-  - Gio::SettingsBindFlags is now Gio::Settings::BindFlags.
-  - Gio::ResolverRecordType is now Gio::Resolver::RecordType.
-  - Gio::Socket: Move enums into class.
-  - Gio::File: Move some flags enums into the class.
-  - Gio::OutputStreamSpliceFlags is now Gio::OuputStream::SpliceFlags.
-  - Gio::CredentialsType is now Gio::Credentials::Type.
-  - Gio::NotificationPriority is now Gio::Notification::Priority.
-  - Gio::FileMonitorEvent is now Gio::FileMonitor::Event.
-  - Gio::FileAttributeInfoFlags is now Gio::FileAttributeInfo::Flags.
-  - Gio::EmblemOrigin is now Gio::Emblem::Origin.
-  - Gio::Converter: Put enums inside class.
-  - Gio::ConverterFlags is now Gio::Converter::Flags.
-  - Gio::ConverterResult is now Gio::Converter::Result.
-  - Gio::AppInfoCreateFlags is now Gio::AppInfo::CreateFlags.
-  - Gio::ApplicationFlags is now Gio::Application::Flags.
-  (Murray Cumming, Kjell Ahlstedt)
-* Remove duplicate ErrorEnum declaration.
-  (Kjell Ahlstedt)
-* ConstructParams:
-  - Remove (hopefully really unnecessary) copy constructor.
-  - C++11: =delete the operator=, instead of making it private.
-  (Murray Cumming)
-* Value:
-  - Remove the CType alias, which should be unnecessary.
-  - value_custom: Replace a template parameter with C++11 type traits.
-  - Value<RefPtr<T>>: Only use this specialization if T has get_base_type().
-  (Murray Cumming) Bug #755037
-* Variant:
-  - operator bool(): Simplify to avoid clang++ warnings.
-  - C++11: Variant: Replace throw(std::bad_cast) with noexcept(false).
-    See https://bugzilla.redhat.com/show_bug.cgi?id=1438766
-  (Murray Cumming)
-* Socket: Avoid creating a RefPtr to this.
-  (Murray Cumming) Bug #755037
-
-Gio:DBus:
-* Use C++11 enum classes instead of old-style enums, and put many enums
-  inside relevant class declarations:
-  - Gio::DBus::InterfaceSkeletonFlags is now Gio::DBus::InterfaceSkeleton::Flags.
-  - Gio::DBus::ServerFlags is now Gio::DBus::Server::Flags.
-  (Murray Cumming, Kjell Ahlstedt)
-
-gmmproc:
-* _WRAP_ENUM(): Generate C++ enum classes instead of enums, and let the enums
-  be inside class declarations.
-  (Kjell Ahlstedt) Bug #86864
-
-Build
-* Windows:  Visual Studio builds: Update ABI version
-  (Chun-wei Fan)
-
-
-2.53.1 (unstable):
-
-Glib:
-* OptionGroup:
-  - Don't allow copy or move.
-  - Remove the OptionGroup& parameter in on_pre_parse(), on_post_parse() and
-    on_error().
-  (Kjell Ahlstedt)
-* IOChannel, StreamIOChannel: Remove deprecated parts.
-  (Kjell Ahlstedt)
-* ustring: Add make_valid().
-  (Krzysztof Piecuch) Bug #780075
-* Remove (unused) Sequence and sequence().
-  (Murray Cumming)
-* Remove ListHandle, SListHandle, ArrayHandle, SArrayHandle, and
-  StringArrayHandle, replacing them with std::vector in API.
-  (Murray Cumming)
-
-gmmproc:
-* _WRAP_METHOD(): Some more use of auto in generated code.
-  (Murray Cumming)
-
-Build:
-* Change the ABI to glibmm-2.54.
+* SettingsSchemaKey: Add missing value/range methods.
+  (Daniel Boles) Bug #774903
+* Variant: Replace throw(std::bad_cast) with noexcept(false),
+  to fix the build with C++17.
+  See https://bugzilla.redhat.com/show_bug.cgi?id=1438766
   (Murray Cumming)
-* Add some #include directives.
-  (Kjell Ahlstedt)
-* Visual Studio: Require Visual Studio 2017 and update the glibmm project.
-  (Chu-wei Fan)
-
-
-2.51.5
-
-Gio:
-* Application: get_default(): Correct the reference counting.
-  (KJell Ahlstedt) Bug #779936 (James Legg)
-* Add PropertyAction.
-  (Kjell Ahlstedt)
-
-Glib:
-* Remove Glib::unconst() because it is unused and unnecessary.
-  (Kjell Ahlstedt)
-* Variant: Add template specialization for std::tuple,
-  and a test.
-  (Alexander Rössler, Kjell Ahlstedt) Bug #777791
-
-
-2.51.2 (unstable):
-Distro packagers should probably not package this yet.
-
-Glib:
-* Object construction: Add custom class init and instance init functions
-  An extra class init function is useful in Gtk::WidgetCustomDraw and
-  Gtk::WidgetCustomSnapshot.
-  (Kjell Ahlstedt) Bug #775348
-
-Gio:
-* Action: #include <glibmm/variant.h>, for convenience.
-  (Daniel Boles) Bug #777953
-* SimpleAction: Make set_state() public.
-  (Daniel Boles) Bug #777953
-
-Documentation:
-* Glib::Variant: Explain how to create "maybe" type.
-  (Daniel Boles) Bug #778219
-
-
-2.51.1.2 (unstable):
-Distro packagers should probably not package this yet.
-
-Glib:
-* Remove some deprecated API
-  (Kjell Ahlstedt)
-* Variant: Remove the string specializations of cast_dynamic.
-  (Kjell Ahlstedt)
-* Glib::VariantType: Add get_item_types(), removing first() and
-  next().
+* VariantType: Deprecate first() and next(). Add get_item_types()
   (Kjell Ahlstedt) Bug #775741
 
-
 Gio:
-* init(): Set the global locale.
-  (Kjell Ahlstedt) Bug #661588
-* ActionBase: get_state_hint_variant() now returns VariantContainerBase.
-  (Kjell Ahlstedt)
-* ActionMap: add_action_with_parameter(): Register the parameter type,
-  to make this work.
-  (Daniel Boles) Bug #774444
-* ActionResult: Add is_tagged_vfunc().
-  (Kjell Ahlstedt)
-* Glib::Dispatcher: Implement the pimpl idiom
-  (Kjell Ahlstedt) Bug #651942
-* File, FileInfo, FileIOStream, FileOutputStream: Use Glib::ustring for
-  (UTF-8) file attributes of string type.
-  (Kjell Ahlstedt) Bug #615950
-* NetworkMonitor: Derive from Gio::Initable.
-  (Kjell Ahlstedt)
-* RemoteActionGroup: Rename some vfuncs to add _full().
-  (Murray Cumming)
-
-Documentation:
-* ActionMap:
-  - ActivateSlot: Mention add_action_bool().
-  - ActivateWithParameterSlot: Be more specific.
+* ActionMap: Add add_action_with_parameter() that takes a parameter type,
+  and deprecated the existing method, because it cannot work.
   (Daniel Boles) Bug #774444
+* SimpleAction: Make set_state() public.
+  (Daniel Boles) Bug #777953
 
 Build:
-* Update the Visual Studio project files.
-  (Chun-wei Fan)
-* Some minor cppcheck fixes.
-  (Murray Cumming)
+* MacOS: Correct build without gdesktopinfo.
+  (John Ralls) Bug #781947
+* Glib::Object: Suppress deprecation warning for g_object_newv() with glib 2.54.
+  (Kjell Ahlstedt)
 
 
-2.51.1.1 (unstable):
+2.51.6 (unstable):
 
-General:
-* Remove no_default_handler in some _WRAP_SIGNAL()s
-  This allows application developers to simply override
-  the default on_*() signal handlers for these signals too,
-  as they can already with most other signals.
-  If you are using, for instance, the -Wsuggest-override
-  compiler option, watch out for new compiler warnings suggesting
-  that your existing signal handler should now be marked with the
-  override keyword - that means you should do so but you should
-  also stop connecting the signal handler in your code.
-  (Kjell Ahlstedt)
-* Build: examples/Makefile.am: Re-insert the dispatcher examples
-  (Kjell Ahlstedt)
+This is version 2.51.6 of glibmm-2.24. Ignore versions 2.51.1 to 2.51.5 of
+unstable glibmm-2.52. Unstable glibmm-2.52 is now unstable glibmm-2.54,
+leaving the 2.51/52 version numbers again for use by stable glibmm-2.52.
 
 Glib:
-* Dispatcher: Don't cast a HANDLE to an int on Windows.
+* Dispatcher:
+  - autodeduce the type of the fd field.
+  (Marcin Kolny) Bug #772074
+  - Don't cast a HANDLE to an int on Windows.
   (Kjell Ahlstedt) Bug #772074
-* ObjectBase:
-  - Remove connect_property_changed_with_return()
-  and let connect_property_changed() return a sigc::connection.
-  (Kjell Ahlstedt)
-  - Use std::forward_list for interface class pointers.
-  (Kjell Ahlstedt)
-  - Replace extra_object_base_data map by instance data.
-  (Kjell Ahlstedt)
-* ObjectBase: overload get_property().
-  (Marcin Kolny)
-* Main, IOSource: autodeduce type of fd field.
-  (Marcin Kolny) Bug #770274
-* Settings: Add property_settings_schema(), and update
-  signal_changed().
-  (Kjell Ahlstedt)
-* Settings: Make set_enum() + set_flags() usable
-  (djb) Bug #774647
-* SettingsSchemaKey: Add missing value/range methods
-  (Daniel Boles) Bug #774903
-* SignalProxyNormal: Remove connect_() and connect_notify_(),
-  adding connect_impl().
-  (Kjell Ahlstedt)
-* Rename SignalProxyDetailed to SignalProxyDetailedBase, and
-  SignalProxyDetailedAnyType to SignalProxyDetailed.
-  Remove SignalProxyDetailed# aliases (# = 0..6).
-  (Kjell Ahlstedt)
-* Source: Replace extra_source_data by instance data.
-  (Kjell Ahlstedt) Bug #561885
+* ustring: Add cbegin() and cend().
+  (Murray Cumming)
 
 Gio:
-* ActionMap::add_action_vfunc(): Const correction.
-  (Murray Cumming)
-* Application: Add dbus_register/unregister_vfunc.
-  (Ritesh Khadgaray, Kjell Ahlstedt) Bug #762191
-* Menu: insert/prepend/add_item(): Const correction.
-  (Murray Cumming)
-* MenuAttributeIter: get_value(): Const correction.
-  (Murray Cumming)
-* MenuModel: get_item_atribute(): const correction.
-  (Murray Cumming)
-* RemoteActionGroup: Derive from Gio::ActionGroup.
-  (Murray Cumming)
+* Action: Include variant.h in the heaer.
+  (Daniel Boles) Bug #777953
+* Application: get_default(): Correct the reference counting.
+  (Kjell Ahlstedt) Bug #779936
+* Settings:
+  - Really add set_enum() and set_flags().
+  (djb) Bug #774647
+  - Writable-change-event signal: Correct the type of the key parameter.
+  (Marcin Kolny) Bug #773977
+* SettingsSchemaSource: get_default(): Correct the refcounting.
+  (Marcin Kolny) Bug #774593
 
-Gio::Dbus:
+Gio::DBus:
 * Proxy: Fix memory leak in get_cached_property_names().
   (Kjell Ahlstedt) Bug #775210
-* Proxy: Derive from (and implement) Gio::DBus::Interface.
-  (Murray Cumming)
-
 
-2.51.1 (unstable):
-
-This is the first release of the glibmm-2.52 API/ABI.
-It installs in parallel with the gtkmm-2.4 API/ABI, of which
-the most recent version is glibmm 2.50. We know that is a bit
-confusing. We are taking the opportunity to do this glibmm ABI
-break while GTK+ (and therefore gtkmm) is also doing an ABI
-break. But we cannot call this glibmm-3.0 because there is no
-glib 3.0.
+Documentation:
+* Glib::Variant: Improve documentation of maybe types.
+  (Daniel Boles) Bug #778219
+* Gio::ActionMap: Clarify doc of ActivateWithParameterSlot
+  (Daniel Boles)
 
 Build:
-* Require C++14.
-  (Murray Cumming)
-* Use libsigc++-3.0 instead of libsigc++-2.0.
-  https://www.murrayc.com/permalink/2016/03/07/libsigc-3-0-very-variadic/
-  (Murray Cumming)
-* Remove lots of deprecated API.
-  (Kjell Ahlstedt)
-
-Gio:
-* BufferedInputStream, InputStream, OutputStream: Add vfuncs,
-  allowing implementation in C++.
-  (Krzysztof KosiÅ„ski, Kjell Ahlstedt) Bug #572471
-* SettingsSchemaSource::get_default(): Correct the reference count.
-  (Marcin Kolny) Bug #774593
-* Settings: Fix type of 'key' parameter of writable-change-event signal
-  (Marcin Kolny) Bug #773977
-
-Glib:
-* ustring: Add cbegin() and cend().
+* Visual Studio builds: "Install" the .pdb files
+  (Chun-wei Fan)
 
 
 2.50.0:
@@ -688,7 +413,7 @@ gmmproc:
 * Remove DocsParser::non_object_method_name()
   (Kjell Ahlstedt)
 * swap() implementations: Use std::swap().
-  (Murray Cumming)
+  (Murray Cumming <murrayc@murrayc.com>
 
 Documentation:
 * Gio::SocketService: Update the class documentation
diff --git a/README b/README
index ba84b33..60bcd05 100644 (file)
--- a/README
+++ b/README
@@ -1,12 +1,92 @@
 This is glibmm, a C++ API for parts of glib that are useful for C++.
 See http://www.gtkmm.org
 
-Installation Procedure
-----------------------
+# Building
 
-$ tar xf glibmm-@GLIBMM_VERSION@.tar.gz
-$ cd glibmm-@GLIBMM_VERSION@
-$ ./configure --prefix=/some_directory
-$ make
-$ make install
+Whenever possible, you should use the official binary packages approved by the
+supplier of your operating system, such as your Linux distribution.
 
+## Building on Windows
+
+See README.win32
+
+## Building from a release tarball
+
+Extract the tarball and go to the extracted directory:
+  $ tar xf glibmm-@GLIBMM_VERSION@.tar.gz
+  $ cd glibmm-@GLIBMM_VERSION@
+
+It's easiest to build with Meson, if the tarball was made with Meson,
+and to build with Autotools, if the tarball was made with Autotools.
+Then you don't have to use maintainer-mode.
+
+How do you know how the tarball was made? If it was made with Meson,
+it contains files in untracked/glib/glibmm/, untracked/gio/giomm/ and
+other subdirectories of untracked/.
+
+### Building from a tarball with Meson
+
+Don't call the builddir 'build'. There is a directory called 'build' with
+files used by Autotools.
+
+  $ meson --prefix /some_directory --libdir lib your_builddir .
+  $ cd your_builddir
+
+If the tarball was made with Autotools, you must enable maintainer-mode:
+  $ meson configure -Dmaintainer-mode=yes
+
+Then, reguardless of how the tarball was made:
+  $ ninja
+  $ ninja install
+You can run the tests like so:
+  $ ninja test
+
+### Building from a tarball with Autotools
+
+If the tarball was made with Autotools:
+  $ ./configure --prefix=/some_directory
+If the tarball was made with Meson, you must enable maintainer-mode:
+  $ ./autogen.sh --prefix=/some_directory
+
+Then, reguardless of how the tarball was made:
+  $ make
+  $ make install
+You can build the examples and tests, and run the tests, like so:
+  $ make check
+
+## Building from git
+
+Building from git can be difficult so you should prefer building from
+a release tarball unless you need to work on the glibmm code itself.
+
+jhbuild can be a good help
+  https://gitlab.gnome.org/GNOME/jhbuild
+  https://wiki.gnome.org/Projects/Jhbuild
+
+### Building from git with Meson
+
+Maintainer-mode is enabled by default when you build from a git clone.
+
+Don't call the builddir 'build'. There is a directory called 'build' with
+files used by Autotools.
+
+  $ meson --prefix /some_directory --libdir lib your_builddir .
+  $ cd your_builddir
+  $ ninja
+  $ ninja install
+You can run the tests like so:
+  $ ninja test
+You can create a tarball like so:
+  $ ninja dist
+
+### Building from git with Autotools
+
+  $ ./autogen.sh --prefix=/some_directory
+  $ make
+  $ make install
+You can build the examples and tests, and run the tests, like so:
+  $ make check
+You can create a tarball like so:
+  $ make distcheck
+or
+  $ make dist
index 468bbbd..62bcea3 100644 (file)
@@ -2,7 +2,7 @@ Building glibmm on Win32
 ===========================\r
 \r
 Currently, both the mingw (native win32) gcc compiler and MS Visual\r
-Studio 2017 and later are supported. glibmm can be built with\r
+Studio 2015 and later are supported. glibmm can be built with\r
 mingw32-gcc using the gnu autotools (automake, autoconf, libtool).\r
 As explicitly stated in the gtk+ for win32 distribution\r
 (http://www.gimp.org/win32/), the gcc compiler provided by the cygwin\r
@@ -28,7 +28,7 @@ that were mentioned above) with mingw by making sure that the mingw
 tools (gcc, ld, dlltool, ..) are called first.\r
 \r
 First, make sure that you have working distribution of the native port\r
-of both libsigc++-3.0.x and glib-2.0 on win32 (see\r
+of both libsigc++-2.10.x and glib-2.0 on win32 (see\r
 http://www.gimp.org/win32). If you can't compile a simple glib example\r
 using gcc and `pkg-config --cflags --libs`, you should not even think\r
 about trying to compile glibmm, let alone using precompiled libglibmm\r
@@ -45,21 +45,62 @@ make
 make check\r
 make install\r
 \r
-2. MS Visual Studio 2017\r
+2. MS Visual Studio 2015\r
 \r
 In a Visual Studio command prompt, navigate to the MSVC_NMake directory.\r
 Run 'nmake /f Makefile.vc CFG=[release|debug]' to build the glibmm and\r
 giomm DLLs, along with their example programs.  If a prefix other than\r
-$(srcroot)\..\vs15\$(Platform) is desired, pass in PREFIX=$(your_prefix)\r
+$(srcroot)\..\vs$(VSVER)\$(Platform) is desired, pass in PREFIX=$(your_prefix)\r
 in the NMake command line.  In order to build the giomm settings example\r
 program, the glib-compile-schemas needs to reside in $(PREFIX)\bin, or\r
-it must be specified via passing in GLIB_COMPILE_SCHEMAS.\r
+it must be specified via passing in GLIB_COMPILE_SCHEMAS.  If you are using\r
+C++ dependencies that are built with Meson, specify USE_MESON_LIBS=1 in\r
+your NMake command line.\r
+\r
+Note that $(VSVER) refers to 14 for Visual Studio 2015 and 15 for Visual\r
+Studio 2017.\r
 \r
 A 'tests' target will build the test programs for glibmm and giomm, an\r
 'install' target is provided to copy the built DLLs and LIBs, along with\r
 with the public headers to appropriate subdirs of $(PREFIX).  A 'clean'\r
 target is also provided to remove all the built files.\r
 \r
+The NMake Makefiles now support building the glibmm libraries directly from a GIT checkout\r
+with a few manual steps required, namely to:\r
+\r
+-Ensure that you have a copy of Cygwin or MSYS/MSYS64 installed, including\r
+ m4.exe and sh.exe.  You should also have a PERL for Windows installation\r
+ as well, and your PATH should contain the paths to your PERL interpreter\r
+ and the bin\ directory of your Cygwin or MSYS/MSYS64 installation, and\r
+ it is recommended that these paths are towards the end of your PATH.  You need\r
+ to install the XML::Parser PERL module as well, which requires libexpat.\r
+\r
+-Make a new copy of the entire source tree to some location, where the build\r
+ is to be done; then in $(srcroot)\MSVC_NMake run\r
+ nmake /f Makefile.vc CFG=[release|debug] prep-git-build, which will copy and generate\r
+ the following files with the proper info (this step may also be needed if the following\r
+ files are not present in the unpacked source tarball):\r
+ --$(srcroot)\MSVC_NMake\glibmm\glibmmconfig.h\r
+ --$(srcroot)\MSVC_NMake\giomm\giommconfig.h\r
+ --$(srcroot)\MSVC_NMake\glibmm\glibmm.rc\r
+ --$(srcroot)\MSVC_NMake\giomm\giomm.rc\r
+ --$(srcroot)\tools\gmmproc\r
+ --$(srcroot)\tools\generate_wrap_init.pl\r
+\r
+After copying the above 6 files, you need to ensure that they reflect on the package version\r
+that best matches your checkout status and the paths in $(srcroot)\tools\gmmproc and\r
+$(srcroot)\tools\generate_wrap_init.pl (the items enclosed between the @...@'s) should reflect\r
+on where you intend for nmake /f Makefile.vc CFG=$(CFG) install to install to (i.e. $(PREFIX)).\r
+For giommconfig.h, it is recommended to keep GIOMM_STATIC_LIB and GIOMM_DISABLE_DEPRECATED\r
+undefined unless you know what you are doing (remember, the NMake Makefiles only support DLL\r
+builds out-of-the-box).  For builds from the release tarballs, running\r
+nmake /f Makefile.vc CFG=[release|debug] gen-perl-scripts-real will also generate\r
+$(srcroot)\tools\gmmproc and $(srcroot)\tools\generate_wrap_init.pl for you.\r
+\r
+Note that the prep-git-build and the gen-perl-scripts-real targets will require a working PERL\r
+installation.\r
+\r
+\r
 3. Glibmm methods and signals not available on win32\r
 \r
 All glibmm methods and signals are available on win32.\r
diff --git a/build/c_std.m4 b/build/c_std.m4
new file mode 100644 (file)
index 0000000..f985023
--- /dev/null
@@ -0,0 +1,54 @@
+## Copyright (c) 2009, 2011  Openismus GmbH  <http://www.openismus.com/>
+##
+## This file is part of glibmm.
+##
+## glibmm 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.
+##
+## glibmm 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 <http://www.gnu.org/licenses/>.
+
+#serial 20120912
+
+## GLIBMM_C_STD_TIME_T_IS_NOT_INT32
+##
+## Test whether std::time_t and gint32 are typedefs of the same builting type.
+## If they aren't then they can be used for method overload.  In that case
+## GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32 is defined to 1.
+##
+AC_DEFUN([GLIBMM_C_STD_TIME_T_IS_NOT_INT32],
+[
+  AC_CACHE_CHECK(
+    [whether std::time_t is not equivalent to gint32, meaning that it can be used for a method overload],
+    [glibmm_cv_c_std_time_t_is_not_int32],
+  [
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+    [[
+      #include <ctime>
+    ]],[[
+      typedef signed int gint32;
+      class Test
+      {
+        void something(gint32 val)
+        {}
+
+        void something(std::time_t val)
+        {}
+      };
+    ]])],
+      [glibmm_cv_c_std_time_t_is_not_int32='yes'],
+      [glibmm_cv_c_std_time_t_is_not_int32='no']
+    )
+  ])
+
+  AS_VAR_IF([glibmm_cv_c_std_time_t_is_not_int32], ['yes'],
+            [AC_DEFINE([GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32], [1],
+                       [Defined when std::time_t is not equivalent to gint32, meaning that it can be used for a method overload])])[]dnl
+])
index 7fcf730..718c7c6 100644 (file)
 
 #serial 20110910
 
+## GLIBMM_CXX_MEMBER_FUNCTIONS_MEMBER_TEMPLATES
+##
+## Test whether the compiler allows member functions to refer to spezialized
+## member function templates.  Some compilers have problems with this.  GCC
+## 2.95.3 aborts with an internal compiler error.
+##
+AC_DEFUN([GLIBMM_CXX_MEMBER_FUNCTIONS_MEMBER_TEMPLATES],
+[dnl
+AC_CACHE_CHECK(
+  [whether C++ member functions may refer to member templates],
+  [glibmm_cv_cxx_member_functions_member_templates],
+  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[
+struct foo
+{
+  template <class C> inline void doit();
+  void thebug();
+};
+
+template <class C>
+inline void foo::doit()
+{}
+
+struct bar
+{
+  void neitherabug();
+};
+
+void bar::neitherabug()
+{
+  void (foo::*func)();
+  func = &foo::doit<int>;
+  (void)func;
+}
+
+void foo::thebug()
+{
+  void (foo::*func)();
+  func = &foo::doit<int>; // the compiler bugs usually show here
+  (void)func;
+}
+]], [[
+void (foo::*func)();
+func = &foo::doit<int>;
+(void)func;
+]])],
+    [glibmm_cv_cxx_member_functions_member_templates=yes],
+    [glibmm_cv_cxx_member_functions_member_templates=no])])
+
+AS_VAR_IF([glibmm_cv_cxx_member_functions_member_templates], ['yes'],
+          [AC_DEFINE([GLIBMM_MEMBER_FUNCTIONS_MEMBER_TEMPLATES], [1],
+                     [Define if C++ member functions may refer to member templates.])])[]dnl
+])
+
 ## GLIBMM_CXX_CAN_DISAMBIGUATE_CONST_TEMPLATE_SPECIALIZATIONS
 ##
 ## Check whether the compiler finds it ambiguous to have both const and
@@ -136,3 +190,70 @@ AS_VAR_IF([glibmm_cv_cxx_can_assign_non_extern_c_functions_to_extern_c_callbacks
           [AC_DEFINE([GLIBMM_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS], [1],
                      [Define if extern "C" and extern "C++" function pointers are compatible.])])[]dnl
 ])
+
+## GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
+##
+## Check whether the compiler puts extern "C" functions in the global
+## namespace, even inside a namespace declaration. The AIX xlC compiler does
+## this, and also gets confused if we declare the namespace again inside the
+## extern "C" block.  This seems like a compiler bug, but not a serious one.
+##
+## It is debatable whether it is a bug at all, since the namespace would only
+## exist at the compiler level anyway, but not be a part of the exported
+## symbol name.  (For the functions in question, it was my fault not to add
+## the namespace prefix to the function name.  Sorry. --danielk)
+##
+AC_DEFUN([GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC],
+[dnl
+AC_CACHE_CHECK(
+  [whether the compiler honors namespaces inside extern "C" blocks],
+  [glibmm_cv_cxx_can_use_namespaces_inside_externc],
+  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[
+namespace test
+{
+
+extern "C" { void do_something(); }
+
+class Something
+{
+  int i;
+  friend void do_something();
+};
+
+void do_something()
+{
+  Something something;
+  something.i = 1;
+}
+
+} // namespace test
+]], [])],
+    [glibmm_cv_cxx_can_use_namespaces_inside_externc=yes],
+    [glibmm_cv_cxx_can_use_namespaces_inside_externc=no])])
+
+AS_VAR_IF([glibmm_cv_cxx_can_use_namespaces_inside_externc], ['yes'],
+          [AC_DEFINE([GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC], [1],
+                     [Define if the compiler honors namespaces inside extern "C" blocks.])])[]dnl
+])
+
+## GLIBMM_CXX_CAN_USE_THREAD_LOCAL
+##
+## Check for thread_local support
+##
+AC_DEFUN([GLIBMM_CXX_CAN_USE_THREAD_LOCAL],
+[dnl
+AC_CACHE_CHECK(
+  [whether the thread_local keyword is supported],
+  [glibmm_cv_cxx_can_use_thread_local],
+  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[
+thread_local int i=0;
+]], [])],
+    [glibmm_cv_cxx_can_use_thread_local=yes],
+    [glibmm_cv_cxx_can_use_thread_local=no])])
+
+AS_VAR_IF([glibmm_cv_cxx_can_use_thread_local], ['yes'],
+          [AC_DEFINE([GLIBMM_CAN_USE_THREAD_LOCAL], [1],
+                     [Define if the thread_local keyword is supported.])])[]dnl
+])
index 06d3c76..a7bfab5 100644 (file)
 
 #serial 20110910
 
+## GLIBMM_CXX_HAS_NAMESPACE_STD()
+##
+## Test whether libstdc++ declares namespace std.  For safety,
+## also check whether several randomly selected STL symbols
+## are available in namespace std.
+##
+## On success, #define GLIBMM_HAVE_NAMESPACE_STD to 1.
+##
+AC_DEFUN([GLIBMM_CXX_HAS_NAMESPACE_STD],
+[
+  AC_CACHE_CHECK(
+    [whether C++ library symbols are declared in namespace std],
+    [glibmm_cv_cxx_has_namespace_std],
+  [
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+    [[
+      #include <algorithm>
+      #include <iterator>
+      #include <iostream>
+      #include <string>
+    ]],[[
+      using std::min;
+      using std::find;
+      using std::copy;
+      using std::bidirectional_iterator_tag;
+      using std::string;
+      using std::istream;
+      using std::cout;
+    ]])],
+      [glibmm_cv_cxx_has_namespace_std='yes'],
+      [glibmm_cv_cxx_has_namespace_std='no']
+    )
+  ])
+
+  AS_VAR_IF([glibmm_cv_cxx_has_namespace_std], ['yes'],
+            [AC_DEFINE([GLIBMM_HAVE_NAMESPACE_STD], [1],
+                       [Defined when the libstdc++ declares the std-namespace])])[]dnl
+])
+
+
 ## GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS()
 ##
 ## Check for standard-conform std::iterator_traits<>, and
@@ -24,6 +64,8 @@
 ##
 AC_DEFUN([GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS],
 [
+  AC_REQUIRE([GLIBMM_CXX_HAS_NAMESPACE_STD])
+
   AC_CACHE_CHECK(
     [whether the C++ library supports std::iterator_traits],
     [glibmm_cv_cxx_has_std_iterator_traits],
@@ -31,7 +73,9 @@ AC_DEFUN([GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS],
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
     [[
       #include <iterator>
+      #ifdef GLIBMM_HAVE_NAMESPACE_STD
       using namespace std;
+      #endif
     ]],[[
       typedef iterator_traits<char*>::value_type ValueType;
     ]])],
@@ -53,6 +97,8 @@ AC_DEFUN([GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS],
 ##
 AC_DEFUN([GLIBMM_CXX_HAS_SUN_REVERSE_ITERATOR],
 [
+  AC_REQUIRE([GLIBMM_CXX_HAS_NAMESPACE_STD])
+
   AC_CACHE_CHECK(
     [for non-standard Sun libCstd reverse_iterator],
     [glibmm_cv_cxx_has_sun_reverse_iterator],
@@ -60,7 +106,9 @@ AC_DEFUN([GLIBMM_CXX_HAS_SUN_REVERSE_ITERATOR],
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
     [[
       #include <iterator>
+      #ifdef GLIBMM_HAVE_NAMESPACE_STD
       using namespace std;
+      #endif
     ]],[[
       typedef reverse_iterator<char*,random_access_iterator_tag,char,char&,char*,int> ReverseIter;
     ]])],
@@ -82,6 +130,8 @@ AC_DEFUN([GLIBMM_CXX_HAS_SUN_REVERSE_ITERATOR],
 ##
 AC_DEFUN([GLIBMM_CXX_HAS_TEMPLATE_SEQUENCE_CTORS],
 [
+  AC_REQUIRE([GLIBMM_CXX_HAS_NAMESPACE_STD])
+
   AC_CACHE_CHECK(
     [whether STL containers have templated sequence constructors],
     [glibmm_cv_cxx_has_template_sequence_ctors],
@@ -91,7 +141,9 @@ AC_DEFUN([GLIBMM_CXX_HAS_TEMPLATE_SEQUENCE_CTORS],
       #include <vector>
       #include <deque>
       #include <list>
+      #ifdef GLIBMM_HAVE_NAMESPACE_STD
       using namespace std;
+      #endif
     ]],[[
       const int array[8] = { 0, };
       vector<int>  test_vector (&array[0], &array[8]);
@@ -117,6 +169,8 @@ AC_DEFUN([GLIBMM_CXX_HAS_TEMPLATE_SEQUENCE_CTORS],
 ##
 AC_DEFUN([GLIBMM_CXX_ALLOWS_STATIC_INLINE_NPOS],
 [
+  AC_REQUIRE([GLIBMM_CXX_HAS_NAMESPACE_STD])
+
   AC_CACHE_CHECK(
     [whether the compiler allows a static member variable to be initialized inline to std::string::npos],
     [glibmm_cv_cxx_has_allows_static_inline_npos],
diff --git a/build/sun.m4 b/build/sun.m4
new file mode 100644 (file)
index 0000000..8eb1152
--- /dev/null
@@ -0,0 +1,34 @@
+## Copyright (c) 2009, 2011  Openismus GmbH  <http://www.openismus.com/>
+##
+## This file is part of glibmm.
+##
+## glibmm 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.
+##
+## glibmm 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 <http://www.gnu.org/licenses/>.
+
+#serial 20110910
+
+AC_DEFUN([GLIBMM_PROG_CXX_SUN],
+[
+  AC_CACHE_CHECK([whether we are using SUN CC compiler],
+                 [glibmm_cv_prog_sun_cxx],
+                 [AS_IF([${CXX-g++} -V 2>&1 | grep -e 'Sun WorkShop' >/dev/null 2>&1],
+                        [glibmm_cv_prog_sun_cxx='yes'],
+                        [glibmm_cv_prog_sun_cxx='no']
+                       )
+                 ]
+                )
+
+  AS_VAR_IF([glibmm_cv_prog_sun_cxx], ['yes'],
+            [AC_DEFINE([GLIBMM_COMPILER_SUN_FORTE], [1],
+                       [Defined when the SUN Forte C++ compiler is being used.])])[]dnl
+])
index 6ebc1e1..8cc53c8 100644 (file)
@@ -15,7 +15,7 @@
 ## You should have received a copy of the GNU Lesser General Public License
 ## along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_INIT([glibmm], [2.63.1],
+AC_INIT([glibmm], [2.64.0],
         [https://gitlab.gnome.org/GNOME/glibmm/issues],
         [glibmm], [http://www.gtkmm.org/])
 AC_PREREQ([2.59])
@@ -30,9 +30,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 AM_MAINTAINER_MODE
 AC_ARG_VAR([ACLOCAL_FLAGS], [aclocal flags, e.g. -I <macro dir>])
 
-MM_PREREQ([0.9.12])
-MM_INIT_MODULE([glibmm-2.64])
-MM_INIT_MODULE([giomm-2.64])
+MM_PREREQ([0.9.10])
+MM_INIT_MODULE([glibmm-2.4])
+MM_INIT_MODULE([giomm-2.4])
 
 # Copy the mm-common .pl scripts into docs/,
 # and use them from there,
@@ -43,7 +43,7 @@ MM_CONFIG_DOCTOOL_DIR([docs])
 AC_SUBST([LIBGLIBMM_SO_VERSION], [4:0:3])
 
 AC_PROG_CXX
-MM_AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
+MM_AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory])
 
 AC_DISABLE_STATIC
 LT_INIT([win32-dll])
@@ -84,7 +84,7 @@ AS_IF([test "x$enable_static" = xyes],
 
 glibreq='2.0 >= 2.61.2'
 
-GLIBMM_MODULES="sigc++-3.0 >= 2.99.5 glib-$glibreq gobject-$glibreq gmodule-$glibreq"
+GLIBMM_MODULES="sigc++-2.0 >= 2.9.1 glib-$glibreq gobject-$glibreq gmodule-$glibreq"
 GIOMM_MODULES="$GLIBMM_MODULES gio-$glibreq"
 test "x$glibmm_host_windows" = xyes || GIOMM_MODULES="$GIOMM_MODULES gio-unix-$glibreq"
 
@@ -94,6 +94,10 @@ PKG_CHECK_MODULES([GIOMM],  [$GIOMM_MODULES])
 AC_CHECK_PROGS([M4], [gm4 m4], [m4])
 GLIB_GSETTINGS
 
+# Check for the SUN Forte compiler, and define GLIBMM_COMPILER_SUN_FORTE
+# in the header.
+GLIBMM_PROG_CXX_SUN
+
 AC_CHECK_FUNCS([flockfile funlockfile getc_unlocked mkfifo])
 
 # Ensure MSVC-compatible struct packing convention is used when
@@ -114,14 +118,18 @@ DK_CHECK_FEATURE([wide stream],
 GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS
 GLIBMM_CXX_HAS_SUN_REVERSE_ITERATOR
 GLIBMM_CXX_HAS_TEMPLATE_SEQUENCE_CTORS
+GLIBMM_CXX_MEMBER_FUNCTIONS_MEMBER_TEMPLATES
 GLIBMM_CXX_CAN_DISAMBIGUATE_CONST_TEMPLATE_SPECIALIZATIONS
 GLIBMM_CXX_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
 GLIBMM_CXX_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS
+GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
 GLIBMM_CXX_ALLOWS_STATIC_INLINE_NPOS
+GLIBMM_CXX_CAN_USE_THREAD_LOCAL
+GLIBMM_C_STD_TIME_T_IS_NOT_INT32
 
 MM_ARG_ENABLE_DOCUMENTATION
 MM_ARG_WITH_TAGFILE_DOC([libstdc++.tag], [mm-common-libstdc++])
-MM_ARG_WITH_TAGFILE_DOC([libsigc++-3.0.tag], [sigc++-3.0])
+MM_ARG_WITH_TAGFILE_DOC([libsigc++-2.0.tag], [sigc++-2.0])
 
 # Check whether --enable-debug-refcounting was given.
 GLIBMM_ARG_ENABLE_DEBUG_REFCOUNTING
@@ -136,6 +144,12 @@ MM_ARG_ENABLE_WARNINGS([GLIBMM_WXXFLAGS],
 # to reduce the code size:
 MM_ARG_DISABLE_DEPRECATED_API([GLIBMM GIOMM])
 
+# These are just defined to avoid breaking old code:
+AC_DEFINE([GLIBMM_EXCEPTIONS_ENABLED],[1], [This is always set. This is only for backwards compatibility.])
+AC_DEFINE([GLIBMM_PROPERTIES_ENABLED],[1], [This is always set. This is only for backwards compatibility.])
+AC_DEFINE([GLIBMM_VFUNCS_ENABLED],[1], [This is always set. This is only for backwards compatibility.])
+AC_DEFINE([GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED],[1], [This is always set. This is only for backwards compatibility.])
+
 AC_CHECK_PROGS([CLANG_FORMAT], [clang-format clang-format-3.9 clang-format-3.8 clang-format-3.7], [])
 AM_CONDITIONAL([HAVE_CLANG_FORMAT], test -n "$CLANG_FORMAT")
 
index 19364c6..9ac3ad8 100644 (file)
@@ -1,8 +1,8 @@
 web_host = gtkmm.org
-web_path_gtkmm = /home/murrayc/gtkmm.org/docs/glibmm-2.64/
-#web_path_gtkmm = /home/groups/g/gt/gtkmm/htdocs/docs/glibmm-2.64/
+web_path_gtkmm = /home/murrayc/gtkmm.org/docs/glibmm-2.4/
+#web_path_gtkmm = /home/groups/g/gt/gtkmm/htdocs/docs/glibmm-2.4/
 web_path_docs = $(web_path_gtkmm)docs/
 rsync_args = -vz --rsh ssh
 
-gtkmm_docdir = $(datadir)/doc/glibmm-2.64/docs
+gtkmm_docdir = $(datadir)/doc/glibmm-2.4/docs
 
index 5b4820c..51dec03 100644 (file)
@@ -303,7 +303,11 @@ PREDEFINED             = __cplusplus \
                          G_OS_WIN32 \
                          "GLIBMM_API=" \
                          "GIOMM_API=" \
-                         GLIBMM_HAVE_WIDE_STREAM
+                         GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED \
+                         GLIBMM_EXCEPTIONS_ENABLED \
+                         GLIBMM_HAVE_WIDE_STREAM \
+                         GLIBMM_PROPERTIES_ENABLED \
+                         GLIBMM_VFUNCS_ENABLED
 EXPAND_AS_DEFINED      = GLIBMM_MAJOR_VERSION \
                          GLIBMM_MINOR_VERSION \
                          GLIBMM_MICRO_VERSION \
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
new file mode 100644 (file)
index 0000000..e9582df
--- /dev/null
@@ -0,0 +1,170 @@
+# docs/reference
+
+# Input: built_files_root, project_source_root, glibmm_pcname, giomm_pcname,
+#        perl, glibmm_hg_ccg_basenames, giomm_hg_ccg_basenames,
+#        glibmm_extra_h_files, giomm_extra_h_files, glibmm_built_h_file_targets,
+#        giomm_built_h_file_targets, install_datadir, python3, doc_reference_py,
+#        build_documentation
+# Output: install_docdir, install_devhelpdir
+
+tag_file_modules = [
+  'mm-common-libstdc++',
+  'sigc++-2.0',
+]
+doxygen_tagfiles = ''
+docinstall_flags = []
+foreach module : tag_file_modules
+  depmod = dependency(module, required: false)
+  if depmod.found()
+    doxytagfile = depmod.get_pkgconfig_variable('doxytagfile')
+    htmlrefpub = depmod.get_pkgconfig_variable('htmlrefpub', default: '')
+    htmlrefdir = depmod.get_pkgconfig_variable('htmlrefdir', default: '')
+    if htmlrefpub == ''
+      htmlrefpub = htmlrefdir
+    elif htmlrefdir == ''
+      htmlrefdir = htmlrefpub
+    endif
+    doxygen_tagfiles += ' "' + doxytagfile + '=' + htmlrefpub + '"'
+    if not htmlrefdir.endswith('/')
+      htmlrefdir += '/'
+    endif
+    docinstall_flags += ['-l', doxytagfile.split('/')[-1] + '@' + htmlrefdir]
+  endif
+endforeach
+
+book_name = glibmm_pcname
+book_title = meson.project_name() + ' Reference Manual'
+
+# Configuration data for Doxyfile.
+doc_conf_data = configuration_data()
+doc_conf_data.set('configure_input',
+  'docs/reference/Doxyfile. Generated from Doxyfile.in by meson.configure_file().')
+doc_conf_data.set('PACKAGE_NAME', meson.project_name())
+doc_conf_data.set('PACKAGE_VERSION', meson.project_version())
+doc_conf_data.set('abs_top_builddir', built_files_root)
+doc_conf_data.set('abs_top_srcdir', project_source_root)
+doc_conf_data.set('GLIBMM_MODULE_NAME', book_name)
+doc_conf_data.set('DOXYGEN_TAGFILES', doxygen_tagfiles)
+doc_conf_data.set('PERL', perl.found() ? perl.path() : '')
+
+configure_file(
+  input: 'Doxyfile.in',
+  output: '@BASENAME@',
+  configuration: doc_conf_data,
+)
+
+# Installation directories relative to {prefix}.
+install_docdir = install_datadir / 'doc' / book_name
+install_reference_docdir = install_docdir / 'reference'
+install_image_docdir = install_docdir / 'images'
+install_devhelpdir = install_datadir / 'devhelp' / 'books' / book_name
+
+if not build_documentation
+  # Documentation shall not be built or installed.
+  # Return to the calling meson.build file.
+  subdir_done()
+endif
+
+# Built input .h files to Doxygen.
+built_h_files = []
+foreach file : glibmm_hg_ccg_basenames
+  built_h_files += built_files_root / 'glib' / 'glibmm' / file + '.h'
+endforeach
+foreach file : giomm_hg_ccg_basenames
+  built_h_files += built_files_root / 'gio' / 'giomm' / file + '.h'
+endforeach
+
+# Hand-coded input .h files to Doxygen.
+src_h_files = []
+foreach file : glibmm_extra_h_files
+  if file != 'wrap_init.h'
+    src_h_files += project_source_root / 'glib' / 'glibmm' / file
+  endif
+endforeach
+foreach file : giomm_extra_h_files
+  if file != 'wrap_init.h'
+    src_h_files += project_source_root / 'gio' / 'giomm' / file
+  endif
+endforeach
+src_h_files += project_source_root / 'glib' / 'glibmm.h'
+src_h_files += project_source_root / 'gio' / 'giomm.h'
+
+doctool_dir = project_source_root / 'untracked' / 'docs' # MMDOCTOOLDIR
+doctool_dist_dir = 'untracked' / 'docs' # Relative to MESON_DIST_ROOT
+
+doc_h_files = src_h_files
+if glibmm_built_h_file_targets.length() + giomm_built_h_file_targets.length() > 0
+  # .h files have been generated from .hg files (maintainer mode).
+  # Use built_h_file_targets instead of built_h_files here, or else Meson won't
+  # know that Doxygen must not be executed until the .h files have been built.
+  doc_h_files += glibmm_built_h_file_targets + giomm_built_h_file_targets
+else
+  # All .h files are stored in the source tree (not maintainer mode).
+  doc_h_files += built_h_files
+endif
+
+# Can't use @INPUT@ in the command. It requires absolute file paths.
+# Paths in built_h_file_targets are relative to project_build_root.
+tag_file = custom_target('html_and_tag',
+  input: doc_h_files,
+  output: book_name + '.tag',
+  command: [
+    python3, doc_reference_py, 'doxygen',
+    doctool_dir,
+    '@OUTPUT@',
+    src_h_files,
+    built_h_files,
+  ],
+  build_by_default: build_documentation,
+  install: true,
+  install_dir: install_reference_docdir,
+)
+
+devhelp_file = custom_target('devhelp',
+  input: tag_file,
+  output: book_name + '.devhelp2',
+  command: [
+    python3, doc_reference_py, 'devhelp',
+    doctool_dir,
+    '@INPUT@',
+    '@OUTPUT@',
+    book_name,
+    book_title,
+  ],
+  build_by_default: build_documentation,
+)
+
+# Install Devhelp file and html files.
+meson.add_install_script(
+  python3.path(), doc_reference_py, 'install_doc',
+  doctool_dir,
+  devhelp_file.full_path(),
+  install_devhelpdir,
+  install_reference_docdir / 'html',
+  docinstall_flags
+)
+
+# Install images.
+image_basefiles = [
+  'gtkmm_logo.gif',
+  'top.gif',
+]
+image_files = []
+foreach file : image_basefiles
+  image_files += '..' / 'images' / file
+endforeach
+
+install_data(image_files, install_dir: install_image_docdir)
+
+if not meson.is_subproject()
+  # Distribute built files and files copied by mm-common-get.
+  # (add_dist_script() is not allowed in a subproject)
+  meson.add_dist_script(
+    python3.path(), doc_reference_py, 'dist_doc',
+    doctool_dir,
+    doctool_dist_dir,
+    meson.current_build_dir(),
+    tag_file.full_path(),
+    devhelp_file.full_path(),
+  )
+endif
index a32cfb8..0de871a 100644 (file)
@@ -32,9 +32,11 @@ check_PROGRAMS =                     \
        options/example                 \
        properties/example              \
        regex/example                   \
-       settings/settings \
-       thread/dispatcher \
-       thread/dispatcher2
+       settings/settings               \
+       thread/dispatcher               \
+       thread/dispatcher2              \
+       thread/thread                   \
+       thread/threadpool
 
 glibmm_includes = -I$(top_builddir)/glib $(if $(srcdir:.=),-I$(top_srcdir)/glib)
 giomm_includes  = -I$(top_builddir)/gio $(if $(srcdir:.=),-I$(top_srcdir)/gio)
@@ -49,6 +51,7 @@ local_libgiomm  = $(top_builddir)/gio/giomm/libgiomm-$(GIOMM_API_VERSION).la
 
 LDADD        = $(GLIBMM_LIBS) $(local_libglibmm)
 giomm_ldadd  = $(GIOMM_LIBS) $(local_libglibmm) $(local_libgiomm)
+thread_ldadd = $(GLIBMM_LIBS) $(local_libglibmm)
 
 child_watch_child_watch_SOURCES  = child_watch/main.cc
 iochannel_stream_example_SOURCES =     \
@@ -65,7 +68,13 @@ properties_example_SOURCES = properties/properties_example.cc
 regex_example_SOURCES      = regex/main.cc
 
 thread_dispatcher_SOURCES  = thread/dispatcher.cc
+thread_dispatcher_LDADD    = $(thread_ldadd)
 thread_dispatcher2_SOURCES = thread/dispatcher2.cc
+thread_dispatcher2_LDADD   = $(thread_ldadd)
+thread_thread_SOURCES      = thread/thread.cc
+thread_thread_LDADD        = $(thread_ldadd)
+thread_threadpool_SOURCES  = thread/threadpool.cc
+thread_threadpool_LDADD    = $(thread_ldadd)
 
 # giomm examples
 dbus_session_bus_service_SOURCES = dbus/session_bus_service.cc
index 60e6c57..8051db3 100644 (file)
@@ -24,7 +24,7 @@ using namespace std;
 class ChildWatch : public sigc::trackable
 {
 public:
-  explicit ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}
+  ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}
 
   void on_child_exited(GPid pid, int status);
   void run(); // fork a child and call signal_child_watch
index 0dd336f..9b7bd95 100644 (file)
@@ -84,7 +84,7 @@ main(int, char**)
   loop = Glib::MainLoop::create();
 
   // Get the user session bus connection.
-  auto connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::SESSION);
+  auto connection = Gio::DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SESSION);
 
   // Check for an unavailable connection.
   if (!connection)
index d97eed3..dda068c 100644 (file)
@@ -113,7 +113,7 @@ on_server_new_connection(const Glib::RefPtr<Gio::DBus::Connection>& connection)
 {
   auto credentials = connection->get_peer_credentials();
 
-  std::string credentials_str;
+  Glib::ustring credentials_str;
 
   if (!credentials)
     credentials_str = "(no credentials received)";
@@ -123,8 +123,7 @@ on_server_new_connection(const Glib::RefPtr<Gio::DBus::Connection>& connection)
   std::cout << "Client connected." << std::endl
             << "Peer credentials: " << credentials_str << std::endl
             << "Negotiated capabilities: unix-fd-passing="
-            << ((connection->get_capabilities() & Gio::DBus::CapabilityFlags::UNIX_FD_PASSING)
-               == Gio::DBus::CapabilityFlags::UNIX_FD_PASSING)
+            << (connection->get_capabilities() & Gio::DBus::CAPABILITY_FLAGS_UNIX_FD_PASSING)
             << std::endl;
 
   // If there is already an active connection, do not accept this new one.
@@ -177,7 +176,7 @@ main(int, char**)
 
   Glib::RefPtr<Gio::DBus::Server> server;
 
-  const Glib::ustring address = "unix:abstract=myadd";
+  const std::string address = "unix:abstract=myadd";
   try
   {
     server = Gio::DBus::Server::create_sync(address, Gio::DBus::generate_guid());
@@ -193,7 +192,7 @@ main(int, char**)
 
   std::cout << "Server is listening at: " << server->get_client_address() << "." << std::endl;
 
-  server->signal_new_connection().connect(sigc::ptr_fun(&on_server_new_connection), false);
+  server->signal_new_connection().connect(sigc::ptr_fun(&on_server_new_connection));
 
   // Keep the server running until the process is killed:
   auto loop = Glib::MainLoop::create();
index aee935b..fade31b 100644 (file)
@@ -156,7 +156,7 @@ main(int, char**)
     return 1;
   }
 
-  const auto id = Gio::DBus::own_name(Gio::DBus::BusType::SESSION, "org.glibmm.DBusExample",
+  const auto id = Gio::DBus::own_name(Gio::DBus::BUS_TYPE_SESSION, "org.glibmm.DBusExample",
     sigc::ptr_fun(&on_bus_acquired), sigc::ptr_fun(&on_name_acquired),
     sigc::ptr_fun(&on_name_lost));
 
index 4fad426..d9f8944 100644 (file)
@@ -43,7 +43,7 @@ Glib::RefPtr<Glib::MainLoop> mainloop;
 bool
 MyCallback(Glib::IOCondition io_condition)
 {
-  if ((io_condition & Glib::IOCondition::IO_IN) != Glib::IOCondition::IO_IN)
+  if ((io_condition & Glib::IO_IN) == 0)
   {
     std::cerr << "Invalid fifo response" << std::endl;
   }
@@ -88,7 +88,7 @@ int main(/* int argc, char *argv[] */)
   }
 
   input_stream.attach(read_fd);
-  input_stream.connect(sigc::ptr_fun(MyCallback), Glib::IOCondition::IO_IN);
+  input_stream.connect(sigc::ptr_fun(MyCallback), Glib::IO_IN);
 
   // and last but not least - run the application main loop
   mainloop->run();
index a1b6155..c75719d 100644 (file)
@@ -24,12 +24,12 @@ main(int, char**)
 
   const std::string filepath = "./example.ini";
 
-  auto keyfile = Glib::KeyFile::create();
+  Glib::KeyFile keyfile;
 
   // An exception will be thrown if the file is not there, or if the file is incorrectly formatted:
   try
   {
-    keyfile->load_from_file(filepath);
+    keyfile.load_from_file(filepath);
   }
   catch (const Glib::Error& ex)
   {
@@ -41,7 +41,7 @@ main(int, char**)
   // An exception will be thrown if the value is not in the file:
   try
   {
-    const Glib::ustring value = keyfile->get_value("somegroup", "somekey");
+    const Glib::ustring value = keyfile.get_value("somegroup", "somekey");
     std::cout << "somekey value=" << value << std::endl;
   }
   catch (const Glib::KeyFileError& ex)
@@ -53,7 +53,7 @@ main(int, char**)
   // An exception will be thrown if the value is not in the file:
   try
   {
-    const Glib::ustring value = keyfile->get_value("First Group", "Welcome");
+    const Glib::ustring value = keyfile.get_value("First Group", "Welcome");
     std::cout << "Welcome value=" << value << std::endl;
   }
   catch (const Glib::KeyFileError& ex)
@@ -65,7 +65,7 @@ main(int, char**)
   // An exception will be thrown if the value is not in the file:
   try
   {
-    const auto values = keyfile->get_integer_list("Another Group", "Numbers");
+    const auto values = keyfile.get_integer_list("Another Group", "Numbers");
 
     for (const auto& p : values)
       std::cout << "Number list value: item=" << p << std::endl;
diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644 (file)
index 0000000..a4ba9cf
--- /dev/null
@@ -0,0 +1,73 @@
+# examples
+
+# input: glibmm_dep, giomm_dep, build_examples, compile_schemas_py
+
+examples = [
+# [[dir-name], exe-name, [sources], giomm-example (not just glibmm-example)]
+  [['compose'], 'example', ['main.cc'], false],
+  [['dbus'], 'session_bus_service', ['session_bus_service.cc'], true],
+  [['dbus'], 'server_without_bus', ['server_without_bus.cc'], true],
+  [['dbus'], 'client_bus_listnames', ['client_bus_listnames.cc'], true],
+  [['keyfile'], 'example', ['main.cc'], false],
+  [['markup'], 'parser', ['parser.cc'], false],
+  [['network'], 'resolver', ['resolver.cc'], true],
+  [['network'], 'socket-client', ['socket-client.cc'], true],
+  [['network'], 'socket-server', ['socket-server.cc'], true],
+  [['options'], 'example', ['main.cc'], false],
+  [['properties'], 'example', ['properties_example.cc'], false],
+  [['regex'], 'example', ['main.cc'], false],
+  [['settings'], 'settings', ['settings.cc', 'org.gtkmm.demo.gschema.xml'], true],
+  [['thread'], 'dispatcher', ['dispatcher.cc'], false],
+  [['thread'], 'dispatcher2', ['dispatcher2.cc'], false],
+  [['thread'], 'thread', ['thread.cc'], false],
+  [['thread'], 'threadpool', ['threadpool.cc'], false],
+]
+
+if not is_host_windows
+  examples += [
+    [['child_watch'], 'child_watch', ['main.cc'], false],
+    [['iochannel_stream'], 'example', ['fdstream.cc', 'main.cc'], false],
+  ]
+endif
+
+
+# import('gnome').compile_schemas() can't be use here.
+# It can only compile schemas in the current directory.
+glib_compile_schemas = find_program('glib-compile-schemas', required: false)
+
+foreach ex : examples
+  dir = ''
+  foreach dir_part : ex[0]
+    dir = dir / dir_part
+  endforeach
+  ex_name = (dir / ex[1]).underscorify()
+  ex_sources = []
+  foreach src : ex[2]
+    if src.endswith('.gschema.xml')
+      if glib_compile_schemas.found()
+        custom_target(dir.underscorify() + '_schemas',
+          input: dir / src,
+          output: dir.underscorify() + '_gschemas.compiled',
+          command: [
+            python3, compile_schemas_py,
+            meson.current_source_dir() / dir,
+            meson.current_build_dir() / dir,
+            '@OUTPUT@'
+          ],
+          build_by_default: build_examples,
+          install: false,
+        )
+      endif
+    else
+      ex_sources += dir / src
+    endif
+  endforeach
+
+  executable(ex_name, ex_sources,
+    cpp_args: ['-DGLIBMM_DISABLE_DEPRECATED', '-DGIOMM_DISABLE_DEPRECATED'],
+    dependencies: ex[3] ? giomm_dep : glibmm_dep,
+    gui_app: false,
+    build_by_default: build_examples,
+    install: false,
+  )
+endforeach
index a651a1a..7753816 100644 (file)
@@ -17,9 +17,6 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef _WIN32
-#include <config.h>
-#endif
 #include <giomm.h>
 #include <iostream>
 #include <mutex>
@@ -87,7 +84,7 @@ print_resolved_name(const Glib::ustring& phys, const Glib::ustring& name)
 
 static void
 print_resolved_addresses(
-  const Glib::ustring& name, const std::vector<Glib::RefPtr<Gio::InetAddress>>& addresses)
+  const Glib::ustring& name, const std::list<Glib::RefPtr<Gio::InetAddress>>& addresses)
 {
   std::lock_guard<std::mutex> lock_guard(response_mutex);
   std::cout << Glib::ustring::compose("Name:    %1\n", name);
@@ -101,7 +98,7 @@ print_resolved_addresses(
 }
 
 static void
-print_resolved_service(const Glib::ustring& service, const std::vector<Gio::SrvTarget>& targets)
+print_resolved_service(const Glib::ustring& service, const std::list<Gio::SrvTarget>& targets)
 {
   std::lock_guard<std::mutex> lock_guard(response_mutex);
   std::cout << Glib::ustring::compose("Service: %1\n", service);
@@ -172,9 +169,11 @@ lookup_one_sync(const Glib::ustring& arg)
   }
   else
   {
+    std::list<Glib::RefPtr<Gio::InetAddress>> addresses;
+
     try
     {
-      const auto addresses = resolver->lookup_by_name(arg, cancellable);
+      addresses = resolver->lookup_by_name(arg, cancellable);
       print_resolved_addresses(arg, addresses);
     }
     catch (const Gio::ResolverError& err)
@@ -285,7 +284,7 @@ static void
 print_connectable_sockaddr(Glib::RefPtr<Gio::SocketAddress> sockaddr)
 {
   Glib::ustring phys;
-  auto isa = std::dynamic_pointer_cast<Gio::InetSocketAddress>(sockaddr);
+  auto isa = Glib::RefPtr<Gio::InetSocketAddress>::cast_dynamic(sockaddr);
 
   if (!isa)
   {
@@ -347,12 +346,12 @@ do_async_connectable(Glib::RefPtr<Gio::SocketAddressEnumerator> enumerator)
 Glib::RefPtr<Gio::SocketConnectable> global_connectable;
 
 static void
-do_connectable(const std::string& arg, gboolean synchronous)
+do_connectable(const Glib::ustring& arg, gboolean synchronous)
 {
   std::vector<Glib::ustring> parts;
   Glib::RefPtr<Gio::SocketConnectable> connectable;
 
-  if (arg.find('/') != std::string::npos)
+  if (arg.find('/') != Glib::ustring::npos)
   {
     /* service/protocol/domain */
     parts = split_service_parts(arg);
@@ -366,18 +365,16 @@ do_connectable(const std::string& arg, gboolean synchronous)
   }
   else
   {
-    std::string host, port_str;
-    guint16 port;
+    Glib::ustring host;
+    guint16 port = 0;
 
     const auto pos = arg.find(':');
-    if (pos != std::string::npos)
+    if (pos != Glib::ustring::npos)
     {
       host = arg.substr(0, pos);
-      port_str = arg.substr(pos);
-      port = std::stoul(port_str);
+      auto port_str = arg.substr(pos);
+      port = std::stoul(port_str.raw());
     }
-    else
-      port = 0;
 
     if (Gio::hostname_is_ip_address(host))
     {
@@ -385,7 +382,7 @@ do_connectable(const std::string& arg, gboolean synchronous)
       connectable = Gio::InetSocketAddress::create(addr, port);
     }
     else
-      connectable = Gio::NetworkAddress::create(arg, port);
+      connectable = Gio::NetworkAddress::create(arg.raw(), port);
   }
 
   const auto enumerator = connectable->enumerate();
@@ -464,7 +461,7 @@ main(int argc, char** argv)
   signal(SIGINT, interrupted);
 
   chan = Glib::IOChannel::create_from_fd(cancel_fds[0]);
-  const auto source = chan->create_watch(Glib::IOCondition::IO_IN);
+  const auto source = chan->create_watch(Glib::IO_IN);
   watch_conn = source->connect(sigc::bind(sigc::ptr_fun(async_cancel), cancellable));
 #endif
 
index 5a3718a..c364d9b 100644 (file)
@@ -68,7 +68,7 @@ socket_address_to_string(const Glib::RefPtr<Gio::SocketAddress>& address)
   Glib::ustring str, res;
   int port;
 
-  auto isockaddr = std::dynamic_pointer_cast<Gio::InetSocketAddress>(address);
+  auto isockaddr = Glib::RefPtr<Gio::InetSocketAddress>::cast_dynamic(address);
   if (!isockaddr)
     return Glib::ustring();
   inet_address = isockaddr->get_address();
@@ -128,7 +128,7 @@ cancel_thread(Glib::RefPtr<Gio::Cancellable> cancellable)
 class JoinAndDelete
 {
 public:
-  void operator()(std::thread* thread) const
+  void operator()(std::thread* thread)
   {
     stop_thread = true;
     cond_thread.notify_all();
@@ -145,7 +145,7 @@ main(int argc, char* argv[])
   Glib::RefPtr<Gio::Socket> socket;
   Glib::RefPtr<Gio::SocketAddress> src_address;
   Glib::RefPtr<Gio::SocketAddress> address;
-  Gio::Socket::Type socket_type;
+  Gio::SocketType socket_type;
   Gio::SocketFamily socket_family;
   Glib::RefPtr<Gio::Cancellable> cancellable;
   Glib::RefPtr<Gio::SocketAddressEnumerator> enumerator;
@@ -188,12 +188,12 @@ main(int argc, char* argv[])
 
   loop = Glib::MainLoop::create();
 
-  socket_type = use_udp ? Gio::Socket::Type::DATAGRAM : Gio::Socket::Type::STREAM;
-  socket_family = use_ipv6 ? Gio::SocketFamily::IPV6 : Gio::SocketFamily::IPV4;
+  socket_type = use_udp ? Gio::SOCKET_TYPE_DATAGRAM : Gio::SOCKET_TYPE_STREAM;
+  socket_family = use_ipv6 ? Gio::SOCKET_FAMILY_IPV6 : Gio::SOCKET_FAMILY_IPV4;
 
   try
   {
-    socket = Gio::Socket::create(socket_family, socket_type, Gio::Socket::Protocol::DEFAULT);
+    socket = Gio::Socket::create(socket_family, socket_type, Gio::SOCKET_PROTOCOL_DEFAULT);
   }
   catch (const Gio::Error& error)
   {
@@ -272,7 +272,7 @@ main(int argc, char* argv[])
     buffer[to_send] = '\0';
     while (to_send > 0)
     {
-      ensure_condition(socket, "send", cancellable, Glib::IOCondition::IO_OUT);
+      ensure_condition(socket, "send", cancellable, Glib::IO_OUT);
       try
       {
         if (use_udp)
@@ -305,7 +305,7 @@ main(int argc, char* argv[])
       to_send -= size;
     }
 
-    ensure_condition(socket, "receive", cancellable, Glib::IOCondition::IO_IN);
+    ensure_condition(socket, "receive", cancellable, Glib::IO_IN);
     try
     {
       if (use_udp)
index a0e6bd1..fb9d6ea 100644 (file)
@@ -75,7 +75,7 @@ public:
 Glib::ustring
 socket_address_to_string(const Glib::RefPtr<Gio::SocketAddress>& address)
 {
-  auto isockaddr = std::dynamic_pointer_cast<Gio::InetSocketAddress>(address);
+  auto isockaddr = Glib::RefPtr<Gio::InetSocketAddress>::cast_dynamic(address);
   if (!isockaddr)
     return Glib::ustring();
 
@@ -134,7 +134,7 @@ cancel_thread(Glib::RefPtr<Gio::Cancellable> cancellable)
 class JoinAndDelete
 {
 public:
-  void operator()(std::thread* thread) const
+  void operator()(std::thread* thread)
   {
     stop_thread = true;
     cond_thread.notify_all();
@@ -176,12 +176,12 @@ main(int argc, char* argv[])
 
   loop = Glib::MainLoop::create();
 
-  auto socket_type = use_udp ? Gio::Socket::Type::DATAGRAM : Gio::Socket::Type::STREAM;
-  auto socket_family = use_ipv6 ? Gio::SocketFamily::IPV6 : Gio::SocketFamily::IPV4;
+  auto socket_type = use_udp ? Gio::SOCKET_TYPE_DATAGRAM : Gio::SOCKET_TYPE_STREAM;
+  auto socket_family = use_ipv6 ? Gio::SOCKET_FAMILY_IPV6 : Gio::SOCKET_FAMILY_IPV4;
 
   try
   {
-    socket = Gio::Socket::create(socket_family, socket_type, Gio::Socket::Protocol::DEFAULT);
+    socket = Gio::Socket::create(socket_family, socket_type, Gio::SOCKET_PROTOCOL_DEFAULT);
   }
   catch (const Gio::Error& error)
   {
@@ -218,7 +218,7 @@ main(int argc, char* argv[])
 
     std::cout << Glib::ustring::compose("listening on port %1...\n", port);
 
-    ensure_condition(socket, "accept", cancellable, Glib::IOCondition::IO_IN);
+    ensure_condition(socket, "accept", cancellable, Glib::IO_IN);
     try
     {
       new_socket = socket->accept(cancellable);
@@ -257,7 +257,7 @@ main(int argc, char* argv[])
     gchar buffer[4096] = {};
     gssize size;
 
-    ensure_condition(recv_socket, "receive", cancellable, Glib::IOCondition::IO_IN);
+    ensure_condition(recv_socket, "receive", cancellable, Glib::IO_IN);
     try
     {
       if (use_udp)
@@ -289,7 +289,7 @@ main(int argc, char* argv[])
 
     while (to_send > 0)
     {
-      ensure_condition(recv_socket, "send", cancellable, Glib::IOCondition::IO_OUT);
+      ensure_condition(recv_socket, "send", cancellable, Glib::IO_OUT);
       try
       {
         if (use_udp)
index cf6796f..6e6bfe1 100644 (file)
@@ -24,9 +24,9 @@ public:
   ExampleOptionGroup();
 
 private:
-  bool on_pre_parse(Glib::OptionContext& context) override;
-  bool on_post_parse(Glib::OptionContext& context) override;
-  void on_error(Glib::OptionContext& context, const Glib::Error& error) override;
+  bool on_pre_parse(Glib::OptionContext& context, Glib::OptionGroup& group) override;
+  bool on_post_parse(Glib::OptionContext& context, Glib::OptionGroup& group) override;
+  void on_error(Glib::OptionContext& context, Glib::OptionGroup& group) override;
 
   bool on_option_arg_string(
     const Glib::ustring& option_name, const Glib::ustring& value, bool has_value);
@@ -43,7 +43,7 @@ public:
   Glib::OptionGroup::vecustrings m_arg_list;
   Glib::OptionGroup::vecustrings m_remaining_list;
   Glib::ustring m_arg_x_string;
-  std::string m_arg_x_filename;
+  Glib::ustring m_arg_x_filename;
 };
 
 ExampleOptionGroup::ExampleOptionGroup()
@@ -88,7 +88,7 @@ ExampleOptionGroup::ExampleOptionGroup()
   entry6.set_long_name("x-string");
   entry6.set_short_name('x');
   entry6.set_description("A string with custom parsing");
-  entry6.set_flags(Glib::OptionEntry::Flags::OPTIONAL_ARG);
+  entry6.set_flags(Glib::OptionEntry::FLAG_OPTIONAL_ARG);
   m_arg_x_string = "not specified";
   add_entry(entry6, sigc::mem_fun(*this, &ExampleOptionGroup::on_option_arg_string));
 
@@ -96,7 +96,7 @@ ExampleOptionGroup::ExampleOptionGroup()
   entry7.set_long_name("x-filename");
   entry7.set_short_name('X');
   entry7.set_description("A filename with custom parsing");
-  entry7.set_flags(Glib::OptionEntry::Flags::OPTIONAL_ARG);
+  entry7.set_flags(Glib::OptionEntry::FLAG_OPTIONAL_ARG);
   m_arg_x_filename = "not specified";
   add_entry_filename(entry7, sigc::mem_fun(*this, &ExampleOptionGroup::on_option_arg_filename));
 
@@ -107,7 +107,7 @@ ExampleOptionGroup::ExampleOptionGroup()
 }
 
 bool
-ExampleOptionGroup::on_pre_parse(Glib::OptionContext& /* context */)
+ExampleOptionGroup::on_pre_parse(Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
 {
   // This is called before the m_arg_* instances are given their values.
   // You do not need to override this method. This is just here to show you how,
@@ -118,7 +118,7 @@ ExampleOptionGroup::on_pre_parse(Glib::OptionContext& /* context */)
 
 bool
 ExampleOptionGroup::on_post_parse(
-  Glib::OptionContext& /* context */)
+  Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
 {
   // This is called after the m_arg_* instances are given their values.
   // You do not need to override this method. This is just here to show you how,
@@ -128,7 +128,7 @@ ExampleOptionGroup::on_post_parse(
 }
 
 void
-ExampleOptionGroup::on_error(Glib::OptionContext& /* context */, const Glib::Error& /* error */)
+ExampleOptionGroup::on_error(Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
 {
   std::cout << "on_error called" << std::endl;
 }
index 94fd059..93f4f57 100644 (file)
@@ -23,12 +23,15 @@ main(int, char**)
 {
   Glib::init();
 
+  Glib::ustring u_abcd = "abcd";
+  Glib::ustring u_1234 = "1234";
+
   /* Reusing one regex pattern: */
   const auto regex = Glib::Regex::create("(a)?(b)");
   std::cout << "Pattern=" << regex->get_pattern() << ", with string=abcd, result=" << std::boolalpha
-            << regex->match("abcd") << std::endl;
+            << regex->match(u_abcd) << std::endl;
   std::cout << "Pattern=" << regex->get_pattern() << ", with string=1234, result=" << std::boolalpha
-            << regex->match("1234") << std::endl;
+            << regex->match(u_1234) << std::endl;
   std::cout << std::endl;
 
   /* Using the static function without a regex instance: */
index ecd18a7..2ec3578 100644 (file)
@@ -76,8 +76,10 @@ private:
 };
 
 template <class T>
-class DeletePtr : public std::unary_function<void, T>
+class DeletePtr
 {
+  typedef void argument_type;
+  typedef T result_type;
 public:
   void operator()(T ptr) const { delete ptr; }
 };
@@ -193,7 +195,7 @@ Application::launch_threads()
   std::cout << "Launching " << progress_threads_.size() << " threads:" << std::endl;
 
   std::for_each(
-    progress_threads_.begin(), progress_threads_.end(), std::mem_fun(&ThreadProgress::launch));
+    progress_threads_.begin(), progress_threads_.end(), std::mem_fn(&ThreadProgress::launch));
 }
 
 void
@@ -205,7 +207,7 @@ Application::on_progress_finished(ThreadProgress* thread_progress)
 
   // Quit if it was the last thread to be joined.
   if (std::find_if(progress_threads_.begin(), progress_threads_.end(),
-        std::mem_fun(&ThreadProgress::unfinished)) == progress_threads_.end())
+        std::mem_fn(&ThreadProgress::unfinished)) == progress_threads_.end())
   {
     main_loop_->quit();
   }
diff --git a/examples/thread/thread.cc b/examples/thread/thread.cc
new file mode 100644 (file)
index 0000000..7af2735
--- /dev/null
@@ -0,0 +1,126 @@
+
+#include <condition_variable>
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+/* For using noexcept on Visual Studio 2013 */
+#include <glibmmconfig.h>
+#endif
+#include <glibmm/init.h>
+#include <glibmm/random.h>
+#include <glibmm/timer.h>
+
+namespace
+{
+
+class MessageQueue
+{
+public:
+  MessageQueue();
+  ~MessageQueue();
+
+  void producer();
+  void consumer();
+
+private:
+  std::mutex mutex_;
+  std::condition_variable cond_push_;
+  std::condition_variable cond_pop_;
+  std::queue<int> queue_;
+};
+
+MessageQueue::MessageQueue()
+{
+}
+
+MessageQueue::~MessageQueue()
+{
+}
+
+void
+MessageQueue::producer()
+{
+  Glib::Rand rand(1234);
+
+  for (auto i = 0; i < 200; ++i)
+  {
+    {
+      std::unique_lock<std::mutex> lock(mutex_);
+
+      cond_pop_.wait(lock, [this]() -> bool { return queue_.size() < 64; });
+
+      queue_.push(i);
+      std::cout << '*';
+      std::cout.flush();
+
+      // We unlock before notifying, because that is what the documentation suggests:
+      // http://en.cppreference.com/w/cpp/thread/condition_variable
+      lock.unlock();
+      cond_push_.notify_one();
+    }
+
+    if (rand.get_bool())
+      continue;
+
+    Glib::usleep(rand.get_int_range(0, 100000));
+  }
+}
+
+void
+MessageQueue::consumer()
+{
+  Glib::Rand rand(4567);
+
+  for (;;)
+  {
+    {
+      std::unique_lock<std::mutex> lock(mutex_);
+
+      cond_push_.wait(lock, [this]() -> bool { return !queue_.empty(); });
+
+      const int i = queue_.front();
+      queue_.pop();
+      std::cout << "\x08 \x08";
+      std::cout.flush();
+
+      // We unlock before notifying, because that is what the documentation suggests:
+      // http://en.cppreference.com/w/cpp/thread/condition_variable
+      lock.unlock();
+      cond_pop_.notify_one();
+
+      if (i >= 199)
+        break;
+    }
+
+    if (rand.get_bool())
+      continue;
+
+    Glib::usleep(rand.get_int_range(10000, 200000));
+  }
+}
+}
+
+int
+main(int, char**)
+{
+  Glib::init();
+
+  MessageQueue queue;
+
+  // TODO: Use std::make_unique() when we use C++14:
+  const auto producer =
+    std::unique_ptr<std::thread>(new std::thread(&MessageQueue::producer, &queue));
+
+  const auto consumer =
+    std::unique_ptr<std::thread>(new std::thread(&MessageQueue::consumer, &queue));
+
+  producer->join();
+  consumer->join();
+
+  std::cout << std::endl;
+
+  return 0;
+}
diff --git a/examples/thread/threadpool.cc b/examples/thread/threadpool.cc
new file mode 100644 (file)
index 0000000..885962b
--- /dev/null
@@ -0,0 +1,68 @@
+
+#include <iostream>
+#include <mutex>
+#include <thread>
+
+// TODO: Remove this example sometime. Glib::ThreadPool is deprecated.
+// TODO: Maybe use std::async() instead?
+#undef GLIBMM_DISABLE_DEPRECATED
+
+#include <glibmmconfig.h>
+
+#ifdef GLIBMM_DISABLE_DEPRECATED
+int
+main(int, char**)
+{
+  // If glibmm is configured with --disable-deprecated-api,
+  // GLIBMM_DISABLE_DEPRECATED is defined in glibmmconfig.h.
+  std::cout << "Glib::ThreadPool not available because deprecated API has been disabled."
+            << std::endl;
+  return 77; // Tell automake's test harness to skip this test.
+}
+
+#else
+
+#include <glibmm/random.h>
+#include <glibmm/threadpool.h>
+#include <glibmm/timer.h>
+
+namespace
+{
+
+std::mutex mutex;
+
+void
+print_char(char c)
+{
+  Glib::Rand rand;
+
+  for (auto i = 0; i < 100; ++i)
+  {
+    {
+      std::lock_guard<std::mutex> lock(mutex);
+      std::cout << c;
+      std::cout.flush();
+    }
+    Glib::usleep(rand.get_int_range(10000, 100000));
+  }
+}
+
+} // anonymous namespace
+
+int
+main(int, char**)
+{
+  Glib::ThreadPool pool(10);
+
+  for (auto c = 'a'; c <= 'z'; ++c)
+  {
+    pool.push(sigc::bind(sigc::ptr_fun(&print_char), c));
+  }
+
+  pool.shutdown();
+
+  std::cout << std::endl;
+
+  return 0;
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
index 30ba71d..7436ddb 100644 (file)
@@ -77,9 +77,6 @@
 #include <giomm/file.h>
 #include <giomm/fileattributeinfo.h>
 #include <giomm/fileattributeinfolist.h>
-#ifndef G_OS_WIN32
-#include <giomm/filedescriptorbased.h>
-#endif
 #include <giomm/fileenumerator.h>
 #include <giomm/fileicon.h>
 #include <giomm/fileinfo.h>
 #include <giomm/permission.h>
 #include <giomm/pollableinputstream.h>
 #include <giomm/pollableoutputstream.h>
-#include <giomm/propertyaction.h>
 #include <giomm/proxy.h>
 #include <giomm/proxyaddress.h>
 #include <giomm/proxyresolver.h>
index 22dabbc..86b4978 100644 (file)
@@ -29,6 +29,8 @@ files_extra_ph = $(giomm_files_extra_ph)
 
 include $(top_srcdir)/build/compile-binding.am
 
+dist_noinst_HEADERS = slot_async.h
+
 local_includes = -I$(top_builddir)/glib $(if $(srcdir:.=),-I$(top_srcdir)/glib)
 local_cppflags = $(binding_includes) $(local_includes) $(binding_cppflags) -DGIOMM_BUILD=1
 
index abe6733..cf37c46 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <giomm/contenttype.h>
-#include <glibmm/vectorutils.h>
 #include <gio/gio.h>
 
 namespace Gio
@@ -117,17 +116,17 @@ content_type_guess(const std::string& filename, const std::string& data, bool& r
   return Glib::convert_return_gchar_ptr_to_ustring(cresult);
 }
 
-std::vector<Glib::ustring>
+Glib::StringArrayHandle
 content_type_guess_for_tree(const Glib::RefPtr<const File>& root)
 {
-  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(
+  return Glib::StringArrayHandle(
     g_content_type_guess_for_tree(const_cast<GFile*>(root->gobj())), Glib::OWNERSHIP_DEEP);
 }
 
-std::vector<Glib::ustring>
+Glib::ListHandle<Glib::ustring>
 content_types_get_registered()
 {
-  return Glib::ListHandler<Glib::ustring>::list_to_vector(g_content_types_get_registered(), Glib::OWNERSHIP_DEEP);
+  return Glib::ListHandle<Glib::ustring>(g_content_types_get_registered(), Glib::OWNERSHIP_DEEP);
 }
 
 } // namespace Gio
index 408adc8..6429b8c 100644 (file)
@@ -17,6 +17,7 @@
 #define _GIOMM_CONTENTTYPE_H
 
 #include <glibmm/ustring.h>
+#include <glibmm/listhandle.h>
 #include <giomm/icon.h>
 #include <giomm/file.h>
 #include <string>
@@ -41,6 +42,7 @@ namespace Gio
  *
  * @return true if the two strings are identical or equivalent, false otherwise.
  */
+GIOMM_API
 bool content_type_equals(const Glib::ustring& type1, const Glib::ustring& type2);
 
 /**
@@ -51,6 +53,7 @@ bool content_type_equals(const Glib::ustring& type1, const Glib::ustring& type2)
  *
  * @return true if @a type is a kind of @a supertype, false otherwise.
  */
+GIOMM_API
 bool content_type_is_a(const Glib::ustring& type, const Glib::ustring& supertype);
 
 /**
@@ -62,6 +65,7 @@ bool content_type_is_a(const Glib::ustring& type, const Glib::ustring& supertype
  *
  * @return true if the type is the unknown type.
  */
+GIOMM_API
 bool content_type_is_unknown(const Glib::ustring& type);
 
 /**
@@ -71,6 +75,7 @@ bool content_type_is_unknown(const Glib::ustring& type);
  *
  * @return a short description of the content type @a type.
  */
+GIOMM_API
 Glib::ustring content_type_get_description(const Glib::ustring& type);
 
 /**
@@ -80,6 +85,7 @@ Glib::ustring content_type_get_description(const Glib::ustring& type);
  *
  * @return the registered mime-type for the given @a type, or an empty string if unknown.
  */
+GIOMM_API
 Glib::ustring content_type_get_mime_type(const Glib::ustring& type);
 
 /**
@@ -89,6 +95,7 @@ Glib::ustring content_type_get_mime_type(const Glib::ustring& type);
  *
  * @return Icon corresponding to the content type.
  */
+GIOMM_API
 Glib::RefPtr<Icon> content_type_get_icon(const Glib::ustring& type);
 
 #ifdef G_OS_UNIX
@@ -100,6 +107,7 @@ Glib::RefPtr<Icon> content_type_get_icon(const Glib::ustring& type);
  *
  * @newin{2,34}
  */
+GIOMM_API
 Glib::RefPtr<Icon> content_type_get_symbolic_icon(const Glib::ustring& type);
 #endif
 
@@ -112,6 +120,7 @@ Glib::RefPtr<Icon> content_type_get_symbolic_icon(const Glib::ustring& type);
  * @return true if the file type corresponds to a type that can be executable,
  * false otherwise.
  */
+GIOMM_API
 bool content_type_can_be_executable(const Glib::ustring& type);
 
 /** Tries to find a content type based on the mime type name.
@@ -121,6 +130,7 @@ bool content_type_can_be_executable(const Glib::ustring& type);
  *
  * @newin{2,20}
  */
+GIOMM_API
 Glib::ustring content_type_from_mime_type(const Glib::ustring& mime_type);
 
 /**
@@ -136,6 +146,7 @@ Glib::ustring content_type_from_mime_type(const Glib::ustring& mime_type);
  * @return A string indicating a guessed content type for the
  * given data.
  */
+GIOMM_API
 Glib::ustring content_type_guess(
   const std::string& filename, const guchar* data, gsize data_size, bool& result_uncertain);
 
@@ -150,6 +161,7 @@ Glib::ustring content_type_guess(
  * @return A string indicating a guessed content type for the
  * given data.
  */
+GIOMM_API
 Glib::ustring content_type_guess(
   const std::string& filename, const std::string& data, bool& result_uncertain);
 
@@ -168,7 +180,8 @@ Glib::ustring content_type_guess(
  *
  * @newin{2,18}
  */
-std::vector<Glib::ustring> content_type_guess_for_tree(const Glib::RefPtr<const File>& root);
+GIOMM_API
+Glib::StringArrayHandle content_type_guess_for_tree(const Glib::RefPtr<const File>& root);
 
 /**
  * Gets a list of strings containing all the registered content types
@@ -176,7 +189,8 @@ std::vector<Glib::ustring> content_type_guess_for_tree(const Glib::RefPtr<const
  *
  * @return List of the registered content types.
  */
-std::vector<Glib::ustring> content_types_get_registered();
+GIOMM_API
+Glib::ListHandle<Glib::ustring> content_types_get_registered();
 
 /** @} group giommContentType */
 
index fe49892..4cc2a50 100644 (file)
@@ -4,7 +4,7 @@ giomm_files_built_cc = $(giomm_files_used_hg:.hg=.cc) wrap_init.cc
 giomm_files_built_h  = $(giomm_files_used_hg:.hg=.h)
 
 giomm_files_extra_cc = contenttype.cc init.cc slot_async.cc socketsource.cc
-giomm_files_extra_h  = contenttype.h init.h slot_async.h socketsource.h wrap_init.h
+giomm_files_extra_h  = contenttype.h init.h socketsource.h wrap_init.h
 giomm_files_extra_ph =
 
 giomm_files_all_h = $(giomm_files_hg:.hg=.h) $(giomm_files_extra_h)
index 74c78ae..73f9dd8 100644 (file)
@@ -2,4 +2,5 @@
 
 include $(top_srcdir)/gio/giomm/filelist.am
 
+# Taken out from $(top_srcdir)/gio/giomm/filelist.am
 giomm_files_built_ph = $(patsubst %.hg,private/%_p.h,$(giomm_files_used_hg))
index 0dd3c88..e6f36ad 100644 (file)
@@ -27,14 +27,12 @@ namespace Gio
 /** Initialize giomm and glibmm.
  *
  * Call it before you use other parts of giomm. You may call it more than once.
- * Calls after the first one have no effect. %Gio::init() calls Glib::init(), which
- * sets the global locale as specified by Glib::set_init_to_users_preferred_locale().
+ * Calls after the first one have no effect. %Gio::init() calls Glib::init().
  *
  * You do not need to call %Gio::init() if you are using Gtk::Application,
  * because it calls %Gio::init() for you.
- *
- * @see Glib::set_init_to_users_preferred_locale()
  */
+GIOMM_API
 void init();
 
 } // end namespace Gio
diff --git a/gio/giomm/meson.build b/gio/giomm/meson.build
new file mode 100644 (file)
index 0000000..99aa3d6
--- /dev/null
@@ -0,0 +1,393 @@
+# gio/giomm
+
+# Input: giomm_build_dep, giomm_pcname, maintainer_mode, project_source_root,
+#        generate_binding_py, handle_built_files_py, m4_files, pm_files,
+#        glibmm_libversion, install_includedir, python3, giomm_rc, gmmproc_dir,
+#        is_host_windows, gmmproc, generate_wrap_init_pl
+# Output: giomm_hg_ccg_basenames, giomm_extra_h_files, built_files_root,
+#         giomm_built_h_file_targets, giomm_dep
+
+giomm_defs_basefiles = [
+  'gio.defs',
+  'gio_enums.defs',
+  'gio_methods.defs',
+  'gio_signals.defs',
+  'gio_extra_objects.defs',
+  'gio_vfuncs.defs',
+  'gio_docs.xml',
+  'gio_docs_override.xml',
+]
+
+giomm_defs_files = []
+foreach file : giomm_defs_basefiles
+  giomm_defs_files += '..' / 'src' / file
+endforeach
+
+# Generated from pairs of .hg and .ccg files.
+giomm_any_hg_ccg_basenames = [
+  'action',
+  'actiongroup',
+  'actionmap',
+  'applaunchcontext',
+  'appinfo',
+  'application',
+  'applicationcommandline',
+  'asyncinitable',
+  'asyncresult',
+  'bufferedinputstream',
+  'bufferedoutputstream',
+  'cancellable',
+  'charsetconverter',
+  'converter',
+  'converterinputstream',
+  'converteroutputstream',
+  'credentials',
+  'datainputstream',
+  'dataoutputstream',
+  'dbusactiongroup',
+  'dbusaddress',
+  'dbusauthobserver',
+  'dbusconnection',
+  'dbuserror',
+  'dbuserrorutils',
+  'dbusinterface',
+  'dbusinterfaceskeleton',
+  'dbusinterfacevtable',
+  'dbusintrospection',
+  'dbusmenumodel',
+  'dbusmessage',
+  'dbusmethodinvocation',
+  'dbusobject',
+  'dbusobjectmanager',
+  'dbusobjectmanagerclient',
+  'dbusobjectmanagerserver',
+  'dbusobjectproxy',
+  'dbusobjectskeleton',
+  'dbusownname',
+  'dbusproxy',
+  'dbusserver',
+  'dbussubtreevtable',
+  'dbusutils',
+  'dbuswatchname',
+  'drive',
+  'emblem',
+  'emblemedicon',
+  'enums',
+  'error',
+  'file',
+  'fileattributeinfo',
+  'fileattributeinfolist',
+  'fileenumerator',
+  'fileicon',
+  'fileinfo',
+  'fileinputstream',
+  'fileiostream',
+  'filemonitor',
+  'filenamecompleter',
+  'fileoutputstream',
+  'filterinputstream',
+  'filteroutputstream',
+  'icon',
+  'inetaddress',
+  'inetsocketaddress',
+  'initable',
+  'inputstream',
+  'iostream',
+  'listmodel',
+  'liststore',
+  'loadableicon',
+  'memoryinputstream',
+  'memoryoutputstream',
+  'menuattributeiter',
+  'menulinkiter',
+  'menu',
+  'menuitem',
+  'menumodel',
+  'mount',
+  'mountoperation',
+  'networkaddress',
+  'networkmonitor',
+  'networkservice',
+  'notification',
+  'outputstream',
+  'permission',
+  'pollableinputstream',
+  'pollableoutputstream',
+  'proxy',
+  'proxyaddress',
+  'proxyresolver',
+  'remoteactiongroup',
+  'resolver',
+  'resource',
+  'seekable',
+  'settings',
+  'settingsschema',
+  'settingsschemakey',
+  'settingsschemasource',
+  'simpleaction',
+  'simpleactiongroup',
+  'simpleiostream',
+  'simplepermission',
+  'socket',
+  'socketaddress',
+  'socketaddressenumerator',
+  'socketclient',
+  'socketconnectable',
+  'socketconnection',
+  'socketcontrolmessage',
+  'socketlistener',
+  'socketservice',
+  'srvtarget',
+  'tcpconnection',
+  'tcpwrapperconnection',
+  'threadedsocketservice',
+  'themedicon',
+  'tlscertificate',
+  'tlsclientconnection',
+  'tlsconnection',
+  'tlsdatabase',
+  'tlsinteraction',
+  'tlspassword',
+  'tlsserverconnection',
+  'volume',
+  'volumemonitor',
+  'zlibdecompressor',
+  'zlibcompressor',
+]
+
+giomm_posix_hg_ccg_basenames = [
+  'unixconnection',
+  'unixcredentialsmessage',
+  'unixfdlist',
+  'unixfdmessage',
+  'unixinputstream',
+  'unixoutputstream',
+  'unixsocketaddress',
+]
+
+giomm_not_mac_hg_ccg_basenames = [
+  'desktopappinfo',
+]
+
+# All .hg/.ccg files, regardless of type of host.
+giomm_hg_ccg_basenames = \
+  giomm_any_hg_ccg_basenames + \
+  giomm_posix_hg_ccg_basenames + \
+  giomm_not_mac_hg_ccg_basenames
+
+# Used .hg/.ccg files in present type of host.
+giomm_used_hg_ccg_basenames = giomm_any_hg_ccg_basenames
+if not is_host_windows
+  giomm_used_hg_ccg_basenames += giomm_posix_hg_ccg_basenames
+  if not is_os_cocoa
+    giomm_used_hg_ccg_basenames += giomm_not_mac_hg_ccg_basenames
+  endif
+endif
+
+# Pairs of hand-coded .h and .cc files.
+giomm_extra_h_cc_basenames = [
+  'contenttype',
+  'init',
+  'socketsource',
+]
+
+giomm_extra_h_files = [
+  'wrap_init.h',
+]
+
+giomm_extra_cc_files = [
+  'slot_async.cc',
+]
+
+foreach file : giomm_extra_h_cc_basenames
+  giomm_extra_h_files += file + '.h'
+  giomm_extra_cc_files += file + '.cc'
+endforeach
+
+install_headers('..' / 'giomm.h', subdir: giomm_pcname)
+install_headers(giomm_extra_h_files, subdir: giomm_pcname / 'giomm')
+
+untracked_giomm = 'untracked' / 'gio' / 'giomm'
+src_untracked_giomm = project_source_root / untracked_giomm
+
+extra_giomm_objects = []
+giomm_cpp_flags = [ '-DGIOMM_BUILD=1' ]
+
+# Build the .rc file for Windows builds and link to it
+if is_host_windows
+  windows = import('windows')
+  giomm_res = windows.compile_resources(giomm_rc)
+  extra_giomm_objects += giomm_res
+endif
+
+if maintainer_mode
+
+  # Maintainer mode. Generate .h and .cc files from .hg and .ccg files in ../src.
+
+  # docs/reference/meson.build needs these.
+  built_files_root = project_build_root
+  giomm_built_h_file_targets = []
+
+  # Force meson+ninja to generate source files before anything is compiled.
+  # Compilation must depend on these targets.
+  giomm_used_built_cc_file_targets = []
+  giomm_used_built_h_file_targets = []
+
+  hg_files = []
+  foreach file : giomm_hg_ccg_basenames
+    hg_files += '..' / 'src' / file + '.hg'
+  endforeach
+
+  # Create wrap_init.cc in project_build_root/gio/giomm.
+  giomm_used_built_cc_file_targets += custom_target('giomm-wrap_init.cc',
+    input: hg_files,
+    output: 'wrap_init.cc',
+    command: [
+      python3, generate_binding_py, 'generate_wrap_init',
+      gmmproc_dir,
+      '@OUTPUT@',
+      'Gio', # namespace
+      '@INPUT@',
+    ],
+    depend_files: generate_wrap_init_pl,
+    build_by_default: maintainer_mode,
+    install: false,
+  )
+
+  # Create .h/_p.h/.cc files in project_build_root/gio/giomm
+  # from .hg/.ccg files in project_source_root/gio/src.
+  foreach file : giomm_hg_ccg_basenames
+    hg_file = '..' / 'src' / file + '.hg'
+    ccg_file = '..' / 'src' / file + '.ccg'
+    built_file_target = custom_target('giomm-' + file + '.cc',
+      input: [hg_file, ccg_file],
+      output: [file + '.stamp', file + '.cc', file + '.h'],
+      command: [
+        python3, handle_built_files_py, 'gmmproc',
+        gmmproc_dir,
+        project_source_root / 'tools' / 'pm',
+        '@OUTPUT0@',
+        file,
+        meson.current_source_dir() / '..' / 'src',
+        project_source_root / 'tools' / 'm4',
+      ],
+      depend_files: giomm_defs_files + m4_files + [gmmproc] + pm_files,
+      build_by_default: maintainer_mode,
+      install: false,
+    )
+    giomm_built_h_file_targets += built_file_target[2]
+    if giomm_used_hg_ccg_basenames.contains(file)
+      giomm_used_built_cc_file_targets += built_file_target[1]
+      giomm_used_built_h_file_targets += built_file_target[2]
+    endif
+  endforeach
+
+  # Create dummy_header.h, depending on all generated headers.
+  # It's created if it does not exist, but it's never updated.
+  # It guarantees that all generated headers are built before giomm_library
+  # is built, at the same time avoiding unnecessary recompilations.
+  # If giomm_used_built_h_file_targets would be listed as sources to giomm_library,
+  # all generated .cc files could be recompiled if one generated .h file has
+  # been changed.
+  built_dummy_h_file_target = custom_target('giomm-dummy_header.h',
+    input: giomm_used_built_h_file_targets,
+    output: 'dummy_header.h',
+    command: [
+      python3, dummy_header_py,
+      '@OUTPUT@',
+    ],
+    build_by_default: maintainer_mode,
+    install: false,
+  )
+
+  extra_include_dirs = ['..', '..' / '..' / 'glib']
+
+  giomm_library = library(giomm_pcname, extra_giomm_objects,
+    giomm_used_built_cc_file_targets, giomm_extra_cc_files, built_dummy_h_file_target,
+    version: glibmm_libversion,
+    include_directories: extra_include_dirs,
+    cpp_args: giomm_cpp_flags,
+    dependencies: giomm_build_dep,
+    link_with: glibmm_library,
+    install: true,
+  )
+
+  built_h_cc_dir = meson.current_build_dir()
+
+else # not maintainer_mode
+
+  # Not maintainer mode. Compile built source code files in
+  # project_source_root/untracked/gio/giomm.
+
+  giomm_used_built_h_file_targets = []
+
+  # docs/reference/meson.build needs these.
+  built_files_root = project_source_root / 'untracked'
+  giomm_built_h_file_targets = []
+
+  # Two cases:
+  # 1. The source code comes from a tarball, where the built files
+  #    are stored in project_source_root/untracked.
+  #    There are no built files in the build tree.
+  # 2. Files have been built in the build tree. Then maintainer_mode has
+  #    been changed from true to false. Files that are missing or not up to date
+  #    in project_source_root/untracked are copied from the build tree.
+
+  # Try to copy built source code files to the source tree.
+  run_command(
+    python3, generate_binding_py, 'copy_built_files',
+    meson.current_build_dir(),
+    src_untracked_giomm,
+    giomm_hg_ccg_basenames,
+  )
+
+  built_cc_files = [ src_untracked_giomm / 'wrap_init.cc' ]
+  foreach file : giomm_used_hg_ccg_basenames
+    built_cc_files += src_untracked_giomm / file + '.cc'
+  endforeach
+
+  extra_include_dirs = [ '..', '..' / '..' / 'untracked' / 'gio',
+         '..' / '..' / 'glib', '..' / '..' / 'untracked' / 'glib',
+  ]
+
+  giomm_library = library(giomm_pcname, extra_giomm_objects,
+    built_cc_files, giomm_extra_cc_files,
+    version: glibmm_libversion,
+    include_directories: extra_include_dirs,
+    cpp_args: giomm_cpp_flags,
+    dependencies: giomm_build_dep,
+    link_with: glibmm_library,
+    install: true,
+  )
+
+  built_h_cc_dir = src_untracked_giomm
+
+endif
+
+# Install built .h and _p.h files.
+meson.add_install_script(
+  python3.path(), generate_binding_py, 'install_built_h_files',
+  built_h_cc_dir,
+  install_includedir / giomm_pcname / 'giomm', # subdir below {prefix}
+  giomm_used_hg_ccg_basenames
+)
+
+if not meson.is_subproject()
+  # Distribute built files.
+  # (add_dist_script() is not allowed in a subproject)
+  meson.add_dist_script(
+    python3.path(), generate_binding_py, 'dist_built_files',
+    built_h_cc_dir,
+    untracked_giomm,
+    giomm_hg_ccg_basenames,
+  )
+endif
+
+# This is useful in the main project when giomm is used as a subproject.
+# It's also used when building example programs and test programs.
+giomm_dep = declare_dependency(
+  sources: glibmm_built_h_file_targets + giomm_used_built_h_file_targets,
+  link_with: [glibmm_library, giomm_library],
+  include_directories: extra_include_dirs,
+  dependencies: giomm_build_dep,
+)
index db23dbf..4f2b6e2 100644 (file)
@@ -14,9 +14,9 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "slot_async.h"
 #include <glibmm/exceptionhandler.h>
 #include <giomm/asyncresult.h>
-#include <giomm/slot_async.h>
 
 namespace Gio
 {
index 378d9d4..72f5286 100644 (file)
@@ -1,6 +1,3 @@
-#ifndef _GIOMM_SLOT_ASYNC_H
-#define _GIOMM_SLOT_ASYNC_H
-
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <gio/gio.h>
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#include <giommconfig.h>
+
+#include <gio/gio.h>
 
 namespace Gio
 {
 
-/** Callback function, used in combination with Gio::SlotAsyncReady.
- *
- * Example:
- * @code
- * _WRAP_METHOD(void acquire_async(const SlotAsyncReady& slot{callback},
- *   const Glib::RefPtr<Cancellable>& cancellable{.?}), g_permission_acquire_async,
- *   slot_name slot, slot_callback SignalProxy_async_callback)
- * @endcode
- */
+GIOMM_API
 void SignalProxy_async_callback(GObject*, GAsyncResult* res, void* data);
 
 } // namespace Gio
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-#endif /* _GIOMM_SLOT_ASYNC_H */
index e46af5d..497a27c 100644 (file)
@@ -31,7 +31,7 @@ giomm_generic_socket_callback(sigc::slot_base* slot, GIOCondition condition)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    return (*static_cast<sigc::slot<bool(Glib::IOCondition)>*>(slot))((Glib::IOCondition)condition);
+    return (*static_cast<sigc::slot<bool, Glib::IOCondition>*>(slot))((Glib::IOCondition)condition);
   }
   catch (...)
   {
@@ -66,7 +66,7 @@ inline SignalSocket::SignalSocket(GMainContext* context) : context_(context)
 }
 
 sigc::connection
-SignalSocket::connect(const sigc::slot<bool(Glib::IOCondition)>& slot,
+SignalSocket::connect(const sigc::slot<bool, Glib::IOCondition>& slot,
   const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition,
   const Glib::RefPtr<Cancellable>& cancellable, int priority)
 {
@@ -90,15 +90,7 @@ Glib::RefPtr<SocketSource>
 SocketSource::create(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition,
   const Glib::RefPtr<Cancellable>& cancellable)
 {
-  return Glib::make_refptr_for_instance<SocketSource>(new SocketSource(socket, condition, cancellable));
-}
-
-// static
-Glib::RefPtr<SocketSource>
-SocketSource::create(GSocket* socket, Glib::IOCondition condition,
-  const Glib::RefPtr<Cancellable>& cancellable)
-{
-  return Glib::make_refptr_for_instance<SocketSource>(new SocketSource(socket, condition, cancellable));
+  return Glib::RefPtr<SocketSource>(new SocketSource(socket, condition, cancellable));
 }
 
 SocketSource::SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition,
@@ -109,14 +101,6 @@ SocketSource::SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition
 {
 }
 
-SocketSource::SocketSource(GSocket* socket, Glib::IOCondition condition,
-  const Glib::RefPtr<Cancellable>& cancellable)
-: IOSource(
-    g_socket_create_source(socket, (GIOCondition)condition, Glib::unwrap(cancellable)),
-    Glib::function_pointer_cast<GSourceFunc>(&giomm_socketsource_callback))
-{
-}
-
 SocketSource::~SocketSource() noexcept
 {
 }
index a90edee..2e3e3b4 100644 (file)
 #include <giomm/cancellable.h>
 #include <sigc++/sigc++.h>
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-using GSocket = struct _GSocket;
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
 namespace Gio
 {
-class Socket;
+class GIOMM_API Socket;
 
 /** @newin{2,42}
  * @ingroup NetworkIO
  */
-class SignalSocket
+class GIOMM_API SignalSocket
 {
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -73,9 +69,9 @@ public:
    * @param priority The priority of the new event source.
    * @return A connection handle, which can be used to disconnect the handler.
    */
-  sigc::connection connect(const sigc::slot<bool(Glib::IOCondition)>& slot,
+  sigc::connection connect(const sigc::slot<bool, Glib::IOCondition>& slot,
     const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition,
-    const Glib::RefPtr<Cancellable>& cancellable = {},
+    const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>(),
     int priority = Glib::PRIORITY_DEFAULT);
 
 private:
@@ -92,8 +88,9 @@ private:
  * @newin{2,42}
  * @ingroup NetworkIO
  */
+GIOMM_API
 SignalSocket signal_socket(
-  const Glib::RefPtr<Glib::MainContext>& context = {});
+  const Glib::RefPtr<Glib::MainContext>& context = Glib::RefPtr<Glib::MainContext>());
 
 /** An event source that can monitor a Gio::Socket.
  * @see Gio::Socket::create_source().
@@ -101,32 +98,19 @@ SignalSocket signal_socket(
  * @newin{2,42}
  * @ingroup NetworkIO
  */
-class SocketSource : public Glib::IOSource
+class GIOMM_API SocketSource : public Glib::IOSource
 {
 public:
   using CppObjectType = Gio::SocketSource;
 
   static Glib::RefPtr<SocketSource> create(const Glib::RefPtr<Socket>& socket,
     Glib::IOCondition condition,
-    const Glib::RefPtr<Cancellable>& cancellable = {});
-
+    const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
 
 protected:
   SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition,
     const Glib::RefPtr<Cancellable>& cancellable);
   ~SocketSource() noexcept override;
-
-private:
-  friend Socket;
-
-  // This is just to avoid the need for Gio::Socket to create a RefPtr<> to itself.
-  static Glib::RefPtr<SocketSource> create(GSocket* socket,
-    Glib::IOCondition condition,
-    const Glib::RefPtr<Cancellable>& cancellable = {});
-
-  // This is just to avoid the need for Gio::Socket to create a RefPtr<> to itself.
-  SocketSource(GSocket* socket, Glib::IOCondition condition,
-    const Glib::RefPtr<Cancellable>& cancellable);
 };
 
 } // namespace Gio
index cb7d947..4b44fb0 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <giommconfig.h>
+
 namespace Gio
 {
+GIOMM_API
 void wrap_init();
 }
 
index 8f27b73..b9579c6 100644 (file)
 #undef GIOMM_STATIC_LIB
 
 // Enable DLL-specific stuff only when not building a static library
-#if !defined(__CYGWIN__) && defined(__MINGW32__) && !defined(GIOMM_STATIC_LIB)
+#if !defined(__CYGWIN__) && (defined(__MINGW32__) || defined(_MSC_VER)) && !defined(GIOMM_STATIC_LIB)
 # define GIOMM_DLL 1
 #endif
 
 #ifdef GIOMM_DLL
-# if defined(GIOMM_BUILD) && defined(_WINDLL)
-   /* Do not dllexport as it is handled by gendef on MSVC */
-#  define GIOMM_API
-# elif !defined(GIOMM_BUILD)
-#  define GIOMM_API __declspec(dllimport)
+# if defined(GIOMM_BUILD)
+#  define GIOMM_API __declspec(dllexport)
 # else
-   /* Build a static library */
-#  define GIOMM_API
-# endif /* GIOMM_BUILD - _WINDLL */
+#  define GIOMM_API __declspec(dllimport)
+# endif
+/* Build a static library or non-native-Windows library */
 #else
 # define GIOMM_API
 #endif /* GIOMM_DLL */
diff --git a/gio/giommconfig.h.meson b/gio/giommconfig.h.meson
new file mode 100644 (file)
index 0000000..9ac31c6
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _GIOMM_CONFIG_H
+#define _GIOMM_CONFIG_H
+
+#include <glibmmconfig.h>
+
+/* Define to omit deprecated API from the library. */
+#mesondefine GIOMM_DISABLE_DEPRECATED
+
+/* Major version number of giomm. */
+#mesondefine GIOMM_MAJOR_VERSION
+
+/* Minor version number of giomm. */
+#mesondefine GIOMM_MINOR_VERSION
+
+/* Micro version number of giomm. */
+#mesondefine GIOMM_MICRO_VERSION
+
+/* Define if giomm is built as a static library */
+#mesondefine GIOMM_STATIC_LIB
+
+// Enable DLL-specific stuff only when not building a static library
+#if !defined(__CYGWIN__) && (defined(__MINGW32__) || defined(_MSC_VER)) && !defined(GIOMM_STATIC_LIB)
+# define GIOMM_DLL 1
+#endif
+
+#ifdef GIOMM_DLL
+# if defined(GIOMM_BUILD)
+#  define GIOMM_API __declspec(dllexport)
+# else
+#  define GIOMM_API __declspec(dllimport)
+# endif
+/* Build a static library or non-native-Windows library */
+#else
+# define GIOMM_API
+#endif /* GIOMM_DLL */
+
+#endif /* _GIOMM_CONFIG_H */
diff --git a/gio/meson.build b/gio/meson.build
new file mode 100644 (file)
index 0000000..4213109
--- /dev/null
@@ -0,0 +1,29 @@
+# gio
+
+# Input: pkg_conf_data, giomm_pcname, install_pkgconfigdir,
+# Output: install_giommconfigdir, giommconfig_h
+
+configure_file(
+  input: 'giomm.pc.in',
+  output: giomm_pcname + '.pc',
+  configuration: pkg_conf_data,
+  install_dir: install_pkgconfigdir,
+)
+
+giomm_pkg_uninst_conf_data = configuration_data()
+giomm_pkg_uninst_conf_data.merge_from(pkg_conf_data)
+giomm_pkg_uninst_conf_data.set('srcdir', meson.current_source_dir())
+
+configure_file(
+  input: 'giomm-uninstalled.pc.in',
+  output: giomm_pcname + '-uninstalled.pc',
+  configuration: giomm_pkg_uninst_conf_data,
+)
+
+install_giommconfigdir = install_libdir / giomm_pcname / 'include'
+giommconfig_h = configure_file(
+  input: 'giommconfig.h.meson',
+  output: 'giommconfig.h',
+  configuration: pkg_conf_data,
+  install_dir: install_giommconfigdir,
+)
index 6ceb81c..9b94762 100644 (file)
@@ -63,9 +63,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class Action : public Glib::Interface
+class GIOMM_API Action : public Glib::Interface
 {
-  _CLASS_INTERFACE(Action, GAction, G_ACTION, GActionInterface)
+  _CLASS_INTERFACE(Action, GAction, G_ACTION, GActionInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::ustring get_name() const, g_action_get_name)
@@ -95,7 +95,10 @@ public:
   template <typename T_Value>
   void get_state_hint(T_Value& value) const;
 
-  _WRAP_METHOD(Glib::VariantContainerBase get_state_hint_variant() const, g_action_get_state_hint)
+  //TODO: When we can break ABI, Return a Glib::VariantContainerBase,
+  // as we already do for ActionGroup::get_action_state_hint(),
+  // because that is what this returns (to specify a range).
+  _WRAP_METHOD(Glib::VariantBase get_state_hint_variant() const, g_action_get_state_hint)
 
   _WRAP_METHOD(bool get_enabled() const, g_action_get_enabled)
 
@@ -124,6 +127,8 @@ public:
 
   _WRAP_METHOD(void change_state_variant(const Glib::VariantBase& value), g_action_change_state)
 
+  _WRAP_METHOD(void change_state(const Glib::VariantBase& value), g_action_change_state, deprecated "Use the templated method instead, passing a normal C++ type.")
+
   /** Queries the current state of the action.
    *
    * If the action is not stateful then a null Variant will be returned.  If the
@@ -160,6 +165,8 @@ public:
 
   _WRAP_METHOD(void activate_variant(const Glib::VariantBase& parameter), g_action_activate)
 
+  _WRAP_METHOD(void activate(const Glib::VariantBase& parameter), g_action_activate, deprecated "Use the templated method instead, passing a normal C++ type.")
+
   _WRAP_METHOD(static bool name_is_valid(const Glib::ustring& action_name), g_action_name_is_valid )
 
   /** Parses a detailed action name into its separate name and target components.
@@ -177,7 +184,7 @@ public:
   static void parse_detailed_name(const Glib::ustring& detailed_name, Glib::ustring& action_name, T_Value& target_value);
 
   _WRAP_METHOD(static void parse_detailed_name_variant(const Glib::ustring& detailed_name,
-    Glib::ustring& action_name{>>}, Glib::VariantBase& target_value{>>}), g_action_parse_detailed_name, errthrow "Glib::VariantParseError")
+    Glib::ustring& action_name{>>}, Glib::VariantBase& target_value{>>}), g_action_parse_detailed_name, errthrow "Glib::VariantParseError", errthrow)
 
   /** Formats a detailed action name from the action's action_name and @a target_value.
    *
@@ -202,7 +209,6 @@ public:
   _WRAP_PROPERTY("state", Glib::VariantBase)
   _WRAP_PROPERTY("state-type", Glib::VariantType)
 
-protected:
 #m4 _CONVERSION(`Glib::ustring',`const gchar*',`$3.c_str()')
   _WRAP_VFUNC(Glib::ustring get_name() const, "get_name", keep_return)
 
index 0a69314..1dca1cd 100644 (file)
@@ -31,9 +31,9 @@ typedef struct _GActionGroupInterface GActionGroupInterface;
 namespace Glib
 {
 
-class VariantBase;
-class VariantContainerBase;
-class VariantType;
+class GIOMM_API VariantBase;
+class GIOMM_API VariantContainerBase;
+class GIOMM_API VariantType;
 
 }
 
@@ -56,9 +56,9 @@ namespace Gio
  * Signals are emitted on the action group in response to state changes on
  * individual actions.
  */
-class ActionGroup : public Glib::Interface
+class GIOMM_API ActionGroup : public Glib::Interface
 {
-  _CLASS_INTERFACE(ActionGroup, GActionGroup, G_ACTION_GROUP, GActionGroupInterface)
+  _CLASS_INTERFACE(ActionGroup, GActionGroup, G_ACTION_GROUP, GActionGroupInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(bool has_action(const Glib::ustring& action_name) const, g_action_group_has_action)
@@ -74,6 +74,9 @@ public:
   _WRAP_METHOD(Glib::VariantType get_action_parameter_type(const Glib::ustring& action_name) const, g_action_group_get_action_parameter_type)
   _WRAP_METHOD(Glib::VariantType get_action_state_type(const Glib::ustring& action_name) const, g_action_group_get_action_state_type)
 
+
+  _WRAP_METHOD(Glib::VariantContainerBase get_action_state_hint(const Glib::ustring& action_name) const, g_action_group_get_action_state_hint, deprecated "Use the get_action_state() method that takes an output parameter instead.")
+
   //TODO: How do we check for a nullptr Variant?
   /**
    * Requests a hint about the valid range of values for the state of the
@@ -100,6 +103,9 @@ public:
 
   _WRAP_METHOD(Glib::VariantContainerBase get_action_state_hint_variant(const Glib::ustring& action_name) const, g_action_group_get_action_state_hint)
 
+
+  _WRAP_METHOD(Glib::VariantBase get_action_state(const Glib::ustring& action_name) const, g_action_group_get_action_state, deprecated "Use the get_action_state() method that takes an output parameter instead.")
+
   //TODO: How do we check for a nullptr Variant?
   /** Queries the current state of the named action within the action group.
    *
@@ -128,15 +134,15 @@ public:
   //TODO: Add templated method, renaming this to action_state_changed_variant).
   _WRAP_METHOD(void action_state_changed (const Glib::ustring& action_name, const Glib::VariantBase& state), g_action_group_action_state_changed)
 
-  _WRAP_SIGNAL(void action_added(const Glib::ustring& action_name), "action-added", detail_name action_name)
-  _WRAP_SIGNAL(void action_enabled_changed(const Glib::ustring& action_name, bool enabled), "action-enabled-changed", detail_name action_name)
-  _WRAP_SIGNAL(void action_removed(const Glib::ustring& action_name), "action-removed", detail_name action_name)
+  //TODO: Remove two_signal_methods when we can break ABI.
+  _WRAP_SIGNAL(void action_added(const Glib::ustring& action_name), "action-added", detail_name action_name, two_signal_methods)
+  _WRAP_SIGNAL(void action_enabled_changed(const Glib::ustring& action_name, bool enabled), "action-enabled-changed", detail_name action_name, two_signal_methods)
+  _WRAP_SIGNAL(void action_removed(const Glib::ustring& action_name), "action-removed", detail_name action_name, two_signal_methods)
 
 #m4 _CONVERSION(`GVariant*', `const Glib::VariantBase&', `Glib::wrap($3, true)')
 
-  _WRAP_SIGNAL(void action_state_changed(const Glib::ustring& action_name, const Glib::VariantBase& value), "action-state-changed", detail_name action_name)
+  _WRAP_SIGNAL(void action_state_changed(const Glib::ustring& action_name, const Glib::VariantBase& value), "action-state-changed", detail_name action_name, two_signal_methods)
 
-protected:
   _WRAP_VFUNC(bool has_action(const Glib::ustring& name) const, "has_action")
 
 #m4 _CONVERSION(`std::vector<Glib::ustring>',`gchar**',`g_strdupv(const_cast<gchar**>(Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data()))')
index c39a242..01a8d37 100644 (file)
@@ -36,6 +36,17 @@ ActionMap::add_action(const Glib::ustring& name, const ActivateSlot& slot)
   return action;
 }
 
+_DEPRECATE_IFDEF_START
+Glib::RefPtr<SimpleAction>
+ActionMap::add_action_with_parameter(
+  const Glib::ustring& name, const ActivateWithParameterSlot& slot)
+{
+  auto action = add_action(name);
+  action->signal_activate().connect(slot);
+  return action;
+}
+_DEPRECATE_IFDEF_END
+
 Glib::RefPtr<SimpleAction>
 ActionMap::add_action_with_parameter(
   const Glib::ustring& name, const Glib::VariantType& parameter_type, const ActivateWithParameterSlot& slot)
@@ -80,7 +91,8 @@ static void
 on_action_radio_string(
   const Glib::VariantBase& parameter, const Gio::ActionMap::ActivateWithStringParameterSlot& slot)
 {
-  const auto variantDerived = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(parameter);
+  // TODO: This syntax is odd:
+  const auto variantDerived = parameter.cast_dynamic<Glib::Variant<Glib::ustring>>(parameter);
   const auto str = variantDerived.get();
   slot(str);
 }
@@ -104,7 +116,8 @@ static void
 on_action_radio_int(
   const Glib::VariantBase& parameter, const Gio::ActionMap::ActivateWithIntParameterSlot& slot)
 {
-  const auto variantDerived = Glib::VariantBase::cast_dynamic<Glib::Variant<int>>(parameter);
+  // TODO: This syntax is odd:
+  const auto variantDerived = parameter.cast_dynamic<Glib::Variant<int>>(parameter);
   const auto str = variantDerived.get();
   slot(str);
 }
index 8e8f437..43075b7 100644 (file)
@@ -28,7 +28,11 @@ typedef struct _GActionMapInterface GActionMapInterface;
 namespace Gio
 {
 
-class Action;
+class GIOMM_API Action;
+
+//TODO: Instead derive from ActionGroup, when we can break ABI,
+//because the GActionMap interface requires the GActionGroup interface.
+//LoadableIcon does a similar thing correctly, for instance.
 
 /** ActionMap - Interface for action containers.
  * The ActionMap interface is implemented by ActionGroup implementations that
@@ -40,9 +44,9 @@ class Action;
  * or "win."). This is the motivation for the 'Map' part of the interface name.
  * @newin{2,32}
  */
-class ActionMap : public Glib::Interface
+class GIOMM_API ActionMap : public Glib::Interface
 {
-  _CLASS_INTERFACE(ActionMap, GActionMap, G_ACTION_MAP, GActionMapInterface)
+  _CLASS_INTERFACE(ActionMap, GActionMap, G_ACTION_MAP, GActionMapInterface, , , GIOMM_API)
 
   // The various add_action...() methods are our equivalent for g_action_map_add_action_entries().
   _IGNORE(g_action_map_add_action_entries)
@@ -54,7 +58,6 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Action> lookup_action(const Glib::ustring& action_name), g_action_map_lookup_action, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Action> lookup_action(const Glib::ustring& action_name) const, g_action_map_lookup_action, constversion, refreturn)
 
-
   /** A convenience method for creating a SimpleAction instance
    * and adding it to the ActionMap.
    *
@@ -70,7 +73,7 @@ public:
    * For instance,
    * void on_slot_activated();
    */
-  using ActivateSlot = sigc::slot<void()>;
+  using ActivateSlot = sigc::slot<void>;
 
   /** A convenience method for creating a SimpleAction instance
    * and adding it to the ActionMap.
@@ -89,7 +92,22 @@ public:
    * For instance,
    * void on_slot_activated(const Glib::VariantBase& parameter);
    */
-  using ActivateWithParameterSlot = sigc::slot<void(const Glib::VariantBase&)>;
+  using ActivateWithParameterSlot = sigc::slot<void, const Glib::VariantBase&>;
+
+_DEPRECATE_IFDEF_START
+  /** A convenience method for creating a SimpleAction instance
+   * and adding it to the ActionMap.
+   *
+   * @param name The name of the Action.
+   * @param slot The callback method to be called when the action is activated.
+   * @return The Action.
+   *
+   * @deprecated This overload does not work as it does not set a parameter
+   * type on the Action, so activating it with a parameter cannot work. Use the
+   * other add_action_with_parameter() overload, which takes a parameter type.
+   */
+  Glib::RefPtr<SimpleAction> add_action_with_parameter(const Glib::ustring& name, const ActivateWithParameterSlot& slot);
+_DEPRECATE_IFDEF_END
 
   /** A convenience method for creating a SimpleAction instance, which when
    * activated will call a slot receiving a given type of parameter, and adding
@@ -139,7 +157,7 @@ public:
    * For instance,
    * void on_slot_activated(const Glib::ustring& parameter);
    */
-  using ActivateWithStringParameterSlot = sigc::slot<void(const Glib::ustring&)>;
+  using ActivateWithStringParameterSlot = sigc::slot<void, const Glib::ustring&>;
 
 //TODO: Docs: Add hints about how to specify the various possible states in the GtkBuilder XML.
   /** A convenience method for creating a string-based radio SimpleAction instance
@@ -169,8 +187,8 @@ public:
    * For instance,
    * void on_slot_activated(int parameter);
    */
-  using ActivateWithIntParameterSlot = sigc::slot<void(int)>;
-  
+  using ActivateWithIntParameterSlot = sigc::slot<void, int>;
+
 //TODO: Docs: Add hints about how to specify the various possible states in the GtkBuilder XML.
   /** A convenience method for creating an integer-based radio SimpleAction instance
    * and adding it to the ActionMap.
@@ -182,13 +200,14 @@ public:
    */
   Glib::RefPtr<SimpleAction> add_action_radio_integer(const Glib::ustring& name, const ActivateWithIntParameterSlot& slot, gint32 state);
 
-protected:
+
 #m4 _CONVERSION(`Glib::RefPtr<Action>', `GAction*', `Glib::unwrap($3)')
   _WRAP_VFUNC(Glib::RefPtr<Action> lookup_action(const Glib::ustring& name) const, "lookup_action", refreturn)
 
-#m4 _CONVERSION(`GAction*', `const Glib::RefPtr<Action>&', `Glib::wrap($3, true)')
-  _WRAP_VFUNC(void add_action(const Glib::RefPtr<Action>& action) const, "add_action")
-
+  //TODO: Change this to use const & when we can break ABI.
+  // ( Changing it causes a symbol lookup error when trying to run already-built applications. )
+#m4 _CONVERSION(`GAction*', `Glib::RefPtr<Action>', `Glib::wrap($3, true)')
+  _WRAP_VFUNC(void add_action(Glib::RefPtr<Action> action) const, "add_action")
   _WRAP_VFUNC(void remove_action(const Glib::ustring& name), "remove_action")
 };
 
index 6be12b9..f239790 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <giomm/file.h>
+#include <glibmm/listhandle.h>
 #include <glibmm/vectorutils.h>
 #include "slot_async.h"
 #include <gio/gio.h>
@@ -24,7 +25,7 @@ namespace Gio
 
 Glib::RefPtr<AppInfo>
 AppInfo::create_from_commandline(
-  const std::string& commandline, const std::string& application_name, CreateFlags flags)
+  const std::string& commandline, const std::string& application_name, AppInfoCreateFlags flags)
 {
   GAppInfo* capp_info = nullptr;
   GError* gerror = nullptr;
@@ -46,14 +47,14 @@ AppInfo::create_duplicate() const
 
 bool
 AppInfo::launch(
-  const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<AppLaunchContext>& launch_context)
+  const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<AppLaunchContext>& context)
 {
   std::vector<Glib::RefPtr<Gio::File>> vec = { file };
 
   GError* gerror = nullptr;
   const bool retvalue = g_app_info_launch(gobj(),
     Glib::ListHandler<Glib::RefPtr<Gio::File>>::vector_to_list(vec).data(),
-    Glib::unwrap(launch_context), &(gerror));
+    Glib::unwrap(context), &(gerror));
   if (gerror)
     ::Glib::Error::throw_exception(gerror);
 
@@ -75,14 +76,14 @@ AppInfo::launch(const Glib::RefPtr<Gio::File>& file)
 }
 
 bool
-AppInfo::launch_uri(const std::string& uri, const Glib::RefPtr<AppLaunchContext>& launch_context)
+AppInfo::launch_uri(const std::string& uri, const Glib::RefPtr<AppLaunchContext>& context)
 {
   std::vector<std::string> vec = { uri };
 
   GError* gerror = nullptr;
   const bool retvalue =
     g_app_info_launch_uris(gobj(), Glib::ListHandler<std::string>::vector_to_list(vec).data(),
-      Glib::unwrap(launch_context), &(gerror));
+      Glib::unwrap(context), &(gerror));
   if (gerror)
     ::Glib::Error::throw_exception(gerror);
 
index b05e13a..0c34ba9 100644 (file)
@@ -25,6 +25,8 @@ _CONFIGINCLUDE(giommconfig.h)
 #include <string>
 
 #include <glibmm/interface.h>
+#include <glibmm/listhandle.h>
+#include <glibmm/arrayhandle.h>
 #include <glibmm/object.h>
 //#include <giomm/file.h>
 #include <giomm/icon.h>
@@ -40,8 +42,9 @@ typedef struct _GAppInfoIface GAppInfoIface;
 namespace Gio
 {
 
+_WRAP_ENUM(AppInfoCreateFlags, GAppInfoCreateFlags, NO_GTYPE)
 
-class File;
+class GIOMM_API File;
 
 /** Application information, to describe applications installed on the system,
  * and launch them.
@@ -49,16 +52,14 @@ class File;
  *
  * @newin{2,16}
  */
-class AppInfo : public Glib::Interface
+class GIOMM_API AppInfo : public Glib::Interface
 {
-  _CLASS_INTERFACE(AppInfo, GAppInfo, G_APP_INFO, GAppInfoIface)
+  _CLASS_INTERFACE(AppInfo, GAppInfo, G_APP_INFO, GAppInfoIface, , , GIOMM_API)
 
 public:
-  _WRAP_ENUM(CreateFlags, GAppInfoCreateFlags, NO_GTYPE)
-
   static Glib::RefPtr<AppInfo> create_from_commandline(const std::string& commandline,
                                                        const std::string& application_name,
-                                                       CreateFlags flags);
+                                                       AppInfoCreateFlags flags);
 
   /**  Creates a duplicate of this AppInfo.
    * @return A duplicate of this AppInfo.
@@ -154,14 +155,19 @@ public:
   _WRAP_METHOD(bool supports_uris() const, g_app_info_supports_uris)
   _WRAP_METHOD(bool supports_files() const, g_app_info_supports_files)
 
-   #m4 _CONVERSION(`const std::vector<std::string>&',`GList*',`Glib::ListHandler<std::string>::vector_to_list($3).data()')
+#m4 _CONVERSION(`const Glib::ListHandle<std::string>&',`GList*',`$3.data()')
+  _WRAP_METHOD(bool launch_uris(const Glib::ListHandle<std::string>& uris,
+                                GAppLaunchContext* context),
+               g_app_info_launch_uris,
+               errthrow, deprecated "Use the method that takes an AppLaunchContext")
 
   //TODO: I think we use Glib::ustring elsewhere for URIs:
-  // 2019-03-14 kjellahl: Glibmm is inconsistent; Glib::ustring in convert.hg,
+  // 2019-03-18 kjellahl: Glibmm is inconsistent; Glib::ustring in convert.hg,
   // std::string in uriutils.hg.
   // The reporter of libxml++ bug https://bugzilla.gnome.org/show_bug.cgi?id=790034
   // proposes std::string.
-  _WRAP_METHOD(bool launch_uris(const std::vector<std::string>& uris,
+#m4 _CONVERSION(`const std::vector<std::string>&',`GList*',`Glib::ListHandler<std::string>::vector_to_list($3).data()')
+  _WRAP_METHOD(bool launch_uris(const Glib::ListHandle<std::string>& uris,
                                 const Glib::RefPtr<AppLaunchContext>& context{?}),
                g_app_info_launch_uris,
                errthrow)
@@ -215,23 +221,23 @@ public:
                g_app_info_remove_supports_type,
                errthrow)
 
-#m4 _CONVERSION(`const char**', `std::vector<Glib::ustring>', `Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
-  _WRAP_METHOD(std::vector<Glib::ustring> get_supported_types() const, g_app_info_get_supported_types)
+#m4 _CONVERSION(`const char**', `Glib::StringArrayHandle', `Glib::StringArrayHandle($3, Glib::OWNERSHIP_NONE)')
+  _WRAP_METHOD(Glib::StringArrayHandle get_supported_types() const, g_app_info_get_supported_types)
 
   _WRAP_METHOD(bool set_as_last_used_for_type(const std::string& content_type), g_app_info_set_as_last_used_for_type, errthrow)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<AppInfo>>',`Glib::ListHandler<Glib::RefPtr<AppInfo>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(static std::vector<Glib::RefPtr<AppInfo>> get_all(), g_app_info_get_all)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle<Glib::RefPtr<AppInfo> >',`Glib::ListHandle<Glib::RefPtr<AppInfo> >($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(static Glib::ListHandle<Glib::RefPtr<AppInfo> > get_all(), g_app_info_get_all)
 
-  _WRAP_METHOD(static std::vector<Glib::RefPtr<AppInfo>> get_all_for_type(const std::string& content_type), g_app_info_get_all_for_type)
+  _WRAP_METHOD(static Glib::ListHandle<Glib::RefPtr<AppInfo> > get_all_for_type(const std::string& content_type), g_app_info_get_all_for_type)
   _WRAP_METHOD(static Glib::RefPtr<AppInfo> get_default_for_type(const std::string& content_type, bool must_support_uris = true), g_app_info_get_default_for_type)
   _WRAP_METHOD(static Glib::RefPtr<AppInfo> get_default_for_uri_scheme(const std::string& uri_scheme), g_app_info_get_default_for_uri_scheme)
   _WRAP_METHOD(static void reset_type_associations(const std::string& content_type), g_app_info_reset_type_associations)
   _WRAP_METHOD(static bool launch_default_for_uri(const std::string& uri, const Glib::RefPtr<AppLaunchContext>& context{?}), g_app_info_launch_default_for_uri, errthrow)
 
   _WRAP_METHOD(static void launch_default_for_uri_async(const std::string& uri, const Glib::RefPtr<AppLaunchContext>& context{.?},
-    const SlotAsyncReady& slot{callback?}, const Glib::RefPtr<Cancellable>& cancellable{.?}),
-    g_app_info_launch_default_for_uri_async, slot_name slot, slot_callback SignalProxy_async_callback)
+    const SlotAsyncReady& slot{callback?}, const Glib::RefPtr<Cancellable>& cancellable{.?}), g_app_info_launch_default_for_uri_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _IGNORE(g_app_info_launch_default_for_uri_async)
   _WRAP_METHOD(static bool launch_default_for_uri_finish(const Glib::RefPtr<AsyncResult>& result), g_app_info_launch_default_for_uri_finish, errthrow)
 
 protected:
@@ -242,10 +248,12 @@ protected:
   //_WRAP_VFUNC(std::string get_description() const, "get_description")
   //_WRAP_VFUNC(std::string get_executable() const, "get_executable")
   //_WRAP_VFUNC(Glib::RefPtr<Icon> get_icon() const, "get_icon")
+//#m4 _CONVERSION(`const Glib::ListHandle<std::string>&',`GList*',`$3.data()')
+//#m4 _CONVERSION(`GList*',`const Glib::ListHandle<std::string>&',`Glib::ListHandle<std::string>($3, Glib::OWNERSHIP_NONE)')
   //_WRAP_VFUNC(bool launch(const std::vector<Gio::File>& filenames, const Glib::RefPtr<AppLaunchContext>& context, GError** error), "launch")
   //_WRAP_VFUNC(bool supports_uris() const, "supports_uris")
   //_WRAP_VFUNC(bool supports_files() const, "supports_files")
-  //_WRAP_VFUNC(bool launch_uris(const std::vector<std::string>& uris, const Glib::RefPtr<AppLaunchContext>& context, GError** error), "launch_uris")
+  //_WRAP_VFUNC(bool launch_uris(const Glib::ListHandle<std::string>& uris, const Glib::RefPtr<AppLaunchContext>& context, GError** error), "launch_uris")
   //_WRAP_VFUNC(bool should_show() const, "should_show")
   //_WRAP_VFUNC(bool set_as_default_for_type(const std::string& content_type, GError** error), "set_as_default_for_type")
   //_WRAP_VFUNC(bool set_as_default_for_extension(const std::string& extension, GError** error), "set_as_default_for_extension")
index f973f08..c81ff36 100644 (file)
@@ -19,6 +19,7 @@
 #include <string>
 
 #include <glibmm/interface.h>
+#include <glibmm/listhandle.h>
 #include <glibmm/object.h>
 //#include <giomm/file.h>
 #include <giomm/icon.h>
@@ -29,17 +30,17 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class AppInfo;
-class File;
+class GIOMM_API AppInfo;
+class GIOMM_API File;
 
 /** This is used to handle, for instance, startup notification and launching of the new application on the same screen as the launching window.
  * See also AppInfo.
  *
  * @newin{2,16}
  */
-class AppLaunchContext : public Glib::Object
+class GIOMM_API AppLaunchContext : public Glib::Object
 {
-  _CLASS_GOBJECT(AppLaunchContext, GAppLaunchContext, G_APP_LAUNCH_CONTEXT, Glib::Object, GObject)
+  _CLASS_GOBJECT(AppLaunchContext, GAppLaunchContext, G_APP_LAUNCH_CONTEXT, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT()
@@ -53,11 +54,11 @@ public:
 #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(std::vector<Glib::ustring> get_environment() const, g_app_launch_context_get_environment)
 
-#m4 _CONVERSION(`const std::vector<std::string>&',`GList*',`Glib::ListHandler<std::string>::vector_to_list$3.data()')
-  _WRAP_METHOD(std::string get_display(const Glib::RefPtr<AppInfo>& info, const std::vector<Glib::RefPtr<Gio::File>>& files),
+#m4 _CONVERSION(`const Glib::ListHandle<std::string>&',`GList*',`$3.data()')
+  _WRAP_METHOD(std::string get_display(const Glib::RefPtr<AppInfo>& info, const Glib::ListHandle< Glib::RefPtr<Gio::File> >& files),
                g_app_launch_context_get_display)
 
-  _WRAP_METHOD(std::string get_startup_notify_id(const Glib::RefPtr<AppInfo>& info, const std::vector<Glib::RefPtr<Gio::File>>& files),
+  _WRAP_METHOD(std::string get_startup_notify_id(const Glib::RefPtr<AppInfo>& info, const Glib::ListHandle< Glib::RefPtr<Gio::File> >& files),
                g_app_launch_context_get_startup_notify_id)
   _WRAP_METHOD(void launch_failed(const std::string& startup_notify_id),
                g_app_launch_context_launch_failed)
index d85ae8d..ab639fb 100644 (file)
 #include <giomm/init.h>
 #include <cstring> // std::memset()
 #include <map>
-#include <mutex>
 #include <vector>
 
-using Flags = Gio::Application::Flags;
-
 namespace // anonymous
 {
+// TODO: At the next ABI break, implement the pimpl idiom. Then we need not use
+// a GQuark for ExtraApplicationData, which should be renamed to
+// struct Gio::Application::Impl.
+// These are new data members that can't be added to Gio::Application now,
+// because it would break ABI.
+struct ExtraApplicationData
+{
+  std::vector<gchar*> option_entry_strings;
+
+  ~ExtraApplicationData()
+  {
+    for (auto str : option_entry_strings)
+    {
+      g_free(str);
+    }
+  }
+};
+
+GQuark quark_extra_application_data =
+  g_quark_from_static_string("glibmm__Gio::Application::quark_extra_application_data");
+
+void
+Application_delete_extra_application_data(gpointer data)
+{
+  ExtraApplicationData* extra_application_data = static_cast<ExtraApplicationData*>(data);
+  delete extra_application_data;
+}
 
 static void
 Application_signal_open_callback(
   GApplication* self, GFile** files, gint n_files, const gchar* hint, void* data)
 {
-  using SlotType = sigc::slot<void(const Gio::Application::type_vec_files&, const Glib::ustring&)>;
+  using SlotType = sigc::slot<void, const Gio::Application::type_vec_files&, const Glib::ustring&>;
 
   Gio::Application::type_vec_files vec_files(n_files);
   for (int i = 0; i < n_files; ++i)
@@ -67,7 +91,7 @@ Application_signal_open_notify_callback(
   GApplication* self, GFile** files, gint n_files, const gchar* hint, void* data)
 {
   using namespace Gio;
-  using SlotType = sigc::slot<void(const Application::type_vec_files&, const Glib::ustring&)>;
+  using SlotType = sigc::slot<void, const Application::type_vec_files&, const Glib::ustring&>;
 
   Application::type_vec_files vec_files(n_files);
   for (int i = 0; i < n_files; i++)
@@ -113,41 +137,26 @@ static const Glib::SignalProxyInfo Application_signal_open_info = { "open",
 class OptionArgCallbackData
 {
 public:
-  explicit OptionArgCallbackData(const Gio::Application* application,
-    const Glib::ustring& long_name, gchar short_name,
-    const Glib::ustring& description, const Glib::ustring& arg_description,
+  explicit OptionArgCallbackData(const Gio::Application* application, gchar short_name,
     const Glib::OptionGroup::SlotOptionArgString& slot)
-  :
-    application_(application),
-    long_name_(g_strdup(long_name.c_str())), // must not be nullptr
+  : application_(application),
     short_name_(short_name),
-    description_(g_strdup(Glib::c_str_or_nullptr(description))),
-    arg_description_(g_strdup(Glib::c_str_or_nullptr(arg_description))),
     slot_string_(new Glib::OptionGroup::SlotOptionArgString(slot)),
     slot_filename_(nullptr)
   {
   }
 
-  explicit OptionArgCallbackData(const Gio::Application* application,
-    const Glib::ustring& long_name, gchar short_name,
-    const Glib::ustring& description, const Glib::ustring& arg_description,
+  explicit OptionArgCallbackData(const Gio::Application* application, gchar short_name,
     const Glib::OptionGroup::SlotOptionArgFilename& slot)
-  :
-    application_(application),
-    long_name_(g_strdup(long_name.c_str())), // must not be nullptr
+  : application_(application),
     short_name_(short_name),
-    description_(g_strdup(Glib::c_str_or_nullptr(description))),
-    arg_description_(g_strdup(Glib::c_str_or_nullptr(arg_description))),
     slot_string_(nullptr),
     slot_filename_(new Glib::OptionGroup::SlotOptionArgFilename(slot))
   {
   }
 
   const Gio::Application* get_application() const { return application_; }
-  const gchar* get_long_name() const { return long_name_; }
   gchar get_short_name() const { return short_name_; }
-  const gchar* get_description() const { return description_; }
-  const gchar* get_arg_description() const { return arg_description_; }
   bool is_filename_option() const { return slot_filename_ != nullptr; }
 
   const Glib::OptionGroup::SlotOptionArgString* get_slot_string() const { return slot_string_; }
@@ -159,9 +168,6 @@ public:
 
   ~OptionArgCallbackData()
   {
-    g_free(long_name_);
-    g_free(description_);
-    g_free(arg_description_);
     delete slot_string_;
     delete slot_filename_;
     // Don't delete application_. It's not owned by this class.
@@ -169,19 +175,15 @@ public:
 
 private:
   const Gio::Application* application_;
-  gchar* long_name_;
   gchar short_name_;
-  gchar* description_;
-  gchar* arg_description_;
   // One of these slot pointers is nullptr and the other one points to a slot.
   Glib::OptionGroup::SlotOptionArgString* slot_string_;
   Glib::OptionGroup::SlotOptionArgFilename* slot_filename_;
 
   // Not copyable
-  OptionArgCallbackData(const OptionArgCallbackData&) = delete;
-  OptionArgCallbackData& operator=(const OptionArgCallbackData&) = delete;
-
-}; // end class OptionArgCallbackData
+  OptionArgCallbackData(const OptionArgCallbackData&);
+  OptionArgCallbackData& operator=(const OptionArgCallbackData&);
+};
 
 using OptionArgCallbackDataMap = std::map<Glib::ustring, OptionArgCallbackData*>;
 OptionArgCallbackDataMap option_arg_callback_data;
@@ -270,13 +272,11 @@ Application::custom_class_init()
   return application_class_.init();
 }
 
-Application::Application(const Glib::ustring& application_id, Flags flags)
+Application::Application(const Glib::ustring& application_id, ApplicationFlags flags)
 : // Mark this class as non-derived to allow C++ vfuncs to be skipped.
-  // GApplication complains about "" but allows nullptr, so we avoid passing "".
   Glib::ObjectBase(nullptr),
-  Glib::Object(Glib::ConstructParams(custom_class_init(),
-    "application_id", Glib::c_str_or_nullptr(application_id),
-    "flags", static_cast<GApplicationFlags>(flags), nullptr))
+  Glib::Object(Glib::ConstructParams(custom_class_init(), "application_id",
+    Glib::c_str_or_nullptr(application_id), "flags", ((GApplicationFlags)(flags)), nullptr))
 {
 }
 
@@ -351,10 +351,10 @@ Application_Class::open_callback(GApplication* self, GFile** files, gint n_files
     (*base->open)(self, files, n_files, hint);
 }
 
-Glib::SignalProxy<void(const Application::type_vec_files&, const Glib::ustring&)>
+Glib::SignalProxy<void, const Application::type_vec_files&, const Glib::ustring&>
 Application::signal_open()
 {
-  return Glib::SignalProxy<void(const Application::type_vec_files&, const Glib::ustring&)>(
+  return Glib::SignalProxy<void, const Application::type_vec_files&, const Glib::ustring&>(
     this, &Application_signal_open_info);
 }
 
@@ -392,67 +392,55 @@ Application::open(const Glib::RefPtr<Gio::File>& file, const Glib::ustring& hint
 void
 Application::add_main_option_entry(OptionType arg_type, const Glib::ustring& long_name,
   gchar short_name, const Glib::ustring& description, const Glib::ustring& arg_description,
-  Glib::OptionEntry::Flags flags)
+  int flags)
 {
-  // g_application_add_main_option() saves copies of the strings.
-  // No need to keep copies in Gio::Application.
-  g_application_add_main_option(gobj(), long_name.c_str(), short_name,
-    static_cast<GOptionFlags>(flags), static_cast<GOptionArg>(arg_type),
-    description.c_str(), Glib::c_str_or_nullptr(arg_description));
+  add_main_option_entry_private(
+    (GOptionArg)arg_type, long_name, short_name, description, arg_description, flags);
 }
 
 void
 Application::add_main_option_entry(const Glib::OptionGroup::SlotOptionArgString& slot,
   const Glib::ustring& long_name, gchar short_name, const Glib::ustring& description,
-  const Glib::ustring& arg_description, Glib::OptionEntry::Flags flags)
+  const Glib::ustring& arg_description, int flags)
 {
-  OptionArgCallbackData* callback_data = nullptr;
   {
     std::lock_guard<std::mutex> lock(option_arg_callback_data_mutex);
     OptionArgCallbackDataMap::iterator iterFind = option_arg_callback_data.find(long_name);
     if (iterFind != option_arg_callback_data.end())
       return; // Ignore duplicates
 
-    callback_data = new OptionArgCallbackData(
-      this, long_name, short_name, description, arg_description, slot);
+    auto callback_data = new OptionArgCallbackData(this, short_name, slot);
     option_arg_callback_data[long_name] = callback_data;
   } // option_arg_callback_data_mutex.unlock()
 
-  add_main_option_entry_private(callback_data->get_long_name(), short_name,
-    callback_data->get_description(), callback_data->get_arg_description(),
-    flags & ~Glib::OptionEntry::Flags::FILENAME);
+  add_main_option_entry_private(G_OPTION_ARG_CALLBACK, long_name, short_name, description,
+    arg_description, flags & ~Glib::OptionEntry::FLAG_FILENAME);
 }
 
 void
 Application::add_main_option_entry_filename(const Glib::OptionGroup::SlotOptionArgFilename& slot,
   const Glib::ustring& long_name, gchar short_name, const Glib::ustring& description,
-  const Glib::ustring& arg_description, Glib::OptionEntry::Flags flags)
+  const Glib::ustring& arg_description, int flags)
 {
-  OptionArgCallbackData* callback_data = nullptr;
   {
     std::lock_guard<std::mutex> lock(option_arg_callback_data_mutex);
     OptionArgCallbackDataMap::iterator iterFind = option_arg_callback_data.find(long_name);
     if (iterFind != option_arg_callback_data.end())
       return; // Ignore duplicates
 
-    callback_data = new OptionArgCallbackData(
-      this, long_name, short_name, description, arg_description, slot);
+    auto callback_data = new OptionArgCallbackData(this, short_name, slot);
     option_arg_callback_data[long_name] = callback_data;
   } // option_arg_callback_data_mutex.unlock()
 
-  add_main_option_entry_private(callback_data->get_long_name(), short_name,
-    callback_data->get_description(), callback_data->get_arg_description(),
-    flags | Glib::OptionEntry::Flags::FILENAME);
+  add_main_option_entry_private(G_OPTION_ARG_CALLBACK, long_name, short_name, description,
+    arg_description, flags | Glib::OptionEntry::FLAG_FILENAME);
 }
 
 void
-Application::add_main_option_entry_private(const gchar* long_name,
-  gchar short_name, const gchar* description,
-  const gchar* arg_description, Glib::OptionEntry::Flags flags)
+Application::add_main_option_entry_private(GOptionArg arg, const Glib::ustring& long_name,
+  gchar short_name, const Glib::ustring& description, const Glib::ustring& arg_description,
+  int flags)
 {
-  // g_application_add_main_option() can't be used for options with
-  // a callback slot, because GOptionEntry.arg_data must be non-null.
-
   // Create a temporary array, just so we can give the correct thing to
   // g_application_add_main_option_entries():
   GOptionEntry array[2];
@@ -461,25 +449,51 @@ Application::add_main_option_entry_private(const gchar* long_name,
   // g_application_add_main_option_entries() does not take its own copy
   // of the strings. We must keep them alive, and keep pointers to them,
   // so we can delete them when the Application instance is deleted.
-  // This is handled in OptionArgCallbackData.
+
+  // GOptionEntry.long_name must be set, even if it's an empty string.
+  gchar* lname = g_strdup(long_name.c_str());
+  gchar* desc = description.empty() ? nullptr : g_strdup(description.c_str());
+  gchar* arg_desc = arg_description.empty() ? nullptr : g_strdup(arg_description.c_str());
+
+  ExtraApplicationData* extra_application_data =
+    static_cast<ExtraApplicationData*>(g_object_get_qdata(gobject_, quark_extra_application_data));
+  if (!extra_application_data)
+  {
+    extra_application_data = new ExtraApplicationData();
+    g_object_set_qdata_full(gobject_, quark_extra_application_data, extra_application_data,
+      Application_delete_extra_application_data);
+  }
+
+  extra_application_data->option_entry_strings.emplace_back(lname);
+  if (desc)
+    extra_application_data->option_entry_strings.emplace_back(desc);
+  if (arg_desc)
+    extra_application_data->option_entry_strings.emplace_back(arg_desc);
 
   // Fill in array[0].
-  array[0].arg = G_OPTION_ARG_CALLBACK;
-  array[0].long_name = long_name;
+  array[0].arg = arg;
+  array[0].long_name = lname;
   array[0].short_name = short_name;
-  array[0].description = description;
-  array[0].arg_description = arg_description;
-  array[0].flags = static_cast<int>(flags);
-
-  // GoptionEntry.arg_data is a function pointer, cast to void*.
-  // See Glib::OptionGroup::CppOptionEntry::allocate_c_arg() for a discussion
-  // of this hack.
-  union {
-    void* dp;
-    GOptionArgFunc fp;
-  } u;
-  u.fp = &Application_option_arg_callback;
-  array[0].arg_data = u.dp;
+  array[0].description = desc;
+  array[0].arg_description = arg_desc;
+  array[0].flags = flags;
+
+  if (arg == G_OPTION_ARG_CALLBACK)
+  {
+    // GoptionEntry.arg_data is a function pointer, cast to void*.
+    // See Glib::OptionGroup::CppOptionEntry::allocate_c_arg() for a discussion
+    // of this hack.
+    union {
+      void* dp;
+      GOptionArgFunc fp;
+    } u;
+    u.fp = &Application_option_arg_callback;
+    array[0].arg_data = u.dp;
+  }
+  else
+    // We ensure that this is null to ensure that it is not used,
+    // telling GApplication to put the parsed value in the options VariantDict instead.
+    array[0].arg_data = nullptr;
 
   g_application_add_main_option_entries(gobj(), array);
 }
@@ -490,4 +504,14 @@ Application::unset_resource_base_path()
   g_application_set_resource_base_path(gobj(), nullptr /* see the C docs. */);
 }
 
+Glib::PropertyProxy< std::string > Application::property_resource_base_path_string()
+{
+  return Glib::PropertyProxy< std::string >(this, "resource-base-path");
+}
+
+Glib::PropertyProxy_ReadOnly< std::string > Application::property_resource_base_path_string() const
+{
+  return Glib::PropertyProxy_ReadOnly< std::string >(this, "resource-base-path");
+}
+
 } // namespace Gio
index 3a3b8e0..a8bf966 100644 (file)
@@ -34,6 +34,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
+_WRAP_ENUM(ApplicationFlags, GApplicationFlags)
 
 /** Application - Core application class.
  * An Application is the foundation of an application, unique for a given
@@ -82,15 +83,12 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class Application : public Glib::Object, public ActionGroup, public ActionMap
+class GIOMM_API Application : public Glib::Object, public ActionGroup, public ActionMap
 {
-  _CLASS_GOBJECT(Application, GApplication, G_APPLICATION, Glib::Object, GObject)
+  _CLASS_GOBJECT(Application, GApplication, G_APPLICATION, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(ActionGroup)
   _IMPLEMENTS_INTERFACE(ActionMap)
 
-public:
-  _WRAP_ENUM(Flags, GApplicationFlags, s#^FLAGS_##)
-
 protected:
   /** Constructs an application instance.
    * If no application ID is given then some features (most notably application uniqueness) will be disabled.
@@ -98,20 +96,18 @@ protected:
    * @param application_id The application ID.
    * @param flags The application flags.
    */
-  explicit Application(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE);
+  explicit Application(const Glib::ustring& application_id = Glib::ustring(), ApplicationFlags flags = APPLICATION_FLAGS_NONE);
   _IGNORE(g_application_new)
 
 public:
   _CUSTOM_DTOR()
 
-  // Application::OptionType wraps GOptionArg, but _WRAP_ENUM can't be used here.
-  // GOptionArg is defined in glib_enums.defs, not in gio_enums.defs.
   /** The OptionType enum values determine the expected type of a command line option.
    * If an option expects an extra argument, it can be specified in several ways;
    * with a short option: "-x arg", with a long option: "--name arg" or combined
-   * in a single argument: "--name=arg". All option types except OptionType::BOOL
-   * expect an extra argument. OptionType::STRING_VECTOR and
-   * OptionType::FILENAME_VECTOR accept more than one extra argument.
+   * in a single argument: "--name=arg". All option types except OPTION_TYPE_BOOL
+   * expect an extra argument. OPTION_TYPE_STRING_VECTOR and
+   * OPTION_TYPE_FILENAME_VECTOR accept more than one extra argument.
    *
    * The descriptions of the enum values show what type of Glib::Variant<>
    * is stored in a Glib::VariantDict.
@@ -120,17 +116,17 @@ public:
    *
    * @ingroup glibmmEnums
    */
-  enum class OptionType
+  enum OptionType
   {
-    BOOL,   ///< bool
-    STRING, ///< Glib::ustring
-    INT,    ///< gint32
-    // CALLBACK,
-    FILENAME = INT+2, ///< std::string
-    STRING_VECTOR,    ///< std::vector<Glib::ustring>
-    FILENAME_VECTOR,  ///< std::vector<std::string>
-    DOUBLE,           ///< double
-    INT64             ///< gint64
+    OPTION_TYPE_BOOL,   ///< bool
+    OPTION_TYPE_STRING, ///< Glib::ustring
+    OPTION_TYPE_INT,    ///< gint32
+    //OPTION_TYPE_CALLBACK,
+    OPTION_TYPE_FILENAME = OPTION_TYPE_INT+2, ///< std::string
+    OPTION_TYPE_STRING_VECTOR,   ///< std::vector<Glib::ustring>
+    OPTION_TYPE_FILENAME_VECTOR, ///< std::vector<std::string>
+    OPTION_TYPE_DOUBLE,          ///< double
+    OPTION_TYPE_INT64            ///< gint64
   };
 
   /** Creates an application instance.
@@ -139,7 +135,7 @@ public:
    * @param application_id The application ID.
    * @param flags The application flags.
    */
-  _WRAP_CREATE(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE)
+  _WRAP_CREATE(const Glib::ustring& application_id = Glib::ustring(), ApplicationFlags flags = APPLICATION_FLAGS_NONE)
 
   _WRAP_METHOD(static bool id_is_valid(const Glib::ustring& application_id), g_application_id_is_valid)
 
@@ -155,8 +151,8 @@ public:
   _WRAP_METHOD(guint get_inactivity_timeout() const, g_application_get_inactivity_timeout)
   _WRAP_METHOD(void set_inactivity_timeout(guint inactivity_timeout), g_application_set_inactivity_timeout)
 
-  _WRAP_METHOD(Flags get_flags() const, g_application_get_flags)
-  _WRAP_METHOD(void set_flags(Flags flags), g_application_set_flags)
+  _WRAP_METHOD(ApplicationFlags get_flags() const, g_application_get_flags)
+  _WRAP_METHOD(void set_flags(ApplicationFlags flags), g_application_set_flags)
 
   _WRAP_METHOD(std::string get_resource_base_path() const, g_application_get_resource_base_path, newin "2,44")
   _WRAP_METHOD(void set_resource_base_path(const std::string& resource_path), g_application_set_resource_base_path, newin "2,44")
@@ -167,7 +163,8 @@ public:
    */
   void unset_resource_base_path();
 
-  _IGNORE(g_application_set_action_group)
+  _WRAP_METHOD(void set_action_group(const Glib::RefPtr<ActionGroup>& action_group), g_application_set_action_group,
+    deprecated "Use the Gio::ActionMap interface instead.")
 
   //Note: We would like to add a group, not just some entries,
   //so we can do pre and post parsing. See https://bugzilla.gnome.org/show_bug.cgi?id=727602
@@ -186,7 +183,7 @@ public:
    * Unlike OptionGroup + OptionContext, Application packs the arguments
    * into a Glib::VariantDict which is passed to the
    * signal_handle_local_options() handler, where it can be
-   * inspected and modified. If Gio::Application::Flags::HANDLES_COMMAND_LINE is
+   * inspected and modified. If Gio::APPLICATION_HANDLES_COMMAND_LINE is
    * set, then the resulting dictionary is sent to the primary instance,
    * where Gio::ApplicationCommandLine::get_options_dict() will return it.
    * This "packing" is done according to the type of the argument --
@@ -206,7 +203,7 @@ public:
    * on the local side.  Calling this function "opts in" to the new
    * behaviour, and in particular, means that unrecognised options will be
    * treated as errors.  Unrecognised options have never been ignored when
-   * Gio::Application::Flags::HANDLES_COMMAND_LINE is unset.
+   * Gio::APPLICATION_HANDLES_COMMAND_LINE is unset.
    *
    * If signal_handle_local_options() needs to see the list of
    * filenames, then the use of G_OPTION_REMAINING as @a long_name is recommended.
@@ -229,14 +226,17 @@ public:
    * @param description The description for the option in `--help` output.
    * @param arg_description The placeholder to use for the extra argument parsed
    *     by the option in `--help` output.
-   * @param flags Flags from Glib::OptionEntry::Flags. Do not set OptionEntry::Flags::FILENAME.
+   * @param flags Flags from Glib::OptionEntry::Flags. Do not set FLAG_FILENAME.
    *     Character encoding is chosen with @a arg_type.
    */
   void add_main_option_entry(OptionType arg_type, const Glib::ustring& long_name,
-    gchar short_name = '\0', const Glib::ustring& description = {},
-    const Glib::ustring& arg_description = {},
-    Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
-  _IGNORE(g_application_add_main_option_entries, g_application_add_main_option)
+    gchar short_name = '\0', const Glib::ustring& description = Glib::ustring(),
+    const Glib::ustring& arg_description = Glib::ustring(), int flags = 0);
+  _IGNORE(g_application_add_main_option_entries)
+
+  //g_application_add_main_option() seems to be just a new convenience function,
+  //TODO: Use it for some of our add_main_option_entry(without slot) implementation.
+  _IGNORE(g_application_add_main_option)
 
   /** Adds a main option entry to be handled by the Application.
    *
@@ -251,13 +251,12 @@ public:
    * @newin{2,42}
    *
    * @see add_main_option_entry(OptionType, const Glib::ustring&,
-   *   gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
+   *   gchar, const Glib::ustring&, const Glib::ustring&, int)
    */
   void add_main_option_entry(const Glib::OptionGroup::SlotOptionArgString& slot,
     const Glib::ustring& long_name,
-    gchar short_name = '\0', const Glib::ustring& description = {},
-    const Glib::ustring& arg_description = {},
-    Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
+    gchar short_name = '\0', const Glib::ustring& description = Glib::ustring(),
+    const Glib::ustring& arg_description = Glib::ustring(), int flags = 0);
 
   /** Adds a main option entry to be handled by the Application.
    *
@@ -272,16 +271,15 @@ public:
    * @newin{2,42}
    *
    * @see add_main_option_entry(OptionType, const Glib::ustring&,
-   *   gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
+   *   gchar, const Glib::ustring&, const Glib::ustring&, int)
    */
   void add_main_option_entry_filename(const Glib::OptionGroup::SlotOptionArgFilename& slot,
     const Glib::ustring& long_name,
-    gchar short_name = '\0', const Glib::ustring& description = {},
-    const Glib::ustring& arg_description = {},
-    Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
+    gchar short_name = '\0', const Glib::ustring& description = Glib::ustring(),
+    const Glib::ustring& arg_description = Glib::ustring(), int flags = 0);
 
   // GApplication takes ownership of the GOptionGroup, unrefing it later.
-#m4 _CONVERSION(`Glib::OptionGroup&',`GOptionGroup*',`($3).gobj_copy()')
+#m4 _CONVERSION(`Glib::OptionGroup&',`GOptionGroup*',`($3).gobj_give_ownership()')
   /** Adds a Glib::OptionGroup to the commandline handling of the application.
    *
    * This function is comparable to Glib::OptionContext::add_group().
@@ -305,7 +303,7 @@ public:
    * Calling this function will cause the options in the supplied option
    * group to be parsed, but it does not cause you to be "opted in" to the
    * new functionality whereby unrecognised options are rejected even if
-   * Gio::Application::Flags::HANDLES_COMMAND_LINE was given.
+   * Gio::APPLICATION_HANDLES_COMMAND_LINE was given.
    *
    * @newin{2,62}
    *
@@ -341,14 +339,14 @@ public:
    * opening files (eg: "view" vs "edit", etc).
    *
    * The application must be registered before calling this method
-   * and it must have the Application::Flags::HANDLES_OPEN flag set.
+   * and it must have the APPLICATION_HANDLES_OPEN flag set.
    *
    * @param files The files to open. This must be non-empty.
    * @param hint A hint.
    *
    * @newin{2,32}
    */
-  void open(const type_vec_files& files, const Glib::ustring& hint = {});
+  void open(const type_vec_files& files, const Glib::ustring& hint = Glib::ustring());
   _IGNORE(g_application_open)
 
   /* Opens the given file.
@@ -361,14 +359,14 @@ public:
    * opening files (eg: "view" vs "edit", etc).
    *
    * The application must be registered before calling this method
-   * and it must have the Application::Flags::HANDLES_OPEN flag set.
+   * and it must have the APPLICATION_HANDLES_OPEN flag set.
    *
    * @param file The file to open. This must be non-empty.
    * @param hint A hint.
    *
    * @newin{2,32}
    */
-  void open(const Glib::RefPtr<Gio::File>& file, const Glib::ustring& hint = {});
+  void open(const Glib::RefPtr<Gio::File>& file, const Glib::ustring& hint = Glib::ustring());
 
   _WRAP_METHOD(int run(int argc, char** argv), g_application_run)
 
@@ -393,35 +391,68 @@ public:
 //  _WRAP_METHOD(void bind_busy_property(const Glib::RefPtr<Glib::ObjectBase>& object, const Glib::ustring& property), g_application_bind_busy_property)
 //  _WRAP_METHOD(void unbind_busy_property(const Glib::RefPtr<Glib::ObjectBase>& object, const Glib::ustring& property), g_application_unbind_busy_property)
 
-  _IGNORE_PROPERTY("action-group")
+  _WRAP_PROPERTY("action-group", Glib::RefPtr<ActionGroup>, deprecated "Use the Gio::ActionMap interface instead.")
   _WRAP_PROPERTY("application-id", Glib::ustring)
-  _WRAP_PROPERTY("flags", Flags)
+  _WRAP_PROPERTY("flags", ApplicationFlags)
   _WRAP_PROPERTY("inactivity-timeout", guint)
   _WRAP_PROPERTY("is-registered", bool)
   _WRAP_PROPERTY("is-remote", bool)
-  _WRAP_PROPERTY("resource-base-path", std::string, newin "2,44")
+
+  //TODO: Change bool to std::string when we can break API/ABI.
+  _WRAP_PROPERTY("resource-base-path", bool, newin "2,44",
+    deprecated "This method has the wrong return type. Will be fixed at the next ABI break. Use property_resource_base_path_string() instead.")
+
+  /** The base resource path for the application.
+   *
+   * @newin{2,56}
+   *
+   * Default value: ""
+   *
+   * @return A PropertyProxy that allows you to get or set the value of the property,
+   * or receive notification when the value of the property changes.
+   */
+  Glib::PropertyProxy< std::string > property_resource_base_path_string();
+
+  /** The base resource path for the application.
+   *
+   * @newin{2,56}
+   *
+   * Default value: ""
+   *
+   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
+   * or receive notification when the value of the property changes.
+   */
+  Glib::PropertyProxy_ReadOnly< std::string > property_resource_base_path_string() const;
+
   _WRAP_PROPERTY("is-busy", bool)
 
+//#m4 _CONVERSION(`const gchar*', `const Glib::ustring&', `Glib::ustring($3)')
+//#m4 _CONVERSION(`GVariant*', `const Glib::VariantBase&', `Glib::wrap($3, true)')
+
   _WRAP_SIGNAL(void startup(), "startup")
-  _WRAP_SIGNAL(void shutdown(), "shutdown", newin "2,46")
+
+  //TODO: Remove no_default_handler when we can break ABI
+  _WRAP_SIGNAL(void shutdown(), "shutdown", no_default_handler, newin "2,46")
+
   _WRAP_SIGNAL(void activate(), "activate")
 
   //We wrap the open signal without _WRAP_SIGNAL(), because we need to change its parameters.
   //See bug https://bugzilla.gnome.org/show_bug.cgi?id=637457
-  Glib::SignalProxy<void(const type_vec_files&, const Glib::ustring&)> signal_open();
+  Glib::SignalProxy< void,  const type_vec_files&, const Glib::ustring& > signal_open();
   _IGNORE_SIGNAL(open)
 
 #m4 _CONVERSION(`GApplicationCommandLine*', `const Glib::RefPtr<ApplicationCommandLine>&',`Glib::wrap($3, true)')
   _WRAP_SIGNAL(int command_line(const Glib::RefPtr<ApplicationCommandLine>& command_line), "command-line")
 
+  //TODO: Remove no_default_handler when we can break ABI
   //TODO: Avoid the use of the Variants in the VariantDict?
   //options must be non-const. The handler is meant to modify it. See the description
   //of add_main_option_entry(OptionType, ...).
 #m4 _CONVERSION(`GVariantDict*',`const Glib::RefPtr<Glib::VariantDict>&',`Glib::wrap($3, true)')
-#m4 _CONVERSION(`const Glib::RefPtr<Glib::VariantDict>&',`GVariantDict*',__CONVERT_REFPTR_TO_P)
-  _WRAP_SIGNAL(int handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options), "handle-local-options")
+  _WRAP_SIGNAL(int handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options), "handle-local-options", no_default_handler)
 
-  _WRAP_SIGNAL(bool name_lost(), "name-lost")
+  //TODO: Remove no_default_handler when we can break ABI
+  _WRAP_SIGNAL(bool name_lost(), "name-lost", no_default_handler)
 
 protected:
   virtual void on_open(const type_vec_files& files, const Glib::ustring& hint);
@@ -439,6 +470,7 @@ protected:
   _WRAP_VFUNC(bool local_command_line(char**& arguments, int& exit_status), local_command_line)
 
 #m4 _CONVERSION(`GVariant*',`const Glib::VariantBase&',`Glib::wrap($3,true)')
+
   _WRAP_VFUNC(void before_emit(const Glib::VariantBase& platform_data), "before_emit")
   _WRAP_VFUNC(void after_emit(const Glib::VariantBase& platform_data), "after_emit")
 
@@ -448,21 +480,19 @@ protected:
   _WRAP_VFUNC(void quit_mainloop(), "quit_mainloop")
   _WRAP_VFUNC(void run_mainloop(), "run_mainloop")
 
-#m4 _CONVERSION(`GDBusConnection*', `const Glib::RefPtr<DBus::connection>&', `Glib::wrap($3, true)')
-#m4 _CONVERSION(`const Glib::RefPtr<DBus::Connection>&',`GDBusConnection*',__CONVERT_REFPTR_TO_P)
-  _WRAP_VFUNC(bool dbus_register(const Glib::RefPtr<DBus::Connection>& connection, const Glib::ustring& object_path), "dbus_register", errthrow)
-  _WRAP_VFUNC(void dbus_unregister(const Glib::RefPtr<DBus::Connection>& connection, const Glib::ustring& object_path), "dbus_unregister")
 
 private:
-  /** This is just a way to call Glib::init() before calling a Glib::Object ctor,
-   * so that glibmm's GQuarks are created before they are used.
+  /** This is just a way to call Glib::init() (which calls g_type_init()) before
+   * calling application_class_.init(), so that
+   * g_application_get_type() will always succeed.
+   * See https://bugzilla.gnome.org/show_bug.cgi?id=639925
    */
   const Glib::Class& custom_class_init();
 
-  // Code, common to the public add_main_option_entry*() methods with a callback slot.
-  void add_main_option_entry_private(const gchar* long_name, gchar short_name,
-    const gchar* description, const gchar* arg_description,
-    Glib::OptionEntry::Flags flags);
+  // Code, common to the public add_main_option_entry*() methods.
+  void add_main_option_entry_private(GOptionArg arg, const Glib::ustring& long_name,
+    gchar short_name, const Glib::ustring& description,
+    const Glib::ustring& arg_description, int flags);
 };
 
 } // namespace Gio
index 3c11745..1bc0a09 100644 (file)
@@ -54,9 +54,9 @@ namespace Gio
  * return until the editing is done.
  * @newin{2,32}
  */
-class ApplicationCommandLine : public Glib::Object
+class GIOMM_API ApplicationCommandLine : public Glib::Object
 {
-  _CLASS_GOBJECT(ApplicationCommandLine, GApplicationCommandLine, G_APPLICATION_COMMAND_LINE, Glib::Object, GObject)
+  _CLASS_GOBJECT(ApplicationCommandLine, GApplicationCommandLine, G_APPLICATION_COMMAND_LINE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
index 6961edd..842ec45 100644 (file)
@@ -29,7 +29,7 @@ typedef struct _GAsyncInitableIface GAsyncInitableIface;
 namespace Gio
 {
 
-class Cancellable;
+class GIOMM_API Cancellable;
 
 /** AsyncInitable - Asynchronously failable object initialization interface.
  * This is the asynchronous version of Initable; it behaves the same in all
@@ -45,9 +45,9 @@ class Cancellable;
  * g_async_initable_init_async() under the cover, calling back with nullptr and a
  * set GError on failure.
  */
-class AsyncInitable : public Glib::Interface
+class GIOMM_API AsyncInitable : public Glib::Interface
 {
-  _CLASS_INTERFACE(AsyncInitable, GAsyncInitable, G_ASYNC_INITABLE, GAsyncInitableIface)
+  _CLASS_INTERFACE(AsyncInitable, GAsyncInitable, G_ASYNC_INITABLE, GAsyncInitableIface, , , GIOMM_API)
 
 protected:
   /** Starts asynchronous initialization of the object implementing the
index 5570bba..4fc4b9a 100644 (file)
@@ -37,7 +37,7 @@ AsyncResult::get_source_object_base()
 
   auto cobj = g_async_result_get_source_object(gobj());
   auto cppobj = Glib::wrap_auto(cobj); // ObjectBase::_get_current_wrapper(cobj);
-  return Glib::make_refptr_for_instance<Glib::ObjectBase>(
+  return Glib::RefPtr<Glib::ObjectBase>(
     cppobj); // g_async_result_get_source_object() gives us a ref, unusually.
 }
 
index 892072b..e31aa28 100644 (file)
@@ -29,80 +29,99 @@ typedef struct _GAsyncResultIface GAsyncResultIface;
 namespace Gio
 {
 
-class AsyncResult;
+class GIOMM_API AsyncResult;
 
 /** A function that will be called when an asynchronous operation within GIO has been completed.
  * @param result The asynchronous function's results.
  *
  * For instance,
  * @code
- * void on_async_ready(Glib::RefPtr<AsyncResult>& result);
+ * void on_async_ready(Glib::RefPtr<Gio::AsyncResult>& result);
  * @endcode
  *
  * @newin{2,16}
+ * @relates Gio::AsyncResult
  */
-using SlotAsyncReady = sigc::slot<void(Glib::RefPtr<AsyncResult>&)>;
+using SlotAsyncReady = sigc::slot<void, Glib::RefPtr<AsyncResult>&>;
 
 /** Provides a base class for implementing asynchronous function results.
+ *
  * Asynchronous operations are broken up into two separate operations which are chained together by a SlotAsyncReady.
  * To begin an asynchronous operation, provide a SlotAsyncReady to the asynchronous function. This callback will be triggered
- * when the operation has completed, and will be passed an AsyncResult instance filled with the details of the operation's success or
- * failure, the object the asynchronous function was started for and any error codes returned. The asynchronous callback function is then
- * expected to call the corresponding "_finish()" function with the object the function was called for, and the AsyncResult instance.
+ * when the operation has completed, and will be passed an %AsyncResult instance
+ * (an instance of a class that implements the %AsyncResult interface)
+ * filled with the details of the operation's success or failure,
+ * the object the asynchronous function was started for and any error codes returned. The asynchronous callback function is then
+ * expected to call the corresponding "_finish()" function of the object the async function was called for, with the %AsyncResult instance.
  *
- * The purpose of the "_finish()" function is to take the generic result of type AsyncResult and return the specific result that the operation
+ * The purpose of the "_finish()" function is to take the generic result of type %AsyncResult and return the specific result that the operation
  * in question yields (e.g. a FileEnumerator for an "enumerate children" operation). If the result or error status of the operation is not needed,
  * there is no need to call the "_finish()" function and GIO will take care of cleaning up the result and error information after the
- * SlotAsyncReady returns. You may also store the AsyncResult and call "_finish()" later.
+ * SlotAsyncReady returns. You may also store the %AsyncResult and call "_finish()" later.
+ * However, the "_finish()" function may be called at most once.
  *
  * Example of a typical asynchronous operation flow:
  * @code
- * void _theoretical_frobnitz_async(const Glib::RefPtr<Theoretical>& t,
- *                                  const SlotAsyncReady& slot);
- *
- * gboolean _theoretical_frobnitz_finish(const Glib::RefPtr<Theoretical>& t,
- *                                       const Glib::RefPtr<AsyncResult>& result);
- *
- * static void
- * on_frobnitz_result(Glib::RefPtr<AsyncResult>& result)
+ * class Theoretical : public Glib::Object
  * {
+ * public:
+ *   Glib::RefPtr<Theoretical> create();
  *
- *   Glib::RefPtr<Glib::Object> source_object = result->get_source_object();
- *   bool success = _theoretical_frobnitz_finish(source_object, res);
+ *   void frobnitz_async(const Gio::SlotAsyncReady& slot);
+ *   Glib::ustring frobnitz_finish(const Glib::RefPtr<Gio::AsyncResult>& result);
+ * // ...
+ * };
  *
- *   if (success)
- *     std::cout << "Hurray" << std::endl;
- *   else
- *     std::cout << "Uh oh!" << std::endl;
+ * // ...
  *
- *   ...
- * }
- *
- * int main (int argc, void *argv[])
+ * namespace
  * {
- *    ...
+ * Glib::RefPtr<Theoretical> theoretical;
  *
- *    _theoretical_frobnitz_async (theoretical_data,
- *                                 sigc::ptr_fun(&on_frobnitz_result) );
+ * void on_frobnitz_ready(Glib::RefPtr<Gio::AsyncResult>& result)
+ * {
+ *   try
+ *   {
+ *     Glib::ustring s = theoretical->frobnitz_finish(result);
+ *     std::cout << s << std::endl;
+ *   }
+ *   catch (const Glib::Error& err)
+ *   {
+ *     std::cerr << err.what() << std::endl;
+ *   }
+ *   // ...
+ * }
+ * } // anonymous namespace
  *
- *    ...
+ * int main(int argc, void* argv[])
+ * {
+ *   // ...
+ *   theoretical = Theoretical::create();
+ *   theoretical->frobnitz_async(sigc::ptr_fun(&on_frobnitz_ready));
+ *   // ...
  * }
  * @endcode
  *
- * The async function could also take an optional Glib::Cancellable object, allowing the calling function to cancel the asynchronous operation.
+ * The async function could also take an optional Gio::Cancellable object, allowing the calling function to cancel the asynchronous operation.
  *
  * The callback for an asynchronous operation is called only once, and is always called, even in the case of a cancelled operation.
- * On cancellation, the result is an <tt>ERROR_CANCELLED</tt> error.
+ * On cancellation the "_finish()" function will throw a Gio::Error exception with a <tt>Gio::Error::CANCELLED</tt> error code.
  *
  * @newin{2,16}
  */
-class AsyncResult : public Glib::Interface
+class GIOMM_API AsyncResult : public Glib::Interface
 {
-  _CLASS_INTERFACE(AsyncResult, GAsyncResult, G_ASYNC_RESULT, GAsyncResultIface)
+  _CLASS_INTERFACE(AsyncResult, GAsyncResult, G_ASYNC_RESULT, GAsyncResultIface, , , GIOMM_API)
 
 public:
   _IGNORE(g_async_result_get_user_data)
-  _IGNORE(g_async_result_get_source_object)
+
+  //Note that this returns a reference, unlike most GTK+ get_*() functions,
+  //so we don't need to use refreturn.
+  _WRAP_METHOD(Glib::RefPtr<Glib::Object> get_source_object(),
+               g_async_result_get_source_object, deprecated "Use get_source_object_base()")
+  _WRAP_METHOD(Glib::RefPtr<const Glib::Object> get_source_object() const,
+               g_async_result_get_source_object, constversion, deprecated "Use get_source_object_base()")
 
   //Note that this returns a reference, unlike most GTK+ get_*() functions,
   //so we don't need to use refreturn.
@@ -113,13 +132,15 @@ public:
 
   _WRAP_METHOD(bool is_tagged(gpointer source_tag) const, g_async_result_is_tagged)
 
-protected:
   // The compiler cannot find an unwrap() for ObjectBase, because
   // ObjectBase::BaseObjectType is not declared.
   //#m4 _CONVERSION(`Glib::RefPtr<Glib::ObjectBase>',`GObject*',__CONVERT_REFPTR_TO_P)
 #m4 _CONVERSION(`Glib::RefPtr<Glib::ObjectBase>',`GObject*',`unwrap_objectbase_custom($3)')
-  _WRAP_VFUNC(Glib::RefPtr<Glib::ObjectBase> get_source_object(), "get_source_object")
-  _WRAP_VFUNC(bool is_tagged(gpointer source_tag), "is_tagged")
+  _WRAP_VFUNC(Glib::RefPtr<Glib::ObjectBase> get_source_object(),
+              "get_source_object")
+
+  //TODO: is_tagged() vfunc when we can break ABI.
 };
 
 } // namespace Gio
+
index 56dfe24..7c82808 100644 (file)
@@ -23,7 +23,7 @@ namespace Gio
 Glib::RefPtr<BufferedInputStream>
 BufferedInputStream::create_sized(const Glib::RefPtr<InputStream>& base_stream, gsize buffer_size)
 {
-  return Glib::make_refptr_for_instance<Gio::BufferedInputStream>(new BufferedInputStream(base_stream, buffer_size));
+  return Glib::RefPtr<Gio::BufferedInputStream>(new BufferedInputStream(base_stream, buffer_size));
 }
 
 void
index d93c665..4e5ecb2 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <giomm/filterinputstream.h>
-#include <giomm/seekable.h>
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -40,11 +39,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class BufferedInputStream : public Gio::FilterInputStream, public Gio::Seekable
+class GIOMM_API BufferedInputStream : public Gio::FilterInputStream
 {
-  _CLASS_GOBJECT(BufferedInputStream, GBufferedInputStream, G_BUFFERED_INPUT_STREAM, Gio::FilterInputStream, GFilterInputStream)
-  _IMPLEMENTS_INTERFACE(Seekable)
-
+  _CLASS_GOBJECT(BufferedInputStream, GBufferedInputStream, G_BUFFERED_INPUT_STREAM, Gio::FilterInputStream, GFilterInputStream, , , GIOMM_API)
 protected:
   _WRAP_CTOR(BufferedInputStream(const Glib::RefPtr<InputStream>& base_stream), g_buffered_input_stream_new)
 
@@ -109,8 +106,9 @@ public:
   _WRAP_PROPERTY("buffer-size", guint)
 
 protected:
+  //TODO: When we can break ABI, add vfunc. See https://bugzilla.gnome.org/show_bug.cgi?id=572471
 #m4 _CONVERSION(`GCancellable*', `const Glib::RefPtr<Cancellable>&', `Glib::wrap($3, true)')
-  _WRAP_VFUNC(gssize fill(gssize count, const Glib::RefPtr<Cancellable>& cancellable), fill, errthrow, err_return_value -1)
+  //_WRAP_VFUNC(gssize fill(gssize count, const Glib::RefPtr<Cancellable>& cancellable), fill, errthrow, err_return_value -1)
 };
 
 } // namespace Gio
index 80e9d07..c334f5c 100644 (file)
@@ -23,7 +23,7 @@ namespace Gio
 Glib::RefPtr<BufferedOutputStream>
 BufferedOutputStream::create_sized(const Glib::RefPtr<OutputStream>& base_stream, gsize size)
 {
-  return Glib::make_refptr_for_instance<Gio::BufferedOutputStream>(new BufferedOutputStream(base_stream, size));
+  return Glib::RefPtr<Gio::BufferedOutputStream>(new BufferedOutputStream(base_stream, size));
 }
 
 } // namespace Gio
index 846411f..0d07670 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2008 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -15,7 +17,6 @@
  */
 
 #include <giomm/filteroutputstream.h>
-#include <giomm/seekable.h>
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -36,11 +37,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class BufferedOutputStream : public Gio::FilterOutputStream, public Gio::Seekable
+class GIOMM_API BufferedOutputStream : public Gio::FilterOutputStream
 {
-  _CLASS_GOBJECT(BufferedOutputStream, GBufferedOutputStream, G_BUFFERED_OUTPUT_STREAM, Gio::FilterOutputStream, GFilterOutputStream)
-  _IMPLEMENTS_INTERFACE(Seekable)
-
+  _CLASS_GOBJECT(BufferedOutputStream, GBufferedOutputStream, G_BUFFERED_OUTPUT_STREAM, Gio::FilterOutputStream, GFilterOutputStream, , , GIOMM_API)
 protected:
   _WRAP_CTOR(BufferedOutputStream(const Glib::RefPtr<OutputStream>& base_stream), g_buffered_output_stream_new)
 
index b4cb956..85976e3 100644 (file)
@@ -14,6 +14,7 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
 
 #include <glibmm/object.h>
 
@@ -28,15 +29,15 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class Cancellable : public Glib::Object
+class GIOMM_API Cancellable : public Glib::Object
 {
-  _CLASS_GOBJECT(Cancellable, GCancellable, G_CANCELLABLE, Glib::Object, GObject)
+  _CLASS_GOBJECT(Cancellable, GCancellable, G_CANCELLABLE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
 
 public:
-  using SlotCancelledCallback = sigc::slot<void()>;
+  using SlotCancelledCallback = sigc::slot<void>;
 
   _WRAP_CREATE()
 
index a5d5029..f4218b5 100644 (file)
@@ -23,7 +23,6 @@ CharsetConverter::CharsetConverter(
   const Glib::ustring& to_charset, const Glib::ustring& from_charset)
 : _CONSTRUCT("to-charset", to_charset.c_str(), "from-charset", from_charset.c_str())
 {
-  init();
 }
 
 } // namespace Gio
index d5679b7..fb7ee55 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <glibmm/object.h>
 #include <giomm/converter.h>
-#include <giomm/initable.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -28,16 +27,14 @@ namespace Gio
  * CharsetConverter is an implementation of Converter based on GIConv.
  * @newin{2,34}
  */
-class CharsetConverter
-: public Glib::Object, public Converter, public Initable
+class GIOMM_API CharsetConverter : public Glib::Object, public Converter
 {
-  _CLASS_GOBJECT(CharsetConverter, GCharsetConverter, G_CHARSET_CONVERTER, Glib::Object, GObject)
+  _CLASS_GOBJECT(CharsetConverter, GCharsetConverter, G_CHARSET_CONVERTER, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Converter)
-  _IMPLEMENTS_INTERFACE(Initable)
 
 protected:
-  // Handwritten to ignore the final GError** parameter in the *_new() function.
-  // But it can throw, due to its call to Initable::init().
+  // Handwritten to ignore the final GError** parameter in the *_new()
+  // function.
   explicit CharsetConverter(const Glib::ustring& to_charset, const Glib::ustring& from_charset);
   _IGNORE(g_charset_converter_new)
 
@@ -48,8 +45,7 @@ public:
    *
    * @param to_charset Destination charset.
    * @param from_charset Source charset.
-   * @return A new CharsetConverter, or <tt>nullptr</tt> on error.
-   * @throw Gio::Error
+   * @return A new CharsetConverter, or <tt>0</tt> on error.
    */
   _WRAP_CREATE(const Glib::ustring& to_charset, const Glib::ustring& from_charset)
 
index 508a1c7..7f97a55 100644 (file)
@@ -16,9 +16,6 @@
 
 #include <gio/gio.h>
 
-using Flags = Gio::Converter::Flags;
-using Result = Gio::Converter::Result;
-
 namespace Gio
 {
 
index 21f8e08..ce0691c 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -27,6 +29,8 @@ typedef struct _GConverterIface GConverterIface;
 namespace Gio
 {
 
+_WRAP_ENUM(ConverterResult, GConverterResult)
+_WRAP_ENUM(ConverterFlags, GConverterFlags)
 
 /** Converter - Data conversion interface.
  * Converter is implemented by objects that convert binary data in various
@@ -37,20 +41,16 @@ namespace Gio
  *
  * @newin{2,34}
  */
-class Converter : public Glib::Interface
+class GIOMM_API Converter : public Glib::Interface
 {
-  _CLASS_INTERFACE(Converter, GConverter, G_CONVERTER, GConverterIface)
+  _CLASS_INTERFACE(Converter, GConverter, G_CONVERTER, GConverterIface, , , GIOMM_API)
 
 public:
-  _WRAP_ENUM(Result, GConverterResult)
-  _WRAP_ENUM(Flags, GConverterFlags)
-
-  _WRAP_METHOD(Result convert(const void* inbuf, gsize inbuf_size, void* outbuf, gsize outbuf_size, Flags flags, gsize& bytes_read, gsize& bytes_written), g_converter_convert, errthrow)
+  _WRAP_METHOD(ConverterResult convert(const void* inbuf, gsize inbuf_size, void* outbuf, gsize outbuf_size, ConverterFlags flags, gsize& bytes_read, gsize& bytes_written), g_converter_convert, errthrow)
   _WRAP_METHOD(void reset(), g_converter_reset)
 
-protected:
 #m4 _CONVERSION(`gsize*',`gsize&',`*($3)')
-  _WRAP_VFUNC(Result convert(const void* inbuf, gsize inbuf_size, void* outbuf, gsize outbuf_size, Flags flags, gsize& bytes_read, gsize& bytes_written), "convert", errthrow)
+  _WRAP_VFUNC(ConverterResult convert(const void* inbuf, gsize inbuf_size, void* outbuf, gsize outbuf_size, ConverterFlags flags, gsize& bytes_read, gsize& bytes_written), "convert", errthrow)
 
   _WRAP_VFUNC(void reset(), "reset")
 };
index ae65e59..9f221d6 100644 (file)
@@ -23,8 +23,8 @@ _PINCLUDE(giomm/private/filterinputstream_p.h)
 namespace Gio
 {
 
-class Converter;
-class InputStream;
+class GIOMM_API Converter;
+class GIOMM_API InputStream;
 
 /** ConverterInputstream - Converter Input Stream.
  * Converter input stream implements InputStream and allows conversion of data
@@ -32,10 +32,10 @@ class InputStream;
  * PollableInputStream interface.
  * @newin{2,34}
  */
-class ConverterInputStream : public FilterInputStream,
-                             public PollableInputStream
+class GIOMM_API ConverterInputStream : public FilterInputStream,
+                                       public PollableInputStream
 {
-  _CLASS_GOBJECT(ConverterInputStream, GConverterInputStream, G_CONVERTER_INPUT_STREAM, FilterInputStream, GFilterInputStream)
+  _CLASS_GOBJECT(ConverterInputStream, GConverterInputStream, G_CONVERTER_INPUT_STREAM, FilterInputStream, GFilterInputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(PollableInputStream)
 
 protected:
index 1729aac..7634898 100644 (file)
@@ -23,8 +23,8 @@ _PINCLUDE(giomm/private/filteroutputstream_p.h)
 namespace Gio
 {
 
-class Converter;
-class OutputStream;
+class GIOMM_API Converter;
+class GIOMM_API OutputStream;
 
 /** ConverterOutputstream - Converter Output Stream.
  * Converter output stream implements OutputStream and allows conversion of
@@ -32,10 +32,10 @@ class OutputStream;
  * the PollableOutputStream interface.
  * @newin{2,34}
  */
-class ConverterOutputStream : public FilterOutputStream,
-                              public PollableOutputStream
+class GIOMM_API ConverterOutputStream : public FilterOutputStream,
+                                        public PollableOutputStream
 {
-  _CLASS_GOBJECT(ConverterOutputStream, GConverterOutputStream, G_CONVERTER_OUTPUT_STREAM, FilterOutputStream, GFilterOutputStream)
+  _CLASS_GOBJECT(ConverterOutputStream, GConverterOutputStream, G_CONVERTER_OUTPUT_STREAM, FilterOutputStream, GFilterOutputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(PollableOutputStream)
 
 protected:
index 7bbcdef..66c6cca 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -22,6 +24,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
+_WRAP_ENUM(CredentialsType, GCredentialsType, NO_GTYPE)
 
 /** An object containing credentials.
  * The Credentials type is a reference-counted wrapper for native credentials.
@@ -45,29 +48,27 @@ namespace Gio
  *
  * @newin{2,28}
  */
-class Credentials : public Glib::Object
+class GIOMM_API Credentials : public Glib::Object
 {
-  _CLASS_GOBJECT(Credentials, GCredentials, G_CREDENTIALS, Glib::Object, GObject)
+  _CLASS_GOBJECT(Credentials, GCredentials, G_CREDENTIALS, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
   _IGNORE(g_credentials_new)
 
 public:
-  _WRAP_ENUM(Type, GCredentialsType, NO_GTYPE)
-
   _WRAP_CREATE()
 
   _WRAP_METHOD(Glib::ustring to_string() const, g_credentials_to_string)
 
-  _WRAP_METHOD(gpointer get_native(Type native_type), g_credentials_get_native)
-  _WRAP_METHOD(void set_native(Type native_type, gpointer native), g_credentials_set_native)
-  _WRAP_METHOD(bool is_same_user(const Glib::RefPtr<const Credentials>& other_credentials), g_credentials_is_same_user, errthrow "Gio::Error")
+  _WRAP_METHOD(gpointer get_native(CredentialsType native_type), g_credentials_get_native)
+  _WRAP_METHOD(void set_native(CredentialsType native_type, gpointer native), g_credentials_set_native)
+  _WRAP_METHOD(bool is_same_user(const Glib::RefPtr<const Credentials>& other_credentials), g_credentials_is_same_user, errthrow)
 
-  _WRAP_METHOD(uid_t get_unix_user(), g_credentials_get_unix_user, errthrow "Gio::Error", ifdef G_OS_UNIX)
-  _WRAP_METHOD(bool set_unix_user(uid_t uid), g_credentials_set_unix_user, errthrow "Gio::Error", ifdef G_OS_UNIX)
+  _WRAP_METHOD(uid_t get_unix_user(), g_credentials_get_unix_user, errthrow, ifdef G_OS_UNIX)
+  _WRAP_METHOD(bool set_unix_user(uid_t uid), g_credentials_set_unix_user, errthrow, ifdef G_OS_UNIX)
 
-  _WRAP_METHOD(pid_t get_unix_pid() const, g_credentials_get_unix_pid, errthrow "Gio::Error", ifdef G_OS_UNIX)
+  _WRAP_METHOD(pid_t get_unix_pid() const, g_credentials_get_unix_pid, errthrow, ifdef G_OS_UNIX)
 };
 
 
index d5b31b4..6291141 100644 (file)
@@ -93,6 +93,85 @@ DataInputStream::read_line_finish(const Glib::RefPtr<AsyncResult>& result, std::
   return retval;
 }
 
+_DEPRECATE_IFDEF_START
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+bool
+DataInputStream::read_until(
+  std::string& data, const std::string& stop_chars, const Glib::RefPtr<Cancellable>& cancellable)
+{
+  GError* gerror = nullptr;
+  char* c_str = g_data_input_stream_read_until(gobj(), stop_chars.c_str(),
+    nullptr, // pass nullptr since we can easily determine the length from the returned std::string
+    Glib::unwrap(cancellable), &gerror);
+  if (gerror)
+    ::Glib::Error::throw_exception(gerror);
+  if (c_str)
+  {
+    data = c_str;
+    g_free(c_str);
+    return true;
+  }
+  // end of stream reached, return failure status
+  return false;
+}
+
+/** non-cancellable version of read_until()
+ */
+bool
+DataInputStream::read_until(std::string& data, const std::string& stop_chars)
+{
+  GError* gerror = nullptr;
+  char* c_str = g_data_input_stream_read_until(gobj(), stop_chars.c_str(),
+    nullptr, // pass nullptr since we can easily determine the length from the returned std::string
+    nullptr, &gerror);
+  if (gerror)
+    ::Glib::Error::throw_exception(gerror);
+  if (c_str)
+  {
+    data = c_str;
+    g_free(c_str);
+    return true;
+  }
+  // end of stream reached, return failure status
+  return false;
+}
+
+void
+DataInputStream::read_until_async(const std::string& stop_chars, const SlotAsyncReady& slot,
+  const Glib::RefPtr<Cancellable>& cancellable, int io_priority)
+{
+  // Create a copy of the slot.
+  // A pointer to it will be passed through the callback's data parameter
+  // and deleted in the callback.
+  auto slot_copy = new SlotAsyncReady(slot);
+
+  g_data_input_stream_read_until_async(gobj(), stop_chars.c_str(), io_priority,
+    Glib::unwrap(cancellable), &SignalProxy_async_callback, slot_copy);
+}
+
+bool
+DataInputStream::read_until_finish(const Glib::RefPtr<AsyncResult>& result, std::string& data)
+{
+  GError* gerror = nullptr;
+  gsize size = 0;
+  gchar* buffer =
+    g_data_input_stream_read_until_finish(gobj(), Glib::unwrap(result), &size, &(gerror));
+  if (gerror)
+    ::Glib::Error::throw_exception(gerror);
+
+  bool retval = false;
+  if (buffer && size)
+  {
+    retval = (buffer != nullptr);
+    data = std::string(buffer, size);
+    g_free(buffer);
+  }
+
+  return retval;
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+_DEPRECATE_IFDEF_END
+
 bool
 DataInputStream::read_upto(
   std::string& data, const std::string& stop_chars, const Glib::RefPtr<Cancellable>& cancellable)
index 157f894..27cc684 100644 (file)
@@ -31,9 +31,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class DataInputStream : public Gio::BufferedInputStream
+class GIOMM_API DataInputStream : public Gio::BufferedInputStream
 {
-  _CLASS_GOBJECT(DataInputStream, GDataInputStream, G_DATA_INPUT_STREAM, Gio::BufferedInputStream, GBufferedInputStream)
+  _CLASS_GOBJECT(DataInputStream, GDataInputStream, G_DATA_INPUT_STREAM, Gio::BufferedInputStream, GBufferedInputStream, , , GIOMM_API)
 
 protected:
   _WRAP_CTOR(DataInputStream(const Glib::RefPtr<InputStream>& base_stream), g_data_input_stream_new)
@@ -138,14 +138,85 @@ public:
    */
   _WRAP_METHOD(void read_line_finish_utf8(const Glib::RefPtr<AsyncResult>& result{.}, std::string& data{OUT}, gsize& length{.?}), g_data_input_stream_read_line_finish_utf8, errthrow)
 
-  _IGNORE(g_data_input_stream_read_until, g_data_input_stream_read_until_async,
-    g_data_input_stream_read_until_finish)dnl// deprecated
+_DEPRECATE_IFDEF_START
+  /** Reads a string from the data input stream, up to the first
+   * occurrence of any of the stop characters.
+   *
+   * Note that, in contrast to read_until_async(),
+   * this function consumes the stop character that it finds.
+   *
+   * Don't use this function in new code.  Its functionality is
+   * inconsistent with read_until_async(). Use
+   * read_upto() instead, but note that that method
+   * does not consume the stop character.
+   *
+   * @param[out] data A string to fill with the read data.
+   * @param stop_chars Characters to terminate the read.
+   * @param cancellable A cancellable object.
+   * @result true if the read succeeded without error.
+   *
+   * @deprecated Use read_upto() instead, which has more consistent behaviour regarding the stop character.
+   */
+  bool read_until(std::string& data, const std::string& stop_chars, const Glib::RefPtr<Cancellable>& cancellable);
+  _IGNORE(g_data_input_stream_read_until)
+
+  /** A non-cancellable version of read_until().
+   *
+   * Note that, in contrast to read_until_async(),
+   * this function consumes the stop character that it finds.
+   *
+   * Don't use this function in new code.  Its functionality is
+   * inconsistent with read_until_async(). Use
+   * read_upto() instead, but note that that method
+   * does not consume the stop character.
+   *
+   * @param[out] data A string to fill with the read data.
+   * @param stop_chars Characters to terminate the read.
+   * @result true if the read succeeded without error.
+   *
+   * @deprecated Use read_upto() instead, which has more consistent behaviour regarding the stop character.
+   */
+  bool read_until(std::string& data, const std::string& stop_chars);
+
+  /** The asynchronous version of read_until(). It is
+   * an error to have two outstanding calls to this function.
+   *
+   * Note that, in contrast to read_until(),
+   * this function does not consume the stop character that it finds.  You
+   * must read it for yourself.
+   *
+   * Don't use this function in new code.  Its functionality is
+   * inconsistent with read_until(). Use read_upto_async() instead.
+   *
+   * @param stop_chars Characters to terminate the read.
+   * @param slot The slot to call when the request is satisfied.
+   * @param cancellable A cancellable object.
+   * @param io_priority The I/O priority of the request.
+   *
+   * @deprecated Use read_upto_async() instead, which has more consistent behaviour regarding the stop character.
+   */
+  void read_until_async(const std::string& stop_chars, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, int io_priority = Glib::PRIORITY_DEFAULT);
+  _IGNORE(g_data_input_stream_read_until_async)
+
+  /** Finish an asynchronous call started by read_until_async().
+   *
+   * @param result The AsyncResult that was provided to the callback slot.
+   * @param[out] data A string to fill with the read data.
+   * @result true if the read succeeded without error.
+   *
+   * @deprecated Use read_upto_finish() instead, which has more consistent behaviour regarding the stop character.
+   */
+  bool read_until_finish(const Glib::RefPtr<AsyncResult>& result, std::string& data);
+  _IGNORE(g_data_input_stream_read_until_finish)
+_DEPRECATE_IFDEF_END
 
  /** Reads a string from the data input stream, up to the first
    * occurrence of any of the stop characters.
    *
-   * This method does <em>not</em> consume the stop character. You have
-   * to use read_byte() to get it before calling %read_upto() again.
+   * In contrast to read_until(), this method
+   * does <em>not</em> consume the stop character. You have
+   * to use read_byte() to get it before calling
+   * read_upto() again.
    *
    * @param[out] data A string to fill with the read data.
    * @param stop_chars Characters to terminate the read.
@@ -167,8 +238,10 @@ public:
   /** The asynchronous version of read_upto(). It is
    * an error to have two outstanding calls to this function.
    *
-   * This method does <em>not</em> consume the stop character. You have
-   * to use read_byte() to get it before calling %read_upto_async() again.
+   * In contrast to read_until(), this method
+   * does <em>not</em> consume the stop character. You have
+   * to use read_byte() to get it before calling
+   * read_upto() again.
    *
    * @param stop_chars Characters to terminate the read.
    * @param slot The slot to call when the request is satisfied.
index aec65bf..749bc34 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <giomm/filteroutputstream.h>
-#include <giomm/seekable.h>
+#include <giomm/bufferedoutputstream.h>
 #include <giomm/enums.h>
 
 _DEFS(giomm,gio)
-_PINCLUDE(giomm/private/filteroutputstream_p.h)
+_PINCLUDE(giomm/private/bufferedoutputstream_p.h)
 
 namespace Gio
 {
 
 /**
- * An implementation of FilterOutputStream that allows for high-level data
+ * An implementation of BufferedOutputStream that allows for high-level data
  * manipulation of arbitrary data (including binary operations).
  *
  * @ingroup Streams
  *
  * @newin{2,16}
  */
-class DataOutputStream : public Gio::FilterOutputStream, public Gio::Seekable
+class GIOMM_API DataOutputStream : public Gio::BufferedOutputStream
 {
-  _CLASS_GOBJECT(DataOutputStream, GDataOutputStream, G_DATA_OUTPUT_STREAM, Gio::FilterOutputStream, GFilterOutputStream)
-  _IMPLEMENTS_INTERFACE(Seekable)
+  _CLASS_GOBJECT(DataOutputStream, GDataOutputStream, G_DATA_OUTPUT_STREAM, Gio::BufferedOutputStream, GBufferedOutputStream, , , GIOMM_API)
 
 protected:
   _WRAP_CTOR(DataOutputStream(const Glib::RefPtr<OutputStream>& base_stream), g_data_output_stream_new)
@@ -61,9 +59,10 @@ public:
 
   _WRAP_METHOD(bool put_uint64(guint64 data, const Glib::RefPtr<Cancellable>& cancellable{?}), g_data_output_stream_put_uint64, errthrow)
 
-  _WRAP_METHOD(bool put_string(const std::string& str, const Glib::RefPtr<Cancellable>& cancellable{?}), g_data_output_stream_put_string, errthrow)
+  _WRAP_METHOD(bool put_string(std::string str, const Glib::RefPtr<Cancellable>& cancellable{?}), g_data_output_stream_put_string, errthrow)
 
   _WRAP_PROPERTY("byte-order", DataStreamByteOrder)
 };
 
 } // namespace Gio
+
index fde6a35..ae9bb6f 100644 (file)
@@ -27,7 +27,7 @@ namespace Gio
 namespace DBus
 {
 
-class Connection;
+class GIOMM_API Connection;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -37,12 +37,12 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * Gio::DBus::Connection::export_action_group().
  * @newin{2,32}
  */
-class ActionGroup
-: public Glib::Object, public Gio::ActionGroup, public Gio::RemoteActionGroup
+class GIOMM_API ActionGroup
+: public Glib::Object, public ::Gio::ActionGroup, public RemoteActionGroup
 {
-  _CLASS_GOBJECT(ActionGroup, GDBusActionGroup, G_DBUS_ACTION_GROUP, Glib::Object, GObject)
-  _IMPLEMENTS_INTERFACE(Gio::ActionGroup)
-  _IMPLEMENTS_INTERFACE(Gio::RemoteActionGroup)
+  _CLASS_GOBJECT(ActionGroup, GDBusActionGroup, G_DBUS_ACTION_GROUP, Glib::Object, GObject, , , GIOMM_API)
+  _IMPLEMENTS_INTERFACE(::Gio::ActionGroup)
+  _IMPLEMENTS_INTERFACE(RemoteActionGroup)
 
 protected:
   _CTOR_DEFAULT
index aa105e7..7993892 100644 (file)
@@ -38,6 +38,7 @@ namespace Address
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_address(const std::string& string);
 
 /** Like is_address() but also checks if the library supports the transports
@@ -50,6 +51,7 @@ bool is_address(const std::string& string);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_supported(const std::string& address);
 
 /** Asynchronously connects to an endpoint specified by @a address and sets up
@@ -68,10 +70,12 @@ bool is_supported(const std::string& address);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 void get_stream(const std::string& address, const SlotAsyncReady slot,
   const Glib::RefPtr<Cancellable>& cancellable);
 
 /// A non-cancellable version of get_stream().
+GIOMM_API
 void get_stream(const std::string& address, const SlotAsyncReady slot);
 
 /** Finishes an operation started with get_stream().
@@ -85,6 +89,7 @@ void get_stream(const std::string& address, const SlotAsyncReady slot);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_finish(const Glib::RefPtr<AsyncResult>& res,
   std::string& out_guid);
 
@@ -97,6 +102,7 @@ Glib::RefPtr<IOStream> get_stream_finish(const Glib::RefPtr<AsyncResult>& res,
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_finish(const Glib::RefPtr<AsyncResult>& res);
 
 /** Synchronously connects to an endpoint specified by @a address and sets up
@@ -115,10 +121,12 @@ Glib::RefPtr<IOStream> get_stream_finish(const Glib::RefPtr<AsyncResult>& res);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_sync(const std::string& address,
   const Glib::RefPtr<Cancellable>& cancellable, std::string& out_guid);
 
 /// A non-cancellable version of get_stream_sync().
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_sync(const std::string& address,
   std::string& out_guid);
 
@@ -136,10 +144,12 @@ Glib::RefPtr<IOStream> get_stream_sync(const std::string& address,
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_sync(const std::string& address,
   const Glib::RefPtr<Cancellable>& cancellable);
 
 /// A non-cancellable version of get_stream_sync().
+GIOMM_API
 Glib::RefPtr<IOStream> get_stream_sync(const std::string& address);
 
 /** Synchronously looks up the D-Bus address for the well-known message bus
@@ -153,10 +163,12 @@ Glib::RefPtr<IOStream> get_stream_sync(const std::string& address);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 std::string get_for_bus_sync(BusType bus_type,
   const Glib::RefPtr<Cancellable>& cancellable);
 
 /// A non-cancellable get_for_bus_sync().
+GIOMM_API
 std::string get_for_bus_sync(BusType bus_type);
 
 } // namespace Address
index 03876c0..df2536e 100644 (file)
@@ -66,9 +66,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,28}
  * @ingroup DBus
  */
-class AuthObserver : public Glib::Object
+class GIOMM_API AuthObserver : public Glib::Object
 {
-  _CLASS_GOBJECT(AuthObserver, GDBusAuthObserver, G_DBUS_AUTH_OBSERVER, Glib::Object, GObject)
+  _CLASS_GOBJECT(AuthObserver, GDBusAuthObserver, G_DBUS_AUTH_OBSERVER, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
index a7464c2..e28e7b4 100644 (file)
 #include <giomm/dbusmethodinvocation.h>
 #include <giomm/dbuserror.h>
 #include <giomm/menumodel.h>
+
+#ifdef G_OS_UNIX
 #include <giomm/unixfdlist.h>
+#endif
+
 #include "slot_async.h"
+#include <mutex>
 
 namespace
 {
@@ -84,7 +89,16 @@ DBusConnection_Message_Filter_giomm_callback_destroy(void* data)
 }
 
 } // extern "C"
-}
+
+// Glib::wrap(GDBusConnection* object, bool take_copy) must be protected by a
+// mutex while a C++ wrapper is being constructed. The same GDBusConnection
+// instance can be used in more than one thread. The wrap() function can be
+// called simultaneously in different threads for the same GDBusConnection
+// instance before it has been given a C++ wrapper.
+// https://gitlab.gnome.org/GNOME/glibmm/issues/56
+std::mutex wrap_mutex;
+
+} // anonymous namespace
 
 namespace Gio
 {
@@ -278,7 +292,7 @@ Connection::create_sync(const Glib::RefPtr<IOStream>& stream, const std::string&
   const Glib::RefPtr<AuthObserver>& observer, const Glib::RefPtr<Cancellable>& cancellable,
   ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(stream, guid, observer, cancellable, flags));
+  return Glib::RefPtr<Connection>(new Connection(stream, guid, observer, cancellable, flags));
 }
 
 // static
@@ -286,7 +300,7 @@ Glib::RefPtr<Connection>
 Connection::create_sync(const Glib::RefPtr<IOStream>& stream, const std::string& guid,
   const Glib::RefPtr<Cancellable>& cancellable, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(stream, guid, cancellable, flags));
+  return Glib::RefPtr<Connection>(new Connection(stream, guid, cancellable, flags));
 }
 
 // static
@@ -294,7 +308,7 @@ Glib::RefPtr<Connection>
 Connection::create_sync(const Glib::RefPtr<IOStream>& stream, const std::string& guid,
   const Glib::RefPtr<AuthObserver>& observer, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(stream, guid, observer, flags));
+  return Glib::RefPtr<Connection>(new Connection(stream, guid, observer, flags));
 }
 
 // static
@@ -302,7 +316,7 @@ Glib::RefPtr<Connection>
 Connection::create_sync(
   const Glib::RefPtr<IOStream>& stream, const std::string& guid, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(stream, guid, flags));
+  return Glib::RefPtr<Connection>(new Connection(stream, guid, flags));
 }
 
 // static
@@ -352,7 +366,7 @@ Connection::create_for_address_sync(const std::string& address,
   const Glib::RefPtr<AuthObserver>& observer, const Glib::RefPtr<Cancellable>& cancellable,
   ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(address, observer, cancellable, flags));
+  return Glib::RefPtr<Connection>(new Connection(address, observer, cancellable, flags));
 }
 
 // static
@@ -360,7 +374,7 @@ Glib::RefPtr<Connection>
 Connection::create_for_address_sync(
   const std::string& address, const Glib::RefPtr<Cancellable>& cancellable, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(address, cancellable, flags));
+  return Glib::RefPtr<Connection>(new Connection(address, cancellable, flags));
 }
 
 // static
@@ -368,14 +382,14 @@ Glib::RefPtr<Connection>
 Connection::create_for_address_sync(
   const std::string& address, const Glib::RefPtr<AuthObserver>& observer, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(address, observer, flags));
+  return Glib::RefPtr<Connection>(new Connection(address, observer, flags));
 }
 
 // static
 Glib::RefPtr<Connection>
 Connection::create_for_address_sync(const std::string& address, ConnectionFlags flags)
 {
-  return Glib::make_refptr_for_instance<Connection>(new Connection(address, flags));
+  return Glib::RefPtr<Connection>(new Connection(address, flags));
 }
 
 // static
@@ -722,3 +736,25 @@ Connection::register_subtree(
 } // namespace DBus
 
 } // namespace Gio
+
+namespace Glib
+{
+
+Glib::RefPtr<Gio::DBus::Connection> wrap(GDBusConnection* object, bool take_copy)
+{
+  Glib::ObjectBase* pCppObject = nullptr;
+  if (!ObjectBase::_get_current_wrapper((GObject*)object))
+  {
+    // 'object' does not yet have a C++ wrapper. Construction of the C++ wrapper
+    // must be thread-safe. See comments at the definition of wrap_mutex.
+    std::lock_guard<std::mutex> lock(wrap_mutex);
+    pCppObject = Glib::wrap_auto((GObject*)object, take_copy);
+  }
+  else
+    pCppObject = Glib::wrap_auto((GObject*)object, take_copy);
+
+  return Glib::RefPtr<Gio::DBus::Connection>(dynamic_cast<Gio::DBus::Connection*>(pCppObject));
+  //We use dynamic_cast<> in case of multiple inheritance.
+}
+
+} // namespace Glib
index 306f870..1cc7a37 100644 (file)
@@ -33,20 +33,20 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class ActionGroup;
-class MenuModel;
-class UnixFDList;
+class GIOMM_API ActionGroup;
+class GIOMM_API MenuModel;
+class GIOMM_API UnixFDList;
 
 
 namespace DBus
 {
 
 _WRAP_ENUM(BusType, GBusType)
-_WRAP_ENUM(CallFlags, GDBusCallFlags, NO_GTYPE)
-_WRAP_ENUM(ConnectionFlags, GDBusConnectionFlags, gtype_func g_dbus_connection_flags_get_type)
-_WRAP_ENUM(SendMessageFlags, GDBusSendMessageFlags, NO_GTYPE)
-_WRAP_ENUM(SignalFlags, GDBusSignalFlags, NO_GTYPE)
-_WRAP_ENUM(SubtreeFlags, GDBusSubtreeFlags, NO_GTYPE)
+_WRAP_ENUM(CallFlags, GDBusCallFlags, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(ConnectionFlags, GDBusConnectionFlags, s#^DBUS_##, gtype_func g_dbus_connection_flags_get_type)
+_WRAP_ENUM(SendMessageFlags, GDBusSendMessageFlags, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(SignalFlags, GDBusSignalFlags, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(SubtreeFlags, GDBusSubtreeFlags, s#^DBUS_##, NO_GTYPE)
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -71,13 +71,14 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,28}
  * @ingroup DBus
  */
-class Connection
+class GIOMM_API Connection
 : public Glib::Object, public Initable, public AsyncInitable
 {
 protected:
-  _CLASS_GOBJECT(Connection, GDBusConnection, G_DBUS_CONNECTION, Glib::Object, GObject)
+  _CLASS_GOBJECT(Connection, GDBusConnection, G_DBUS_CONNECTION, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Initable)
   _IMPLEMENTS_INTERFACE(AsyncInitable)
+  _CUSTOM_WRAP_FUNCTION
 
 protected:
 
@@ -172,9 +173,9 @@ public:
    * Glib::ustring& signal_name, const Glib::VariantContainerBase& parameters);.
    * @endcode
    */
-  using SlotSignal = sigc::slot<void(const Glib::RefPtr<Connection>&,
+  using SlotSignal = sigc::slot<voidconst Glib::RefPtr<Connection>&,
     const Glib::ustring&, const Glib::ustring&, const Glib::ustring&,
-    const Glib::ustring&, const Glib::VariantContainerBase&)>;
+    const Glib::ustring&, const Glib::VariantContainerBase&>;
 
   /** Signature for slot used in add_filter().
    *  For example,
@@ -190,9 +191,9 @@ public:
    * drop a message can simply return <tt>0</tt>.  And filter function may
    * modify a message by copying it and return the copy.
    */
-  using SlotMessageFilter = sigc::slot<Glib::RefPtr<Message>(
+  using SlotMessageFilter = sigc::slot<Glib::RefPtr<Message>,
     const Glib::RefPtr<Connection>&,
-    const Glib::RefPtr<Message>&, bool)>;
+    const Glib::RefPtr<Message>&, bool>;
 
   /** Asynchronously connects to the message bus specified by @a bus_type.
    *
@@ -216,6 +217,8 @@ public:
    */
   static void get(BusType bus_type, const SlotAsyncReady& slot);
 
+  _WRAP_METHOD_DOCS_ONLY( g_bus_get_finish, errthrow)
+  /// @throw Glib::Error.
   _WRAP_METHOD(static Glib::RefPtr<Connection> get_finish(const Glib::RefPtr<AsyncResult>& res), g_bus_get_finish, errthrow)
 
   _WRAP_METHOD(static Glib::RefPtr<Connection> get_sync(BusType bus_type, const Glib::RefPtr<Cancellable>& cancellable{?}), g_bus_get_sync, errthrow)
@@ -226,28 +229,30 @@ public:
     const Glib::RefPtr<AuthObserver>& observer,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new)
   static void create(const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create().
   static void create(const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
     const SlotAsyncReady& slot,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create().
   static void create(const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const SlotAsyncReady& slot,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_finish)
+  /// @throw Glib::Error.
   _WRAP_METHOD(static Glib::RefPtr<Connection> create_finish(const Glib::RefPtr<AsyncResult>& res), g_dbus_connection_new_finish, errthrow)
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address)
@@ -255,78 +260,84 @@ public:
     const Glib::RefPtr<AuthObserver>& observer,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address)
   static void create_for_address(const std::string& address,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_address().
   static void create_for_address(const std::string& address,
     const Glib::RefPtr<AuthObserver>& observer,
     const SlotAsyncReady& slot,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_address().
   static void create_for_address(const std::string& address,
     const SlotAsyncReady& slot,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address_finish)
+  /// @throw Glib::Error.
   _WRAP_METHOD(static Glib::RefPtr<Connection> create_for_address_finish(const Glib::RefPtr<AsyncResult>& res), g_dbus_connection_new_for_address_finish, errthrow)
 
-  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_sync, errthrow)
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_sync)
+  /// @throw Glib::Error.
   static Glib::RefPtr<Connection> create_sync(
     const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
-  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_sync, errthrow)
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_sync)
+  /// @throw Glib::Error.
   static Glib::RefPtr<Connection> create_sync(
     const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_sync().
   static Glib::RefPtr<Connection> create_sync(
     const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_sync().
   static Glib::RefPtr<Connection> create_sync(
     const Glib::RefPtr<IOStream>& stream,
     const std::string& guid,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
-  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address_sync, errthrow)
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address_sync)
+  /// @throw Glib::Error.
   static Glib::RefPtr<Connection> create_for_address_sync(
     const std::string& address,
     const Glib::RefPtr<AuthObserver>& observer,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
-  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address_sync, errthrow)
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_new_for_address_sync)
+  /// @throw Glib::Error.
   static Glib::RefPtr<Connection> create_for_address_sync(
     const std::string& address,
     const Glib::RefPtr<Cancellable>& cancellable,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_address_sync().
   static Glib::RefPtr<Connection> create_for_address_sync(
     const std::string& address,
     const Glib::RefPtr<AuthObserver>& observer,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_address_sync().
   static Glib::RefPtr<Connection> create_for_address_sync(
     const std::string& address,
-    ConnectionFlags flags = Gio::DBus::ConnectionFlags::NONE);
+    ConnectionFlags flags = Gio::DBus::CONNECTION_FLAGS_NONE);
 
   /** Closes the connection. Note that this never causes the process to exit
    * (this might only happen if the other end of a shared message bus
@@ -478,11 +489,11 @@ public:
 
   /// A send_message() without an "out_serial" parameter.
   bool send_message(const Glib::RefPtr<Message>& message,
-    SendMessageFlags flags = Gio::DBus::SendMessageFlags::NONE);
+    SendMessageFlags flags = Gio::DBus::SEND_MESSAGE_FLAGS_NONE);
 
   /** Asynchronously sends message to the peer represented by the connection.
    *
-   * Unless flags contain the Gio::DBus::SendMessageFlags::PRESERVE_SERIAL
+   * Unless flags contain the Gio::DBus::SEND_MESSAGE_FLAGS_PRESERVE_SERIAL
    * flag, the serial number will be assigned by the connection and set on
    * message via Gio::DBus::Message::set_serial().
    *
@@ -498,7 +509,7 @@ public:
    * send_message_with_reply_sync() for the synchronous version.
    *
    * Note that message must be unlocked, unless flags contain the
-   * Gio::DBus::SendMessageFlags::PRESERVE_SERIAL flag.
+   * Gio::DBus::SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag.
    *
    * See the C API docs for examples.
    *
@@ -522,6 +533,8 @@ public:
     int timeout_msec,
     const SlotAsyncReady& slot);
 
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_connection_send_message_with_reply_finish)
+  /// @throw Glib::Error.
   _WRAP_METHOD(Glib::RefPtr<Message> send_message_with_reply_finish(const Glib::RefPtr<AsyncResult>& res), g_dbus_connection_send_message_with_reply_finish, errthrow)
 
   /** Synchronously sends @a message to the peer represented by the connection
@@ -529,7 +542,7 @@ public:
    * reached. See send_message_with_reply() for the asynchronous version of
    * this method.
    *
-   * Unless flags contain the Gio::DBus::SendMessageFlags::PRESERVE_SERIAL
+   * Unless flags contain the Gio::DBus::SEND_MESSAGE_FLAGS_PRESERVE_SERIAL
    * flag, the serial number will be assigned by the connection and set on
    * message via Gio::DBus::Message::set_serial().
    *
@@ -546,7 +559,7 @@ public:
    * See the C API docs for examples.
    *
    * Note that message must be unlocked, unless flags contain the
-   * Gio::DBus::SendMessageFlags::PRESERVE_SERIAL flag.
+   * Gio::DBus::SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag.
    *
    * @param message A Message.
    * @param cancellable A Cancellable.
@@ -628,10 +641,10 @@ public:
     const Glib::VariantContainerBase&   parameters,
     const SlotAsyncReady&               slot,
     const Glib::RefPtr<Cancellable>&    cancellable,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
   _IGNORE(g_dbus_connection_call)
 
   /// A non-cancellable version of call().
@@ -641,10 +654,10 @@ public:
     const Glib::ustring&                method_name,
     const Glib::VariantContainerBase&   parameters,
     const SlotAsyncReady&               slot,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
 
   /** Finishes an operation started with call().
    * @param res A AsyncResult obtained from the SlotAsyncReady passed to
@@ -695,10 +708,10 @@ public:
     const Glib::ustring&                method_name,
     const Glib::VariantContainerBase&   parameters,
     const Glib::RefPtr<Cancellable>&    cancellable,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
   _IGNORE(g_dbus_connection_call_sync)
 
   /// A non-cancellable version of call_sync().
@@ -707,10 +720,10 @@ public:
     const Glib::ustring&                interface_name,
     const Glib::ustring&                method_name,
     const Glib::VariantContainerBase&   parameters,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
 
 #ifdef G_OS_UNIX
   /** Like call() but also takes a GUnixFDList object.
@@ -746,10 +759,10 @@ public:
     const SlotAsyncReady&               slot,
     const Glib::RefPtr<Cancellable>&    cancellable,
     const Glib::RefPtr<UnixFDList>&     fd_list,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
   _IGNORE(g_dbus_connection_call_with_unix_fd_list)
 
   /** A non-cancellable version of call() (with a UnixFDList).
@@ -762,10 +775,10 @@ public:
     const Glib::VariantContainerBase&   parameters,
     const SlotAsyncReady&               slot,
     const Glib::RefPtr<UnixFDList>&     fd_list,
-    const Glib::ustring&                bus_name = {},
+    const Glib::ustring&                bus_name = Glib::ustring(),
     int                                 timeout_msec = -1,
-    CallFlags                           flags = Gio::DBus::CallFlags::NONE,
-    const Glib::VariantType&            reply_type = {});
+    CallFlags                           flags = Gio::DBus::CALL_FLAGS_NONE,
+    const Glib::VariantType&            reply_type = Glib::VariantType());
 #endif // G_OS_UNIX
 
   /** Finishes an operation started with call() (with a UnixFDList).
@@ -787,10 +800,10 @@ public:
       const Glib::RefPtr<Cancellable>&    cancellable{.?},
       const Glib::RefPtr<UnixFDList>&     fd_list{.},
       Glib::RefPtr<UnixFDList>&           out_fd_list{.>>},
-      const Glib::ustring&                bus_name{.NULL} = {},
+      const Glib::ustring&                bus_name{.NULL} = Glib::ustring(),
       int                                 timeout_msec{.} = -1,
-      CallFlags                           flags{.} = Gio::DBus::CallFlags::NONE,
-      const Glib::VariantType&            reply_type{.} = {}
+      CallFlags                           flags{.} = Gio::DBus::CALL_FLAGS_NONE,
+      const Glib::VariantType&            reply_type{.} = Glib::VariantType()
     ),
     g_dbus_connection_call_with_unix_fd_list_sync, errthrow, ifdef G_OS_UNIX
   )
@@ -814,8 +827,8 @@ public:
     const Glib::ustring&                object_path,
     const Glib::ustring&                interface_name,
     const Glib::ustring&                signal_name,
-    const Glib::ustring&                destination_bus_name = {},
-    const Glib::VariantContainerBase&   parameters = {});
+    const Glib::ustring&                destination_bus_name = Glib::ustring(),
+    const Glib::VariantContainerBase&   parameters = Glib::VariantContainerBase());
   _IGNORE(g_dbus_connection_emit_signal)
 
   /** Subscribes to signals on the connection and invokes @a slot with a
@@ -851,12 +864,12 @@ public:
    */
   guint signal_subscribe(
     const SlotSignal& slot,
-    const Glib::ustring& sender = {},
-    const Glib::ustring& interface_name = {},
-    const Glib::ustring& member = {},
-    const Glib::ustring& object_path = {},
-    const Glib::ustring& arg0 = {},
-    SignalFlags flags = Gio::DBus::SignalFlags::NONE);
+    const Glib::ustring& sender = Glib::ustring(),
+    const Glib::ustring& interface_name = Glib::ustring(),
+    const Glib::ustring& member = Glib::ustring(),
+    const Glib::ustring& object_path = Glib::ustring(),
+    const Glib::ustring& arg0 = Glib::ustring(),
+    SignalFlags flags = Gio::DBus::SIGNAL_FLAGS_NONE);
   _IGNORE(g_dbus_connection_signal_subscribe)
 
   _WRAP_METHOD(void signal_unsubscribe(guint subscription_id), g_dbus_connection_signal_unsubscribe)
@@ -965,7 +978,7 @@ public:
    *
    * When handling remote calls into any node in the subtree, first the
    * enumerate slot is used to check if the node exists. If the node
-   * exists or the Gio::DBus::SubtreeFlags::DISPATCH_TO_UNENUMERATED_NODES flag
+   * exists or the Gio::DBus::SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag
    * is set the introspection slot is used to check if the node supports the
    * requested method. If so, the dispatch function is used to determine where
    * to dispatch the call. The collected InterfaceVTable will be used to
@@ -995,7 +1008,7 @@ public:
    */
   guint register_subtree(const Glib::ustring& object_path,
     const SubtreeVTable& vtable,
-    SubtreeFlags flags = Gio::DBus::SubtreeFlags::NONE);
+    SubtreeFlags flags = Gio::DBus::SUBTREE_FLAGS_NONE);
   _IGNORE(g_dbus_connection_register_subtree)
 
   _WRAP_METHOD(bool unregister_subtree(guint registration_id), g_dbus_connection_unregister_subtree)
index 95bfe59..2489256 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/error.h>
 
 _DEFS(giomm,gio)
@@ -27,7 +29,7 @@ namespace DBus
 //The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the DBus sub-namespace
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
-_WRAP_GERROR(Error, GDBusError, G_DBUS_ERROR, NO_GTYPE)
+_WRAP_GERROR(Error, GDBusError, G_DBUS_ERROR, NO_GTYPE, decl_prefix GIOMM_API)
 
 } //namespace DBus
 
index 084fa0c..47982c0 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 _DEFS(giomm,gio)
 
 namespace Glib
 {
 
-class Error;
+class GLIBMM_API Error;
 
 }
 
@@ -41,6 +43,7 @@ namespace ErrorUtils
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_remote_error(const Glib::Error& error);
 
 /** Gets the D-Bus error name used for @a error, if any.
@@ -56,6 +59,7 @@ bool is_remote_error(const Glib::Error& error);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 Glib::ustring get_remote_error(const Glib::Error& error);
 
 /** Looks for extra information in the error message used to recover the D-Bus
@@ -70,6 +74,7 @@ Glib::ustring get_remote_error(const Glib::Error& error);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool strip_remote_error(Glib::Error& error);
 
 } // namespace ErrorUtils
index f85c896..6b3a980 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -30,20 +32,22 @@ namespace Gio
 namespace DBus
 {
 
-class InterfaceInfo;
-class Object;
+class GIOMM_API InterfaceInfo;
+class GIOMM_API Object;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
+//TODO: Have Proxy derive from this interface when there is an ABI break.
+
 /** Interface - Base type for D-Bus interfaces.
  * The Interface type is the base type for D-Bus interfaces both on the service
  * side (see InterfaceSkeleton) and client side (see Proxy).
  * @newin{2,34}
  */
 
-class Interface : public Glib::Interface
+class GIOMM_API Interface : public Glib::Interface
 {
-  _CLASS_INTERFACE(Interface, GDBusInterface, G_DBUS_INTERFACE, GDBusInterfaceIface)
+  _CLASS_INTERFACE(Interface, GDBusInterface, G_DBUS_INTERFACE, GDBusInterfaceIface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::RefPtr<InterfaceInfo> get_info(), g_dbus_interface_get_info)
@@ -57,7 +61,6 @@ public:
 
   _WRAP_METHOD(void set_object(const Glib::RefPtr<Gio::DBus::Object>& object), g_dbus_interface_set_object)
 
-protected:
   _WRAP_VFUNC(Glib::RefPtr<InterfaceInfo> get_info() const, "get_info")
   _WRAP_VFUNC(Glib::RefPtr<Gio::DBus::Object> get_object() const, "get_object")
 
index a327e96..0c0b4e8 100644 (file)
@@ -17,5 +17,3 @@
 #include <giomm/dbusconnection.h>
 #include <giomm/dbusintrospection.h>
 #include <giomm/dbusmethodinvocation.h>
-
-using Flags = Gio::DBus::InterfaceSkeleton::Flags;
index 8ad4693..287c363 100644 (file)
@@ -27,25 +27,25 @@ namespace Gio
 namespace DBus
 {
 
-class InterfaceInfo;
-class Connection;
-class MethodInvocation;
+_WRAP_ENUM(InterfaceSkeletonFlags, GDBusInterfaceSkeletonFlags, gtype_func g_dbus_interface_skeleton_flags_get_type)
+
+class GIOMM_API InterfaceInfo;
+class GIOMM_API Connection;
+class GIOMM_API MethodInvocation;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
 /** Abstract base class for D-Bus interfaces on the service side.
  * @newin{2,38}
  */
-class InterfaceSkeleton
+class GIOMM_API InterfaceSkeleton
 : public Glib::Object,
   public Interface
 {
-  _CLASS_GOBJECT(InterfaceSkeleton, GDBusInterfaceSkeleton, G_DBUS_INTERFACE_SKELETON, Glib::Object, GObject)
+  _CLASS_GOBJECT(InterfaceSkeleton, GDBusInterfaceSkeleton, G_DBUS_INTERFACE_SKELETON, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Interface)
 
 public:
-  _WRAP_ENUM(Flags, GDBusInterfaceSkeletonFlags, gtype_func g_dbus_interface_skeleton_flags_get_type)
-
   _WRAP_METHOD(void flush(), g_dbus_interface_skeleton_flush)
 
   _WRAP_METHOD(Glib::RefPtr<InterfaceInfo> get_info(), g_dbus_interface_skeleton_get_info)
@@ -71,10 +71,10 @@ public:
 
   _WRAP_METHOD(Glib::ustring get_object_path() const, g_dbus_interface_skeleton_get_object_path)
 
-  _WRAP_METHOD(Flags get_flags() const, g_dbus_interface_skeleton_get_flags)
-  _WRAP_METHOD(void set_flags(Flags flags), g_dbus_interface_skeleton_set_flags)
+  _WRAP_METHOD(InterfaceSkeletonFlags get_flags() const, g_dbus_interface_skeleton_get_flags)
+  _WRAP_METHOD(void set_flags(InterfaceSkeletonFlags flags), g_dbus_interface_skeleton_set_flags)
 
-  _WRAP_PROPERTY("g-flags", Flags)
+  _WRAP_PROPERTY("g-flags", InterfaceSkeletonFlags)
 
 #m4 _CONVERSION(`GDBusMethodInvocation*',`const Glib::RefPtr<MethodInvocation>&',`Glib::wrap($3, true)')
   _WRAP_SIGNAL(bool authorize_method(const Glib::RefPtr<MethodInvocation>& invocation), "g_authorize_method")
index 800f3fd..4430895 100644 (file)
@@ -44,7 +44,7 @@ namespace DBus
  * @newin{2,28}
  * @ingroup DBus
  */
-class InterfaceVTable
+class GIOMM_API InterfaceVTable
 {
   _CLASS_GENERIC(InterfaceVTable, GDBusInterfaceVTable)
 
@@ -60,14 +60,14 @@ public:
    * @endcode
    */
   using SlotInterfaceMethodCall = sigc::slot<
-    void(
+    void,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::VariantContainerBase&,
-    const Glib::RefPtr<MethodInvocation>&)
+    const Glib::RefPtr<MethodInvocation>&
     >;
 
   /** The type for a slot which handles getting a property for a D-Bus
@@ -82,13 +82,13 @@ public:
    * @throw Glib::Error.
    */
   using SlotInterfaceGetProperty = sigc::slot<
-    void(
+    void,
     Glib::VariantBase&,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
-    const Glib::ustring&)
+    const Glib::ustring&
     >;
 
   /** The type for a slot which handles setting a property for a D-Bus
@@ -103,13 +103,13 @@ public:
    * @throw Glib::Error.
    */
   using SlotInterfaceSetProperty = sigc::slot<
-    bool(
+    bool,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
-    const Glib::VariantBase&)
+    const Glib::VariantBase&
     >;
 
   /** Constructs a new InterfaceVTable using the specified slots.
@@ -119,8 +119,8 @@ public:
    */
   explicit InterfaceVTable(
    const SlotInterfaceMethodCall& slot_method_call,
-   const SlotInterfaceGetProperty& slot_get_property = {},
-   const SlotInterfaceSetProperty& slot_set_property = {}
+   const SlotInterfaceGetProperty& slot_get_property = SlotInterfaceGetProperty(),
+   const SlotInterfaceSetProperty& slot_set_property = SlotInterfaceSetProperty()
   );
 
   InterfaceVTable(const InterfaceVTable& other) = delete;
index f1ba9b5..5186996 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <glibmm/refptr.h>
-#include <glibmm/value.h>
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <gio/gio.h>
-#include <vector>
+#include <glibmm/arrayhandle.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -28,21 +28,21 @@ namespace Gio
 namespace DBus
 {
 
-_WRAP_ENUM(PropertyInfoFlags, GDBusPropertyInfoFlags, NO_GTYPE)
+_WRAP_ENUM(PropertyInfoFlags, GDBusPropertyInfoFlags, s#^DBUS_##, NO_GTYPE)
 
 /** Stores information about an annotation.
  *
  * @newin{2,28}
  * @ingroup DBus
  */
-class AnnotationInfo final
+class GIOMM_API AnnotationInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(AnnotationInfo, GDBusAnnotationInfo, NONE, g_dbus_annotation_info_ref, g_dbus_annotation_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(AnnotationInfo, GDBusAnnotationInfo, NONE, g_dbus_annotation_info_ref, g_dbus_annotation_info_unref, GIOMM_API)
   _IGNORE(g_dbus_annotation_info_ref, g_dbus_annotation_info_unref)
 
 public:
-#m4 _CONVERSION(`const std::vector<Glib::RefPtr<AnnotationInfo>>&', `GDBusAnnotationInfo**',`Glib::ArrayHandler<Glib::RefPtr<AnnotationInfo>>::vector_to_array($3).data()')
-  _WRAP_METHOD(static Glib::ustring info_lookup(const std::vector<Glib::RefPtr<AnnotationInfo>>&  annotations, const Glib::ustring& name), g_dbus_annotation_info_lookup)
+#m4 _CONVERSION(`const Glib::ArrayHandle< Glib::RefPtr<AnnotationInfo> >&', `GDBusAnnotationInfo**', `const_cast<GDBusAnnotationInfo**>($3.data())')
+  _WRAP_METHOD(static Glib::ustring info_lookup(const Glib::ArrayHandle< Glib::RefPtr<AnnotationInfo> >& annotations, const Glib::ustring& name), g_dbus_annotation_info_lookup)
 };
 
 /** ArgInfo - Stores information about an argument for a method or a
@@ -51,9 +51,9 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class ArgInfo final
+class GIOMM_API ArgInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(ArgInfo, GDBusArgInfo, NONE, g_dbus_arg_info_ref, g_dbus_arg_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(ArgInfo, GDBusArgInfo, NONE, g_dbus_arg_info_ref, g_dbus_arg_info_unref, GIOMM_API)
   _IGNORE(g_dbus_arg_info_ref, g_dbus_arg_info_unref)
 
 public:
@@ -64,9 +64,9 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class MethodInfo final
+class GIOMM_API MethodInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(MethodInfo, GDBusMethodInfo, NONE, g_dbus_method_info_ref, g_dbus_method_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(MethodInfo, GDBusMethodInfo, NONE, g_dbus_method_info_ref, g_dbus_method_info_unref, GIOMM_API)
   _IGNORE(g_dbus_method_info_ref, g_dbus_method_info_unref)
 
 public:
@@ -77,9 +77,9 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class SignalInfo final
+class GIOMM_API SignalInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(SignalInfo, GDBusSignalInfo, NONE, g_dbus_signal_info_ref, g_dbus_signal_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(SignalInfo, GDBusSignalInfo, NONE, g_dbus_signal_info_ref, g_dbus_signal_info_unref, GIOMM_API)
   _IGNORE(g_dbus_signal_info_ref, g_dbus_signal_info_unref)
 
 public:
@@ -90,9 +90,9 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class PropertyInfo final
+class GIOMM_API PropertyInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(PropertyInfo, GDBusPropertyInfo, NONE, g_dbus_property_info_ref, g_dbus_property_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(PropertyInfo, GDBusPropertyInfo, NONE, g_dbus_property_info_ref, g_dbus_property_info_unref, GIOMM_API)
   _IGNORE(g_dbus_property_info_ref, g_dbus_property_info_unref)
 
 public:
@@ -103,9 +103,9 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class InterfaceInfo final
+class GIOMM_API InterfaceInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(InterfaceInfo, GDBusInterfaceInfo, NONE, g_dbus_interface_info_ref, g_dbus_interface_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(InterfaceInfo, GDBusInterfaceInfo, NONE, g_dbus_interface_info_ref, g_dbus_interface_info_unref, GIOMM_API)
   _IS_REFCOUNTED_BOXEDTYPE(g_dbus_interface_info_get_type)
   _IGNORE(g_dbus_interface_info_ref, g_dbus_interface_info_unref)
 
@@ -131,13 +131,15 @@ public:
  * @newin{2,28}
  * @ingroup DBus
  */
-class NodeInfo final
+class GIOMM_API NodeInfo final
 {
-  _CLASS_OPAQUE_REFCOUNTED(NodeInfo, GDBusNodeInfo, NONE, g_dbus_node_info_ref, g_dbus_node_info_unref)
+  _CLASS_OPAQUE_REFCOUNTED(NodeInfo, GDBusNodeInfo, NONE, g_dbus_node_info_ref, g_dbus_node_info_unref, GIOMM_API)
   _IGNORE(g_dbus_node_info_ref, g_dbus_node_info_unref)
 
 public:
-  _WRAP_METHOD(static Glib::RefPtr<NodeInfo> create_for_xml(const Glib::ustring& xml_data), g_dbus_node_info_new_for_xml, errthrow "Glib::MarkupError")
+  _WRAP_METHOD_DOCS_ONLY(g_dbus_node_info_new_for_xml)
+  /// @throw Glib::Error.
+  _WRAP_METHOD(static Glib::RefPtr<NodeInfo> create_for_xml(const Glib::ustring& xml_data), g_dbus_node_info_new_for_xml, errthrow)
 
   _WRAP_METHOD(Glib::RefPtr<InterfaceInfo> lookup_interface(const Glib::ustring& name), g_dbus_node_info_lookup_interface, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const InterfaceInfo> lookup_interface(const Glib::ustring& name) const, g_dbus_node_info_lookup_interface, constversion, refreturn)
index f704350..1f24ad6 100644 (file)
@@ -25,7 +25,7 @@ namespace Gio
 namespace DBus
 {
 
-class Connection;
+class GIOMM_API Connection;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -35,9 +35,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * Gio::DBus::Connection::export_menu_model().
  * @newin{2,32}
  */
-class MenuModel : public ::Gio::MenuModel
+class GIOMM_API MenuModel : public ::Gio::MenuModel
 {
-  _CLASS_GOBJECT(MenuModel, GDBusMenuModel, G_DBUS_MENU_MODEL, ::Gio::MenuModel, GMenuModel)
+  _CLASS_GOBJECT(MenuModel, GDBusMenuModel, G_DBUS_MENU_MODEL, ::Gio::MenuModel, GMenuModel, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
index 544f5e3..0c364f1 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 #include <glibmm/variant.h>
 #include <glibmm/utility.h>
@@ -31,10 +33,10 @@ namespace Gio
 namespace DBus
 {
 
-_WRAP_ENUM(MessageType, GDBusMessageType, NO_GTYPE)
-_WRAP_ENUM(MessageFlags, GDBusMessageFlags, NO_GTYPE)
-_WRAP_ENUM(MessageHeaderField, GDBusMessageHeaderField, NO_GTYPE)
-_WRAP_ENUM(CapabilityFlags, GDBusCapabilityFlags, gtype_func g_dbus_capability_flags_get_type)
+_WRAP_ENUM(MessageType, GDBusMessageType, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(MessageFlags, GDBusMessageFlags, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(MessageHeaderField, GDBusMessageHeaderField, s#^DBUS_##, NO_GTYPE)
+_WRAP_ENUM(CapabilityFlags, GDBusCapabilityFlags, s#^DBUS_##, gtype_func g_dbus_capability_flags_get_type)
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -44,9 +46,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,28}
  * @ingroup DBus
  */
-class Message : public Glib::Object
+class GIOMM_API Message : public Glib::Object
 {
-  _CLASS_GOBJECT(Message, GDBusMessage, G_DBUS_MESSAGE, Glib::Object, GObject)
+  _CLASS_GOBJECT(Message, GDBusMessage, G_DBUS_MESSAGE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -75,20 +77,28 @@ public:
   // Ignore variable argument functions.
   _IGNORE(g_dbus_message_new_method_error, g_dbus_message_new_method_error_valist)
 
-  _WRAP_METHOD(static Glib::RefPtr<Message> create_from_blob(const guchar* blob,  gsize blob_len, CapabilityFlags capabilities = CapabilityFlags::NONE), g_dbus_message_new_from_blob, errthrow "Gio::Error")
+  _WRAP_METHOD(static Glib::RefPtr<Message> create_from_blob(const guchar* blob,  gsize blob_len, CapabilityFlags capabilities = CAPABILITY_FLAGS_NONE), g_dbus_message_new_from_blob, errthrow)
 
 
   _WRAP_METHOD(Glib::ustring print(guint indent), g_dbus_message_print)
 
   _WRAP_METHOD(bool get_locked() const, g_dbus_message_get_locked)
   _WRAP_METHOD(void lock() ,g_dbus_message_lock)
-  _WRAP_METHOD(Glib::RefPtr<Message> copy() const, g_dbus_message_copy, errthrow "Gio::Error")
+  _WRAP_METHOD(Glib::RefPtr<Message> copy() const, g_dbus_message_copy, errthrow)
 
   _WRAP_METHOD(MessageType get_message_type() const, g_dbus_message_get_message_type)
   _WRAP_METHOD(void set_message_type(MessageType type), g_dbus_message_set_message_type)
 
-  // BIG_ENDIAN and LITTLE_ENDIAN are defined as preprocessor macros somewhere.
-  _WRAP_ENUM(ByteOrder, GDBusMessageByteOrder, NO_GTYPE, s#ENDIAN$#ENDIAN_ORDER#)
+  //gmmproc can't handle the character literals, and this won't be expanded in future,
+  //so we just wrap it by hand.
+  enum ByteOrder
+  {
+    BYTE_ORDER_BIG_ENDIAN    = 'B',
+    BYTE_ORDER_LITTLE_ENDIAN = 'l'
+  };
+
+  #m4 _CONVERSION(`ByteOrder',`GDBusMessageByteOrder',`(GDBusMessageByteOrder)($3)')
+  #m4 _CONVERSION(`GDBusMessageByteOrder',`ByteOrder',`(ByteOrder)($3)')
 
   _WRAP_METHOD(ByteOrder get_byte_order() const, g_dbus_message_get_byte_order)
   _WRAP_METHOD(void set_byte_order(ByteOrder byte_order), g_dbus_message_set_byte_order)
@@ -107,8 +117,8 @@ public:
 
   _WRAP_METHOD(void set_body(const Glib::VariantBase& body), g_dbus_message_set_body)
 
-  _WRAP_METHOD(Glib::RefPtr<UnixFDList> get_unix_fd_list(), g_dbus_message_get_unix_fd_list, ifdef G_OS_UNIX)
-  _WRAP_METHOD(Glib::RefPtr<const UnixFDList> get_unix_fd_list() const, g_dbus_message_get_unix_fd_list, constversion, ifdef G_OS_UNIX)
+  _WRAP_METHOD(Glib::RefPtr<UnixFDList> get_unix_fd_list(), g_dbus_message_get_unix_fd_list, refreturn, ifdef G_OS_UNIX)
+  _WRAP_METHOD(Glib::RefPtr<const UnixFDList> get_unix_fd_list() const, g_dbus_message_get_unix_fd_list, refreturn, constversion, ifdef G_OS_UNIX)
   _WRAP_METHOD(void set_unix_fd_list(const Glib::RefPtr<UnixFDList>& fd_list), g_dbus_message_set_unix_fd_list, ifdef G_OS_UNIX)
 
 #ifdef G_OS_UNIX
@@ -129,8 +139,8 @@ public:
 
   _WRAP_METHOD(void set_header(MessageHeaderField header_field, const Glib::VariantBase& value), g_dbus_message_set_header)
 
-  #m4 _CONVERSION(`guchar*',`std::vector<guchar>',`Glib::ArrayHandler<guchar>::array_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
-  _WRAP_METHOD(std::vector<guchar> get_header_fields() const, g_dbus_message_get_header_fields)
+  #m4 _CONVERSION(`guchar*',`Glib::ArrayHandle<guchar>',`Glib::ArrayHandle<guchar>($3)')
+  _WRAP_METHOD(Glib::ArrayHandle<guchar> get_header_fields() const, g_dbus_message_get_header_fields)
 
   _WRAP_METHOD(Glib::ustring get_destination() const, g_dbus_message_get_destination)
   _WRAP_METHOD(void set_destination(const Glib::ustring& value), g_dbus_message_set_destination)
@@ -158,9 +168,9 @@ public:
 
   _WRAP_METHOD(Glib::ustring get_arg0() const, g_dbus_message_get_arg0)
 
-  _WRAP_METHOD(static gssize bytes_needed(const guchar* blob, gsize blob_len), g_dbus_message_bytes_needed, errthrow "Gio::Error")
+  _WRAP_METHOD(static gssize bytes_needed(const guchar* blob, gsize blob_len), g_dbus_message_bytes_needed, errthrow)
 
-  _WRAP_METHOD(guchar* to_blob(gsize& out_size, CapabilityFlags capabilities = CapabilityFlags::NONE), g_dbus_message_to_blob, errthrow "Gio::Error")
+  _WRAP_METHOD(guchar* to_blob(gsize& out_size, CapabilityFlags capabilities = CAPABILITY_FLAGS_NONE), g_dbus_message_to_blob, errthrow)
 
   _WRAP_METHOD(void to_exception(), g_dbus_message_to_gerror, errthrow)
 
index 65e81c0..90fd776 100644 (file)
@@ -26,7 +26,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Glib
 {
 
-class Error;
+class GLIBMM_API Error;
 
 }
 
@@ -36,7 +36,7 @@ namespace Gio
 namespace DBus
 {
 
-class Connection;
+class GIOMM_API Connection;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -52,9 +52,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,28}
  * @ingroup DBus
  */
-class MethodInvocation : public Glib::Object
+class GIOMM_API MethodInvocation : public Glib::Object
 {
-  _CLASS_GOBJECT(MethodInvocation, GDBusMethodInvocation, G_DBUS_METHOD_INVOCATION, Glib::Object, GObject)
+  _CLASS_GOBJECT(MethodInvocation, GDBusMethodInvocation, G_DBUS_METHOD_INVOCATION, Glib::Object, GObject, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::ustring get_sender() const, g_dbus_method_invocation_get_sender)
index b4ac349..b2b8806 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -30,7 +32,7 @@ namespace Gio
 namespace DBus
 {
 
-class Interface;
+class GIOMM_API Interface;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -41,9 +43,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,34}
  */
 
-class Object : public Glib::Interface
+class GIOMM_API Object : public Glib::Interface
 {
-  _CLASS_INTERFACE(Object, GDBusObject, G_DBUS_OBJECT, GDBusObjectIface)
+  _CLASS_INTERFACE(Object, GDBusObject, G_DBUS_OBJECT, GDBusObjectIface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::ustring get_object_path() const, g_dbus_object_get_object_path)
@@ -65,7 +67,6 @@ public:
   _WRAP_SIGNAL(void interface_added(const Glib::RefPtr<Gio::DBus::Interface>& iface), "interface_added")
   _WRAP_SIGNAL(void interface_removed(const Glib::RefPtr<Gio::DBus::Interface>& iface), "interface_removed")
 
-protected:
 #m4 _CONVERSION(`Glib::ustring',`const gchar*',`$3.c_str()')
   _WRAP_VFUNC(Glib::ustring get_object_path() const, "get_object_path", keep_return)
 
index 00f60ca..61fa89d 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 #include <glibmm/ustring.h>
 #include <vector>
@@ -31,8 +33,8 @@ namespace Gio
 
 namespace DBus
 {
-class Interface;
-class Object;
+class GIOMM_API Interface;
+class GIOMM_API Object;
 
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -49,9 +51,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,62}
  * @ingroup DBus
  */
-class ObjectManager : public Glib::Interface
+class GIOMM_API ObjectManager : public Glib::Interface
 {
-  _CLASS_INTERFACE(ObjectManager, GDBusObjectManager, G_DBUS_OBJECT_MANAGER, GDBusObjectManagerIface)
+  _CLASS_INTERFACE(ObjectManager, GDBusObjectManager, G_DBUS_OBJECT_MANAGER, GDBusObjectManagerIface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::ustring get_object_path() const, g_dbus_object_manager_get_object_path)
index 76cc808..813485f 100644 (file)
@@ -43,13 +43,12 @@ namespace Gio
 namespace DBus
 {
 using MapChangedProperties = ObjectManagerClient::MapChangedProperties;
-using Flags = ObjectManagerClient::Flags;
 
 ObjectManagerClient::ObjectManagerClient(const Glib::RefPtr<Connection>& connection,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const SlotAsyncReady& slot_async_ready,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 : _CONSTRUCT("connection", Glib::unwrap(connection),
   "flags", static_cast<GDBusObjectManagerClientFlags>(flags),
   "name", Glib::c_str_or_nullptr(name),
@@ -81,7 +80,7 @@ ObjectManagerClient::ObjectManagerClient(BusType bus_type,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const SlotAsyncReady& slot_async_ready,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 : _CONSTRUCT("bus-type", bus_type,
   "flags", static_cast<GDBusObjectManagerClientFlags>(flags),
   "name", Glib::c_str_or_nullptr(name),
@@ -113,7 +112,7 @@ void ObjectManagerClient::create(const Glib::RefPtr<Connection>& connection,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const SlotAsyncReady& slot_async_ready,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 {
   // This does not return anything, because it is async - see create_finish().
   ObjectManagerClient(connection, name, object_path, slot_async_ready, cancellable, slot_proxy_type, flags);
@@ -123,9 +122,9 @@ Glib::RefPtr<Gio::DBus::ObjectManagerClient> ObjectManagerClient::create_sync(
   const Glib::RefPtr<Connection>& connection,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 {
-  return Glib::make_refptr_for_instance<ObjectManagerClient>(
+  return Glib::RefPtr<ObjectManagerClient>(
     new ObjectManagerClient(connection, name, object_path, {}, cancellable, slot_proxy_type, flags));
 }
 
@@ -133,7 +132,7 @@ void ObjectManagerClient::create_for_bus(BusType bus_type,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const SlotAsyncReady& slot_async_ready,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 {
   // This does not return anything, because it is async - see create_for_bus_finish().
   ObjectManagerClient(bus_type, name, object_path, slot_async_ready, cancellable, slot_proxy_type, flags);
@@ -143,9 +142,9 @@ Glib::RefPtr<Gio::DBus::ObjectManagerClient> ObjectManagerClient::create_for_bus
   BusType bus_type,
   const Glib::ustring& name, const Glib::ustring& object_path,
   const Glib::RefPtr<Cancellable>& cancellable,
-  const SlotProxyType& slot_proxy_type, Flags flags)
+  const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags)
 {
-  return Glib::make_refptr_for_instance<ObjectManagerClient>(
+  return Glib::RefPtr<ObjectManagerClient>(
     new ObjectManagerClient(bus_type, name, object_path, {}, cancellable, slot_proxy_type, flags));
 }
 
index 94e6c55..c05c742 100644 (file)
@@ -31,6 +31,9 @@ namespace Gio
 
 namespace DBus
 {
+_WRAP_ENUM(ObjectManagerClientFlags, GDBusObjectManagerClientFlags, s#^DBUS_##,
+  gtype_func g_dbus_object_manager_client_flags_get_type)
+
 //The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the DBus sub-namespace
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
@@ -50,7 +53,7 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * If the name for a %Gio::DBus::ObjectManagerClient is not owned by anyone at
  * object construction time, the default behavior is to request the
  * message bus to launch an owner for the name. This behavior can be
- * disabled using the Gio::DBus::ObjectManagerClient::Flags::DO_NOT_AUTO_START
+ * disabled using the Gio::DBus::OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
  * flag. It's also worth noting that this only works if the name of
  * interest is activatable in the first place. E.g. in some cases it
  * is not possible to launch an owner for the requested name. In this
@@ -113,20 +116,18 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,62}
  * @ingroup DBus
  */
-class ObjectManagerClient
+class GIOMM_API ObjectManagerClient
 : public Glib::Object,
   public Initable,
   public AsyncInitable,
   public ObjectManager
 {
-  _CLASS_GOBJECT(ObjectManagerClient, GDBusObjectManagerClient, G_DBUS_OBJECT_MANAGER_CLIENT, Glib::Object, GObject)
+  _CLASS_GOBJECT(ObjectManagerClient, GDBusObjectManagerClient, G_DBUS_OBJECT_MANAGER_CLIENT, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Initable)
   _IMPLEMENTS_INTERFACE(AsyncInitable)
   _IMPLEMENTS_INTERFACE(DBus::ObjectManager)
 
 public:
-  _WRAP_ENUM(Flags, GDBusObjectManagerClientFlags, gtype_func g_dbus_object_manager_client_flags_get_type)
-
   /** A slot that will be called to determine the GType to use for an interface proxy
    * (if interface_name is not an empty string) or object proxy (if interface_name is
    * an empty string).
@@ -155,14 +156,14 @@ protected:
     const Glib::ustring& object_path,
     const SlotAsyncReady& slot_async_ready,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const SlotProxyType& slot_proxy_type, Flags flags);
+    const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags);
 
   ObjectManagerClient(BusType bus_type,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const SlotAsyncReady& slot_async_ready,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const SlotProxyType& slot_proxy_type, Flags flags);
+    const SlotProxyType& slot_proxy_type, ObjectManagerClientFlags flags);
   _IGNORE(g_dbus_object_manager_client_new, g_dbus_object_manager_client_new_for_bus,
           g_dbus_object_manager_client_new_sync, g_dbus_object_manager_client_new_for_bus_sync)
 
@@ -182,7 +183,7 @@ public:
    * @param cancellable A Cancellable or an empty Glib::RefPtr.
    * @param slot_proxy_type A SlotProxyType slot, or an empty slot to always construct
    *        GDBusProxy or GDBusObjectProxy proxies.
-   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClient::Flags enumeration.
+   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClientFlags enumeration.
    */
   static void create(const Glib::RefPtr<Connection>& connection,
     const Glib::ustring& name,
@@ -190,7 +191,7 @@ public:
     const SlotAsyncReady& slot_async_ready,
     const Glib::RefPtr<Cancellable>& cancellable = {},
     const SlotProxyType& slot_proxy_type = {},
-    Flags flags = Flags::NONE);
+    ObjectManagerClientFlags flags = OBJECT_MANAGER_CLIENT_FLAGS_NONE);
 
   // g_dbus_object_manager_client_new_finish() and g_dbus_object_manager_client_new_for_bus_finish()
   // return GDBusObjectManager pointers, although they are GDBusObjectManagerClient pointers.
@@ -216,7 +217,7 @@ public:
    * @param cancellable A Cancellable or an empty Glib::RefPtr.
    * @param slot_proxy_type A SlotProxyType slot, or an empty slot to always construct
    *        GDBusProxy or GDBusObjectProxy proxies.
-   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClient::Flags enumeration.
+   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClientFlags enumeration.
    * @throw Glib::Error
    */
   static Glib::RefPtr<Gio::DBus::ObjectManagerClient> create_sync(
@@ -225,7 +226,7 @@ public:
     const Glib::ustring& object_path,
     const Glib::RefPtr<Cancellable>& cancellable = {},
     const SlotProxyType& slot_proxy_type = {},
-    Flags flags = Flags::NONE);
+    ObjectManagerClientFlags flags = OBJECT_MANAGER_CLIENT_FLAGS_NONE);
 
   /** Creates a new %Gio::DBus::ObjectManagerClient object.
    *
@@ -244,7 +245,7 @@ public:
    * @param cancellable A Cancellable or an empty Glib::RefPtr.
    * @param slot_proxy_type A SlotProxyType slot, or an empty slot to always construct
    *        GDBusProxy or GDBusObjectProxy proxies.
-   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClient::Flags enumeration.
+   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClientFlags enumeration.
    */
   static void create_for_bus(BusType bus_type,
     const Glib::ustring& name,
@@ -252,10 +253,10 @@ public:
     const SlotAsyncReady& slot_async_ready,
     const Glib::RefPtr<Cancellable>& cancellable = {},
     const SlotProxyType& slot_proxy_type = {},
-    Flags flags = Flags::NONE);
+    ObjectManagerClientFlags flags = OBJECT_MANAGER_CLIENT_FLAGS_NONE);
 
   /** Finishes an operation started with create_for_bus().
-   * 
+   *
    * @param res An AsyncResult obtained from the SlotAsyncReady passed to create_for_bus().
    * @return A %Gio::DBus::ObjectManagerClient object. If an error has occurred,
    *         a Glib::Error is thrown and nothing is returned.
@@ -279,7 +280,7 @@ public:
    * @param cancellable A Cancellable or an empty Glib::RefPtr.
    * @param slot_proxy_type A SlotProxyType slot, or an empty slot to always construct
    *        GDBusProxy or GDBusObjectProxy proxies.
-   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClient::Flags enumeration.
+   * @param flags Zero or more flags from the Gio::DBus::ObjectManagerClientFlags enumeration.
    * @throw Glib::Error
    */
   static Glib::RefPtr<Gio::DBus::ObjectManagerClient> create_for_bus_sync(
@@ -288,18 +289,18 @@ public:
     const Glib::ustring& object_path,
     const Glib::RefPtr<Cancellable>& cancellable = {},
     const SlotProxyType& slot_proxy_type = {},
-    Flags flags = Flags::NONE);
+    ObjectManagerClientFlags flags = OBJECT_MANAGER_CLIENT_FLAGS_NONE);
 
   _WRAP_METHOD(Glib::RefPtr<Connection> get_connection(), g_dbus_object_manager_client_get_connection, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Connection> get_connection() const, g_dbus_object_manager_client_get_connection, refreturn, constversion)
 
-  _WRAP_METHOD(Flags get_flags() const, g_dbus_object_manager_client_get_flags)
+  _WRAP_METHOD(ObjectManagerClientFlags get_flags() const, g_dbus_object_manager_client_get_flags)
 
   _WRAP_METHOD(Glib::ustring get_name() const, g_dbus_object_manager_client_get_name)
   _WRAP_METHOD(Glib::ustring get_name_owner() const, g_dbus_object_manager_client_get_name_owner)
 
  _WRAP_PROPERTY("connection", Glib::RefPtr<Connection>)
- _WRAP_PROPERTY("flags", Flags)
+ _WRAP_PROPERTY("flags", ObjectManagerClientFlags)
  _WRAP_PROPERTY("object-path", Glib::ustring)
  _WRAP_PROPERTY("name", Glib::ustring)
  _WRAP_PROPERTY("name-owner", Glib::ustring)
index 1497d4b..03392e6 100644 (file)
@@ -57,9 +57,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,62}
  * @ingroup DBus
  */
-class ObjectManagerServer : public Glib::Object, public ObjectManager
+class GIOMM_API ObjectManagerServer : public Glib::Object, public ObjectManager
 {
-  _CLASS_GOBJECT(ObjectManagerServer, GDBusObjectManagerServer, G_DBUS_OBJECT_MANAGER_SERVER, Glib::Object, GObject)
+  _CLASS_GOBJECT(ObjectManagerServer, GDBusObjectManagerServer, G_DBUS_OBJECT_MANAGER_SERVER, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(DBus::ObjectManager)
 
 protected:
index 755b4fc..fb1b064 100644 (file)
@@ -39,9 +39,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,62}
  * @ingroup DBus
  */
-class ObjectProxy : public Glib::Object, public Object
+class GIOMM_API ObjectProxy : public Glib::Object, public Object
 {
-  _CLASS_GOBJECT(ObjectProxy, GDBusObjectProxy, G_DBUS_OBJECT_PROXY, Glib::Object, GObject)
+  _CLASS_GOBJECT(ObjectProxy, GDBusObjectProxy, G_DBUS_OBJECT_PROXY, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(DBus::Object)
 
 protected:
index 41197da..1ca7c67 100644 (file)
@@ -41,9 +41,9 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,62}
  * @ingroup DBus
  */
-class ObjectSkeleton : public Glib::Object, public Object
+class GIOMM_API ObjectSkeleton : public Glib::Object, public Object
 {
-  _CLASS_GOBJECT(ObjectSkeleton, GDBusObjectSkeleton, G_DBUS_OBJECT_SKELETON, Glib::Object, GObject)
+  _CLASS_GOBJECT(ObjectSkeleton, GDBusObjectSkeleton, G_DBUS_OBJECT_SKELETON, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(DBus::Object)
 
 protected:
index 7d0c99a..2f47683 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2010 The giomm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -24,7 +26,7 @@ namespace Gio
 namespace DBus
 {
 
-_WRAP_ENUM(BusNameOwnerFlags, GBusNameOwnerFlags)
+_WRAP_ENUM(BusNameOwnerFlags, GBusNameOwnerFlags, s#^DBUS_##)
 
 /** For example,
  * void on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection>& connection,
@@ -32,21 +34,21 @@ _WRAP_ENUM(BusNameOwnerFlags, GBusNameOwnerFlags)
  * @newin{2,28}
  * @ingroup DBus
  */
-using SlotBusAcquired = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring)>;
+using SlotBusAcquired = sigc::slot<void, const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring>;
 
 /** For example,
  * void on_name_acquired(const Glib::RefPtr<Gio::DBus::Connection>& connection,
  * const Glib::ustring& name);
  * @ingroup DBus
  */
-using SlotNameAcquired = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring)>;
+using SlotNameAcquired = sigc::slot<void, const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring>;
 
 /** For example,
  * void on_name_lost(const Glib::RefPtr<Gio::DBus::Connection>& connection,
  * const Glib::ustring& name);
  * @ingroup DBus
  */
-using SlotNameLost = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring)>;
+using SlotNameLost = sigc::slot<void, const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring>;
 
 //TODO: See https://bugzilla.gnome.org/show_bug.cgi?id=646427 about the apparent uselessness of SlotNameAcquired.
 //TODO: Add example from C API in class docs.
@@ -107,19 +109,21 @@ using SlotNameLost = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&,
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 guint own_name(
   BusType bus_type,
   const Glib::ustring& name,
-  const SlotBusAcquired& bus_acquired_slot = {},
-  const SlotNameAcquired& name_acquired_slot = {},
-  const SlotNameLost& name_lost_slot = {},
-  BusNameOwnerFlags flags = Gio::DBus::BusNameOwnerFlags::NONE
+  const SlotBusAcquired& bus_acquired_slot = SlotBusAcquired(),
+  const SlotNameAcquired& name_acquired_slot = SlotNameAcquired(),
+  const SlotNameLost& name_lost_slot = SlotNameLost(),
+  BusNameOwnerFlags flags = Gio::DBus::BUS_NAME_OWNER_FLAGS_NONE
 );
 _IGNORE(g_bus_own_name)
 
 /** Stops owning a name.
  * @param owner_id An identifier obtained from own_name().
  */
+GIOMM_API
 void unown_name(guint owner_id);
 _IGNORE(g_bus_unown_name)
 
index eb8c311..eefebcc 100644 (file)
@@ -145,7 +145,7 @@ Proxy::create_sync(const Glib::RefPtr<Connection>& connection, const Glib::ustri
   const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<InterfaceInfo>& info,
   ProxyFlags flags)
 {
-  return Glib::make_refptr_for_instance<Proxy>(
+  return Glib::RefPtr<Proxy>(
     new Proxy(connection, name, object_path, interface_name, cancellable, info, flags));
 }
 
@@ -154,7 +154,7 @@ Proxy::create_sync(const Glib::RefPtr<Connection>& connection, const Glib::ustri
   const Glib::ustring& object_path, const Glib::ustring& interface_name,
   const Glib::RefPtr<InterfaceInfo>& info, ProxyFlags flags)
 {
-  return Glib::make_refptr_for_instance<Proxy>(new Proxy(connection, name, object_path, interface_name, info, flags));
+  return Glib::RefPtr<Proxy>(new Proxy(connection, name, object_path, interface_name, info, flags));
 }
 
 void
@@ -180,7 +180,7 @@ Proxy::create_for_bus_sync(BusType bus_type, const Glib::ustring& name,
   const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<InterfaceInfo>& info,
   ProxyFlags flags)
 {
-  return Glib::make_refptr_for_instance<Proxy>(
+  return Glib::RefPtr<Proxy>(
     new Proxy(bus_type, name, object_path, interface_name, cancellable, info, flags));
 }
 
@@ -189,7 +189,7 @@ Proxy::create_for_bus_sync(BusType bus_type, const Glib::ustring& name,
   const Glib::ustring& object_path, const Glib::ustring& interface_name,
   const Glib::RefPtr<InterfaceInfo>& info, ProxyFlags flags)
 {
-  return Glib::make_refptr_for_instance<Proxy>(new Proxy(bus_type, name, object_path, interface_name, info, flags));
+  return Glib::RefPtr<Proxy>(new Proxy(bus_type, name, object_path, interface_name, info, flags));
 }
 
 void
index 4185a3d..3a31a14 100644 (file)
@@ -17,7 +17,6 @@
 #include <glibmm/object.h>
 #include <giomm/asyncresult.h>
 #include <giomm/dbusintrospection.h>
-#include <giomm/dbusinterface.h>
 #include <giomm/initable.h>
 #include <giomm/asyncinitable.h>
 #include <giomm/dbusconnection.h>
@@ -33,7 +32,7 @@ namespace DBus
 //The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the DBus sub-namespace
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
-_WRAP_ENUM(ProxyFlags, GDBusProxyFlags, gtype_func g_dbus_proxy_flags_get_type)
+_WRAP_ENUM(ProxyFlags, GDBusProxyFlags, s#^DBUS_##, gtype_func g_dbus_proxy_flags_get_type)
 
 /** A client-side proxy.
  * This is a base class used for proxies to access a D-Bus interface on
@@ -61,16 +60,14 @@ _WRAP_ENUM(ProxyFlags, GDBusProxyFlags, gtype_func g_dbus_proxy_flags_get_type)
  * @newin{2,28}
  * @ingroup DBus
  */
-class Proxy
+class GIOMM_API Proxy
 : public Glib::Object,
   public Initable,
-  public AsyncInitable,
-  public Interface
+  public AsyncInitable
 {
-  _CLASS_GOBJECT(Proxy, GDBusProxy, G_DBUS_PROXY, Glib::Object, GObject)
+  _CLASS_GOBJECT(Proxy, GDBusProxy, G_DBUS_PROXY, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Initable)
   _IMPLEMENTS_INTERFACE(AsyncInitable)
-  _IMPLEMENTS_INTERFACE(DBus::Interface)
 
 protected:
 
@@ -80,31 +77,31 @@ protected:
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(const Glib::RefPtr<Connection>& connection,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(const Glib::RefPtr<Connection>& connection,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(const Glib::RefPtr<Connection>& connection,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(BusType bus_type,
     const Glib::ustring& name,
@@ -112,31 +109,31 @@ protected:
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(BusType bus_type,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(BusType bus_type,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   Proxy(BusType bus_type,
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
 public:
 
@@ -147,8 +144,8 @@ public:
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   /// Non-cancellable version of create().
   static void create(const Glib::RefPtr<Connection>& connection,
@@ -156,8 +153,8 @@ public:
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_finish)
   /// @throw Glib::Error.
@@ -170,8 +167,8 @@ public:
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   /// Non-cancellable version of create_sync().
   static Glib::RefPtr<Proxy>
@@ -179,8 +176,8 @@ public:
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_for_bus)
   static void create_for_bus(BusType bus_type,
@@ -189,8 +186,8 @@ public:
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_bus().
   static void create_for_bus(BusType bus_type,
@@ -198,8 +195,8 @@ public:
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const SlotAsyncReady& slot,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_for_bus_finish)
   /// @throw Glib::Error.
@@ -212,8 +209,8 @@ public:
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
     const Glib::RefPtr<Cancellable>& cancellable,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   /// Non-cancellable version of create_for_bus_sync().
   static Glib::RefPtr<Proxy>
@@ -221,8 +218,8 @@ public:
     const Glib::ustring& name,
     const Glib::ustring& object_path,
     const Glib::ustring& interface_name,
-    const Glib::RefPtr<InterfaceInfo>& info = {},
-    ProxyFlags flags = ProxyFlags::NONE);
+    const Glib::RefPtr<InterfaceInfo>& info = Glib::RefPtr<InterfaceInfo>(),
+    ProxyFlags flags = PROXY_FLAGS_NONE);
 
   _WRAP_METHOD(ProxyFlags get_flags() const, g_dbus_proxy_get_flags)
 
@@ -255,8 +252,8 @@ public:
 
   _WRAP_METHOD(void set_cached_property(const Glib::ustring& property_name, const Glib::VariantBase& value), g_dbus_proxy_set_cached_property)
 
-#m4 _CONVERSION(`gchar**', `std::vector<Glib::ustring>', `Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> get_cached_property_names() const, g_dbus_proxy_get_cached_property_names)
+#m4 _CONVERSION(`gchar**', `Glib::StringArrayHandle', `Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle get_cached_property_names() const, g_dbus_proxy_get_cached_property_names)
 
   _WRAP_METHOD(void set_interface_info(const Glib::RefPtr<InterfaceInfo>& info), g_dbus_proxy_set_interface_info)
   _WRAP_METHOD(Glib::RefPtr<InterfaceInfo> get_interface_info(), g_dbus_proxy_get_interface_info)
@@ -267,9 +264,9 @@ public:
       const Glib::ustring&               method_name{.},
       const SlotAsyncReady&              slot{callback?},
       const Glib::RefPtr<Cancellable>&   cancellable{.?},
-      const Glib::VariantContainerBase&  parameters{.} = {},
+      const Glib::VariantContainerBase&  parameters{.} = Glib::VariantContainerBase(),
       int                                timeout_msec{.} = -1,
-      CallFlags                          flags{.} = Gio::DBus::CallFlags::NONE
+      CallFlags                          flags{.} = Gio::DBus::CALL_FLAGS_NONE
     ),
     g_dbus_proxy_call, slot_name slot, slot_callback SignalProxy_async_callback
   )
@@ -288,9 +285,9 @@ public:
     Glib::VariantContainerBase call_sync(
       const Glib::ustring&               method_name{.},
       const Glib::RefPtr<Cancellable>&   cancellable{.?},
-      const Glib::VariantContainerBase&  parameters{.} = {},
+      const Glib::VariantContainerBase&  parameters{.} = Glib::VariantContainerBase(),
       int                                timeout_msec{.} = -1,
-      CallFlags                          flags{.} = Gio::DBus::CallFlags::NONE
+      CallFlags                          flags{.} = Gio::DBus::CALL_FLAGS_NONE
     ),
     g_dbus_proxy_call_sync, errthrow
   )
@@ -303,7 +300,7 @@ public:
       const Glib::RefPtr<Cancellable>&    cancellable{.?},
       const Glib::RefPtr<UnixFDList>&     fd_list{.},
       int                                 timeout_msec{.} = -1,
-      CallFlags                           flags{.} = Gio::DBus::CallFlags::NONE
+      CallFlags                           flags{.} = Gio::DBus::CALL_FLAGS_NONE
     ),
     g_dbus_proxy_call_with_unix_fd_list, ifdef G_OS_UNIX,
       slot_name slot, slot_callback SignalProxy_async_callback
@@ -327,7 +324,7 @@ public:
       const Glib::RefPtr<UnixFDList>&     fd_list{.},
       Glib::RefPtr<UnixFDList>&           out_fd_list{.>>},
       int                                 timeout_msec{.} = -1,
-      CallFlags                           flags{.} = Gio::DBus::CallFlags::NONE
+      CallFlags                           flags{.} = Gio::DBus::CALL_FLAGS_NONE
     ),
     g_dbus_proxy_call_with_unix_fd_list_sync, errthrow, ifdef G_OS_UNIX
   )
index 82f3bac..cd8ca6d 100644 (file)
@@ -20,8 +20,6 @@
 #include <giomm/dbusconnection.h>
 #include <giomm/dbusauthobserver.h>
 
-using Flags = Gio::DBus::Server::Flags;
-
 namespace Gio
 {
 
@@ -30,7 +28,7 @@ namespace DBus
 
 Server::Server(const std::string& address, const std::string& guid,
   const Glib::RefPtr<AuthObserver>& observer, const Glib::RefPtr<Cancellable>& cancellable,
-  Flags flags)
+  ServerFlags flags)
 : _CONSTRUCT("address", Glib::c_str_or_nullptr(address), "flags",
     static_cast<GDBusServerFlags>(flags), "guid", Glib::c_str_or_nullptr(guid),
     "authentication-observer", Glib::unwrap(observer))
@@ -39,7 +37,7 @@ Server::Server(const std::string& address, const std::string& guid,
 }
 
 Server::Server(const std::string& address, const std::string& guid,
-  const Glib::RefPtr<Cancellable>& cancellable, Flags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, ServerFlags flags)
 : _CONSTRUCT("address", Glib::c_str_or_nullptr(address), "flags",
     static_cast<GDBusServerFlags>(flags), "guid", Glib::c_str_or_nullptr(guid),
     "authentication-observer", static_cast<GDBusAuthObserver*>(nullptr))
@@ -48,7 +46,7 @@ Server::Server(const std::string& address, const std::string& guid,
 }
 
 Server::Server(const std::string& address, const std::string& guid,
-  const Glib::RefPtr<AuthObserver>& observer, Flags flags)
+  const Glib::RefPtr<AuthObserver>& observer, ServerFlags flags)
 : _CONSTRUCT("address", Glib::c_str_or_nullptr(address), "flags",
     static_cast<GDBusServerFlags>(flags), "guid", Glib::c_str_or_nullptr(guid),
     "authentication-observer", Glib::unwrap(observer))
@@ -56,7 +54,7 @@ Server::Server(const std::string& address, const std::string& guid,
   init();
 }
 
-Server::Server(const std::string& address, const std::string& guid, Flags flags)
+Server::Server(const std::string& address, const std::string& guid, ServerFlags flags)
 : _CONSTRUCT("address", Glib::c_str_or_nullptr(address), "flags",
     static_cast<GDBusServerFlags>(flags), "guid", Glib::c_str_or_nullptr(guid),
     "authentication-observer", static_cast<GDBusAuthObserver*>(nullptr))
@@ -67,29 +65,29 @@ Server::Server(const std::string& address, const std::string& guid, Flags flags)
 Glib::RefPtr<Server>
 Server::create_sync(const std::string& address, const std::string& guid,
   const Glib::RefPtr<AuthObserver>& observer, const Glib::RefPtr<Cancellable>& cancellable,
-  Flags flags)
+  ServerFlags flags)
 {
-  return Glib::make_refptr_for_instance<Server>(new Server(address, guid, observer, cancellable, flags));
+  return Glib::RefPtr<Server>(new Server(address, guid, observer, cancellable, flags));
 }
 
 Glib::RefPtr<Server>
 Server::create_sync(const std::string& address, const std::string& guid,
-  const Glib::RefPtr<Cancellable>& cancellable, Flags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, ServerFlags flags)
 {
-  return Glib::make_refptr_for_instance<Server>(new Server(address, guid, cancellable, flags));
+  return Glib::RefPtr<Server>(new Server(address, guid, cancellable, flags));
 }
 
 Glib::RefPtr<Server>
 Server::create_sync(const std::string& address, const std::string& guid,
-  const Glib::RefPtr<AuthObserver>& observer, Flags flags)
+  const Glib::RefPtr<AuthObserver>& observer, ServerFlags flags)
 {
-  return Glib::make_refptr_for_instance<Server>(new Server(address, guid, observer, flags));
+  return Glib::RefPtr<Server>(new Server(address, guid, observer, flags));
 }
 
 Glib::RefPtr<Server>
-Server::create_sync(const std::string& address, const std::string& guid, Flags flags)
+Server::create_sync(const std::string& address, const std::string& guid, ServerFlags flags)
 {
-  return Glib::make_refptr_for_instance<Server>(new Server(address, guid, flags));
+  return Glib::RefPtr<Server>(new Server(address, guid, flags));
 }
 
 } // namespace DBus
index bf0105d..f983350 100644 (file)
@@ -28,6 +28,8 @@ namespace Gio
 namespace DBus
 {
 
+_WRAP_ENUM(ServerFlags, GDBusServerFlags, s#^DBUS_##, gtype_func g_dbus_server_flags_get_type)
+
 _GMMPROC_EXTRA_NAMESPACE(DBus)
 
 //TODO: Add example from the C API in class docs.
@@ -46,34 +48,32 @@ _GMMPROC_EXTRA_NAMESPACE(DBus)
  * @newin{2,28}
  * @ingroup DBus
  */
-class Server : public Glib::Object, public Initable
+class GIOMM_API Server : public Glib::Object, public Initable
 {
-  _CLASS_GOBJECT(Server, GDBusServer, G_DBUS_SERVER, Glib::Object, GObject)
+  _CLASS_GOBJECT(Server, GDBusServer, G_DBUS_SERVER, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Initable)
 
-public:
-  _WRAP_ENUM(Flags, GDBusServerFlags, gtype_func g_dbus_server_flags_get_type)
-
 protected:
+
   Server(const std::string& address,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
     const Glib::RefPtr<Cancellable>& cancellable,
-    Flags flags);
+    ServerFlags flags);
 
   Server(const std::string& address,
     const std::string& guid,
     const Glib::RefPtr<Cancellable>& cancellable,
-    Flags flags);
+    ServerFlags flags);
 
   Server(const std::string& address,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
-    Flags flags);
+    ServerFlags flags);
 
   Server(const std::string& address,
     const std::string& guid,
-    Flags flags);
+    ServerFlags flags);
 
 public:
 
@@ -83,38 +83,38 @@ public:
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
     const Glib::RefPtr<Cancellable>& cancellable,
-    Flags flags = Gio::DBus::Server::Flags::NONE);
+    ServerFlags flags = Gio::DBus::SERVER_FLAGS_NONE);
 
   _WRAP_METHOD_DOCS_ONLY(g_dbus_server_new_sync)
   /// @throw Glib::Error.
   static Glib::RefPtr<Server> create_sync(const std::string& address,
     const std::string& guid,
     const Glib::RefPtr<Cancellable>& cancellable,
-    Flags flags = Gio::DBus::Server::Flags::NONE);
+    ServerFlags flags = Gio::DBus::SERVER_FLAGS_NONE);
 
   /// Non-cancellable version of create_sync().
   static Glib::RefPtr<Server> create_sync(const std::string& address,
     const std::string& guid,
     const Glib::RefPtr<AuthObserver>& observer,
-    Flags flags = Gio::DBus::Server::Flags::NONE);
+    ServerFlags flags = Gio::DBus::SERVER_FLAGS_NONE);
 
   /// Non-cancellable version of create_sync().
   static Glib::RefPtr<Server> create_sync(const std::string& address,
     const std::string& guid,
-    Flags flags = Gio::DBus::Server::Flags::NONE);
+    ServerFlags flags = Gio::DBus::SERVER_FLAGS_NONE);
 
   _WRAP_METHOD(void start(), g_dbus_server_start)
   _WRAP_METHOD(void stop(), g_dbus_server_stop)
   _WRAP_METHOD(bool is_active() const, g_dbus_server_is_active)
   _WRAP_METHOD(std::string get_guid() const, g_dbus_server_get_guid)
-  _WRAP_METHOD(Flags get_flags() const, g_dbus_server_get_flags)
+  _WRAP_METHOD(ServerFlags get_flags() const, g_dbus_server_get_flags)
   _WRAP_METHOD(std::string get_client_address() const, g_dbus_server_get_client_address)
 
   _WRAP_PROPERTY("active", bool)
   _WRAP_PROPERTY("address", std::string)
   _WRAP_PROPERTY("authentication-observer", Glib::RefPtr<AuthObserver>)
   _WRAP_PROPERTY("client-address", std::string)
-  _WRAP_PROPERTY("flags", Flags)
+  _WRAP_PROPERTY("flags", ServerFlags)
   _WRAP_PROPERTY("guid", std::string)
 
 #m4 _CONVERSION(`GDBusConnection*', `const Glib::RefPtr<Connection>&', `Glib::wrap($3, true)')
index 477dffc..8dfbae3 100644 (file)
@@ -41,7 +41,7 @@ namespace DBus
  * @newin{2,28}
  * @ingroup DBus
  */
-class SubtreeVTable
+class GIOMM_API SubtreeVTable
 {
   _CLASS_GENERIC(SubtreeVTable, GDBusSubtreeVTable)
 
@@ -64,10 +64,10 @@ public:
    * @endcode
    */
   using SlotSubtreeEnumerate = sigc::slot<
-    std::vector<Glib::ustring>(
+    std::vector<Glib::ustring>,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
-    const Glib::ustring&)
+    const Glib::ustring&
     >;
 
   /** The type for a slot which handles introspecting a child node.
@@ -91,11 +91,11 @@ public:
    * @endcode
    */
   using SlotSubtreeIntrospect = sigc::slot<
-    std::vector< Glib::RefPtr<Gio::DBus::InterfaceInfo> >(
+    std::vector< Glib::RefPtr<Gio::DBus::InterfaceInfo> >,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
     const Glib::ustring&,
-    const Glib::ustring&)
+    const Glib::ustring&
     >;
 
   /** The type for a slot which handles dispatching a remote call on a child
@@ -113,12 +113,12 @@ public:
    * @endcode
    */
   using SlotSubtreeDispatch = sigc::slot<
-    const InterfaceVTable*(
+    const InterfaceVTable*,
     const Glib::RefPtr<Connection>&,
     const Glib::ustring&,
     const Glib::ustring&,
     const Glib::ustring&,
-    const Glib::ustring&)
+    const Glib::ustring&
     >;
 
   /** Constructs a new SubtreeVTable using specified slots.
@@ -128,8 +128,8 @@ public:
    */
   explicit SubtreeVTable(
    const SlotSubtreeEnumerate& slot_enumerate,
-   const SlotSubtreeIntrospect& slot_introspect = {},
-   const SlotSubtreeDispatch& slot_dispatch = {}
+   const SlotSubtreeIntrospect& slot_introspect = SlotSubtreeIntrospect(),
+   const SlotSubtreeDispatch& slot_dispatch = SlotSubtreeDispatch()
   );
 
   SubtreeVTable(const SubtreeVTable& other) = delete;
index 85844dc..68b0e13 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 _DEFS(giomm,gio)
 
 namespace Gio
@@ -32,6 +34,7 @@ namespace DBus
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 std::string generate_guid();
 
 /** Checks if @a string is a D-Bus GUID.
@@ -44,6 +47,7 @@ std::string generate_guid();
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_guid(const std::string& string);
 
 /** Checks if @a string is a valid D-Bus bus name (either unique or
@@ -54,6 +58,7 @@ bool is_guid(const std::string& string);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_name(const Glib::ustring& string);
 
 /** Checks if @a string is a valid D-Bus unique bus name.
@@ -63,6 +68,7 @@ bool is_name(const Glib::ustring& string);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_unique_name(const Glib::ustring& string);
 
 /** Checks if @a string is a valid D-Bus member (e.g. signal or method) name.
@@ -72,6 +78,7 @@ bool is_unique_name(const Glib::ustring& string);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_member_name(const Glib::ustring& string);
 
 /** Checks if @a string is a valid D-Bus interface name.
@@ -81,6 +88,7 @@ bool is_member_name(const Glib::ustring& string);
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 bool is_interface_name(const Glib::ustring& string);
 
 }
index 1821c9e..ce4a817 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2010 The giomm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -24,21 +26,21 @@ namespace Gio
 namespace DBus
 {
 
-_WRAP_ENUM(BusNameWatcherFlags, GBusNameWatcherFlags, NO_GTYPE)
+_WRAP_ENUM(BusNameWatcherFlags, GBusNameWatcherFlags, s#^DBUS_##, NO_GTYPE)
 
 /** For example,
  * void on_name_appeared(const Glib::RefPtr<Gio::DBus::Connection>& connection,
  * const Glib::ustring& name, const Glib::ustring& name_owner);
  * @ingroup DBus
  */
-using SlotNameAppeared = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring, const Glib::ustring&)>;
+using SlotNameAppeared = sigc::slot<void, const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring, const Glib::ustring&>;
 
 /** For example,
  * void on_name_vanished(const Glib::RefPtr<Gio::DBus::Connection>& connection,
  * const Glib::ustring& name);
  * @ingroup DBus
  */
-using SlotNameVanished = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring)>;
+using SlotNameVanished = sigc::slot<void, const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring>;
 
 //TODO: Add example from C API in class docs?
 /** Starts watching @a name on the bus specified by @a bus_type and calls
@@ -81,12 +83,13 @@ using SlotNameVanished = sigc::slot<void(const Glib::RefPtr<Gio::DBus::Connectio
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 guint watch_name(
   BusType bus_type,
   const Glib::ustring& name,
-  const SlotNameAppeared& name_appeared_slot = {},
-  const SlotNameVanished& name_vanished_slot = {},
-  BusNameWatcherFlags flags = Gio::DBus::BusNameWatcherFlags::NONE
+  const SlotNameAppeared& name_appeared_slot = SlotNameAppeared(),
+  const SlotNameVanished& name_vanished_slot = SlotNameVanished(),
+  BusNameWatcherFlags flags = Gio::DBus::BUS_NAME_WATCHER_FLAGS_NONE
 );
 _IGNORE(g_bus_watch_name)
 
@@ -104,12 +107,13 @@ _IGNORE(g_bus_watch_name)
  * @newin{2,28}
  * @ingroup DBus
  */
+GIOMM_API
 guint watch_name(
   const Glib::RefPtr<Connection>& connection,
   const Glib::ustring& name,
-  const SlotNameAppeared& name_appeared_slot = {},
-  const SlotNameVanished& name_vanished_slot = {},
-  BusNameWatcherFlags flags = Gio::DBus::BusNameWatcherFlags::NONE
+  const SlotNameAppeared& name_appeared_slot = SlotNameAppeared(),
+  const SlotNameVanished& name_vanished_slot = SlotNameVanished(),
+  BusNameWatcherFlags flags = Gio::DBus::BUS_NAME_WATCHER_FLAGS_NONE
 );
 _IGNORE(g_bus_watch_name_on_connection)
 
@@ -117,6 +121,7 @@ _IGNORE(g_bus_watch_name_on_connection)
  * @param watcher_id An identifier obtained from watch_name().
  * @ingroup DBus
  */
+GIOMM_API
 void unwatch_name(guint watcher_id);
 _IGNORE(g_bus_unwatch_name)
 
index 4060593..e561ce8 100644 (file)
@@ -28,7 +28,7 @@ _GMMPROC_WRAP_CONDITIONALLY(if !defined(G_OS_WIN32) && !defined(GLIBMM_OS_COCOA)
 namespace Glib
 {
 
-class KeyFile;
+class GLIBMM_API KeyFile;
 
 }
 
@@ -40,24 +40,24 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class DesktopAppInfo
+class GIOMM_API DesktopAppInfo
 : public Glib::Object,
   public AppInfo
 {
-  _CLASS_GOBJECT(DesktopAppInfo, GDesktopAppInfo, G_DESKTOP_APP_INFO, Glib::Object, GObject)
+  _CLASS_GOBJECT(DesktopAppInfo, GDesktopAppInfo, G_DESKTOP_APP_INFO, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(AppInfo)
 
 public:
   // TODO: should use _WRAP_CREATE(), but these functions do more than just call
   // g_object_new() because there's quite a bit of error-handling to do.
   _WRAP_METHOD(static Glib::RefPtr<DesktopAppInfo> create(const std::string& desktop_id), g_desktop_app_info_new)
-  _WRAP_METHOD(static Glib::RefPtr<DesktopAppInfo> create_from_keyfile(const Glib::RefPtr<Glib::KeyFile>& key_file), g_desktop_app_info_new_from_keyfile)
+  _WRAP_METHOD(static Glib::RefPtr<DesktopAppInfo> create_from_keyfile(Glib::KeyFile& key_file), g_desktop_app_info_new_from_keyfile)
   _WRAP_METHOD(static Glib::RefPtr<DesktopAppInfo> create_from_filename(const std::string& filename), g_desktop_app_info_new_from_filename)
 
   _WRAP_METHOD(std::string get_filename() const, g_desktop_app_info_get_filename)
   _WRAP_METHOD(bool is_hidden() const, g_desktop_app_info_get_is_hidden)
-
-  _IGNORE(g_desktop_app_info_set_desktop_env)
+  _WRAP_METHOD(static void set_desktop_env(const std::string& desktop_env), g_desktop_app_info_set_desktop_env,
+    deprecated "Do not use this API. Since 2.42 the value of the `XDG_CURRENT_DESKTOP` environment variable will be used.")
 
 #m4 _CONVERSION(`const char* const*', `std::vector<Glib::ustring>', `Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
   _WRAP_METHOD(std::vector<Glib::ustring> get_keywords() const, g_desktop_app_info_get_keywords)
index 95186ea..08a90d4 100644 (file)
 #include <glibmm/exceptionhandler.h>
 #include "slot_async.h"
 
-using StartStopType = Gio::Drive::StartStopType;
-
 namespace Gio
 {
 
 void
 Drive::eject(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -40,7 +38,7 @@ Drive::eject(
 }
 
 void
-Drive::eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
+Drive::eject(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -55,7 +53,7 @@ Drive::eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
 
 void
 Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -69,7 +67,7 @@ Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyn
 
 void
 Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  Mount::UnmountFlags flags)
+  MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -83,7 +81,7 @@ Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyn
 }
 
 void
-Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_drive_eject_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     Glib::unwrap(mount_operation),
@@ -93,7 +91,7 @@ Drive::eject(const Glib::RefPtr<MountOperation>& mount_operation, Mount::Unmount
 }
 
 void
-Drive::eject(Mount::UnmountFlags flags)
+Drive::eject(MountUnmountFlags flags)
 {
   g_drive_eject_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     nullptr, // mount_operation
@@ -136,7 +134,7 @@ Drive::poll_for_media()
 
 void
 Drive::stop(const Glib::RefPtr<MountOperation>& mount_operation,
-  const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, Mount::UnmountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -149,7 +147,7 @@ Drive::stop(const Glib::RefPtr<MountOperation>& mount_operation,
 
 void
 Drive::stop(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  Mount::UnmountFlags flags)
+  MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -162,7 +160,7 @@ Drive::stop(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsync
 
 void
 Drive::start(const Glib::RefPtr<MountOperation>& mount_operation,
-  const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, StartFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, DriveStartFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -175,7 +173,7 @@ Drive::start(const Glib::RefPtr<MountOperation>& mount_operation,
 
 void
 Drive::start(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  StartFlags flags)
+  DriveStartFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
index a89974a..21d2856 100644 (file)
@@ -14,6 +14,7 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmm/listhandle.h>
 #include <giomm/mount.h>
 #include <giomm/icon.h>
 //#include <giomm/volume.h>
@@ -30,6 +31,9 @@ typedef struct _GDriveIface GDriveIface;
 namespace Gio
 {
 
+_WRAP_ENUM(DriveStartFlags, GDriveStartFlags)
+_WRAP_ENUM(DriveStartStopType, GDriveStartStopType)
+
 /** Virtual File System drive management.
  *
  * This represent a piece of hardware connected to the machine. It's generally only created for removable hardware or hardware with removable media.
@@ -42,14 +46,11 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class Drive : public Glib::Interface
+class GIOMM_API Drive : public Glib::Interface
 {
-  _CLASS_INTERFACE(Drive, GDrive, G_DRIVE, GDriveIface)
+  _CLASS_INTERFACE(Drive, GDrive, G_DRIVE, GDriveIface, , , GIOMM_API)
 public:
 
-  _WRAP_ENUM(StartFlags, GDriveStartFlags)
-  _WRAP_ENUM(StartStopType, GDriveStartStopType)
-
   _WRAP_METHOD(Glib::ustring get_name() const, g_drive_get_name)
 
   _WRAP_METHOD(Glib::RefPtr<Icon> get_icon(), g_drive_get_icon, refreturn)
@@ -60,8 +61,8 @@ public:
 
   _WRAP_METHOD(bool has_volumes() const, g_drive_has_volumes)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Volume>>',`Glib::ListHandler<Glib::RefPtr<Volume>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<Volume>> get_volumes(), g_drive_get_volumes)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Volume> > get_volumes(), g_drive_get_volumes)
 
   _WRAP_METHOD(bool is_media_removable() const, g_drive_is_media_removable)
   _WRAP_METHOD(bool is_removable() const,  g_drive_is_removable)
@@ -75,21 +76,21 @@ public:
    * @param flags Flags affecting the unmount if required for eject.
    * @param cancellable A cancellable object which can be used to cancel the eject.
    */
-  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Ejects the drive.
    * @param slot A callback which will be called when the eject is completed.
    * @param flags Flags affecting the unmount if required for eject.
    */
-  void eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Ejects the drive.
    * @param flags Flags affecting the unmount if required for eject.
    */
-  void eject(Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_drive_eject)
   _IGNORE(g_drive_eject_with_operation)
 
@@ -124,13 +125,13 @@ public:
 
   _WRAP_METHOD(std::string get_identifier(const std::string& kind) const, g_drive_get_identifier)
 
-  #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> enumerate_identifiers() const, g_drive_enumerate_identifiers)
+  #m4 _CONVERSION(`char**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle enumerate_identifiers() const, g_drive_enumerate_identifiers)
 
   /** @newin{2,22} */
-  void start(const Glib::RefPtr<MountOperation>& mount_operation, const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, StartFlags flags = StartFlags::NONE);
+  void start(const Glib::RefPtr<MountOperation>& mount_operation, const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, DriveStartFlags flags = DRIVE_START_NONE);
   /** @newin{2,22} */
-  void start(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, StartFlags flags = StartFlags::NONE);
+  void start(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, DriveStartFlags flags = DRIVE_START_NONE);
   _IGNORE(g_drive_start)
   _WRAP_METHOD(bool start_finish(const Glib::RefPtr<AsyncResult>& result), g_drive_start_finish, errthrow)
   /** @newin{2,22} */
@@ -139,24 +140,31 @@ public:
   _WRAP_METHOD(bool can_start_degraded() const, g_drive_can_start_degraded)
 
   /** @newin{2,22} */
-  void stop(const Glib::RefPtr<MountOperation>& mount_operation, const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void stop(const Glib::RefPtr<MountOperation>& mount_operation, const Glib::RefPtr<Cancellable>& cancellable, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   /** @newin{2,22} */
-  void stop(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void stop(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_drive_stop)
   _WRAP_METHOD(bool stop_finish(const Glib::RefPtr<AsyncResult>& result), g_drive_stop_finish, errthrow)
   /** @newin{2,22} */
   _WRAP_METHOD(bool can_stop() const, g_drive_can_stop)
 
-  _WRAP_METHOD(StartStopType get_start_stop_type() const, g_drive_get_start_stop_type)
+  _WRAP_METHOD(DriveStartStopType get_start_stop_type() const, g_drive_get_start_stop_type)
 
   _WRAP_METHOD(Glib::ustring get_sort_key() const,  g_drive_get_sort_key)
 
-  _WRAP_SIGNAL(void changed(), changed, newin "2,20")
-  _WRAP_SIGNAL(void disconnected(), disconnected, newin "2,20")
-  _WRAP_SIGNAL(void eject_button(), eject_button, newin "2,20")
-  _WRAP_SIGNAL(void stop_button(), stop_button)
+  /** @newin{2,20}
+   */
+  _WRAP_SIGNAL(void changed(), changed, no_default_handler)
+
+  /** @newin{2,20}
+   */
+  _WRAP_SIGNAL(void disconnected(), disconnected, no_default_handler)
+
+  /** @newin{2,20}
+   */
+  _WRAP_SIGNAL(void eject_button(), eject_button, no_default_handler)
+  _WRAP_SIGNAL(void stop_button(), stop_button, no_default_handler)
 
-protected:
   //_WRAP_VFUNC(Glib::ustring get_name() const, get_name)
   //Careful of ref-counting: //_WRAP_VFUNC(Glib::RefPtr<Icon> get_icon() const, get_icon)
   //_WRAP_VFUNC(bool has_volumes() const, has_volumes)
@@ -168,6 +176,7 @@ namespace Glib
 {
 
 //Pre-declare this so we can use it in TypeTrait:
+GIOMM_API
 Glib::RefPtr<Gio::Drive> wrap(GDrive* object, bool take_copy);
 
 namespace Container_Helpers
@@ -179,7 +188,7 @@ namespace Container_Helpers
  * would not return a wrapper for an interface.
  */
 template <>
-struct TypeTraits< Glib::RefPtr<Gio::Drive> >
+struct GIOMM_API TypeTraits< Glib::RefPtr<Gio::Drive> >
 {
   using CppType = Glib::RefPtr<Gio::Drive>;
   using CType = GDrive*;
index 0220a12..24667b5 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <gio/gio.h>
 
-using Origin = Gio::Emblem::Origin;
-
 namespace Gio
 {
 
index 1ee816b..712d50c 100644 (file)
@@ -23,6 +23,8 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
+_WRAP_ENUM(EmblemOrigin, GEmblemOrigin, NO_GTYPE)
+
 /** An object for emblems
  *
  * Emblem is an implementation of GIcon that supports having an emblem, which
@@ -34,16 +36,13 @@ namespace Gio
  *
  * @newin{2,20}
  */
-class Emblem
+class GIOMM_API Emblem
 : public Glib::Object,
   public Icon
 {
-  _CLASS_GOBJECT(Emblem, GEmblem, G_EMBLEM, Glib::Object, GObject)
+  _CLASS_GOBJECT(Emblem, GEmblem, G_EMBLEM, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Icon)
 
-public:
-  _WRAP_ENUM(Origin, GEmblemOrigin, NO_GTYPE)
-
 protected:
   /** Creates a new emblem for @a icon.
    * @param icon A Gio::Icon containing the icon.
@@ -52,9 +51,9 @@ protected:
 
   /** Creates a new emblem for @a icon.
    * @param icon A Gio::Icon containing the icon.
-   * @param origin An Origin value defining the emblem's origin
+   * @param origin An EmblemOrigin value defining the emblem's origin
    */
- _WRAP_CTOR(Emblem(const Glib::RefPtr<Icon>& icon, Origin origin), g_emblem_new_with_origin)
+ _WRAP_CTOR(Emblem(const Glib::RefPtr<Icon>& icon, EmblemOrigin origin), g_emblem_new_with_origin)
 
 public:
   /** Creates a new emblem for @a icon.
@@ -64,13 +63,13 @@ public:
 
   /** Creates a new emblem for @a icon.
    * @param icon A Gio::Icon containing the icon.
-   * @param origin An Origin value defining the emblem's origin
+   * @param origin An EmblemOrigin value defining the emblem's origin
    */
-  _WRAP_CREATE(const Glib::RefPtr<Icon>& icon, Origin origin)
+  _WRAP_CREATE(const Glib::RefPtr<Icon>& icon, EmblemOrigin origin)
 
   _WRAP_METHOD(Glib::RefPtr<Icon> get_icon(), g_emblem_get_icon)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_icon() const, g_emblem_get_icon, constversion)
-  _WRAP_METHOD(Origin get_origin() const, g_emblem_get_origin)
+  _WRAP_METHOD(EmblemOrigin get_origin() const, g_emblem_get_origin)
 
 };
 
index de9a291..c8f1cf1 100644 (file)
@@ -14,6 +14,7 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmm/listhandle.h>
 #include <glibmm/object.h>
 #include <giomm/icon.h>
 #include <giomm/emblem.h>
@@ -34,11 +35,11 @@ namespace Gio
  *
  * @newin{2,20}
  */
-class EmblemedIcon
+class GIOMM_API EmblemedIcon
 : public Glib::Object,
   public Icon
 {
-  _CLASS_GOBJECT(EmblemedIcon, GEmblemedIcon, G_EMBLEMED_ICON, Glib::Object, GObject)
+  _CLASS_GOBJECT(EmblemedIcon, GEmblemedIcon, G_EMBLEMED_ICON, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Icon)
 
 protected:
@@ -77,11 +78,11 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Icon> get_icon(), g_emblemed_icon_get_icon)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_icon() const, g_emblemed_icon_get_icon, constversion)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Emblem>>',`Glib::ListHandler<Glib::RefPtr<Emblem>>::list_to_vector($3, Glib::OWNERSHIP_NONE)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<Emblem>> get_emblems(), g_emblemed_icon_get_emblems)
-  dnl// Can't use the constversion parameter in _WRAP_METHOD() when a vector is returned.
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<const Emblem>>',`Glib::ListHandler<Glib::RefPtr<const Emblem>>::list_to_vector($3, Glib::OWNERSHIP_NONE)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<const Emblem>> get_emblems() const, g_emblemed_icon_get_emblems)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle<Glib::RefPtr<Emblem> >',`$2($3, Glib::OWNERSHIP_NONE)')
+  _WRAP_METHOD(Glib::ListHandle<Glib::RefPtr<Emblem> > get_emblems(), g_emblemed_icon_get_emblems)
+
+//TODO: #m4 _CONVERSION(`GList*',`Glib::ListHandle<Glib::RefPtr<const Emblem> >',`$2($3, Glib::OWNERSHIP_NONE)')
+//  _WRAP_METHOD(Glib::ListHandle<Glib::RefPtr<const Emblem> > get_emblems() const, g_emblemed_icon_get_emblems, constversion)
 
   _WRAP_METHOD(void add_emblem(const Glib::RefPtr<Emblem>& emblem), g_emblemed_icon_add_emblem)
   _WRAP_METHOD(void clear_emblems(), g_emblemed_icon_clear_emblems)
index b46b7fe..a80830b 100644 (file)
@@ -22,9 +22,9 @@ _DEFS(giomm,gio)
 namespace Gio
 {
 
-// BIG_ENDIAN and LITTLE_ENDIAN are defined as preprocessor macros somewhere.
-_WRAP_ENUM(DataStreamByteOrder, GDataStreamByteOrder, s#ENDIAN$#ENDIAN_ORDER#)
+_WRAP_ENUM(DataStreamByteOrder, GDataStreamByteOrder)
 _WRAP_ENUM(DataStreamNewlineType, GDataStreamNewlineType)
+_WRAP_ENUM(ErrorEnum, GIOErrorEnum, NO_GTYPE)
 _WRAP_ENUM(SocketFamily, GSocketFamily)
 _WRAP_ENUM(TlsAuthenticationMode, GTlsAuthenticationMode)
 _WRAP_ENUM(TlsCertificateFlags, GTlsCertificateFlags)
index 7df46d2..a754e21 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/error.h>
 #include <glibmm/interface.h>
 
@@ -38,9 +40,9 @@ namespace Gio
 
 /** Exception class for giomm errors.
  */
-_WRAP_GERROR(Error, GIOErrorEnum, G_IO_ERROR, NO_GTYPE)
-_WRAP_GERROR(ResolverError, GResolverError, G_RESOLVER_ERROR, NO_GTYPE)
-_WRAP_GERROR(TlsError, GTlsError, G_TLS_ERROR, NO_GTYPE, s#^EOF$#ENDOFFILE#)
+_WRAP_GERROR(Error, GIOErrorEnum, G_IO_ERROR, NO_GTYPE, decl_prefix GIOMM_API)
+_WRAP_GERROR(ResolverError, GResolverError, G_RESOLVER_ERROR, NO_GTYPE, decl_prefix GIOMM_API)
+_WRAP_GERROR(TlsError, GTlsError, G_TLS_ERROR, NO_GTYPE, s#^EOF$#ENDOFFILE#, decl_prefix GIOMM_API)
 
 } // namespace Gio
 
index 2e8f428..a1ded83 100644 (file)
@@ -222,7 +222,7 @@ File::read_async(
 
 void
 File::append_to_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  CreateFlags flags, int io_priority)
+  FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -234,7 +234,7 @@ File::append_to_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable
 }
 
 void
-File::append_to_async(const SlotAsyncReady& slot, CreateFlags flags, int io_priority)
+File::append_to_async(const SlotAsyncReady& slot, FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -248,7 +248,7 @@ File::append_to_async(const SlotAsyncReady& slot, CreateFlags flags, int io_prio
 
 void
 File::create_file_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  CreateFlags flags, int io_priority)
+  FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -260,7 +260,7 @@ File::create_file_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellab
 }
 
 void
-File::create_file_async(const SlotAsyncReady& slot, CreateFlags flags, int io_priority)
+File::create_file_async(const SlotAsyncReady& slot, FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -274,7 +274,7 @@ File::create_file_async(const SlotAsyncReady& slot, CreateFlags flags, int io_pr
 
 void
 File::create_file_readwrite_async(const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags, int io_priority)
+  const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -287,7 +287,7 @@ File::create_file_readwrite_async(const SlotAsyncReady& slot,
 
 void
 File::create_file_readwrite_async(
-  const SlotAsyncReady& slot, CreateFlags flags, int io_priority)
+  const SlotAsyncReady& slot, FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -301,7 +301,7 @@ File::create_file_readwrite_async(
 
 void
 File::replace_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  const std::string& etag, bool make_backup, CreateFlags flags, int io_priority)
+  const std::string& etag, bool make_backup, FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -315,7 +315,7 @@ File::replace_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>&
 
 void
 File::replace_async(const SlotAsyncReady& slot, const std::string& etag, bool make_backup,
-  CreateFlags flags, int io_priority)
+  FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -355,7 +355,7 @@ File::open_readwrite_async(
 void
 File::replace_readwrite_async(const SlotAsyncReady& slot,
   const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag, bool make_backup,
-  CreateFlags flags, int io_priority)
+  FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -369,7 +369,7 @@ File::replace_readwrite_async(const SlotAsyncReady& slot,
 
 void
 File::replace_readwrite_async(const SlotAsyncReady& slot, const std::string& etag, bool make_backup,
-  CreateFlags flags, int io_priority)
+  FileCreateFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -580,7 +580,7 @@ File::set_display_name_async(
 
 bool
 File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -602,7 +602,7 @@ File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
 }
 
 bool
-File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, CopyFlags flags)
+File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -624,7 +624,7 @@ File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
 }
 
 bool
-File::copy(const Glib::RefPtr<File>& destination, CopyFlags flags)
+File::copy(const Glib::RefPtr<File>& destination, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res = g_file_copy(gobj(), Glib::unwrap(destination), static_cast<GFileCopyFlags>(flags),
@@ -639,7 +639,7 @@ File::copy(const Glib::RefPtr<File>& destination, CopyFlags flags)
 void
 File::copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress,
   const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable,
-  CopyFlags flags, int io_priority)
+  FileCopyFlags flags, int io_priority)
 {
   // Create a new pair which will hold copies of passed slots.
   // This will be deleted in the SignalProxy_file_copy_async_callback() callback
@@ -657,7 +657,7 @@ File::copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress&
 
 void
 File::copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready,
-  const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags, int io_priority)
+  const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags, int io_priority)
 {
   // Create copies of slots.
   // Pointers to them will be passed through the callbacks' data parameter
@@ -671,7 +671,7 @@ File::copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& sl
 
 void
 File::copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress,
-  const SlotAsyncReady& slot_ready, CopyFlags flags, int io_priority)
+  const SlotAsyncReady& slot_ready, FileCopyFlags flags, int io_priority)
 {
   // Create a new pair which will hold copies of passed slots.
   // This will be deleted in the SignalProxy_file_copy_async_callback() callback
@@ -689,7 +689,7 @@ File::copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress&
 
 void
 File::copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready,
-  CopyFlags flags, int io_priority)
+  FileCopyFlags flags, int io_priority)
 {
   // Create copies of slots.
   // Pointers to them will be passed through the callbacks' data parameter
@@ -702,7 +702,7 @@ File::copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& sl
 
 bool
 File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -724,7 +724,7 @@ File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
 }
 
 bool
-File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, CopyFlags flags)
+File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -746,7 +746,7 @@ File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
 }
 
 bool
-File::move(const Glib::RefPtr<File>& destination, CopyFlags flags)
+File::move(const Glib::RefPtr<File>& destination, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -804,7 +804,7 @@ File::set_attributes_finish(
 
 void
 File::mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation,
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -818,7 +818,7 @@ File::mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation,
 
 void
 File::mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation,
-  const SlotAsyncReady& slot, Mount::MountFlags flags)
+  const SlotAsyncReady& slot, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -830,7 +830,7 @@ File::mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation,
 }
 
 void
-File::mount_mountable(const SlotAsyncReady& slot, Mount::MountFlags flags)
+File::mount_mountable(const SlotAsyncReady& slot, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -842,7 +842,7 @@ File::mount_mountable(const SlotAsyncReady& slot, Mount::MountFlags flags)
 }
 
 void
-File::mount_mountable(Mount::MountFlags flags)
+File::mount_mountable(MountMountFlags flags)
 {
   g_file_mount_mountable(
     gobj(), static_cast<GMountMountFlags>(flags), nullptr, nullptr, nullptr, nullptr);
@@ -850,7 +850,7 @@ File::mount_mountable(Mount::MountFlags flags)
 
 void
 File::unmount_mountable(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -862,7 +862,7 @@ File::unmount_mountable(
 }
 
 void
-File::unmount_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
+File::unmount_mountable(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -874,7 +874,7 @@ File::unmount_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
 }
 
 void
-File::unmount_mountable(Mount::UnmountFlags flags)
+File::unmount_mountable(MountUnmountFlags flags)
 {
   g_file_unmount_mountable_with_operation(
     gobj(), static_cast<GMountUnmountFlags>(flags), nullptr, nullptr, nullptr, nullptr);
@@ -882,7 +882,7 @@ File::unmount_mountable(Mount::UnmountFlags flags)
 
 void
 File::unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -896,7 +896,7 @@ File::unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellab
 
 void
 File::unmount_mountable(const SlotAsyncReady& slot,
-  const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -909,7 +909,7 @@ File::unmount_mountable(const SlotAsyncReady& slot,
 
 void
 File::unmount_mountable(
-  const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_file_unmount_mountable_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     Glib::unwrap(mount_operation), nullptr, nullptr, nullptr);
@@ -917,7 +917,7 @@ File::unmount_mountable(
 
 void
 File::mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation,
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -931,7 +931,7 @@ File::mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation
 
 void
 File::mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation,
-  const SlotAsyncReady& slot, Mount::MountFlags flags)
+  const SlotAsyncReady& slot, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -943,7 +943,7 @@ File::mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation
 }
 
 void
-File::mount_enclosing_volume(const SlotAsyncReady& slot, Mount::MountFlags flags)
+File::mount_enclosing_volume(const SlotAsyncReady& slot, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -955,7 +955,7 @@ File::mount_enclosing_volume(const SlotAsyncReady& slot, Mount::MountFlags flags
 }
 
 void
-File::mount_enclosing_volume(Mount::MountFlags flags)
+File::mount_enclosing_volume(MountMountFlags flags)
 {
   g_file_mount_enclosing_volume(
     gobj(), static_cast<GMountMountFlags>(flags), nullptr, nullptr, nullptr, nullptr);
@@ -963,7 +963,7 @@ File::mount_enclosing_volume(Mount::MountFlags flags)
 
 void
 File::eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -977,7 +977,7 @@ File::eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable
 
 void
 File::eject_mountable(const SlotAsyncReady& slot,
-  const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -989,7 +989,7 @@ File::eject_mountable(const SlotAsyncReady& slot,
 }
 
 void
-File::eject_mountable(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+File::eject_mountable(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_file_eject_mountable_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     Glib::unwrap(mount_operation), nullptr, nullptr, nullptr);
@@ -997,7 +997,7 @@ File::eject_mountable(const Glib::RefPtr<MountOperation>& mount_operation, Mount
 
 void
 File::eject_mountable(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1009,7 +1009,7 @@ File::eject_mountable(
 }
 
 void
-File::eject_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
+File::eject_mountable(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1021,7 +1021,7 @@ File::eject_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
 }
 
 void
-File::eject_mountable(Mount::UnmountFlags flags)
+File::eject_mountable(MountUnmountFlags flags)
 {
   g_file_eject_mountable_with_operation(
     gobj(), static_cast<GMountUnmountFlags>(flags), nullptr, nullptr, nullptr, nullptr);
@@ -1089,7 +1089,7 @@ File::load_partial_contents_async(
 void
 File::replace_contents(const char* contents, gsize length, const std::string& etag,
   std::string& new_etag, const Glib::RefPtr<Cancellable>& cancellable, bool make_backup,
-  CreateFlags flags)
+  FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   gchar* c_etag_new = nullptr;
@@ -1107,7 +1107,7 @@ File::replace_contents(const char* contents, gsize length, const std::string& et
 
 void
 File::replace_contents(const char* contents, gsize length, const std::string& etag,
-  std::string& new_etag, bool make_backup, CreateFlags flags)
+  std::string& new_etag, bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   gchar* c_etag_new = nullptr;
@@ -1124,7 +1124,7 @@ File::replace_contents(const char* contents, gsize length, const std::string& et
 
 void
 File::replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag,
-  const Glib::RefPtr<Cancellable>& cancellable, bool make_backup, CreateFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   gchar* c_etag_new = nullptr;
@@ -1142,7 +1142,7 @@ File::replace_contents(const std::string& contents, const std::string& etag, std
 
 void
 File::replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag,
-  bool make_backup, CreateFlags flags)
+  bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   gchar* c_etag_new = nullptr;
@@ -1160,7 +1160,7 @@ File::replace_contents(const std::string& contents, const std::string& etag, std
 void
 File::replace_contents_async(const SlotAsyncReady& slot,
   const Glib::RefPtr<Cancellable>& cancellable, const char* contents, gsize length,
-  const std::string& etag, bool make_backup, CreateFlags flags)
+  const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1174,7 +1174,7 @@ File::replace_contents_async(const SlotAsyncReady& slot,
 
 void
 File::replace_contents_async(const SlotAsyncReady& slot, const char* contents, gsize length,
-  const std::string& etag, bool make_backup, CreateFlags flags)
+  const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1188,7 +1188,7 @@ File::replace_contents_async(const SlotAsyncReady& slot, const char* contents, g
 void
 File::replace_contents_async(const SlotAsyncReady& slot,
   const Glib::RefPtr<Cancellable>& cancellable, const std::string& contents,
-  const std::string& etag, bool make_backup, CreateFlags flags)
+  const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1202,7 +1202,7 @@ File::replace_contents_async(const SlotAsyncReady& slot,
 
 void
 File::replace_contents_async(const SlotAsyncReady& slot, const std::string& contents,
-  const std::string& etag, bool make_backup, CreateFlags flags)
+  const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1241,7 +1241,7 @@ File::replace_contents_finish(const Glib::RefPtr<AsyncResult>& result)
 void
 File::replace_contents_bytes_async(const SlotAsyncReady& slot,
   const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<const Glib::Bytes>& contents,
-  const std::string& etag, bool make_backup, CreateFlags flags)
+  const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1256,7 +1256,7 @@ File::replace_contents_bytes_async(const SlotAsyncReady& slot,
 void
 File::replace_contents_bytes_async(const SlotAsyncReady& slot,
   const Glib::RefPtr<const Glib::Bytes>& contents, const std::string& etag, bool make_backup,
-  CreateFlags flags)
+  FileCreateFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1270,7 +1270,7 @@ File::replace_contents_bytes_async(const SlotAsyncReady& slot,
 
 Glib::RefPtr<FileOutputStream>
 File::replace(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag,
-  bool make_backup, CreateFlags flags)
+  bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_replace(gobj(), Glib::c_str_or_nullptr(etag),
@@ -1283,7 +1283,7 @@ File::replace(const Glib::RefPtr<Cancellable>& cancellable, const std::string& e
 }
 
 Glib::RefPtr<FileOutputStream>
-File::replace(const std::string& etag, bool make_backup, CreateFlags flags)
+File::replace(const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_replace(gobj(), Glib::c_str_or_nullptr(etag),
@@ -1296,7 +1296,7 @@ File::replace(const std::string& etag, bool make_backup, CreateFlags flags)
 
 Glib::RefPtr<FileIOStream>
 File::replace_readwrite(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag,
-  bool make_backup, CreateFlags flags)
+  bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_replace_readwrite(gobj(), Glib::c_str_or_nullptr(etag),
@@ -1309,7 +1309,7 @@ File::replace_readwrite(const Glib::RefPtr<Cancellable>& cancellable, const std:
 }
 
 Glib::RefPtr<FileIOStream>
-File::replace_readwrite(const std::string& etag, bool make_backup, CreateFlags flags)
+File::replace_readwrite(const std::string& etag, bool make_backup, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_replace_readwrite(gobj(), Glib::c_str_or_nullptr(etag),
@@ -1395,7 +1395,7 @@ File::monitor(FileMonitorFlags flags)
 void
 File::measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable,
   const SlotFileMeasureProgress& slot_progress, guint64& disk_usage, guint64& num_dirs,
-  guint64& num_files, MeasureFlags flags)
+  guint64& num_files, FileMeasureFlags flags)
 {
   GError* gerror = nullptr;
   g_file_measure_disk_usage(gobj(), ((GFileMeasureFlags)(flags)),
@@ -1410,7 +1410,7 @@ File::measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable,
 void
 File::measure_disk_usage_async(const SlotAsyncReady& slot_ready,
   const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& slot_progress,
-  MeasureFlags flags, int io_priority)
+  FileMeasureFlags flags, int io_priority)
 {
   // Create a new pair which will hold copies of passed slots.
   // This will be deleted in the SignalProxy_file_measure_async_callback() callback
@@ -1430,7 +1430,7 @@ File::measure_disk_usage_async(const SlotAsyncReady& slot_ready,
 
 void
 File::start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  const Glib::RefPtr<MountOperation>& start_operation, Drive::StartFlags flags)
+  const Glib::RefPtr<MountOperation>& start_operation, DriveStartFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1443,7 +1443,7 @@ File::start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable
 
 void
 File::start_mountable(const SlotAsyncReady& slot,
-  const Glib::RefPtr<MountOperation>& start_operation, Drive::StartFlags flags)
+  const Glib::RefPtr<MountOperation>& start_operation, DriveStartFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1456,7 +1456,7 @@ File::start_mountable(const SlotAsyncReady& slot,
 
 void
 File::stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-  const Glib::RefPtr<MountOperation>& start_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& start_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1469,7 +1469,7 @@ File::stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>
 
 void
 File::stop_mountable(const SlotAsyncReady& slot,
-  const Glib::RefPtr<MountOperation>& start_operation, Mount::UnmountFlags flags)
+  const Glib::RefPtr<MountOperation>& start_operation, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -1555,7 +1555,7 @@ File::set_attributes_from_info(const Glib::RefPtr<FileInfo>& info, FileQueryInfo
 
 bool
 File::copy_attributes(const Glib::RefPtr<File>& destination,
-  const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -1570,7 +1570,7 @@ File::copy_attributes(const Glib::RefPtr<File>& destination,
 }
 
 bool
-File::copy_attributes(const Glib::RefPtr<File>& destination, CopyFlags flags)
+File::copy_attributes(const Glib::RefPtr<File>& destination, FileCopyFlags flags)
 {
   GError* gerror = nullptr;
   bool res;
@@ -1585,7 +1585,7 @@ File::copy_attributes(const Glib::RefPtr<File>& destination, CopyFlags flags)
 }
 
 Glib::RefPtr<FileOutputStream>
-File::create_file(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags)
+File::create_file(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_create(gobj(), ((GFileCreateFlags)(flags)),
@@ -1597,7 +1597,7 @@ File::create_file(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flag
 }
 
 Glib::RefPtr<FileOutputStream>
-File::create_file(CreateFlags flags)
+File::create_file(FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue =
@@ -1609,7 +1609,7 @@ File::create_file(CreateFlags flags)
 }
 
 Glib::RefPtr<FileIOStream>
-File::create_file_readwrite(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags)
+File::create_file_readwrite(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_create_readwrite(gobj(), ((GFileCreateFlags)(flags)),
@@ -1621,7 +1621,7 @@ File::create_file_readwrite(const Glib::RefPtr<Cancellable>& cancellable, Create
 }
 
 Glib::RefPtr<FileIOStream>
-File::create_file_readwrite(CreateFlags flags)
+File::create_file_readwrite(FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue =
@@ -1633,7 +1633,7 @@ File::create_file_readwrite(CreateFlags flags)
 }
 
 Glib::RefPtr<FileOutputStream>
-File::append_to(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags)
+File::append_to(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::wrap(g_file_append_to(gobj(), ((GFileCreateFlags)(flags)),
@@ -1645,7 +1645,7 @@ File::append_to(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags)
 }
 
 Glib::RefPtr<FileOutputStream>
-File::append_to(CreateFlags flags)
+File::append_to(FileCreateFlags flags)
 {
   GError* gerror = nullptr;
   auto retvalue =
index 32e2b0e..e49dee8 100644 (file)
@@ -40,11 +40,14 @@ typedef struct _GFileIface GFileIface;
 namespace Gio
 {
 
-class Mount;
-class Volume;
+class GIOMM_API Mount;
+class GIOMM_API Volume;
 
 _WRAP_ENUM(FileQueryInfoFlags, GFileQueryInfoFlags, NO_GTYPE)
+_WRAP_ENUM(FileCreateFlags, GFileCreateFlags, NO_GTYPE)
+_WRAP_ENUM(FileCopyFlags, GFileCopyFlags, NO_GTYPE)
 _WRAP_ENUM(FileMonitorFlags, GFileMonitorFlags, NO_GTYPE)
+_WRAP_ENUM(FileMeasureFlags, GFileMeasureFlags, NO_GTYPE)
 
 
 /** File and directory handling.
@@ -71,14 +74,11 @@ _WRAP_ENUM(FileMonitorFlags, GFileMonitorFlags, NO_GTYPE)
  *
  * @newin{2,16}
  */
-class File : public Glib::Interface
+class GIOMM_API File : public Glib::Interface
 {
-  _CLASS_INTERFACE(File, GFile, G_FILE, GFileIface)
+  _CLASS_INTERFACE(File, GFile, G_FILE, GFileIface, , , GIOMM_API)
 
 public:
-  _WRAP_ENUM(CreateFlags, GFileCreateFlags, NO_GTYPE)
-  _WRAP_ENUM(CopyFlags, GFileCopyFlags, NO_GTYPE)
-  _WRAP_ENUM(MeasureFlags, GFileMeasureFlags, NO_GTYPE)
 
   _IGNORE(g_file_icon_new) //g_file_icon_new is not a GFile method.
 
@@ -221,7 +221,7 @@ public:
    * the file doesn't already exist it is created.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -234,17 +234,17 @@ public:
    * If the file is a directory a Gio::Error with IS_DIRECTORY will be
    * thrown. Other errors are possible too, and depend on what kind of
    * filesystem the file is on.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param cancellable Optional Cancellable object.
    * @return A FileOutputStream.
    */
-  Glib::RefPtr<FileOutputStream> append_to(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> append_to(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Gets an output stream for appending data to the file. If
    * the file doesn't already exist it is created.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -253,10 +253,10 @@ public:
    * If the file is a directory a Gio::Error with IS_DIRECTORY will be
    * thrown. Other errors are possible too, and depend on what kind of
    * filesystem the file is on.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @return A FileOutputStream.
    */
-  Glib::RefPtr<FileOutputStream> append_to(CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> append_to(FileCreateFlags flags = FILE_CREATE_NONE);
   _IGNORE(g_file_append_to)
 
   //We renamed this to create_file from (g_file_create() and g_file_create_readwrite), to avoid confusion with static create() methods,
@@ -266,7 +266,7 @@ public:
    * The file must not already exist.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -284,16 +284,16 @@ public:
    * filesystem the file is on.
    *
    * @param cancellable A Cancellable object which can be used to cancel the operation.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @return A FileOutputStream for the newly created file.
    */
-  Glib::RefPtr<FileOutputStream> create_file(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> create_file(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Creates a new file and returns an output stream for writing to it.
    * The file must not already exist.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -307,17 +307,17 @@ public:
    * Other errors are possible too, and depend on what kind of
    * filesystem the file is on.
    *
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @return A FileOutputStream for the newly created file.
    */
-  Glib::RefPtr<FileOutputStream> create_file(CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> create_file(FileCreateFlags flags = FILE_CREATE_NONE);
   _IGNORE(g_file_create)
 
   /** Creates a new file and returns a stream for reading and writing to it.
    * The file must not already exist.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -339,16 +339,16 @@ public:
    * rather than just opening for reading or writing.
    *
    * @param cancellable A Cancellable object which can be used to cancel the operation.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @return A FileOutputStream for the newly created file.
    */
-  Glib::RefPtr<FileIOStream> create_file_readwrite(const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileIOStream> create_file_readwrite(const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Creates a new file and returns a stream for reading and writing to it.
    * The file must not already exist.
    *
    * By default files created are generally readable by everyone,
-   * but if you pass CreateFlags::PRIVATE in @a flags the file
+   * but if you pass FILE_CREATE_PRIVATE in @a flags the file
    * will be made readable only to the current user, to the level that
    * is supported on the target filesystem.
    *
@@ -366,10 +366,10 @@ public:
    * supported, so make sure you really need to do read and write streaming,
    * rather than just opening for reading or writing.
    *
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @return A FileOutputStream for the newly created file.
    */
-  Glib::RefPtr<FileIOStream> create_file_readwrite(CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileIOStream> create_file_readwrite(FileCreateFlags flags = FILE_CREATE_NONE);
   _IGNORE(g_file_create_readwrite)
 
 
@@ -379,7 +379,7 @@ public:
    * not affect an already existing copy of the file. For instance, for local files it may write to a
    * temporary file and then atomically rename over the destination when the stream is closed.
    *
-   * By default files created are generally readable by everyone, but if you pass CreateFlags::PRIVATE in
+   * By default files created are generally readable by everyone, but if you pass FILE_CREATE_PRIVATE in
    * @a flags the file will be made readable only to the current user, to the level that is supported on the
    * target filesystem.
    *
@@ -405,10 +405,10 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param etag An optional entity tag for the current Glib::File.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @return A FileOutputStream.
    */
-  Glib::RefPtr<FileOutputStream> replace(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> replace(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
 
   /** Returns an output stream for overwriting the file, possibly creating a backup copy of the file first.
@@ -416,7 +416,7 @@ public:
    * not affect an already existing copy of the file. For instance, for local files it may write to a
    * temporary file and then atomically rename over the destination when the stream is closed.
    *
-   * By default files created are generally readable by everyone, but if you pass CreateFlags::PRIVATE in
+   * By default files created are generally readable by everyone, but if you pass FILE_CREATE_PRIVATE in
    * @a flags the file will be made readable only to the current user, to the level that is supported on the
    * target filesystem.
    *
@@ -438,10 +438,10 @@ public:
    *
    * @param etag An optional entity tag for the current Glib::File.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @return A FileOutputStream.
    */
-  Glib::RefPtr<FileOutputStream> replace(const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileOutputStream> replace(const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   _IGNORE(g_file_replace)
 
@@ -452,20 +452,20 @@ public:
    * When the operation is finished, @a slot will be called. You can then call append_to_finish() to get the result of the operation.
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param cancellable A Cancellable object which can be used to cancel the operation.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void append_to_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void append_to_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asynchronously opens the file for appending.
    * For more details, see append_to() which is the synchronous version of this call.
    *
    * When the operation is finished, @a slot will be called. You can then call append_to_finish() to get the result of the operation.
    * @param slot A callback slot which will be called when the request is satisfied.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void append_to_async(const SlotAsyncReady& slot, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void append_to_async(const SlotAsyncReady& slot, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_append_to_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileOutputStream> append_to_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -482,10 +482,10 @@ public:
    *
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param cancellable A Cancellable object which can be used to cancel the operation.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void create_file_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void create_file_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asynchronously creates a new file and returns an output stream for writing to it. The file must not already exist.
    * For more details, see create_file() which is the synchronous version of this call.
@@ -493,10 +493,10 @@ public:
    * When the operation is finished, @a slot will be called. You can then call create_file_finish() to get the result of the operation.
    *
    * @param slot A callback slot which will be called when the request is satisfied.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void create_file_async(const SlotAsyncReady& slot, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void create_file_async(const SlotAsyncReady& slot, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_create_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileOutputStream> create_file_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -513,12 +513,12 @@ public:
    *
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param cancellable A Cancellable object which can be used to cancel the operation.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    *
    * @newin{2,24}
    */
-  void create_file_readwrite_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void create_file_readwrite_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asynchronously creates a new file and returns a stream for reading and
    * writing to it. The file must not already exist.
@@ -528,12 +528,12 @@ public:
    * When the operation is finished, @a slot will be called. You can then call create_file_readwrite_finish() to get the result of the operation.
    *
    * @param slot A callback slot which will be called when the request is satisfied.
-   * @param flags a set of CreateFlags.
+   * @param flags a set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    *
    * @newin{2,24}
    */
-  void create_file_readwrite_async(const SlotAsyncReady& slot, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void create_file_readwrite_async(const SlotAsyncReady& slot, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_create_readwrite_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileIOStream> create_file_readwrite_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -548,10 +548,10 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param etag An entity tag for the current Gio::File.
    * @param make_backup true if a backup of the existing file should be made.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void replace_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void replace_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asyncronously overwrites the file, replacing the contents, possibly creating a backup copy of the file first.
    * For more details, see replace() which is the synchronous version of this call.
@@ -560,10 +560,10 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param etag An entity tag for the current Gio::File.
    * @param make_backup true if a backup of the existing file should be made.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void replace_async(const SlotAsyncReady& slot, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void replace_async(const SlotAsyncReady& slot, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_replace_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileOutputStream> replace_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -633,12 +633,12 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param etag An optional entity tag for the current Glib::File.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @return A FileOutputStream.
    *
    * @newin{2,24}
    */
-  Glib::RefPtr<FileIOStream> replace_readwrite(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileIOStream> replace_readwrite(const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
 
   /** Returns an output stream for overwriting the file in readwrite mode, possibly creating a backup copy of the file first.
@@ -653,12 +653,12 @@ public:
    *
    * @param etag An optional entity tag for the current Glib::File.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @return A FileOutputStream.
    *
    * @newin{2,24}
    */
-  Glib::RefPtr<FileIOStream> replace_readwrite(const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  Glib::RefPtr<FileIOStream> replace_readwrite(const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   _IGNORE(g_file_replace_readwrite)
 
@@ -673,12 +673,12 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param etag An entity tag for the current Gio::File.
    * @param make_backup true if a backup of the existing file should be made.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    *
    * @newin{2,24}
    */
-  void replace_readwrite_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void replace_readwrite_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asyncronously overwrites the file in read-write mode, replacing the contents, possibly creating a backup copy of the file first.
    *
@@ -688,12 +688,12 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param etag An entity tag for the current Gio::File.
    * @param make_backup true if a backup of the existing file should be made.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param io_priority The I/O priority of the request.
    *
    * @newin{2,24}
    */
-  void replace_readwrite_async(const SlotAsyncReady& slot, const std::string& etag = {}, bool make_backup = false, CreateFlags flags = CreateFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void replace_readwrite_async(const SlotAsyncReady& slot, const std::string& etag = std::string(), bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_replace_readwrite_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileIOStream> replace_readwrite_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -718,7 +718,7 @@ public:
    *
    * For symlinks, normally the information about the target of the
    * symlink is returned, rather than information about the symlink itself.
-   * However if you pass FileQueryInfoFlags::NOFOLLOW_SYMLINKS in @a flags the
+   * However if you pass FILE_QUERY_INFO_NOFOLLOW_SYMLINKS in @a flags the
    * information about the symlink itself will be returned. Also, for symlinks
    * that point to non-existing files the information about the symlink itself
    * will be returned.
@@ -731,7 +731,7 @@ public:
    * @param flags: A set of FileQueryInfoFlags.
    * @result a FileInfo for the file, or an empty RefPtr on error.
    */
-  Glib::RefPtr<FileInfo> query_info(const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE) const;
+  Glib::RefPtr<FileInfo> query_info(const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE) const;
 
   /** Gets the requested information about the file. The result
    * is a FileInfo object that contains key-value attributes (such as the  type or size
@@ -747,7 +747,7 @@ public:
    *
    * For symlinks, normally the information about the target of the
    * symlink is returned, rather than information about the symlink itself.
-   * However if you pass FileQueryInfoFlags::NOFOLLOW_SYMLINKS in @a flags the
+   * However if you pass FILE_QUERY_INFO_NOFOLLOW_SYMLINKS in @a flags the
    * information about the symlink itself will be returned. Also, for symlinks
    * that point to non-existing files the information about the symlink itself
    * will be returned.
@@ -759,7 +759,7 @@ public:
    * @param flags: A set of FileQueryInfoFlags.
    * @result a FileInfo for the file, or an empty RefPtr on error.
    */
-  Glib::RefPtr<FileInfo> query_info(const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE) const;
+  Glib::RefPtr<FileInfo> query_info(const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE) const;
 
   _IGNORE(g_file_query_info)
 
@@ -779,7 +779,7 @@ public:
    *
    * @newin{2,18}
    */
-   FileType query_file_type(FileQueryInfoFlags flags = FileQueryInfoFlags::NONE) const;
+   FileType query_file_type(FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE) const;
 
   /** Asynchronously gets the requested information about specified file. The result is a FileInfo object that contains key-value attributes (such as type or size for the file).
    *
@@ -792,7 +792,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void query_info_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT) const;
+  void query_info_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT) const;
 
   /** Asynchronously gets the requested information about specified file. The result is a FileInfo object that contains key-value attributes (such as type or size for the file).
    *
@@ -804,7 +804,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void query_info_async(const SlotAsyncReady& slot, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT) const;
+  void query_info_async(const SlotAsyncReady& slot, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT) const;
   _IGNORE(g_file_query_info_async)
 
 
@@ -958,7 +958,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @return A FileEnumerator if successful.
    */
-  Glib::RefPtr<FileEnumerator> enumerate_children(const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE);
+  Glib::RefPtr<FileEnumerator> enumerate_children(const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE);
   _IGNORE(g_file_enumerate_children)
 
   /** Gets the requested information about the files in a directory. The result
@@ -981,7 +981,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @return A FileEnumerator if successful.
    */
-  Glib::RefPtr<FileEnumerator> enumerate_children(const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE);
+  Glib::RefPtr<FileEnumerator> enumerate_children(const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE);
   _IGNORE(g_file_enumerate_children)
 
 
@@ -997,7 +997,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void enumerate_children_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void enumerate_children_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asynchronously gets the requested information about the files in a directory. The result is a GFileEnumerator object that will give out GFileInfo objects for all the files in the directory.
    *
@@ -1009,7 +1009,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void enumerate_children_async(const SlotAsyncReady& slot, const std::string& attributes = "*", FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void enumerate_children_async(const SlotAsyncReady& slot, const std::string& attributes = "*", FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_enumerate_children_async)
 
   _WRAP_METHOD(Glib::RefPtr<FileEnumerator> enumerate_children_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -1117,11 +1117,11 @@ public:
   /** A signal handler would be, for instance:
    * void on_file_progress(goffset current_num_bytes, goffset total_num_bytes);
    */
-  using SlotFileProgress = sigc::slot<void(goffset, goffset)>;
+  using SlotFileProgress = sigc::slot<void, goffset, goffset>;
 
   /** Copies the file source to the location specified by destination. Can not handle recursive copies of directories.
-   * If the flag CopyFlags::OVERWRITE is specified an already existing destination file is overwritten.
-   * If the flag CopyFlags::NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
+   * If the flag FILE_COPY_OVERWRITE is specified an already existing destination file is overwritten.
+   * If the flag FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
    *
    * The operation can be cancelled by triggering the cancellable object from another thread. If the operation was cancelled, a Gio::Error with CANCELLED will be thrown.
    *
@@ -1129,55 +1129,55 @@ public:
    *
    * If the source file does not exist then a Gio::Error with NOT_FOUND will be thrown, independent on the status of the destination.
    *
-   * If CopyFlags::OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
+   * If FILE_COPY_OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
    *
    * If trying to overwrite a file over a directory a Gio::Error with IS_DIRECTORY will be thrown.
    * If trying to overwrite a directory with a directory a Gio::Error with WOULD_MERGE will be thrown.
    *
-   * If the source is a directory and the target does not exist, or CopyFlags::OVERWRITE is specified and the target is a file,
+   * If the source is a directory and the target does not exist, or FILE_COPY_OVERWRITE is specified and the target is a file,
    * then a Gio::Error with WOULD_RECURSE will be thrown.
    *
    * If you are interested in copying the Gio::File object itself (not the on-disk file), see File::dup().
    */
-  bool copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags = CopyFlags::NONE);
+  bool copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags = FILE_COPY_NONE);
 
   /** Copies the file source to the location specified by destination. Can not handle recursive copies of directories.
-   * If the flag CopyFlags::OVERWRITE is specified an already existing destination file is overwritten.
-   * If the flag CopyFlags::NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
+   * If the flag FILE_COPY_OVERWRITE is specified an already existing destination file is overwritten.
+   * If the flag FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
    *
    * The operation can be monitored via the @a slot callback.
    *
    * If the source file does not exist then a Gio::Error with NOT_FOUND will be thrown, independent on the status of the destination.
    *
-   * If CopyFlags::OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
+   * If FILE_COPY_OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
    *
    * If trying to overwrite a file over a directory a Gio::Error with IS_DIRECTORY will be thrown.
    * If trying to overwrite a directory with a directory a Gio::Error with WOULD_MERGE will be thrown.
    *
-   * If the source is a directory and the target does not exist, or CopyFlags::OVERWRITE is specified and the target is a file,
+   * If the source is a directory and the target does not exist, or FILE_COPY_OVERWRITE is specified and the target is a file,
    * then a Gio::Error with WOULD_RECURSE will be thrown.
    *
    * If you are interested in copying the Gio::File object itself (not the on-disk file), see File::dup().
    */
-  bool copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, CopyFlags flags = CopyFlags::NONE);
+  bool copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, FileCopyFlags flags = FILE_COPY_NONE);
 
   /** Copies the file source to the location specified by destination. Can not handle recursive copies of directories.
-   * If the flag CopyFlags::OVERWRITE is specified an already existing destination file is overwritten.
-   * If the flag CopyFlags::NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
+   * If the flag FILE_COPY_OVERWRITE is specified an already existing destination file is overwritten.
+   * If the flag FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
    *
    * If the source file does not exist then a Gio::Error with NOT_FOUND will be thrown, independent on the status of the destination.
    *
-   * If CopyFlags::OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
+   * If FILE_COPY_OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
    *
    * If trying to overwrite a file over a directory a Gio::Error with IS_DIRECTORY will be thrown.
    * If trying to overwrite a directory with a directory a Gio::Error with WOULD_MERGE will be thrown.
    *
-   * If the source is a directory and the target does not exist, or CopyFlags::OVERWRITE is specified and the target is a file,
+   * If the source is a directory and the target does not exist, or FILE_COPY_OVERWRITE is specified and the target is a file,
    * then a Gio::Error with WOULD_RECURSE will be thrown.
    *
    * If you are interested in copying the Gio::File object itself (not the on-disk file), see File::dup().
    */
-  bool copy(const Glib::RefPtr<File>& destination, CopyFlags flags = CopyFlags::NONE);
+  bool copy(const Glib::RefPtr<File>& destination, FileCopyFlags flags = FILE_COPY_NONE);
   _IGNORE(g_file_copy)
 
   /** Copies the file to the location specified by @a destination asynchronously.
@@ -1194,10 +1194,10 @@ public:
    * @param slot_progress The callback slot to be called with progress information
    * @param slot_ready A SlotAsyncReady to call when the request is satisfied
    * @param cancellable A Cancellable object which can be used to cancel the operation
-   * @param flags Set of CopyFlags
+   * @param flags Set of FileCopyFlags
    * @param io_priority The I/O priority of the request
    */
-  void copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress, const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags = CopyFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress, const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags = FILE_COPY_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Copies the file to the location specified by @a destination asynchronously.
    * For details of the behaviour, see copy().
@@ -1208,10 +1208,10 @@ public:
    * @param destination Destination File
    * @param slot_ready A SlotAsyncReady to call when the request is satisfied
    * @param cancellable A Cancellable object which can be used to cancel the operation
-   * @param flags Set of CopyFlags
+   * @param flags Set of FileCopyFlags
    * @param io_priority The I/O priority of the request
    */
-  void copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags = CopyFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags = FILE_COPY_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Copies the file to the location specified by @a destination asynchronously.
    * For details of the behaviour, see copy().
@@ -1226,10 +1226,10 @@ public:
    * @param destination Destination File
    * @param slot_progress The callback slot to be called with progress information
    * @param slot_ready A SlotAsyncReady to call when the request is satisfied
-   * @param flags Set of CopyFlags
+   * @param flags Set of FileCopyFlags
    * @param io_priority The I/O priority of the request
    */
-  void copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress, const SlotAsyncReady& slot_ready, CopyFlags flags = CopyFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void copy_async(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot_progress, const SlotAsyncReady& slot_ready, FileCopyFlags flags = FILE_COPY_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Copies the file to the location specified by @a destination asynchronously.
    * For details of the behaviour, see copy().
@@ -1239,10 +1239,10 @@ public:
    *
    * @param destination Destination File
    * @param slot_ready A SlotAsyncReady to call when the request is satisfied
-   * @param flags Set of CopyFlags
+   * @param flags Set of FileCopyFlags
    * @param io_priority The I/O priority of the request
    */
-  void copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready, CopyFlags flags = CopyFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void copy_async(const Glib::RefPtr<File>& destination, const SlotAsyncReady& slot_ready, FileCopyFlags flags = FILE_COPY_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_copy_async)
 
   _WRAP_METHOD(bool copy_finish(const Glib::RefPtr<AsyncResult>& res),
@@ -1253,27 +1253,27 @@ public:
    * used, otherwise a copy and delete fallback is used. The native implementation may support moving directories (for instance on moves inside
    * the same filesystem), but the fallback code does not.
    *
-   * If the flag CopyFlags::OVERWRITE is specified an already existing destination file is overwritten.
+   * If the flag FILE_COPY_OVERWRITE is specified an already existing destination file is overwritten.
    *
-   * If the flag CopyFlags::NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
+   * If the flag FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks will be copied as symlinks, otherwise the target of the source symlink will be copied.
    *
    * The operation can be cancelled by triggering the cancellable object from another thread. If the operation was cancelled, a Gio::Error with CANCELLED will be thrown.
    *
    * The operation can be monitored via the @a slot callback.
    * If the source file does not exist then a Gio::Error with NOT_FOUND will be thrown, independent on the status of the destination.
    *
-   * If G_CopyFlags::OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
+   * If G_FILE_COPY_OVERWRITE is not specified and the target exists, then a Gio::Error with EXISTS will be thrown.
    *
    * If trying to overwrite a file over a directory a Gio::Error with IS_DIRECTORY will be thrown.
    * If trying to overwrite a directory with a directory a Gio::Error with WOULD_MERGE will be thrown.
    *
-   * If the source is a directory and the target does not exist, or CopyFlags::OVERWRITE is specified and the target is a file, then a Gio::Error with WOULD_RECURSE may be thrown (if the native move operation isn't available).
+   * If the source is a directory and the target does not exist, or FILE_COPY_OVERWRITE is specified and the target is a file, then a Gio::Error with WOULD_RECURSE may be thrown (if the native move operation isn't available).
    */
-  bool move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags = CopyFlags::NONE);
+  bool move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags = FILE_COPY_NONE);
 
-  bool move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, CopyFlags flags = CopyFlags::NONE);
+  bool move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot, FileCopyFlags flags = FILE_COPY_NONE);
 
-  bool move(const Glib::RefPtr<File>& destination, CopyFlags flags = CopyFlags::NONE);
+  bool move(const Glib::RefPtr<File>& destination, FileCopyFlags flags = FILE_COPY_NONE);
   _IGNORE(g_file_move)
 
   _WRAP_METHOD(bool make_directory(const Glib::RefPtr<Cancellable>& cancellable{?}),
@@ -1347,7 +1347,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @return <tt>true</tt> if there was any error, <tt>false</tt> otherwise.
    */
-  bool set_attributes_from_info(const Glib::RefPtr<FileInfo>& info, const Glib::RefPtr<Cancellable>& cancellable, FileQueryInfoFlags flags = FileQueryInfoFlags::NONE);
+  bool set_attributes_from_info(const Glib::RefPtr<FileInfo>& info, const Glib::RefPtr<Cancellable>& cancellable, FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE);
 
   /** Tries to set all attributes in the FileInfo on the target values,
    * not stopping on the first error.
@@ -1365,7 +1365,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @return <tt>true</tt> if there was any error, <tt>false</tt> otherwise.
    */
-  bool set_attributes_from_info(const Glib::RefPtr<FileInfo>& info, FileQueryInfoFlags flags = FileQueryInfoFlags::NONE);
+  bool set_attributes_from_info(const Glib::RefPtr<FileInfo>& info, FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE);
   _IGNORE(g_file_set_attributes_from_info)
 
 
@@ -1380,7 +1380,7 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void set_attributes_async(const Glib::RefPtr<FileInfo>& info, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void set_attributes_async(const Glib::RefPtr<FileInfo>& info, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Asynchronously sets the attributes of file with info.
    *
@@ -1392,13 +1392,13 @@ public:
    * @param flags A set of FileQueryInfoFlags.
    * @param io_priority The I/O priority of the request.
    */
-  void set_attributes_async(const Glib::RefPtr<FileInfo>& info, const SlotAsyncReady& slot, FileQueryInfoFlags flags = FileQueryInfoFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void set_attributes_async(const Glib::RefPtr<FileInfo>& info, const SlotAsyncReady& slot, FileQueryInfoFlags flags = FILE_QUERY_INFO_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_set_attributes_async)
   _IGNORE(g_file_set_attributes_finish) // takes GFileInfo**
 
   bool set_attributes_finish(const Glib::RefPtr<AsyncResult>& result, const Glib::RefPtr<FileInfo>& info);
 
-  _WRAP_METHOD(bool set_attribute_string(const std::string& attribute, const Glib::ustring& value, FileQueryInfoFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}),
+  _WRAP_METHOD(bool set_attribute_string(const std::string& attribute, const std::string& value, FileQueryInfoFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}),
                g_file_set_attribute_string,
                errthrow)
 
@@ -1435,7 +1435,7 @@ public:
    * @param cancellable A Cancellable object.
    * @param flags Flags affecting the operation.
    */
-  void mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Starts a @a mount_operation, mounting the volume that contains the file.
    *
@@ -1446,7 +1446,7 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_enclosing_volume(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Starts a @a mount_operation, mounting the volume that contains the file.
    *
@@ -1456,14 +1456,14 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void mount_enclosing_volume(const SlotAsyncReady& slot, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_enclosing_volume(const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
   _IGNORE(g_file_mount_enclosing_volume)
 
   /** Starts a @a mount_operation, mounting the volume that contains the file.
    *
    * @param flags Flags affecting the operation.
    */
-  void mount_enclosing_volume(Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_enclosing_volume(MountMountFlags flags = MOUNT_MOUNT_NONE);
   _IGNORE(g_file_mount_enclosing_volume)
 
   _WRAP_METHOD(bool mount_enclosing_volume_finish(const Glib::RefPtr<AsyncResult>& result),
@@ -1483,7 +1483,7 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a file of type FILE_TYPE_MOUNTABLE. Using @a mount_operation, you can request callbacks when, for instance,
    * passwords are needed during authentication.
@@ -1494,7 +1494,7 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a file of type FILE_TYPE_MOUNTABLE without user interaction.
    *
@@ -1503,13 +1503,13 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void mount_mountable(const SlotAsyncReady& slot, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_mountable(const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a file of type FILE_TYPE_MOUNTABLE without user interaction.
    *
    * @param flags Flags affecting the operation.
    */
-  void mount_mountable(Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount_mountable(MountMountFlags flags = MOUNT_MOUNT_NONE);
   _IGNORE(g_file_mount_mountable)
 
   _WRAP_METHOD(Glib::RefPtr<File> mount_mountable_finish(const Glib::RefPtr<AsyncResult>& result),
@@ -1527,7 +1527,7 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param flags Flags affecting the operation.
    */
-  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Unmounts a file of type FILE_TYPE_MOUNTABLE.
    *
@@ -1536,13 +1536,13 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void unmount_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Unmounts a file of type FILE_TYPE_MOUNTABLE.
    *
    * @param flags Flags affecting the operation.
    */
-  void unmount_mountable(Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Unmounts a file of type FILE_TYPE_MOUNTABLE.
    *
@@ -1558,7 +1558,7 @@ public:
    *
    * @newin{2,24}
    */
-  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Unmounts a file of type FILE_TYPE_MOUNTABLE.
    *
@@ -1570,7 +1570,7 @@ public:
    *
    * @newin{2,24}
    */
-  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Unmounts a file of type FILE_TYPE_MOUNTABLE.
    *
@@ -1579,7 +1579,7 @@ public:
    *
    * @newin{2,24}
    */
-  void unmount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void unmount_mountable(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   _IGNORE(g_file_unmount_mountable, g_file_unmount_mountable_finish, g_file_unmount_mountable_with_operation)
 
@@ -1598,7 +1598,7 @@ public:
    * @param cancellable A Cancellable object which can be used to cancel the operation.
    * @param flags Flags affecting the operation.
    */
-  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Starts an asynchronous eject on a mountable.
    *
@@ -1607,13 +1607,13 @@ public:
    * @param slot A callback slot which will be called when the request is satisfied.
    * @param flags Flags affecting the operation.
    */
-  void eject_mountable(const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Starts an asynchronous eject on a mountable.
    *
    * @param flags Flags affecting the operation.
    */
-  void eject_mountable(Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Starts an asynchronous eject on a mountable.
    *
@@ -1629,7 +1629,7 @@ public:
    *
    * @newin{2,24}
    */
-  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Starts an asynchronous eject on a mountable.
    *
@@ -1641,7 +1641,7 @@ public:
    *
    * @newin{2,24}
    */
-  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   /** Starts an asynchronous eject on a mountable.
    *
@@ -1650,7 +1650,7 @@ public:
    *
    * @newin{2,24}
    */
-  void eject_mountable(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject_mountable(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
   _IGNORE(g_file_eject_mountable, g_file_eject_mountable_finish, g_file_eject_mountable_with_operation)
 
@@ -1664,7 +1664,7 @@ public:
    * Normally only a subset of the file attributes are copied,
    * those that are copies in a normal file copy operation
    * (which for instance does not include e.g. mtime). However
-   * if CopyFlags::ALL_METADATA is specified in @a flags, then
+   * if FILE_COPY_ALL_METADATA is specified in @a flags, then
    * all the metadata that is possible to copy is copied.
    *
    * @param destination A File to copy attributes to.
@@ -1672,21 +1672,21 @@ public:
    * @param flags A set of FileMonitorFlags.
    * @result true if the attributes were copied successfully, false otherwise.
    */
-  bool copy_attributes(const Glib::RefPtr<File>& destination, const Glib::RefPtr<Cancellable>& cancellable, CopyFlags flags = CopyFlags::NONE);
+  bool copy_attributes(const Glib::RefPtr<File>& destination, const Glib::RefPtr<Cancellable>& cancellable, FileCopyFlags flags = FILE_COPY_NONE);
 
   /** Copies the file attributes from @a source to @a destination.
    *
    * Normally only a subset of the file attributes are copied,
    * those that are copies in a normal file copy operation
    * (which for instance does not include e.g. mtime). However
-   * if CopyFlags::ALL_METADATA is specified in @a flags, then
+   * if FILE_COPY_ALL_METADATA is specified in @a flags, then
    * all the metadata that is possible to copy is copied.
    *
    * @param destination A File to copy attributes to.
    * @param flags A set of FileMonitorFlags.
    * @result true if the attributes were copied successfully, false otherwise.
    */
-  bool copy_attributes(const Glib::RefPtr<File>& destination, CopyFlags flags = CopyFlags::NONE);
+  bool copy_attributes(const Glib::RefPtr<File>& destination, FileCopyFlags flags = FILE_COPY_NONE);
   _IGNORE(g_file_copy_attributes)
 
   /** Obtains a directory monitor for the given file.
@@ -1699,7 +1699,7 @@ public:
    * @param flags A set of FileMonitorFlags.
    * @return A FileMonitor for the file.
    */
-  Glib::RefPtr<FileMonitor> monitor_directory(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor_directory(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FILE_MONITOR_NONE);
 
   /** Obtains a directory monitor for the given file.
    * This may fail if directory monitoring is not supported.
@@ -1707,7 +1707,7 @@ public:
    * @param flags A set of FileMonitorFlags.
    * @return A FileMonitor for the file.
    */
-  Glib::RefPtr<FileMonitor> monitor_directory(FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor_directory(FileMonitorFlags flags = FILE_MONITOR_NONE);
   _IGNORE(g_file_monitor_directory)
 
   /** Obtains a file monitor for the given file. If no file notification
@@ -1720,7 +1720,7 @@ public:
    * @param flags A set of FileMonitorFlags.
    * @return A FileMonitor for the file.
    */
-  Glib::RefPtr<FileMonitor> monitor_file(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor_file(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FILE_MONITOR_NONE);
 
   /** Obtains a file monitor for the given file. If no file notification
    * mechanism exists, then regular polling of the file is used.
@@ -1731,7 +1731,7 @@ public:
    * @param flags A set of FileMonitorFlags.
    * @return A FileMonitor for the file.
    */
-  Glib::RefPtr<FileMonitor> monitor_file(FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor_file(FileMonitorFlags flags = FILE_MONITOR_NONE);
   _IGNORE(g_file_monitor_file)
 
 
@@ -1747,7 +1747,7 @@ public:
    *
    * @newin{2,18}
    */
-  Glib::RefPtr<FileMonitor> monitor(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor(const Glib::RefPtr<Cancellable>& cancellable, FileMonitorFlags flags = FILE_MONITOR_NONE);
 
   /** Obtains a file monitor for the given file. If no file notification
    * mechanism exists, then regular polling of the file is used.
@@ -1760,7 +1760,7 @@ public:
    *
    * @newin{2,18}
    */
-  Glib::RefPtr<FileMonitor> monitor(FileMonitorFlags flags = FileMonitorFlags::NONE);
+  Glib::RefPtr<FileMonitor> monitor(FileMonitorFlags flags = FILE_MONITOR_NONE);
   _IGNORE(g_file_monitor)
 
 
@@ -1802,7 +1802,7 @@ public:
   *
   * @newin{2,38}
   */
- using SlotFileMeasureProgress = sigc::slot<void(bool, guint64, guint64, guint64)>;
+ using SlotFileMeasureProgress = sigc::slot<void, bool, guint64, guint64, guint64>;
 
   //We do not use the {callback} syntax with _WRAP_METHOD here, because it expects to use user_data rather than progress_data.
   //We ignore the gboolean result, because we throw an exception if it is false.
@@ -1832,9 +1832,9 @@ public:
    * @param disk_usage The number of bytes of disk space used.
    * @param num_dirs The number of directories encountered.
    * @param num_files The number of non-directories encountered.
-   * @param flags Set of MeasureFlags.
+   * @param flags Set of FileMeasureFlags.
    */
-  void measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& slot_progress, guint64& disk_usage, guint64& num_dirs, guint64& num_files, MeasureFlags flags = MeasureFlags::NONE);
+  void measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& slot_progress, guint64& disk_usage, guint64& num_dirs, guint64& num_files, FileMeasureFlags flags = FILE_MEASURE_NONE);
   _IGNORE(g_file_measure_disk_usage)
 
   /** Recursively measures the disk usage of the file.
@@ -1848,10 +1848,10 @@ public:
    * @param slot_ready A SlotAsyncReady to call when the request is satisfied
    * @param cancellable A Cancellable object which can be used to cancel the operation
    * @param slot_progress The callback slot to be called with progress information
-   * @param flags Set of MeasureFlags
+   * @param flags Set of FileMeasureFlags
    * @param io_priority The I/O priority of the request
    */
-  void measure_disk_usage_async(const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& slot_progress, MeasureFlags flags = MeasureFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void measure_disk_usage_async(const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& slot_progress, FileMeasureFlags flags = FILE_MEASURE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_measure_disk_usage_async)
 
   _WRAP_METHOD(bool measure_disk_usage_finish(const Glib::RefPtr<AsyncResult>& result, guint64& disk_usage, guint64& num_dirs, guint64& num_files), g_file_measure_disk_usage_finish, errthrow)
@@ -1878,7 +1878,7 @@ public:
   *
   * @newin{2,24}
   */
-  void start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& start_operation, Drive::StartFlags flags = Drive::StartFlags::NONE);
+  void start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& start_operation, DriveStartFlags flags = DRIVE_START_NONE);
 
  /** Starts a file of type Mountable.
   * Using @a start_operation, you can request callbacks when, for instance,
@@ -1897,7 +1897,7 @@ public:
   *
   * @newin{2,24}
   */
-  void start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& start_operation, Drive::StartFlags flags =  Drive::StartFlags::NONE);
+  void start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& start_operation, DriveStartFlags flags =  DRIVE_START_NONE);
   _IGNORE(g_file_start_mountable)
 
   _WRAP_METHOD(bool start_mountable_finish(const Glib::RefPtr<AsyncResult>& result),
@@ -1922,7 +1922,7 @@ public:
   *
   * @newin{2,24}
   */
-  void stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& start_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<MountOperation>& start_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
 
 
  /** Stops a file of type Mountable.
@@ -1942,7 +1942,7 @@ public:
   *
   * @newin{2,24}
   */
-  void stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& start_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void stop_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<MountOperation>& start_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_file_stop_mountable)
 
   _WRAP_METHOD(bool stop_mountable_finish(const Glib::RefPtr<AsyncResult>& result),
@@ -2096,7 +2096,7 @@ public:
   /** A signal handler would be, for instance:
    * bool on_read_more(const char* file_contents, goffset file_size);
    */
-  using SlotReadMore = sigc::slot<bool(const char*, goffset)>;
+  using SlotReadMore = sigc::slot<bool, const char*, goffset>;
 
   //Note that slot_read_more can be nullptr but that would not be a useful method overload, because the documentation says that it would
   //then be equivalent to load_contents_async.
@@ -2171,12 +2171,12 @@ public:
    * @param etag The old entity tag
    * for the document.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param new_etag A location to a new entity tag
    * for the document.
    * @param cancellable A Cancellable object.
    */
-  void replace_contents(const char* contents, gsize length, const std::string& etag, std::string& new_etag, const Glib::RefPtr<Cancellable>& cancellable, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents(const char* contents, gsize length, const std::string& etag, std::string& new_etag, const Glib::RefPtr<Cancellable>& cancellable, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Replaces the contents of the file with @a contents of @a length bytes.
    *
@@ -2192,11 +2192,11 @@ public:
    * @param etag The old entity tag
    * for the document.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param new_etag A location to a new entity tag
    * for the document.
    */
-  void replace_contents(const char* contents, gsize length, const std::string& etag, std::string& new_etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents(const char* contents, gsize length, const std::string& etag, std::string& new_etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Replaces the contents of the file with @a contents.
    *
@@ -2215,12 +2215,12 @@ public:
    * @param etag The old entity tag
    * for the document.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param new_etag A location to a new entity tag
    * for the document.
    * @param cancellable A Cancellable object.
    */
-  void replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag, const Glib::RefPtr<Cancellable>& cancellable, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag, const Glib::RefPtr<Cancellable>& cancellable, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   /** Replaces the contents of the file with @a contents.
    *
@@ -2235,11 +2235,11 @@ public:
    * @param etag The old entity tag
    * for the document.
    * @param make_backup <tt>true</tt> if a backup should be created.
-   * @param flags A set of CreateFlags.
+   * @param flags A set of FileCreateFlags.
    * @param new_etag A location to a new entity tag
    * for the document.
    */
-  void replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents(const std::string& contents, const std::string& etag, std::string& new_etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
   _IGNORE(g_file_replace_contents)
 
 
@@ -2266,9 +2266,9 @@ public:
   * @param length The length of @a contents in bytes.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const char* contents, gsize length, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const char* contents, gsize length, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
  /** Starts an asynchronous replacement of the file with the given
   * @a contents of @a length bytes. @a etag will replace the document's
@@ -2285,9 +2285,9 @@ public:
   * @param length The length of @a contents in bytes.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_async(const SlotAsyncReady& slot, const char* contents, gsize length, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_async(const SlotAsyncReady& slot, const char* contents, gsize length, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
  /** Starts an asynchronous replacement of the file with the given
   * @a contents of @a length bytes. @a etag will replace the document's
@@ -2308,9 +2308,9 @@ public:
   * @param contents String of contents to replace the file with.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& contents, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const std::string& contents, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
  /** Starts an asynchronous replacement of the file with the given
   * @a contents. @a etag will replace the document's
@@ -2330,9 +2330,9 @@ public:
   * @param contents String of contents to replace the file with.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_async(const SlotAsyncReady& slot, const std::string& contents, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_async(const SlotAsyncReady& slot, const std::string& contents, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   _IGNORE(g_file_replace_contents_async)
 
@@ -2372,9 +2372,9 @@ public:
   * @param contents Bytes of contents to replace the file with.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_bytes_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<const Glib::Bytes>& contents, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_bytes_async(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const Glib::RefPtr<const Glib::Bytes>& contents, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
  /** Same as replace_contents_async() but takes a Gio::Bytes input instead.
   *
@@ -2392,15 +2392,15 @@ public:
   * @param contents Bytes of contents to replace the file with.
   * @param etag a new entity tag for the file.
   * @param make_backup true if a backup should be created.
-  * @param flags A set of CreateFlags.
+  * @param flags A set of FileCreateFlags.
   */
-  void replace_contents_bytes_async(const SlotAsyncReady& slot, const Glib::RefPtr<const Glib::Bytes>& contents, const std::string& etag, bool make_backup = false, CreateFlags flags = CreateFlags::NONE);
+  void replace_contents_bytes_async(const SlotAsyncReady& slot, const Glib::RefPtr<const Glib::Bytes>& contents, const std::string& etag, bool make_backup = false, FileCreateFlags flags = FILE_CREATE_NONE);
 
   _IGNORE(g_file_replace_contents_async)
 
+
   _WRAP_METHOD(bool supports_thread_contexts() const, g_file_supports_thread_contexts)
 
-protected:
   // *** vfuncs ***
 
   //_WRAP_VFUNC(Glib::RefPtr<File> dup() const, "dup")
@@ -2441,6 +2441,7 @@ namespace Glib
 {
 
 //Pre-declare this so we can use it in TypeTrait:
+GIOMM_API
 Glib::RefPtr<Gio::File> wrap(GFile* object, bool take_copy);
 
 namespace Container_Helpers
@@ -2452,7 +2453,7 @@ namespace Container_Helpers
  * would not return a wrapper for an interface.
  */
 template <>
-struct TypeTraits< Glib::RefPtr<Gio::File> >
+struct GIOMM_API TypeTraits< Glib::RefPtr<Gio::File> >
 {
   using CppType = Glib::RefPtr<Gio::File>;
   using CType = GFile*;
index 63ed535..a3884e6 100644 (file)
@@ -22,7 +22,7 @@ namespace Gio
 FileAttributeInfo::FileAttributeInfo(const GFileAttributeInfo* ginfo)
 : m_name(ginfo->name ? ginfo->name : ""),
   m_type(static_cast<FileAttributeType>(ginfo->type)),
-  m_flags(static_cast<Flags>(ginfo->flags))
+  m_flags(static_cast<FileAttributeInfoFlags>(ginfo->flags))
 {
 }
 
@@ -73,7 +73,7 @@ FileAttributeInfo::get_type() const
   return m_type;
 }
 
-FileAttributeInfo::Flags
+FileAttributeInfoFlags
 FileAttributeInfo::get_flags() const
 {
   return m_flags;
index 0c9c9a5..4fd21f8 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <string>
 #include <gio/gio.h> //TODO: avoid this include
 #include <glibmm/object.h>
@@ -24,6 +26,7 @@ namespace Gio
 {
 
 _WRAP_ENUM(FileAttributeType, GFileAttributeType)
+_WRAP_ENUM(FileAttributeInfoFlags, GFileAttributeInfoFlags)
 _WRAP_ENUM(FileAttributeStatus, GFileAttributeStatus)
 
 
@@ -31,12 +34,10 @@ _WRAP_ENUM(FileAttributeStatus, GFileAttributeStatus)
  *
  * @newin{2,16}
  */
-class FileAttributeInfo
+class GIOMM_API FileAttributeInfo
 {
   _CLASS_GENERIC(FileAttributeInfo, GFileAttributeInfo)
 public:
-  _WRAP_ENUM(Flags, GFileAttributeInfoFlags)
-
   explicit FileAttributeInfo(const GFileAttributeInfo* ginfo);
 
   FileAttributeInfo(const FileAttributeInfo& other);
@@ -49,12 +50,12 @@ public:
 
   std::string get_name() const;
   FileAttributeType get_type() const;
-  Flags get_flags() const;
+  FileAttributeInfoFlags get_flags() const;
 
 protected:
   std::string m_name;
   FileAttributeType m_type;
-  Flags m_flags;
+  FileAttributeInfoFlags m_flags;
 };
 
 } // namespace Gio
index 2ea1dc7..32a9149 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -29,7 +31,7 @@ namespace Gio
  * e.g. "standard::*" will return all of the keys in the "standard" namespace.
  *
  * Values are stored within the list in Gio::FileAttributeValue structures. Values can store different types, listed in the enum
- * Gio::FileAttributeType. Upon creation of a Gio::FileAttributeValue, the type will be set to Gio::FileAttributeType::INVALID.
+ * Gio::FileAttributeType. Upon creation of a Gio::FileAttributeValue, the type will be set to Gio::FILE_ATTRIBUTE_TYPE_INVALID.
  *
  * The list of possible attributes for a filesystem (pointed to by a Gio::File) is availible as a Gio::FileAttributeInfoList.
  * This list is queryable by key names as indicated earlier.
@@ -42,12 +44,13 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FileAttributeInfoList final
+class GIOMM_API FileAttributeInfoList final
 {
   _CLASS_OPAQUE_REFCOUNTED(FileAttributeInfoList, GFileAttributeInfoList,
                            g_file_attribute_info_list_new,
                            g_file_attribute_info_list_ref,
-                           g_file_attribute_info_list_unref)
+                           g_file_attribute_info_list_unref,
+                           GIOMM_API)
   _IGNORE(g_file_attribute_info_list_new, g_file_attribute_info_list_ref, g_file_attribute_info_list_unref)
 public:
 
@@ -70,7 +73,7 @@ public:
 
   _WRAP_METHOD(Glib::RefPtr<FileAttributeInfoList> dup() const, g_file_attribute_info_list_dup)
 
-  _WRAP_METHOD(void add(const std::string& name, FileAttributeType type, FileAttributeInfo::Flags flags = FileAttributeInfo::Flags::NONE), g_file_attribute_info_list_add)
+  _WRAP_METHOD(void add(const std::string& name, FileAttributeType type, FileAttributeInfoFlags flags = FILE_ATTRIBUTE_INFO_NONE), g_file_attribute_info_list_add)
 };
 
 } // namespace Gio
diff --git a/gio/src/filedescriptorbased.hg b/gio/src/filedescriptorbased.hg
deleted file mode 100644 (file)
index 57f27dc..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2017 The giomm 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <glibmm/interface.h>
-
-_DEFS(giomm,gio)
-_PINCLUDE(glibmm/private/interface_p.h)
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-typedef struct _GFileDescriptorBasedIface GFileDescriptorBasedIface;
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-namespace Gio
-{
-
-/** Interface for file descriptor based IO.
- *
- * %FileDescriptorBased is implemented by streams (implementations of
- * Gio::InputStream or Gio::OutputStream) that are based on file descriptors.
- *
- * @ingroup Streams
- *
- * @newin{2,58}
- */
-class FileDescriptorBased : public Glib::Interface
-{
-  _CLASS_INTERFACE(FileDescriptorBased, GFileDescriptorBased, G_FILE_DESCRIPTOR_BASED, GFileDescriptorBasedIface)
-  _GTKMMPROC_WIN32_NO_WRAP
-
-public:
-  _WRAP_METHOD(int get_fd() const, g_file_descriptor_based_get_fd, newin "2,58")
-
-protected:
-  _WRAP_VFUNC(int get_fd() const, "get_fd")
-};
-
-} // namespace Gio
index 6e59340..e432d0d 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 #include <glibmm/object.h>
+#include <glibmm/arrayhandle.h>
+#include <glibmm/listhandle.h>
 #include <glibmm/priorities.h>
 #include <giomm/asyncresult.h>
 #include <giomm/cancellable.h>
@@ -27,7 +29,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class File;
+class GIOMM_API File;
 
 //TODO: Consider wrapping this like a std::iterator (or at least renaming it), though the asyncness probably makes that unsuitable.
 
@@ -44,9 +46,9 @@ class File;
  *
  * @newin{2,16}
  */
-class FileEnumerator : public Glib::Object
+class GIOMM_API FileEnumerator : public Glib::Object
 {
-  _CLASS_GOBJECT(FileEnumerator, GFileEnumerator, G_FILE_ENUMERATOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(FileEnumerator, GFileEnumerator, G_FILE_ENUMERATOR, Glib::Object, GObject, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::RefPtr<FileInfo> next_file(const Glib::RefPtr<Cancellable>& cancellable{?}),
@@ -94,8 +96,8 @@ public:
   void next_files_async(const SlotAsyncReady& slot, int num_files = 1, int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_file_enumerator_next_files_async)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<FileInfo>>', `Glib::ListHandler<Glib::RefPtr<FileInfo>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<FileInfo>> next_files_finish(const Glib::RefPtr<AsyncResult>& result),
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<FileInfo> >', `$2(($3), Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<FileInfo> > next_files_finish(const Glib::RefPtr<AsyncResult>& result),
                g_file_enumerator_next_files_finish,
                errthrow)
 
index dd4d3d6..7406876 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -29,13 +31,12 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FileIcon
+class GIOMM_API FileIcon
 : public Glib::Object,
-  public Icon,
+  //Already derived by LoadableIcon: public Icon,
   public LoadableIcon
 {
-  _CLASS_GOBJECT(FileIcon, GFileIcon, G_FILE_ICON, Glib::Object, GObject)
-  _IMPLEMENTS_INTERFACE(Icon)
+  _CLASS_GOBJECT(FileIcon, GFileIcon, G_FILE_ICON, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(LoadableIcon)
 
 protected:
index 457aac8..086cee1 100644 (file)
@@ -27,4 +27,16 @@ FileAttributeMatcher::create(const std::string& attributes)
   return Glib::wrap(g_file_attribute_matcher_new(attributes.c_str()));
 }
 
+_DEPRECATE_IFDEF_START
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+Glib::TimeVal
+FileInfo::modification_time() const
+{
+  Glib::TimeVal result;
+  g_file_info_get_modification_time(const_cast<GFileInfo*>(gobj()), (GTimeVal*)(&result));
+  return result;
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+_DEPRECATE_IFDEF_END
+
 } // namespace Gio
index d547cea..ae5be38 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmm/arrayhandle.h>
 #include <glibmm/datetime.h>
 #include <glibmm/object.h>
+#include <glibmm/timeval.h>
 #include <giomm/fileattributeinfolist.h>
 #include <giomm/icon.h>
 
@@ -24,7 +26,17 @@ _PINCLUDE(glibmm/private/object_p.h)
 
 namespace Gio
 {
-_WRAP_ENUM(FileType, GFileType, NO_GTYPE)
+
+// Rename FILE_TYPE_UNKNOWN to FILE_TYPE_NOT_KNOWN because the former is a
+// define in a Windows header (winbase.h, included from windows.h).
+_WRAP_ENUM(FileType, GFileType, NO_GTYPE, s#FILE_TYPE_UNKNOWN#FILE_TYPE_NOT_KNOWN#)
+
+// Provide FILE_TYPE_UNKNOWN for backwards compatibility.
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#ifndef FILE_TYPE_UNKNOWN
+const FileType FILE_TYPE_UNKNOWN = FILE_TYPE_NOT_KNOWN;
+#endif
+#endif
 
 //TODO: attribute strings
 
@@ -32,10 +44,11 @@ _WRAP_ENUM(FileType, GFileType, NO_GTYPE)
  *
  * @newin{2,16}
  */
-class FileAttributeMatcher final
+class GIOMM_API FileAttributeMatcher final
 {
   _CLASS_OPAQUE_REFCOUNTED(FileAttributeMatcher, GFileAttributeMatcher,
-                           NONE, g_file_attribute_matcher_ref, g_file_attribute_matcher_unref)
+                           NONE, g_file_attribute_matcher_ref, g_file_attribute_matcher_unref,
+                           GIOMM_API)
   _IGNORE(g_file_attribute_matcher_ref, g_file_attribute_matcher_unref)
 
 public:
@@ -67,10 +80,9 @@ public:
  *
  * FileAttributeMatcher allows for searching through a FileInfo for attributes.
  */
-class FileInfo : public Glib::Object
+class GIOMM_API FileInfo : public Glib::Object
 {
-  _CLASS_GOBJECT(FileInfo, GFileInfo, G_FILE_INFO, Glib::Object, GObject)
-  _IGNORE(g_file_info_get_modification_time, g_file_info_set_modification_time)dnl // deprecated
+  _CLASS_GOBJECT(FileInfo, GFileInfo, G_FILE_INFO, Glib::Object, GObject, , , GIOMM_API)
 
 public:
   _CTOR_DEFAULT()
@@ -84,8 +96,8 @@ public:
 
   _WRAP_METHOD(bool has_namespace(const std::string& name_space) const, g_file_info_has_namespace)
 
-  #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> list_attributes(const std::string& name_space{?}) const,
+  #m4 _CONVERSION(`char**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle list_attributes(const std::string& name_space{?}) const,
                g_file_info_list_attributes)
 
   _WRAP_METHOD(FileAttributeType get_attribute_type(const std::string& attribute) const,
@@ -95,7 +107,8 @@ public:
 
   _WRAP_METHOD(FileAttributeStatus get_attribute_status(const std::string& attribute) const, g_file_info_get_attribute_status)
 
-  _WRAP_METHOD(Glib::ustring get_attribute_string(const std::string& attribute) const,
+  //TODO: This should return a ustring instead: https://bugzilla.gnome.org/show_bug.cgi?id=615950#c7
+  _WRAP_METHOD(std::string get_attribute_string(const std::string& attribute) const,
                g_file_info_get_attribute_string)
 
 #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
@@ -120,7 +133,8 @@ public:
 
   _WRAP_METHOD(bool set_attribute_status(const std::string& attribute, FileAttributeStatus status), g_file_info_set_attribute_status)
 
-  _WRAP_METHOD(void set_attribute_string(const std::string& attribute, const Glib::ustring& attr_value),
+  //TODO: This should take a ustring value instead: https://bugzilla.gnome.org/show_bug.cgi?id=615950#c7
+  _WRAP_METHOD(void set_attribute_string(const std::string& attribute, const std::string& attr_value),
                g_file_info_set_attribute_string)
 
 #m4 _CONVERSION(`const std::vector<Glib::ustring>&',`char**',`const_cast<char**>(Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data())')
@@ -151,9 +165,11 @@ public:
   _WRAP_METHOD(bool is_symlink() const, g_file_info_get_is_symlink)
   _WRAP_METHOD(std::string get_name() const, g_file_info_get_name)
 
-  _WRAP_METHOD(Glib::ustring get_display_name() const, g_file_info_get_display_name)
+  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(std::string get_display_name() const, g_file_info_get_display_name)
 
-  _WRAP_METHOD(Glib::ustring get_edit_name() const, g_file_info_get_edit_name)
+  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(std::string get_edit_name() const, g_file_info_get_edit_name)
 
   _WRAP_METHOD(Glib::RefPtr<Icon> get_icon(), g_file_info_get_icon, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_icon() const, g_file_info_get_icon, refreturn, constversion)
@@ -161,15 +177,22 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Icon> get_symbolic_icon(), g_file_info_get_symbolic_icon, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_symbolic_icon() const, g_file_info_get_symbolic_icon, refreturn, constversion)
 
-  _WRAP_METHOD(Glib::ustring get_content_type() const, g_file_info_get_content_type)
+  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(std::string get_content_type() const, g_file_info_get_content_type)
 
   _WRAP_METHOD(goffset get_size() const, g_file_info_get_size)
 
+_DEPRECATE_IFDEF_START
+  /// @deprecated Use get_modification_date_time() instead.
+  Glib::TimeVal modification_time() const;
+_DEPRECATE_IFDEF_END
+  _IGNORE(g_file_info_get_modification_time)
   _WRAP_METHOD(Glib::DateTime get_modification_date_time() const, g_file_info_get_modification_date_time)
 
   _WRAP_METHOD(std::string get_symlink_target() const, g_file_info_get_symlink_target)
 
-  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_info_get_etag)
+  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(std::string get_etag() const, g_file_info_get_etag)
 
   _WRAP_METHOD(gint32 get_sort_order() const, g_file_info_get_sort_order)
   _WRAP_METHOD(void set_attribute_mask(const Glib::RefPtr<FileAttributeMatcher>& mask),
@@ -183,18 +206,24 @@ public:
   _WRAP_METHOD(void set_is_symlink(bool symlink = true), g_file_info_set_is_symlink)
   _WRAP_METHOD(void set_name(const std::string& name), g_file_info_set_name)
 
-  _WRAP_METHOD(void set_display_name(const Glib::ustring& display_name), g_file_info_set_display_name)
+  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(void set_display_name(const std::string& display_name), g_file_info_set_display_name)
 
-  _WRAP_METHOD(void set_edit_name(const Glib::ustring& edit_name), g_file_info_set_edit_name)
+  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(void set_edit_name(const std::string& edit_name), g_file_info_set_edit_name)
 
   _WRAP_METHOD(void set_icon(const Glib::RefPtr<Icon>& icon), g_file_info_set_icon)
   _WRAP_METHOD(void set_symbolic_icon(const Glib::RefPtr<Icon>& icon), g_file_info_set_symbolic_icon)
 
-  _WRAP_METHOD(void set_content_type(const Glib::ustring& content_type), g_file_info_set_content_type)
+  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
+  _WRAP_METHOD(void set_content_type(const std::string& content_type), g_file_info_set_content_type)
 
   _WRAP_METHOD(void set_size(goffset size), g_file_info_set_size)
 
+  _WRAP_METHOD(void set_modification_time(const Glib::TimeVal& mtime), g_file_info_set_modification_time,
+    deprecated "Use set_modification_date_time() instead.")
   _WRAP_METHOD(void set_modification_date_time(const Glib::DateTime& mtime), g_file_info_set_modification_date_time)
+
   _WRAP_METHOD(void set_symlink_target(const std::string& symlink_target), g_file_info_set_symlink_target)
   _WRAP_METHOD(void set_sort_order(gint32 sort_order), g_file_info_set_sort_order)
 };
index 0159d8c..23d9a70 100644 (file)
@@ -36,11 +36,11 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FileInputStream
+class GIOMM_API FileInputStream
 : public Gio::InputStream,
   public Seekable
 {
-  _CLASS_GOBJECT(FileInputStream, GFileInputStream, G_FILE_INPUT_STREAM, Gio::InputStream, GInputStream)
+  _CLASS_GOBJECT(FileInputStream, GFileInputStream, G_FILE_INPUT_STREAM, Gio::InputStream, GInputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Seekable)
 
 public:
index e6f66ce..518e4b6 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -34,11 +36,11 @@ namespace Gio
  *
  * @newin{2,22}
  */
-class FileIOStream
+class GIOMM_API FileIOStream
 : public Gio::IOStream,
     public Gio::Seekable
 {
-  _CLASS_GOBJECT(FileIOStream, GFileIOStream, G_FILE_IO_STREAM, Gio::IOStream, GIOStream)
+  _CLASS_GOBJECT(FileIOStream, GFileIOStream, G_FILE_IO_STREAM, Gio::IOStream, GIOStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Seekable)
 
 public:
@@ -97,7 +99,7 @@ public:
   _WRAP_METHOD(Glib::RefPtr<FileInfo> query_info_finish(const Glib::RefPtr<AsyncResult>& result),
                g_file_io_stream_query_info_finish,
                errthrow)
-  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_io_stream_get_etag)
+  _WRAP_METHOD(std::string get_etag() const, g_file_io_stream_get_etag)
 
 };
 
index 38f92d8..24fd67d 100644 (file)
@@ -99,7 +99,6 @@ giomm_files_any_hg =                  \
        permission.hg           \
        pollableinputstream.hg          \
        pollableoutputstream.hg         \
-       propertyaction.hg \
        proxy.hg                        \
        proxyaddress.hg                 \
        proxyresolver.hg                \
@@ -142,7 +141,6 @@ giomm_files_any_hg =                        \
        zlibcompressor.hg
 
 giomm_files_posix_hg =                 \
-       filedescriptorbased.hg \
        unixconnection.hg               \
        unixcredentialsmessage.hg       \
        unixfdlist.hg                   \
index 56fd605..c9660ca 100644 (file)
@@ -2,6 +2,7 @@
 
 include $(top_srcdir)/gio/src/filelist.am
 
+# Split out from $(top_srcdir)/gio/src/filelist.am
 if HOST_WINDOWS_NATIVE
 giomm_files_arch_hg =
 else
index 150291f..3901af9 100644 (file)
@@ -18,8 +18,6 @@
 #include <giomm/file.h>
 #include <gio/gio.h>
 
-using Event = Gio::FileMonitor::Event;
-
 namespace Gio
 {
 
index 32643ba..3bd46a3 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 //#include <giomm/file.h>
 #include <glibmm/object.h>
 
@@ -24,8 +26,9 @@ _PINCLUDE(gio/gio.h)
 namespace Gio
 {
 
+_WRAP_ENUM(FileMonitorEvent, GFileMonitorEvent, NO_GTYPE)
 
-class File;
+class GIOMM_API File;
 
 /** Monitors a file or directory for changes.
  * To obtain a FileMonitor for a file or directory, use File::monitor_file() or
@@ -36,15 +39,13 @@ class File;
  *
  * @newin{2,16}
  */
-class FileMonitor : public Glib::Object
+class GIOMM_API FileMonitor : public Glib::Object
 {
-  _CLASS_GOBJECT(FileMonitor, GFileMonitor, G_FILE_MONITOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(FileMonitor, GFileMonitor, G_FILE_MONITOR, Glib::Object, GObject, , , GIOMM_API)
 protected:
 
 public:
 
-  _WRAP_ENUM(Event, GFileMonitorEvent, NO_GTYPE)
-
   _WRAP_METHOD(bool cancel(), g_file_monitor_cancel)
   _WRAP_METHOD(bool is_cancelled() const, g_file_monitor_is_cancelled)
   _WRAP_METHOD(void set_rate_limit(int limit_msecs), g_file_monitor_set_rate_limit)
@@ -53,13 +54,12 @@ public:
   _IGNORE(g_file_monitor_emit_event)
 
 #m4 _CONVERSION(`GFile*',`const Glib::RefPtr<File>&',`Glib::wrap($3, true)')
-  _WRAP_SIGNAL(void changed(const Glib::RefPtr<File>& file, const Glib::RefPtr<File>& other_file, Event event_type), "changed")
+  _WRAP_SIGNAL(void changed(const Glib::RefPtr<File>& file, const Glib::RefPtr<File>& other_file, FileMonitorEvent event_type), "changed")
+
+  //_WRAP_VFUNC(bool cancel(), cancel);
 
   _WRAP_PROPERTY("rate-limit", int)
   _WRAP_PROPERTY("cancelled", bool)
-
-protected:
-  //_WRAP_VFUNC(bool cancel(), cancel);
 };
 
 } // namespace Gio
index 5115c4f..b998b64 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 //#include <giomm/file.h>
+#include <glibmm/arrayhandle.h>
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -24,16 +27,16 @@ _PINCLUDE(gio/gio.h)
 namespace Gio
 {
 
-class File;
+class GIOMM_API File;
 
 /** Completes partial file and directory names given a partial string by looking in the file system for clues.
  * Can return a list of possible completion strings for widget implementation.
  *
  * @newin{2,16}
  */
-class FilenameCompleter : public Glib::Object
+class GIOMM_API FilenameCompleter : public Glib::Object
 {
-  _CLASS_GOBJECT(FilenameCompleter, GFilenameCompleter, G_FILENAME_COMPLETER, Glib::Object, GObject)
+  _CLASS_GOBJECT(FilenameCompleter, GFilenameCompleter, G_FILENAME_COMPLETER, Glib::Object, GObject, , , GIOMM_API)
 protected:
   _CTOR_DEFAULT
   _IGNORE(g_filename_completer_new)
@@ -42,8 +45,8 @@ public:
 
   _WRAP_METHOD(std::string get_completion_suffix(const std::string& initial_text) const, g_filename_completer_get_completion_suffix)
 
-  #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> get_completions(const std::string& initial_text) const, g_filename_completer_get_completions)
+  #m4 _CONVERSION(`char**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle get_completions(const std::string& initial_text) const, g_filename_completer_get_completions)
   _WRAP_METHOD(void set_dirs_only(bool dirs_only = true), g_filename_completer_set_dirs_only)
 
   _WRAP_SIGNAL(void got_completion_data(), got_completion_data)
index f8682ab..248908d 100644 (file)
@@ -39,11 +39,11 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FileOutputStream
+class GIOMM_API FileOutputStream
 : public OutputStream,
   public Seekable
 {
-  _CLASS_GOBJECT(FileOutputStream, GFileOutputStream, G_FILE_OUTPUT_STREAM, Gio::OutputStream, GOutputStream)
+  _CLASS_GOBJECT(FileOutputStream, GFileOutputStream, G_FILE_OUTPUT_STREAM, Gio::OutputStream, GOutputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Seekable)
 
 public:
@@ -134,7 +134,7 @@ public:
                g_file_output_stream_query_info_finish,
                refreturn, errthrow)
 
-  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_output_stream_get_etag)
+  _WRAP_METHOD(std::string get_etag() const, g_file_output_stream_get_etag)
 };
 
 } // namespace Gio
index 1549bd4..92ad7f5 100644 (file)
@@ -31,9 +31,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FilterInputStream : public Gio::InputStream
+class GIOMM_API FilterInputStream : public Gio::InputStream
 {
-  _CLASS_GOBJECT(FilterInputStream, GFilterInputStream, G_FILTER_INPUT_STREAM, Gio::InputStream, GInputStream)
+  _CLASS_GOBJECT(FilterInputStream, GFilterInputStream, G_FILTER_INPUT_STREAM, Gio::InputStream, GInputStream, , , GIOMM_API)
 
 protected:
   // This needs to be hand-coded because there is no public GFilterInputStream constructor.
index 7a9f762..67d59f5 100644 (file)
@@ -32,9 +32,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class FilterOutputStream : public Gio::OutputStream
+class GIOMM_API FilterOutputStream : public Gio::OutputStream
 {
-  _CLASS_GOBJECT(FilterOutputStream, GFilterOutputStream, G_FILTER_OUTPUT_STREAM, Gio::OutputStream, GOutputStream)
+  _CLASS_GOBJECT(FilterOutputStream, GFilterOutputStream, G_FILTER_OUTPUT_STREAM, Gio::OutputStream, GOutputStream, , , GIOMM_API)
 
 protected:
   // This needs to be hand-coded because there is no public GFilterOutputStream constructor.
index 4ac0d5f..e71dda7 100644 (file)
@@ -2784,9 +2784,7 @@ g_dtls_connection_set_rehandshake_mode().
 
 Since: 2.48
 
-Deprecated: 2.60. Changing the rehandshake mode is no longer
-required for compatibility. Also, rehandshaking has been removed
-from the TLS protocol in TLS 1.3.
+Deprecated: 2.60: The rehandshake mode is ignored.
 
 </description>
 </property>
@@ -3759,6 +3757,65 @@ Since: 2.44
 </description>
 </property>
 
+<signal name="GMemoryMonitor::low-memory-warning">
+<description>
+Emitted when the system is running low on free memory. The signal
+handler should then take the appropriate action depending on the
+warning level. See the #GMemoryMonitorWarningLevel documentation for
+details.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="monitor">
+<parameter_description> a #GMemoryMonitor
+</parameter_description>
+</parameter>
+<parameter name="level">
+<parameter_description> the #GMemoryMonitorWarningLevel warning level
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</signal>
+
+<enum name="GMemoryMonitorWarningLevel">
+<description>
+Memory availability warning levels.
+
+Note that because new values might be added, it is recommended that applications check
+#GMemoryMonitorWarningLevel as ranges, for example:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+if (warning_level &gt; G_MEMORY_MONITOR_WARNING_LEVEL_LOW)
+drop_caches ();
+]|
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="G_MEMORY_MONITOR_WARNING_LEVEL_LOW">
+<parameter_description> Memory on the device is low, processes
+should free up unneeded resources (for example, in-memory caches) so they can
+be used elsewhere.
+</parameter_description>
+</parameter>
+<parameter name="G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM">
+<parameter_description> Same as @G_MEMORY_MONITOR_WARNING_LEVEL_LOW
+but the device has even less free memory, so processes should try harder to free
+up unneeded resources. If your process does not need to stay running, it is a
+good time for it to quit.
+</parameter_description>
+</parameter>
+<parameter name="G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL">
+<parameter_description> The system will soon start terminating
+processes to reclaim memory, including background processes.
+</parameter_description>
+</parameter>
+</parameters>
+</enum>
+
 <property name="GMemoryOutputStream:data">
 <description>
 Pointer to buffer where data will be written.
@@ -6002,14 +6059,12 @@ Since: 2.28
 
 <property name="GTlsClientConnection:use-ssl3">
 <description>
-If %TRUE, forces the connection to use a fallback version of TLS
-or SSL, rather than trying to negotiate the best version of TLS
-to use. See g_tls_client_connection_set_use_ssl3().
+SSL 3.0 is no longer supported. See
+g_tls_client_connection_set_use_ssl3() for details.
 
 Since: 2.28
 
-Deprecated: 2.56: SSL 3.0 is insecure, and this property does not
-generally enable or disable it, despite its name.
+Deprecated: 2.56: SSL 3.0 is insecure.
 
 </description>
 </property>
@@ -6189,6 +6244,8 @@ g_tls_connection_set_rehandshake_mode().
 
 Since: 2.28
 
+Deprecated: 2.60: The rehandshake mode is ignored.
+
 </description>
 </property>
 
@@ -7739,7 +7796,7 @@ Since: 2.38
 </description>
 <parameters>
 <parameter name="action_name">
-<parameter_description> an potential action name
+<parameter_description> a potential action name
 </parameter_description>
 </parameter>
 </parameters>
@@ -8765,7 +8822,7 @@ Initiates startup notification for the application and returns the
 `DESKTOP_STARTUP_ID` for the launched operation, if supported.
 
 Startup notification IDs are defined in the 
-[FreeDesktop.Org Startup Notifications standard](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt&quot;).
+[FreeDesktop.Org Startup Notifications standard](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt).
 
 
 </description>
@@ -8989,14 +9046,14 @@ consumed, they will no longer be visible to the default handling
 
 It is important to use the proper GVariant format when retrieving
 the options with g_variant_dict_lookup():
-- for %G_OPTION_ARG_NONE, use b
-- for %G_OPTION_ARG_STRING, use &amp;s
-- for %G_OPTION_ARG_INT, use i
-- for %G_OPTION_ARG_INT64, use x
-- for %G_OPTION_ARG_DOUBLE, use d
-- for %G_OPTION_ARG_FILENAME, use ^ay
-- for %G_OPTION_ARG_STRING_ARRAY, use &amp;as
-- for %G_OPTION_ARG_FILENAME_ARRAY, use ^aay
+- for %G_OPTION_ARG_NONE, use `b`
+- for %G_OPTION_ARG_STRING, use `&amp;s`
+- for %G_OPTION_ARG_INT, use `i`
+- for %G_OPTION_ARG_INT64, use `x`
+- for %G_OPTION_ARG_DOUBLE, use `d`
+- for %G_OPTION_ARG_FILENAME, use `^&amp;ay`
+- for %G_OPTION_ARG_STRING_ARRAY, use `^a&amp;s`
+- for %G_OPTION_ARG_FILENAME_ARRAY, use `^a&amp;ay`
 
 Since: 2.40
 
@@ -11389,7 +11446,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 </parameters>
-<return> an identifier (never 0) that an be used with
+<return> an identifier (never 0) that can be used with
 g_bus_unown_name() to stop owning the name.
 
 </return>
@@ -11433,7 +11490,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 </parameters>
-<return> an identifier (never 0) that an be used with
+<return> an identifier (never 0) that can be used with
 g_bus_unown_name() to stop owning the name
 
 </return>
@@ -11471,7 +11528,7 @@ or %NULL
 </parameter_description>
 </parameter>
 </parameters>
-<return> an identifier (never 0) that an be used with
+<return> an identifier (never 0) that can be used with
 g_bus_unown_name() to stop owning the name.
 
 </return>
@@ -11514,7 +11571,7 @@ acquired or %NULL
 </parameter_description>
 </parameter>
 </parameters>
-<return> an identifier (never 0) that an be used with
+<return> an identifier (never 0) that can be used with
 g_bus_unown_name() to stop owning the name.
 
 </return>
@@ -11524,6 +11581,13 @@ g_bus_unown_name() to stop owning the name.
 <description>
 Stops owning a name.
 
+Note that there may still be D-Bus traffic to process (relating to owning
+and unowning the name) in the current thread-default #GMainContext after
+this function has returned. You should continue to iterate the #GMainContext
+until the #GDestroyNotify function passed to g_bus_own_name() is called, in
+order to avoid memory leaks through callbacks queued on the #GMainContext
+after it’s stopped being iterated.
+
 Since: 2.26
 
 </description>
@@ -11540,6 +11604,13 @@ Since: 2.26
 <description>
 Stops watching a name.
 
+Note that there may still be D-Bus traffic to process (relating to watching
+and unwatching the name) in the current thread-default #GMainContext after
+this function has returned. You should continue to iterate the #GMainContext
+until the #GDestroyNotify function passed to g_bus_watch_name() is called, in
+order to avoid memory leaks through callbacks queued on the #GMainContext
+after it’s stopped being iterated.
+
 Since: 2.26
 
 </description>
@@ -11556,7 +11627,7 @@ Since: 2.26
 <description>
 Starts watching @name on the bus specified by @bus_type and calls
 @name_appeared_handler and @name_vanished_handler when the name is
-known to have a owner respectively known to lose its
+known to have an owner respectively known to lose its
 owner. Callbacks will be invoked in the
 [thread-default main context][g-main-context-push-thread-default]
 of the thread you are calling this function from.
@@ -11617,7 +11688,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 </parameters>
-<return> An identifier (never 0) that an be used with
+<return> An identifier (never 0) that can be used with
 g_bus_unwatch_name() to stop watching the name.
 
 </return>
@@ -11661,7 +11732,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 </parameters>
-<return> An identifier (never 0) that an be used with
+<return> An identifier (never 0) that can be used with
 g_bus_unwatch_name() to stop watching the name.
 
 </return>
@@ -11699,7 +11770,7 @@ to not exist or %NULL.
 </parameter_description>
 </parameter>
 </parameters>
-<return> An identifier (never 0) that an be used with
+<return> An identifier (never 0) that can be used with
 g_bus_unwatch_name() to stop watching the name.
 
 </return>
@@ -11737,7 +11808,7 @@ to not exist or %NULL.
 </parameter_description>
 </parameter>
 </parameters>
-<return> An identifier (never 0) that an be used with
+<return> An identifier (never 0) that can be used with
 g_bus_unwatch_name() to stop watching the name.
 
 </return>
@@ -12802,7 +12873,7 @@ Since: 2.24
 Gets a pointer to native credentials of type @native_type from
 @credentials.
 
-It is a programming error (which will cause an warning to be
+It is a programming error (which will cause a warning to be
 logged) to use this method if there is no #GCredentials support for
 the OS or if @native_type isn't supported by the OS.
 
@@ -12931,7 +13002,7 @@ Since: 2.26
 Copies the native credentials of type @native_type from @native
 into @credentials.
 
-It is a programming error (which will cause an warning to be
+It is a programming error (which will cause a warning to be
 logged) to use this method if there is no #GCredentials support for
 the OS or if @native_type isn't supported by the OS.
 
@@ -15763,7 +15834,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 <parameter name="guid">
-<parameter_description> the GUID to use if a authenticating as a server or %NULL
+<parameter_description> the GUID to use if authenticating as a server or %NULL
 </parameter_description>
 </parameter>
 <parameter name="flags">
@@ -15971,7 +16042,7 @@ Since: 2.26
 </parameter_description>
 </parameter>
 <parameter name="guid">
-<parameter_description> the GUID to use if a authenticating as a server or %NULL
+<parameter_description> the GUID to use if authenticating as a server or %NULL
 </parameter_description>
 </parameter>
 <parameter name="flags">
@@ -16518,6 +16589,24 @@ needed. (It is not guaranteed to be called synchronously when the
 signal is unsubscribed from, and may be called after @connection
 has been destroyed.)
 
+As @callback is potentially invoked in a different thread from where it’s
+emitted, it’s possible for this to happen after
+g_dbus_connection_signal_unsubscribe() has been called in another thread.
+Due to this, @user_data should have a strong reference which is freed with
+@user_data_free_func, rather than pointing to data whose lifecycle is tied
+to the signal subscription. For example, if a #GObject is used to store the
+subscription ID from g_dbus_connection_signal_subscribe(), a strong reference
+to that #GObject must be passed to @user_data, and g_object_unref() passed to
+@user_data_free_func. You are responsible for breaking the resulting
+reference count cycle by explicitly unsubscribing from the signal when
+dropping the last external reference to the #GObject. Alternatively, a weak
+reference may be used.
+
+It is guaranteed that if you unsubscribe from a signal using
+g_dbus_connection_signal_unsubscribe() from the same thread which made the
+corresponding g_dbus_connection_signal_subscribe() call, @callback will not
+be invoked after g_dbus_connection_signal_unsubscribe() returns.
+
 The returned subscription identifier is an opaque value which is guaranteed
 to never be zero.
 
@@ -16584,6 +16673,14 @@ subscription is removed or %NULL
 <description>
 Unsubscribes from signals.
 
+Note that there may still be D-Bus traffic to process (relating to this
+signal subscription) in the current thread-default #GMainContext after this
+function has returned. You should continue to iterate the #GMainContext
+until the #GDestroyNotify function passed to
+g_dbus_connection_signal_subscribe() is called, in order to avoid memory
+leaks through callbacks queued on the #GMainContext after it’s stopped being
+iterated.
+
 Since: 2.26
 
 </description>
@@ -16848,7 +16945,7 @@ Since: 2.26
 </description>
 <parameters>
 <parameter name="error_domain">
-<parameter_description> A #GQuark for a error domain.
+<parameter_description> A #GQuark for an error domain.
 </parameter_description>
 </parameter>
 <parameter name="error_code">
@@ -16992,7 +17089,7 @@ Since: 2.26
 </description>
 <parameters>
 <parameter name="error_domain">
-<parameter_description> A #GQuark for a error domain.
+<parameter_description> A #GQuark for an error domain.
 </parameter_description>
 </parameter>
 <parameter name="error_code">
@@ -23294,6 +23391,10 @@ g_dtls_connection_set_rehandshake_mode() for details.
 
 Since: 2.48
 
+Deprecated: 2.64. Changing the rehandshake mode is no longer
+required for compatibility. Also, rehandshaking has been removed
+from the TLS protocol in TLS 1.3.
+
 </description>
 <parameters>
 <parameter name="conn">
@@ -23301,7 +23402,7 @@ Since: 2.48
 </parameter_description>
 </parameter>
 </parameters>
-<return> @conn's rehandshaking mode
+<return> %G_TLS_REHANDSHAKE_SAFELY
 
 </return>
 </function>
@@ -23332,28 +23433,25 @@ Attempts a TLS handshake on @conn.
 
 On the client side, it is never necessary to call this method;
 although the connection needs to perform a handshake after
-connecting (or after sending a &quot;STARTTLS&quot;-type command) and may
-need to rehandshake later if the server requests it,
-#GDtlsConnection will handle this for you automatically when you try
-to send or receive data on the connection. However, you can call
-g_dtls_connection_handshake() manually if you want to know for sure
-whether the initial handshake succeeded or failed (as opposed to
-just immediately trying to write to @conn, in which
-case if it fails, it may not be possible to tell if it failed
-before or after completing the handshake).
+connecting, #GDtlsConnection will handle this for you automatically
+when you try to send or receive data on the connection. You can call
+g_dtls_connection_handshake() manually if you want to know whether
+the initial handshake succeeded or failed (as opposed to just
+immediately trying to use @conn to read or write, in which case,
+if it fails, it may not be possible to tell if it failed before
+or after completing the handshake), but beware that servers may reject
+client authentication after the handshake has completed, so a
+successful handshake does not indicate the connection will be usable.
 
 Likewise, on the server side, although a handshake is necessary at
 the beginning of the communication, you do not need to call this
 function explicitly unless you want clearer error reporting.
 
-If TLS 1.2 or older is in use, you may call
-g_dtls_connection_handshake() after the initial handshake to
-rehandshake; however, this usage is deprecated because rehandshaking
-is no longer part of the TLS protocol in TLS 1.3. Accordingly, the
-behavior of calling this function after the initial handshake is now
-undefined, except it is guaranteed to be reasonable and
-nondestructive so as to preserve compatibility with code written for
-older versions of GLib.
+Previously, calling g_dtls_connection_handshake() after the initial
+handshake would trigger a rehandshake; however, this usage was
+deprecated in GLib 2.60 because rehandshaking was removed from the
+TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after
+the initial handshake will no longer do anything.
 
 #GDtlsConnection::accept_certificate may be emitted during the
 handshake.
@@ -23562,26 +23660,10 @@ Since: 2.48
 
 <function name="g_dtls_connection_set_rehandshake_mode">
 <description>
-Sets how @conn behaves with respect to rehandshaking requests.
-
-%G_TLS_REHANDSHAKE_NEVER means that it will never agree to
-rehandshake after the initial handshake is complete. (For a client,
-this means it will refuse rehandshake requests from the server, and
-for a server, this means it will close the connection with an error
-if the client attempts to rehandshake.)
-
-%G_TLS_REHANDSHAKE_SAFELY means that the connection will allow a
-rehandshake only if the other end of the connection supports the
-TLS `renegotiation_info` extension. This is the default behavior,
-but means that rehandshaking will not work against older
-implementations that do not support that extension.
-
-%G_TLS_REHANDSHAKE_UNSAFELY means that the connection will allow
-rehandshaking even without the `renegotiation_info` extension. On
-the server side in particular, this is not recommended, since it
-leaves the server open to certain attacks. However, this mode is
-necessary if you need to allow renegotiation with older client
-software.
+Since GLib 2.64, changing the rehandshake mode is no longer supported
+and will have no effect. With TLS 1.3, rehandshaking has been removed from
+the TLS protocol, replaced by separate post-handshake authentication and
+rekey operations.
 
 Since: 2.48
 
@@ -24281,7 +24363,7 @@ counted structures, and are created with a reference count of 1. If
 the number of references falls to 0, the #GFileAttributeMatcher is
 automatically destroyed.
 
-The @attribute string should be formatted with specific keys separated
+The @attributes string should be formatted with specific keys separated
 from namespaces with a double colon. Several &quot;namespace::key&quot; strings may be
 concatenated with a single comma (e.g. &quot;standard::type,standard::is-hidden&quot;).
 The wildcard &quot;*&quot; may be used to match all keys and namespaces, or
@@ -26088,7 +26170,7 @@ Virtual: prefix_matches
 </parameter_description>
 </parameter>
 </parameters>
-<return>  %TRUE if the @files's parent, grandparent, etc is @prefix,
+<return>  %TRUE if the @file's parent, grandparent, etc is @prefix,
 %FALSE otherwise.
 </return>
 </function>
@@ -26347,7 +26429,7 @@ attribute does not contain a signed 32-bit integer, or is invalid,
 <function name="g_file_info_get_attribute_int64">
 <description>
 Gets a signed 64-bit integer contained within the attribute. If the
-attribute does not contain an signed 64-bit integer, or is invalid,
+attribute does not contain a signed 64-bit integer, or is invalid,
 0 will be returned.
 
 
@@ -26692,6 +26774,10 @@ Checks if a file is a symlink.
 Gets the modification time of the current @info and returns it as a
 #GDateTime.
 
+This requires the %G_FILE_ATTRIBUTE_TIME_MODIFIED attribute. If
+%G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is provided, the resulting #GDateTime
+will have microsecond precision.
+
 Since: 2.62
 
 </description>
@@ -26826,7 +26912,7 @@ Checks if a file info structure has an attribute named @attribute.
 </parameter_description>
 </parameter>
 </parameters>
-<return> %TRUE if @Ginfo has an attribute named @attribute,
+<return> %TRUE if @info has an attribute named @attribute,
 %FALSE otherwise.
 </return>
 </function>
@@ -26849,7 +26935,7 @@ Since: 2.22
 </parameter_description>
 </parameter>
 </parameters>
-<return> %TRUE if @Ginfo has an attribute in @name_space,
+<return> %TRUE if @info has an attribute in @name_space,
 %FALSE otherwise.
 
 </return>
@@ -27330,8 +27416,9 @@ See %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK.
 
 <function name="g_file_info_set_modification_date_time">
 <description>
-Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED attribute in the file
-info to the given date/time value.
+Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
+%G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
+given date/time value.
 
 Since: 2.62
 
@@ -27351,8 +27438,9 @@ Since: 2.62
 
 <function name="g_file_info_set_modification_time">
 <description>
-Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED attribute in the file
-info to the given time value.
+Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
+%G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
+given time value.
 
 Deprecated: 2.62: Use g_file_info_set_modification_date_time() instead, as
 #GTimeVal is deprecated due to the year 2038 problem.
@@ -27868,7 +27956,7 @@ entity tag for the file, or %NULL if the entity tag is not needed
 <description>
 Loads the content of the file into memory. The data is always
 zero-terminated, but this is not included in the resultant @length.
-The returned @content should be freed with g_free() when no longer
+The returned @contents should be freed with g_free() when no longer
 needed.
 
 If @cancellable is not %NULL, then the operation can be cancelled by
@@ -27952,7 +28040,7 @@ was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 <description>
 Finishes an asynchronous load of the @file's contents.
 The contents are placed in @contents, and @length is set to the
-size of the @contents string. The @content should be freed with
+size of the @contents string. The @contents should be freed with
 g_free() when no longer needed. If @etag_out is present, it will be
 set to the new entity tag for the @file.
 
@@ -28039,7 +28127,7 @@ when the request is satisfied
 Finishes an asynchronous partial load operation that was started
 with g_file_load_partial_contents_async(). The data is always
 zero-terminated, but this is not included in the resultant @length.
-The returned @content should be freed with g_free() when no longer
+The returned @contents should be freed with g_free() when no longer
 needed.
 
 
@@ -28775,10 +28863,6 @@ inside the same filesystem), but the fallback code does not.
 If the flag #G_FILE_COPY_OVERWRITE is specified an already
 existing @destination file is overwritten.
 
-If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
-will be copied as symlinks, otherwise the target of the
-@source symlink will be copied.
-
 If @cancellable is not %NULL, then the operation can be cancelled by
 triggering the cancellable object from another thread. If the operation
 was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
@@ -30164,7 +30248,7 @@ was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 If @make_backup is %TRUE, this function will attempt to
 make a backup of @file.
 
-Note that no copy of @content will be made, so it must stay valid
+Note that no copy of @contents will be made, so it must stay valid
 until @callback is called. See g_file_replace_contents_bytes_async()
 for a #GBytes version that will automatically hold a reference to the
 contents (without copying) for the duration of the call.
@@ -30480,7 +30564,7 @@ Free the returned object with g_object_unref().
 
 <function name="g_file_set_attribute">
 <description>
-Sets an attribute in the file with attribute name @attribute to @value.
+Sets an attribute in the file with attribute name @attribute to @value_p.
 
 Some attributes can be unset by setting @type to
 %G_FILE_ATTRIBUTE_TYPE_INVALID and @value_p to %NULL.
@@ -31141,7 +31225,7 @@ when the request is satisfied, or %NULL
 
 <function name="g_file_stop_mountable_finish">
 <description>
-Finishes an stop operation, see g_file_stop_mountable() for details.
+Finishes a stop operation, see g_file_stop_mountable() for details.
 
 Finish an asynchronous stop operation that was started
 with g_file_stop_mountable().
@@ -34558,6 +34642,72 @@ Since: 2.44
 <return></return>
 </function>
 
+<function name="g_list_store_find">
+<description>
+Looks up the given @item in the list store by looping over the items until
+the first occurrence of @item. If @item was not found, then @position will
+not be set, and this method will return %FALSE.
+
+If you need to compare the two items with a custom comparison function, use
+g_list_store_find_with_equal_func() with a custom #GEqualFunc instead.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="store">
+<parameter_description> a #GListStore
+</parameter_description>
+</parameter>
+<parameter name="item">
+<parameter_description> an item
+</parameter_description>
+</parameter>
+<parameter name="position">
+<parameter_description> the first position of @item, if it was found.
+</parameter_description>
+</parameter>
+</parameters>
+<return> Whether @store contains @item. If it was found, @position will be
+set to the position where @item occurred for the first time.
+
+</return>
+</function>
+
+<function name="g_list_store_find_with_equal_func">
+<description>
+Looks up the given @item in the list store by looping over the items and
+comparing them with @compare_func until the first occurrence of @item which
+matches. If @item was not found, then @position will not be set, and this
+method will return %FALSE.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="store">
+<parameter_description> a #GListStore
+</parameter_description>
+</parameter>
+<parameter name="item">
+<parameter_description> an item
+</parameter_description>
+</parameter>
+<parameter name="equal_func">
+<parameter_description> A custom equality check function
+</parameter_description>
+</parameter>
+<parameter name="position">
+<parameter_description> the first position of @item, if it was found.
+</parameter_description>
+</parameter>
+</parameters>
+<return> Whether @store contains @item. If it was found, @position will be
+set to the position where @item occurred for the first time.
+
+</return>
+</function>
+
 <function name="g_list_store_insert">
 <description>
 Inserts @item into @store at @position. @item must be of type
@@ -34963,6 +35113,20 @@ Creates a new #GMemoryInputStream with data in memory of a given size.
 </return>
 </function>
 
+<function name="g_memory_monitor_dup_default">
+<description>
+Gets a reference to the default #GMemoryMonitor for the system.
+
+Since: 2.64
+
+</description>
+<parameters>
+</parameters>
+<return> a new reference to the default #GMemoryMonitor
+
+</return>
+</function>
+
 <function name="g_memory_output_stream_get_data">
 <description>
 Gets any loaded data from the @ostream.
@@ -37087,7 +37251,7 @@ memory cards. See the
 [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec)
 specification for more on x-content types.
 
-This is an synchronous operation and as such may block doing IO;
+This is a synchronous operation and as such may block doing IO;
 see g_mount_guess_content_type() for the asynchronous version.
 
 Since: 2.18
@@ -43293,7 +43457,7 @@ Gets the value that is stored in @settings for @key and converts it
 to the flags value that it represents.
 
 In order to use this function the type of the value must be an array
-of strings and it must be marked in the schema file as an flags type.
+of strings and it must be marked in the schema file as a flags type.
 
 It is a programmer error to give a @key that isn't contained in the
 schema for @settings or is not marked as a flags type.
@@ -43704,7 +43868,7 @@ function is intended for introspection reasons.
 You should free the return value with g_strfreev() when you are done
 with it.
 
-Deprecated: 2.46: Use g_settings_schema_list_keys instead().
+Deprecated: 2.46: Use g_settings_schema_list_keys() instead.
 
 </description>
 <parameters>
@@ -44042,7 +44206,7 @@ schemas correspond to exactly one set of keys in the backend
 database: those located at the path returned by this function.
 
 Relocatable schemas can be referenced by other schemas and can
-threfore describe multiple sets of keys at different locations.  For
+therefore describe multiple sets of keys at different locations.  For
 relocatable schemas, this function will return %NULL.
 
 Since: 2.32
@@ -51138,7 +51302,7 @@ Since: 2.40
 </description>
 <parameters>
 <parameter name="self">
-<parameter_description> a #GSubprocess
+<parameter_description> a #GSubprocessLauncher
 </parameter_description>
 </parameter>
 <parameter name="variable">
@@ -51225,7 +51389,7 @@ Since: 2.40
 </description>
 <parameters>
 <parameter name="self">
-<parameter_description> a #GSubprocess
+<parameter_description> a #GSubprocessLauncher
 </parameter_description>
 </parameter>
 <parameter name="cwd">
@@ -51263,7 +51427,7 @@ Since: 2.40
 </description>
 <parameters>
 <parameter name="self">
-<parameter_description> a #GSubprocess
+<parameter_description> a #GSubprocessLauncher
 </parameter_description>
 </parameter>
 <parameter name="env">
@@ -51412,7 +51576,7 @@ Since: 2.40
 </description>
 <parameters>
 <parameter name="self">
-<parameter_description> a #GSubprocess
+<parameter_description> a #GSubprocessLauncher
 </parameter_description>
 </parameter>
 <parameter name="variable">
@@ -51640,7 +51804,7 @@ Since: 2.40
 </description>
 <parameters>
 <parameter name="self">
-<parameter_description> a #GSubprocess
+<parameter_description> a #GSubprocessLauncher
 </parameter_description>
 </parameter>
 <parameter name="variable">
@@ -52314,6 +52478,41 @@ Since: 2.36
 </return>
 </function>
 
+<function name="g_task_propagate_value">
+<description>
+Gets the result of @task as a #GValue, and transfers ownership of
+that value to the caller. As with g_task_return_value(), this is
+a generic low-level method; g_task_propagate_pointer() and the like
+will usually be more useful for C code.
+
+If the task resulted in an error, or was cancelled, then this will
+instead set @error and return %FALSE.
+
+Since this method transfers ownership of the return value (or
+error) to the caller, you may only call it once.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="task">
+<parameter_description> a #GTask
+</parameter_description>
+</parameter>
+<parameter name="value">
+<parameter_description> return location for the #GValue
+</parameter_description>
+</parameter>
+<parameter name="error">
+<parameter_description> return location for a #GError
+</parameter_description>
+</parameter>
+</parameters>
+<return> %TRUE if @task succeeded, %FALSE on error.
+
+</return>
+</function>
+
 <function name="g_task_report_error">
 <description>
 Creates a #GTask and then immediately calls g_task_return_error()
@@ -52581,6 +52780,34 @@ function
 <return></return>
 </function>
 
+<function name="g_task_return_value">
+<description>
+Sets @task's result to @result (by copying it) and completes the task.
+
+If @result is %NULL then a #GValue of type #G_TYPE_POINTER
+with a value of %NULL will be used for the result.
+
+This is a very generic low-level method intended primarily for use
+by language bindings; for C code, g_task_return_pointer() and the
+like will normally be much easier to use.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="task">
+<parameter_description> a #GTask
+</parameter_description>
+</parameter>
+<parameter name="result">
+<parameter_description> the #GValue result of
+a task function
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
 <function name="g_task_run_in_thread">
 <description>
 Runs @task_func in another thread. When @task_func returns, @task's
@@ -53689,12 +53916,34 @@ Since: 2.28
 
 <function name="g_tls_client_connection_copy_session_state">
 <description>
-Copies session state from one connection to another. This is
-not normally needed, but may be used when the same session
-needs to be used between different endpoints as is required
-by some protocols such as FTP over TLS. @source should have
-already completed a handshake, and @conn should not have
-completed a handshake.
+Possibly copies session state from one connection to another, for use
+in TLS session resumption. This is not normally needed, but may be
+used when the same session needs to be used between different
+endpoints, as is required by some protocols, such as FTP over TLS.
+@source should have already completed a handshake and, since TLS 1.3,
+it should have been used to read data at least once. @conn should not
+have completed a handshake.
+
+It is not possible to know whether a call to this function will
+actually do anything. Because session resumption is normally used
+only for performance benefit, the TLS backend might not implement
+this function. Even if implemented, it may not actually succeed in
+allowing @conn to resume @source's TLS session, because the server
+may not have sent a session resumption token to @source, or it may
+refuse to accept the token from @conn. There is no way to know
+whether a call to this function is actually successful.
+
+Using this function is not required to benefit from session
+resumption. If the TLS backend supports session resumption, the
+session will be resumed automatically if it is possible to do so
+without weakening the privacy guarantees normally provided by TLS,
+without need to call this function. For example, with TLS 1.3,
+a session ticket will be automatically copied from any
+#GTlsClientConnection that has previously received session tickets
+from the server, provided a ticket is available that has not
+previously been used for session resumption, since session ticket
+reuse would be a privacy weakness. Using this function causes the
+ticket to be copied without regard for privacy considerations.
 
 Since: 2.46
 
@@ -53760,14 +54009,12 @@ known.
 
 <function name="g_tls_client_connection_get_use_ssl3">
 <description>
-Gets whether @conn will force the lowest-supported TLS protocol
-version rather than attempt to negotiate the highest mutually-
-supported version of TLS; see g_tls_client_connection_set_use_ssl3().
+SSL 3.0 is no longer supported. See
+g_tls_client_connection_set_use_ssl3() for details.
 
 Since: 2.28
 
-Deprecated: 2.56: SSL 3.0 is insecure, and this function does not
-actually indicate whether it is enabled.
+Deprecated: 2.56: SSL 3.0 is insecure.
 
 </description>
 <parameters>
@@ -53776,7 +54023,7 @@ actually indicate whether it is enabled.
 </parameter_description>
 </parameter>
 </parameters>
-<return> whether @conn will use the lowest-supported TLS protocol version
+<return> %FALSE
 
 </return>
 </function>
@@ -53857,24 +54104,20 @@ Since: 2.28
 
 <function name="g_tls_client_connection_set_use_ssl3">
 <description>
-Since 2.42.1, if @use_ssl3 is %TRUE, this forces @conn to use the
-lowest-supported TLS protocol version rather than trying to properly
-negotiate the highest mutually-supported protocol version with the
-peer. Be aware that SSL 3.0 is generally disabled by the
-#GTlsBackend, so the lowest-supported protocol version is probably
-not SSL 3.0.
+Since GLib 2.42.1, SSL 3.0 is no longer supported.
 
-Since 2.58, this may additionally cause an RFC 7507 fallback SCSV to
-be sent to the server, causing modern TLS servers to immediately
-terminate the connection. You should generally only use this function
-if you need to connect to broken servers that exhibit TLS protocol
-version intolerance, and when an initial attempt to connect to a
-server normally has already failed.
+From GLib 2.42.1 through GLib 2.62, this function could be used to
+force use of TLS 1.0, the lowest-supported TLS protocol version at
+the time. In the past, this was needed to connect to broken TLS
+servers that exhibited protocol version intolerance. Such servers
+are no longer common, and using TLS 1.0 is no longer considered
+acceptable.
+
+Since GLib 2.64, this function does nothing.
 
 Since: 2.28
 
-Deprecated: 2.56: SSL 3.0 is insecure, and this function does not
-generally enable or disable it, despite its name.
+Deprecated: 2.56: SSL 3.0 is insecure.
 
 </description>
 <parameters>
@@ -53883,7 +54126,7 @@ generally enable or disable it, despite its name.
 </parameter_description>
 </parameter>
 <parameter name="use_ssl3">
-<parameter_description> whether to use the lowest-supported protocol version
+<parameter_description> a #gboolean, ignored
 </parameter_description>
 </parameter>
 </parameters>
@@ -54080,7 +54323,7 @@ from the TLS protocol in TLS 1.3.
 </parameter_description>
 </parameter>
 </parameters>
-<return> @conn's rehandshaking mode
+<return> %G_TLS_REHANDSHAKE_SAFELY
 
 </return>
 </function>
@@ -54131,28 +54374,30 @@ Attempts a TLS handshake on @conn.
 
 On the client side, it is never necessary to call this method;
 although the connection needs to perform a handshake after
-connecting (or after sending a &quot;STARTTLS&quot;-type command) and may
-need to rehandshake later if the server requests it,
+connecting (or after sending a &quot;STARTTLS&quot;-type command),
 #GTlsConnection will handle this for you automatically when you try
-to send or receive data on the connection. However, you can call
-g_tls_connection_handshake() manually if you want to know for sure
-whether the initial handshake succeeded or failed (as opposed to
-just immediately trying to write to @conn's output stream, in which
-case if it fails, it may not be possible to tell if it failed
-before or after completing the handshake).
+to send or receive data on the connection. You can call
+g_tls_connection_handshake() manually if you want to know whether
+the initial handshake succeeded or failed (as opposed to just
+immediately trying to use @conn to read or write, in which case,
+if it fails, it may not be possible to tell if it failed before or
+after completing the handshake), but beware that servers may reject
+client authentication after the handshake has completed, so a
+successful handshake does not indicate the connection will be usable.
 
 Likewise, on the server side, although a handshake is necessary at
 the beginning of the communication, you do not need to call this
 function explicitly unless you want clearer error reporting.
 
-If TLS 1.2 or older is in use, you may call
-g_tls_connection_handshake() after the initial handshake to
-rehandshake; however, this usage is deprecated because rehandshaking
-is no longer part of the TLS protocol in TLS 1.3. Accordingly, the
-behavior of calling this function after the initial handshake is now
-undefined, except it is guaranteed to be reasonable and
-nondestructive so as to preserve compatibility with code written for
-older versions of GLib.
+Previously, calling g_tls_connection_handshake() after the initial
+handshake would trigger a rehandshake; however, this usage was
+deprecated in GLib 2.60 because rehandshaking was removed from the
+TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after
+the initial handshake will no longer do anything.
+
+When using a #GTlsConnection created by #GSocketClient, the
+#GSocketClient performs the initial handshake, so calling this
+function manually is not recommended.
 
 #GTlsConnection::accept_certificate may be emitted during the
 handshake.
@@ -54361,27 +54606,10 @@ Since: 2.30
 
 <function name="g_tls_connection_set_rehandshake_mode">
 <description>
-Sets how @conn behaves with respect to rehandshaking requests, when
-TLS 1.2 or older is in use.
-
-%G_TLS_REHANDSHAKE_NEVER means that it will never agree to
-rehandshake after the initial handshake is complete. (For a client,
-this means it will refuse rehandshake requests from the server, and
-for a server, this means it will close the connection with an error
-if the client attempts to rehandshake.)
-
-%G_TLS_REHANDSHAKE_SAFELY means that the connection will allow a
-rehandshake only if the other end of the connection supports the
-TLS `renegotiation_info` extension. This is the default behavior,
-but means that rehandshaking will not work against older
-implementations that do not support that extension.
-
-%G_TLS_REHANDSHAKE_UNSAFELY means that the connection will allow
-rehandshaking even without the `renegotiation_info` extension. On
-the server side in particular, this is not recommended, since it
-leaves the server open to certain attacks. However, this mode is
-necessary if you need to allow renegotiation with older client
-software.
+Since GLib 2.64, changing the rehandshake mode is no longer supported
+and will have no effect. With TLS 1.3, rehandshaking has been removed from
+the TLS protocol, replaced by separate post-handshake authentication and
+rekey operations.
 
 Since: 2.28
 
@@ -55380,7 +55608,7 @@ Since: 2.40
 
 <function name="g_tls_interaction_request_certificate_finish">
 <description>
-Complete an request certificate user interaction request. This should be once
+Complete a request certificate user interaction request. This should be once
 the g_tls_interaction_request_certificate_async() completion callback is called.
 
 If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsConnection
index 1df08d9..9d757d3 100644 (file)
@@ -1,91 +1,4 @@
 <root>
-<substitute_type_name from="GAppInfoCreateFlags" to="Gio::AppInfo::CreateFlags" />
-<substitute_type_name from="GApplicationFlags" to="Gio::Application::Flags" />
-<substitute_type_name from="GConverterFlags" to="Gio::Converter::Flags" />
-<substitute_type_name from="GConverterResult" to="Gio::Converter::Result" />
-<substitute_type_name from="GCredentialsType" to="Gio::Credentials::Type" />
-<substitute_type_name from="GDBusActionGroup" to="Gio::DBus::ActionGroup" />
-<substitute_type_name from="GDBusConnection" to="Gio::DBus::Connection" />
-<substitute_type_name from="GDBusAuthObserver" to="Gio::DBus::AuthObserver" />
-<substitute_type_name from="GDBusMessage" to="Gio::DBus::Message" />
-<substitute_type_name from="GDBusCallFlags" to="Gio::DBus::CallFlags" />
-<substitute_type_name from="GDBusInterfaceSkeletonFlags" to="Gio::DBus::InterfaceSkeleton::Flags" />
-<substitute_type_name from="GDBusProxyFlags" to="Gio::DBus::ProxyFlags" />
-<substitute_type_name from="GDBusProxy" to="Gio::DBus::Proxy" />
-<substitute_type_name from="GDBusInterfaceInfo" to="Gio::DBus::InterfaceInfo" />
-<substitute_type_name from="GDBusServer" to="Gio::DBus::Server" />
-<substitute_type_name from="GDBusServerFlags" to="Gio::DBus::Server::Flags" />
-<substitute_type_name from="GDriveStartFlags" to="Gio::Drive::StartFlags" />
-<substitute_type_name from="GDriveStartStopType" to="Gio::Drive::StartStopType" />
-<substitute_type_name from="GEmblemOrigin" to="Gio::Emblem::Origin" />
-<substitute_type_name from="GIOErrorEnum" to="Gio::Error" />
-<substitute_type_name from="GFileAttributeInfoFlags" to="Gio::FileAttributeInfo::Flags" />
-<substitute_type_name from="GFileCopyFlags" to="Gio::File::CopyFlags" />
-<substitute_type_name from="GFileCreateFlags" to="Gio::File::CreateFlags" />
-<substitute_type_name from="GFileMeasureFlags" to="Gio::File::MeasureFlags" />
-<substitute_type_name from="GFileMonitorEvent" to="Gio::FileMonitor::Event" />
-<substitute_type_name from="GIOStreamSpliceFlags" to="Gio::IOStream::SpliceFlags" />
-<substitute_type_name from="GMountMountFlags" to="Gio::Mount::MountFlags" />
-<substitute_type_name from="GMountUnmountFlags" to="Gio::Unmount::MountFlags" />
-<substitute_type_name from="GNotificationPriority" to="Gio::Notification::Priority" />
-<substitute_type_name from="GOutputStreamSpliceFlags" to="Gio::OutputStream::SpliceFlags" />
-<substitute_type_name from="GResolverRecordType" to="Gio::Resolver::RecordType" />
-<substitute_type_name from="GResourceFlags" to="Gio::Resource::Flags" />
-<substitute_type_name from="GResourceLookupFlags" to="Gio::Resource::LookupFlags" />
-<substitute_type_name from="GSettingsBindFlags" to="Gio::Settings::BindFlags" />
-<substitute_type_name from="GSocketMsgFlags" to="Gio::Socket::MsgFlags" />
-<substitute_type_name from="GSocketProtocol" to="Gio::Socket::Protocol" />
-<substitute_type_name from="GSocketType" to="Gio::Socket::Type" />
-<substitute_type_name from="GTlsDatabaseLookupFlags" to="Gio::TlsDatabase::LookupFlags" />
-<substitute_type_name from="GTlsDatabaseVerifyFlags" to="Gio::TlsDatabase::VerifyFlags" />
-<substitute_type_name from="GTlsPasswordFlags" to="Gio::TlsPassword::Flags" />
-<substitute_type_name from="GUnixSocketAddressType" to="Gio::UnixSocketAddress::Type" />
-
-<substitute_enumerator_name from_prefix="G_APPLICATION_" to_prefix="Gio::Application::Flags::" />
-<substitute_enumerator_name from="G_APPLICATION_FLAGS_NONE" to="Gio::Application::Flags::NONE" />
-<!-- GConverterFlags and GConverterResult both have prefix G_CONVERTER_. -->
-<substitute_enumerator_name from="G_CONVERTER_NO_FLAGS" to="Gio::Converter::Flags::NO_FLAGS" />
-<substitute_enumerator_name from="G_CONVERTER_INPUT_AT_END" to="Gio::Converter::Flags::INPUT_AT_END" />
-<substitute_enumerator_name from="G_CONVERTER_FLUSH" to="Gio::Converter::Flags::FLUSH" />
-<substitute_enumerator_name from_prefix="G_CONVERTER_" to_prefix="Gio::Converter::Result::" />
-
-<substitute_enumerator_name from_prefix="G_DATA_STREAM_BYTE_ORDER_" to_prefix="Gio::DataStreamByteOrder::" />
-<substitute_enumerator_name from_prefix="G_DATA_STREAM_NEWLINE_TYPE_" to_prefix="Gio::DataStreamNewlineType::" />
-<substitute_enumerator_name from_prefix="G_IO_ERROR_" to_prefix="Gio::Error::" />
-<substitute_enumerator_name from_prefix="G_DBUS_CAPABILITY_FLAGS_" to_prefix="Gio::DBus::CapabilityFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_CONNECTION_FLAGS_" to_prefix="Gio::DBus::ConnectionFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_SEND_MESSAGE_FLAGS_" to_prefix="Gio::DBus::SendMessageFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_MESSAGE_TYPE_" to_prefix="Gio::DBus::MessageType::" />
-<substitute_enumerator_name from_prefix="G_DBUS_ERROR_" to_prefix="Gio::DBus::Error::" />
-<substitute_enumerator_name from_prefix="G_DBUS_MESSAGE_HEADER_FIELD_" to_prefix="Gio::DBus::MessageHeaderField::" />
-<substitute_enumerator_name from_prefix="G_DBUS_MESSAGE_FLAGS_" to_prefix="Gio::DBus::MessageFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_" to_prefix="Gio::DBus::ObjectManagerClient::Flags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_PROXY_FLAGS_" to_prefix="Gio::DBus::ProxyFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_INTERFACE_SKELETON_FLAGS_" to_prefix="Gio::DBus::InterfaceSkeleton::Flags::" />
-<substitute_enumerator_name from_prefix="G_BUS_NAME_OWNER_FLAGS_" to_prefix="Gio::DBus::BusNameOwnerFlags::" />
-<substitute_enumerator_name from_prefix="G_DBUS_SERVER_FLAGS_" to_prefix="Gio::DBus::Server::Flags::" />
-<substitute_enumerator_name from_prefix="G_FILE_MONITOR_EVENT_" to_prefix="Gio::FileMonitor::Event::" />
-<substitute_enumerator_name from_prefix="G_FILE_MONITOR_" to_prefix="Gio::FileMonitorFlags::" />
-<substitute_enumerator_name from_prefix="G_FILE_TYPE_" to_prefix="Gio::FileType::" />
-<substitute_enumerator_name from_prefix="G_NETWORK_CONNECTIVITY_" to_prefix="Gio::NetworkConnectivity::" />
-<substitute_enumerator_name from_prefix="G_PASSWORD_SAVE_" to_prefix="Gio::PasswordSave::" />
-<substitute_enumerator_name from_prefix="G_RESOLVER_RECORD_" to_prefix="Gio::Resolver::RecordType::" />
-<substitute_enumerator_name from_prefix="G_RESOURCE_ERROR_" to_prefix="Gio::ResourceError::" />
-<substitute_enumerator_name from_prefix="G_SETTINGS_BIND_" to_prefix="Gio::Settings::BindFlags::" />
-<substitute_enumerator_name from_prefix="G_SOCKET_PROTOCOL_" to_prefix="Gio::Socket::Protocol::" />
-<substitute_enumerator_name from_prefix="G_SOCKET_TYPE_" to_prefix="Gio::Socket::Type::" />
-<substitute_enumerator_name from_prefix="G_SOCKET_FAMILY_" to_prefix="Gio::SocketFamily::" />
-<substitute_enumerator_name from_prefix="G_IO_" to_prefix="Glib::IOCondition::" />
-<substitute_enumerator_name from_prefix="G_SOCKET_CLIENT_" to_prefix="Gio::SocketClientEvent::" />
-<substitute_enumerator_name from_prefix="G_TLS_AUTHENTICATION_" to_prefix="Gio::GTlsAuthenticationMode::" />
-<substitute_enumerator_name from_prefix="G_TLS_CERTIFICATE_" to_prefix="Gio::TlsCertificateFlags::" />
-<substitute_enumerator_name from_prefix="G_TLS_REHANDSHAKE_" to_prefix="Gio::TlsRehandshakeMode::" />
-<substitute_enumerator_name from_prefix="G_TLS_DATABASE_VERIFY_" to_prefix="Gio::TlsDatabaseVerifyFlags::" />
-<substitute_enumerator_name from_prefix="G_TLS_INTERACTION_" to_prefix="Gio::TlsInteractionResult::" />
-<substitute_enumerator_name from_prefix="G_TLS_ERROR_" to_prefix="Gio::TlsError::" />
-<substitute_enumerator_name from_prefix="G_TLS_PASSWORD_" to_prefix="Gio::TlsPassword::Flags::" />
-<substitute_enumerator_name from_prefix="G_ZLIB_COMPRESSOR_FORMAT_" to_prefix="Gio::ZlibCompressorFormat::" />
-<substitute_enumerator_name from_prefix="G_UNIX_SOCKET_ADDRESS_" to_prefix="Gio::UnixSocketAddress::Type::" />
 <!-- These are preprocessor defines. Don't substitute. -->
 <substitute_enumerator_name from="G_MAXSSIZE" to="G_MAXSSIZE" />
 <substitute_enumerator_name from="G_MAXINT" to="G_MAXINT" />
@@ -94,7 +7,6 @@
 <substitute_enumerator_name from="G_RESOURCE_ERROR" to="G_RESOURCE_ERROR" />
 <substitute_enumerator_name from="G_RESOLVER_ERROR" to="G_RESOLVER_ERROR" />
 <substitute_enumerator_name from="G_TLS_ERROR" to="G_TLS_ERROR" />
-<substitute_enumerator_name from="G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE" to="G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE" />
 <substitute_enumerator_name from_prefix="G_FILE_ATTRIBUTE_" to_prefix="G_FILE_ATTRIBUTE_" />
 <substitute_enumerator_name from_prefix="G_MENU_ATTRIBUTE_" to_prefix="G_MENU_ATTRIBUTE_" />
 <substitute_enumerator_name from_prefix="G_MENU_LINK_" to_prefix="G_MENU_LINK_" />
index 2b85aed..91eb253 100644 (file)
     '("busy" "G_IO_ERROR_BUSY" "26")
     '("would-block" "G_IO_ERROR_WOULD_BLOCK" "27")
     '("host-not-found" "G_IO_ERROR_HOST_NOT_FOUND" "28")
-    '("host-was-not-found" "G_IO_ERROR_HOST_WAS_NOT_FOUND" "28")
+    '("host-not-found" "G_IO_ERROR_HOST_WAS_NOT_FOUND" "28")
     '("would-merge" "G_IO_ERROR_WOULD_MERGE" "29")
     '("failed-handled" "G_IO_ERROR_FAILED_HANDLED" "30")
     '("too-many-open-files" "G_IO_ERROR_TOO_MANY_OPEN_FILES" "31")
   )
 )
 
+;; Original typedef:
+;; typedef enum {
+;;   G_MEMORY_MONITOR_WARNING_LEVEL_LOW      = 50,
+;;   G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM   = 100,
+;;   G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL = 255
+;; } GMemoryMonitorWarningLevel;
+
+(define-enum-extended MemoryMonitorWarningLevel
+  (in-module "G")
+  (c-name "GMemoryMonitorWarningLevel")
+  (values
+    '("low" "G_MEMORY_MONITOR_WARNING_LEVEL_LOW" "50")
+    '("medium" "G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM" "100")
+    '("critical" "G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL" "255")
+  )
+)
+
 ;; From gresolver.h
 
 ;; Original typedef:
index 4ef9701..4d64a58 100644 (file)
@@ -6,7 +6,7 @@
      '("busy" "G_IO_ERROR_BUSY" "26")
      '("would-block" "G_IO_ERROR_WOULD_BLOCK" "27")
      '("host-not-found" "G_IO_ERROR_HOST_NOT_FOUND" "28")
-+    '("host-was-not-found" "G_IO_ERROR_HOST_WAS_NOT_FOUND" "28")
++    '("host-not-found" "G_IO_ERROR_HOST_WAS_NOT_FOUND" "28")
      '("would-merge" "G_IO_ERROR_WOULD_MERGE" "29")
      '("failed-handled" "G_IO_ERROR_FAILED_HANDLED" "30")
      '("too-many-open-files" "G_IO_ERROR_TOO_MANY_OPEN_FILES" "31")
index 2a1adfe..19945b6 100644 (file)
   )
 )
 
+(define-enum MonitorWarningLevel
+  (in-module "GMemory")
+  (c-name "GMemoryMonitorWarningLevel")
+  (gtype-id "G_TYPE_MEMORY_MONITOR_WARNING_LEVEL")
+  (values
+    '("low" "G_MEMORY_MONITOR_WARNING_LEVEL_LOW")
+    '("medium" "G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM")
+    '("critical" "G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL")
+  )
+)
+
 (define-flags NameLookupFlags
   (in-module "GResolver")
   (c-name "GResolverNameLookupFlags")
   )
 )
 
+(define-method find
+  (of-object "GListStore")
+  (c-name "g_list_store_find")
+  (return-type "gboolean")
+  (parameters
+    '("gpointer" "item")
+    '("guint*" "position")
+  )
+)
+
+(define-method find_with_equal_func
+  (of-object "GListStore")
+  (c-name "g_list_store_find_with_equal_func")
+  (return-type "gboolean")
+  (parameters
+    '("gpointer" "item")
+    '("GEqualFunc" "equal_func")
+    '("guint*" "position")
+  )
+)
+
 
 
 ;; From gloadableicon.h
     '("GFileMonitorFlags" "flags")
     '("GFileMonitorCallback" "callback")
     '("gpointer" "user_data")
+    '("GClosureNotify" "destroy_user_data")
     '("GError**" "error")
   )
 )
 
 
 
+;; From gmemorymonitordbus.h
+
+
+
+;; From gmemorymonitor.h
+
+(define-function g_memory_monitor_dup_default
+  (c-name "g_memory_monitor_dup_default")
+  (return-type "GMemoryMonitor*")
+)
+
+
+
+;; From gmemorymonitorportal.h
+
+
+
 ;; From gmemoryoutputstream.h
 
 (define-function g_memory_output_stream_get_type
   (varargs #t)
 )
 
+(define-method return_value
+  (of-object "GTask")
+  (c-name "g_task_return_value")
+  (return-type "none")
+  (parameters
+    '("GValue*" "result")
+  )
+)
+
 (define-method return_error_if_cancelled
   (of-object "GTask")
   (c-name "g_task_return_error_if_cancelled")
   )
 )
 
+(define-method propagate_value
+  (of-object "GTask")
+  (c-name "g_task_propagate_value")
+  (return-type "gboolean")
+  (parameters
+    '("GValue*" "value")
+    '("GError**" "error")
+  )
+)
+
 (define-method had_error
   (of-object "GTask")
   (c-name "g_task_had_error")
   (return-type "GType")
 )
 
+(define-function g_memory_monitor_warning_level_get_type
+  (c-name "g_memory_monitor_warning_level_get_type")
+  (return-type "GType")
+)
+
 (define-function g_resolver_name_lookup_flags_get_type
   (c-name "g_resolver_name_lookup_flags_get_type")
   (return-type "GType")
index 16a893f..f57f187 100644 (file)
   (readable #t)
   (writable #t)
   (construct-only #t)
+  (deprecated #t)
   (default-value "FALSE")
 )
 
   (readable #t)
   (writable #t)
   (construct-only #f)
+  (deprecated #t)
   (default-value "TRUE")
 )
 
index cfa1382..8f8cea8 100644 (file)
@@ -1,5 +1,5 @@
---- tools/gen_scripts/../../gio/src/gio_signals.defs.orig      2019-07-15 15:42:00.493060856 +0200
-+++ tools/gen_scripts/../../gio/src/gio_signals.defs   2019-07-15 15:42:00.513060927 +0200
+--- ./../../gio/src/gio_signals.defs.orig      2020-03-16 18:33:48.007956031 +0100
++++ ./../../gio/src/gio_signals.defs   2020-03-16 18:36:00.059688821 +0100
 @@ -87,11 +87,11 @@
    (return-type "void")
    (flags "Run Last, Must Collect")
  
  ;; From GApplication
  
-@@ -744,11 +744,11 @@
+@@ -597,10 +597,11 @@
+   (prop-type "GParamBoolean")
+   (docs "Whether or not this is an abstract address")
+   (readable #t)
+   (writable #t)
+   (construct-only #t)
++  (deprecated #t)
+   (default-value "FALSE")
+ )
+ (define-property address-type
+   (of-object "GUnixSocketAddress")
+@@ -744,11 +745,11 @@
    (of-object "GMountOperation")
    (return-type "void")
    (flags "Run Last")
@@ -26,7 +38,7 @@
  
  (define-signal reply
    (of-object "GMountOperation")
-@@ -1142,11 +1142,11 @@
+@@ -1142,11 +1143,11 @@
  (define-signal writable-change-event
    (of-object "GSettings")
    (return-type "gboolean")
@@ -39,7 +51,7 @@
  
  (define-property settings-schema
    (of-object "GSettings")
-@@ -1226,20 +1226,20 @@
+@@ -1226,20 +1227,20 @@
  (define-signal activate
    (of-object "GSimpleAction")
    (return-type "void")
@@ -62,7 +74,7 @@
  
  (define-property name
    (of-object "GSimpleAction")
-@@ -1886,11 +1886,11 @@
+@@ -1886,11 +1887,11 @@
  (define-signal writable-change-event
    (of-object "GSettings")
    (return-type "gboolean")
@@ -75,7 +87,7 @@
  
  (define-property settings-schema
    (of-object "GSettings")
-@@ -2808,23 +2808,23 @@
+@@ -2809,23 +2810,23 @@
    (parameters
      '("GDBusObjectProxy*" "p0")
      '("GDBusProxy*" "p1")
  
  (define-property bus-type
    (of-object "GDBusObjectManagerClient")
-@@ -2997,23 +2997,23 @@
+@@ -2998,23 +2999,23 @@
  (define-signal g-properties-changed
    (of-object "GDBusProxy")
    (return-type "void")
index 8ba65e1..e23e9a3 100644 (file)
   (return-type "void")
 )
 
-(define-vfunc dbus_register
-  (of-object "GApplication")
-  (return-type "gboolean")
-  (parameters
-    '("GDBusConnection*" "connection")
-    '("const-gchar*" "object_path")
-    '("GError**" "error")
-  )
-)
-
-(define-vfunc dbus_unregister
+(define-vfunc shutdown
   (of-object "GApplication")
   (return-type "void")
-  (parameters
-    '("GDBusConnection*" "connection")
-    '("const-gchar*" "object_path")
-  )
 )
 
 ; GAsyncInitable
   (return-type "GObject*")
 )
 
-(define-vfunc is_tagged
-  (of-object "GAsyncResult")
-  (return-type "gboolean")
- (parameters
-  '("gpointer" "source_tag")
- )
-)
-
 ; GBufferedInputStream
 
 (define-vfunc fill
   )
 )
 
-; GFileDescriptorBased
-
-(define-vfunc get_fd
- (of-object "GFileDescriptorBased")
- (return-type "int")
-)
-
 ; GFileInputStream
 
 (define-vfunc tell
index 23cba52..9d3249b 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 #include <glibmm/variant.h>
 
@@ -43,9 +45,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class Icon : public Glib::Interface
+class GIOMM_API Icon : public Glib::Interface
 {
-  _CLASS_INTERFACE(Icon, GIcon, G_ICON, GIconIface)
+  _CLASS_INTERFACE(Icon, GIcon, G_ICON, GIconIface, , , GIOMM_API)
 
 public:
   // We can't just use a _WRAP_CREATE macro here since this is an abstract
@@ -77,7 +79,6 @@ public:
   _WRAP_METHOD(Glib::VariantBase serialize() const, g_icon_serialize, newin "2,48")
   _WRAP_METHOD(static Glib::RefPtr<Icon> deserialize(const Glib::VariantBase& value), g_icon_deserialize, newin "2,48")
 
-protected:
   //_WRAP_VFUNC(guint hash() const, "hash")
 
   // TODO: also kind of related to equal() being virtual or not,
index e4c0c0a..7a3145d 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 #include <giomm/enums.h>
 
@@ -37,10 +39,10 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class InetAddress
+class GIOMM_API InetAddress
 : public Glib::Object
 {
-  _CLASS_GOBJECT(InetAddress, GInetAddress, G_INET_ADDRESS, Glib::Object, GObject)
+  _CLASS_GOBJECT(InetAddress, GInetAddress, G_INET_ADDRESS, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
  _WRAP_CTOR(InetAddress(const guint8 *bytes, SocketFamily family), g_inet_address_new_from_bytes)
index 4177cb5..9220480 100644 (file)
@@ -35,10 +35,10 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class InetSocketAddress
+class GIOMM_API InetSocketAddress
 : public SocketAddress
 {
-  _CLASS_GOBJECT(InetSocketAddress, GInetSocketAddress, G_INET_SOCKET_ADDRESS, SocketAddress, GSocketAddress)
+  _CLASS_GOBJECT(InetSocketAddress, GInetSocketAddress, G_INET_SOCKET_ADDRESS, SocketAddress, GSocketAddress, , , GIOMM_API)
 
 protected:
  _WRAP_CTOR(InetSocketAddress(const Glib::RefPtr<InetAddress>& address, guint16 port), g_inet_socket_address_new)
@@ -54,13 +54,10 @@ public:
  _WRAP_METHOD(guint32 get_flowinfo() const, g_inet_socket_address_get_flowinfo)
  _WRAP_METHOD(guint32 get_scope_id() const, g_inet_socket_address_get_scope_id)
 
-  _WRAP_PROPERTY("address", Glib::RefPtr<InetAddress>)
-  // Don't use guint16 or guint32 in _WRAP_PROPERTY().
-  // There are no Glib::Value<> specializations for those types.
-  // Glib::Value<unsigned int> exists, and guint is a typedef of unsigned int.
-  _WRAP_PROPERTY("port", guint)
-  _WRAP_PROPERTY("flowinfo", guint)
-  _WRAP_PROPERTY("scope-id", guint)
+ _WRAP_PROPERTY("address", Glib::RefPtr<InetAddress>)
+ _WRAP_PROPERTY("port", guint16)
+ _WRAP_PROPERTY("flowinfo", guint32)
+ _WRAP_PROPERTY("scope-id", guint32)
 };
 
 } // namespace Gio
index 09bca9f..2be9124 100644 (file)
@@ -48,15 +48,14 @@ namespace Gio
  *
  * @newin{2,24}
  */
-class Initable : public Glib::Interface
+class GIOMM_API Initable : public Glib::Interface
 {
-  _CLASS_INTERFACE(Initable, GInitable, G_INITABLE, GInitableIface)
+  _CLASS_INTERFACE(Initable, GInitable, G_INITABLE, GInitableIface, , , GIOMM_API)
 
 protected:
   _WRAP_METHOD(void init(const Glib::RefPtr<Cancellable>& cancellable{?}),
     g_initable_init, errthrow)
 
-protected:
   _WRAP_VFUNC(bool init(const Glib::RefPtr<Cancellable>& cancellable, GError** error), "init")
 };
 
index 1618043..5ed092b 100644 (file)
@@ -35,9 +35,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class InputStream : public Glib::Object
+class GIOMM_API InputStream : public Glib::Object
 {
-  _CLASS_GOBJECT(InputStream, GInputStream, G_INPUT_STREAM, Glib::Object, GObject)
+  _CLASS_GOBJECT(InputStream, GInputStream, G_INPUT_STREAM, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -389,10 +389,11 @@ protected:
   _WRAP_METHOD(bool set_pending(), g_input_stream_set_pending, errthrow, newin "2,50")
   _WRAP_METHOD(void clear_pending(), g_input_stream_clear_pending, newin "2,50")
 
+  //TODO: When we can break ABI, add vfuncs. See https://bugzilla.gnome.org/show_bug.cgi?id=572471
 #m4 _CONVERSION(`GCancellable*', `const Glib::RefPtr<Cancellable>&', `Glib::wrap($3, true)')
-  _WRAP_VFUNC(gssize read(void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable), read_fn, errthrow, err_return_value -1)
-  _WRAP_VFUNC(gssize skip(gsize count, const Glib::RefPtr<Cancellable>& cancellable), skip, errthrow, err_return_value -1)
-  _WRAP_VFUNC(bool close(const Glib::RefPtr<Cancellable>& cancellable), close_fn, errthrow)
+  //_WRAP_VFUNC(gssize read(void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable), read_fn, errthrow, err_return_value -1)
+  //_WRAP_VFUNC(gssize skip(gsize count, const Glib::RefPtr<Cancellable>& cancellable), skip, errthrow, err_return_value -1)
+  //_WRAP_VFUNC(bool close(const Glib::RefPtr<Cancellable>& cancellable), close_fn, errthrow)
 };
 
 } // namespace Gio
index 800932d..5807215 100644 (file)
@@ -48,7 +48,7 @@ IOStream::close_async(const SlotAsyncReady& slot, int io_priority)
 
 void
 IOStream::splice_async(const Glib::RefPtr<IOStream>& stream2, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, SpliceFlags flags, int io_priority)
+  const Glib::RefPtr<Cancellable>& cancellable, IOStreamSpliceFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -61,7 +61,7 @@ IOStream::splice_async(const Glib::RefPtr<IOStream>& stream2, const SlotAsyncRea
 
 void
 IOStream::splice_async(const Glib::RefPtr<IOStream>& stream2, const SlotAsyncReady& slot,
-  SpliceFlags flags, int io_priority)
+  IOStreamSpliceFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
index f52fe17..5b93a96 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The giomm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -27,6 +29,8 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
+_WRAP_ENUM(IOStreamSpliceFlags, GIOStreamSpliceFlags, NO_GTYPE)
+
 /** IOStream - Base class for implementing read/write streams.
  * IOStream represents an object that has both read and write streams.
  * Generally the two streams acts as separate input and output streams, but
@@ -56,14 +60,12 @@ namespace Gio
  *
  * @newin{2,22}
  */
-class IOStream : public Glib::Object
+class GIOMM_API IOStream : public Glib::Object
 {
-  _CLASS_GOBJECT(IOStream, GIOStream, G_IO_STREAM, Glib::Object, GObject)
+  _CLASS_GOBJECT(IOStream, GIOStream, G_IO_STREAM, Glib::Object, GObject, , , GIOMM_API)
 
 public:
 
-  _WRAP_ENUM(SpliceFlags, GIOStreamSpliceFlags, NO_GTYPE)
-
   /**  Asyncronously splice the output stream to the input stream of @a
    * stream2, and splice the output stream of @a stream2 to the input stream of
    * this stream.
@@ -74,21 +76,21 @@ public:
    * @param stream2 The second IOStream.
    * @param slot A SlotAsyncReady slot.
    * @param cancellable A Cancellable object.
-   * @param flags A set of SpliceFlags.
+   * @param flags A set of IOStreamSpliceFlags.
    * @param io_priority The io priority of the request.
    *
    * @newin{2,34}
    */
   void splice_async(const Glib::RefPtr<IOStream>& stream2,
     const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable,
-    SpliceFlags flags = SpliceFlags::NONE,
+    IOStreamSpliceFlags flags = Gio::IO_STREAM_SPLICE_NONE,
     int io_priority = Glib::PRIORITY_DEFAULT);
   _IGNORE(g_io_stream_splice_async)
 
   /// A non-cancellable version of splice_async().
   void splice_async(const Glib::RefPtr<IOStream>& stream2,
     const SlotAsyncReady& slot,
-    SpliceFlags flags = SpliceFlags::NONE,
+    IOStreamSpliceFlags flags = Gio::IO_STREAM_SPLICE_NONE,
     int io_priority = Glib::PRIORITY_DEFAULT);
 
   _WRAP_METHOD(static bool splice_finish(const Glib::RefPtr<AsyncResult>& result), g_io_stream_splice_finish, errthrow)
index 324a9ec..3d1f31f 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 #include <gio/gio.h>
 
@@ -73,9 +75,9 @@ namespace Gio
  *
  * @newin{2,50}
  */
-class ListModel : public Glib::Interface
+class GIOMM_API ListModel : public Glib::Interface
 {
-  _CLASS_INTERFACE(ListModel, GListModel, G_LIST_MODEL, GListModelInterface)
+  _CLASS_INTERFACE(ListModel, GListModel, G_LIST_MODEL, GListModelInterface, , , GIOMM_API)
 
 protected:
   _WRAP_METHOD(void items_changed(guint position, guint removed, guint added), g_list_model_items_changed, newin "2,50")
@@ -93,7 +95,6 @@ public:
 
   _WRAP_SIGNAL(void items_changed(guint position, guint removed, guint added), "items-changed", no_default_handler, newin "2,50")
 
-protected:
   _WRAP_VFUNC(GType get_item_type(), "get_item_type")
   _WRAP_VFUNC(guint get_n_items(), "get_n_items")
   _WRAP_VFUNC(gpointer get_item(guint position), "get_item")
index 8c93c85..844041d 100644 (file)
@@ -34,11 +34,11 @@ namespace Gio
  *
  * @newin{2,50}
  */
-class ListStoreBase
+class GIOMM_API ListStoreBase
 : public Glib::Object,
   public ListModel
 {
-  _CLASS_GOBJECT(ListStoreBase, GListStore, G_LIST_STORE, Glib::Object, GObject)
+  _CLASS_GOBJECT(ListStoreBase, GListStore, G_LIST_STORE, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(ListModel)
   _STRUCT_NOT_HIDDEN
 
@@ -62,7 +62,7 @@ public:
    *
    * @newin{2,50}
    */
-  using SlotCompare = sigc::slot<int(const Glib::RefPtr<const Glib::ObjectBase>&, const Glib::RefPtr<const Glib::ObjectBase>&)>;
+  using SlotCompare = sigc::slot<int, const Glib::RefPtr<const Glib::ObjectBase>&, const Glib::RefPtr<const Glib::ObjectBase>&>;
 
   _WRAP_METHOD(guint insert_sorted(const Glib::RefPtr<Glib::ObjectBase>& item,
     const SlotCompare& slot{compare_func}), g_list_store_insert_sorted,
@@ -174,7 +174,7 @@ public:
    *
    * @newin{2,50}
    */
-  using SlotCompare = sigc::slot<int(const Glib::RefPtr<const T_item>&, const Glib::RefPtr<const T_item>&)>;
+  using SlotCompare = sigc::slot<int, const Glib::RefPtr<const T_item>&, const Glib::RefPtr<const T_item>&>;
 
   /** Inserts @a item at a position to be determined by the @a slot.
    *
@@ -243,13 +243,13 @@ ListStore<T_item>::ListStore()
 template <typename T_item>
 Glib::RefPtr<ListStore<T_item>> ListStore<T_item>::create()
 {
-  return Glib::make_refptr_for_instance<ListStore<T_item>>(new ListStore<T_item>());
+  return Glib::RefPtr<ListStore<T_item>>(new ListStore<T_item>());
 }
 
 template <typename T_item>
 Glib::RefPtr<T_item> ListStore<T_item>::get_item(guint position)
 {
-  return std::dynamic_pointer_cast<T_item>(ListModel::get_object(position));
+  return Glib::RefPtr<T_item>::cast_dynamic(ListModel::get_object(position));
 }
 
 template <typename T_item>
@@ -309,9 +309,9 @@ int ListStore<T_item>::compare_data_func(gconstpointer a, gconstpointer b, gpoin
 
   // cast_dynamic is necessary if T_item is a user-derived class, such as
   // class MyObject : public Glib::Object
-  const Glib::RefPtr<const T_item> item_a = std::dynamic_pointer_cast<T_item>(
+  const Glib::RefPtr<const T_item> item_a = Glib::RefPtr<T_item>::cast_dynamic(
     Glib::wrap(static_cast<typename T_item::BaseObjectType*>(const_cast<gpointer>(a)), true));
-  const Glib::RefPtr<const T_item> item_b = std::dynamic_pointer_cast<T_item>(
+  const Glib::RefPtr<const T_item> item_b = Glib::RefPtr<T_item>::cast_dynamic(
     Glib::wrap(static_cast<typename T_item::BaseObjectType*>(const_cast<gpointer>(b)), true));
 
   return (*slot)(item_a, item_b);
index 22f6950..10ddbe8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <gio/gio.h>
 #include <glibmm/error.h>
+#include <giomm/private/icon_p.h>
 #include "slot_async.h"
 
 namespace Gio
index a706f24..8811127 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <glibmm/interface.h>
+#include <giomm/icon.h>
 #include <giomm/inputstream.h>
+#include <giomm/icon.h>
 
 _DEFS(giomm,gio)
-_PINCLUDE(glibmm/private/interface_p.h)
+_PINCLUDE(giomm/private/icon_p.h)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 typedef struct _GLoadableIconIface GLoadableIconIface;
@@ -31,9 +32,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class LoadableIcon : public Glib::Interface
+class GIOMM_API LoadableIcon : public Icon
 {
-  _CLASS_INTERFACE(LoadableIcon, GLoadableIcon, G_LOADABLE_ICON, GLoadableIconIface)
+  _CLASS_INTERFACE(LoadableIcon, GLoadableIcon, G_LOADABLE_ICON, GLoadableIconIface, Icon, GIcon, , , GIOMM_API)
 
 public:
 /**
index 920e616..1388d7f 100644 (file)
@@ -27,9 +27,6 @@ public:
   {
   }
 
-  SlotWithData(const SlotWithData& src) = delete;
-  SlotWithData& operator=(const SlotWithData& src) = delete;
-
   ~SlotWithData() { delete m_slot; }
 
   void operator()() { (*m_slot)(m_data); }
@@ -62,6 +59,29 @@ destroy_data_callback(void* user_data)
 namespace Gio
 {
 
+_DEPRECATE_IFDEF_START
+void
+MemoryInputStream::add_data(const std::string& data)
+{
+  char* data_copy = g_strdup(data.c_str());
+  g_memory_input_stream_add_data(gobj(), data_copy, -1, g_free);
+}
+
+void
+MemoryInputStream::add_data(const void* data, gssize len)
+{
+  char* data_copy = nullptr;
+
+  // copy the data so that the caller doesn't need to keep the data alive
+  if (len < 0)
+    data_copy = g_strdup(static_cast<const gchar*>(data));
+  else
+    data_copy = static_cast<gchar*>(g_memdup(data, len));
+
+  g_memory_input_stream_add_data(gobj(), data_copy, len, g_free);
+}
+_DEPRECATE_IFDEF_END
+
 void
 MemoryInputStream::add_data(const void* data, gssize len, const SlotDestroyData& destroy_slot)
 {
index 1485256..d65956f 100644 (file)
@@ -18,7 +18,6 @@ _CONFIGINCLUDE(giommconfig.h)
 
 #include <giomm/inputstream.h>
 #include <giomm/seekable.h>
-#include <giomm/pollableinputstream.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(giomm/private/inputstream_p.h)
@@ -32,14 +31,12 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class MemoryInputStream
+class GIOMM_API MemoryInputStream
 : public Gio::InputStream,
-  public Seekable,
-  public PollableInputStream
+  public Seekable
 {
-  _CLASS_GOBJECT(MemoryInputStream, GMemoryInputStream, G_MEMORY_INPUT_STREAM, Gio::InputStream, GInputStream)
+  _CLASS_GOBJECT(MemoryInputStream, GMemoryInputStream, G_MEMORY_INPUT_STREAM, Gio::InputStream, GInputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Seekable)
-  _IMPLEMENTS_INTERFACE(PollableInputStream)
 
 protected:
   _CTOR_DEFAULT
@@ -48,6 +45,27 @@ protected:
 public:
   _WRAP_CREATE()
 
+_DEPRECATE_IFDEF_START
+  /** Appends to data that can be read from the input stream.
+   *
+   * @param data Input data.
+   *
+   * @deprecated Use add_data() with SlotDestroyData or GDestroyNotify instead.
+   */
+  void add_data(const std::string& data);
+
+  /** Appends to data that can be read from the input stream.
+   *
+   * Note that the data will be copied internally and freed when no longer needed.
+   *
+   * @param data Input data.
+   * @param len Length of the data, may be -1 if data is a null-terminated string.
+   *
+   * @deprecated Use add_data() with SlotDestroyData or GDestroyNotify instead.
+   */
+  void add_data(const void* data, gssize len);
+_DEPRECATE_IFDEF_END
+
   _WRAP_METHOD(void add_data(const void* data, gssize len, GDestroyNotify destroy), g_memory_input_stream_add_data)
 
   /** For example,
@@ -57,7 +75,7 @@ public:
    *
    * @newin{2,40}
    */
-  using SlotDestroyData = sigc::slot<void(void*)>;
+  using SlotDestroyData = sigc::slot<void, void*>;
 
   /** Appends to data that can be read from the input stream.
    *
index 310caec..4d4d15e 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <giomm/outputstream.h>
 #include <giomm/seekable.h>
-#include <giomm/pollableoutputstream.h>
 #include <glibmm/object.h>
 // TODO: remove this if possible -- it's here for the GReallocFunc definition
 #include <gio/gio.h>
@@ -28,7 +27,7 @@ namespace Glib
 {
 
 // Forward declaration.
-class Bytes;
+class GLIBMM_API Bytes;
 
 }
 
@@ -43,14 +42,12 @@ namespace Gio
  *
  * @newin{2,20}
  */
-class MemoryOutputStream :
+class GIOMM_API MemoryOutputStream :
     public OutputStream,
-    public Seekable,
-    public PollableOutputStream
+    public Seekable
 {
-  _CLASS_GOBJECT(MemoryOutputStream, GMemoryOutputStream, G_MEMORY_OUTPUT_STREAM, Gio::OutputStream, GOutputStream)
+  _CLASS_GOBJECT(MemoryOutputStream, GMemoryOutputStream, G_MEMORY_OUTPUT_STREAM, Gio::OutputStream, GOutputStream, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Seekable)
-  _IMPLEMENTS_INTERFACE(PollableOutputStream)
 
 protected:
   // Hand-coded because it's equivalent to g_memory_output_stream_new_resizable(),
index 99d5ff1..29f92bf 100644 (file)
@@ -34,9 +34,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class Menu : public Gio::MenuModel
+class GIOMM_API Menu : public Gio::MenuModel
 {
-  _CLASS_GOBJECT(Menu, GMenu, G_MENU, ::Gio::MenuModel, GMenuModel)
+  _CLASS_GOBJECT(Menu, GMenu, G_MENU, ::Gio::MenuModel, GMenuModel, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -47,9 +47,10 @@ public:
 
   _WRAP_METHOD(void freeze(), g_menu_freeze)
 
-  _WRAP_METHOD(void insert_item(int position, const Glib::RefPtr<const MenuItem>& item), g_menu_insert_item)
-  _WRAP_METHOD(void prepend_item(const Glib::RefPtr<const MenuItem>& item), g_menu_prepend_item)
-  _WRAP_METHOD(void append_item(const Glib::RefPtr<const MenuItem>& item), g_menu_append_item)
+  //TODO: Make the item "const Glib::RefPtr<const MenuItem>&" when we can break ABI? The function is documented as just copying its attributes.
+  _WRAP_METHOD(void insert_item(int position, const Glib::RefPtr<MenuItem>& item), g_menu_insert_item)
+  _WRAP_METHOD(void prepend_item(const Glib::RefPtr<MenuItem>& item), g_menu_prepend_item)
+  _WRAP_METHOD(void append_item(const Glib::RefPtr<MenuItem>& item), g_menu_append_item)
   _WRAP_METHOD(void remove(int position), g_menu_remove)
   _WRAP_METHOD(void remove_all(), g_menu_remove_all)
 
@@ -61,7 +62,6 @@ public:
   _WRAP_METHOD(void prepend(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_prepend)
   _WRAP_METHOD(void append(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_append)
 
-// TODO: Should the MenuModel be const too?
   _WRAP_METHOD(void insert_section(int position, const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_insert_section)
   _WRAP_METHOD(void prepend_section(const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_prepend_section)
   _WRAP_METHOD(void append_section(const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_append_section)
index 558c240..10fcddc 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -25,9 +27,9 @@ namespace Gio
 /** MenuAttributeIter - A menu attribute iterator.
  * @newin{2,32}
  */
-class MenuAttributeIter : public Glib::Object
+class GIOMM_API MenuAttributeIter : public Glib::Object
 {
-  _CLASS_GOBJECT(MenuAttributeIter, GMenuAttributeIter, G_MENU_ATTRIBUTE_ITER, Glib::Object, GObject)
+  _CLASS_GOBJECT(MenuAttributeIter, GMenuAttributeIter, G_MENU_ATTRIBUTE_ITER, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -38,7 +40,10 @@ public:
 
   _WRAP_METHOD(Glib::ustring get_name() const, g_menu_attribute_iter_get_name)
 
-  _WRAP_METHOD(Glib::VariantBase get_value() const, g_menu_attribute_iter_get_value)
+  //TODO: When we can break ABI, remove the method overload and just make it const.
+  //It makes no sense to return const by value.
+  _WRAP_METHOD(Glib::VariantBase get_value(), g_menu_attribute_iter_get_value)
+  _WRAP_METHOD(const Glib::VariantBase get_value() const, g_menu_attribute_iter_get_value, constversion)
 
   _WRAP_METHOD(bool next(), g_menu_attribute_iter_next)
 };
index 4db5c4d..a9a3ee5 100644 (file)
@@ -42,6 +42,14 @@ MenuItem::MenuItem(const Glib::RefPtr<MenuModel>& submenu) : _CONSTRUCT()
   set_submenu(submenu);
 }
 
+_DEPRECATE_IFDEF_START
+void
+MenuItem::set_action_and_target(const Glib::ustring& action)
+{
+  g_menu_item_set_action_and_target_value(gobj(), action.c_str(), nullptr);
+}
+_DEPRECATE_IFDEF_END
+
 void
 MenuItem::set_action(const Glib::ustring& action)
 {
index 02d1aed..e6482f4 100644 (file)
@@ -30,9 +30,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class MenuItem : public Glib::Object
+class GIOMM_API MenuItem : public Glib::Object
 {
-  _CLASS_GOBJECT(MenuItem, GMenuItem, G_MENU_ITEM, Glib::Object, GObject)
+  _CLASS_GOBJECT(MenuItem, GMenuItem, G_MENU_ITEM, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   /** Creates a new MenuItem.
@@ -47,7 +47,7 @@ protected:
    * @param label The section label.
    * @param detailed_action: The detailed action string.
    */
-  explicit MenuItem(const Glib::ustring& label = {}, const Glib::ustring& detailed_action = {});
+  explicit MenuItem(const Glib::ustring& label = Glib::ustring(), const Glib::ustring& detailed_action = Glib::ustring());
   _IGNORE(g_menu_item_new)
 
   /** Creates a new MenuItem representing a submenu.
@@ -101,6 +101,7 @@ GMenuItem * g_menu_item_new_section                 (const Glib::ustring& label,
   //void set_attribute(const Glib::ustring& attribute, const T_Value& value) const;
 
   _WRAP_METHOD(void set_attribute_value(const Glib::ustring& attribute, const Glib::VariantBase& value), g_menu_item_set_attribute_value)
+  _WRAP_METHOD(void set_attribute(const Glib::ustring& attribute, const Glib::VariantBase& value), g_menu_item_set_attribute_value, deprecated "Use set_attribute() instead.")
   _IGNORE(g_menu_item_set_attribute)
 
 //These are documented as transfer-full, so we don't need to use refreturn.
@@ -118,11 +119,19 @@ GMenuItem * g_menu_item_new_section                 (const Glib::ustring& label,
   //void get_attribute(const Glib::ustring& attribute, T_Value& value) const;
   //_WRAP_METHOD(Glib::VariantBase get_attribute_value(const Glib::ustring& attribute, const Glib::VariantType& expected_type{?}) const, g_menu_item_get_attribute_value)
 
+  _WRAP_METHOD(Glib::VariantBase get_attribute(const Glib::ustring& attribute, const Glib::VariantType& expected_type{?}) const, g_menu_item_get_attribute_value, deprecated "Use get_attribute_value() instead.")
   _WRAP_METHOD(Glib::VariantBase get_attribute_value(const Glib::ustring& attribute, const Glib::VariantType& expected_type{?}) const, g_menu_item_get_attribute_value)
 
   // Ignore varargs function.
   _IGNORE(g_menu_item_get_attribute)
 
+_DEPRECATE_IFDEF_START
+  /** Unsets the target for the specified @a action.
+   * @deprecated Use set_action() or unset_target() instead.
+   */
+  void set_action_and_target(const Glib::ustring& action);
+_DEPRECATE_IFDEF_END
+
   /** Sets the action for the menu item.
    * See set_action_and_target().
    *
index 8cba9df..10f6cad 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -22,14 +24,14 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class MenuModel;
+class GIOMM_API MenuModel;
 
 /** MenuLinkIter - A menu link iterator.
  * @newin{2,32}
  */
-class MenuLinkIter : public Glib::Object
+class GIOMM_API MenuLinkIter : public Glib::Object
 {
-  _CLASS_GOBJECT(MenuLinkIter, GMenuLinkIter, G_MENU_LINK_ITER, Glib::Object, GObject)
+  _CLASS_GOBJECT(MenuLinkIter, GMenuLinkIter, G_MENU_LINK_ITER, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
index 81fb877..0402ee7 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -43,8 +45,8 @@ enum MenuLink
   MENU_LINK_SUBMENU
 };
 
-class MenuAttributeIter;
-class MenuLinkIter;
+class GIOMM_API MenuAttributeIter;
+class GIOMM_API MenuLinkIter;
 
 /** MenuModel - An abstract class representing the contents of a menu.
  * MenuModel represents the contents of a menu -- an ordered list of menu
@@ -120,9 +122,9 @@ class MenuLinkIter;
  * See the C API docs for a graphical example.
  * @newin{2,32}
  */
-class MenuModel : public Glib::Object
+class GIOMM_API MenuModel : public Glib::Object
 {
-  _CLASS_GOBJECT(MenuModel, GMenuModel, G_MENU_MODEL, Glib::Object, GObject)
+  _CLASS_GOBJECT(MenuModel, GMenuModel, G_MENU_MODEL, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -131,13 +133,16 @@ public:
 #m4begin
 dnl See the .ccg implementation for how this conversion works.
 
+  //TODO: When we can break ABI, remove the method overload and just make it const.
+  //It makes no sense to return const by value.
   _CONVERSION(`MenuAttribute',`const gchar*',`giomm_get_menu_attribute($3)')
 #m4end
 
   //TODO: Add a get_item_attribute() templated method to get values directly
   //instead of returning a Glib::VariantBase?
 
-  _WRAP_METHOD(Glib::VariantBase get_item_attribute(int item_index, MenuAttribute attribute, const Glib::VariantType& expected_type) const, g_menu_model_get_item_attribute_value)
+  _WRAP_METHOD(Glib::VariantBase get_item_attribute(int item_index, MenuAttribute attribute, const Glib::VariantType& expected_type), g_menu_model_get_item_attribute_value)
+  _WRAP_METHOD(const Glib::VariantBase get_item_attribute(int item_index, MenuAttribute attribute, const Glib::VariantType& expected_type) const, g_menu_model_get_item_attribute_value, constversion)
 
   // Ignore varargs function
   _IGNORE(g_menu_model_get_item_attribute)
index 6a4fd36..939931d 100644 (file)
@@ -26,7 +26,7 @@ namespace Gio
 
 void
 Mount::unmount(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -39,7 +39,7 @@ Mount::unmount(
 }
 
 void
-Mount::unmount(const SlotAsyncReady& slot, UnmountFlags flags)
+Mount::unmount(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -53,7 +53,7 @@ Mount::unmount(const SlotAsyncReady& slot, UnmountFlags flags)
 }
 
 void
-Mount::unmount(UnmountFlags flags)
+Mount::unmount(MountUnmountFlags flags)
 {
   g_mount_unmount_with_operation(gobj(), GMountUnmountFlags(flags),
     nullptr, // mount_operation
@@ -64,7 +64,7 @@ Mount::unmount(UnmountFlags flags)
 
 void
 Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -77,7 +77,7 @@ Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAs
 
 void
 Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  UnmountFlags flags)
+  MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -90,7 +90,7 @@ Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAs
 }
 
 void
-Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, UnmountFlags flags)
+Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_mount_unmount_with_operation(gobj(), GMountUnmountFlags(flags), Glib::unwrap(mount_operation),
     nullptr, // cancellable
@@ -100,7 +100,7 @@ Mount::unmount(const Glib::RefPtr<MountOperation>& mount_operation, UnmountFlags
 
 void
 Mount::remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, MountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -113,7 +113,7 @@ Mount::remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncRea
 
 void
 Mount::remount(
-  const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, MountFlags flags)
+  const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -125,21 +125,21 @@ Mount::remount(
 }
 
 void
-Mount::remount(const Glib::RefPtr<MountOperation>& operation, MountFlags flags)
+Mount::remount(const Glib::RefPtr<MountOperation>& operation, MountMountFlags flags)
 {
   g_mount_remount(gobj(), static_cast<GMountMountFlags>(flags), Glib::unwrap(operation), nullptr,
     nullptr, nullptr);
 }
 
 void
-Mount::remount(MountFlags flags)
+Mount::remount(MountMountFlags flags)
 {
   g_mount_remount(gobj(), static_cast<GMountMountFlags>(flags), nullptr, nullptr, nullptr, nullptr);
 }
 
 void
 Mount::eject(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -152,7 +152,7 @@ Mount::eject(
 }
 
 void
-Mount::eject(const SlotAsyncReady& slot, UnmountFlags flags)
+Mount::eject(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -166,7 +166,7 @@ Mount::eject(const SlotAsyncReady& slot, UnmountFlags flags)
 }
 
 void
-Mount::eject(UnmountFlags flags)
+Mount::eject(MountUnmountFlags flags)
 {
   g_mount_eject_with_operation(gobj(), GMountUnmountFlags(flags),
     nullptr, // mount_operation
@@ -177,7 +177,7 @@ Mount::eject(UnmountFlags flags)
 
 void
 Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -190,7 +190,7 @@ Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyn
 
 void
 Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  UnmountFlags flags)
+  MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -203,7 +203,7 @@ Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyn
 }
 
 void
-Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, UnmountFlags flags)
+Mount::eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_mount_eject_with_operation(gobj(), GMountUnmountFlags(flags), Glib::unwrap(mount_operation),
     nullptr, // cancellable
index d4d93e0..b3f00f2 100644 (file)
@@ -34,10 +34,12 @@ typedef struct _GMountIface GMountIface;
 namespace Gio
 {
 
+_WRAP_ENUM(MountUnmountFlags, GMountUnmountFlags, NO_GTYPE)
+_WRAP_ENUM(MountMountFlags, GMountMountFlags, NO_GTYPE)
 
-class File;
-class Drive;
-class Volume;
+class GIOMM_API File;
+class GIOMM_API Drive;
+class GIOMM_API Volume;
 
 /** The Mount interface represents user-visible mounts.
  * Mount is a "mounted" filesystem that you can access. Mounted is in quotes because it's not the same as a unix mount:
@@ -51,13 +53,11 @@ class Volume;
  *
  * @newin{2,16}
  */
-class Mount : public Glib::Interface
+class GIOMM_API Mount : public Glib::Interface
 {
-  _CLASS_INTERFACE(Mount, GMount, G_MOUNT, GMountIface)
+  _CLASS_INTERFACE(Mount, GMount, G_MOUNT, GMountIface, , , GIOMM_API)
 
 public:
-  _WRAP_ENUM(UnmountFlags, GMountUnmountFlags, NO_GTYPE)
-  _WRAP_ENUM(MountFlags, GMountMountFlags, NO_GTYPE)
 
   _WRAP_METHOD(Glib::RefPtr<File> get_root(), g_mount_get_root, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const File> get_root() const, g_mount_get_root, refreturn, constversion)
@@ -81,12 +81,12 @@ public:
   _WRAP_METHOD(bool can_unmount() const, g_mount_can_unmount)
   _WRAP_METHOD(bool can_eject() const, g_mount_can_eject)
 
-  void unmount(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags = UnmountFlags::NONE);
-  void unmount(const SlotAsyncReady& slot, UnmountFlags flags = UnmountFlags::NONE);
-  void unmount(UnmountFlags flags = UnmountFlags::NONE);
-  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, UnmountFlags flags = UnmountFlags::NONE);
-  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, UnmountFlags flags = UnmountFlags::NONE);
-  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags = UnmountFlags::NONE);
+  void unmount(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void unmount(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void unmount(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void unmount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_mount_unmount)
   _IGNORE(g_mount_unmount_with_operation)
 
@@ -105,7 +105,7 @@ public:
    * @param cancellable A cancellable object which can be used to cancel the operation.
    * @param flags Flags affecting the operation.
    */
-  void remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountFlags flags = MountFlags::NONE);
+  void remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Remounts a mount.
    * This is an asynchronous operation, and is finished by calling mount_finish() with the AsyncResult data returned in the callback slot.
@@ -118,7 +118,7 @@ public:
    * @param slot A callback which will be called when the operation is completed or canceled.
    * @param flags Flags affecting the operation.
    */
-  void remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, MountFlags flags = MountFlags::NONE);
+  void remount(const Glib::RefPtr<MountOperation>& operation, const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Remounts a mount.
    *
@@ -129,7 +129,7 @@ public:
    * @param operation A mount operation.
    * @param flags Flags affecting the operation.
    */
-  void remount(const Glib::RefPtr<MountOperation>& operation, MountFlags flags = MountFlags::NONE);
+  void remount(const Glib::RefPtr<MountOperation>& operation, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Remounts a mount, without user interaction.
    *
@@ -139,18 +139,18 @@ public:
    *
    * @param flags Flags affecting the operation.
    */
-  void remount(MountFlags flags = MountFlags::NONE);
+  void remount(MountMountFlags flags = MOUNT_MOUNT_NONE);
   _IGNORE(g_mount_remount)
 
 
   _WRAP_METHOD(bool remount_finish(const Glib::RefPtr<AsyncResult>& result), g_mount_remount_finish, errthrow)
 
-  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags = UnmountFlags::NONE);
-  void eject(const SlotAsyncReady& slot, UnmountFlags flags = UnmountFlags::NONE);
-  void eject(UnmountFlags flags = UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, UnmountFlags flags = UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, UnmountFlags flags = UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, UnmountFlags flags = UnmountFlags::NONE);
+  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_mount_eject)
   _IGNORE(g_mount_eject_with_operation)
 
@@ -206,7 +206,7 @@ public:
   void guess_content_type_sync(bool force_rescan = true);
   _IGNORE(g_mount_guess_content_type_sync)
 
-  #m4 _CONVERSION(`gchar**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
+  #m4 _CONVERSION(`gchar**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
 
   /** Finishes guessing content types of the Mount.
    * If any errors occurred during the operation, an exception will be thrown.
@@ -219,7 +219,7 @@ public:
    * @return An array of content types.
    * @throw Glib::Error
    */
-  _WRAP_METHOD(std::vector<Glib::ustring> guess_content_type_finish(const Glib::RefPtr<AsyncResult>& result), g_mount_guess_content_type_finish, errthrow)
+  _WRAP_METHOD(Glib::StringArrayHandle guess_content_type_finish(const Glib::RefPtr<AsyncResult>& result), g_mount_guess_content_type_finish, errthrow)
 
   _WRAP_METHOD(bool is_shadowed() const, g_mount_is_shadowed)
   _WRAP_METHOD(void shadow(), g_mount_shadow)
@@ -231,7 +231,7 @@ public:
 
   _WRAP_SIGNAL(void changed(), changed)
   _WRAP_SIGNAL(void unmounted(), unmounted)
-  _WRAP_SIGNAL(void pre_unmount(), pre_unmount)
+  _WRAP_SIGNAL(void pre_unmount(), pre_unmount, no_default_handler)
 
   //There are no properties.
 };
@@ -242,6 +242,7 @@ namespace Glib
 {
 
 //Pre-declare this so we can use it in TypeTrait:
+GIOMM_API
 Glib::RefPtr<Gio::Mount> wrap(GMount* object, bool take_copy);
 
 namespace Container_Helpers
@@ -253,7 +254,7 @@ namespace Container_Helpers
  * would not return a wrapper for an interface.
  */
 template <>
-struct TypeTraits< Glib::RefPtr<Gio::Mount> >
+struct GIOMM_API TypeTraits< Glib::RefPtr<Gio::Mount> >
 {
   using CppType = Glib::RefPtr<Gio::Mount>;
   using CType = GMount*;
index 9a19e00..c45a428 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
+#include <glibmm/arrayhandle.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -39,9 +42,9 @@ _WRAP_ENUM(MountOperationResult, GMountOperationResult, NO_GTYPE)
  *
  * @newin{2,16}
  */
-class MountOperation : public Glib::Object
+class GIOMM_API MountOperation : public Glib::Object
 {
-  _CLASS_GOBJECT(MountOperation, GMountOperation, G_MOUNT_OPERATION, Glib::Object, GObject)
+  _CLASS_GOBJECT(MountOperation, GMountOperation, G_MOUNT_OPERATION, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -77,18 +80,20 @@ public:
 #m4 _CONVERSION(`const char*',`const Glib::ustring&',__GCHARP_TO_USTRING)
   _WRAP_SIGNAL(void ask_password(const Glib::ustring& message, const Glib::ustring& default_user, const Glib::ustring& default_domain, AskPasswordFlags flags), ask_password)
 
-  //TODO: We really need some test to make sure that our use of ArrayHandler is correct. murrayc.
-#m4 _CONVERSION(`const std::vector<Glib::ustring>&',`const gchar**',`const_cast<const gchar**>(Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data())')
-#m4 _CONVERSION(`const gchar**',`const std::vector<Glib::ustring>&',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
-  _WRAP_SIGNAL(void ask_question(const Glib::ustring& message, const std::vector<Glib::ustring>& choices), ask_question)
+  //TODO: We really need some test to make sure that our use of StringArrayHandle is correct. murrayc.
+#m4 _CONVERSION(`const Glib::StringArrayHandle&',`const gchar**',`const_cast<const gchar**>(($3).data())')
+#m4 _CONVERSION(`const gchar**',`const Glib::StringArrayHandle&',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_NONE)')
+  _WRAP_SIGNAL(void ask_question(const Glib::ustring& message, const Glib::StringArrayHandle& choices), ask_question)
 
   _WRAP_SIGNAL(void reply(MountOperationResult result), reply)
-  _WRAP_SIGNAL(void aborted(), aborted)
+
+  //TODO: Remove no_default_handler when we can break ABI:
+  _WRAP_SIGNAL(void aborted(), aborted, no_default_handler)
 
   //TODO: The array of char* is not very pleasant to wrap:
   //_WRAP_SIGNAL( void show_processes(const Glib::ustring& message, GArray* processes, const gchar *choices[]);
 
-  _WRAP_SIGNAL(void show_unmount_progress(const Glib::ustring& message, gint64 time_left, gint64 bytes_left), "show_unmount_progress")
+  _WRAP_SIGNAL(void show_unmount_progress(const Glib::ustring& message, gint64 time_left, gint64 bytes_left), "show_unmount_progress", no_default_handler)
 
   _WRAP_PROPERTY("username", Glib::ustring)
   _WRAP_PROPERTY("password", Glib::ustring)
index ff5e123..41bd61f 100644 (file)
@@ -32,10 +32,10 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class NetworkAddress : public Glib::Object,
+class GIOMM_API NetworkAddress : public Glib::Object,
     public SocketConnectable
 {
-  _CLASS_GOBJECT(NetworkAddress, GNetworkAddress, G_NETWORK_ADDRESS, Glib::Object, GObject)
+  _CLASS_GOBJECT(NetworkAddress, GNetworkAddress, G_NETWORK_ADDRESS, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(SocketConnectable)
 
   _WRAP_CTOR(NetworkAddress(const std::string& hostname, guint16 port), g_network_address_new)
index 7c36b2c..b376e47 100644 (file)
@@ -33,21 +33,20 @@ namespace Gio
 
 _WRAP_ENUM(NetworkConnectivity, GNetworkConnectivity)
 
-
 /** Network status monitor.
  *
- * %NetworkMonitor provides an easy-to-use cross-platform API
+ * %Gio::NetworkMonitor provides an easy-to-use cross-platform API
  * for monitoring network connectivity. On Linux, the available
  * implementations are based on the kernel's netlink interface and
  * on NetworkManager.
  *
  * There is also an implementation for use inside Flatpak sandboxes.
-
+ *
  * @newin{2,44}
  */
-class NetworkMonitor : public Glib::Interface
+class GIOMM_API NetworkMonitor : public Glib::Interface
 {
-  _CLASS_INTERFACE(NetworkMonitor, GNetworkMonitor, G_NETWORK_MONITOR, GNetworkMonitorInterface)
+  _CLASS_INTERFACE(NetworkMonitor, GNetworkMonitor, G_NETWORK_MONITOR, GNetworkMonitorInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(static Glib::RefPtr<NetworkMonitor> get_default(), g_network_monitor_get_default, newin "2,44")
index 581fc78..47a07bb 100644 (file)
@@ -36,10 +36,10 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class NetworkService : public Glib::Object,
+class GIOMM_API NetworkService : public Glib::Object,
     public SocketConnectable
 {
-  _CLASS_GOBJECT(NetworkService, GNetworkService, G_NETWORK_SERVICE, Glib::Object, GObject)
+  _CLASS_GOBJECT(NetworkService, GNetworkService, G_NETWORK_SERVICE, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(SocketConnectable)
 
   _WRAP_CTOR(NetworkService(const Glib::ustring& service, const Glib::ustring& protocol, const Glib::ustring& domain), g_network_service_new)
index 2ab0384..8e65c90 100644 (file)
@@ -25,8 +25,9 @@ _PINCLUDE(glibmm/private/object_p.h)
 
 namespace Gio
 {
-class Icon;
+class GIOMM_API Icon;
 
+_WRAP_ENUM(NotificationPriority, GNotificationPriority, newin "2,44")
 
 /** User Notifications (pop up messages).
  *
@@ -54,9 +55,9 @@ class Icon;
  *
  * @newin{2,40}
  */
-class Notification : public Glib::Object
+class GIOMM_API Notification : public Glib::Object
 {
-  _CLASS_GOBJECT(Notification, GNotification, G_NOTIFICATION, Glib::Object, GObject)
+  _CLASS_GOBJECT(Notification, GNotification, G_NOTIFICATION, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   // Can't use _WRAP_CTOR. GNotification has no properties, but it must have a title.
@@ -64,16 +65,14 @@ protected:
   _IGNORE(g_notification_new)
 
 public:
-  _WRAP_ENUM(Priority, GNotificationPriority, newin "2,44")
-
   _WRAP_METHOD_DOCS_ONLY(g_notification_new)
   _WRAP_CREATE(const Glib::ustring& title)
 
   _WRAP_METHOD(void set_title(const Glib::ustring& title), g_notification_set_title)
   _WRAP_METHOD(void set_body(const Glib::ustring& body), g_notification_set_body)
   _WRAP_METHOD(void set_icon(const Glib::RefPtr<Icon>& icon), g_notification_set_icon)
-  _IGNORE(g_notification_set_urgent)
-  _WRAP_METHOD(void set_priority(Priority priority = Priority::NORMAL), g_notification_set_priority, newin "2,44")
+  _WRAP_METHOD(void set_urgent(bool urgent = true), g_notification_set_urgent, deprecated "Use set_priority() instead.")
+  _WRAP_METHOD(void set_priority(NotificationPriority priority = NOTIFICATION_PRIORITY_NORMAL), g_notification_set_priority, newin "2,44")
 
   _WRAP_METHOD(void add_button(const Glib::ustring& label, const Glib::ustring& detailed_action), g_notification_add_button)
 
index da48f7d..6ba8fe4 100644 (file)
@@ -19,8 +19,6 @@
 #include <glibmm/exceptionhandler.h>
 #include "slot_async.h"
 
-using SpliceFlags = Gio::OutputStream::SpliceFlags;
-
 namespace Gio
 {
 
@@ -78,7 +76,7 @@ OutputStream::write_all_async(
 
 void
 OutputStream::splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, SpliceFlags flags, int io_priority)
+  const Glib::RefPtr<Cancellable>& cancellable, OutputStreamSpliceFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -92,7 +90,7 @@ OutputStream::splice_async(const Glib::RefPtr<InputStream>& source, const SlotAs
 
 void
 OutputStream::splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot,
-  SpliceFlags flags, int io_priority)
+  OutputStreamSpliceFlags flags, int io_priority)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -228,7 +226,7 @@ OutputStream::write_bytes_async(
 
 gssize
 OutputStream::splice(const Glib::RefPtr<InputStream>& source,
-  const Glib::RefPtr<Cancellable>& cancellable, SpliceFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, OutputStreamSpliceFlags flags)
 {
   GError* gerror = nullptr;
   gssize retvalue = g_output_stream_splice(gobj(), Glib::unwrap(source),
@@ -240,7 +238,7 @@ OutputStream::splice(const Glib::RefPtr<InputStream>& source,
 }
 
 gssize
-OutputStream::splice(const Glib::RefPtr<InputStream>& source, SpliceFlags flags)
+OutputStream::splice(const Glib::RefPtr<InputStream>& source, OutputStreamSpliceFlags flags)
 {
   GError* gerror = nullptr;
   gssize retvalue = g_output_stream_splice(
index c87f23f..d51d549 100644 (file)
@@ -26,6 +26,7 @@ _PINCLUDE(gio/gio.h) // for GOutputStreamSpliceFlags
 namespace Gio
 {
 
+_WRAP_ENUM(OutputStreamSpliceFlags, GOutputStreamSpliceFlags, NO_GTYPE)
 
 /** Base class for implementing streaming output.
  *
@@ -33,15 +34,14 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class OutputStream : public Glib::Object
+class GIOMM_API OutputStream : public Glib::Object
 {
-  _CLASS_GOBJECT(OutputStream, GOutputStream, G_OUTPUT_STREAM, Glib::Object, GObject)
+  _CLASS_GOBJECT(OutputStream, GOutputStream, G_OUTPUT_STREAM, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
 
 public:
-  _WRAP_ENUM(SpliceFlags, GOutputStreamSpliceFlags, NO_GTYPE)
 
   _WRAP_METHOD(gssize write(const void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable{?}),
                g_output_stream_write,
@@ -204,21 +204,21 @@ public:
   /** Splices an input stream into an output stream.
    *
    * @param source An InputStream.
-   * @param flags A set of SpliceFlags.
+   * @param flags A set of OutputStreamSpliceFlags.
    * @param cancellable A Cancellable object.
    * ignore.
    * @return A #gssize containing the size of the data spliced.
    */
-  gssize splice(const Glib::RefPtr<InputStream>& source, const Glib::RefPtr<Cancellable>& cancellable, SpliceFlags flags = SpliceFlags::NONE);
+  gssize splice(const Glib::RefPtr<InputStream>& source, const Glib::RefPtr<Cancellable>& cancellable, OutputStreamSpliceFlags flags = OUTPUT_STREAM_SPLICE_NONE);
 
   /** Splices an input stream into an output stream.
    *
    * @param source An InputStream.
-   * @param flags A set of SpliceFlags.
+   * @param flags A set of OutputStreamSpliceFlags.
    * ignore.
    * @return A #gssize containing the size of the data spliced.
    */
-  gssize splice(const Glib::RefPtr<InputStream>& source, SpliceFlags flags = SpliceFlags::NONE);
+  gssize splice(const Glib::RefPtr<InputStream>& source, OutputStreamSpliceFlags flags = OUTPUT_STREAM_SPLICE_NONE);
   _IGNORE(g_output_stream_splice)
 
   _WRAP_METHOD(bool flush(const Glib::RefPtr<Cancellable>& cancellable{?}),
@@ -410,10 +410,10 @@ public:
    * @param source An InputStream.
    * @param slot Callback slot to call when the request is satisfied.
    * @param cancellable Cancellable object.
-   * @param flags A set of SpliceFlags.
+   * @param flags A set of OutputStreamSpliceFlags.
    * @param io_priority The io priority of the request.
    */
-  void splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, SpliceFlags flags = SpliceFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, OutputStreamSpliceFlags flags = OUTPUT_STREAM_SPLICE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   /** Splices a stream asynchronously.
    *  When the operation is finished @a slot will be called.
@@ -425,10 +425,10 @@ public:
    *
    * @param source An InputStream.
    * @param slot Callback slot to call when the request is satisfied.
-   * @param flags A set of SpliceFlags.
+   * @param flags A set of OutputStreamSpliceFlags.
    * @param io_priority The io priority of the request.
    */
-  void splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot, SpliceFlags flags = SpliceFlags::NONE, int io_priority = Glib::PRIORITY_DEFAULT);
+  void splice_async(const Glib::RefPtr<InputStream>& source, const SlotAsyncReady& slot, OutputStreamSpliceFlags flags = OUTPUT_STREAM_SPLICE_NONE, int io_priority = Glib::PRIORITY_DEFAULT);
 
   _IGNORE(g_output_stream_splice_async)
 
@@ -502,12 +502,13 @@ protected:
   _WRAP_METHOD(bool set_pending(), g_output_stream_set_pending, errthrow, newin "2,50")
   _WRAP_METHOD(void clear_pending(), g_output_stream_clear_pending, newin "2,50")
 
+  //TODO: When we can break ABI, add vfuncs. See https://bugzilla.gnome.org/show_bug.cgi?id=572471
 #m4 _CONVERSION(`GCancellable*', `const Glib::RefPtr<Cancellable>&', `Glib::wrap($3, true)')
 #m4 _CONVERSION(`GInputStream*', `const Glib::RefPtr<InputStream>&', `Glib::wrap($3, true)')
-  _WRAP_VFUNC(gssize write(const void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable), write_fn, errthrow, err_return_value -1)
-  _WRAP_VFUNC(gssize splice(const Glib::RefPtr<InputStream>& source, const Glib::RefPtr<Cancellable>& cancellable{.}, SpliceFlags flags{.}), splice, errthrow, err_return_value -1)
-  _WRAP_VFUNC(bool flush(const Glib::RefPtr<Cancellable>& cancellable), flush, errthrow)
-  _WRAP_VFUNC(bool close(const Glib::RefPtr<Cancellable>& cancellable), close_fn, errthrow)
+  //_WRAP_VFUNC(gssize write(const void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable), write_fn, errthrow, err_return_value -1)
+  //_WRAP_VFUNC(gssize splice(const Glib::RefPtr<InputStream>& source, const Glib::RefPtr<Cancellable>& cancellable{.}, OutputStreamSpliceFlags flags{.}), splice, errthrow, err_return_value -1)
+  //_WRAP_VFUNC(bool flush(const Glib::RefPtr<Cancellable>& cancellable), flush, errthrow)
+  //_WRAP_VFUNC(bool close(const Glib::RefPtr<Cancellable>& cancellable), close_fn, errthrow)
 };
 
 } // namespace Gio
index d702b5b..b6b939d 100644 (file)
@@ -45,9 +45,9 @@ namespace Gio
  *
  * @newin{2,42}
  */
-class Permission : public Glib::Object
+class GIOMM_API Permission : public Glib::Object
 {
-  _CLASS_GOBJECT(Permission, GPermission, G_PERMISSION, Glib::Object, GObject)
+  _CLASS_GOBJECT(Permission, GPermission, G_PERMISSION, Glib::Object, GObject, , , GIOMM_API)
 
 public:
 
index e834c3f..dd6e7f8 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -27,14 +29,11 @@ typedef struct _GPollableInputStreamInterface GPollableInputStreamInterface;
 namespace Gio
 {
 
-class Cancellable;
+class GIOMM_API Cancellable;
 
-// GPollableInputStream requires GInputStream (a GObject), but Gio::PollableInputStream
-// shall not be derived from Gio::InputStream, like the Gio::Tls[Client|Server]Connection
-// interfaces are derived from Gio::TlsConnection. The unusual Gio::TlsConnection class
-// hierarchy is possible only because no subclass of Glib::Object implements
-// Gio::Tls[Client|Server]Connection.
-// See https://bugzilla.gnome.org/show_bug.cgi?id=776537
+//TODO: Instead derive from InputStream, when we can break ABI,
+//because the GPollableInputStream interface requires the GInputStream interface.
+//LoadableIcon does a similar thing correctly, for instance.
 
 /** PollableInputStream - Interface for pollable input streams.
  * PollableInputStream is implemented by InputStreams that can be polled for
@@ -42,9 +41,9 @@ class Cancellable;
  * expects UNIX-file-descriptor-style asynchronous I/O rather than GIO-style.
  * @newin{2,34}
  */
-class PollableInputStream : public Glib::Interface
+class GIOMM_API PollableInputStream : public Glib::Interface
 {
-  _CLASS_INTERFACE(PollableInputStream, GPollableInputStream, G_POLLABLE_INPUT_STREAM, GPollableInputStreamInterface)
+  _CLASS_INTERFACE(PollableInputStream, GPollableInputStream, G_POLLABLE_INPUT_STREAM, GPollableInputStreamInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(bool can_poll() const, g_pollable_input_stream_can_poll)
@@ -54,7 +53,6 @@ public:
 
   _WRAP_METHOD(gssize read_nonblocking(void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable{?}), g_pollable_input_stream_read_nonblocking, errthrow)
 
-protected:
   _WRAP_VFUNC(bool can_poll() const, "can_poll")
   _WRAP_VFUNC(bool is_readable() const, "is_readable")
 
index e761a87..523d6ee 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -27,14 +29,11 @@ typedef struct _GPollableOutputStreamInterface GPollableOutputStreamInterface;
 namespace Gio
 {
 
-class Cancellable;
+class GIOMM_API Cancellable;
 
-// GPollableOutputStream requires GOutputStream (a GObject), but Gio::PollableOutputStream
-// shall not be derived from Gio::OutputStream, like the Gio::Tls[Client|Server]Connection
-// interfaces are derived from Gio::TlsConnection. The unusual Gio::TlsConnection class
-// hierarchy is possible only because no subclass of Glib::Object implements
-// Gio::Tls[Client|Server]Connection.
-// See https://bugzilla.gnome.org/show_bug.cgi?id=776537
+//TODO: Instead derive from OutputStream, when we can break ABI,
+//because the GPollableOutputStream interface requires the GOutputStream interface.
+//LoadableIcon does a similar thing correctly, for instance.
 
 /** PollableOutputStream - Interface for pollable output streams.
  * PollableOutputStream is implemented by OutputStreams that can be polled for
@@ -43,9 +42,9 @@ class Cancellable;
  * GIO-style.
  * @newin{2,34}
  */
-class PollableOutputStream : public Glib::Interface
+class GIOMM_API PollableOutputStream : public Glib::Interface
 {
-  _CLASS_INTERFACE(PollableOutputStream, GPollableOutputStream, G_POLLABLE_OUTPUT_STREAM, GPollableOutputStreamInterface)
+  _CLASS_INTERFACE(PollableOutputStream, GPollableOutputStream, G_POLLABLE_OUTPUT_STREAM, GPollableOutputStreamInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(bool can_poll() const, g_pollable_output_stream_can_poll)
@@ -55,7 +54,6 @@ public:
 
   _WRAP_METHOD(gssize write_nonblocking(const void* buffer, gsize count, const Glib::RefPtr<Cancellable>& cancellable{?}), g_pollable_output_stream_write_nonblocking, errthrow)
 
-protected:
   _WRAP_VFUNC(bool can_poll() const, "can_poll")
   _WRAP_VFUNC(bool is_writable() const, "is_writable")
 
diff --git a/gio/src/propertyaction.hg b/gio/src/propertyaction.hg
deleted file mode 100644 (file)
index bd7da4a..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (C) 2017 The giomm 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <glibmm/object.h>
-#include <glibmm/refptr.h>
-#include <giomm/action.h>
-
-_DEFS(giomm,gio)
-_PINCLUDE(glibmm/private/object_p.h)
-
-namespace Gio
-{
-/** An Action reflecting a Glib::Object property.
- *
- * A %PropertyAction is a way to get an Action with a state value
- * reflecting and controlling the value of a Glib::Object property.
- *
- * The state of the action will correspond to the value of the property.
- * Changing it will change the property (assuming the requested value
- * matches the requirements as specified in the GParamSpec, used when the
- * property was installed).
- *
- * Only the most common types are presently supported. Booleans are
- * mapped to booleans, strings to strings, signed/unsigned integers to
- * int32/uint32 and floats and doubles to doubles.
- *
- * If the property is an enum then the state will be string-typed and
- * conversion will automatically be performed between the enum value and
- * "nick" string as per the GEnumValue table.
- *
- * Flags types are not currently supported.
- *
- * Properties of object types, boxed types and pointer types are not
- * supported and probably never will be.
- *
- * Properties of Glib::Variant types are not currently supported.
- *
- * If the property is boolean-valued then the action will have a nullptr
- * parameter type, and activating the action (with no parameter) will
- * toggle the value of the property.
- *
- * In all other cases, the parameter type will correspond to the type of
- * the property.
- *
- * The general idea here is to reduce the number of locations where a
- * particular piece of state is kept (and therefore has to be synchronised
- * between). %PropertyAction does not have a separate state that is kept
- * in sync with the property value -- its state is the property value.
- *
- * For example, it might be useful to create an Action corresponding to
- * property_visible_child_name() of a Gtk::Stack so that the current
- * page can be switched from a menu. The active radio indication in the
- * menu is then directly determined from the active page of the Gtk::Stack.
- *
- * An anti-example would be binding property_active_id() on a Gtk::ComboBox.
- * This is because the state of the combobox itself is probably uninteresting
- * and is actually being used to control something else.
- *
- * Another anti-example would be to bind to property_visible_child_name()
- * of a Gtk::Stack if this value is actually stored in Gio::Settings.
- * In that case, the real source of the value is
- * Gio::Settings. If you want an Action to control a setting stored in
- * Gio::Settings, see Gio::Settings::create_action() instead, and possibly
- * combine its use with Gio::Settings::bind().
- *
- * @newin{2,58}
- */
-class PropertyAction : public Glib::Object, public Action
-{
-  _CLASS_GOBJECT(PropertyAction, GPropertyAction, G_PROPERTY_ACTION, Glib::Object, GObject)
-  _IMPLEMENTS_INTERFACE(Action)
-
-protected:
-  PropertyAction(const Glib::ustring& name, const Glib::PropertyProxy_Base& property_proxy,
-    bool invert_boolean = false);
-
-public:
-  /** Creates an Action corresponding to the value of property @a property_proxy.
-   *
-   * The property must be existent and readable and writable (and not construct-only).
-   *
-   * This function takes a reference on the property's object and doesn't
-   * release it until the action is destroyed.
-   *
-   * @param name The name of the action to create.
-   * @param property_proxy The property to bind.
-   * @param invert_boolean If <tt>true</tt>, the state of the action will be
-   *        the negation of the property value, provided the property is boolean.
-   * @return A new %PropertyAction.
-   *
-   * @newin{2,58}
-   */
-  _WRAP_CREATE(const Glib::ustring& name, const Glib::PropertyProxy_Base& property_proxy,
-    bool invert_boolean = false)
-
-  _WRAP_PROPERTY("name", Glib::ustring, newin "2,58")
-  _WRAP_PROPERTY("parameter-type", Glib::VariantType, newin "2,58")
-  _WRAP_PROPERTY("enabled", bool, newin "2,58")
-  _WRAP_PROPERTY("state-type", Glib::VariantType, newin "2,58")
-  _WRAP_PROPERTY("state", Glib::VariantBase, newin "2,58")
-  //_WRAP_PROPERTY("object", Glib::ObjectBase) // write-only, construct-only
-  //_WRAP_PROPERTY("property-name", Glib::ustring) // write-only, construct-only
-  _WRAP_PROPERTY("invert-boolean", bool, newin "2,58")
-
-  // There are no methods (apart from ctor and create), signals or vfuncs.
-};
-
-} // namespace Gio
index 4fb94d2..eac5139 100644 (file)
@@ -43,9 +43,9 @@ namespace Gio
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class Proxy : public Glib::Interface
+class GIOMM_API Proxy : public Glib::Interface
 {
-  _CLASS_INTERFACE(Proxy, GProxy, G_PROXY, GProxyInterface)
+  _CLASS_INTERFACE(Proxy, GProxy, G_PROXY, GProxyInterface, , , GIOMM_API)
 
 public:
 
index 3221b4b..4df5b08 100644 (file)
@@ -28,10 +28,10 @@ namespace Gio
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class ProxyAddress
+class GIOMM_API ProxyAddress
 : public InetSocketAddress
 {
-  _CLASS_GOBJECT(ProxyAddress, GProxyAddress, G_PROXY_ADDRESS, InetSocketAddress, GInetSocketAddress)
+  _CLASS_GOBJECT(ProxyAddress, GProxyAddress, G_PROXY_ADDRESS, InetSocketAddress, GInetSocketAddress, , , GIOMM_API)
 
 protected:
   _WRAP_CTOR(ProxyAddress(const Glib::RefPtr<InetAddress>& address,
@@ -39,8 +39,8 @@ protected:
     const Glib::ustring& protocol,
     const Glib::ustring& destination_hostname,
     guint16 destination_port,
-    const Glib::ustring& username = {},
-    const Glib::ustring& password = {}), g_proxy_address_new)
+    const Glib::ustring& username = Glib::ustring(),
+    const Glib::ustring& password = Glib::ustring()), g_proxy_address_new)
 
 public:
   _WRAP_CREATE(const Glib::RefPtr<InetAddress>& address,
@@ -48,8 +48,8 @@ public:
     const Glib::ustring& protocol,
     const Glib::ustring& destination_hostname,
     guint16 destination_port,
-    const Glib::ustring& username = {},
-    const Glib::ustring& password = {})
+    const Glib::ustring& username = Glib::ustring(),
+    const Glib::ustring& password = Glib::ustring())
 
   _WRAP_METHOD(Glib::ustring get_protocol() const, g_proxy_address_get_protocol)
   _WRAP_METHOD(Glib::ustring get_destination_protocol() const, g_proxy_address_get_destination_protocol)
@@ -65,10 +65,10 @@ public:
   _WRAP_PROPERTY("protocol", Glib::ustring)
   _WRAP_PROPERTY("destination_protocol", Glib::ustring)
   _WRAP_PROPERTY("destination_hostname", Glib::ustring)
-  // Don't use guint16 in _WRAP_PROPERTY().
-  // There is no Glib::Value<> specialization for guint16.
-  // Glib::Value<unsigned int> exists, and guint is a typedef of unsigned int.
-  _WRAP_PROPERTY("destination_port", guint)
+
+//TODO: This should really be a guint16:
+  _WRAP_PROPERTY("destination_port", Glib::ustring)
+
   _WRAP_PROPERTY("username", Glib::ustring)
   _WRAP_PROPERTY("password", Glib::ustring)
   _WRAP_PROPERTY("uri", Glib::ustring)
index fb2d047..dbd75bc 100644 (file)
@@ -39,9 +39,9 @@ namespace Gio
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class ProxyResolver : public Glib::Interface
+class GIOMM_API ProxyResolver : public Glib::Interface
 {
-  _CLASS_INTERFACE(ProxyResolver, GProxyResolver, G_PROXY_RESOLVER, GProxyResolverInterface)
+  _CLASS_INTERFACE(ProxyResolver, GProxyResolver, G_PROXY_RESOLVER, GProxyResolverInterface, , , GIOMM_API)
 
 public:
 
@@ -49,7 +49,7 @@ public:
 
   _WRAP_METHOD(bool is_supported() const, g_proxy_resolver_is_supported)
 
-  //TODO: Use std::string instead of ustring?:
+  //TODO: Use std::string instead of ustring (StringArrayHandle uses ustring)?:
 #m4 _CONVERSION(`gchar**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(std::vector<Glib::ustring> lookup(const Glib::ustring& uri,
                                                 const Glib::RefPtr<Cancellable>& cancellable), g_proxy_resolver_lookup, errthrow)
index e4a63df..1369966 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2012 The giomm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -14,6 +16,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/interface.h>
 
 _DEFS(giomm,gio)
@@ -27,6 +31,12 @@ typedef struct _GRemoteActionGroupInterface GRemoteActionGroupInterface;
 namespace Gio
 {
 
+
+//TODO: Instead derive from ActionGroup, when we can break ABI,
+//because the GRemoteActionGroup interface requires the GActionGroup interface.
+//LoadableIcon does a similar thing correctly, for instance.
+
+
 /** RemoteActionGroup - a ActionGroup that interacts with other processes.
  * The RemoteActionGroup interface is implemented by ActionGroup instances that
  * either transmit action invocations to other processes or receive action
@@ -48,18 +58,18 @@ namespace Gio
  * platform data for action invocations that arrive by way of D-Bus.
  * @newin{2,32}
  */
-class RemoteActionGroup : public Glib::Interface
+class GIOMM_API RemoteActionGroup : public Glib::Interface
 {
-  _CLASS_INTERFACE(RemoteActionGroup, GRemoteActionGroup, G_REMOTE_ACTION_GROUP, GRemoteActionGroupInterface)
+  _CLASS_INTERFACE(RemoteActionGroup, GRemoteActionGroup, G_REMOTE_ACTION_GROUP, GRemoteActionGroupInterface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(void activate_action(const Glib::ustring& action_name, const Glib::VariantBase& parameter, const Glib::VariantBase& platform_data), g_remote_action_group_activate_action_full)
   _WRAP_METHOD(void change_action_state(const Glib::ustring& action_name, const Glib::VariantBase& value, const Glib::VariantBase& platform_data), g_remote_action_group_change_action_state_full)
 
-protected:
 #m4 _CONVERSION(`GVariant*',`const Glib::VariantBase&',`Glib::wrap($3, true)')
-  _WRAP_VFUNC(void activate_action_full(const Glib::ustring& action_name, const Glib::VariantBase& parameter, const Glib::VariantBase& platform_data), "activate_action_full")
-  _WRAP_VFUNC(void change_action_state_full(const Glib::ustring& action_name, const Glib::VariantBase& value, const Glib::VariantBase& platform_data), "change_action_state_full")
+
+  _WRAP_VFUNC(void activate_action(const Glib::ustring& action_name, const Glib::VariantBase& parameter, const Glib::VariantBase& platform_data), "activate_action_full")
+  _WRAP_VFUNC(void change_action_state(const Glib::ustring& action_name, const Glib::VariantBase& value, const Glib::VariantBase& platform_data), "change_action_state_full")
 };
 
 } // namespace Gio
index 6efdf6b..77b6f5e 100644 (file)
 #include <glibmm/error.h>
 #include "slot_async.h"
 
-namespace {
-
-struct SrvTargetListTraits
-{
-  using CppType = Gio::SrvTarget;
-  using CType = const GSrvTarget*;
-  using CTypeNonConst = GSrvTarget*;
-
-  static CType to_c_type(const CppType& item) { return item.gobj(); }
-  static CType to_c_type(CType ptr) { return ptr; }
-  static CppType to_cpp_type(CType item) { return CppType(const_cast<CTypeNonConst>(item), true /* take_copy */); }
-  static void release_c_type(CType item) { g_srv_target_free(const_cast<CTypeNonConst>(item)); }
-};
-
-} // anonymous namespace
-
 namespace Gio
 {
 
@@ -110,7 +94,7 @@ Resolver::lookup_service_async(const Glib::ustring& service, const Glib::ustring
 }
 
 void
-Resolver::lookup_records_async(const Glib::ustring& rrname, RecordType record_type,
+Resolver::lookup_records_async(const Glib::ustring& rrname, ResolverRecordType record_type,
   const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable)
 {
   auto slot_copy = new SlotAsyncReady(slot);
@@ -122,7 +106,7 @@ Resolver::lookup_records_async(const Glib::ustring& rrname, RecordType record_ty
 
 void
 Resolver::lookup_records_async(
-  const Glib::ustring& rrname, RecordType record_type, const SlotAsyncReady& slot)
+  const Glib::ustring& rrname, ResolverRecordType record_type, const SlotAsyncReady& slot)
 {
   auto slot_copy = new SlotAsyncReady(slot);
 
index 52d7fe2..599ecb9 100644 (file)
@@ -28,13 +28,15 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Glib
 {
 
-class VariantContainerBase;
+class GLIBMM_API VariantContainerBase;
 
 }
 
 namespace Gio
 {
 
+_WRAP_ENUM(ResolverRecordType, GResolverRecordType)
+
 /** Asynchronous and cancellable DNS resolver
  *
  * Resolver provides cancellable synchronous and asynchronous DNS resolution,
@@ -48,16 +50,14 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class Resolver
+class GIOMM_API Resolver
 : public Glib::Object
 {
-  _CLASS_GOBJECT(Resolver, GResolver, G_RESOLVER, Glib::Object, GObject)
+  _CLASS_GOBJECT(Resolver, GResolver, G_RESOLVER, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
 
 public:
-  _WRAP_ENUM(RecordType, GResolverRecordType)
-
   static Glib::RefPtr<Resolver> get_default();
   _IGNORE(g_resolver_get_default)
   static void set_default(const Glib::RefPtr<Resolver>& resolver);
@@ -66,8 +66,8 @@ public:
   // g_resolver_free_addresses is just a C convenience function
   _IGNORE(g_resolver_free_addresses)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<InetAddress>>',`Glib::ListHandler<Glib::RefPtr<InetAddress>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<InetAddress>> lookup_by_name(const Glib::ustring& hostname, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_by_name, errthrow)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<InetAddress> >',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<InetAddress> > lookup_by_name(const Glib::ustring& hostname, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_by_name, errthrow)
 
   /** Begins asynchronously resolving hostname to determine its associated IP address(es), and eventually calls @a slot, which must call
    * lookup_by_name_finish() to get the result. See lookup_by_name() for more details.
@@ -87,7 +87,7 @@ public:
   void lookup_by_name_async(const Glib::ustring& hostname, const SlotAsyncReady& slot);
   _IGNORE(g_resolver_lookup_by_name_async)
 
-  _WRAP_METHOD(std::vector<Glib::RefPtr<InetAddress>> lookup_by_name_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_by_name_finish, errthrow)
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<InetAddress> > lookup_by_name_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_by_name_finish, errthrow)
 
   _WRAP_METHOD(Glib::ustring lookup_by_address(const Glib::RefPtr<InetAddress>& address, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_by_address, errthrow)
 
@@ -111,8 +111,8 @@ public:
 
   _WRAP_METHOD(Glib::ustring lookup_by_address_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_by_address_finish, errthrow)
 
-#m4 _CONVERSION(`GList*',`std::vector<SrvTarget>',`Glib::ListHandler<SrvTarget, SrvTargetListTraits>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<SrvTarget> lookup_service(const Glib::ustring& service, const Glib::ustring& protocol, const Glib::ustring& domain, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_service, errthrow)
+#m4 _CONVERSION(`GList*',`ListHandle_SrvTarget',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(ListHandle_SrvTarget lookup_service(const Glib::ustring& service, const Glib::ustring& protocol, const Glib::ustring& domain, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_service, errthrow)
 
   /** Begins asynchronously performing a DNS SRV lookup for the given service and protocol in the given domain, and eventually calls callback,
    * which must call lookup_service_finish() to get the final result. See glookup_service() for more details.
@@ -136,11 +136,11 @@ public:
   void lookup_service_async(const Glib::ustring& service, const Glib::ustring& protocol, const Glib::ustring& domain, const SlotAsyncReady& slot);
   _IGNORE(g_resolver_lookup_service_async)
 
-  _WRAP_METHOD(std::vector<SrvTarget> lookup_service_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_service_finish, errthrow)
+  _WRAP_METHOD(ListHandle_SrvTarget lookup_service_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_service_finish, errthrow)
 
 #m4 _CONVERSION(`GList*',`std::vector<Glib::VariantContainerBase>',`Glib::ListHandler<Glib::VariantContainerBase>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
 
-  _WRAP_METHOD(std::vector<Glib::VariantContainerBase> lookup_records(const Glib::ustring& rrname, RecordType record_type, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_records, errthrow)
+  _WRAP_METHOD(std::vector<Glib::VariantContainerBase> lookup_records(const Glib::ustring& rrname, ResolverRecordType record_type, const Glib::RefPtr<Cancellable>& cancellable{?}), g_resolver_lookup_records, errthrow)
 
   /** Begins asynchronously performing a DNS lookup for the given @a rrname,
    * and eventually calls @a slot, which must call lookup_records_finish() to
@@ -153,23 +153,33 @@ public:
    * @newin{2,36}
    */
   void lookup_records_async(const Glib::ustring& rrname,
-    RecordType record_type, const SlotAsyncReady& slot,
+    ResolverRecordType record_type, const SlotAsyncReady& slot,
     const Glib::RefPtr<Cancellable>& cancellable);
   _IGNORE(g_resolver_lookup_records_async)
 
   /// A non-cancellable version of lookup_records_async().
   void lookup_records_async(const Glib::ustring& rrname,
-    RecordType record_type, const SlotAsyncReady& slot);
+    ResolverRecordType record_type, const SlotAsyncReady& slot);
 
   _WRAP_METHOD(std::vector<Glib::VariantContainerBase> lookup_records_finish(const Glib::RefPtr<AsyncResult>& result), g_resolver_lookup_records_finish, errthrow)
 
-  _WRAP_SIGNAL(void reload(), reload)
+  //TODO: Remove no_default_handler when we can break ABI:
+  _WRAP_SIGNAL(void reload(), reload, no_default_handler)
 };
 
+GIOMM_API
 std::string hostname_to_ascii (const Glib::ustring& hostname);
+
+GIOMM_API
 Glib::ustring hostname_to_unicode (const Glib::ustring& hostname);
+
+GIOMM_API
 bool hostname_is_non_ascii (const Glib::ustring& hostname);
+
+GIOMM_API
 bool hostname_is_ascii_encoded (const Glib::ustring& hostname);
+
+GIOMM_API
 bool hostname_is_ip_address (const Glib::ustring& hostname);
 
 } // namespace Gio
index d8305b3..78479de 100644 (file)
 
 namespace Gio
 {
-// Hand-coded because we want Flags& instead of guint32&.
+// Hand-coded because we want ResourceFlags& instead of guint32&.
 void
-Resource::get_info(const std::string& path, gsize& size, Flags& flags,
-  LookupFlags lookup_flags) const
+Resource::get_info(const std::string& path, gsize& size, ResourceFlags& flags,
+  ResourceLookupFlags lookup_flags) const
 {
   guint32 file_flags = 0;
   GError* gerror = nullptr;
@@ -31,11 +31,11 @@ Resource::get_info(const std::string& path, gsize& size, Flags& flags,
     (GResourceLookupFlags)lookup_flags, &size, &file_flags, &gerror);
   if (gerror)
     ::Glib::Error::throw_exception(gerror);
-  flags = static_cast<Flags>(file_flags);
+  flags = static_cast<ResourceFlags>(file_flags);
 }
 
 void
-Resource::get_file_exists(const std::string& path, LookupFlags lookup_flags) const
+Resource::get_file_exists(const std::string& path, ResourceLookupFlags lookup_flags) const
 {
   GError* gerror = nullptr;
   g_resource_get_info(const_cast<GResource*>(gobj()), path.c_str(),
@@ -45,17 +45,17 @@ Resource::get_file_exists(const std::string& path, LookupFlags lookup_flags) con
 }
 
 bool
-Resource::get_file_exists_nothrow(const std::string& path, LookupFlags lookup_flags) const
+Resource::get_file_exists_nothrow(const std::string& path, ResourceLookupFlags lookup_flags) const
 {
   return g_resource_get_info(const_cast<GResource*>(gobj()), path.c_str(),
     (GResourceLookupFlags)lookup_flags, nullptr, nullptr, nullptr);
 }
 
-// Hand-coded because we want Flags& instead of guint32&.
+// Hand-coded because we want ResourceFlags& instead of guint32&.
 // static
 void
 Resource::get_info_global(
-  const std::string& path, gsize& size, Flags& flags, LookupFlags lookup_flags)
+  const std::string& path, gsize& size, ResourceFlags& flags, ResourceLookupFlags lookup_flags)
 {
   guint32 file_flags = 0;
   GError* gerror = nullptr;
@@ -65,12 +65,12 @@ Resource::get_info_global(
     path.c_str(), (GResourceLookupFlags)lookup_flags, &size, &file_flags, &gerror);
   if (gerror)
     ::Glib::Error::throw_exception(gerror);
-  flags = static_cast<Flags>(file_flags);
+  flags = static_cast<ResourceFlags>(file_flags);
 }
 
 // static
 void
-Resource::get_file_exists_global(const std::string& path, LookupFlags lookup_flags)
+Resource::get_file_exists_global(const std::string& path, ResourceLookupFlags lookup_flags)
 {
   GError* gerror = nullptr;
   g_resources_get_info(path.c_str(), (GResourceLookupFlags)lookup_flags, nullptr, nullptr, &gerror);
@@ -80,7 +80,7 @@ Resource::get_file_exists_global(const std::string& path, LookupFlags lookup_fla
 
 // static
 bool
-Resource::get_file_exists_global_nothrow(const std::string& path, LookupFlags lookup_flags)
+Resource::get_file_exists_global_nothrow(const std::string& path, ResourceLookupFlags lookup_flags)
 {
   return g_resources_get_info(
     path.c_str(), (GResourceLookupFlags)lookup_flags, nullptr, nullptr, nullptr);
index fda236b..8885514 100644 (file)
@@ -32,7 +32,10 @@ namespace Gio
 
 /** Exception class for resource file handling errors.
  */
-_WRAP_GERROR(ResourceError, GResourceError, G_RESOURCE_ERROR, NO_GTYPE, newin "2,34")
+_WRAP_GERROR(ResourceError, GResourceError, G_RESOURCE_ERROR, NO_GTYPE, newin "2,34", decl_prefix GIOMM_API)
+
+_WRAP_ENUM(ResourceFlags, GResourceFlags, newin "2,44")
+_WRAP_ENUM(ResourceLookupFlags, GResourceLookupFlags, newin "2,44")
 
 /** %Resource framework.
  *
@@ -124,22 +127,19 @@ _WRAP_GERROR(ResourceError, GResourceError, G_RESOURCE_ERROR, NO_GTYPE, newin "2
  *
  * @newin{2,44}
  */
-class Resource final
+class GIOMM_API Resource final
 {
-  _CLASS_OPAQUE_REFCOUNTED(Resource, GResource, NONE, g_resource_ref, g_resource_unref)
+  _CLASS_OPAQUE_REFCOUNTED(Resource, GResource, NONE, g_resource_ref, g_resource_unref, GIOMM_API)
   _IGNORE(g_resource_ref, g_resource_unref)
 
 public:
-  _WRAP_ENUM(Flags, GResourceFlags, newin "2,44")
-  _WRAP_ENUM(LookupFlags, GResourceLookupFlags, newin "2,44")
-
-  _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_data(const Glib::RefPtr<const Glib::Bytes>& data), g_resource_new_from_data, errthrow "Glib::FileError", newin "2,44")
-  _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_file(const std::string& filename), g_resource_load, errthrow "Glib::FileError", newin "2,44")
-  _WRAP_METHOD(Glib::RefPtr<InputStream> open_stream(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE) const, g_resource_open_stream, errthrow "Gio::ResourceError", newin "2,44")
-  _WRAP_METHOD(Glib::RefPtr<const Glib::Bytes> lookup_data(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE) const, g_resource_lookup_data, errthrow "Gio::ResourceError", newin "2,44")
+  _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_data(const Glib::RefPtr<const Glib::Bytes>& data), g_resource_new_from_data, errthrow, newin "2,44")
+  _WRAP_METHOD(static Glib::RefPtr<Resource> create_from_file(const std::string& filename), g_resource_load, errthrow, newin "2,44")
+  _WRAP_METHOD(Glib::RefPtr<InputStream> open_stream(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_open_stream, errthrow, newin "2,44")
+  _WRAP_METHOD(Glib::RefPtr<const Glib::Bytes> lookup_data(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_lookup_data, errthrow, newin "2,44")
 
 #m4 _CONVERSION(`char**',`std::vector<std::string>',`Glib::ArrayHandler<std::string>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<std::string> enumerate_children(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE) const, g_resource_enumerate_children, errthrow "Gio::ResourceError", newin "2,44")
+  _WRAP_METHOD(std::vector<std::string> enumerate_children(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const, g_resource_enumerate_children, errthrow, newin "2,44")
 
   /** Looks for a file at the specified @a path in the resource and
    * if found returns information about it.
@@ -151,10 +151,10 @@ public:
    * @param path A pathname inside the resource.
    * @param[out] size A location to place the length of the contents of the file.
    * @param[out] flags A location to place the flags about the file.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @throw Gio::ResourceError if the file was not found.
    */
-  void get_info(const std::string& path, gsize& size, Flags& flags, LookupFlags lookup_flags = LookupFlags::NONE) const;
+  void get_info(const std::string& path, gsize& size, ResourceFlags& flags, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const;
   _IGNORE(g_resource_get_info)
 
   /** Looks for a file at the specified @a path in the resource.
@@ -164,10 +164,10 @@ public:
    * @newin{2,44}
    *
    * @param path A pathname inside the resource.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @throw Gio::ResourceError if the file was not found.
    */
-  void get_file_exists(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE) const;
+  void get_file_exists(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const;
 
   /** Looks for a file at the specified @a path in the resource.
    *
@@ -177,17 +177,17 @@ public:
    * @newin{2,44}
    *
    * @param path A pathname inside the resource.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @return <tt>true</tt> if the file was found, <tt>false</tt> if there were errors.
    */
-  bool get_file_exists_nothrow(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE) const;
+  bool get_file_exists_nothrow(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE) const;
 
   // 'register' is a keyword. Can't be the name of a method.
   _WRAP_METHOD(void register_global(), g_resources_register, newin "2,44")
   _WRAP_METHOD(void unregister_global(), g_resources_unregister, newin "2,44")
-  _WRAP_METHOD(static Glib::RefPtr<InputStream> open_stream_global(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE), g_resources_open_stream, errthrow "Gio::ResourceError", newin "2,44")
-  _WRAP_METHOD(static Glib::RefPtr<const Glib::Bytes> lookup_data_global(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE), g_resources_lookup_data, errthrow "Gio::ResourceError", newin "2,44")
-  _WRAP_METHOD(static std::vector<std::string> enumerate_children_global(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE), g_resources_enumerate_children, errthrow "Gio::ResourceError", newin "2,44")
+  _WRAP_METHOD(static Glib::RefPtr<InputStream> open_stream_global(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_open_stream, errthrow, newin "2,44")
+  _WRAP_METHOD(static Glib::RefPtr<const Glib::Bytes> lookup_data_global(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_lookup_data, errthrow, newin "2,44")
+  _WRAP_METHOD(static std::vector<std::string> enumerate_children_global(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE), g_resources_enumerate_children, errthrow, newin "2,44")
 
   /** Looks for a file at the specified @a path in the set of
    * globally registered resources and if found returns information about it.
@@ -199,10 +199,10 @@ public:
    * @param path A pathname inside the resource.
    * @param[out] size A location to place the length of the contents of the file.
    * @param[out] flags A location to place the flags about the file.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @throw Gio::ResourceError if the file was not found.
    */
-  static void get_info_global(const std::string& path, gsize& size, Flags& flags, LookupFlags lookup_flags = LookupFlags::NONE);
+  static void get_info_global(const std::string& path, gsize& size, ResourceFlags& flags, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE);
   _IGNORE(g_resources_get_info)
 
   /** Looks for a file at the specified @a path in the set of
@@ -213,10 +213,10 @@ public:
    * @newin{2,44}
    *
    * @param path A pathname inside the resource.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @throw Gio::ResourceError if the file was not found.
    */
-  static void get_file_exists_global(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE);
+  static void get_file_exists_global(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE);
 
   /** Looks for a file at the specified @a path in the set of
    * globally registered resources.
@@ -227,10 +227,10 @@ public:
    * @newin{2,44}
    *
    * @param path A pathname inside the resource.
-   * @param lookup_flags A LookupFlags.
+   * @param lookup_flags A ResourceLookupFlags.
    * @return <tt>true</tt> if the file was found, <tt>false</tt> if there were errors.
    */
-  static bool get_file_exists_global_nothrow(const std::string& path, LookupFlags lookup_flags = LookupFlags::NONE);
+  static bool get_file_exists_global_nothrow(const std::string& path, ResourceLookupFlags lookup_flags = RESOURCE_LOOKUP_FLAGS_NONE);
 
   _IGNORE(g_static_resource_init, g_static_resource_fini, g_static_resource_get_resource)dnl//Used only by the glib-compile-resources command
 };
index f32f90d..1749bf7 100644 (file)
@@ -41,9 +41,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class Seekable : public Glib::Interface
+class GIOMM_API Seekable : public Glib::Interface
 {
-  _CLASS_INTERFACE(Seekable, GSeekable, G_SEEKABLE, GSeekableIface)
+  _CLASS_INTERFACE(Seekable, GSeekable, G_SEEKABLE, GSeekableIface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(goffset tell() const, g_seekable_tell)
@@ -59,7 +59,6 @@ public:
 
   //TODO: Document the exception in the C API: https://bugzilla.gnome.org/show_bug.cgi?id=509990#c1
 
-protected:
   //_WRAP_VFUNC(goffset tell() const, tell)
   //_WRAP_VFUNC(goffset can_seek() const, can_seek)
   //_WRAP_VFUNC(goffset seek(goffset offset, Glib::SeekType type, const Glib::RefPtr<Cancellable>& cancellable, GError** error), seek)
index 05ff5e2..5ec3391 100644 (file)
@@ -54,7 +54,7 @@ Settings::get_default_value(const Glib::ustring& key, Glib::VariantBase& value)
 }
 void
 Settings::bind(
-  const Glib::ustring& key, const Glib::PropertyProxy_Base& property_proxy, BindFlags flags)
+  const Glib::ustring& key, const Glib::PropertyProxy_Base& property_proxy, SettingsBindFlags flags)
 {
   bind(key, property_proxy.get_object(), property_proxy.get_name(), flags);
 }
@@ -66,4 +66,14 @@ Settings::bind_writable(
   bind_writable(key, property_proxy.get_object(), property_proxy.get_name(), inverted);
 }
 
+_DEPRECATE_IFDEF_START
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+std::vector<Glib::ustring>
+Settings::list_schemas()
+{
+  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(
+    g_settings_list_schemas(), Glib::OWNERSHIP_NONE);
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+_DEPRECATE_IFDEF_END
 }
index 8c0a57b..b335881 100644 (file)
@@ -16,6 +16,7 @@
 
 _CONFIGINCLUDE(giommconfig.h)
 
+#include <glibmm/arrayhandle.h>
 #include <glibmm/object.h>
 #include <glibmm/variant.h>
 #include <giomm/action.h>
@@ -25,7 +26,9 @@ _PINCLUDE(glibmm/private/object_p.h)
 
 namespace Gio
 {
-class SettingsSchema;
+class GIOMM_API SettingsSchema;
+
+  _WRAP_ENUM(SettingsBindFlags, GSettingsBindFlags)
 
 /** A high-level API for application settings
  *
@@ -34,26 +37,21 @@ class SettingsSchema;
  *
  * @newin{2,28}
  */
-class Settings : public Glib::Object
+class GIOMM_API Settings : public Glib::Object
 {
-  _CLASS_GOBJECT(Settings, GSettings, G_SETTINGS, Glib::Object, GObject)
-
-public:
-  _WRAP_ENUM(BindFlags, GSettingsBindFlags)
+  _CLASS_GOBJECT(Settings, GSettings, G_SETTINGS, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _WRAP_CTOR(Settings(const Glib::ustring& schema_id), g_settings_new)
   _WRAP_CTOR(Settings(const Glib::ustring& schema_id, const Glib::ustring& path), g_settings_new_with_path)
   //TODO: Requires SettingsBackend: _WRAP_CTOR(Settings(const Glib::ustring& schema_id, const Glib::RefPtr<SettingsBackend>& backend), g_settings_new_with_backend)
   //TODO: Requires SettingsBackend: _WRAP_CTOR(Settings(const Glib::ustring& schema_id, const Glib::RefPtr<SettingsBackend>& backend, const Glib::ustring& path), g_settings_new_with_backend_and_path)
-  //TODO: Requires SettingsBackend: _WRAP_CTOR(Settings(const Glib::RefPtr<SettingsSchema>& settings_schema, const Glib::RefPtr<SettingsBackend>& backend, const Glib::ustring& path), g_settings_new_full)
 
 public:
   _WRAP_CREATE(const Glib::ustring& schema_id)
   _WRAP_CREATE(const Glib::ustring& schema_id, const Glib::ustring& path)
   //TODO: Requires SettingsBackend: _WRAP_CREATE(const Glib::ustring& schema_id, const Glib::RefPtr<SettingsBackend>& backend)
   //TODO: Requires SettingsBackend: _WRAP_CREATE(const Glib::ustring& schema_id, const Glib::RefPtr<SettingsBackend>& backend, const Glib::ustring& path)
-  //TODO: Requires SettingsBackend: _WRAP_CREATE(const Glib::RefPtr<SettingsSchema>& settings_schema, const Glib::RefPtr<SettingsBackend>& backend, const Glib::ustring& path)
 
   //TODO: Rename these to get/set_*_value_variant() and add templated get/set_*_value() methods as elsewhere?
   _WRAP_METHOD(bool set_value(const Glib::ustring& key, const Glib::VariantBase& value),  g_settings_set_value)
@@ -134,28 +132,33 @@ public:
   _IGNORE(g_settings_get_default_value)
 
   _WRAP_METHOD(int get_int(const Glib::ustring& key) const, g_settings_get_int)
-  _WRAP_METHOD(bool set_int(const Glib::ustring& key, int value), g_settings_set_int)
+  _WRAP_METHOD(void set_int(const Glib::ustring& key, int value), g_settings_set_int)
   _WRAP_METHOD(gint64 get_int64(const Glib::ustring& key) const, g_settings_get_int64)
-  _WRAP_METHOD(bool set_int64(const Glib::ustring& key, gint64 value), g_settings_set_int64)
+  _WRAP_METHOD(void set_int64(const Glib::ustring& key, gint64 value), g_settings_set_int64)
   _WRAP_METHOD(guint get_uint(const Glib::ustring& key) const, g_settings_get_uint)
-  _WRAP_METHOD(bool set_uint(const Glib::ustring& key, guint value), g_settings_set_uint)
+  _WRAP_METHOD(void set_uiint(const Glib::ustring& key, guint value), g_settings_set_uint, deprecated "Use set_uint() instead.")
+  _WRAP_METHOD(void set_uint(const Glib::ustring& key, guint value), g_settings_set_uint)
   _WRAP_METHOD(guint64 get_uint64(const Glib::ustring& key) const, g_settings_get_uint64)
-  _WRAP_METHOD(bool set_uint64(const Glib::ustring& key, guint64 value), g_settings_set_uint64)
+  _WRAP_METHOD(void set_uint64(const Glib::ustring& key, guint64 value), g_settings_set_uint64)
   _WRAP_METHOD(bool get_boolean(const Glib::ustring& key) const, g_settings_get_boolean)
-  _WRAP_METHOD(bool set_boolean(const Glib::ustring& key, bool value), g_settings_set_boolean)
+  _WRAP_METHOD(void set_boolean(const Glib::ustring& key, bool value), g_settings_set_boolean)
   _WRAP_METHOD(Glib::ustring get_string(const Glib::ustring& key) const, g_settings_get_string)
-  _WRAP_METHOD(bool set_string(const Glib::ustring& key, const Glib::ustring& value), g_settings_set_string)
+  _WRAP_METHOD(void set_string(const Glib::ustring& key, const Glib::ustring& value), g_settings_set_string)
   _WRAP_METHOD(double get_double(const Glib::ustring& key) const, g_settings_get_double)
-  _WRAP_METHOD(bool set_double(const Glib::ustring& key, double value), g_settings_set_double)
+  _WRAP_METHOD(void set_double(const Glib::ustring& key, double value), g_settings_set_double)
 
-  #m4 _CONVERSION(`gchar**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> get_string_array(const Glib::ustring& key) const, g_settings_get_strv)
+  #m4 _CONVERSION(`gchar**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle get_string_array(const Glib::ustring& key) const, g_settings_get_strv)
 
-  _WRAP_METHOD(bool set_string_array(const Glib::ustring& key, const std::vector<Glib::ustring>& value), g_settings_set_strv)
+  _WRAP_METHOD(bool set_string_array(const Glib::ustring& key,  const Glib::StringArrayHandle& value), g_settings_set_strv)
 
   _WRAP_METHOD(int get_enum(const Glib::ustring& key) const, g_settings_get_enum)
+  _WRAP_METHOD(bool get_enum(const Glib::ustring& key, int value), g_settings_set_enum,
+    deprecated "This method is misnamed. Use set_enum() instead.")
   _WRAP_METHOD(bool set_enum(const Glib::ustring& key, int value), g_settings_set_enum)
   _WRAP_METHOD(guint get_flags(const Glib::ustring& key) const, g_settings_get_flags)
+  _WRAP_METHOD(bool get_flags(const Glib::ustring& key, guint value), g_settings_set_flags,
+    deprecated "This method is misnamed. Use set_flags() instead.")
   _WRAP_METHOD(bool set_flags(const Glib::ustring& key, guint value), g_settings_set_flags)
 
   // Ignore varargs functions.
@@ -172,17 +175,27 @@ public:
 
   _WRAP_METHOD(void reset(const Glib::ustring& key), g_settings_reset)
 
+_DEPRECATE_IFDEF_START
+//We must hand-code this because gmmproc is confused by the static keyword with the vector.
+//#m4 _CONVERSION(`const gchar*const*',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
+  _WRAP_METHOD_DOCS_ONLY(g_settings_list_schemas)
+  static std::vector<Glib::ustring> list_schemas();
+  _IGNORE(g_settings_list_schemas)
+_DEPRECATE_IFDEF_END
+
 #m4 _CONVERSION(`gchar**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(std::vector<Glib::ustring> list_children() const, g_settings_list_children)
-  _IGNORE(g_settings_list_keys)
+  _WRAP_METHOD(std::vector<Glib::ustring> list_keys() const, g_settings_list_keys, deprecated "Use SettingsSchema::list_keys().")
 
   _IGNORE(g_settings_get_range, g_settings_list_relocatable_schemas) // deprecated
 
-  _IGNORE(g_settings_range_check)
+  _WRAP_METHOD(bool range_check(const Glib::ustring& key, const Glib::VariantBase& value) const, g_settings_range_check,
+    deprecated "Use g_settings_schema_key_range_check() instead.")
+  //TODO: Wrap GSettingsSchema
 
 #m4 _CONVERSION(`Glib::ObjectBase*',`gpointer',(gpointer)$3->gobj())
-  _WRAP_METHOD(void bind(const Glib::ustring& key, Glib::ObjectBase* object, const Glib::ustring& property, BindFlags flags = BindFlags::DEFAULT), g_settings_bind)
-  void bind(const Glib::ustring& key, const Glib::PropertyProxy_Base& property_proxy, BindFlags flags = BindFlags::DEFAULT);
+  _WRAP_METHOD(void bind(const Glib::ustring& key, Glib::ObjectBase* object, const Glib::ustring& property, SettingsBindFlags flags=SETTINGS_BIND_DEFAULT), g_settings_bind)
+  void bind(const Glib::ustring& key, const Glib::PropertyProxy_Base& property_proxy, SettingsBindFlags flags=SETTINGS_BIND_DEFAULT);
   // TODO: implement bind_with_mapping
   _WRAP_METHOD(void bind_writable(const Glib::ustring& key, Glib::ObjectBase* object, const Glib::ustring& property, bool inverted=false), g_settings_bind_writable)
   void bind_writable(const Glib::ustring& key, const Glib::PropertyProxy_Base& property_proxy, bool inverted=false);
@@ -195,18 +208,19 @@ public:
   _WRAP_PROPERTY("delay-apply", bool)
   _WRAP_PROPERTY("has-unapplied", bool)
   _WRAP_PROPERTY("path", std::string)
-  _IGNORE_PROPERTY("schema")
+  _WRAP_PROPERTY("schema", Glib::ustring, deprecated "Use the 'schema-id' property instead. In a future version, this property may instead refer to a SettingsSchema.")
   _WRAP_PROPERTY("schema-id", Glib::ustring)
 
-  _WRAP_PROPERTY("settings-schema", Glib::RefPtr<SettingsSchema>, newin "2,58")
+  _WRAP_PROPERTY("settings-schema", Glib::RefPtr<SettingsSchema>, newin "2,60")
 
-  //TODO?: _WRAP_SIGNAL(bool change_event(const std::vector<Glib::QueryQuark>&  keys, int n_keys), "change-event")
+  //TODO?: _WRAP_SIGNAL(bool change_event(const Glib::ArrayHandle<Glib::QueryQuark>& keys, int n_keys), "change-event")
 
+  //TODO: Remove two_signal_methods when we can break ABI.
 #m4 _CONVERSION(`const char*',`const Glib::ustring&',__GCHARP_TO_USTRING)
-  _WRAP_SIGNAL(void changed(const Glib::ustring& key), "changed", detail_name key)
+  _WRAP_SIGNAL(void changed(const Glib::ustring& key), "changed", detail_name key, two_signal_methods)
 
   _WRAP_SIGNAL(bool writable_change_event(GQuark key), "writable-change-event")
-  _WRAP_SIGNAL(void writable_changed(const Glib::ustring& key), writable_changed, detail_name key)
+  _WRAP_SIGNAL(void writable_changed(const Glib::ustring& key), writable_changed, detail_name key, two_signal_methods)
 };
 
 } // namespace Gio
index 0be3671..4bd9d59 100644 (file)
@@ -17,6 +17,7 @@
 _CONFIGINCLUDE(giommconfig.h)
 
 #include <giomm/settingsschemakey.h>
+#include <glibmm/arrayhandle.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -50,9 +51,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class SettingsSchema final
+class GIOMM_API SettingsSchema final
 {
-  _CLASS_OPAQUE_REFCOUNTED(SettingsSchema, GSettingsSchema, NONE, g_settings_schema_ref, g_settings_schema_unref)
+  _CLASS_OPAQUE_REFCOUNTED(SettingsSchema, GSettingsSchema, NONE, g_settings_schema_ref, g_settings_schema_unref, GIOMM_API)
   _IS_REFCOUNTED_BOXEDTYPE
 
 protected:
index 4734ca0..49bcf41 100644 (file)
@@ -35,9 +35,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class SettingsSchemaKey final
+class GIOMM_API SettingsSchemaKey final
 {
-  _CLASS_OPAQUE_REFCOUNTED(SettingsSchemaKey, GSettingsSchemaKey, NONE, g_settings_schema_key_ref, g_settings_schema_key_unref)
+  _CLASS_OPAQUE_REFCOUNTED(SettingsSchemaKey, GSettingsSchemaKey, NONE, g_settings_schema_key_ref, g_settings_schema_key_unref, GIOMM_API)
 
 protected:
   _IGNORE(g_settings_schema_key_ref, g_settings_schema_key_unref)
index 5975c38..536fe5b 100644 (file)
@@ -34,9 +34,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class SettingsSchemaSource final
+class GIOMM_API SettingsSchemaSource final
 {
-  _CLASS_OPAQUE_REFCOUNTED(SettingsSchemaSource, GSettingsSchemaSource, NONE, g_settings_schema_source_ref, g_settings_schema_source_unref)
+  _CLASS_OPAQUE_REFCOUNTED(SettingsSchemaSource, GSettingsSchemaSource, NONE, g_settings_schema_source_ref, g_settings_schema_source_unref, GIOMM_API)
 
 protected:
   _IGNORE(g_settings_schema_source_ref, g_settings_schema_source_unref)
index 5874112..6e1445c 100644 (file)
@@ -37,9 +37,9 @@ namespace Gio
  *
  * @newin{2,32}
  */
-class SimpleAction : public Glib::Object, public Action
+class GIOMM_API SimpleAction : public Glib::Object, public Action
 {
-  _CLASS_GOBJECT(SimpleAction, GSimpleAction, G_SIMPLE_ACTION, Glib::Object, GObject)
+  _CLASS_GOBJECT(SimpleAction, GSimpleAction, G_SIMPLE_ACTION, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Action)
   _STRUCT_NOT_HIDDEN
 
index d12e4a1..1e60d7d 100644 (file)
@@ -25,7 +25,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class Action;
+class GIOMM_API Action;
 
 /** SimpleActionGroup - A simple ActionGroup implementation.
  * SimpleActionGroup is a hash table filled with Action objects, implementing
@@ -33,11 +33,11 @@ class Action;
  *
  * @newin{2,32}
  */
-class SimpleActionGroup : public Glib::Object,
-                          public ActionGroup,
-                          public ActionMap
+class GIOMM_API SimpleActionGroup : public Glib::Object,
+                                    public ActionGroup,
+                                    public ActionMap
 {
-  _CLASS_GOBJECT(SimpleActionGroup, GSimpleActionGroup, G_SIMPLE_ACTION_GROUP, Glib::Object, GObject)
+  _CLASS_GOBJECT(SimpleActionGroup, GSimpleActionGroup, G_SIMPLE_ACTION_GROUP, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(ActionGroup)
   _IMPLEMENTS_INTERFACE(ActionMap)
 
@@ -48,7 +48,11 @@ public:
   _WRAP_METHOD_DOCS_ONLY(g_simple_action_group_new)
   _WRAP_CREATE()
 
-  _IGNORE(g_simple_action_group_lookup, g_simple_action_group_insert, g_simple_action_group_remove)
+  _WRAP_METHOD(Glib::RefPtr<Action> lookup(const Glib::ustring& action_name), g_simple_action_group_lookup, refreturn, deprecated "Use ActionMap::lookup_action() instead")
+  _WRAP_METHOD(Glib::RefPtr<const Action> lookup(const Glib::ustring& action_name) const, g_simple_action_group_lookup, refreturn, constversion, deprecated "Use ActionMap::lookup_action() instead")
+
+  _WRAP_METHOD(void insert(const Glib::RefPtr<Action>& action), g_simple_action_group_insert, deprecated "Use ActionMap::add_action() instead")
+  _WRAP_METHOD(void remove(const Glib::ustring& action_name), g_simple_action_group_remove, deprecated "Use ActionMap::remove_action() instead")
 
   _IGNORE(g_simple_action_group_add_entries) // deprecated
 };
index e510649..af5714d 100644 (file)
@@ -36,9 +36,9 @@ namespace Gio
  *
  * @newin{2,46}
  */
-class SimpleIOStream : public Gio::IOStream
+class GIOMM_API SimpleIOStream : public Gio::IOStream
 {
-  _CLASS_GOBJECT(SimpleIOStream, GSimpleIOStream, G_SIMPLE_IO_STREAM, Gio::IOStream, GIOStream)
+  _CLASS_GOBJECT(SimpleIOStream, GSimpleIOStream, G_SIMPLE_IO_STREAM, Gio::IOStream, GIOStream, , , GIOMM_API)
 
 protected:
   /** Creates a new SimpleIOStream wrapping @a input_stream and @a output_stream.
index cce3b6b..21dab98 100644 (file)
@@ -31,9 +31,9 @@ namespace Gio
  * Calling Permission::acquire() or Permission::release() will result
  * in errors.
  */
-class SimplePermission : public Permission
+class GIOMM_API SimplePermission : public Permission
 {
-  _CLASS_GOBJECT(SimplePermission, GSimplePermission, G_SIMPLE_PERMISSION, Gio::Permission, GPermission)
+  _CLASS_GOBJECT(SimplePermission, GSimplePermission, G_SIMPLE_PERMISSION, Gio::Permission, GPermission, , , GIOMM_API)
 
 protected:
 
index 31cf240..767882e 100644 (file)
 #include <giomm/socketsource.h>
 #include "slot_async.h"
 
-using Type = Gio::Socket::Type;
-using Protocol = Gio::Socket::Protocol;
-
 namespace Gio
 {
 
-Socket::Socket(SocketFamily family, Type type, Protocol protocol,
+Socket::Socket(SocketFamily family, SocketType type, SocketProtocol protocol,
   const Glib::RefPtr<Cancellable>& cancellable)
 : _CONSTRUCT("family", int(family), "type", int(type), "protocol", int(protocol))
 {
@@ -40,17 +37,17 @@ Socket::Socket(int fd, const Glib::RefPtr<Cancellable>& cancellable) : _CONSTRUC
 
 // static
 Glib::RefPtr<Socket>
-Socket::create(SocketFamily family, Type type, Protocol protocol,
+Socket::create(SocketFamily family, SocketType type, SocketProtocol protocol,
   const Glib::RefPtr<Cancellable>& cancellable)
 {
-  return Glib::make_refptr_for_instance<Socket>(new Socket(family, type, protocol, cancellable));
+  return Glib::RefPtr<Socket>(new Socket(family, type, protocol, cancellable));
 }
 
 // static
 Glib::RefPtr<Socket>
 Socket::create_from_fd(int fd, const Glib::RefPtr<Cancellable>& cancellable)
 {
-  return Glib::make_refptr_for_instance<Socket>(new Socket(fd, cancellable));
+  return Glib::RefPtr<Socket>(new Socket(fd, cancellable));
 }
 
 gssize
@@ -114,7 +111,10 @@ Socket::send_with_blocking(
 Glib::RefPtr<SocketSource>
 Socket::create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable)
 {
-  return SocketSource::create(gobj(), condition, cancellable);
+  // The corresponding unreference() takes place in the dtor
+  // of the Glib::RefPtr<Socket> object below.
+  reference();
+  return SocketSource::create(Glib::RefPtr<Socket>(this), condition, cancellable);
 }
 
 } // namespace Gio
index 1069eb2..7e38609 100644 (file)
@@ -28,8 +28,11 @@ _PINCLUDE(glibmm/private/object_p.h)
 
 namespace Gio
 {
-class SocketSource;
+class GIOMM_API SocketSource;
 
+_WRAP_ENUM(SocketType, GSocketType)
+_WRAP_ENUM(SocketProtocol, GSocketProtocol)
+_WRAP_ENUM(SocketMsgFlags, GSocketMsgFlags)
 
 /** @defgroup NetworkIO Portable Network I/O Functionality
  */
@@ -82,18 +85,13 @@ class SocketSource;
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class Socket : public Glib::Object, public Initable
+class GIOMM_API Socket : public Glib::Object, public Initable
 {
-  _CLASS_GOBJECT(Socket, GSocket, G_SOCKET, Glib::Object, GObject)
+  _CLASS_GOBJECT(Socket, GSocket, G_SOCKET, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Initable)
 
-public:
-  _WRAP_ENUM(Type, GSocketType)
-  _WRAP_ENUM(Protocol, GSocketProtocol)
-  _WRAP_ENUM(MsgFlags, GSocketMsgFlags)
-
 protected:
-  Socket(SocketFamily family, Type type, Protocol protocol,
+  Socket(SocketFamily family, SocketType type, SocketProtocol protocol,
          const Glib::RefPtr<Cancellable>& cancellable);
 
   Socket(int fd, const Glib::RefPtr<Cancellable>& cancellable);
@@ -105,8 +103,8 @@ public:
    * @throw Glib::Error
    */
   static Glib::RefPtr<Socket>
-  create(SocketFamily family, Type type, Protocol protocol,
-         const Glib::RefPtr<Cancellable>& cancellable = {});
+  create(SocketFamily family, SocketType type, SocketProtocol protocol,
+         const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
 
   // gmmproc thinks that this function should be wrapped in this class because
   // its only parameter is a GSocket.  In fact, it is wrapped in the
@@ -118,7 +116,7 @@ public:
    * @throw Glib::Error
    */
   static Glib::RefPtr<Socket> create_from_fd(int fd, const Glib::RefPtr<Cancellable>&
-                                             cancellable = {});
+                                             cancellable = Glib::RefPtr<Cancellable>());
 
   /** When a socket is created it is attached to an address family, but it doesn't
    * have an address in this family. Socket::bind() assigns the address (sometimes
@@ -255,7 +253,7 @@ public:
    * @param cancellable A Cancellable. The default value means the source is not cancellable.
    * @return A newly allocated SocketSource.
    */
-  Glib::RefPtr<SocketSource> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable = {});
+  Glib::RefPtr<SocketSource> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
   _IGNORE(g_socket_create_source)
 
   _WRAP_METHOD(void shutdown(bool shutdown_read, bool shutdown_write), g_socket_shutdown, errthrow)
@@ -279,8 +277,8 @@ public:
   _WRAP_METHOD(int get_fd() const, g_socket_get_fd)
   _WRAP_METHOD(Glib::RefPtr<SocketAddress> get_local_address() const, g_socket_get_local_address, errthrow)
   _WRAP_METHOD(Glib::RefPtr<SocketAddress> get_remote_address() const, g_socket_get_remote_address, errthrow)
-  _WRAP_METHOD(Protocol get_protocol() const, g_socket_get_protocol)
-  _WRAP_METHOD(Type get_socket_type() const, g_socket_get_socket_type)
+  _WRAP_METHOD(SocketProtocol get_protocol() const, g_socket_get_protocol)
+  _WRAP_METHOD(SocketType get_socket_type() const, g_socket_get_socket_type)
   _WRAP_METHOD(bool speaks_ipv4() const, g_socket_speaks_ipv4)
 
   _WRAP_METHOD(Glib::RefPtr<Credentials> get_credentials(), g_socket_get_credentials, errthrow)
@@ -290,10 +288,10 @@ public:
   _WRAP_METHOD(void set_timeout(guint timeout), g_socket_set_timeout)
 
   _WRAP_METHOD_DOCS_ONLY(g_socket_receive_with_blocking)
-  gssize receive_with_blocking(gchar* buffer, gsize size, bool blocking, const Glib::RefPtr<Cancellable>& cancellable = {});
+  gssize receive_with_blocking(gchar* buffer, gsize size, bool blocking, const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
 
   _WRAP_METHOD_DOCS_ONLY(g_socket_send_with_blocking)
-  gssize send_with_blocking(gchar* buffer, gsize size, bool blocking, const Glib::RefPtr<Cancellable>& cancellable = {});
+  gssize send_with_blocking(gchar* buffer, gsize size, bool blocking, const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
 
   _WRAP_METHOD(bool get_option(int level, int optname, int& value) const, g_socket_get_option, errthrow)
   _WRAP_METHOD(bool set_option(int level, int optname, int value), g_socket_set_option, errthrow)
@@ -321,9 +319,9 @@ public:
   _WRAP_PROPERTY("local-address", Glib::RefPtr<SocketAddress>)
   _WRAP_PROPERTY("remote-address", Glib::RefPtr<SocketAddress>)
   _WRAP_PROPERTY("timeout", guint)
-  _WRAP_PROPERTY("protocol", Protocol)
+  _WRAP_PROPERTY("protocol", SocketProtocol)
   _WRAP_PROPERTY("broadcast", bool)
-  _WRAP_PROPERTY("type", Type)
+  _WRAP_PROPERTY("type", SocketType)
   _WRAP_PROPERTY("ttl", guint)
   _WRAP_PROPERTY("multicast-loopback", bool)
   _WRAP_PROPERTY("multicast-ttl", guint)
index 1be525e..4c6409e 100644 (file)
@@ -32,10 +32,10 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketAddress : public Glib::Object,
+class GIOMM_API SocketAddress : public Glib::Object,
     public SocketConnectable
 {
-  _CLASS_GOBJECT(SocketAddress, GSocketAddress, G_SOCKET_ADDRESS, Glib::Object, GObject)
+  _CLASS_GOBJECT(SocketAddress, GSocketAddress, G_SOCKET_ADDRESS, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(SocketConnectable)
 
 public:
@@ -49,7 +49,7 @@ public:
   _WRAP_METHOD(bool to_native(gpointer dest, gsize destlen), g_socket_address_to_native, errthrow)
   _WRAP_METHOD(gssize get_native_size() const, g_socket_address_get_native_size)
 
-  _WRAP_PROPERTY("family", SocketFamily)
+  _WRAP_PROPERTY("family", Glib::RefPtr<SocketFamily>)
 };
 
 } // namespace Gio
index 28cf187..050cc6a 100644 (file)
@@ -24,16 +24,16 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class SocketAddress;
+class GIOMM_API SocketAddress;
 
 /** Enumerator type for objects that contain or generate SocketAddresses
  *
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketAddressEnumerator : public Glib::Object
+class GIOMM_API SocketAddressEnumerator : public Glib::Object
 {
-  _CLASS_GOBJECT(SocketAddressEnumerator, GSocketAddressEnumerator, G_SOCKET_ADDRESS_ENUMERATOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(SocketAddressEnumerator, GSocketAddressEnumerator, G_SOCKET_ADDRESS_ENUMERATOR, Glib::Object, GObject, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(Glib::RefPtr<SocketAddress> next(const Glib::RefPtr<Cancellable>& cancellable{?}), g_socket_address_enumerator_next, errthrow)
index e32cf6f..635c0e5 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2010 Jonathon Jongsma
  *
  * This library is free software; you can redistribute it and/or
@@ -49,9 +51,9 @@ _WRAP_ENUM(SocketClientEvent, GSocketClientEvent)
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketClient : public Glib::Object
+class GIOMM_API SocketClient : public Glib::Object
 {
-  _CLASS_GOBJECT(SocketClient, GSocketClient, G_SOCKET_CLIENT, Glib::Object, GObject)
+  _CLASS_GOBJECT(SocketClient, GSocketClient, G_SOCKET_CLIENT, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -60,10 +62,10 @@ public:
   _WRAP_CREATE()
   _WRAP_METHOD(SocketFamily get_family() const, g_socket_client_get_family)
   _WRAP_METHOD(void set_family(SocketFamily family), g_socket_client_set_family)
-  _WRAP_METHOD(Socket::Type get_socket_type() const, g_socket_client_get_socket_type)
-  _WRAP_METHOD(void set_socket_type(Socket::Type type), g_socket_client_set_socket_type)
-  _WRAP_METHOD(Socket::Protocol get_protocol() const, g_socket_client_get_protocol)
-  _WRAP_METHOD(void set_protocol(Socket::Protocol protocol), g_socket_client_set_protocol)
+  _WRAP_METHOD(SocketType get_socket_type() const, g_socket_client_get_socket_type)
+  _WRAP_METHOD(void set_socket_type(SocketType type), g_socket_client_set_socket_type)
+  _WRAP_METHOD(SocketProtocol get_protocol() const, g_socket_client_get_protocol)
+  _WRAP_METHOD(void set_protocol(SocketProtocol protocol), g_socket_client_set_protocol)
   _WRAP_METHOD(Glib::RefPtr<SocketAddress> get_local_address(), g_socket_client_get_local_address)
   _WRAP_METHOD(Glib::RefPtr<const SocketAddress> get_local_address() const, g_socket_client_get_local_address, constversion)
   _WRAP_METHOD(void set_local_address(const Glib::RefPtr<SocketAddress>& address), g_socket_client_set_local_address)
@@ -158,8 +160,8 @@ public:
 
   _WRAP_PROPERTY("family", SocketFamily)
   _WRAP_PROPERTY("local-address", Glib::RefPtr<SocketAddress>)
-  _WRAP_PROPERTY("protocol", Socket::Protocol)
-  _WRAP_PROPERTY("type", Socket::Type)
+  _WRAP_PROPERTY("protocol", SocketProtocol)
+  _WRAP_PROPERTY("type", SocketType)
   _WRAP_PROPERTY("timeout", guint)
   _WRAP_PROPERTY("enable-proxy", bool)
   _WRAP_PROPERTY("tls", bool)
@@ -168,7 +170,7 @@ public:
 
 #m4 _CONVERSION(`GSocketConnectable*',`const Glib::RefPtr<SocketConnectable>&',`Glib::wrap($3, true)')
 #m4 _CONVERSION(`GIOStream*',`const Glib::RefPtr<IOStream>&',`Glib::wrap($3, true)')
-  _WRAP_SIGNAL(void event(SocketClientEvent event, const Glib::RefPtr<SocketConnectable>& connectable, const Glib::RefPtr<IOStream>& connection), event)
+  _WRAP_SIGNAL(void event(SocketClientEvent event, const Glib::RefPtr<SocketConnectable>& connectable, const Glib::RefPtr<IOStream>& connection), event, no_default_handler)
 };
 
 } // namespace Gio
index 266a8a6..2488b8d 100644 (file)
@@ -32,9 +32,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketConnectable : public Glib::Interface
+class GIOMM_API SocketConnectable : public Glib::Interface
 {
-  _CLASS_INTERFACE(SocketConnectable, GSocketConnectable, G_SOCKET_CONNECTABLE, GSocketConnectableIface)
+  _CLASS_INTERFACE(SocketConnectable, GSocketConnectable, G_SOCKET_CONNECTABLE, GSocketConnectableIface, , , GIOMM_API)
 
 public:
   _WRAP_METHOD (Glib::RefPtr<SocketAddressEnumerator> enumerate(), g_socket_connectable_enumerate)
index 1c9a738..6423767 100644 (file)
@@ -46,9 +46,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketConnection : public Gio::IOStream
+class GIOMM_API SocketConnection : public Gio::IOStream
 {
-  _CLASS_GOBJECT(SocketConnection, GSocketConnection, G_SOCKET_CONNECTION, Gio::IOStream, GIOStream)
+  _CLASS_GOBJECT(SocketConnection, GSocketConnection, G_SOCKET_CONNECTION, Gio::IOStream, GIOStream, , , GIOMM_API)
 
 public:
   _WRAP_METHOD(bool connect(const Glib::RefPtr<SocketAddress>& address, const Glib::RefPtr<Cancellable>& cancellable{?}), g_socket_connection_connect, errthrow)
index 620e8d8..8d04d0b 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 #include <set>
 
@@ -48,9 +50,9 @@ namespace Gio
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class SocketControlMessage : public Glib::Object
+class GIOMM_API SocketControlMessage : public Glib::Object
 {
-  _CLASS_GOBJECT(SocketControlMessage, GSocketControlMessage, G_SOCKET_CONTROL_MESSAGE, Glib::Object, GObject)
+  _CLASS_GOBJECT(SocketControlMessage, GSocketControlMessage, G_SOCKET_CONTROL_MESSAGE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -62,6 +64,11 @@ public:
   _WRAP_METHOD(gsize get_size() const, g_socket_control_message_get_size)
   _WRAP_METHOD(void serialize(gpointer data), g_socket_control_message_serialize)
 
+  _WRAP_VFUNC(gsize get_size() const, "get_size")
+  _WRAP_VFUNC(int get_level() const, "get_level")
+  _WRAP_VFUNC(int get_type() const, "get_type")
+  _WRAP_VFUNC(void serialize(gpointer data), "serialize")
+
 protected:
   // The deserialize vfunc in GLib is a class virtual function (not associated
   // with an instance). Such functions don't exist in C++.
@@ -108,14 +115,9 @@ protected:
    */
   static void add_deserialize_func(DeserializeFunc func);
 
-  _WRAP_VFUNC(gsize get_size() const, "get_size")
-  _WRAP_VFUNC(int get_level() const, "get_level")
-  _WRAP_VFUNC(int get_type() const, "get_type")
-  _WRAP_VFUNC(void serialize(gpointer data), "serialize")
-
 private:
-  // Functions registered with add_deserialize_func(). 
-  static std::set<DeserializeFunc> m_deserialize_funcs;  
+  // Functions registered with add_deserialize_func().
+  static std::set<DeserializeFunc> m_deserialize_funcs;
 };
 
 } // namespace Gio
index c85394e..c48dbb8 100644 (file)
@@ -33,8 +33,8 @@ SocketListener::add_socket(const Glib::RefPtr<Socket>& socket)
 }
 
 bool
-SocketListener::add_address(const Glib::RefPtr<SocketAddress>& address, Socket::Type type,
-  Socket::Protocol protocol, const Glib::RefPtr<Glib::Object>& source_object,
+SocketListener::add_address(const Glib::RefPtr<SocketAddress>& address, SocketType type,
+  SocketProtocol protocol, const Glib::RefPtr<Glib::Object>& source_object,
   Glib::RefPtr<SocketAddress>& effective_address)
 {
   GError* gerror = nullptr;
@@ -52,8 +52,8 @@ SocketListener::add_address(const Glib::RefPtr<SocketAddress>& address, Socket::
 }
 
 bool
-SocketListener::add_address(const Glib::RefPtr<SocketAddress>& address, Socket::Type type,
-  Socket::Protocol protocol, Glib::RefPtr<SocketAddress>& effective_address)
+SocketListener::add_address(const Glib::RefPtr<SocketAddress>& address, SocketType type,
+  SocketProtocol protocol, Glib::RefPtr<SocketAddress>& effective_address)
 {
   GError* gerror = nullptr;
   GSocketAddress* retaddr = nullptr;
index 0db6398..e19af91 100644 (file)
@@ -42,9 +42,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketListener : public Glib::Object
+class GIOMM_API SocketListener : public Glib::Object
 {
-  _CLASS_GOBJECT(SocketListener, GSocketListener, G_SOCKET_LISTENER, Glib::Object, GObject)
+  _CLASS_GOBJECT(SocketListener, GSocketListener, G_SOCKET_LISTENER, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -63,11 +63,11 @@ public:
   bool add_socket(const Glib::RefPtr<Socket>& socket);
 
   _WRAP_METHOD_DOCS_ONLY(g_socket_listener_add_address)
-bool add_address(const Glib::RefPtr<SocketAddress>& address, Socket::Type type, Socket::Protocol protocol, const Glib::RefPtr<Glib::Object>& source_object, Glib::RefPtr<SocketAddress>& effective_address);
+bool add_address(const Glib::RefPtr<SocketAddress>& address, SocketType type, SocketProtocol protocol, const Glib::RefPtr<Glib::Object>& source_object, Glib::RefPtr<SocketAddress>& effective_address);
   _IGNORE(g_socket_listener_add_address)
 
   _WRAP_METHOD_DOCS_ONLY(g_socket_listener_add_address)
-  bool add_address(const Glib::RefPtr<SocketAddress>& address, Socket::Type type, Socket::Protocol protocol, Glib::RefPtr<SocketAddress>& effective_address);
+  bool add_address(const Glib::RefPtr<SocketAddress>& address, SocketType type, SocketProtocol protocol, Glib::RefPtr<SocketAddress>& effective_address);
 
   _WRAP_METHOD(bool add_inet_port(guint16 port, const Glib::RefPtr<Glib::Object>& source_object), g_socket_listener_add_inet_port, errthrow)
 
index a21eb18..871af83 100644 (file)
@@ -54,9 +54,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SocketService : public Gio::SocketListener
+class GIOMM_API SocketService : public Gio::SocketListener
 {
-  _CLASS_GOBJECT(SocketService, GSocketService, G_SOCKET_SERVICE, Gio::SocketListener, GSocketListener)
+  _CLASS_GOBJECT(SocketService, GSocketService, G_SOCKET_SERVICE, Gio::SocketListener, GSocketListener, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
index 727182d..7040309 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <glibmm/value.h>
+_CONFIGINCLUDE(giommconfig.h)
+
+#include <glibmm/listhandle.h>
+
+// unfortunately we need to include the C header for the type traits
+// implementation
+#include <gio/gio.h>
 
 _DEFS(giomm,gio)
 
@@ -39,9 +45,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class SrvTarget
+class GIOMM_API SrvTarget
 {
-  _CLASS_BOXEDTYPE(SrvTarget, GSrvTarget, NONE, g_srv_target_copy, g_srv_target_free)
+  _CLASS_BOXEDTYPE(SrvTarget, GSrvTarget, NONE, g_srv_target_copy, g_srv_target_free, GIOMM_API)
 public:
   SrvTarget(const Glib::ustring& hostname, guint16 port, guint16 priority, guint16 weight);
 
@@ -54,6 +60,23 @@ public:
 
 };
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+struct SrvTargetListTraits
+{
+  using CppType = Gio::SrvTarget;
+  using CType = const GSrvTarget*;
+  using CTypeNonConst = GSrvTarget*;
+
+  static CType to_c_type(const CppType& item) { return item.gobj(); }
+  static CType to_c_type(CType ptr) { return ptr; }
+  static CppType to_cpp_type(CType item) { return CppType(const_cast<CTypeNonConst>(item), true /* take_copy */); }
+  static void release_c_type(CType item) { g_srv_target_free(const_cast<CTypeNonConst>(item)); }
+};
+
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+using ListHandle_SrvTarget = Glib::ListHandle<Gio::SrvTarget, SrvTargetListTraits>;
 
 } // namespace Gio
 
index 6352c17..7a6394f 100644 (file)
@@ -32,9 +32,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class TcpConnection : public Gio::SocketConnection
+class GIOMM_API TcpConnection : public Gio::SocketConnection
 {
-    _CLASS_GOBJECT(TcpConnection, GTcpConnection, G_TCP_CONNECTION, Gio::SocketConnection, GSocketConnection)
+    _CLASS_GOBJECT(TcpConnection, GTcpConnection, G_TCP_CONNECTION, Gio::SocketConnection, GSocketConnection, , , GIOMM_API)
 
 public:
     _WRAP_METHOD(void set_graceful_disconnect (bool graceful_disconnect), g_tcp_connection_set_graceful_disconnect)
index 420d17a..53a2c3f 100644 (file)
@@ -33,9 +33,9 @@ namespace Gio
  * @newin{2,44}
  * @ingroup NetworkIO
  */
-class TcpWrapperConnection : public Gio::TcpConnection
+class GIOMM_API TcpWrapperConnection : public Gio::TcpConnection
 {
-    _CLASS_GOBJECT(TcpWrapperConnection, GTcpWrapperConnection, G_TCP_WRAPPER_CONNECTION, Gio::TcpConnection, GTcpConnection)
+    _CLASS_GOBJECT(TcpWrapperConnection, GTcpWrapperConnection, G_TCP_WRAPPER_CONNECTION, Gio::TcpConnection, GTcpConnection, , , GIOMM_API)
 
 public:
 
index 00fffc1..fbb6d47 100644 (file)
@@ -19,7 +19,7 @@
 namespace Gio
 {
 
-ThemedIcon::ThemedIcon(const Glib::ustring& iconname, bool use_default_fallbacks)
+ThemedIcon::ThemedIcon(const std::string& iconname, bool use_default_fallbacks)
 : _CONSTRUCT("name", iconname.c_str(), "use-default-fallbacks", gboolean(use_default_fallbacks))
 {
 }
index 1d9974b..f8efcbd 100644 (file)
@@ -36,20 +36,24 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class ThemedIcon
+class GIOMM_API ThemedIcon
 : public Glib::Object,
   public Icon
 {
-  _CLASS_GOBJECT(ThemedIcon, GThemedIcon, G_THEMED_ICON, Glib::Object, GObject)
+  _CLASS_GOBJECT(ThemedIcon, GThemedIcon, G_THEMED_ICON, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Icon)
 
 protected:
+  //TODO: When we can break ABI, change the type of icon names to Glib::ustring
+  // in methods where it is std::string. Gtkmm consistently uses Glib::ustring
+  // for icon names, but Gio::ThemedIcon is inconsistent.
+
   /** Creates a new themed icon for @a iconname, and optionally all the names that can be created by shortening @a iconname at '-' characters.
    *
    * @param iconname A string containing an icon name.
    * @param use_default_fallbacks Whether to use all the names that can be created by shortening @a iconname at '-' characters.
    */
-  explicit ThemedIcon(const Glib::ustring& iconname, bool use_default_fallbacks = false);
+  explicit ThemedIcon(const std::string& iconname, bool use_default_fallbacks = false);
   _IGNORE(g_themed_icon_new, g_themed_icon_new_with_default_fallbacks)
 
   /** Creates a new themed icon for @a iconnames.
@@ -79,7 +83,7 @@ public:
    * @param iconname A string containing an icon name.
    * @param use_default_fallbacks Whether to use all the names that can be created by shortening @a iconname at '-' characters.
    */
-  _WRAP_CREATE(const Glib::ustring& iconname, bool use_default_fallbacks = false)
+  _WRAP_CREATE(const std::string& iconname, bool use_default_fallbacks = false)
 
   /** Creates a new themed icon for @a iconnames.
    *
@@ -89,11 +93,11 @@ public:
    */
   _WRAP_CREATE(const std::vector<Glib::ustring>& iconnames)
 
-  _WRAP_METHOD(void prepend_name(const Glib::ustring& iconname), g_themed_icon_prepend_name)
-  _WRAP_METHOD(void append_name(const Glib::ustring& iconname), g_themed_icon_append_name)
+  _WRAP_METHOD(void prepend_name(const std::string& iconname), g_themed_icon_prepend_name)
+  _WRAP_METHOD(void append_name(const std::string& iconname), g_themed_icon_append_name)
 
-  #m4 _CONVERSION(`const gchar* const*',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
-  _WRAP_METHOD(std::vector<Glib::ustring> get_names() const, g_themed_icon_get_names)
+  #m4 _CONVERSION(`const gchar* const*',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_NONE)')
+  _WRAP_METHOD(Glib::StringArrayHandle get_names() const, g_themed_icon_get_names)
 
   //There are no signals.
 
index ef23974..ce80455 100644 (file)
@@ -44,9 +44,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class ThreadedSocketService : public Gio::SocketService
+class GIOMM_API ThreadedSocketService : public Gio::SocketService
 {
-    _CLASS_GOBJECT(ThreadedSocketService, GThreadedSocketService, G_THREADED_SOCKET_SERVICE, Gio::SocketService, GSocketService)
+    _CLASS_GOBJECT(ThreadedSocketService, GThreadedSocketService, G_THREADED_SOCKET_SERVICE, Gio::SocketService, GSocketService, , , GIOMM_API)
 
 protected:
     _WRAP_CTOR(ThreadedSocketService(int max_threads), g_threaded_socket_service_new)
index 3cb4910..57fdd6a 100644 (file)
@@ -24,7 +24,7 @@ namespace Gio
 Glib::RefPtr<TlsCertificate>
 TlsCertificate::create_from_pem(const std::string& data, gssize length)
 {
-  return Glib::make_refptr_for_instance<TlsCertificate>(new TlsCertificate(data, length));
+  return Glib::RefPtr<TlsCertificate>(new TlsCertificate(data, length));
 }
 
 } // namesapce Gio
index 3f36566..47869ac 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 #include <giomm/enums.h>
 
@@ -24,14 +26,14 @@ namespace Glib
 {
 
 // Forward declaration.
-class ByteArray;
+class GLIBMM_API ByteArray;
 
 }
 
 namespace Gio
 {
 
-class SocketConnectable;
+class GIOMM_API SocketConnectable;
 
 /** TlsCertificate - TLS certificate.
  * A certificate used for TLS authentication and encryption. This can represent
@@ -40,9 +42,9 @@ class SocketConnectable;
  * needed when acting as a TlsServerConnection).
  * @newin{2,36}
  */
-class TlsCertificate : public Glib::Object
+class GIOMM_API TlsCertificate : public Glib::Object
 {
-  _CLASS_GOBJECT(TlsCertificate, GTlsCertificate, G_TLS_CERTIFICATE, Glib::Object, GObject)
+  _CLASS_GOBJECT(TlsCertificate, GTlsCertificate, G_TLS_CERTIFICATE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _WRAP_CTOR(TlsCertificate(const std::string& data, gssize length), g_tls_certificate_new_from_pem, errthrow)
@@ -79,7 +81,6 @@ public:
   // Write-only and construct-only
   //_WRAP_PROPERTY("private-key-pem", std::string)
 
-protected:
 #m4 _CONVERSION(`GSocketConnectable*',`const Glib::RefPtr<const SocketConnectable>&',`Glib::wrap($3, true)')
 #m4 _CONVERSION(`GTlsCertificate*',`const Glib::RefPtr<const TlsCertificate>&',`Glib::wrap($3, true)')
   _WRAP_VFUNC(TlsCertificateFlags verify(const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<const TlsCertificate>& trusted_ca) const, "verify")
index f5d0bce..aa096e1 100644 (file)
@@ -29,27 +29,23 @@ typedef struct _GTlsClientConnectionInterface GTlsClientConnectionInterface;
 namespace Gio
 {
 
-class SocketConnectable;
-
-// It's unusual that a subclass of Glib::Object is a base class of an interface.
-// For a discussion, see https://bugzilla.gnome.org/show_bug.cgi?id=776537
-// especially the last paragraph of comment 6.
+class GIOMM_API SocketConnectable;
 
 /** TlsClientConnection - TLS client-side connection.
  * TlsClientConnection is the client-side subclass of TlsConnection,
  * representing a client-side TLS connection.
  * @newin{2,36}
  */
-class TlsClientConnection
+class GIOMM_API TlsClientConnection
 : public Glib::Interface,
   public TlsConnection
 {
-  _CLASS_INTERFACE(TlsClientConnection, GTlsClientConnection, G_TLS_CLIENT_CONNECTION, GTlsClientConnectionInterface)
+  _CLASS_INTERFACE(TlsClientConnection, GTlsClientConnection, G_TLS_CLIENT_CONNECTION, GTlsClientConnectionInterface, , , GIOMM_API)
   _CUSTOM_CTOR_CAST
 
 public:
-  // It's not possible to use _WRAP_CTOR/_WRAP_CREATE to wrap the new
-  // function because this is an interface.
+  //TODO: It's not possible to use _WRAP_CTOR/_WRAP_CREATE to wrap the new
+  //function because this is an interface.
 #m4 _CONVERSION(`GIOStream*',`Glib::RefPtr<TlsClientConnection>',`Glib::wrap(G_TLS_CLIENT_CONNECTION($3))')
   _WRAP_METHOD(static Glib::RefPtr<TlsClientConnection> create(const Glib::RefPtr<IOStream>& base_io_stream, const Glib::RefPtr<const SocketConnectable>& server_identity{?}), g_tls_client_connection_new, errthrow)
 
@@ -61,7 +57,10 @@ public:
   _WRAP_METHOD(void set_validation_flags(TlsCertificateFlags flags), g_tls_client_connection_set_validation_flags)
   _WRAP_METHOD(TlsCertificateFlags get_validation_flags() const, g_tls_client_connection_get_validation_flags)
 
-  _IGNORE(g_tls_client_connection_set_use_ssl3, g_tls_client_connection_get_use_ssl3) dnl// deprecated
+  _WRAP_METHOD(void set_use_ssl3(bool use_ssl3 = true), g_tls_client_connection_set_use_ssl3,
+    deprecated "SSL 3.0 is insecure, and this function does not generally enable or disable it, despite its name.")
+  _WRAP_METHOD(bool get_use_ssl3() const, g_tls_client_connection_get_use_ssl3,
+    deprecated "SSL 3.0 is insecure, and this function does not actually indicate whether it is enabled.")
 
 #m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<Glib::ByteArray> >',`Glib::ListHandler< Glib::RefPtr<Glib::ByteArray> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(std::vector< Glib::RefPtr<Glib::ByteArray> > get_accepted_cas(), g_tls_client_connection_get_accepted_cas)
@@ -69,14 +68,16 @@ public:
 #m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<const Glib::ByteArray> >',`Glib::ListHandler< Glib::RefPtr<const Glib::ByteArray> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(std::vector< Glib::RefPtr<const Glib::ByteArray> > get_accepted_cas() const, g_tls_client_connection_get_accepted_cas)
 
+
   _WRAP_METHOD(void copy_session_state(const Glib::RefPtr<TlsClientConnection>& source), g_tls_client_connection_copy_session_state)
 
   // property_accepted_cas() won't work unless a Glib::Value<std::vector<Glib::RefPtr<Glib::ByteArray>>>
   // specialization is added. Workaround: Use get_accepted_cas().
-  //_WRAP_PROPERTY("accepted-cas", std::vector<Glib::RefPtr<Glib::ByteArray>>)
+  _WRAP_PROPERTY("accepted-cas", std::vector< Glib::RefPtr<Glib::ByteArray> >,
+    deprecated "property_accepted_cas() does not work. Use get_accepted_cas() instead.")
   _WRAP_PROPERTY("server-identity", Glib::RefPtr<SocketConnectable>)
+  _WRAP_PROPERTY("use-ssl3", bool, deprecated "SSL 3.0 is insecure, and this property does not generally enable or disable it, despite its name.")
   _WRAP_PROPERTY("validation-flags", TlsCertificateFlags)
-  _IGNORE_PROPERTY(use-ssl3) dnl// deprecated
 };
 
 } // namespace Gio
index 6ba9c73..f332abe 100644 (file)
@@ -26,9 +26,11 @@ _PINCLUDE(giomm/private/iostream_p.h)
 namespace Gio
 {
 
-class Cancellable;
-class TlsDatabase;
-class TlsInteraction;
+_WRAP_ENUM(TlsRehandshakeMode,GTlsRehandshakeMode)
+
+class GIOMM_API Cancellable;
+class GIOMM_API TlsDatabase;
+class GIOMM_API TlsInteraction;
 
 /** TlsConnection - TLS connection type.
  * TlsConnection is the base TLS connection class type, which wraps an IOStream
@@ -37,9 +39,9 @@ class TlsInteraction;
  * server-side TLS, respectively.
  * @newin{2,36}
  */
-class TlsConnection : public IOStream
+class GIOMM_API TlsConnection : public IOStream
 {
-  _CLASS_GOBJECT(TlsConnection, GTlsConnection, G_TLS_CONNECTION, IOStream, GIOStream)
+  _CLASS_GOBJECT(TlsConnection, GTlsConnection, G_TLS_CONNECTION, IOStream, GIOStream, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -58,8 +60,15 @@ public:
   _WRAP_METHOD(void set_require_close_notify(bool require_close_notify = true), g_tls_connection_set_require_close_notify)
   _WRAP_METHOD(bool get_require_close_notify() const, g_tls_connection_get_require_close_notify)
 
-  _IGNORE(g_tls_connection_set_use_system_certdb, g_tls_connection_get_use_system_certdb)dnl // deprecated
-  _IGNORE(g_tls_connection_set_rehandshake_mode, g_tls_connection_get_rehandshake_mode)dnl // deprecated
+  _WRAP_METHOD(void set_rehandshake_mode(TlsRehandshakeMode mode), g_tls_connection_set_rehandshake_mode,
+    deprecated "Changing the rehandshake mode is no longer required for compatibility. Also, rehandshaking has been removed from the TLS protocol in TLS 1.3.")
+  _WRAP_METHOD(TlsRehandshakeMode get_rehandshake_mode() const, g_tls_connection_get_rehandshake_mode,
+    deprecated "Changing the rehandshake mode is no longer required for compatibility. Also, rehandshaking has been removed from the TLS protocol in TLS 1.3.")
+
+  _WRAP_METHOD(void set_use_system_certdb(bool use_system_certdb = true), g_tls_connection_set_use_system_certdb,
+    deprecated "Use set_database() instead.")
+  _WRAP_METHOD(bool get_use_system_certdb() const, g_tls_connection_get_use_system_certdb,
+    deprecated "Use get_database() instead.")
 
   _WRAP_METHOD(Glib::RefPtr<TlsDatabase> get_database(), g_tls_connection_get_database)
   _WRAP_METHOD(Glib::RefPtr<const TlsDatabase> get_database() const, g_tls_connection_get_database, constversion)
@@ -84,13 +93,14 @@ public:
   _WRAP_PROPERTY("interaction", Glib::RefPtr<TlsInteraction>)
   _WRAP_PROPERTY("peer-certificate", Glib::RefPtr<TlsCertificate>)
   _WRAP_PROPERTY("peer-certificate-errors", TlsCertificateFlags)
+  _WRAP_PROPERTY("rehandshake-mode", TlsRehandshakeMode,
+    deprecated "Changing the rehandshake mode is no longer required for compatibility. Also, rehandshaking has been removed from the TLS protocol in TLS 1.3.")
   _WRAP_PROPERTY("require-close-notify", bool)
-  _IGNORE_PROPERTY("use-system-certdb", "rehandshake-mode")dnl // deprecated
+  _WRAP_PROPERTY("use-system-certdb", bool, deprecated "Use property_database() instead.")
 
 #m4 _CONVERSION(`GTlsCertificate*',`const Glib::RefPtr<const TlsCertificate>&',`Glib::wrap($3, true)')
   _WRAP_SIGNAL(bool accept_certificate(const Glib::RefPtr<const TlsCertificate>& peer_cert, TlsCertificateFlags errors), "accept_certificate")
 
-protected:
   _WRAP_VFUNC(bool handshake(const Glib::RefPtr<Cancellable>& cancellable), "handshake", errthrow)
   _WRAP_VFUNC(void handshake_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, int io_priority{.} = Glib::PRIORITY_DEFAULT), "handshake_async", slot_name slot, slot_callback SignalProxy_async_callback)
 
index f351f20..80ef0a7 100644 (file)
@@ -21,9 +21,6 @@
 #include <giomm/tlsinteraction.h>
 #include "slot_async.h"
 
-using VerifyFlags = Gio::TlsDatabase::VerifyFlags;
-using LookupFlags = Gio::TlsDatabase::LookupFlags;
-
 namespace
 {
 // Used in call to g_list_copy_deep().
index 571ff7d..95d577c 100644 (file)
@@ -25,17 +25,20 @@ namespace Glib
 {
 
 // Forward declaration.
-class ByteArray;
+class GLIBMM_API ByteArray;
 
 }
 
 namespace Gio
 {
 
-class Cancellable;
-class SocketConnectable;
-class TlsCertificate;
-class TlsInteraction;
+_WRAP_ENUM(TlsDatabaseVerifyFlags, GTlsDatabaseVerifyFlags)
+_WRAP_ENUM(TlsDatabaseLookupFlags, GTlsDatabaseLookupFlags)
+
+class GIOMM_API Cancellable;
+class GIOMM_API SocketConnectable;
+class GIOMM_API TlsCertificate;
+class GIOMM_API TlsInteraction;
 
 /** TlsDatabase - TLS database type.
  * TlsDatabase is used to lookup certificates and other information from a
@@ -46,9 +49,9 @@ class TlsInteraction;
  * It is used internally by TlsConnection.
  * @newin{2,36}
  */
-class TlsDatabase : public Glib::Object
+class GIOMM_API TlsDatabase : public Glib::Object
 {
-  _CLASS_GOBJECT(TlsDatabase, GTlsDatabase, G_TLS_DATABASE, Glib::Object, GObject)
+  _CLASS_GOBJECT(TlsDatabase, GTlsDatabase, G_TLS_DATABASE, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -57,91 +60,66 @@ public:
   //TODO?: Have a constant for the C macro G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER (which is a string)?
   //TODO?: Have a constant for the C macro G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT (which is a string)?
 
-  _WRAP_ENUM(VerifyFlags, GTlsDatabaseVerifyFlags)
-  _WRAP_ENUM(LookupFlags, GTlsDatabaseLookupFlags)
-
-  _WRAP_METHOD(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity{?}, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, VerifyFlags flags{.} = VerifyFlags::NONE) const, g_tls_database_verify_chain, errthrow)
-  _WRAP_METHOD(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity{?}, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, VerifyFlags flags{.} = VerifyFlags::NONE) const, g_tls_database_verify_chain_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity{?}, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseVerifyFlags flags{.} = TLS_DATABASE_VERIFY_NONE) const, g_tls_database_verify_chain, errthrow)
+  _WRAP_METHOD(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity{?}, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseVerifyFlags flags{.} = TLS_DATABASE_VERIFY_NONE) const, g_tls_database_verify_chain_async, slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_METHOD(TlsCertificateFlags verify_chain_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_database_verify_chain_finish, errthrow)
 
-  _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificate_issuer, errthrow)
-  _WRAP_METHOD(Glib::RefPtr<const TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE) const, g_tls_database_lookup_certificate_issuer, errthrow, constversion)
+  _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificate_issuer, errthrow)
+  _WRAP_METHOD(Glib::RefPtr<const TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE) const, g_tls_database_lookup_certificate_issuer, errthrow, constversion)
 
-  _WRAP_METHOD(void lookup_certificate_issuer_async(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificate_issuer_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(void lookup_certificate_issuer_async(const Glib::RefPtr<const TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificate_issuer_async, slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_database_lookup_certificate_issuer_finish, errthrow)
 
 #m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<TlsCertificate> >',`Glib::ListHandler< Glib::RefPtr<TlsCertificate> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificates_issued_by, errthrow)
+  _WRAP_METHOD(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = Gio::TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificates_issued_by, errthrow)
 
 #m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<const TlsCertificate> >',`Glib::ListHandler< Glib::RefPtr<const TlsCertificate> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector< Glib::RefPtr<const TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE) const, g_tls_database_lookup_certificates_issued_by, errthrow)
+  _WRAP_METHOD(std::vector< Glib::RefPtr<const TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = Gio::TLS_DATABASE_LOOKUP_NONE) const, g_tls_database_lookup_certificates_issued_by, errthrow)
 
-  _WRAP_METHOD(void lookup_certificates_issued_by_async(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificates_issued_by_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(void lookup_certificates_issued_by_async(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = Gio::TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificates_issued_by_async, slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_METHOD(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_database_lookup_certificates_issued_by_finish, errthrow)
 
   _WRAP_METHOD(Glib::ustring create_certificate_handle(const Glib::RefPtr<const TlsCertificate>& certificate) const, g_tls_database_create_certificate_handle)
 
-  _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificate_for_handle, errthrow)
-  _WRAP_METHOD(Glib::RefPtr<const TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE) const, g_tls_database_lookup_certificate_for_handle, errthrow, constversion)
+  _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificate_for_handle, errthrow)
+  _WRAP_METHOD(Glib::RefPtr<const TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE) const, g_tls_database_lookup_certificate_for_handle, errthrow, constversion)
 
-  _WRAP_METHOD(void lookup_certificate_for_handle_async(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, LookupFlags flags{.} = LookupFlags::NONE), g_tls_database_lookup_certificate_for_handle_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(void lookup_certificate_for_handle_async(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction{?}, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.} = TLS_DATABASE_LOOKUP_NONE), g_tls_database_lookup_certificate_for_handle_async, slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_METHOD(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_database_lookup_certificate_for_handle_finish, errthrow)
 
-protected:
 #m4 _CONVERSION(`GTlsCertificate*',`const Glib::RefPtr<TlsCertificate>&',`Glib::wrap($3, true)')
 #m4 _CONVERSION(`GSocketConnectable*',`const Glib::RefPtr<const SocketConnectable>&',`Glib::wrap($3, true)')
 #m4 _CONVERSION(`GTlsInteraction*',`const Glib::RefPtr<TlsInteraction>&',`Glib::wrap($3, true)')
 
-  _WRAP_VFUNC(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, VerifyFlags flags{.}) const, "verify_chain", errthrow)
-  _WRAP_VFUNC(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, VerifyFlags flags{.}) const, "verify_chain_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain", errthrow)
+  _WRAP_VFUNC(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain_async", slot_name slot, slot_callback SignalProxy_async_callback)
 
 #m4 _CONVERSION(`GAsyncResult*',`const Glib::RefPtr<AsyncResult>&',`Glib::wrap($3, true)')
 
   _WRAP_VFUNC(TlsCertificateFlags verify_chain_finish(const Glib::RefPtr<AsyncResult>& result), "verify_chain_finish", errthrow)
 
 dnl// create_certificate_handle_vfunc() shall return a newly allocated string.
-dnl// Also, ensure that create_certificate_handle_vfunc() never returns an empty char[],
-dnl// because that could be caused by an intermediate empty ustring from an initial null char*.
 #m4 _CONVERSION(`GTlsCertificate*',`const Glib::RefPtr<const TlsCertificate>&',`Glib::wrap($3, true)')
-#m4 _CONVERSION(`Glib::ustring',`gchar*',`g_strdup(Glib::c_str_or_nullptr($3))')
 #m4 _CONVERSION(`gchar*',`Glib::ustring',`Glib::convert_return_gchar_ptr_to_ustring($3)')
   _WRAP_VFUNC(Glib::ustring create_certificate_handle(const Glib::RefPtr<const TlsCertificate>& certificate) const, "create_certificate_handle")
 
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(
-    const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction,
-    const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}),
-    "lookup_certificate_for_handle", errthrow, refreturn_ctype)
-  _WRAP_VFUNC(void lookup_certificate_for_handle_async(
-    const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction,
-    const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}),
-    "lookup_certificate_for_handle_async", slot_name slot, slot_callback SignalProxy_async_callback)
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle_finish(
-    const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_for_handle_finish", errthrow, refreturn_ctype)
-
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(
-    const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction,
-    const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}),
-    "lookup_certificate_issuer", errthrow, refreturn_ctype)
-  _WRAP_VFUNC(void lookup_certificate_issuer_async(
-    const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction,
-    const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}),
-    "lookup_certificate_issuer_async", slot_name slot, slot_callback SignalProxy_async_callback)
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer_finish(
-    const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_issuer_finish", errthrow, refreturn_ctype)
+#m4 _CONVERSION(`Glib::RefPtr<TlsCertificate>',`GTlsCertificate*',`G_TLS_CERTIFICATE(g_object_ref(Glib::unwrap($3)))')
+
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle", errthrow)
+  _WRAP_VFUNC(void lookup_certificate_for_handle_async(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_for_handle_finish", errthrow)
+
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer", errthrow)
+  _WRAP_VFUNC(void lookup_certificate_issuer_async(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_issuer_finish", errthrow)
 
 #m4 _CONVERSION(`std::vector< Glib::RefPtr<TlsCertificate> >',`GList*',
 #m4  `g_list_copy_deep(Glib::ListHandler< Glib::RefPtr<TlsCertificate> >::vector_to_list($3).data(), list_copy_ref, nullptr)')
 #m4 _CONVERSION(`GByteArray*',`const Glib::RefPtr<Glib::ByteArray>&',`Glib::wrap($3, true)')
 
-  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(
-    const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction,
-    const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}), "lookup_certificates_issued_by", errthrow)
-  _WRAP_VFUNC(void lookup_certificates_issued_by_async(
-    const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction,
-    const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, LookupFlags flags{.}),
-    "lookup_certificates_issued_by_async", slot_name slot, slot_callback SignalProxy_async_callback)
-  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by_finish(
-    const Glib::RefPtr<AsyncResult>& result), "lookup_certificates_issued_by_finish", errthrow)
+  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by", errthrow)
+  _WRAP_VFUNC(void lookup_certificates_issued_by_async(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificates_issued_by_finish", errthrow)
 };
 
 } // namespace Gio
index 0113229..1fa26f5 100644 (file)
@@ -28,9 +28,6 @@ typedef struct _GTlsFileDatabaseInterface GTlsFileDatabaseInterface;
 
 namespace Gio
 {
-// It's unusual that a subclass of Glib::Object is a base class of an interface.
-// For a discussion, see https://bugzilla.gnome.org/show_bug.cgi?id=776537
-// especially the last paragraph of comment 6.
 
 /** TlsFileDatabase - TLS file based database type.
  * TlsFileDatabase is implemented by TlsDatabase objects which load their
@@ -39,15 +36,16 @@ namespace Gio
  *
  * @newin{2,36}
  */
-class TlsFileDatabase
+class GIOMM_API TlsFileDatabase
 : public Glib::Interface,
   public TlsDatabase
 {
-  _CLASS_INTERFACE(TlsFileDatabase, GTlsFileDatabase, G_TLS_FILE_DATABASE, GTlsFileDatabaseInterface)
+  _CLASS_INTERFACE(TlsFileDatabase, GTlsFileDatabase, G_TLS_FILE_DATABASE, GTlsFileDatabaseInterface, , , GIOMM_API)
 
 public:
-  // It's not possible to use _WRAP_CTOR/_WRAP_CREATE to wrap the new
-  // function because this is an interface.
+  //TODO: It is not possible to use _WRAP_CTOR()/WRAP_CREATE() here because this
+  //class is an interface.
+  //  So, should we make it possible to use them? murrayc.
 #m4 _CONVERSION(`GTlsDatabase*',`Glib::RefPtr<TlsFileDatabase>',`Glib::wrap(G_TLS_FILE_DATABASE($3))')
   _WRAP_METHOD(static Glib::RefPtr<TlsFileDatabase> create(const std::string& anchors), g_tls_file_database_new, errthrow)
 
index bcb3ec6..ed1ed01 100644 (file)
@@ -28,8 +28,8 @@ namespace Gio
 _WRAP_ENUM(TlsInteractionResult, GTlsInteractionResult)
 _WRAP_ENUM(TlsCertificateRequestFlags, GTlsCertificateRequestFlags)
 
-class Cancellable;
-class TlsPassword;
+class GIOMM_API Cancellable;
+class GIOMM_API TlsPassword;
 
 /** TlsInteraction - Interaction with the user during TLS operations.
  * TlsInteraction provides a mechanism for the TLS connection and database code
@@ -53,9 +53,9 @@ class TlsPassword;
  * finish method.
  * @newin{2,36}
  */
-class TlsInteraction : public Glib::Object
+class GIOMM_API TlsInteraction : public Glib::Object
 {
-  _CLASS_GOBJECT(TlsInteraction, GTlsInteraction, G_TLS_INTERACTION, Glib::Object, GObject)
+  _CLASS_GOBJECT(TlsInteraction, GTlsInteraction, G_TLS_INTERACTION, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
   _CTOR_DEFAULT
@@ -66,6 +66,8 @@ public:
   _WRAP_METHOD(TlsInteractionResult ask_password_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_interaction_ask_password_finish, errthrow)
   _WRAP_METHOD(TlsInteractionResult invoke_ask_password(const Glib::RefPtr<TlsPassword>& password, const Glib::RefPtr<Cancellable>& cancellable{?}), g_tls_interaction_invoke_ask_password, errthrow)
 
+
+
   _WRAP_METHOD(TlsInteractionResult invoke_request_certificate(const Glib::RefPtr<TlsConnection>& connection, TlsCertificateRequestFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}), g_tls_interaction_invoke_request_certificate, errthrow)
 
   _WRAP_METHOD(TlsInteractionResult request_certificate(const Glib::RefPtr<TlsConnection>& connection, TlsCertificateRequestFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}), g_tls_interaction_request_certificate, errthrow)
@@ -74,7 +76,7 @@ public:
 
   _WRAP_METHOD(TlsInteractionResult request_certificate_finish(const Glib::RefPtr<AsyncResult>& result), g_tls_interaction_request_certificate_finish, errthrow)
 
-protected:
+
 #m4 _CONVERSION(`GTlsPassword*',`const Glib::RefPtr<TlsPassword>&',`Glib::wrap($3, true)')
   _WRAP_VFUNC(TlsInteractionResult ask_password(const Glib::RefPtr<TlsPassword>& password, const Glib::RefPtr<Cancellable>& cancellable), "ask_password", errthrow)
   _WRAP_VFUNC(void ask_password_async(const Glib::RefPtr<TlsPassword>& password, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}), "ask_password_async", slot_name slot, slot_callback SignalProxy_async_callback)
index c51f24b..8cba83c 100644 (file)
@@ -15,5 +15,3 @@
  */
 
 #include <gio/gio.h>
-
-using Flags = Gio::TlsPassword::Flags;
index e314af8..12e8baf 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 
 _DEFS(giomm,gio)
@@ -22,24 +24,22 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
+_WRAP_ENUM(TlsPasswordFlags, GTlsPasswordFlags)
 
 /** TlsPassword - TLS Passwords for prompting.
  * Holds a password used in TLS.
  * @newin{2,36}
  */
-class TlsPassword : public Glib::Object
+class GIOMM_API TlsPassword : public Glib::Object
 {
-  _CLASS_GOBJECT(TlsPassword, GTlsPassword, G_TLS_PASSWORD, Glib::Object, GObject)
-
-public:
-  _WRAP_ENUM(Flags, GTlsPasswordFlags)
+  _CLASS_GOBJECT(TlsPassword, GTlsPassword, G_TLS_PASSWORD, Glib::Object, GObject, , , GIOMM_API)
 
 protected:
-  _WRAP_CTOR(TlsPassword(const Glib::ustring& description{.}, Flags flags{.} = Flags::NONE), g_tls_password_new)
+  _WRAP_CTOR(TlsPassword(const Glib::ustring& description{.}, TlsPasswordFlags flags{.} = Gio::TLS_PASSWORD_NONE), g_tls_password_new)
 
 public:
   _WRAP_METHOD_DOCS_ONLY(g_tls_password_new)
-  _WRAP_CREATE(const Glib::ustring& description{.}, Flags flags{.} = Flags::NONE)
+  _WRAP_CREATE(const Glib::ustring& description{.}, TlsPasswordFlags flags{.} = Gio::TLS_PASSWORD_NONE)
 
   _WRAP_METHOD(const guchar* get_value(gsize& length{?}) const, g_tls_password_get_value)
 
@@ -52,17 +52,16 @@ public:
   _WRAP_METHOD(Glib::ustring get_description() const, g_tls_password_get_description)
   _WRAP_METHOD(void set_description(const Glib::ustring& description), g_tls_password_set_description)
 
-  _WRAP_METHOD(Flags get_flags() const, g_tls_password_get_flags)
-  _WRAP_METHOD(void set_flags(Flags flags), g_tls_password_set_flags)
+  _WRAP_METHOD(TlsPasswordFlags get_flags() const, g_tls_password_get_flags)
+  _WRAP_METHOD(void set_flags(TlsPasswordFlags flags), g_tls_password_set_flags)
 
   _WRAP_METHOD(Glib::ustring get_warning() const, g_tls_password_get_warning)
   _WRAP_METHOD(void set_warning(const Glib::ustring& warning), g_tls_password_set_warning)
 
   _WRAP_PROPERTY("description", Glib::ustring)
-  _WRAP_PROPERTY("flags", Flags)
+  _WRAP_PROPERTY("flags", TlsPasswordFlags)
   _WRAP_PROPERTY("warning", Glib::ustring)
 
-protected:
 #m4 _CONVERSION(`gsize*', `gsize&', `*($3)')
   _WRAP_VFUNC(const guchar* get_value(gsize& length) const, "get_value")
 
index 67bd0a9..7b4c8b8 100644 (file)
@@ -28,23 +28,20 @@ typedef struct _GTlsServerConnectionInterface GTlsServerConnectionInterface;
 
 namespace Gio
 {
-// It's unusual that a subclass of Glib::Object is a base class of an interface.
-// For a discussion, see https://bugzilla.gnome.org/show_bug.cgi?id=776537
-// especially the last paragraph of comment 6.
 
 /** TlsServerConnection - TLS server-side connection.
  * TlsServerConnection is the server-side subclass of TlsConnection,
  * representing a server-side TLS connection.
  * @newin{2,36}
  */
-class TlsServerConnection : public Glib::Interface, public TlsConnection
+class GIOMM_API TlsServerConnection : public Glib::Interface, public TlsConnection
 {
-  _CLASS_INTERFACE(TlsServerConnection, GTlsServerConnection, G_TLS_SERVER_CONNECTION, GTlsServerConnectionInterface)
+  _CLASS_INTERFACE(TlsServerConnection, GTlsServerConnection, G_TLS_SERVER_CONNECTION, GTlsServerConnectionInterface, , , GIOMM_API)
   _CUSTOM_CTOR_CAST
 
 public:
-  // It's not possible to use _WRAP_CTOR/_WRAP_CREATE to wrap the new
-  // function because this is an interface.
+  //TODO: It's not possible to use _WRAP_CTOR/_WRAP_CREATE to wrap the new
+  //function because this is an interface.
 #m4 _CONVERSION(`GIOStream*',`Glib::RefPtr<TlsServerConnection>',`Glib::wrap(G_TLS_SERVER_CONNECTION($3))')
   _WRAP_METHOD(static Glib::RefPtr<IOStream> create(const Glib::RefPtr<IOStream>& base_io_stream, const Glib::RefPtr<TlsCertificate>& certificate), g_tls_server_connection_new, errthrow)
 
index 1ddd1d2..3b157ab 100644 (file)
@@ -35,9 +35,9 @@ namespace Gio
  * @newin{2,24}
  * @ingroup NetworkIO
  */
-class UnixConnection : public Gio::SocketConnection
+class GIOMM_API UnixConnection : public Gio::SocketConnection
 {
-    _CLASS_GOBJECT(UnixConnection, GUnixConnection, G_UNIX_CONNECTION, Gio::SocketConnection, GSocketConnection)
+    _CLASS_GOBJECT(UnixConnection, GUnixConnection, G_UNIX_CONNECTION, Gio::SocketConnection, GSocketConnection, , , GIOMM_API)
     _GTKMMPROC_WIN32_NO_WRAP
 
 public:
index 9ba8239..49eb02e 100644 (file)
@@ -22,7 +22,7 @@ _PINCLUDE(giomm/private/socketcontrolmessage_p.h)
 namespace Gio
 {
 
-class Credentials;
+class GIOMM_API Credentials;
 
 /** UnixCredentialsMessage - A SocketControlMessage containing credentials.
  * This SocketControlMessage contains a Credentials instance. It may be sent
@@ -37,9 +37,9 @@ class Credentials;
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class UnixCredentialsMessage : public SocketControlMessage
+class GIOMM_API UnixCredentialsMessage : public SocketControlMessage
 {
-  _CLASS_GOBJECT(UnixCredentialsMessage, GUnixCredentialsMessage, G_UNIX_CREDENTIALS_MESSAGE, Gio::SocketControlMessage, GSocketControlMessage)
+  _CLASS_GOBJECT(UnixCredentialsMessage, GUnixCredentialsMessage, G_UNIX_CREDENTIALS_MESSAGE, Gio::SocketControlMessage, GSocketControlMessage, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
 protected:
index 5a66bd2..f35d700 100644 (file)
@@ -20,7 +20,7 @@
 namespace Gio
 {
 
-UnixFDList::UnixFDList(const std::vector<int>&  fds)
+UnixFDList::UnixFDList(const Glib::ArrayHandle<int>& fds)
 : // Mark this class as non-derived to allow C++ vfuncs to be skipped.
   Glib::ObjectBase(nullptr),
   // g_unix_fd_list_new_from_array() must be called.
@@ -28,11 +28,11 @@ UnixFDList::UnixFDList(const std::vector<int>&  fds)
   // _CONSTRUCT() + g_unit_fd_list_append() is not an alternative.
   // g_unit_fd_list_append() duplicates the file descriptor,
   // but g_unix_fd_list_new_from_array() does not.
-  Glib::Object((GObject*)g_unix_fd_list_new_from_array(Glib::ArrayHandler<int>::vector_to_array(fds).data(), fds.size()))
+  Glib::Object((GObject*)g_unix_fd_list_new_from_array(fds.data(), fds.size()))
 {
 }
 
-UnixFDList::UnixFDList(const std::vector<int>&  fds, int n_fds)
+UnixFDList::UnixFDList(const Glib::ArrayHandle<int>& fds, int n_fds)
 : // Mark this class as non-derived to allow C++ vfuncs to be skipped.
   Glib::ObjectBase(nullptr),
   // g_unix_fd_list_new_from_array() must be called.
@@ -40,28 +40,28 @@ UnixFDList::UnixFDList(const std::vector<int>&  fds, int n_fds)
   // _CONSTRUCT() + g_unit_fd_list_append() is not an alternative.
   // g_unit_fd_list_append() duplicates the file descriptor,
   // but g_unix_fd_list_new_from_array() does not.
-  Glib::Object((GObject*)g_unix_fd_list_new_from_array(Glib::ArrayHandler<int>::vector_to_array(fds).data(), n_fds))
+  Glib::Object((GObject*)g_unix_fd_list_new_from_array(fds.data(), n_fds))
 {
 }
 
-const std::vector<int>
+const Glib::ArrayHandle<int>
 UnixFDList::peek_fds() const
 {
   int length = 0;
   const auto fds = g_unix_fd_list_peek_fds(const_cast<GUnixFDList*>(gobj()), &length);
   // The array is terminated with a -1, but that terminating element is
   // not included in the length that g_unix_fd_list_peek_fds() returns.
-  return Glib::ArrayHandler<int>::array_to_vector(fds, length, Glib::OWNERSHIP_NONE);
+  return Glib::ArrayHandle<int>(fds, length, Glib::OWNERSHIP_NONE);
 }
 
-std::vector<int>
+Glib::ArrayHandle<int>
 UnixFDList::steal_fds()
 {
   int length = 0;
   const auto fds = g_unix_fd_list_steal_fds(gobj(), &length);
   // The array is terminated with a -1, but that terminating element is
   // not included in the length that g_unix_fd_list_steal_fds() returns.
-  return Glib::ArrayHandler<int>::array_to_vector(fds, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<int>(fds, length, Glib::OWNERSHIP_DEEP);
 }
 
 } // namespace Gio
index f3885a1..0f06dcc 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
+#include <glibmm/arrayhandle.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -33,18 +36,18 @@ namespace Gio
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class UnixFDList : public Glib::Object
+class GIOMM_API UnixFDList : public Glib::Object
 {
-  _CLASS_GOBJECT(UnixFDList, GUnixFDList, G_UNIX_FD_LIST, Glib::Object, GObject)
+  _CLASS_GOBJECT(UnixFDList, GUnixFDList, G_UNIX_FD_LIST, Glib::Object, GObject, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
 protected:
   _CTOR_DEFAULT
   _IGNORE(g_unix_fd_list_new)
 
-  explicit UnixFDList(const std::vector<int>&  fds);
+  explicit UnixFDList(const Glib::ArrayHandle<int>& fds);
 
-  explicit UnixFDList(const std::vector<int>&  fds, int n_fds);
+  explicit UnixFDList(const Glib::ArrayHandle<int>& fds, int n_fds);
   _IGNORE(g_unix_fd_list_new_from_array)
 
 public:
@@ -59,13 +62,13 @@ public:
    * @param fds The list of file descriptors to use for creation.
    * @return A new UnixFDList.
    */
-  _WRAP_CREATE(const std::vector<int>&  fds)
+  _WRAP_CREATE(const Glib::ArrayHandle<int>& fds)
 
   _WRAP_METHOD_DOCS_ONLY(g_unix_fd_list_new_from_array)
-  _WRAP_CREATE(const std::vector<int>&  fds, int n_fds)
+  _WRAP_CREATE(const Glib::ArrayHandle<int>& fds, int n_fds)
 
   _WRAP_METHOD(int get_length() const, g_unix_fd_list_get_length)
-  _WRAP_METHOD(int get(int index) const, g_unix_fd_list_get, errthrow "Gio::Error")
+  _WRAP_METHOD(int get(int index) const, g_unix_fd_list_get, errthrow)
 
   /** Returns the array of file descriptors that is contained in this object.
    *
@@ -76,7 +79,7 @@ public:
    *
    * @newin{2,28}
    */
-  const std::vector<int> peek_fds() const;
+  const Glib::ArrayHandle<int> peek_fds() const;
   _IGNORE(g_unix_fd_list_peek_fds)
 
   /** Returns the array of file descriptors that is contained in this object.
@@ -91,12 +94,12 @@ public:
    *
    * @newin{2,28}
    */
-  std::vector<int> steal_fds();
+  Glib::ArrayHandle<int> steal_fds();
   _IGNORE(g_unix_fd_list_steal_fds)
 
   _WRAP_METHOD_DOCS_ONLY(g_unix_fd_list_append)
   ///@throw Glib::Error.
-  _WRAP_METHOD(int append(int fd), g_unix_fd_list_append, errthrow "Gio::Error")
+  _WRAP_METHOD(int append(int fd), g_unix_fd_list_append, errthrow)
 };
 
 } // namespace Gio
index 53ea803..b7b6f55 100644 (file)
 namespace Gio
 {
 
-std::vector<int>
+Glib::ArrayHandle<int>
 UnixFDMessage::steal_fds()
 {
   int length = 0;
   const auto fds = g_unix_fd_message_steal_fds(gobj(), &length);
   // The array is terminated with a -1, but that terminating element is
   // not included in the length that g_unix_fd_message_steal_fds() returns.
-  return Glib::ArrayHandler<int>::array_to_vector(fds, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<int>(fds, length, Glib::OWNERSHIP_DEEP);
 }
 
 } // namespace Gio
index 3398a0c..4b065b2 100644 (file)
@@ -14,6 +14,7 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmm/arrayhandle.h>
 #include <giomm/socketcontrolmessage.h>
 
 _DEFS(giomm,gio)
@@ -22,7 +23,7 @@ _PINCLUDE(giomm/private/socketcontrolmessage_p.h)
 namespace Gio
 {
 
-class UnixFDList;
+class GIOMM_API UnixFDList;
 
 /** UnixFDMessage â€” A GSocketControlMessage containing a GUnixFDList.
  * This SocketControlMessage contains a UnixFDList. It may be sent using
@@ -37,9 +38,9 @@ class UnixFDList;
  * @ingroup NetworkIO
  * @newin{2,28}
  */
-class UnixFDMessage : public SocketControlMessage
+class GIOMM_API UnixFDMessage : public SocketControlMessage
 {
-  _CLASS_GOBJECT(UnixFDMessage, GUnixFDMessage, G_UNIX_FD_MESSAGE, Gio::SocketControlMessage, GSocketControlMessage)
+  _CLASS_GOBJECT(UnixFDMessage, GUnixFDMessage, G_UNIX_FD_MESSAGE, Gio::SocketControlMessage, GSocketControlMessage, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
 protected:
@@ -56,7 +57,7 @@ public:
   _WRAP_METHOD(Glib::RefPtr<UnixFDList> get_fd_list(), g_unix_fd_message_get_fd_list, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const UnixFDList> get_fd_list() const, g_unix_fd_message_get_fd_list, refreturn, constversion)
 
-  _WRAP_METHOD(bool append_fd(int fd), g_unix_fd_message_append_fd, errthrow "Gio::Error")
+  _WRAP_METHOD(bool append_fd(int fd), g_unix_fd_message_append_fd, errthrow)
 
   /** Returns the array of file descriptors that is contained in this object.
    *
@@ -70,7 +71,7 @@ public:
    *
    * @newin{2,28}
    */
-  std::vector<int> steal_fds();
+  Glib::ArrayHandle<int> steal_fds();
   _IGNORE(g_unix_fd_message_steal_fds)
 
   _WRAP_PROPERTY("fd-list", Glib::RefPtr<UnixFDList>)
index b3521cd..b299e9c 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -15,8 +17,6 @@
  */
 
 #include <giomm/inputstream.h>
-#include <giomm/pollableinputstream.h>
-#include <giomm/filedescriptorbased.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(giomm/private/inputstream_p.h)
@@ -33,12 +33,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class UnixInputStream
-: public Gio::InputStream, public PollableInputStream, public FileDescriptorBased
+class GIOMM_API UnixInputStream : public Gio::InputStream
 {
-  _CLASS_GOBJECT(UnixInputStream, GUnixInputStream, G_UNIX_INPUT_STREAM, Gio::InputStream, GInputStream)
-  _IMPLEMENTS_INTERFACE(PollableInputStream)
-  _IMPLEMENTS_INTERFACE(FileDescriptorBased)
+  _CLASS_GOBJECT(UnixInputStream, GUnixInputStream, G_UNIX_INPUT_STREAM, Gio::InputStream, GInputStream, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
 protected:
index 7c8f2f6..f815de6 100644 (file)
@@ -32,11 +32,11 @@ namespace Gio
 // TODO: GUnixMount seems to be hidden (the gunixmount.h header is not installed.)
 // But we do need to wrap GUnixMountPoint, GUnixMountEntry and GUnixMountMonitor from gunixmounts.h - notice the s. murrayc.
 /*
-class UnixMount
+class GIOMM_API UnixMount
 : public Glib::Object,
   public Mount
 {
-  _CLASS_GOBJECT(UnixMount, GUnixMount, G_UNIX_MOUNT, Glib::Object, GObject)
+  _CLASS_GOBJECT(UnixMount, GUnixMount, G_UNIX_MOUNT, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Mount)
   _GTKMMPROC_WIN32_NO_WRAP
 };
index 5f00910..5850fc5 100644 (file)
@@ -1,3 +1,5 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -15,8 +17,6 @@
  */
 
 #include <giomm/outputstream.h>
-#include <giomm/pollableoutputstream.h>
-#include <giomm/filedescriptorbased.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(giomm/private/outputstream_p.h)
@@ -32,12 +32,9 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class UnixOutputStream
-: public Gio::OutputStream, public PollableOutputStream, public FileDescriptorBased
+class GIOMM_API UnixOutputStream : public Gio::OutputStream
 {
-  _CLASS_GOBJECT(UnixOutputStream, GUnixOutputStream, G_UNIX_OUTPUT_STREAM, Gio::OutputStream, GOutputStream)
-  _IMPLEMENTS_INTERFACE(PollableOutputStream)
-  _IMPLEMENTS_INTERFACE(FileDescriptorBased)
+  _CLASS_GOBJECT(UnixOutputStream, GUnixOutputStream, G_UNIX_OUTPUT_STREAM, Gio::OutputStream, GOutputStream, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
 protected:
index b3751af..9c8b042 100644 (file)
 
 #include <gio/gunixsocketaddress.h>
 
-using Type = Gio::UnixSocketAddress::Type;
-
 namespace Gio
 {
 
 Glib::RefPtr<UnixSocketAddress>
-UnixSocketAddress::create(const std::string& path, Type type, int path_len)
+UnixSocketAddress::create(const std::string& path, UnixSocketAddressType type, int path_len)
 {
   return Glib::wrap(reinterpret_cast<GUnixSocketAddress*>(g_unix_socket_address_new_with_type(
     path.c_str(), path_len, static_cast<GUnixSocketAddressType>(type))));
index cfbeac6..25cbb6e 100644 (file)
@@ -21,13 +21,13 @@ _CONFIGINCLUDE(giommconfig.h)
 _DEFS(giomm,gio)
 _PINCLUDE(giomm/private/socketaddress_p.h)
 
-namespace Glib
-{
-class ByteArray;
-}
-
 namespace Gio
 {
+
+_WRAP_ENUM(UnixSocketAddressType, GUnixSocketAddressType)
+
+class GLIBMM_API ByteArray;
+
 /** UnixSocketAddress - UNIX SocketAddress.
  * Support for UNIX-domain (also known as local) sockets.
  *
@@ -45,21 +45,18 @@ namespace Gio
  * @newin{2,28}
  * @ingroup NetworkIO
  */
-class UnixSocketAddress
+class GIOMM_API UnixSocketAddress
 : public SocketAddress
 {
-  _CLASS_GOBJECT(UnixSocketAddress, GUnixSocketAddress, G_UNIX_SOCKET_ADDRESS, SocketAddress, GSocketAddress)
+  _CLASS_GOBJECT(UnixSocketAddress, GUnixSocketAddress, G_UNIX_SOCKET_ADDRESS, SocketAddress, GSocketAddress, , , GIOMM_API)
   _GTKMMPROC_WIN32_NO_WRAP
 
-public:
-  _WRAP_ENUM(Type, GUnixSocketAddressType)
-
 protected:
  _WRAP_CTOR(UnixSocketAddress(const std::string& path), g_unix_socket_address_new)
 
  //TODO: Possibly add when g_unix_socket_address_new_with_type() does not do
  //more than call g_object_new() (maybe file a bug).
- //_WRAP_CTOR(UnixSocketAddress(const std::string& path, int path_len = -1, Type type = Type::PATH), g_unix_socket_address_new_with_type)
+ //_WRAP_CTOR(UnixSocketAddress(const std::string& path, int path_len = -1, UnixSocketAddressType type = Gio::UNIX_SOCKET_ADDRESS_PATH), g_unix_socket_address_new_with_type)
 
 public:
  _WRAP_METHOD_DOCS_ONLY(g_unix_socket_address_new)
@@ -68,25 +65,25 @@ public:
  //TODO: Add when the above constructor is included, removing the handwritten
  //create() method for it below.
  //_WRAP_METHOD_DOCS_ONLY(g_unix_socket_address_new_with_type)
- //_WRAP_CREATE(const std::string& path, int path_len = -1, Type type = Type::PATH)
+ //_WRAP_CREATE(const std::string& path, int path_len = -1, UnixSocketAddressType type = Gio::UNIX_SOCKET_ADDRESS_PATH)
 
  _WRAP_METHOD_DOCS_ONLY(g_unix_socket_address_new_with_type)
  static Glib::RefPtr<UnixSocketAddress> create(const std::string& path,
-   Type type, int path_len = -1);
+   UnixSocketAddressType type, int path_len = -1);
 
  // Deprecated.
  _IGNORE(g_unix_socket_address_get_is_abstract)
 
- _WRAP_METHOD(Type get_address_type() const, g_unix_socket_address_get_address_type)
+ _WRAP_METHOD(UnixSocketAddressType get_address_type() const, g_unix_socket_address_get_address_type)
  _WRAP_METHOD(std::string get_path() const, g_unix_socket_address_get_path)
  _IGNORE(g_unix_socket_address_get_path_len)
 
  _WRAP_METHOD(static bool abstract_names_supported(), g_unix_socket_address_abstract_names_supported)
 
-  _IGNORE_PROPERTY("abstract")
-  _WRAP_PROPERTY("address-type", Type)
+  _WRAP_PROPERTY("abstract", bool, deprecated "Use property_address_type() instead, which distinguishes between zero-padded and non-zero-padded abstract addresses.")
+  _WRAP_PROPERTY("address-type", UnixSocketAddressType)
   _WRAP_PROPERTY("path", std::string)
-  _WRAP_PROPERTY("path-as-array", Glib::RefPtr<Glib::ByteArray>)
+  _WRAP_PROPERTY("path-as-array", Glib::RefPtr<ByteArray>)
 };
 
 } // namespace Gio
index e0ad7c4..2d1d01a 100644 (file)
@@ -26,7 +26,7 @@ namespace Gio
 
 void
 Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -39,7 +39,7 @@ Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsy
 
 void
 Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  Mount::MountFlags flags)
+  MountMountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -52,7 +52,7 @@ Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsy
 }
 
 void
-Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, Mount::MountFlags flags)
+Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, MountMountFlags flags)
 {
   g_volume_mount(gobj(), static_cast<GMountMountFlags>(flags), Glib::unwrap(mount_operation),
     nullptr, // cancellable
@@ -60,7 +60,7 @@ Volume::mount(const Glib::RefPtr<MountOperation>& mount_operation, Mount::MountF
 }
 
 void
-Volume::mount(Mount::MountFlags flags)
+Volume::mount(MountMountFlags flags)
 {
   g_volume_mount(gobj(), static_cast<GMountMountFlags>(flags), nullptr,
     nullptr, // cancellable
@@ -69,7 +69,7 @@ Volume::mount(Mount::MountFlags flags)
 
 void
 Volume::eject(
-  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -82,7 +82,7 @@ Volume::eject(
 }
 
 void
-Volume::eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
+Volume::eject(const SlotAsyncReady& slot, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -96,7 +96,7 @@ Volume::eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags)
 }
 
 void
-Volume::eject(Mount::UnmountFlags flags)
+Volume::eject(MountUnmountFlags flags)
 {
   g_volume_eject_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     nullptr, // mount_operation
@@ -107,7 +107,7 @@ Volume::eject(Mount::UnmountFlags flags)
 
 void
 Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags)
+  const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -121,7 +121,7 @@ Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsy
 
 void
 Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot,
-  Mount::UnmountFlags flags)
+  MountUnmountFlags flags)
 {
   // Create a copy of the slot.
   // A pointer to it will be passed through the callback's data parameter
@@ -135,7 +135,7 @@ Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsy
 }
 
 void
-Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags)
+Volume::eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags)
 {
   g_volume_eject_with_operation(gobj(), static_cast<GMountUnmountFlags>(flags),
     Glib::unwrap(mount_operation),
index 4bad6c4..03b3f61 100644 (file)
@@ -33,8 +33,8 @@ namespace Gio
 
 // Making a forward declaration here to avoid circular dependency.
 // file.hg already includes volume.h.
-class File;
-class Drive;
+class GIOMM_API File;
+class GIOMM_API Drive;
 
 /** The Volume interface represents user-visible objects that can be mounted.
  *
@@ -50,9 +50,9 @@ class Drive;
  *
  * @newin{2,16}
  */
-class Volume : public Glib::Interface
+class GIOMM_API Volume : public Glib::Interface
 {
-  _CLASS_INTERFACE(Volume, GVolume, G_DRIVE, GVolumeIface)
+  _CLASS_INTERFACE(Volume, GVolume, G_DRIVE, GVolumeIface, , , GIOMM_API)
 public:
   _WRAP_METHOD(std::string get_name() const, g_volume_get_name)
   _WRAP_METHOD(std::string get_uuid() const, g_volume_get_uuid)
@@ -97,7 +97,7 @@ public:
    * @param cancellable A cancellable object which can be used to cancel the operation.
    * @param flags Flags affecting the operation.
    */
-  void mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a volume.
    * This is an asynchronous operation, and is finished by calling mount_finish() with the AsyncResult data returned in the callback slot.
@@ -106,20 +106,20 @@ public:
    * @param slot A callback which will be called when the operation is completed or canceled.
    * @param flags Flags affecting the operation.
    */
-  void mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a volume.
    *
    * @param mount_operation A mount operation.
    * @param flags Flags affecting the operation.
    */
-  void mount(const Glib::RefPtr<MountOperation>& mount_operation, Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount(const Glib::RefPtr<MountOperation>& mount_operation, MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   /** Mounts a volume.
    *
    * @param flags Flags affecting the operation.
    */
-  void mount(Mount::MountFlags flags = Mount::MountFlags::NONE);
+  void mount(MountMountFlags flags = MOUNT_MOUNT_NONE);
 
   _IGNORE(g_volume_mount)
 
@@ -127,12 +127,12 @@ public:
                g_volume_mount_finish,
                errthrow)
 
-  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
-  void eject(const Glib::RefPtr<MountOperation>& mount_operation, Mount::UnmountFlags flags = Mount::UnmountFlags::NONE);
+  void eject(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, const SlotAsyncReady& slot, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
+  void eject(const Glib::RefPtr<MountOperation>& mount_operation, MountUnmountFlags flags = MOUNT_UNMOUNT_NONE);
   _IGNORE(g_volume_eject)
   _IGNORE(g_volume_eject_with_operation)
 
@@ -144,8 +144,8 @@ public:
   _WRAP_METHOD(std::string get_identifier(const std::string& kind) const,
                g_volume_get_identifier)
 
-  #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::ustring> enumerate_identifiers() const,
+  #m4 _CONVERSION(`char**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::StringArrayHandle enumerate_identifiers() const,
                g_volume_enumerate_identifiers)
 
   _WRAP_METHOD(Glib::RefPtr<File> get_activation_root(), g_volume_get_activation_root)
@@ -156,7 +156,6 @@ public:
   _WRAP_SIGNAL(void changed(), changed)
   _WRAP_SIGNAL(void removed(), removed)
 
-protected:
   //_WRAP_VFUNC(std::string get_name(), get_name)
   //_WRAP_VFUNC(Glib::RefPtr<Icon> get_icon(), get_icon)
   //_WRAP_VFUNC(std::string get_uuid(), get_uuid)
@@ -188,6 +187,7 @@ namespace Glib
 {
 
 //Pre-declare this so we can use it in TypeTrait:
+GIOMM_API
 Glib::RefPtr<Gio::Volume> wrap(GVolume* object, bool take_copy);
 
 namespace Container_Helpers
@@ -199,7 +199,7 @@ namespace Container_Helpers
  * would not return a wrapper for an interface.
  */
 template <>
-struct TypeTraits< Glib::RefPtr<Gio::Volume> >
+struct GIOMM_API TypeTraits< Glib::RefPtr<Gio::Volume> >
 {
   using CppType = Glib::RefPtr<Gio::Volume>;
   using CType = GVolume*;
index 2449a4d..5972536 100644 (file)
@@ -33,28 +33,29 @@ namespace Gio
  *
  * @newin{2,16}
  */
-class VolumeMonitor : public Glib::Object
+class GIOMM_API VolumeMonitor : public Glib::Object
 {
-  _CLASS_GOBJECT(VolumeMonitor, GVolumeMonitor, G_VOLUME_MONITOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(VolumeMonitor, GVolumeMonitor, G_VOLUME_MONITOR, Glib::Object, GObject, , , GIOMM_API)
 protected:
 
 public:
 
   _WRAP_METHOD(static Glib::RefPtr<VolumeMonitor> get(), g_volume_monitor_get)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Drive>>',`Glib::ListHandler<Glib::RefPtr<Drive>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<Drive>> get_connected_drives(), g_volume_monitor_get_connected_drives)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Drive> >',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Drive> > get_connected_drives(), g_volume_monitor_get_connected_drives)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Volume>>',`Glib::ListHandler<Glib::RefPtr<Volume>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<Volume>> get_volumes(), g_volume_monitor_get_volumes)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Volume> > get_volumes(), g_volume_monitor_get_volumes)
 
-#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Mount>>',`Glib::ListHandler<Glib::RefPtr<Mount>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector<Glib::RefPtr<Mount>> get_mounts(), g_volume_monitor_get_mounts)
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Mount> >',`$2($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Mount> > get_mounts(), g_volume_monitor_get_mounts)
 
   _WRAP_METHOD(Glib::RefPtr<Volume> get_volume_for_uuid(const std::string& uuid), g_volume_monitor_get_volume_for_uuid, refreturn)
   _WRAP_METHOD(Glib::RefPtr<Mount> get_mount_for_uuid(const std::string& uuid), g_volume_monitor_get_mount_for_uuid, refreturn)
 
-  _IGNORE(g_volume_monitor_adopt_orphan_mount)
+  _WRAP_METHOD(static Glib::RefPtr<Volume> adopt_orphan_mount(const Glib::RefPtr<Mount>& mount), g_volume_monitor_adopt_orphan_mount,
+    deprecated "Instead of using this function, create shadow mounts with the URI of the mount you intend to adopt.")
 
 #m4 _CONVERSION(`GVolume*',`const Glib::RefPtr<Volume>&',`Glib::wrap($3, true)')
   _WRAP_SIGNAL(void volume_added(const Glib::RefPtr<Volume>& volume), volume_added)
@@ -72,11 +73,11 @@ public:
   _WRAP_SIGNAL(void drive_disconnected(const Glib::RefPtr<Drive>& drive), drive_disconnected)
   _WRAP_SIGNAL(void drive_changed(const Glib::RefPtr<Drive>& drive), drive_changed)
 
-  _WRAP_SIGNAL(void drive_eject_button(const Glib::RefPtr<Drive>& drive), drive_eject_button)
-  _WRAP_SIGNAL(void drive_stop_button(const Glib::RefPtr<Drive>& drive), drive_stop_button)
+  //TODO: Remove no_default_handler when we can break ABI:
+  _WRAP_SIGNAL(void drive_eject_button(const Glib::RefPtr<Drive>& drive), drive_eject_button, no_default_handler)
+  _WRAP_SIGNAL(void drive_stop_button(const Glib::RefPtr<Drive>& drive), drive_stop_button, no_default_handler)
 
-protected:
-  //TODO: Use ListHandler?
+  //TODO: Use ListHandle?
   //_WRAP_VFUNC(GList* get_volumes(), get_volumes)
   //_WRAP_VFUNC(GList* get_mounts(), get_mounts)
 
index 58e7cc8..a012708 100644 (file)
@@ -14,6 +14,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+_CONFIGINCLUDE(giommconfig.h)
+
 #include <glibmm/object.h>
 #include <giomm/converter.h>
 
@@ -25,16 +27,16 @@ namespace Gio
 
 _WRAP_ENUM(ZlibCompressorFormat,  GZlibCompressorFormat)
 
-class FileInfo;
+class GIOMM_API FileInfo;
 
 /** ZlibCompressor - Zlib compressor.
  * ZlibCompressor is an implementation of Converter that compresses data using
  * zlib.
  * @newin{2,34}
  */
-class ZlibCompressor : public Glib::Object, public Converter
+class GIOMM_API ZlibCompressor : public Glib::Object, public Converter
 {
-  _CLASS_GOBJECT(ZlibCompressor, GZlibCompressor, G_ZLIB_COMPRESSOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(ZlibCompressor, GZlibCompressor, G_ZLIB_COMPRESSOR, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Converter)
 
 protected:
index aab9763..7ff479a 100644 (file)
@@ -24,16 +24,16 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-class FileInfo;
+class GIOMM_API FileInfo;
 
 /** ZlibDecompressor - Zlib decompressor.
  * ZlibDecompressor is an implementation of Converter that decompresses data
  * compressed with zlib.
  * @newin{2,34}
  */
-class ZlibDecompressor : public Glib::Object, public Converter
+class GIOMM_API ZlibDecompressor : public Glib::Object, public Converter
 {
-  _CLASS_GOBJECT(ZlibDecompressor, GZlibDecompressor, G_ZLIB_DECOMPRESSOR, Glib::Object, GObject)
+  _CLASS_GOBJECT(ZlibDecompressor, GZlibDecompressor, G_ZLIB_DECOMPRESSOR, Glib::Object, GObject, , , GIOMM_API)
   _IMPLEMENTS_INTERFACE(Converter)
 
 protected:
index a7587d1..ac753ce 100644 (file)
  * - Glib::Regex: Regular expression string matching.
  * - Glib::KeyFile: Parsing and writing of key files (similar to .ini files)
  * - Glib::Checksum
- * - Glib::Date, Glib::DateTime, Glib::Timer
+ * - Glib::Date, Glib::Timer, Glib::TimeVal
  * - Glib::Dispatcher: Inter-thread communication
  * - @ref FileUtils and @ref UriUtils
  * - @ref MainLoop
  * - @ref Spawn
+ * - @ref Threads
  * - @ref MiscUtils
  *
  * giomm (part of the glibmm project) also contains:
  *
  * If your  source file is @c program.cc, you can compile it with:
  * @code
- * g++ program.cc -o program  `pkg-config --cflags --libs glibmm-2.64 giomm-2.64`
+ * g++ program.cc -o program  `pkg-config --cflags --libs glibmm-2.4 giomm-2.4`
  * @endcode
  *
  * Alternatively, if using autoconf, use the following in @c configure.ac:
  * @code
- * PKG_CHECK_MODULES([GLIBMM], [glibmm-2.64 giomm-2.64])
+ * PKG_CHECK_MODULES([GLIBMM], [glibmm-2.4 giomm-2.4])
  * @endcode
  * Then use the generated @c GLIBMM_CFLAGS and @c GLIBMM_LIBS variables in the
  * project Makefile.am files. For example:
 //#include <glibmm/i18n.h> //This must be included by the application, after system headers such as
 //<iostream>.
 
+// Include this first because we need it to be the first thing to include <glib.h>,
+// so we can do an undef trick to still use deprecated API in the header:
+#include <glibmm/thread.h>
+
+#include <glibmm/threads.h>
+
+#include <glibmm/arrayhandle.h>
 #include <glibmm/balancedtree.h>
 #include <glibmm/base64.h>
 #ifndef GLIBMM_INCLUDED_FROM_WRAP_INIT_CC
 #include <glibmm/exception.h>
 #include <glibmm/exceptionhandler.h>
 #include <glibmm/fileutils.h>
+#include <glibmm/helperlist.h>
 #include <glibmm/interface.h>
 #include <glibmm/iochannel.h>
 #include <glibmm/init.h>
 #include <glibmm/keyfile.h>
+#include <glibmm/streamiochannel.h>
+#include <glibmm/listhandle.h>
 #include <glibmm/main.h>
 #include <glibmm/markup.h>
 #include <glibmm/miscutils.h>
 #include <glibmm/shell.h>
 #include <glibmm/signalproxy_connectionnode.h>
 #include <glibmm/signalproxy.h>
+#include <glibmm/slisthandle.h>
 #include <glibmm/spawn.h>
 #include <glibmm/stringutils.h>
+#include <glibmm/threadpool.h>
 #include <glibmm/timer.h>
+#include <glibmm/timeval.h>
 #include <glibmm/timezone.h>
 #include <glibmm/uriutils.h>
 #include <glibmm/ustring.h>
 #include <glibmm/value.h>
+#include <glibmm/valuearray.h>
 #include <glibmm/variant.h>
 #include <glibmm/variantdict.h>
 #include <glibmm/variantiter.h>
 #include <glibmm/varianttype.h>
 #include <glibmm/vectorutils.h>
+#include <glibmm/weakref.h>
 #include <glibmm/wrap.h>
 
 #endif /* _GLIBMM_H */
index 25e6c16..b08f62d 100644 (file)
@@ -16,6 +16,6 @@ Name: glibmm
 Description: C++ wrapper for GLib
 Version: @PACKAGE_VERSION@
 URL: http://www.gtkmm.org/
-Requires: gobject-2.0 sigc++-3.0
+Requires: gobject-2.0 sigc++-2.0
 Libs: -L${libdir} -lglibmm-@GLIBMM_API_VERSION@
 Cflags: -I${includedir}/@GLIBMM_MODULE_NAME@ -I${libdir}/@GLIBMM_MODULE_NAME@/include
diff --git a/glib/glibmm/arrayhandle.cc b/glib/glibmm/arrayhandle.cc
new file mode 100644 (file)
index 0000000..3a388b6
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (C) 2011 The glibmm 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/arrayhandle.h>
+
+namespace Glib
+{
+
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::~ArrayHandle() noexcept
+{
+  if (parray_ && ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      const CType* const pend = parray_ + size_;
+      for (const CType* p = parray_; p != pend; ++p)
+        Tr::release_c_type(*p);
+    }
+    g_free(const_cast<CType*>(parray_));
+  }
+}
+
+} // namespace Glib
diff --git a/glib/glibmm/arrayhandle.h b/glib/glibmm/arrayhandle.h
new file mode 100644 (file)
index 0000000..97319cc
--- /dev/null
@@ -0,0 +1,754 @@
+#ifndef _GLIBMM_ARRAYHANDLE_H
+#define _GLIBMM_ARRAYHANDLE_H
+
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+#include <glibmm/containerhandle_shared.h>
+
+namespace Glib
+{
+
+namespace Container_Helpers
+{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/* Count the number of elements in a 0-terminated sequence.
+ */
+template <class T>
+inline std::size_t
+compute_array_size(const T* array)
+{
+  const T* pend = array;
+
+  while (*pend)
+    ++pend;
+
+  return (pend - array);
+}
+
+/* Allocate and fill a 0-terminated array.  The size argument
+ * specifies the number of elements in the input sequence.
+ */
+template <class For, class Tr>
+typename Tr::CType*
+create_array(For pbegin, std::size_t size, Tr)
+{
+  using CType = typename Tr::CType;
+
+  CType* const array = static_cast<CType*>(g_malloc((size + 1) * sizeof(CType)));
+  CType* const array_end = array + size;
+
+  for (CType* pdest = array; pdest != array_end; ++pdest)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    *pdest = Tr::to_c_type(*&*pbegin);
+    ++pbegin;
+  }
+
+  *array_end = CType();
+  return array;
+}
+
+template <class For>
+gboolean*
+create_bool_array(For pbegin, std::size_t size)
+{
+  gboolean* const array(static_cast<gboolean*>(g_malloc((size + 1) * sizeof(gboolean))));
+  gboolean* const array_end(array + size);
+
+  for (gboolean* pdest(array); pdest != array_end; ++pdest)
+  {
+    *pdest = *pbegin;
+    ++pbegin;
+  }
+
+  *array_end = false;
+  return array;
+}
+
+/* Convert from any container that supports forward
+ * iterators and has a size() method.
+ */
+template <class Tr, class Cont>
+struct ArraySourceTraits
+{
+  using CType = typename Tr::CType;
+
+  static std::size_t get_size(const Cont& cont) { return cont.size(); }
+
+  static const CType* get_data(const Cont& cont, std::size_t size)
+  {
+    return Glib::Container_Helpers::create_array(cont.begin(), size, Tr());
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+// source traits for bools.
+template <class Cont>
+struct BoolArraySourceTraits
+{
+  using CType = gboolean;
+
+  static std::size_t get_size(const Cont& cont) { return cont.size(); }
+
+  static const CType* get_data(const Cont& cont, std::size_t size)
+  {
+    return Glib::Container_Helpers::create_bool_array(cont.begin(), size);
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+/* Convert from a 0-terminated array.  The Cont argument must be a pointer
+ * to the first element.  Note that only arrays of the C type are supported.
+ */
+template <class Tr, class Cont>
+struct ArraySourceTraits<Tr, Cont*>
+{
+  using CType = typename Tr::CType;
+
+  static std::size_t get_size(const CType* array)
+  {
+    return (array) ? Glib::Container_Helpers::compute_array_size(array) : 0;
+  }
+
+  static const CType* get_data(const CType* array, std::size_t) { return array; }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
+};
+
+template <class Tr, class Cont>
+struct ArraySourceTraits<Tr, const Cont*> : ArraySourceTraits<Tr, Cont*>
+{
+};
+
+/* Convert from a 0-terminated array.  The Cont argument must be a pointer
+ * to the first element.  Note that only arrays of the C type are supported.
+ * For consistency, the array must be 0-terminated, even though the array
+ * size is known at compile time.
+ */
+template <class Tr, class Cont, std::size_t N>
+struct ArraySourceTraits<Tr, Cont[N]>
+{
+  using CType = typename Tr::CType;
+
+  static std::size_t get_size(const CType*) { return (N - 1); }
+
+  static const CType* get_data(const CType* array, std::size_t) { return array; }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
+};
+
+template <class Tr, class Cont, std::size_t N>
+struct ArraySourceTraits<Tr, const Cont[N]> : ArraySourceTraits<Tr, Cont[N]>
+{
+};
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+/**
+ * @ingroup ContHelpers
+ */
+template <class Tr>
+class ArrayHandleIterator
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using iterator_category = std::random_access_iterator_tag;
+  using value_type = CppType;
+  using difference_type = std::ptrdiff_t;
+  using reference = value_type;
+  using pointer = void;
+
+  explicit inline ArrayHandleIterator(const CType* pos);
+
+  inline value_type operator*() const;
+  inline value_type operator[](difference_type offset) const;
+
+  inline ArrayHandleIterator<Tr>& operator++();
+  inline const ArrayHandleIterator<Tr> operator++(int);
+  // these are needed by msvc 2005 when using deque.
+  inline ArrayHandleIterator<Tr>& operator--();
+  inline const ArrayHandleIterator<Tr> operator--(int);
+
+  // All this random access stuff is only there because STL algorithms
+  // usually have optimized specializations for random access iterators,
+  // and we don't want to give away efficiency for nothing.
+  //
+  inline ArrayHandleIterator<Tr>& operator+=(difference_type rhs);
+  inline ArrayHandleIterator<Tr>& operator-=(difference_type rhs);
+  inline const ArrayHandleIterator<Tr> operator+(difference_type rhs) const;
+  inline const ArrayHandleIterator<Tr> operator-(difference_type rhs) const;
+  inline difference_type operator-(const ArrayHandleIterator<Tr>& rhs) const;
+
+  inline bool operator==(const ArrayHandleIterator<Tr>& rhs) const;
+  inline bool operator!=(const ArrayHandleIterator<Tr>& rhs) const;
+  inline bool operator<(const ArrayHandleIterator<Tr>& rhs) const;
+  inline bool operator>(const ArrayHandleIterator<Tr>& rhs) const;
+  inline bool operator<=(const ArrayHandleIterator<Tr>& rhs) const;
+  inline bool operator>=(const ArrayHandleIterator<Tr>& rhs) const;
+
+private:
+  const CType* pos_;
+};
+
+} // namespace Container_Helpers
+
+// TODO: When we can break ABI, remove this and replace uses of it with std::vector.
+// We cannot deprecate it yet, because we cannot easily deprecate methods that use it
+//- for instance, we cannot just override methods that use it as a return type.
+
+/** This is an intermediate type. When a method takes this, or returns this, you
+ * should use a standard C++ container of your choice, such as std::list or
+ * std::vector.
+ *
+ * However, this is not used in new API. We now prefer to just use std::vector,
+ * which is less flexibile, but makes the API clearer.
+ *
+ * @ingroup ContHandles
+ */
+template <class T, class Tr = Glib::Container_Helpers::TypeTraits<T>>
+class ArrayHandle
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using value_type = CppType;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using const_iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
+  using iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
+
+  template <class Cont>
+  inline ArrayHandle(const Cont& container);
+
+  // Take over ownership of an array created by GTK+ functions.
+  inline ArrayHandle(const CType* array, std::size_t array_size, Glib::OwnershipType ownership);
+  inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
+
+  // Copying clears the ownership flag of the source handle.
+  inline ArrayHandle(const ArrayHandle<T, Tr>& other);
+
+  ~ArrayHandle() noexcept;
+
+  inline const_iterator begin() const;
+  inline const_iterator end() const;
+
+  template <class U>
+  inline operator std::vector<U>() const;
+  template <class U>
+  inline operator std::deque<U>() const;
+  template <class U>
+  inline operator std::list<U>() const;
+
+  template <class Cont>
+  inline void assign_to(Cont& container) const;
+
+  template <class Out>
+  inline void copy(Out pdest) const;
+
+  inline const CType* data() const;
+  inline std::size_t size() const;
+  inline bool empty() const;
+
+private:
+  std::size_t size_;
+  const CType* parray_;
+  mutable Glib::OwnershipType ownership_;
+
+  // No copy assignment.
+  ArrayHandle<T, Tr>& operator=(const ArrayHandle<T, Tr>&);
+};
+
+template <>
+class GLIBMM_API ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>
+{
+public:
+  using Me = ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>;
+  using Tr = Container_Helpers::TypeTraits<bool>;
+
+  using CppType = Tr::CppType;
+  using CType = Tr::CType;
+
+  using value_type = CppType;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using const_iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
+  using iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
+
+  template <class Cont>
+  inline ArrayHandle(const Cont& container);
+
+  // Take over ownership of an array created by GTK+ functions.
+  inline ArrayHandle(const CType* array, std::size_t array_size, Glib::OwnershipType ownership);
+  inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
+
+  // Copying clears the ownership flag of the source handle.
+  inline ArrayHandle(const Me& other);
+
+  ~ArrayHandle() noexcept;
+
+  inline const_iterator begin() const;
+  inline const_iterator end() const;
+
+  // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
+  template <class U>
+  inline operator std::vector<U>() const
+  {
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+    return std::vector<U>(this->begin(), this->end());
+#else
+    std::vector<U> temp;
+    temp.reserve(this->size());
+    Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+    return temp;
+#endif
+  }
+
+  // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
+  template <class U>
+  inline operator std::deque<U>() const
+  {
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+    return std::deque<U>(this->begin(), this->end());
+#else
+    std::deque<U> temp;
+    Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+    return temp;
+#endif
+  }
+
+  // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
+  template <class U>
+  inline operator std::list<U>() const
+  {
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+    return std::list<U>(this->begin(), this->end());
+#else
+    std::list<U> temp;
+    Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+    return temp;
+#endif
+  }
+
+  template <class Cont>
+  inline void assign_to(Cont& container) const;
+
+  template <class Out>
+  inline void copy(Out pdest) const;
+
+  inline const CType* data() const;
+  inline std::size_t size() const;
+  inline bool empty() const;
+
+private:
+  std::size_t size_;
+  const CType* parray_;
+  mutable Glib::OwnershipType ownership_;
+
+  // No copy assignment.
+  Me& operator=(const Me&);
+};
+
+// TODO: Remove this when we can break glibmm API.
+/** If a method takes this as an argument, or has this as a return type, then you can use a standard
+ * container such as std::list<Glib::ustring> or std::vector<Glib::ustring>.
+ *
+ *
+ * However, this is not used in new API. We now prefer to just use std::vector,
+ * which is less flexibile, but makes the API clearer.
+ *
+ * @ingroup ContHandles
+ */
+using StringArrayHandle = ArrayHandle<Glib::ustring>;
+
+/***************************************************************************/
+/*  Inline implementation                                                  */
+/***************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Container_Helpers
+{
+
+/**** Glib::Container_Helpers::ArrayHandleIterator<> ***********************/
+
+template <class Tr>
+inline ArrayHandleIterator<Tr>::ArrayHandleIterator(const CType* pos) : pos_(pos)
+{
+}
+
+template <class Tr>
+inline typename ArrayHandleIterator<Tr>::value_type ArrayHandleIterator<Tr>::operator*() const
+{
+  return Tr::to_cpp_type(*pos_);
+}
+
+template <class Tr>
+inline typename ArrayHandleIterator<Tr>::value_type ArrayHandleIterator<Tr>::operator[](
+  difference_type offset) const
+{
+  return Tr::to_cpp_type(pos_[offset]);
+}
+
+template <class Tr>
+inline ArrayHandleIterator<Tr>& ArrayHandleIterator<Tr>::operator++()
+{
+  ++pos_;
+  return *this;
+}
+
+template <class Tr>
+inline const ArrayHandleIterator<Tr> ArrayHandleIterator<Tr>::operator++(int)
+{
+  return ArrayHandleIterator<Tr>(pos_++);
+}
+
+template <class Tr>
+inline ArrayHandleIterator<Tr>& ArrayHandleIterator<Tr>::operator--()
+{
+  --pos_;
+  return *this;
+}
+
+template <class Tr>
+inline const ArrayHandleIterator<Tr> ArrayHandleIterator<Tr>::operator--(int)
+{
+  return ArrayHandleIterator<Tr>(pos_--);
+}
+
+template <class Tr>
+inline ArrayHandleIterator<Tr>&
+ArrayHandleIterator<Tr>::operator+=(typename ArrayHandleIterator<Tr>::difference_type rhs)
+{
+  pos_ += rhs;
+  return *this;
+}
+
+template <class Tr>
+inline ArrayHandleIterator<Tr>&
+ArrayHandleIterator<Tr>::operator-=(typename ArrayHandleIterator<Tr>::difference_type rhs)
+{
+  pos_ -= rhs;
+  return *this;
+}
+
+template <class Tr>
+inline const ArrayHandleIterator<Tr>
+ArrayHandleIterator<Tr>::operator+(typename ArrayHandleIterator<Tr>::difference_type rhs) const
+{
+  return ArrayHandleIterator<Tr>(pos_ + rhs);
+}
+
+template <class Tr>
+inline const ArrayHandleIterator<Tr>
+ArrayHandleIterator<Tr>::operator-(typename ArrayHandleIterator<Tr>::difference_type rhs) const
+{
+  return ArrayHandleIterator<Tr>(pos_ - rhs);
+}
+
+template <class Tr>
+inline typename ArrayHandleIterator<Tr>::difference_type
+ArrayHandleIterator<Tr>::operator-(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ - rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator==(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ == rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator!=(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ != rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator<(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ < rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator>(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ > rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator<=(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ <= rhs.pos_);
+}
+
+template <class Tr>
+inline bool
+ArrayHandleIterator<Tr>::operator>=(const ArrayHandleIterator<Tr>& rhs) const
+{
+  return (pos_ >= rhs.pos_);
+}
+
+} // namespace Container_Helpers
+
+/**** Glib::ArrayHandle<> **************************************************/
+
+template <class T, class Tr>
+template <class Cont>
+inline ArrayHandle<T, Tr>::ArrayHandle(const Cont& container)
+: size_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::get_size(container)),
+  parray_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::get_data(container, size_)),
+  ownership_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::initial_ownership)
+{
+}
+
+template <class T, class Tr>
+inline ArrayHandle<T, Tr>::ArrayHandle(const typename ArrayHandle<T, Tr>::CType* array,
+  std::size_t array_size, Glib::OwnershipType ownership)
+: size_((array) ? array_size : 0), parray_(array), ownership_(ownership)
+{
+}
+
+template <class T, class Tr>
+inline ArrayHandle<T, Tr>::ArrayHandle(
+  const typename ArrayHandle<T, Tr>::CType* array, Glib::OwnershipType ownership)
+: size_((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
+  parray_(array),
+  ownership_(ownership)
+{
+}
+
+template <class T, class Tr>
+inline ArrayHandle<T, Tr>::ArrayHandle(const ArrayHandle<T, Tr>& other)
+: size_(other.size_), parray_(other.parray_), ownership_(other.ownership_)
+{
+  other.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <class T, class Tr>
+ArrayHandle<T, Tr>::~ArrayHandle() noexcept
+{
+  if (parray_ && ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      const CType* const pend = parray_ + size_;
+      for (const CType* p = parray_; p != pend; ++p)
+        Tr::release_c_type(*p);
+    }
+    g_free(const_cast<CType*>(parray_));
+  }
+}
+
+template <class T, class Tr>
+inline typename ArrayHandle<T, Tr>::const_iterator
+ArrayHandle<T, Tr>::begin() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
+}
+
+template <class T, class Tr>
+inline typename ArrayHandle<T, Tr>::const_iterator
+ArrayHandle<T, Tr>::end() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
+}
+
+template <class T, class Tr>
+template <class U>
+inline ArrayHandle<T, Tr>::operator std::vector<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::vector<U>(this->begin(), this->end());
+#else
+  std::vector<U> temp;
+  temp.reserve(this->size());
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline ArrayHandle<T, Tr>::operator std::deque<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::deque<U>(this->begin(), this->end());
+#else
+  std::deque<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline ArrayHandle<T, Tr>::operator std::list<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::list<U>(this->begin(), this->end());
+#else
+  std::list<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class Cont>
+inline void
+ArrayHandle<T, Tr>::assign_to(Cont& container) const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  container.assign(this->begin(), this->end());
+#else
+  Cont temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  container.swap(temp);
+#endif
+}
+
+template <class T, class Tr>
+template <class Out>
+inline void
+ArrayHandle<T, Tr>::copy(Out pdest) const
+{
+  std::copy(this->begin(), this->end(), pdest);
+}
+
+template <class T, class Tr>
+inline const typename ArrayHandle<T, Tr>::CType*
+ArrayHandle<T, Tr>::data() const
+{
+  return parray_;
+}
+
+template <class T, class Tr>
+inline std::size_t
+ArrayHandle<T, Tr>::size() const
+{
+  return size_;
+}
+
+template <class T, class Tr>
+inline bool
+ArrayHandle<T, Tr>::empty() const
+{
+  return (size_ == 0);
+}
+
+/**** Glib::ArrayHandle<bool> **********************************************/
+
+template <class Cont>
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(const Cont& container)
+: size_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_size(container)),
+  parray_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_data(container, size_)),
+  ownership_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::initial_ownership)
+{
+}
+
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
+  const gboolean* array, std::size_t array_size, Glib::OwnershipType ownership)
+: size_((array) ? array_size : 0), parray_(array), ownership_(ownership)
+{
+}
+
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
+  const gboolean* array, Glib::OwnershipType ownership)
+: size_((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
+  parray_(array),
+  ownership_(ownership)
+{
+}
+
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
+  const ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>& other)
+: size_(other.size_), parray_(other.parray_), ownership_(other.ownership_)
+{
+  other.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::const_iterator
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::begin() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
+}
+
+inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::const_iterator
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::end() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
+}
+
+template <class Cont>
+inline void
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::assign_to(Cont& container) const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  container.assign(this->begin(), this->end());
+#else
+  Cont temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  container.swap(temp);
+#endif
+}
+
+template <class Out>
+inline void
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::copy(Out pdest) const
+{
+  std::copy(this->begin(), this->end(), pdest);
+}
+
+inline const gboolean*
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::data() const
+{
+  return parray_;
+}
+
+inline std::size_t
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::size() const
+{
+  return size_;
+}
+
+inline bool
+ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::empty() const
+{
+  return (size_ == 0);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+#endif /* _GLIBMM_ARRAYHANDLE_H */
index 5fae475..e981dd7 100644 (file)
@@ -18,6 +18,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmmconfig.h>
+
 #include <string>
 #include <glib.h>
 
@@ -40,12 +42,14 @@ namespace Base64
  * @param break_lines Enables/disables line breaking.
  * @return The string encoded in Base-64.
  */
+GLIBMM_API
 std::string encode(const std::string& source, bool break_lines = false);
 
 /** Decode the given base64 encoded string.
  * @param source A string to decode.
  * @return The resulting decode string
  */
+GLIBMM_API
 std::string decode(const std::string& source);
 }
 
index 36c3c4b..057abed 100644 (file)
@@ -84,8 +84,21 @@ Class::register_derived_type(GType base_type, GTypeModule* module)
 }
 
 GType
+Class::clone_custom_type(const char* custom_type_name) const
+{
+  return clone_custom_type(custom_type_name, nullptr, nullptr, nullptr);
+}
+
+GType
+Class::clone_custom_type(
+  const char* custom_type_name, const interface_class_vector_type& interface_classes) const
+{
+  return clone_custom_type(custom_type_name, &interface_classes, nullptr, nullptr);
+}
+
+GType
 Class::clone_custom_type(
-  const char* custom_type_name, const interface_classes_type* interface_classes,
+  const char* custom_type_name, const interface_class_vector_type* interface_classes,
   const class_init_funcs_type* class_init_funcs, GInstanceInitFunc instance_init_func) const
 {
   std::string full_name("gtkmm__CustomObject_");
@@ -189,11 +202,11 @@ Class::custom_class_init_function(void* g_class, void* class_data)
   const class_init_funcs_type& class_init_funcs =
     *static_cast<class_init_funcs_type*>(class_data);
 
-  g_return_if_fail(!class_init_funcs.empty() && std::get<GClassInitFunc>(class_init_funcs[0]) != nullptr);
+  g_return_if_fail(!class_init_funcs.empty() && std::get<0>(class_init_funcs[0]) != nullptr);
 
   // Call the wrapper's class_init_function() to redirect
   // the vfunc and default signal handler callbacks.
-  auto init_func = std::get<GClassInitFunc>(class_init_funcs[0]);
+  GClassInitFunc init_func = std::get<0>(class_init_funcs[0]);
   (*init_func)(g_class, nullptr);
 
   GObjectClass* const gobject_class = static_cast<GObjectClass*>(g_class);
@@ -203,9 +216,9 @@ Class::custom_class_init_function(void* g_class, void* class_data)
   // Call extra class init functions, if any.
   for (std::size_t i = 1; i < class_init_funcs.size(); ++i)
   {
-    if (auto extra_init_func = std::get<GClassInitFunc>(class_init_funcs[i]))
+    if (GClassInitFunc extra_init_func = std::get<0>(class_init_funcs[i]))
     {
-      auto extra_class_data = std::get<void*>(class_init_funcs[i]);
+      void* extra_class_data = std::get<1>(class_init_funcs[i]);
       (*extra_init_func)(g_class, extra_class_data);
     }
   }
index 127b9c9..59e96a7 100644 (file)
@@ -1,6 +1,9 @@
+// -*- c++ -*-
 #ifndef _GLIBMM_CLASS_H
 #define _GLIBMM_CLASS_H
 
+/* $Id$ */
+
 /* Copyright 2001 Free Software Foundation
  * Copyright (C) 1998-2002 The gtkmm Development Team
  *
@@ -28,9 +31,9 @@
 
 namespace Glib
 {
-class Interface_Class;
+class GLIBMM_API Interface_Class;
 
-class Class
+class GLIBMM_API Class
 {
 public:
   /* No constructor/destructor:
@@ -51,14 +54,41 @@ public:
 
   inline GType get_type() const;
 
+  // TODO: Remove this method at the next ABI/API break.
+  /** Register a static custom GType, derived from the parent of this class's type.
+   * The parent type of the registered custom type is the same C class as the parent
+   * of the get_type() type. If a type with the specified name is already registered,
+   * nothing is done. register_derived_type() must have been called.
+   * @param custom_type_name The name of the registered type is
+   *        "gtkmm__CustomObject_" + canonic(custom_type_name), where canonic()
+   *        replaces special characters with '+'.
+   * @return The registered type.
+   */
+  GType clone_custom_type(const char* custom_type_name) const;
+
   /// The type that holds pointers to the interfaces of custom types.
-  using interface_classes_type = std::vector<const Interface_Class*>;
+  using interface_class_vector_type = std::vector<const Interface_Class*>;
+
   /** The type that holds pointers to extra class init functions of custom types.
    * The std::tuple contains a function pointer and a pointer to class data.
    * The class data pointer can be nullptr, if the function does not need it.
    */
   using class_init_funcs_type = std::vector<std::tuple<GClassInitFunc, void*>>;
 
+  // TODO: Remove this method at the next ABI/API break.
+  /** Register a static custom GType, derived from the parent of this class's type.
+   * The parent type of the registered custom type is the same C class as the parent
+   * of the get_type() type. If a type with the specified name is already registered,
+   * nothing is done. register_derived_type() must have been called.
+   * @param custom_type_name The name of the registered type is
+   *        "gtkmm__CustomObject_" + canonic(custom_type_name), where canonic()
+   *        replaces special characters with '+'.
+   * @param interface_classes Interfaces that the custom type implements.
+   * @return The registered type.
+   */
+  GType clone_custom_type(
+    const char* custom_type_name, const interface_class_vector_type& interface_classes) const;
+
   /** Register a static custom GType, derived from the parent of this class's type.
    * The parent type of the registered custom type is the same C class as the parent
    * of the get_type() type. If a type with the specified name is already registered,
@@ -74,7 +104,7 @@ public:
    * @return The registered type.
    */
   GType clone_custom_type(
-    const char* custom_type_name, const interface_classes_type* interface_classes,
+    const char* custom_type_name, const interface_class_vector_type* interface_classes,
     const class_init_funcs_type* class_init_funcs, GInstanceInitFunc instance_init_func) const;
 
 protected:
index e8bfd7b..21db808 100644 (file)
@@ -53,6 +53,43 @@ enum OwnershipType
   OWNERSHIP_DEEP /*!< Release the list, and its elements, when the container is deleted. */
 };
 
+/** Utility class holding an iterator sequence.
+ * @ingroup ContHandles
+ * This can be used to initialize a Glib container handle (such as
+ * Glib::ArrayHandle) with an iterator sequence.  Use the helper
+ * function Glib::sequence() to create a Sequence<> object.
+ */
+template <class Iterator>
+class Sequence
+{
+private:
+  Iterator pbegin_;
+  Iterator pend_;
+
+public:
+  Sequence(Iterator pbegin, Iterator pend) : pbegin_(pbegin), pend_(pend) {}
+
+  Iterator begin() const { return pbegin_; }
+  Iterator end() const { return pend_; }
+  std::size_t size() const { return std::distance(pbegin_, pend_); }
+};
+
+/** Helper function to create a Glib::Sequence<> object, which
+ * in turn can be used to initialize a container handle.
+ * @ingroup ContHandles
+ *
+ * @par Usage example:
+ * @code
+ * combo.set_popdown_strings(Glib::sequence(foo_begin, foo_end));
+ * @endcode
+ */
+template <class Iterator>
+inline Sequence<Iterator>
+sequence(Iterator pbegin, Iterator pend)
+{
+  return Sequence<Iterator>(pbegin, pend);
+}
+
 namespace Container_Helpers
 {
 
@@ -84,8 +121,7 @@ struct TypeTraits
 // be next to the objects that they use.
 #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
 
-/** Partial specialization for pointers to GObject instances.
- * The C++ type is not a Glib::RefPtr<>. It can be a gtkmm widget.
+/** Partial specialization for pointers to GtkObject instances.
  * @ingroup ContHelpers
  */
 template <class T>
@@ -117,8 +153,7 @@ struct TypeTraits<T*>
 // This confuse the SUN Forte compiler, so we ifdef it out:
 #ifdef GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
 
-/** Partial specialization for pointers to const GObject instances.
- * The C++ type is not a Glib::RefPtr<>. It can be a gtkmm widget.
+/** Partial specialization for pointers to const GtkObject instances.
  * @ingroup ContHelpers
  */
 template <class T>
@@ -170,7 +205,7 @@ struct TypeTraits<Glib::RefPtr<T>>
     // because that would be "dependent", and g++ 3.4 does not allow that.
     // The specific Glib::wrap() overloads don't do anything special anyway.
     GObject* cobj = (GObject*)(ptr);
-    return Glib::make_refptr_for_instance<T>(dynamic_cast<T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
+    return Glib::RefPtr<T>(dynamic_cast<T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
     // We use dynamic_cast<> in case of multiple inheritance.
   }
 
@@ -206,7 +241,7 @@ struct TypeTraits<Glib::RefPtr<const T>>
     // because that would be "dependent", and g++ 3.4 does not allow that.
     // The specific Glib::wrap() overloads don't do anything special anyway.
     GObject* cobj = (GObject*)const_cast<CTypeNonConst>(ptr);
-    return Glib::make_refptr_for_instance<const T>(
+    return Glib::RefPtr<const T>(
       dynamic_cast<const T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
     // We use dynamic_cast<> in case of multiple inheritance.
   }
@@ -229,7 +264,7 @@ struct TypeTraits<Glib::RefPtr<const T>>
  * the output type cannot be 'const char*'.
  */
 template <>
-struct TypeTraits<Glib::ustring>
+struct GLIBMM_API TypeTraits<Glib::ustring>
 {
   using CppType = Glib::ustring;
   using CType = const char*;
@@ -251,7 +286,7 @@ struct TypeTraits<Glib::ustring>
  * cannot be 'const char*'.
  */
 template <>
-struct TypeTraits<std::string>
+struct GLIBMM_API TypeTraits<std::string>
 {
   using CppType = std::string;
   using CType = const char*;
@@ -270,7 +305,7 @@ struct TypeTraits<std::string>
  * @ingroup ContHelpers
  */
 template <>
-struct TypeTraits<bool>
+struct GLIBMM_API TypeTraits<bool>
 {
   using CppType = bool;
   using CType = gboolean;
@@ -286,7 +321,7 @@ struct TypeTraits<bool>
  * @ingroup ContHelpers
  */
 template <>
-struct TypeTraits<Glib::VariantBase>
+struct GLIBMM_API TypeTraits<Glib::VariantBase>
 {
   using CppType = Glib::VariantBase;
   using CType = GVariant*;
@@ -305,7 +340,7 @@ struct TypeTraits<Glib::VariantBase>
  * @ingroup ContHelpers
  */
 template <>
-struct TypeTraits<Glib::VariantContainerBase>
+struct GLIBMM_API TypeTraits<Glib::VariantContainerBase>
 {
   using CppType = Glib::VariantContainerBase;
   using CType = GVariant*;
diff --git a/glib/glibmm/containers.cc b/glib/glibmm/containers.cc
new file mode 100644 (file)
index 0000000..bb19f45
--- /dev/null
@@ -0,0 +1,26 @@
+/* containers.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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/containers.h>
+
+namespace Glib
+{
+
+gpointer glibmm_null_pointer = nullptr;
+
+} // namespace Glib
diff --git a/glib/glibmm/containers.h b/glib/glibmm/containers.h
new file mode 100644 (file)
index 0000000..55fc2c5
--- /dev/null
@@ -0,0 +1,360 @@
+#ifndef _GLIBMM_CONTAINERS_H
+#define _GLIBMM_CONTAINERS_H
+
+/* containers.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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+#include <glibmm/sarray.h> /* for backward compatibility */
+#include <glibmm/wrap.h>
+#include <glib.h>
+#include <iterator>
+#include <cstddef>
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Glib
+{
+
+template <class T>
+class List_Iterator;
+template <class T>
+class List_ConstIterator;
+template <class T>
+class List_ReverseIterator;
+
+// Most of these methods in the non-template classes needs to be moved
+// to implementation.
+
+// Daniel Elstner has ideas about generating these per-widget with m4. murrayc.
+
+extern GLIBMM_API gpointer glibmm_null_pointer;
+
+template <class T>
+class List_Iterator_Base
+{
+public:
+  using value_type = T;
+  using pointer = T*;
+  using reference = T&;
+};
+
+/// For instance, List_Iterator< Gtk::Widget >
+template <class T>
+class List_Iterator : public List_Iterator_Base<T>
+{
+public:
+  using iterator_category = std::bidirectional_iterator_tag;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using pointer = typename List_Iterator_Base<T>::pointer;
+  using reference = typename List_Iterator_Base<T>::reference;
+
+  GList* const* head_;
+  GList* node_;
+
+  using Self = List_Iterator<T>;
+
+  List_Iterator(GList* const& head, GList* node) : head_(&head), node_(node) {}
+
+  List_Iterator() : head_(nullptr), node_(nullptr) {}
+
+  List_Iterator(const Self& src) : head_(src.head_), node_(src.node_) {}
+
+  bool operator==(const Self& src) const { return node_ == src.node_; }
+  bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+  Self& operator++()
+  {
+    if (!node_)
+      node_ = g_list_first(*head_);
+    else
+      node_ = (GList*)g_list_next(node_);
+    return *this;
+  }
+
+  Self operator++(int)
+  {
+    Self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  Self& operator--()
+  {
+    if (!node_)
+      node_ = g_list_last(*head_);
+    else
+      node_ = (GList*)g_list_previous(node_);
+
+    return *this;
+  }
+
+  Self operator--(int)
+  {
+    Self tmp = *this;
+    --*this;
+    return tmp;
+  }
+
+  reference operator*() const { return *(pointer)(node_ ? node_->data : glibmm_null_pointer); }
+
+  pointer operator->() const { return &**this; }
+};
+
+/// For instance, SList_Iterator< Gtk::Widget >
+template <class T>
+class SList_Iterator : public List_Iterator_Base<T>
+{
+public:
+  using iterator_category = std::forward_iterator_tag;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using pointer = typename List_Iterator_Base<T>::pointer;
+  using reference = typename List_Iterator_Base<T>::reference;
+
+  GSList* node_;
+  using Self = SList_Iterator<T>;
+
+  SList_Iterator(GSList* node) : node_(node) {}
+
+  SList_Iterator() : node_(nullptr) {}
+
+  SList_Iterator(const Self& src) : node_(src.node_) {}
+
+  bool operator==(const Self& src) const { return node_ == src.node_; }
+  bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+  Self& operator++()
+  {
+    node_ = g_slist_next(node_);
+    return *this;
+  }
+
+  Self operator++(int)
+  {
+    Self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  reference operator*() const
+  {
+    return reinterpret_cast<T&>(node_ ? node_->data : glibmm_null_pointer);
+  }
+
+  pointer operator->() const { return &**this; }
+};
+
+// This iterator variation returns T_IFace (wrapped from T_Impl)
+// For instance,  List_Cpp_Iterator<GtkWidget, Gtk::Widget> is
+// a little like std::list<Gtk::Widget>::iterator
+template <class T_Impl, class T_IFace>
+class List_Cpp_Iterator : public List_Iterator_Base<T_IFace>
+{
+public:
+  using iterator_category = std::bidirectional_iterator_tag;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using pointer = typename List_Iterator_Base<T_IFace>::pointer;
+  using reference = typename List_Iterator_Base<T_IFace>::reference;
+
+  using Self = List_Cpp_Iterator<T_Impl, T_IFace>;
+
+  GList** head_;
+  GList* node_;
+
+  bool operator==(const Self& src) const { return node_ == src.node_; }
+  bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+  List_Cpp_Iterator(GList*& head, GList* node) : head_(&head), node_(node) {}
+
+  List_Cpp_Iterator() : head_(nullptr), node_(nullptr) {}
+
+  List_Cpp_Iterator(const Self& src) : head_(src.head_), node_(src.node_) {}
+
+  reference operator*() const
+  {
+    if (node_ && node_->data)
+    {
+      // We copy/paste the widget wrap() implementation here,
+      // because we can not use a specific Glib::wrap(T_Impl) overload here,
+      // because that would be "dependent", and g++ 3.4 does not allow that.
+      // The specific Glib::wrap() overloads don't do anything special anyway.
+      GObject* cobj = static_cast<GObject*>(node_->data);
+
+#ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
+      return *dynamic_cast<pointer>(Glib::wrap_auto(cobj, false));
+#else
+      // We really do need to use dynamic_cast<>, so I expect problems if this code is used.
+      // murrayc.
+      return *static_cast<pointer>(Glib::wrap_auto(cobj, false));
+#endif
+    }
+    return *static_cast<pointer>(nullptr); // boom!
+  }
+
+  pointer operator->() const { return &**this; }
+
+  Self& operator++()
+  {
+    if (!node_)
+      node_ = g_list_first(*head_);
+    else
+      node_ = (GList*)g_list_next(node_);
+
+    return *this;
+  }
+
+  Self operator++(int)
+  {
+    Self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  Self& operator--()
+  {
+    if (!node_)
+      node_ = g_list_last(*head_);
+    else
+      node_ = (GList*)g_list_previous(node_);
+
+    return *this;
+  }
+
+  Self operator--(int)
+  {
+    Self tmp = *this;
+    --*this;
+    return tmp;
+  }
+};
+
+template <class T_Base>
+class List_ReverseIterator : private T_Base
+{
+public:
+  using iterator_category = typename T_Base::iterator_category;
+  using size_type = typename T_Base::size_type;
+  using difference_type = typename T_Base::difference_type;
+
+  using value_type = typename T_Base::value_type;
+  using pointer = typename T_Base::pointer;
+  using reference = typename T_Base::reference;
+
+  using Self = List_ReverseIterator<T_Base>;
+
+  bool operator==(const Self& src) const { return T_Base::operator==(src); }
+  bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
+
+  List_ReverseIterator(GList* const& head, GList* node) : T_Base(head, node) {}
+
+  List_ReverseIterator() : T_Base() {}
+
+  List_ReverseIterator(const Self& src) : T_Base(src) {}
+
+  List_ReverseIterator(const T_Base& src) : T_Base(src) { ++(*this); }
+
+  Self& operator++()
+  {
+    T_Base::operator--();
+    return *this;
+  }
+  Self& operator--()
+  {
+    T_Base::operator++();
+    return *this;
+  }
+  Self operator++(int)
+  {
+    Self src = *this;
+    T_Base::operator--();
+    return src;
+  }
+  Self operator--(int)
+  {
+    Self src = *this;
+    T_Base::operator++();
+    return src;
+  }
+
+  reference operator*() const { return T_Base::operator*(); }
+  pointer operator->() const { return T_Base::operator->(); }
+};
+
+template <class T_Base>
+class List_ConstIterator : public T_Base
+{
+public:
+  using iterator_category = typename T_Base::iterator_category;
+  using size_type = typename T_Base::size_type;
+  using difference_type = typename T_Base::difference_type;
+
+  using value_type = const typename T_Base::value_type;
+  using pointer = const typename T_Base::pointer;
+  using reference = const typename T_Base::reference;
+
+  using Self = List_ConstIterator<T_Base>;
+
+  bool operator==(const Self& src) const { return T_Base::operator==(src); }
+  bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
+
+  List_ConstIterator(GList* const& head, GList* node) : T_Base(head, node) {}
+
+  List_ConstIterator() : T_Base() {}
+
+  List_ConstIterator(const Self& src) : T_Base(src) {}
+
+  List_ConstIterator(const T_Base& src) : T_Base(src) {}
+
+  Self& operator++()
+  {
+    T_Base::operator++();
+    return *this;
+  }
+  Self& operator--()
+  {
+    T_Base::operator--();
+    return *this;
+  }
+  Self operator++(int)
+  {
+    Self src = *this;
+    T_Base::operator++();
+    return src;
+  }
+  Self operator--(int)
+  {
+    Self src = *this;
+    T_Base::operator--();
+    return src;
+  }
+
+  reference operator*() const { return T_Base::operator*(); }
+  pointer operator->() const { return T_Base::operator->(); }
+};
+
+} // namespace Glib
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+#endif /* _GLIBMM_CONTAINERS_H */
index d5a96de..601e99e 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#ifndef GLIBMM_CAN_USE_THREAD_LOCAL
+#include <glibmm/threads.h>
+#endif
+
 #include <glibmm/dispatcher.h>
 #include <glibmm/exceptionhandler.h>
 #include <glibmm/fileutils.h>
@@ -22,8 +26,7 @@
 #include <cerrno>
 #include <fcntl.h>
 #include <glib.h>
-#include <forward_list>
-#include <memory>
+#include <set>
 #include <utility> // For std::move()
 
 #ifdef G_OS_WIN32
 #define EINTR 0 /* TODO: should use the real define */
 #endif
 
-namespace Glib
-{
-class DispatchNotifier;
-}
-
 namespace
 {
 
 struct DispatchNotifyData
 {
-  Glib::Dispatcher::Impl* dispatcher_impl;
+  Glib::Dispatcher* dispatcher;
   Glib::DispatchNotifier* notifier;
 
-  DispatchNotifyData()
-  : dispatcher_impl(nullptr), notifier(nullptr)
-  {}
+  DispatchNotifyData() : dispatcher(nullptr), notifier(nullptr) {}
 
-  DispatchNotifyData(Glib::Dispatcher::Impl* d, Glib::DispatchNotifier* n)
-  : dispatcher_impl(d), notifier(n)
-  {}
+  DispatchNotifyData(Glib::Dispatcher* d, Glib::DispatchNotifier* n) : dispatcher(d), notifier(n) {}
 };
 
 static void
@@ -126,33 +120,11 @@ fd_close_and_invalidate(int& fd)
 }
 #endif /* !G_OS_WIN32 */
 
-void warn_dropped_dispatcher_message()
-{
-  g_warning("Dropped dispatcher message as the dispatcher no longer exists.");
-}
-
 } // anonymous namespace
 
 namespace Glib
 {
 
-// The most important reason for having the dispatcher implementation in a separate
-// class is that its deletion can be delayed until it's safe to delete it.
-// Deletion is safe when the pipe does not contain any message to the dispatcher
-// to delete. When the pipe is empty, it's surely safe.
-struct Dispatcher::Impl
-{
-public:
-  sigc::signal<void()> signal_;
-  DispatchNotifier*  notifier_;
-
-  explicit Impl(const Glib::RefPtr<MainContext>& context);
-
-  // noncopyable
-  Impl(const Impl&) = delete;
-  Impl& operator=(const Impl&) = delete;
-};
-
 class DispatchNotifier : public sigc::trackable
 {
 public:
@@ -162,10 +134,11 @@ public:
   DispatchNotifier(const DispatchNotifier&) = delete;
   DispatchNotifier& operator=(const DispatchNotifier&) = delete;
 
-  static DispatchNotifier* reference_instance(const Glib::RefPtr<MainContext>& context);
-  static void unreference_instance(DispatchNotifier* notifier, Dispatcher::Impl* dispatcher_impl);
+  static DispatchNotifier* reference_instance(
+    const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher);
+  static void unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher);
 
-  void send_notification(Dispatcher::Impl* dispatcher_impl);
+  void send_notification(Dispatcher* dispatcher);
 
 protected:
   // Only used by reference_instance().  Should be private, but that triggers
@@ -173,10 +146,14 @@ protected:
   explicit DispatchNotifier(const Glib::RefPtr<MainContext>& context);
 
 private:
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
   static thread_local DispatchNotifier* thread_specific_instance_;
+#else
+  static Glib::Threads::Private<DispatchNotifier> thread_specific_instance_;
+#endif
+
+  std::set<const Dispatcher*> deleted_dispatchers_;
 
-  using UniqueImplPtr = std::unique_ptr<Dispatcher::Impl>;
-  std::forward_list<UniqueImplPtr> orphaned_dispatcher_impl_;
   long ref_count_;
   Glib::RefPtr<MainContext> context_;
 #ifdef G_OS_WIN32
@@ -195,10 +172,16 @@ private:
 
 /**** Glib::DispatchNotifier ***********************************************/
 
+// static
+
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
 thread_local DispatchNotifier* DispatchNotifier::thread_specific_instance_ = nullptr;
+#else
+Glib::Threads::Private<DispatchNotifier> DispatchNotifier::thread_specific_instance_;
+#endif
 
 DispatchNotifier::DispatchNotifier(const Glib::RefPtr<MainContext>& context)
-: orphaned_dispatcher_impl_(),
+: deleted_dispatchers_(),
   ref_count_(0),
   context_(context),
 #ifdef G_OS_WIN32
@@ -221,10 +204,10 @@ DispatchNotifier::DispatchNotifier(const Glib::RefPtr<MainContext>& context)
 
     // The following code is equivalent to
     // context_->signal_io().connect(
-    //   sigc::mem_fun(*this, &DispatchNotifier::pipe_io_handler), fd, Glib::IOCondition::IO_IN);
+    //   sigc::mem_fun(*this, &DispatchNotifier::pipe_io_handler), fd, Glib::IO_IN);
     // except for source->set_can_recurse(true).
 
-    const auto source = IOSource::create(fd, Glib::IOCondition::IO_IN);
+    const auto source = IOSource::create(fd, Glib::IO_IN);
 
     // If the signal emission in pipe_io_handler() starts a new main loop,
     // the event source shall not be blocked while that loop runs. (E.g. while
@@ -294,20 +277,40 @@ DispatchNotifier::create_pipe()
 }
 
 // static
-DispatchNotifier* DispatchNotifier::reference_instance(
-  const Glib::RefPtr<MainContext>& context)
+DispatchNotifier*
+DispatchNotifier::reference_instance(
+  const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher)
 {
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
   DispatchNotifier* instance = thread_specific_instance_;
+#else
+  DispatchNotifier* instance = thread_specific_instance_.get();
+#endif
 
   if (!instance)
   {
     instance = new DispatchNotifier(context);
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
     thread_specific_instance_ = instance;
+#else
+    thread_specific_instance_.replace(instance);
+#endif
   }
   else
   {
     // Prevent massive mess-up.
     g_return_val_if_fail(instance->context_ == context, nullptr);
+
+    // In the possible but unlikely case that a new dispatcher gets the same
+    // address as a newly deleted one, if the pipe still contains messages to
+    // the deleted dispatcher, those messages will be delivered to the new one.
+    // Not ideal, but perhaps the best that can be done without breaking ABI.
+    // The alternative would be to remove the following erase(), and risk not
+    // delivering messages sent to the new dispatcher.
+    // TODO: When we can break ABI, a better solution without this drawback can
+    // be implemented. See https://bugzilla.gnome.org/show_bug.cgi?id=651942
+    // especially comment 16.
+    instance->deleted_dispatchers_.erase(dispatcher);
   }
 
   ++instance->ref_count_; // initially 0
@@ -316,49 +319,48 @@ DispatchNotifier* DispatchNotifier::reference_instance(
 }
 
 // static
-void DispatchNotifier::unreference_instance(
-  DispatchNotifier* notifier, Dispatcher::Impl* dispatcher_impl)
+void
+DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher)
 {
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
   DispatchNotifier* const instance = thread_specific_instance_;
+#else
+  DispatchNotifier* const instance = thread_specific_instance_.get();
+#endif
 
   // Yes, the notifier argument is only used to check for sanity.
   g_return_if_fail(instance == notifier);
 
   if (instance->pipe_is_empty())
-  {
-    // No messages in the pipe. Delete the Dispatcher::Impl immediately.
-    delete dispatcher_impl;
-    instance->orphaned_dispatcher_impl_.clear();
-  }
+    // No messages in the pipe. No need to keep track of deleted dispatchers.
+    instance->deleted_dispatchers_.clear();
   else
-  {
-    // There are messages in the pipe, possibly to the orphaned Dispatcher::Impl.
-    // Keep it around until it can safely be deleted.
-    // Delete all slots connected to the Dispatcher. Then the signal emission
-    // in pipe_io_handler() will do nothing.
-    dispatcher_impl->signal_.clear();
-    // Add a slot that will warn that a message has been dropped.
-    dispatcher_impl->signal_.connect(sigc::ptr_fun(warn_dropped_dispatcher_message));
-    instance->orphaned_dispatcher_impl_.push_front(UniqueImplPtr(dispatcher_impl));
-  }
+    // There are messages in the pipe, possibly to the deleted dispatcher.
+    // Keep its address, so pipe_io_handler() can avoid delivering messages to it.
+    instance->deleted_dispatchers_.insert(dispatcher);
 
   if (--instance->ref_count_ <= 0)
   {
     g_return_if_fail(instance->ref_count_ == 0); // could be < 0 if messed up
 
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
     delete thread_specific_instance_;
     thread_specific_instance_ = nullptr;
+#else
+    thread_specific_instance_.replace(nullptr);
+#endif
   }
 }
 
-void DispatchNotifier::send_notification(Dispatcher::Impl* dispatcher_impl)
+void
+DispatchNotifier::send_notification(Dispatcher* dispatcher)
 {
 #ifdef G_OS_WIN32
   {
     const std::lock_guard<std::mutex> lock(mutex_);
 
     const bool was_empty = notify_queue_.empty();
-    notify_queue_.emplace_back(DispatchNotifyData(dispatcher_impl, this));
+    notify_queue_.emplace_back(DispatchNotifyData(dispatcher, this));
 
     if (was_empty)
     {
@@ -370,7 +372,7 @@ void DispatchNotifier::send_notification(Dispatcher::Impl* dispatcher_impl)
   }
 #else /* !G_OS_WIN32 */
 
-  DispatchNotifyData data(dispatcher_impl, this);
+  DispatchNotifyData data(dispatcher, this);
   gssize n_written;
 
   do
@@ -403,10 +405,10 @@ DispatchNotifier::pipe_is_empty()
 #ifdef G_OS_WIN32
   return notify_queue_.empty();
 #else
-  PollFD poll_fd(fd_receiver_, Glib::IOCondition::IO_IN);
+  PollFD poll_fd(fd_receiver_, Glib::IO_IN);
   // GPollFD*, number of file descriptors to poll, timeout (ms)
   g_poll(poll_fd.gobj(), 1, 0);
-  return static_cast<int>(poll_fd.get_revents() & Glib::IOCondition::IO_IN) == 0;
+  return (poll_fd.get_revents() & Glib::IO_IN) == 0;
 #endif
 }
 
@@ -464,69 +466,75 @@ bool DispatchNotifier::pipe_io_handler(Glib::IOCondition)
 
   g_return_val_if_fail(data.notifier == this, true);
 
+  // Drop the received message, if it is addressed to a deleted dispatcher.
+  const bool drop_message =
+    (deleted_dispatchers_.find(data.dispatcher) != deleted_dispatchers_.end());
+
+  // If the pipe is empty, there can be no messages to deleted dispatchers.
+  // No reason to keep track of them any more.
+  if (!deleted_dispatchers_.empty() && pipe_is_empty())
+    deleted_dispatchers_.clear();
+
+  if (drop_message)
+  {
+    g_warning("Dropped dispatcher message as the dispatcher no longer exists");
+    return true;
+  }
+
   // Actually, we wouldn't need the try/catch block because the Glib::Source
   // C callback already does it for us.  However, we do it anyway because the
   // default return value is 'false', which is not what we want.
   try
   {
-    data.dispatcher_impl->signal_(); // emit
+    data.dispatcher->signal_(); // emit
   }
   catch (...)
   {
     Glib::exception_handlers_invoke();
   }
 
-  if (!orphaned_dispatcher_impl_.empty() && pipe_is_empty())
-    orphaned_dispatcher_impl_.clear();
-
   return true;
 }
 
-/**** Glib::Dispatcher and Glib::Dispatcher::Impl **************************/
+/**** Glib::Dispatcher *****************************************************/
 
-Dispatcher::Impl::Impl(const Glib::RefPtr<MainContext>& context)
-: signal_(),
-  notifier_(DispatchNotifier::reference_instance(context))
+Dispatcher::Dispatcher()
+: signal_(), notifier_(DispatchNotifier::reference_instance(MainContext::get_default(), this))
 {
 }
 
-Dispatcher::Dispatcher()
-: impl_(new Dispatcher::Impl(MainContext::get_default()))
-{}
-
-
 Dispatcher::Dispatcher(const Glib::RefPtr<MainContext>& context)
-: impl_(new Dispatcher::Impl(context))
+: signal_(), notifier_(DispatchNotifier::reference_instance(context, this))
 {
 }
 
 Dispatcher::~Dispatcher() noexcept
 {
-  DispatchNotifier::unreference_instance(impl_->notifier_, impl_);
+  DispatchNotifier::unreference_instance(notifier_, this);
 }
 
 void
 Dispatcher::emit()
 {
-  impl_->notifier_->send_notification(impl_);
+  notifier_->send_notification(this);
 }
 
 void
 Dispatcher::operator()()
 {
-  impl_->notifier_->send_notification(impl_);
+  notifier_->send_notification(this);
 }
 
 sigc::connection
-Dispatcher::connect(const sigc::slot<void()>& slot)
+Dispatcher::connect(const sigc::slot<void>& slot)
 {
-  return impl_->signal_.connect(slot);
+  return signal_.connect(slot);
 }
 
 sigc::connection
-Dispatcher::connect(sigc::slot<void()>&& slot)
+Dispatcher::connect(sigc::slot<void>&& slot)
 {
-  return impl_->signal_.connect(std::move(slot));
+  return signal_.connect(std::move(slot));
 }
 
 } // namespace Glib
index 00c6384..9134030 100644 (file)
 namespace Glib
 {
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+class DispatchNotifier;
+#endif
+
 /** Signal class for inter-thread communication.
  * @ingroup Threads
- * Glib::Dispatcher works similar to sigc::signal<void()>.  But unlike normal
+ * Glib::Dispatcher works similar to sigc::signal<void>.  But unlike normal
  * signals, the notification happens asynchronously through a pipe.  This is
  * a simple and efficient way of communicating between threads, and especially
  * useful in a thread model with a single GUI thread.
@@ -62,7 +66,7 @@ namespace Glib
  * likely minor and the notification still happens asynchronously.  Apart
  * from the additional lock the behavior matches the Unix implementation.
  */
-class Dispatcher
+class GLIBMM_API Dispatcher
 {
 public:
   /** Create new Dispatcher instance using the default main context.
@@ -83,17 +87,18 @@ public:
   void emit();
   void operator()();
 
-  sigc::connection connect(const sigc::slot<void()>& slot);
+  sigc::connection connect(const sigc::slot<void>& slot);
   /** @newin{2,48}
    */
-  sigc::connection connect(sigc::slot<void()>&& slot);
-
-  #ifndef DOXYGEN_SHOULD_SKIP_THIS
-  struct Impl;
-  #endif
+  sigc::connection connect(sigc::slot<void>&& slot);
 
 private:
-  Impl* impl_; // hidden implementation
+  sigc::signal<void> signal_;
+  DispatchNotifier* notifier_;
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  friend class Glib::DispatchNotifier;
+#endif
 };
 
 /*! A Glib::Dispatcher example.
index 5f49ee2..1cd3b00 100644 (file)
@@ -25,7 +25,7 @@
 namespace Glib
 {
 
-class Error : public Glib::Exception
+class GLIBMM_API Error : public Glib::Exception
 {
 public:
   Error();
@@ -72,9 +72,9 @@ protected:
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 // This is needed so Glib::Error can be used with
-// Glib::Value and _WRAP_PROPERTY in Gtk::MediaStream.
+// Glib::Value and _WRAP_PROPERTY.
 template <>
-class Value<Glib::Error> : public ValueBase_Boxed
+class GLIBMM_API Value<Glib::Error> : public ValueBase_Boxed
 {
 public:
   using CppType = Glib::Error;
index 726f39e..62c1135 100644 (file)
@@ -24,7 +24,7 @@
 namespace Glib
 {
 
-class Exception
+class GLIBMM_API Exception
 {
 public:
   virtual ~Exception() noexcept = 0;
index 3c15f8c..023c204 100644 (file)
@@ -16,6 +16,9 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#ifndef GLIBMM_CAN_USE_THREAD_LOCAL
+#include <glibmm/threads.h>
+#endif
 #include <glibmmconfig.h>
 #include <glibmm/error.h>
 #include <glibmm/exceptionhandler.h>
@@ -30,7 +33,11 @@ using HandlerList = std::list<sigc::slot<void()>>;
 
 // Each thread has its own list of exception handlers
 // to avoid thread synchronization problems.
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
 static thread_local HandlerList* thread_specific_handler_list = nullptr;
+#else
+static Glib::Threads::Private<HandlerList> thread_specific_handler_list;
+#endif
 
 static void
 glibmm_exception_warning(const GError* error)
@@ -80,14 +87,22 @@ namespace Glib
 {
 
 sigc::connection
-add_exception_handler(const sigc::slot<void()>& slot)
+add_exception_handler(const sigc::slot<void>& slot)
 {
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
   HandlerList* handler_list = thread_specific_handler_list;
+#else
+  HandlerList* handler_list = thread_specific_handler_list.get();
+#endif
 
   if (!handler_list)
   {
     handler_list = new HandlerList();
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
     thread_specific_handler_list = handler_list;
+#else
+    thread_specific_handler_list.set(handler_list);
+#endif
   }
 
   handler_list->emplace_back(slot);
@@ -112,7 +127,11 @@ exception_handlers_invoke() noexcept
   // handled.  If there are no more handlers in the list and the exception
   // is still unhandled, call glibmm_unexpected_exception().
 
+#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
   if (HandlerList* const handler_list = thread_specific_handler_list)
+#else
+  if(HandlerList *const handler_list = thread_specific_handler_list.get())
+#endif
   {
     HandlerList::iterator pslot = handler_list->begin();
 
index a34fdbf..22ecdc8 100644 (file)
@@ -27,10 +27,12 @@ namespace Glib
 
 /** Specify a slot to be called when an exception is thrown by a signal handler.
  */
-sigc::connection add_exception_handler(const sigc::slot<void()>& slot);
+GLIBMM_API
+sigc::connection add_exception_handler(const sigc::slot<void>& slot);
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 // internal
+GLIBMM_API
 void exception_handlers_invoke() noexcept;
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
index 29c2a95..c2c6ce3 100644 (file)
@@ -73,9 +73,9 @@ namespace Glib
  * must be listed before Glib::Object or a class derived from
  * %Glib::Object (Gtk::Widget in the example) in the list of base classes.
  *
- * @newin{2,58}
+ * @newin{2,60}
  */
-class ExtraClassInit : virtual public ObjectBase
+class GLIBMM_API ExtraClassInit : virtual public ObjectBase
 {
 protected:
   /** Constructor.
index 530c439..793abd3 100644 (file)
@@ -4,14 +4,16 @@ glibmm_files_built_cc = $(glibmm_files_used_hg:.hg=.cc) $(glibmm_files_cc_m4:.m4
 glibmm_files_built_h  = $(glibmm_files_used_hg:.hg=.h) $(glibmm_files_h_m4:.m4=)
 
 glibmm_files_extra_cc =                        \
+       arrayhandle.cc                  \
        base64.cc                       \
        class.cc                        \
+       containers.cc                   \
        debug.cc                        \
        dispatcher.cc                   \
        error.cc                        \
        exception.cc                    \
        exceptionhandler.cc             \
-       extraclassinit.cc               \
+       extraclassinit.cc \
        init.cc                         \
        interface.cc                    \
        main.cc                         \
@@ -23,10 +25,14 @@ glibmm_files_extra_cc =                     \
        propertyproxy_base.cc           \
        quark.cc                        \
        random.cc                       \
+       sarray.cc                       \
        signalproxy.cc                  \
        signalproxy_connectionnode.cc   \
+       streamiochannel.cc              \
        stringutils.cc                  \
+       threadpool.cc                   \
        timer.cc                        \
+       timeval.cc                      \
        ustring.cc                      \
        utility.cc                      \
        value.cc                        \
@@ -36,19 +42,23 @@ glibmm_files_extra_cc =                     \
        wrap.cc
 
 glibmm_files_extra_h =                 \
+       arrayhandle.h                   \
        base64.h                        \
        class.h                         \
        containerhandle_shared.h        \
+       containers.h                    \
        debug.h                         \
        dispatcher.h                    \
        error.h                         \
        exception.h                     \
        exceptionhandler.h              \
-       extraclassinit.h                \
+       extraclassinit.h \
+       helperlist.h                    \
        i18n-lib.h                      \
        i18n.h                          \
        init.h                          \
        interface.h                     \
+       listhandle.h                    \
        main.h                          \
        object.h                        \
        objectbase.h                    \
@@ -60,16 +70,22 @@ glibmm_files_extra_h =                      \
        quark.h                         \
        random.h                        \
        refptr.h                        \
+       sarray.h                        \
        signalproxy.h                   \
        signalproxy_connectionnode.h    \
+       slisthandle.h                   \
+       streamiochannel.h               \
        stringutils.h                   \
+       threadpool.h                    \
        timer.h                         \
+       timeval.h                       \
        ustring.h                       \
        utility.h                       \
        value.h                         \
        value_custom.h                  \
        variantdbusstring.h \
        vectorutils.h                   \
+       weakref.h                       \
        wrap.h                          \
        wrap_init.h
 
index dc7295c..8068dc8 100644 (file)
@@ -2,4 +2,5 @@
 
 include $(top_srcdir)/glib/glibmm/filelist.am
 
+# Split out from $(top_srcdir)/glib/glimm/filelist.am
 glibmm_files_built_ph = $(patsubst %.hg,private/%_p.h,$(glibmm_files_used_hg))
diff --git a/glib/glibmm/helperlist.h b/glib/glibmm/helperlist.h
new file mode 100644 (file)
index 0000000..751b42d
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef _GLIBMM_HELPERLIST_H
+#define _GLIBMM_HELPERLIST_H
+
+/* helperlist.h
+ *
+ * Copyright 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 <http://www.gnu.org/licenses/>.
+ */
+
+// This is not hidden by GLIBMM_DISABLE_DEPRECATED
+// because gtkmm-2.24 still uses this type in its public API.
+// Note that gtkmm-2.24 itself is completely deprecated, so we really
+// can remove this whole class some time soon.
+//#ifndef GLIBMM_DISABLE_DEPRECATED
+
+#include <glibmm/containers.h>
+
+namespace Glib
+{
+
+// This class has some pure virtual methods which need to be implemented by derived classes.
+
+/**
+ * @deprecated This class should no longer be necessary. It has not been used
+ * by glibmm or gtkmm since gtkmm-2.4.
+ */
+template <typename T_Child, typename T_CppElement, typename T_Iterator>
+class HelperList
+{
+public:
+  HelperList() : gparent_(nullptr) {}
+
+  HelperList(GObject*
+      gp) // We use gp instead of gparent because that can cause warnings about a shadowed member.
+    : gparent_(gp)
+  {
+  }
+
+  virtual ~HelperList() noexcept {}
+
+  using value_type = T_Child;
+  using reference = value_type&;
+  using const_reference = const value_type&;
+
+  using iterator = T_Iterator;
+  using const_iterator = List_ConstIterator<iterator>;
+  using reverse_iterator = List_ReverseIterator<iterator>;
+  using const_reverse_iterator = List_ConstIterator<reverse_iterator>;
+
+  using element_type = T_CppElement;
+
+  using difference_type = std::size_t; // TODO Why not std::ptrdiff_t?
+  using size_type = std::size_t;
+
+  // These are implemented differently for each Helper List.
+  virtual iterator erase(iterator) = 0;
+
+  virtual void erase(iterator start, iterator stop)
+  {
+    while (start != stop)
+      start = erase(start); // Implemented in derived class.
+  }
+
+  virtual void remove(const_reference) = 0;
+
+  size_type size() const { return g_list_length(glist()); }
+
+  inline size_type max_size() { return size_type(-1); }
+  inline bool empty() { return glist() == nullptr; }
+
+  inline iterator begin() { return begin_(); }
+  inline iterator end() { return end_(); }
+
+  inline const_iterator begin() const { return const_iterator(begin_()); }
+  inline const_iterator end() const { return const_iterator(end_()); }
+
+  inline reverse_iterator rbegin() { return reverse_iterator(end_()); }
+  inline reverse_iterator rend() { return reverse_iterator(begin_()); }
+
+  inline const_reverse_iterator rbegin() const
+  {
+    return const_reverse_iterator(reverse_iterator(end_()));
+  }
+  inline const_reverse_iterator rend() const
+  {
+    return const_reverse_iterator(reverse_iterator(begin_()));
+  }
+
+  reference front() const { return *begin(); }
+
+  reference back() const { return *(--end()); }
+
+  reference operator[](size_type l) const
+  {
+    size_type j = 0;
+    iterator i;
+    for (i = begin(), j = 0; i != end() && j < l; ++i, ++j)
+      ;
+    return (*i);
+  }
+
+  //  iterator find(const_reference w)
+  //  {
+  //    iterator i = begin();
+  //    for(i = begin(); i != end() && (*i != w); i++);
+  //    return i;
+  //  }
+  //
+  //  iterator find(Widget& w)
+  //  {
+  //    iterator i;
+  //    for (i = begin(); i != end() && ((*i)->$1() != &w); i++);
+  //    return i;
+  //  }
+
+  // Derived classes might choose to reimplement these as public:
+  inline void pop_front() { erase(begin()); }
+  inline void pop_back() { erase(--end()); }
+
+  void clear() { erase(begin(), end()); }
+
+  GObject* gparent() { return gparent_; };
+  const GObject* gparent() const { return gparent_; };
+
+protected:
+  virtual GList*& glist() const = 0; // front of list
+
+  iterator begin_() const { return iterator(glist(), glist()); }
+
+  iterator end_() const { return iterator(glist(), (GList*)nullptr); }
+
+  GObject* gparent_;
+};
+
+} /* namespace Glib */
+
+//#endif //GLIBMM_DISABLE_DEPRECATED
+
+#endif /* _GLIBMM_HELPERLIST_H */
index 0b34447..ab96892 100644 (file)
 
 #include <glibmm/init.h>
 #include <glibmm/error.h>
-#include <locale>
-#include <clocale>
-#include <stdexcept>
-
-namespace
-{
-  bool init_to_users_preferred_locale = true;
-
-} // anonymous namespace
 
 namespace Glib
 {
-void set_init_to_users_preferred_locale(bool state)
-{
-  init_to_users_preferred_locale = state;
-}
-
-bool get_init_to_users_preferred_locale()
-{
-  return init_to_users_preferred_locale;
-}
 
-void init()
+void
+init()
 {
-  static bool is_initialized = false;
-
-  if (is_initialized)
-    return;
-
-  if (init_to_users_preferred_locale)
-  {
-    try
-    {
-      // Set the global locale for C++ functions and the locale for C functions
-      // to the user-preferred locale.
-      std::locale::global(std::locale(""));
-    }
-    catch (const std::runtime_error& ex)
-    {
-      g_warning("Can't set the global locale to the user's preferred locale.\n"
-        "   %s\n   The environment variable LANG may be wrong.\n", ex.what());
-    }
-  }
-  else
-  {
-    try
-    {
-      // Make the C++ locale equal to the C locale.
-      std::locale::global(std::locale(std::setlocale(LC_ALL, nullptr)));
-    }
-    catch (const std::runtime_error& ex)
-    {
-      g_warning("Can't make the global C++ locale equal to the C locale.\n"
-        "   %s\n   C locale = %s\n", ex.what(), std::setlocale(LC_ALL, nullptr));
-    }
-  }
-
   // Also calls Glib::wrap_register_init() and Glib::wrap_init().
   Glib::Error::register_init();
-
-  is_initialized = true;
 }
 
 } // namespace Glib
index f41040a..5bf7e20 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmmconfig.h>
+
 namespace Glib
 {
 
 /** Initialize glibmm.
  *
  * Call it before you use other parts of glibmm. You may call it more than once.
- * Calls after the first one have no effect. %Glib::init() sets the global locale
- * as specified by set_init_to_users_preferred_locale().
+ * Calls after the first one have no effect.
  *
  * You do not need to call %Glib::init() if you are using Gtk::Application or
  * Gio::init(), because they call %Glib::init() for you.
- *
- * @see set_init_to_users_preferred_locale()
  */
+GLIBMM_API
 void init();
 
-/** Instruct Glib::init() which global locale to set.
- *
- * To have the intended effect, this function must be called before init() is called.
- * Not calling it has the same effect as calling it with @a state = <tt>true</tt>.
- *
- * Note the confusing difference between C locale and "C" locale.
- * The C locale is the locale used by C code, set by std::setlocale(LC_ALL,&nbsp;locale_name).
- * The "C" locale is the classic locale, set by std::setlocale(LC_ALL,&nbsp;"C")
- * or std::locale::global(std::locale::classic()). It's the default global locale
- * in a C or C++ program.
- *
- * In a mixed C and C++ program, like a program using glibmm, having the C global
- * locale differ from std::locale::global() is error prone. Glib::init() tries
- * to avoid that.
- *
- * @param state If <tt>true</tt>, init() will set the C and C++ global locale
- *              to the user's preferred locale (std::locale::global(std::locale(""))).
- *              The user's preferred locale is set in the program's environment,
- *              usually with the LANG environment variable.<br>
- *              If <tt>false</tt>, init() will set the C++ global locale to the C global locale
- *              (std::locale::global(std::locale(std::setlocale(LC_ALL,&nbsp;nullptr)))).
- *
- * @newin{2,58}
- */
-void set_init_to_users_preferred_locale(bool state = true);
-
-/** Get the state, set with set_init_to_users_preferred_locale().
- * @returns The state, set with set_init_to_users_preferred_locale(); <tt>true</tt>
- *          if set_init_to_users_preferred_locale() has not been called.
- *
- * @newin{2,58}
- */
-bool get_init_to_users_preferred_locale();
-
 } // namespace Glib
 
 #endif /* _GLIBMM_INIT_H */
index f01f13d..793e767 100644 (file)
@@ -155,7 +155,7 @@ Interface::get_base_type()
 RefPtr<ObjectBase>
 wrap_interface(GObject* object, bool take_copy)
 {
-  return Glib::make_refptr_for_instance<ObjectBase>(wrap_auto(object, take_copy));
+  return Glib::RefPtr<ObjectBase>(wrap_auto(object, take_copy));
 }
 
 } // namespace Glib
index 9e35b5e..e4f04d4 100644 (file)
@@ -23,7 +23,7 @@ namespace Glib
 {
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-class Interface_Class;
+class GLIBMM_API Interface_Class;
 #endif
 
 // There is no base GInterface struct in Glib, though there is G_TYPE_INTERFACE enum value.
@@ -78,6 +78,7 @@ public:
   inline const GObject* gobj() const { return gobject_; }
 };
 
+GLIBMM_API
 RefPtr<ObjectBase> wrap_interface(GObject* object, bool take_copy = false);
 
 } // namespace Glib
diff --git a/glib/glibmm/listhandle.h b/glib/glibmm/listhandle.h
new file mode 100644 (file)
index 0000000..d9ffeb1
--- /dev/null
@@ -0,0 +1,412 @@
+#ifndef _GLIBMM_LISTHANDLE_H
+#define _GLIBMM_LISTHANDLE_H
+
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+#include <glibmm/containerhandle_shared.h>
+#include <glib.h>
+
+namespace Glib
+{
+
+namespace Container_Helpers
+{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/* Create and fill a GList as efficient as possible.
+ * This requires bidirectional iterators.
+ */
+template <class Bi, class Tr>
+GList*
+create_list(Bi pbegin, Bi pend, Tr)
+{
+  GList* head = nullptr;
+
+  while (pend != pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void* const item = Tr::to_c_type(*&*--pend);
+    head = g_list_prepend(head, const_cast<void*>(item));
+  }
+
+  return head;
+}
+
+/* Create a GList from a 0-terminated input sequence.
+ * Build it in reverse order and reverse the whole list afterwards,
+ * because appending to the list would be horribly inefficient.
+ */
+template <class For, class Tr>
+GList*
+create_list(For pbegin, Tr)
+{
+  GList* head = nullptr;
+
+  while (*pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void* const item = Tr::to_c_type(*&*pbegin);
+    head = g_list_prepend(head, const_cast<void*>(item));
+    ++pbegin;
+  }
+
+  return g_list_reverse(head);
+}
+
+/* Convert from any container that supports bidirectional iterators.
+ */
+template <class Tr, class Cont>
+struct ListSourceTraits
+{
+  static GList* get_data(const Cont& cont)
+  {
+    return Glib::Container_Helpers::create_list(cont.begin(), cont.end(), Tr());
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+/* Convert from a 0-terminated array.  The Cont
+ * argument must be a pointer to the first element.
+ */
+template <class Tr, class Cont>
+struct ListSourceTraits<Tr, Cont*>
+{
+  static GList* get_data(const Cont* array)
+  {
+    return (array) ? Glib::Container_Helpers::create_list(array, Tr()) : nullptr;
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+template <class Tr, class Cont>
+struct ListSourceTraits<Tr, const Cont*> : ListSourceTraits<Tr, Cont*>
+{
+};
+
+/* Convert from a 0-terminated array.  The Cont argument must be a pointer
+ * to the first element.  For consistency, the array must be 0-terminated,
+ * even though the array size is known at compile time.
+ */
+template <class Tr, class Cont, std::size_t N>
+struct ListSourceTraits<Tr, Cont[N]>
+{
+  static GList* get_data(const Cont* array)
+  {
+    return Glib::Container_Helpers::create_list(array, array + (N - 1), Tr());
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+template <class Tr, class Cont, std::size_t N>
+struct ListSourceTraits<Tr, const Cont[N]> : ListSourceTraits<Tr, Cont[N]>
+{
+};
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+/**
+ * @ingroup ContHelpers
+ */
+template <class Tr>
+class ListHandleIterator
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = CppType;
+  using difference_type = std::ptrdiff_t;
+  using reference = value_type;
+  using pointer = void;
+
+  explicit inline ListHandleIterator(const GList* node);
+
+  inline value_type operator*() const;
+  inline ListHandleIterator<Tr>& operator++();
+  inline const ListHandleIterator<Tr> operator++(int);
+
+  inline bool operator==(const ListHandleIterator<Tr>& rhs) const;
+  inline bool operator!=(const ListHandleIterator<Tr>& rhs) const;
+
+private:
+  const GList* node_;
+};
+
+} // namespace Container_Helpers
+
+// TODO: Remove this when we can break glibmm API.
+/** This is an intermediate type. When a method takes this, or returns this, you
+ * should use a standard C++ container of your choice, such as std::list or
+ * std::vector.
+ *
+ * However, this is not used in new API. We now prefer to just use std::vector,
+ * which is less flexibile, but makes the API clearer.
+ *
+ * @ingroup ContHandles
+ */
+template <class T, class Tr = Glib::Container_Helpers::TypeTraits<T>>
+class ListHandle
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using value_type = CppType;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using const_iterator = Glib::Container_Helpers::ListHandleIterator<Tr>;
+  using iterator = Glib::Container_Helpers::ListHandleIterator<Tr>;
+
+  template <class Cont>
+  inline ListHandle(const Cont& container);
+
+  // Take over ownership of an array created by GTK+ functions.
+  inline ListHandle(GList* glist, Glib::OwnershipType ownership);
+
+  // Copying clears the ownership flag of the source handle.
+  inline ListHandle(const ListHandle<T, Tr>& other);
+
+  ~ListHandle() noexcept;
+
+  inline const_iterator begin() const;
+  inline const_iterator end() const;
+
+  template <class U>
+  inline operator std::vector<U>() const;
+  template <class U>
+  inline operator std::deque<U>() const;
+  template <class U>
+  inline operator std::list<U>() const;
+
+  template <class Cont>
+  inline void assign_to(Cont& container) const;
+
+  template <class Out>
+  inline void copy(Out pdest) const;
+
+  inline GList* data() const;
+  inline std::size_t size() const;
+  inline bool empty() const;
+
+private:
+  GList* plist_;
+  mutable Glib::OwnershipType ownership_;
+
+  // No copy assignment.
+  ListHandle<T, Tr>& operator=(const ListHandle<T, Tr>&);
+};
+
+/***************************************************************************/
+/*  Inline implementation                                                  */
+/***************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Container_Helpers
+{
+
+/**** Glib::Container_Helpers::ListHandleIterator<> ************************/
+
+template <class Tr>
+inline ListHandleIterator<Tr>::ListHandleIterator(const GList* node) : node_(node)
+{
+}
+
+template <class Tr>
+inline typename ListHandleIterator<Tr>::value_type ListHandleIterator<Tr>::operator*() const
+{
+  return Tr::to_cpp_type(static_cast<typename Tr::CTypeNonConst>(node_->data));
+}
+
+template <class Tr>
+inline ListHandleIterator<Tr>& ListHandleIterator<Tr>::operator++()
+{
+  node_ = node_->next;
+  return *this;
+}
+
+template <class Tr>
+inline const ListHandleIterator<Tr> ListHandleIterator<Tr>::operator++(int)
+{
+  const ListHandleIterator<Tr> tmp(*this);
+  node_ = node_->next;
+  return tmp;
+}
+
+template <class Tr>
+inline bool
+ListHandleIterator<Tr>::operator==(const ListHandleIterator<Tr>& rhs) const
+{
+  return (node_ == rhs.node_);
+}
+
+template <class Tr>
+inline bool
+ListHandleIterator<Tr>::operator!=(const ListHandleIterator<Tr>& rhs) const
+{
+  return (node_ != rhs.node_);
+}
+
+} // namespace Container_Helpers
+
+/**** Glib::ListHandle<> ***************************************************/
+
+template <class T, class Tr>
+template <class Cont>
+inline ListHandle<T, Tr>::ListHandle(const Cont& container)
+: plist_(Glib::Container_Helpers::ListSourceTraits<Tr, Cont>::get_data(container)),
+  ownership_(Glib::Container_Helpers::ListSourceTraits<Tr, Cont>::initial_ownership)
+{
+}
+
+template <class T, class Tr>
+inline ListHandle<T, Tr>::ListHandle(GList* glist, Glib::OwnershipType ownership)
+: plist_(glist), ownership_(ownership)
+{
+}
+
+template <class T, class Tr>
+inline ListHandle<T, Tr>::ListHandle(const ListHandle<T, Tr>& other)
+: plist_(other.plist_), ownership_(other.ownership_)
+{
+  other.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <class T, class Tr>
+ListHandle<T, Tr>::~ListHandle() noexcept
+{
+  if (ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      for (GList* node = plist_; node != nullptr; node = node->next)
+        Tr::release_c_type(static_cast<typename Tr::CTypeNonConst>(node->data));
+    }
+    g_list_free(plist_);
+  }
+}
+
+template <class T, class Tr>
+inline typename ListHandle<T, Tr>::const_iterator
+ListHandle<T, Tr>::begin() const
+{
+  return Glib::Container_Helpers::ListHandleIterator<Tr>(plist_);
+}
+
+template <class T, class Tr>
+inline typename ListHandle<T, Tr>::const_iterator
+ListHandle<T, Tr>::end() const
+{
+  return Glib::Container_Helpers::ListHandleIterator<Tr>(nullptr);
+}
+
+template <class T, class Tr>
+template <class U>
+inline ListHandle<T, Tr>::operator std::vector<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::vector<U>(this->begin(), this->end());
+#else
+  std::vector<U> temp;
+  temp.reserve(this->size());
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline ListHandle<T, Tr>::operator std::deque<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::deque<U>(this->begin(), this->end());
+#else
+  std::deque<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline ListHandle<T, Tr>::operator std::list<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::list<U>(this->begin(), this->end());
+#else
+  std::list<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class Cont>
+inline void
+ListHandle<T, Tr>::assign_to(Cont& container) const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  container.assign(this->begin(), this->end());
+#else
+  Cont temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  container.swap(temp);
+#endif
+}
+
+template <class T, class Tr>
+template <class Out>
+inline void
+ListHandle<T, Tr>::copy(Out pdest) const
+{
+  std::copy(this->begin(), this->end(), pdest);
+}
+
+template <class T, class Tr>
+inline GList*
+ListHandle<T, Tr>::data() const
+{
+  return plist_;
+}
+
+template <class T, class Tr>
+inline std::size_t
+ListHandle<T, Tr>::size() const
+{
+  return g_list_length(plist_);
+}
+
+template <class T, class Tr>
+inline bool
+ListHandle<T, Tr>::empty() const
+{
+  return (plist_ == nullptr);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+#endif /* _GLIBMM_LISTHANDLE_H */
index 3ca2c73..40d39c6 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmmconfig.h> // May define GLIBMM_DISABLE_DEPRECATED
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+// Include glibmm/thread.h first because we need it to be first to include <glib.h>,
+// so we can do an undef trick to still use deprecated API in the header:
+#include <glibmm/thread.h>
+#include <glibmm/threads.h>
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 #include <glibmm/main.h>
 #include <glibmm/exceptionhandler.h>
 #include <glibmm/wrap.h>
 #include <glibmm/iochannel.h>
 #include <glibmm/utility.h>
 #include <algorithm>
+#include <map> // Needed until the next ABI break.
 
 namespace
 {
-// Convert an interval from milliseconds to microseconds,
-// suitable for adding to Source::get_time().
-inline gint64 ms2us(unsigned int ms)
-{
-  return static_cast<gint64>(ms) * 1000;
-}
+void
+time64_to_time_val(gint64 time64, Glib::TimeVal& time_val)
+{
+  // This function is not guaranteed to convert correctly if time64 is negative.
+  const long seconds = static_cast<long>(time64 / G_GINT64_CONSTANT(1000000));
+  const long microseconds =
+    static_cast<long>(time64 - static_cast<gint64>(seconds) * G_GINT64_CONSTANT(1000000));
+  time_val = Glib::TimeVal(seconds, microseconds);
+}
+
+// TODO: At the next ABI break, replace ExtraSourceData by new data members in Source.
+// Then the mutex is not necessary, but to keep the code thread-safe, use the
+// g_atomic_*() functions on these data elements.
+// These are new data members that can't be added to Glib::Source now,
+// because it would break ABI.
+struct ExtraSourceData
+{
+  ExtraSourceData() : ref_count(1), keep_wrapper(2) {}
+  int ref_count;
+  // When both Source::unreference() and SourceCallbackData::destroy_notify_callback()
+  // have decreased keep_wrapper, it's time to delete the C++ wrapper.
+  int keep_wrapper;
+};
 
-class SourceConnectionNode : public sigc::notifiable
+std::map<const Glib::Source*, ExtraSourceData> extra_source_data;
+// Source instances may be used in different threads.
+// Accesses to extra_source_data must be thread-safe.
+std::mutex extra_source_data_mutex;
+
+class SourceConnectionNode
 {
 public:
   explicit inline SourceConnectionNode(const sigc::slot_base& slot);
 
-  static void notify(sigc::notifiable* data);
-  static void destroy_notify_callback(sigc::notifiable* data);
+  static void* notify(void* data);
+  static void destroy_notify_callback(void* data);
 
   inline void install(GSource* source);
   inline sigc::slot_base* get_slot();
@@ -52,8 +84,8 @@ inline SourceConnectionNode::SourceConnectionNode(const sigc::slot_base& slot)
   slot_.set_parent(this, &SourceConnectionNode::notify);
 }
 
-void
-SourceConnectionNode::notify(sigc::notifiable* data)
+void*
+SourceConnectionNode::notify(void* data)
 {
   SourceConnectionNode* const self = static_cast<SourceConnectionNode*>(data);
 
@@ -68,11 +100,13 @@ SourceConnectionNode::notify(sigc::notifiable* data)
     // Destroying the object triggers execution of destroy_notify_handler(),
     // either immediately or later, so we leave that to do the deletion.
   }
+
+  return nullptr;
 }
 
 // static
 void
-SourceConnectionNode::destroy_notify_callback(sigc::notifiable* data)
+SourceConnectionNode::destroy_notify_callback(void* data)
 {
   SourceConnectionNode* const self = static_cast<SourceConnectionNode*>(data);
 
@@ -138,8 +172,17 @@ SourceCallbackData::destroy_notify_callback(void* data)
   if (self->node)
     SourceConnectionNode::destroy_notify_callback(self->node);
 
-  // destroy_notify_callback2() does nothing if self->wrapper == nullptr.
-  Glib::Source::destroy_notify_callback2(self->wrapper);
+  if (self->wrapper)
+  {
+    std::unique_lock<std::mutex> lock(extra_source_data_mutex);
+    if (--extra_source_data[self->wrapper].keep_wrapper == 0)
+    {
+      // No other reference exists to the wrapper. Delete it!
+      extra_source_data.erase(self->wrapper);
+      lock.unlock();
+      Glib::Source::destroy_notify_callback(self->wrapper);
+    }
+  }
 
   delete self;
 }
@@ -197,7 +240,7 @@ glibmm_source_callback(void* data)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    return (*static_cast<sigc::slot<bool()>*>(conn_data->get_slot()))();
+    return (*static_cast<sigc::slot<bool>*>(conn_data->get_slot()))();
   }
   catch (...)
   {
@@ -218,7 +261,7 @@ glibmm_source_callback_once(void* data)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    (*static_cast<sigc::slot<void()>*>(conn_data->get_slot()))();
+    (*static_cast<sigc::slot<void>*>(conn_data->get_slot()))();
   }
   catch (...)
   {
@@ -227,13 +270,6 @@ glibmm_source_callback_once(void* data)
   return 0; // Destroy the event source after one call
 }
 
-static void
-glibmm_source_destroy_notify_callback(void* data)
-{
-  SourceConnectionNode* const conn_data = static_cast<SourceConnectionNode*>(data);
-  SourceConnectionNode::destroy_notify_callback(conn_data);
-}
-
 static gboolean
 glibmm_iosource_callback(GIOChannel*, GIOCondition condition, void* data)
 {
@@ -243,7 +279,7 @@ glibmm_iosource_callback(GIOChannel*, GIOCondition condition, void* data)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    return (*static_cast<sigc::slot<bool(Glib::IOCondition)>*>(callback_data->node->get_slot()))(
+    return (*static_cast<sigc::slot<bool, Glib::IOCondition>*>(callback_data->node->get_slot()))(
       (Glib::IOCondition)condition);
   }
   catch (...)
@@ -265,7 +301,7 @@ glibmm_child_watch_callback(GPid pid, gint child_status, void* data)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    (*static_cast<sigc::slot<void(GPid, int)>*>(conn_data->get_slot()))(pid, child_status);
+    (*static_cast<sigc::slot<void, GPid, int>*>(conn_data->get_slot()))(pid, child_status);
   }
   catch (...)
   {
@@ -276,7 +312,7 @@ glibmm_child_watch_callback(GPid pid, gint child_status, void* data)
 
 static void
 glibmm_signal_connect_once(
-  const sigc::slot<void()>& slot, int priority, GSource* source, GMainContext* context)
+  const sigc::slot<void>& slot, int priority, GSource* source, GMainContext* context)
 {
   SourceConnectionNode* const conn_node = new SourceConnectionNode(slot);
 
@@ -284,7 +320,7 @@ glibmm_signal_connect_once(
     g_source_set_priority(source, priority);
 
   g_source_set_callback(source, &glibmm_source_callback_once, conn_node,
-    &glibmm_source_destroy_notify_callback);
+    &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context);
@@ -299,7 +335,7 @@ glibmm_main_context_invoke_callback(void* data)
   try
   {
     // Recreate the specific slot from the generic slot node.
-    return (*static_cast<sigc::slot<bool()>*>(slot))();
+    return (*static_cast<sigc::slot<bool>*>(slot))();
   }
   catch (...)
   {
@@ -339,7 +375,7 @@ PollFD::PollFD(PollFD::fd_t fd)
 PollFD::PollFD(PollFD::fd_t fd, IOCondition events)
 {
   gobject_.fd = fd;
-  gobject_.events = static_cast<decltype(gobject_.events)>(events);
+  gobject_.events = events;
   gobject_.revents = 0;
 }
 
@@ -351,7 +387,7 @@ inline SignalTimeout::SignalTimeout(GMainContext* context) : context_(context)
 
 /* Note that this is our equivalent of g_timeout_add(). */
 sigc::connection
-SignalTimeout::connect(const sigc::slot<bool()>& slot, unsigned int interval, int priority)
+SignalTimeout::connect(const sigc::slot<bool>& slot, unsigned int interval, int priority)
 {
   SourceConnectionNode* const conn_node = new SourceConnectionNode(slot);
   const sigc::connection connection(*conn_node->get_slot());
@@ -362,8 +398,7 @@ SignalTimeout::connect(const sigc::slot<bool()>& slot, unsigned int interval, in
     g_source_set_priority(source, priority);
 
   g_source_set_callback(
-    source, &glibmm_source_callback, conn_node,
-    &glibmm_source_destroy_notify_callback);
+    source, &glibmm_source_callback, conn_node, &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context_);
@@ -373,7 +408,7 @@ SignalTimeout::connect(const sigc::slot<bool()>& slot, unsigned int interval, in
 }
 
 void
-SignalTimeout::connect_once(const sigc::slot<void()>& slot, unsigned int interval, int priority)
+SignalTimeout::connect_once(const sigc::slot<void>& slot, unsigned int interval, int priority)
 {
   GSource* const source = g_timeout_source_new(interval);
   glibmm_signal_connect_once(slot, priority, source, context_);
@@ -381,7 +416,7 @@ SignalTimeout::connect_once(const sigc::slot<void()>& slot, unsigned int interva
 
 /* Note that this is our equivalent of g_timeout_add_seconds(). */
 sigc::connection
-SignalTimeout::connect_seconds(const sigc::slot<bool()>& slot, unsigned int interval, int priority)
+SignalTimeout::connect_seconds(const sigc::slot<bool>& slot, unsigned int interval, int priority)
 {
   SourceConnectionNode* const conn_node = new SourceConnectionNode(slot);
   const sigc::connection connection(*conn_node->get_slot());
@@ -392,8 +427,7 @@ SignalTimeout::connect_seconds(const sigc::slot<bool()>& slot, unsigned int inte
     g_source_set_priority(source, priority);
 
   g_source_set_callback(
-    source, &glibmm_source_callback, conn_node,
-    &glibmm_source_destroy_notify_callback);
+    source, &glibmm_source_callback, conn_node, &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context_);
@@ -404,7 +438,7 @@ SignalTimeout::connect_seconds(const sigc::slot<bool()>& slot, unsigned int inte
 
 void
 SignalTimeout::connect_seconds_once(
-  const sigc::slot<void()>& slot, unsigned int interval, int priority)
+  const sigc::slot<void>& slot, unsigned int interval, int priority)
 {
   GSource* const source = g_timeout_source_new_seconds(interval);
   glibmm_signal_connect_once(slot, priority, source, context_);
@@ -423,7 +457,7 @@ inline SignalIdle::SignalIdle(GMainContext* context) : context_(context)
 }
 
 sigc::connection
-SignalIdle::connect(const sigc::slot<bool()>& slot, int priority)
+SignalIdle::connect(const sigc::slot<bool>& slot, int priority)
 {
   SourceConnectionNode* const conn_node = new SourceConnectionNode(slot);
   const sigc::connection connection(*conn_node->get_slot());
@@ -434,8 +468,7 @@ SignalIdle::connect(const sigc::slot<bool()>& slot, int priority)
     g_source_set_priority(source, priority);
 
   g_source_set_callback(
-    source, &glibmm_source_callback, conn_node,
-    &glibmm_source_destroy_notify_callback);
+    source, &glibmm_source_callback, conn_node, &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context_);
@@ -445,7 +478,7 @@ SignalIdle::connect(const sigc::slot<bool()>& slot, int priority)
 }
 
 void
-SignalIdle::connect_once(const sigc::slot<void()>& slot, int priority)
+SignalIdle::connect_once(const sigc::slot<void>& slot, int priority)
 {
   GSource* const source = g_idle_source_new();
   glibmm_signal_connect_once(slot, priority, source, context_);
@@ -465,7 +498,7 @@ inline SignalIO::SignalIO(GMainContext* context) : context_(context)
 
 sigc::connection
 SignalIO::connect(
-  const sigc::slot<bool(IOCondition)>& slot, PollFD::fd_t fd, IOCondition condition, int priority)
+  const sigc::slot<bool, IOCondition>& slot, PollFD::fd_t fd, IOCondition condition, int priority)
 {
   const auto source = IOSource::create(fd, condition);
 
@@ -480,7 +513,7 @@ SignalIO::connect(
 }
 
 sigc::connection
-SignalIO::connect(const sigc::slot<bool(IOCondition)>& slot, const Glib::RefPtr<IOChannel>& channel,
+SignalIO::connect(const sigc::slot<bool, IOCondition>& slot, const Glib::RefPtr<IOChannel>& channel,
   IOCondition condition, int priority)
 {
   const auto source = IOSource::create(channel, condition);
@@ -508,7 +541,7 @@ inline SignalChildWatch::SignalChildWatch(GMainContext* context) : context_(cont
 }
 
 sigc::connection
-SignalChildWatch::connect(const sigc::slot<void(GPid, int)>& slot, GPid pid, int priority)
+SignalChildWatch::connect(const sigc::slot<void, GPid, int>& slot, GPid pid, int priority)
 {
   SourceConnectionNode* const conn_node = new SourceConnectionNode(slot);
   const sigc::connection connection(*conn_node->get_slot());
@@ -519,8 +552,7 @@ SignalChildWatch::connect(const sigc::slot<void(GPid, int)>& slot, GPid pid, int
     g_source_set_priority(source, priority);
 
   g_source_set_callback(source, Glib::function_pointer_cast<GSourceFunc>(&glibmm_child_watch_callback),
-    conn_node,
-    &glibmm_source_destroy_notify_callback);
+    conn_node, &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context_);
@@ -541,7 +573,7 @@ signal_child_watch()
 Glib::RefPtr<MainContext>
 MainContext::create()
 {
-  return Glib::make_refptr_for_instance<MainContext>(reinterpret_cast<MainContext*>(g_main_context_new()));
+  return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(g_main_context_new()));
 }
 
 // static
@@ -575,6 +607,22 @@ MainContext::acquire()
   return g_main_context_acquire(gobj());
 }
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+bool
+MainContext::wait(Glib::Cond& cond, Glib::Mutex& mutex)
+{
+  return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
+}
+
+bool
+MainContext::wait(Glib::Threads::Cond& cond, Glib::Threads::Mutex& mutex)
+{
+  return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 void
 MainContext::release()
 {
@@ -653,10 +701,30 @@ MainContext::remove_poll(PollFD& fd)
 }
 
 void
-MainContext::invoke(const sigc::slot<bool()>& slot, int priority)
+MainContext::push_thread_default()
+{
+  g_main_context_push_thread_default(gobj());
+}
+
+void
+MainContext::pop_thread_default()
+{
+  g_main_context_pop_thread_default(gobj());
+}
+
+// static
+Glib::RefPtr<MainContext>
+MainContext::get_thread_default()
+{
+  // g_main_context_ref_thread_default() gives us a ref.
+  return Glib::wrap(g_main_context_ref_thread_default(), false);
+}
+
+void
+MainContext::invoke(const sigc::slot<bool>& slot, int priority)
 {
   // Make a copy of slot on the heap.
-  sigc::slot_base* const slot_copy = new sigc::slot<bool()>(slot);
+  sigc::slot_base* const slot_copy = new sigc::slot<bool>(slot);
 
   g_main_context_invoke_full(gobj(), priority, glibmm_main_context_invoke_callback, slot_copy,
     glibmm_main_context_invoke_destroy_notify_callback);
@@ -723,7 +791,7 @@ wrap(GMainContext* gobject, bool take_copy)
   if (take_copy && gobject)
     g_main_context_ref(gobject);
 
-  return Glib::make_refptr_for_instance<MainContext>(reinterpret_cast<MainContext*>(gobject));
+  return Glib::RefPtr<MainContext>(reinterpret_cast<MainContext*>(gobject));
 }
 
 /**** Glib::MainLoop *******************************************************/
@@ -731,13 +799,13 @@ wrap(GMainContext* gobject, bool take_copy)
 Glib::RefPtr<MainLoop>
 MainLoop::create(bool is_running)
 {
-  return Glib::make_refptr_for_instance<MainLoop>(reinterpret_cast<MainLoop*>(g_main_loop_new(nullptr, is_running)));
+  return Glib::RefPtr<MainLoop>(reinterpret_cast<MainLoop*>(g_main_loop_new(nullptr, is_running)));
 }
 
 Glib::RefPtr<MainLoop>
 MainLoop::create(const Glib::RefPtr<MainContext>& context, bool is_running)
 {
-  return Glib::make_refptr_for_instance<MainLoop>(
+  return Glib::RefPtr<MainLoop>(
     reinterpret_cast<MainLoop*>(g_main_loop_new(Glib::unwrap(context), is_running)));
 }
 
@@ -809,7 +877,7 @@ wrap(GMainLoop* gobject, bool take_copy)
   if (take_copy && gobject)
     g_main_loop_ref(gobject);
 
-  return Glib::make_refptr_for_instance<MainLoop>(reinterpret_cast<MainLoop*>(gobject));
+  return Glib::RefPtr<MainLoop>(reinterpret_cast<MainLoop*>(gobject));
 }
 
 /**** Glib::Source *********************************************************/
@@ -888,17 +956,30 @@ Source::gobj_copy() const
 void
 Source::reference() const
 {
-  ++ref_count_;
+  std::lock_guard<std::mutex> lock(extra_source_data_mutex);
+  ++extra_source_data[this].ref_count;
 }
 
 void
 Source::unreference() const
 {
-  if (--ref_count_ == 0)
+  std::unique_lock<std::mutex> lock(extra_source_data_mutex);
+  if (--extra_source_data[this].ref_count == 0)
   {
     GSource* const tmp_gobject = gobject_;
 
-    destroy_notify_callback2(const_cast<Source*>(this));
+    if (--extra_source_data[this].keep_wrapper == 0)
+    {
+      // The last reference from a RefPtr<Source> has been deleted, and
+      // SourceCallbackData::destroy_notify_callback() has been called while
+      // extra_source_data[this].keep_wrapper was > 1.
+      // Delete the wrapper!
+      extra_source_data.erase(this);
+      lock.unlock();
+      destroy_notify_callback(const_cast<Source*>(this));
+    }
+    else
+      lock.unlock();
 
     // Drop the one and only GSource reference held by the C++ wrapper.
     // If the GSource instance is attached to a main context, the GMainContext
@@ -974,6 +1055,16 @@ Source::remove_poll(Glib::PollFD& poll_fd)
   g_source_remove_poll(gobject_, poll_fd.gobj());
 }
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+void
+Source::get_current_time(Glib::TimeVal& current_time)
+{
+  g_source_get_current_time(gobject_, &current_time);
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 gint64
 Source::get_time() const
 {
@@ -1048,19 +1139,17 @@ Source::dispatch_vfunc(GSource*, GSourceFunc callback, void* user_data)
 
 // static
 void
-Source::destroy_notify_callback2(void* data)
+Source::destroy_notify_callback(void* data)
 {
   if (data)
   {
     Source* const self = static_cast<Source*>(data);
-    if (--self->keep_wrapper_ == 0)
-    {
-      // gobject_ is already invalid at this point.
-      self->gobject_ = nullptr;
 
-      // No exception checking: if the dtor throws, you're out of luck anyway.
-      delete self;
-    }
+    // gobject_ is already invalid at this point.
+    self->gobject_ = nullptr;
+
+    // No exception checking: if the dtor throws, you're out of luck anyway.
+    delete self;
   }
 }
 
@@ -1076,8 +1165,7 @@ Source::attach_signal_source(const sigc::slot_base& slot, int priority, GSource*
     g_source_set_priority(source, priority);
 
   g_source_set_callback(
-    source, callback_func, conn_node,
-    &glibmm_source_destroy_notify_callback);
+    source, callback_func, conn_node, &SourceConnectionNode::destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context);
@@ -1108,18 +1196,19 @@ Source::get_slot_from_callback_data(void* data)
 Glib::RefPtr<TimeoutSource>
 TimeoutSource::create(unsigned int interval)
 {
-  return Glib::make_refptr_for_instance<TimeoutSource>(new TimeoutSource(interval));
+  return Glib::RefPtr<TimeoutSource>(new TimeoutSource(interval));
 }
 
 sigc::connection
-TimeoutSource::connect(const sigc::slot<bool()>& slot)
+TimeoutSource::connect(const sigc::slot<bool>& slot)
 {
   return connect_generic(slot);
 }
 
 TimeoutSource::TimeoutSource(unsigned int interval) : interval_(interval)
 {
-  expiration_ = get_time() + ms2us(interval_);
+  time64_to_time_val(get_time(), expiration_);
+  expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
 }
 
 TimeoutSource::~TimeoutSource() noexcept
@@ -1129,24 +1218,33 @@ TimeoutSource::~TimeoutSource() noexcept
 bool
 TimeoutSource::prepare(int& timeout)
 {
-  gint64 remaining = expiration_ - get_time();
+  Glib::TimeVal current_time;
+  time64_to_time_val(get_time(), current_time);
 
-  if (remaining <= 0)
+  Glib::TimeVal remaining = expiration_;
+  remaining.subtract(current_time);
+
+  if (remaining.negative())
   {
     // Already expired.
     timeout = 0;
   }
   else
   {
+    const unsigned long milliseconds = static_cast<unsigned long>(remaining.tv_sec) * 1000U +
+                                       static_cast<unsigned long>(remaining.tv_usec) / 1000U;
+
     // Set remaining milliseconds.
-    timeout = std::min<gint64>(G_MAXINT, remaining / 1000);
+    timeout = std::min<unsigned long>(G_MAXINT, milliseconds);
 
     // Check if the system time has been set backwards. (remaining > interval)
-    if (remaining > ms2us(interval_))
+    remaining.add_milliseconds(-std::min<unsigned long>(G_MAXLONG, interval_) - 1);
+    if (!remaining.negative())
     {
       // Oh well.  Reset the expiration time to now + interval;
       // this at least avoids hanging for long periods of time.
-      expiration_ = get_time() + ms2us(interval_);
+      expiration_ = current_time;
+      expiration_.add_milliseconds(interval_);
       timeout = std::min<unsigned int>(G_MAXINT, interval_);
     }
   }
@@ -1157,16 +1255,22 @@ TimeoutSource::prepare(int& timeout)
 bool
 TimeoutSource::check()
 {
-  return expiration_ <= get_time();
+  Glib::TimeVal current_time;
+  time64_to_time_val(get_time(), current_time);
+
+  return (expiration_ <= current_time);
 }
 
 bool
 TimeoutSource::dispatch(sigc::slot_base* slot)
 {
-  const bool again = (*static_cast<sigc::slot<bool()>*>(slot))();
+  const bool again = (*static_cast<sigc::slot<bool>*>(slot))();
 
   if (again)
-    expiration_ = get_time() + ms2us(interval_);
+  {
+    time64_to_time_val(get_time(), expiration_);
+    expiration_.add_milliseconds(std::min<unsigned long>(G_MAXLONG, interval_));
+  }
 
   return again;
 }
@@ -1177,11 +1281,11 @@ TimeoutSource::dispatch(sigc::slot_base* slot)
 Glib::RefPtr<IdleSource>
 IdleSource::create()
 {
-  return Glib::make_refptr_for_instance<IdleSource>(new IdleSource());
+  return Glib::RefPtr<IdleSource>(new IdleSource());
 }
 
 sigc::connection
-IdleSource::connect(const sigc::slot<bool()>& slot)
+IdleSource::connect(const sigc::slot<bool>& slot)
 {
   return connect_generic(slot);
 }
@@ -1211,7 +1315,7 @@ IdleSource::check()
 bool
 IdleSource::dispatch(sigc::slot_base* slot)
 {
-  return (*static_cast<sigc::slot<bool()>*>(slot))();
+  return (*static_cast<sigc::slot<bool>*>(slot))();
 }
 
 /**** Glib::IOSource *******************************************************/
@@ -1220,23 +1324,17 @@ IdleSource::dispatch(sigc::slot_base* slot)
 Glib::RefPtr<IOSource>
 IOSource::create(PollFD::fd_t fd, IOCondition condition)
 {
-  return Glib::make_refptr_for_instance<IOSource>(new IOSource(fd, condition));
+  return Glib::RefPtr<IOSource>(new IOSource(fd, condition));
 }
 
 Glib::RefPtr<IOSource>
 IOSource::create(const Glib::RefPtr<IOChannel>& channel, IOCondition condition)
 {
-  return Glib::make_refptr_for_instance<IOSource>(new IOSource(channel, condition));
-}
-
-Glib::RefPtr<IOSource>
-IOSource::create(GIOChannel* channel, IOCondition condition)
-{
-  return Glib::make_refptr_for_instance<IOSource>(new IOSource(channel, condition));
+  return Glib::RefPtr<IOSource>(new IOSource(channel, condition));
 }
 
 sigc::connection
-IOSource::connect(const sigc::slot<bool(IOCondition)>& slot)
+IOSource::connect(const sigc::slot<bool, IOCondition>& slot)
 {
   return connect_generic(slot);
 }
@@ -1252,12 +1350,6 @@ IOSource::IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition
 {
 }
 
-IOSource::IOSource(GIOChannel* channel, IOCondition condition)
-: Source(g_io_create_watch(channel, (GIOCondition)condition),
-    Glib::function_pointer_cast<GSourceFunc>(&glibmm_iosource_callback))
-{
-}
-
 IOSource::IOSource(GSource* cast_item, GSourceFunc callback_func) : Source(cast_item, callback_func)
 {
 }
@@ -1276,13 +1368,13 @@ IOSource::prepare(int& timeout)
 bool
 IOSource::check()
 {
-  return static_cast<int>(poll_fd_.get_revents() & poll_fd_.get_events()) != 0;
+  return ((poll_fd_.get_revents() & poll_fd_.get_events()) != 0);
 }
 
 bool
 IOSource::dispatch(sigc::slot_base* slot)
 {
-  return (*static_cast<sigc::slot<bool(IOCondition)>*>(slot))(poll_fd_.get_revents());
+  return (*static_cast<sigc::slot<bool, IOCondition>*>(slot))(poll_fd_.get_revents());
 }
 
 } // namespace Glib
index c2f799c..9a0ba45 100644 (file)
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmmconfig.h>
 #include <glibmm/refptr.h>
+#include <glibmm/timeval.h>
 #include <glibmm/priorities.h>
 #include <glibmm/iochannel.h>
 #include <sigc++/sigc++.h>
 #include <vector>
 #include <cstddef>
-#include <atomic>
 
 namespace Glib
 {
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+class GLIBMM_API Cond;
+class GLIBMM_API Mutex;
+
+namespace Threads
+{
+class GLIBMM_API Cond;
+class GLIBMM_API Mutex;
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 /** @defgroup MainLoop The Main Event Loop
  * Manages all available sources of events.
  * @{
  */
-
-class PollFD
+class GLIBMM_API PollFD
 {
 public:
   using fd_t = decltype(GPollFD::fd);
@@ -45,10 +56,10 @@ public:
   void set_fd(fd_t fd) { gobject_.fd = fd; }
   fd_t get_fd() const { return gobject_.fd; }
 
-  void set_events(IOCondition events) { gobject_.events = static_cast<decltype(gobject_.events)>(events); }
+  void set_events(IOCondition events) { gobject_.events = events; }
   IOCondition get_events() const { return static_cast<IOCondition>(gobject_.events); }
 
-  void set_revents(IOCondition revents) { gobject_.revents = static_cast<decltype(gobject_.revents)>(revents); }
+  void set_revents(IOCondition revents) { gobject_.revents = revents; }
   IOCondition get_revents() const { return static_cast<IOCondition>(gobject_.revents); }
 
   GPollFD* gobj() { return &gobject_; }
@@ -58,7 +69,17 @@ private:
   GPollFD gobject_;
 };
 
-class SignalTimeout
+// Concerning SignalTimeout::connect_once(), SignalTimeout::connect_seconds_once()
+// and SignalIdle::connect_once():
+// See https://bugzilla.gnome.org/show_bug.cgi?id=396963 and
+// http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+// It's recommended to replace sigc::slot<void>& by std::function<void()>& in
+// Threads::Thread::create() and ThreadPool::push() at the next ABI break.
+// Such a replacement would be a mixed blessing in SignalTimeout and SignalIdle.
+// In a single-threaded program auto-disconnection of trackable slots is safe
+// and can be useful.
+
+class GLIBMM_API SignalTimeout
 {
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -101,7 +122,7 @@ public:
    * @return A connection handle, which can be used to disconnect the handler.
    */
   sigc::connection connect(
-    const sigc::slot<bool()>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
+    const sigc::slot<bool>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
 
   /** Connects a timeout handler that runs only once.
    * This method takes a function pointer to a function with a void return
@@ -123,7 +144,7 @@ public:
    * @param priority The priority of the new event source.
    */
   void connect_once(
-    const sigc::slot<void()>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
+    const sigc::slot<void>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
 
   /** Connects a timeout handler with whole second granularity.
    *
@@ -161,7 +182,7 @@ public:
    * @newin{2,14}
    */
   sigc::connection connect_seconds(
-    const sigc::slot<bool()>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
+    const sigc::slot<bool>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
 
   /** Connects a timeout handler that runs only once with whole second
    *  granularity.
@@ -185,7 +206,7 @@ public:
    * @param priority The priority of the new event source.
    */
   void connect_seconds_once(
-    const sigc::slot<void()>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
+    const sigc::slot<void>& slot, unsigned int interval, int priority = PRIORITY_DEFAULT);
 
 private:
   GMainContext* context_;
@@ -194,7 +215,7 @@ private:
   SignalTimeout& operator=(const SignalTimeout&);
 };
 
-class SignalIdle
+class GLIBMM_API SignalIdle
 {
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -223,7 +244,7 @@ public:
    * @param priority The priority of the new event source.
    * @return A connection handle, which can be used to disconnect the handler.
    */
-  sigc::connection connect(const sigc::slot<bool()>& slot, int priority = PRIORITY_DEFAULT_IDLE);
+  sigc::connection connect(const sigc::slot<bool>& slot, int priority = PRIORITY_DEFAULT_IDLE);
 
   /** Connects an idle handler that runs only once.
    * This method takes a function pointer to a function with a void return
@@ -243,7 +264,7 @@ public:
    * @endcode
    * @param priority The priority of the new event source.
    */
-  void connect_once(const sigc::slot<void()>& slot, int priority = PRIORITY_DEFAULT_IDLE);
+  void connect_once(const sigc::slot<void>& slot, int priority = PRIORITY_DEFAULT_IDLE);
 
 private:
   GMainContext* context_;
@@ -252,7 +273,7 @@ private:
   SignalIdle& operator=(const SignalIdle&);
 };
 
-class SignalIO
+class GLIBMM_API SignalIO
 {
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -284,7 +305,7 @@ public:
    * @param priority The priority of the new event source.
    * @return A connection handle, which can be used to disconnect the handler.
    */
-  sigc::connection connect(const sigc::slot<bool(IOCondition)>& slot, PollFD::fd_t fd, IOCondition condition,
+  sigc::connection connect(const sigc::slot<bool, IOCondition>& slot, PollFD::fd_t fd, IOCondition condition,
     int priority = PRIORITY_DEFAULT);
 
   /** Connects an I/O handler that watches an I/O channel.
@@ -313,7 +334,7 @@ public:
    * @param priority The priority of the new event source.
    * @return A connection handle, which can be used to disconnect the handler.
    */
-  sigc::connection connect(const sigc::slot<bool(IOCondition)>& slot,
+  sigc::connection connect(const sigc::slot<bool, IOCondition>& slot,
     const Glib::RefPtr<IOChannel>& channel, IOCondition condition, int priority = PRIORITY_DEFAULT);
 
 private:
@@ -323,7 +344,7 @@ private:
   SignalIO& operator=(const SignalIO&);
 };
 
-class SignalChildWatch
+class GLIBMM_API SignalChildWatch
 {
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -345,7 +366,7 @@ public:
    * @return A connection handle, which can be used to disconnect the handler.
    */
   sigc::connection connect(
-    const sigc::slot<void(GPid, int)>& slot, GPid pid, int priority = PRIORITY_DEFAULT);
+    const sigc::slot<void, GPid, int>& slot, GPid pid, int priority = PRIORITY_DEFAULT);
 
 private:
   GMainContext* context_;
@@ -357,26 +378,30 @@ private:
 /** Convenience timeout signal.
  * @return A signal proxy; you want to use SignalTimeout::connect().
  */
+GLIBMM_API
 SignalTimeout signal_timeout();
 
 /** Convenience idle signal.
  * @return A signal proxy; you want to use SignalIdle::connect().
  */
+GLIBMM_API
 SignalIdle signal_idle();
 
 /** Convenience I/O signal.
  * @return A signal proxy; you want to use SignalIO::connect().
  */
+GLIBMM_API
 SignalIO signal_io();
 
 /** Convenience child watch signal.
  * @return A signal proxy; you want to use SignalChildWatch::connect().
  */
+GLIBMM_API
 SignalChildWatch signal_child_watch();
 
 /** Main context.
  */
-class MainContext
+class GLIBMM_API MainContext
 {
 public:
   using CppObjectType = Glib::MainContext;
@@ -390,10 +415,13 @@ public:
    * @return The new MainContext.
    */
   static Glib::RefPtr<MainContext> create();
-  /** Returns the default main context.
-   * This is the main context used for main loop functions when a main loop is not explicitly
-   * specified.
-   * @return The new MainContext.
+
+  /** Returns the global default main context.
+   * This is the main context used for main loop functions when a main loop
+   * is not explicitly specified, and corresponds to the "main" main loop.
+   *
+   * @return The global default main context.
+   * @see get_thread_default()
    */
   static Glib::RefPtr<MainContext> get_default();
 
@@ -432,6 +460,34 @@ public:
    */
   bool acquire();
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+  /** Tries to become the owner of the specified context, as with acquire().
+   * But if another thread is the owner, atomically drop mutex and wait on cond
+   * until that owner releases ownership or until cond is signaled, then try
+   * again (once) to become the owner.
+   * @param cond A condition variable.
+   * @param mutex A mutex, currently held.
+   * @return true if the operation succeeded, and this thread is now the owner of context.
+   *
+   * @deprecated Use the underlying g_main_context_is_owner() function
+   *   and separate locking, if you really need this functionality.
+   */
+  bool wait(Glib::Cond& cond, Glib::Mutex& mutex);
+
+  /** Tries to become the owner of the specified context, as with acquire().
+   * But if another thread is the owner, atomically drop mutex and wait on cond
+   * until that owner releases ownership or until cond is signaled, then try
+   * again (once) to become the owner.
+   * @param cond A condition variable.
+   * @param mutex A mutex, currently held.
+   * @return true if the operation succeeded, and this thread is now the owner of context.
+   *
+   * @deprecated Use the underlying g_main_context_is_owner() function
+   *   and separate locking, if you really need this functionality.
+   */
+  bool wait(Glib::Threads::Cond& cond, Glib::Threads::Mutex& mutex);
+#endif // GLIBMM_DISABLE_DEPRECATED
+
   /** Releases ownership of a context previously acquired by this thread with acquire(). If the
    * context was acquired
    * multiple times, the only release ownership when release() is called as many times as it was
@@ -502,6 +558,72 @@ public:
    */
   void remove_poll(PollFD& fd);
 
+  /** Acquires the context and sets it as the thread-default context for the current thread.
+   *
+   * This will cause certain asynchronous operations (such as most gio-based I/O)
+   * which are started in this thread to run under this context and deliver their
+   * results to its main loop, rather than running under the global
+   * default context in the main thread. Note that calling this function
+   * changes the context returned by get_thread_default(),
+   * not the one returned by get_default(), so it does not affect
+   * the context used by functions like g_idle_add().
+   *
+   * Normally you would call this function shortly after creating a new
+   * thread, passing it a Glib::MainContext which will be run by a
+   * Glib::MainLoop in that thread, to set a new default context for all
+   * async operations in that thread. In this case you may not need to
+   * ever call pop_thread_default(), assuming you want the
+   * new Glib::MainContext to be the default for the whole lifecycle of the
+   * thread.
+   *
+   * If you don't have control over how the new thread was created (e.g.
+   * if the new thread isn't newly created, or if the thread life
+   * cycle is managed by a GThreadPool), it is always suggested to wrap
+   * the logic that needs to use the new Glib::MainContext inside a
+   * push_thread_default() / pop_thread_default()
+   * pair, otherwise threads that are re-used will end up never explicitly
+   * releasing the Glib::MainContext reference they hold.
+   *
+   * In some cases you may want to schedule a single operation in a
+   * non-default context, or temporarily use a non-default context in
+   * the main thread. In that case, you can wrap the call to the
+   * asynchronous operation inside a push_thread_default() / pop_thread_default()
+   * pair, but it is up to you to ensure that no other asynchronous operations
+   * accidentally get started while the non-default context is active.
+   *
+   * Beware that libraries that predate this function may not correctly
+   * handle being used from a thread with a thread-default context. Eg,
+   * see Gio::File::supports_thread_contexts().
+   *
+   * @newin{2,64}
+   */
+  void push_thread_default();
+
+  /** Pops the context off the thread-default context stack (verifying that
+   * it was on the top of the stack).
+   *
+   * @newin{2,64}
+   */
+  void pop_thread_default();
+
+  /** Gets the thread-default MainContext for this thread.
+   * Asynchronous operations that want to be able to be run in contexts
+   * other than the default one should call this method to get a MainContext
+   * to add their Glib::Sources to. (Note that even in single-threaded
+   * programs applications may sometimes want to temporarily push a
+   * non-default context, so it is not safe to assume that this will
+   * always return the global default context if you are running in
+   * the default thread.)
+   *
+   * This method wraps g_main_context_ref_thread_default(),
+   * and not g_main_context_get_thread_default().
+   *
+   * @return The thread-default MainContext.
+   *
+   * @newin{2,64}
+   */
+  static Glib::RefPtr<MainContext> get_thread_default();
+
   /** Invokes a function in such a way that this MainContext is owned during
    * the invocation of @a slot.
    *
@@ -532,7 +654,7 @@ public:
    *
    * @newin{2,38}
    */
-  void invoke(const sigc::slot<bool()>& slot, int priority = PRIORITY_DEFAULT);
+  void invoke(const sigc::slot<bool>& slot, int priority = PRIORITY_DEFAULT);
 
   /** Timeout signal, attached to this MainContext.
    * @return A signal proxy; you want to use SignalTimeout::connect().
@@ -568,9 +690,10 @@ private:
 };
 
 /** @relates Glib::MainContext */
+GLIBMM_API
 Glib::RefPtr<MainContext> wrap(GMainContext* gobject, bool take_copy = false);
 
-class MainLoop
+class GLIBMM_API MainLoop
 {
 public:
   using CppObjectType = Glib::MainLoop;
@@ -626,9 +749,10 @@ private:
 };
 
 /** @relates Glib::MainLoop */
+GLIBMM_API
 Glib::RefPtr<MainLoop> wrap(GMainLoop* gobject, bool take_copy = false);
 
-class Source
+class GLIBMM_API Source
 {
 public:
   using CppObjectType = Glib::Source;
@@ -737,6 +861,16 @@ protected:
    */
   void remove_poll(PollFD& poll_fd);
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+  /** Gets the "current time" to be used when checking this source.
+   *
+   * @param[out] current_time Glib::TimeVal in which to store current time.
+   *
+   * @deprecated Use get_time() instead.
+   */
+  void get_current_time(Glib::TimeVal& current_time);
+#endif // GLIBMM_DISABLE_DEPRECATED
+
   // TODO: Remove mention of g_get_monotonic time when we wrap it in C++.
   /** Gets the time to be used when checking this source. The advantage of
    * calling this function over calling g_get_monotonic_time() directly is
@@ -759,13 +893,6 @@ protected:
 private:
   GSource* gobject_;
 
-  mutable std::atomic_int ref_count_ {1};
-  // The C++ wrapper (the Source instance) is deleted, when both Source::unreference()
-  // and SourceCallbackData::destroy_notify_callback() have decreased keep_wrapper_
-  // by calling destroy_notify_callback2().
-  // https://bugzilla.gnome.org/show_bug.cgi?id=561885
-  std::atomic_int keep_wrapper_ {2};
-
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   static inline Source* get_wrapper(GSource* source);
 
@@ -776,8 +903,7 @@ private:
   static gboolean dispatch_vfunc(GSource* source, GSourceFunc callback, void* user_data);
 
 public:
-  // Really destroys the object during the second call. See keep_wrapper_.
-  static void destroy_notify_callback2(void* data);
+  static void destroy_notify_callback(void* data);
   // Used by SignalXyz, possibly in other files.
   static sigc::connection attach_signal_source(const sigc::slot_base& slot, int priority,
     GSource* source, GMainContext* context, GSourceFunc callback_func);
@@ -788,13 +914,13 @@ public:
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 };
 
-class TimeoutSource : public Glib::Source
+class GLIBMM_API TimeoutSource : public Glib::Source
 {
 public:
   using CppObjectType = Glib::TimeoutSource;
 
   static Glib::RefPtr<TimeoutSource> create(unsigned int interval);
-  sigc::connection connect(const sigc::slot<bool()>& slot);
+  sigc::connection connect(const sigc::slot<bool>& slot);
 
 protected:
   explicit TimeoutSource(unsigned int interval);
@@ -805,17 +931,19 @@ protected:
   bool dispatch(sigc::slot_base* slot) override;
 
 private:
-  gint64 expiration_;     // microseconds
-  unsigned int interval_; // milliseconds
+  // TODO: Replace with gint64, because TimeVal is deprecated, when we can break ABI.
+  Glib::TimeVal expiration_;
+
+  unsigned int interval_;
 };
 
-class IdleSource : public Glib::Source
+class GLIBMM_API IdleSource : public Glib::Source
 {
 public:
   using CppObjectType = Glib::IdleSource;
 
   static Glib::RefPtr<IdleSource> create();
-  sigc::connection connect(const sigc::slot<bool()>& slot);
+  sigc::connection connect(const sigc::slot<bool>& slot);
 
 protected:
   IdleSource();
@@ -826,7 +954,7 @@ protected:
   bool dispatch(sigc::slot_base* slot_data) override;
 };
 
-class IOSource : public Glib::Source
+class GLIBMM_API IOSource : public Glib::Source
 {
 public:
   using CppObjectType = Glib::IOSource;
@@ -834,7 +962,7 @@ public:
   static Glib::RefPtr<IOSource> create(PollFD::fd_t fd, IOCondition condition);
   static Glib::RefPtr<IOSource> create(
     const Glib::RefPtr<IOChannel>& channel, IOCondition condition);
-  sigc::connection connect(const sigc::slot<bool(IOCondition)>& slot);
+  sigc::connection connect(const sigc::slot<bool, IOCondition>& slot);
 
 protected:
   IOSource(PollFD::fd_t fd, IOCondition condition);
@@ -854,14 +982,6 @@ protected:
   bool dispatch(sigc::slot_base* slot) override;
 
 private:
-  friend IOChannel;
-
-  // This is just to avoid the need for Gio::Socket to create a RefPtr<> to itself.
-  static Glib::RefPtr<IOSource> create(GIOChannel* channel, IOCondition condition);
-
-  // This is just to avoid the need for Gio::Socket to create a RefPtr<> to itself.
-  IOSource(GIOChannel* channel, IOCondition condition);
-
   PollFD poll_fd_;
 };
 
diff --git a/glib/glibmm/meson.build b/glib/glibmm/meson.build
new file mode 100644 (file)
index 0000000..fc4630c
--- /dev/null
@@ -0,0 +1,364 @@
+# glib/glibmm
+
+# Input: glibmm_build_dep, glibmm_pcname, maintainer_mode, project_source_root,
+#        generate_binding_py, handle_built_files_py, m4_files, pm_files,
+#        glibmm_libversion, install_includedir, python3, glibmm_rc, gmmproc_dir,
+#        is_host_windows, gmmproc, generate_wrap_init_pl
+# Output: glibmm_hg_ccg_basenames, glibmm_extra_h_files, built_files_root,
+#         glibmm_built_h_file_targets, glibmm_dep
+
+glibmm_defs_basefiles = [
+  'glib.defs',
+  'glib_enums.defs',
+  'glib_functions.defs',
+  'glib_signals.defs',
+  'glib_extra_objects.defs',
+  'gmodule_enums.defs',
+  'gmodule_functions.defs',
+  'gobject_enums.defs',
+  'gobject_functions.defs',
+  'glib_docs.xml',
+  'glib_docs_override.xml',
+]
+
+glibmm_defs_files = []
+foreach file : glibmm_defs_basefiles
+  glibmm_defs_files += '..' / 'src' / file
+endforeach
+
+# Generated from pairs of .hg and .ccg files.
+glibmm_hg_ccg_basenames = [
+  'balancedtree',
+  'binding',
+  'bytes',
+  'bytearray',
+  'checksum',
+  'convert',
+  'date',
+  'datetime',
+  'enums',
+  'fileutils',
+  'iochannel',
+  'keyfile',
+  'markup',
+  'miscutils',
+  'module',
+  'nodetree',
+  'optioncontext',
+  'optionentry',
+  'optiongroup',
+  'regex',
+  'shell',
+  'spawn',
+  'thread',
+  'threads',
+  'timezone',
+  'unicode',
+  'uriutils',
+  'valuearray',
+  'variant',
+  'variantdict',
+  'variantiter',
+  'varianttype',
+]
+
+# Generated from .m4 files.
+glibmm_h_m4_files = [
+  'value_basictypes.h',
+  'variant_basictypes.h',
+]
+
+glibmm_cc_m4_files = [
+  'value_basictypes.cc',
+  'variant_basictypes.cc',
+]
+
+# Pairs of hand-coded .h and .cc files.
+glibmm_extra_h_cc_basenames = [
+  'arrayhandle',
+  'base64',
+  'class',
+  'containers',
+  'debug',
+  'dispatcher',
+  'error',
+  'exception',
+  'exceptionhandler',
+  'extraclassinit',
+  'init',
+  'interface',
+  'main',
+  'object',
+  'objectbase',
+  'pattern',
+  'property',
+  'propertyproxy',
+  'propertyproxy_base',
+  'quark',
+  'random',
+  'sarray',
+  'signalproxy',
+  'signalproxy_connectionnode',
+  'streamiochannel',
+  'stringutils',
+  'threadpool',
+  'timer',
+  'timeval',
+  'ustring',
+  'utility',
+  'value',
+  'value_custom',
+  'variantdbusstring',
+  'vectorutils',
+  'wrap',
+]
+
+glibmm_extra_h_files = [
+  'containerhandle_shared.h',
+  'helperlist.h',
+  'i18n-lib.h',
+  'i18n.h',
+  'listhandle.h',
+  'priorities.h',
+  'refptr.h',
+  'slisthandle.h',
+  'weakref.h',
+  'wrap_init.h',
+]
+
+glibmm_extra_ph_files = [
+  'private' / 'interface_p.h',
+  'private' / 'object_p.h',
+]
+
+glibmm_extra_cc_files = []
+
+foreach file : glibmm_extra_h_cc_basenames
+  glibmm_extra_h_files += file + '.h'
+  glibmm_extra_cc_files += file + '.cc'
+endforeach
+
+install_headers('..' / 'glibmm.h', subdir: glibmm_pcname)
+install_headers(glibmm_extra_h_files, subdir: glibmm_pcname / 'glibmm')
+install_headers(glibmm_extra_ph_files, subdir: glibmm_pcname / 'glibmm' / 'private')
+
+untracked_glibmm = 'untracked' / 'glib' / 'glibmm'
+src_untracked_glibmm = project_source_root / untracked_glibmm
+
+extra_glibmm_objects = []
+glibmm_cpp_args = [ '-DGLIBMM_BUILD=1' ]
+
+# Build the .rc file for Windows builds and link to it
+if is_host_windows
+  windows = import('windows')
+  glibmm_res = windows.compile_resources(glibmm_rc)
+  extra_glibmm_objects += glibmm_res
+endif
+
+if maintainer_mode
+
+  # Maintainer mode. Generate .h and .cc files from .hg and .ccg files in ../src.
+
+  # docs/reference/meson.build needs these.
+  built_files_root = project_build_root
+  glibmm_built_h_file_targets = []
+
+  # Force meson+ninja to generate source files before anything is compiled.
+  # Compilation must depend on these targets.
+  glibmm_built_cc_file_targets = []
+
+  hg_files = []
+  foreach file : glibmm_hg_ccg_basenames
+    hg_files += '..' / 'src' / file + '.hg'
+  endforeach
+
+  # Create wrap_init.cc in project_build_root/glib/glibmm.
+  glibmm_built_cc_file_targets += custom_target('glibmm-wrap_init.cc',
+    input: hg_files,
+    output: 'wrap_init.cc',
+    command: [
+      python3, generate_binding_py, 'generate_wrap_init',
+      gmmproc_dir,
+      '@OUTPUT@',
+      'Glib', # namespace
+      '@INPUT@',
+    ],
+    depend_files: generate_wrap_init_pl,
+    build_by_default: maintainer_mode,
+    install: false,
+  )
+
+  # Create .h/_p.h/.cc files in project_build_root/glib/glibmm
+  # from .hg/.ccg files in project_source_root/glib/src.
+  foreach file : glibmm_hg_ccg_basenames
+    hg_file = '..' / 'src' / file + '.hg'
+    ccg_file = '..' / 'src' / file + '.ccg'
+    built_file_target = custom_target('glibmm-' + file + '.cc',
+      input: [hg_file, ccg_file],
+      output: [file + '.stamp', file + '.cc', file + '.h'],
+      command: [
+        python3, handle_built_files_py, 'gmmproc',
+        gmmproc_dir,
+        project_source_root / 'tools' / 'pm',
+        '@OUTPUT0@',
+        file,
+        meson.current_source_dir() / '..' / 'src',
+        project_source_root / 'tools' / 'm4',
+      ],
+      depend_files: glibmm_defs_files + m4_files + [gmmproc] + pm_files,
+      build_by_default: maintainer_mode,
+      install: false,
+    )
+    glibmm_built_cc_file_targets += built_file_target[1]
+    glibmm_built_h_file_targets += built_file_target[2]
+  endforeach
+
+  # Create .h and .cc files in project_build_root/glib/glibmm
+  # from .m4 files in project_source_root/glib/src.
+  foreach output_file : glibmm_h_m4_files + glibmm_cc_m4_files
+    input_file = '..' / 'src' / output_file + '.m4'
+    built_file_target = custom_target('glibmm-' + output_file,
+      input: input_file,
+      output: output_file,
+      command: [
+        python3, handle_built_files_py, 'build_from_m4',
+        meson.current_source_dir() / '..' / 'src',
+        '@INPUT@',
+        '@OUTPUT@',
+      ],
+      depend_files: '..' / 'src' / 'template.macros.m4',
+      build_by_default: maintainer_mode,
+      install: false,
+    )
+    if output_file.endswith('.cc')
+      glibmm_built_cc_file_targets += built_file_target
+    else
+      glibmm_built_h_file_targets += built_file_target
+    endif
+  endforeach
+
+  # Create dummy_header.h, depending on all generated headers.
+  # It's created if it does not exist, but it's never updated.
+  # It guarantees that all generated headers are built before glibmm_library
+  # is built, at the same time avoiding unnecessary recompilations.
+  # If glibmm_built_h_file_targets would be listed as sources to glibmm_library,
+  # all generated .cc files could be recompiled if one generated .h file has
+  # been changed.
+  built_dummy_h_file_target = custom_target('glibmm-dummy_header.h',
+    input: glibmm_built_h_file_targets,
+    output: 'dummy_header.h',
+    command: [
+      python3, dummy_header_py,
+      '@OUTPUT@',
+    ],
+    build_by_default: maintainer_mode,
+    install: false,
+  )
+
+  extra_include_dirs = ['..']
+
+  glibmm_library = library(glibmm_pcname, extra_glibmm_objects,
+    glibmm_built_cc_file_targets, glibmm_extra_cc_files, built_dummy_h_file_target,
+    include_directories: extra_include_dirs,
+    cpp_args: glibmm_cpp_args,
+    version: glibmm_libversion,
+    dependencies: glibmm_build_dep,
+    install: true,
+  )
+
+  built_h_cc_dir = meson.current_build_dir()
+
+else # not maintainer_mode
+
+  # Not maintainer mode. Compile built source code files in
+  # project_source_root/untracked/glib/glibmm.
+
+  # docs/reference/meson.build needs these.
+  built_files_root = project_source_root / 'untracked'
+  glibmm_built_h_file_targets = []
+
+  # Two cases:
+  # 1. The source code comes from a tarball, where the built files
+  #    are stored in project_source_root/untracked.
+  #    There are no built files in the build tree.
+  # 2. Files have been built in the build tree. Then maintainer_mode has
+  #    been changed from true to false. Files that are missing or not up to date
+  #    in project_source_root/untracked are copied from the build tree.
+
+  # Try to copy built source code files to the source tree.
+  run_command(
+    python3, generate_binding_py, 'copy_built_files',
+    meson.current_build_dir(),
+    src_untracked_glibmm,
+    glibmm_hg_ccg_basenames,
+  )
+  run_command(
+    python3, handle_built_files_py, 'copy_built_files',
+    meson.current_build_dir(),
+    src_untracked_glibmm,
+    glibmm_h_m4_files + glibmm_cc_m4_files,
+  )
+
+  built_cc_files = [ src_untracked_glibmm / 'wrap_init.cc' ]
+  foreach file : glibmm_hg_ccg_basenames
+    built_cc_files += src_untracked_glibmm / file + '.cc'
+  endforeach
+  foreach file : glibmm_cc_m4_files
+    built_cc_files += src_untracked_glibmm / file
+  endforeach
+
+  extra_include_dirs = [ '..', '..' / '..' / 'untracked' / 'glib' ]
+
+  glibmm_library = library(glibmm_pcname, extra_glibmm_objects,
+    built_cc_files, glibmm_extra_cc_files,
+    include_directories: extra_include_dirs,
+    cpp_args: glibmm_cpp_args,
+    version: glibmm_libversion,
+    dependencies: glibmm_build_dep,
+    install: true,
+  )
+
+  built_h_cc_dir = src_untracked_glibmm
+
+endif
+
+# Install built .h and _p.h files.
+meson.add_install_script(
+  python3.path(), generate_binding_py, 'install_built_h_files',
+  built_h_cc_dir,
+  install_includedir / glibmm_pcname / 'glibmm', # subdir below {prefix}
+  glibmm_hg_ccg_basenames
+)
+# Install .h files built from .m4 files.
+meson.add_install_script(
+  python3.path(), handle_built_files_py, 'install_built_h_files',
+  built_h_cc_dir,
+  install_includedir / glibmm_pcname / 'glibmm', # subdir below {prefix}
+  glibmm_h_m4_files,
+)
+
+if not meson.is_subproject()
+  # Distribute built files.
+  # (add_dist_script() is not allowed in a subproject)
+  meson.add_dist_script(
+    python3.path(), generate_binding_py, 'dist_built_files',
+    built_h_cc_dir,
+    untracked_glibmm,
+    glibmm_hg_ccg_basenames,
+  )
+  meson.add_dist_script(
+    python3.path(), handle_built_files_py, 'dist_built_files',
+    built_h_cc_dir,
+    untracked_glibmm,
+    glibmm_h_m4_files + glibmm_cc_m4_files,
+  )
+endif
+
+# This is useful in the main project when glibmm is used as a subproject.
+# It's also used when building example programs and test programs.
+glibmm_dep = declare_dependency(
+  sources: glibmm_built_h_file_targets,
+  link_with: glibmm_library,
+  include_directories: extra_include_dirs,
+  dependencies: glibmm_build_dep,
+)
index 4dc73b3..2fa0910 100644 (file)
 
 #include <string.h>
 
+// Weak references:
+// I'm not sure what the point of these are apart from being a hacky way out of circular references,
+// but maybe we could make it easier to use them by making a Java Reference Object -style class like
+// so:
+// Glib::WeakRef<SomeDerivedObject> weakrefSomeObject(object1);
+// ...
+// if(weakrefSomeObject->isStillAlive())
+// {
+//   weakrefSomeObject->some_method();
+// }
+// else
+// {
+//   //Deal with it, maybe recreating the object.
+// }
+//
+// Without this, the coder has to define his own signal handler which sets his own isStillAlive
+// boolean.
+// weakrefSomeObject<> could still have its own signal_destroyed signal so that coders can choose to
+// deal
+// with the destruction as soon as it happens instead of just checking later before they try to use
+// it.
+
 namespace Glib
 {
 
 ConstructParams::ConstructParams(const Glib::Class& glibmm_class_)
-: glibmm_class(glibmm_class_), n_parameters(0), parameter_names(nullptr), parameter_values(nullptr)
+: glibmm_class(glibmm_class_), n_parameters(0), parameters(nullptr)
 {
 }
 
@@ -46,7 +68,7 @@ ConstructParams::ConstructParams(const Glib::Class& glibmm_class_)
  */
 ConstructParams::ConstructParams(
   const Glib::Class& glibmm_class_, const char* first_property_name, ...)
-: glibmm_class(glibmm_class_), n_parameters(0), parameter_names(nullptr), parameter_values(nullptr)
+: glibmm_class(glibmm_class_), n_parameters(0), parameters(nullptr)
 {
   va_list var_args;
   va_start(var_args, first_property_name);
@@ -69,26 +91,25 @@ ConstructParams::ConstructParams(
       break;
     }
 
-    if (n_parameters >= n_alloced_params) {
-      n_alloced_params += 8;
-      parameter_names = g_renew(const char*, parameter_names, n_alloced_params);
-      parameter_values = g_renew(GValue, parameter_values, n_alloced_params);
-    }
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+    if (n_parameters >= n_alloced_params)
+      parameters = g_renew(GParameter, parameters, n_alloced_params += 8);
 
-    auto& param_name = parameter_names[n_parameters];
-    auto& param_value = parameter_values[n_parameters];
-    param_name = name;
-    param_value.g_type = 0;
+    GParameter& param = parameters[n_parameters];
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+    param.name = name;
+    param.value.g_type = 0;
 
     // Fill the GValue with the current vararg, and move on to the next one.
-    g_value_init(&param_value, G_PARAM_SPEC_VALUE_TYPE(pspec));
-    G_VALUE_COLLECT(&param_value, var_args, 0, &collect_error);
+    g_value_init(&param.value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+    G_VALUE_COLLECT(&param.value, var_args, 0, &collect_error);
 
     if (collect_error)
     {
       g_warning("Glib::ConstructParams::ConstructParams(): %s", collect_error);
       g_free(collect_error);
-      g_value_unset(&param_value);
+      g_value_unset(&param.value);
       break;
     }
 
@@ -102,15 +123,34 @@ ConstructParams::ConstructParams(
 
 ConstructParams::~ConstructParams() noexcept
 {
-  while (n_parameters > 0) {
-    auto& param_value = parameter_values[--n_parameters];
-    g_value_unset(&param_value);
-  }
+  while (n_parameters > 0)
+    g_value_unset(&parameters[--n_parameters].value);
 
-  g_free(parameter_names);
-  g_free(parameter_values);
+  g_free(parameters);
 }
 
+/*
+ * Some compilers require the existence of a copy constructor in certain
+ * usage contexts.  This implementation is fully functional, but unlikely
+ * to be ever actually called due to optimization.
+ */
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ConstructParams::ConstructParams(const ConstructParams& other)
+: glibmm_class(other.glibmm_class),
+  n_parameters(other.n_parameters),
+  parameters(g_new(GParameter, n_parameters))
+{
+  for (unsigned int i = 0; i < n_parameters; ++i)
+  {
+    parameters[i].name = other.parameters[i].name;
+    parameters[i].value.g_type = 0;
+
+    g_value_init(&parameters[i].value, G_VALUE_TYPE(&other.parameters[i].value));
+    g_value_copy(&other.parameters[i].value, &parameters[i].value);
+  }
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+
 /**** Glib::Object_Class ***************************************************/
 
 const Glib::Class&
@@ -158,7 +198,6 @@ Object::Object()
   if (custom_type_name_ && !is_anonymous_custom_())
   {
     object_class_.init();
-
     // This creates a type that is derived (indirectly) from GObject.
     object_type = object_class_.clone_custom_type(custom_type_name_,
       get_custom_interface_classes(), get_custom_class_init_functions(),
@@ -166,10 +205,10 @@ Object::Object()
     custom_class_init_finished();
   }
 
-  GObject* const new_object = g_object_new_with_properties(object_type, 0, nullptr, nullptr);
+  void* const new_object = g_object_new(object_type, nullptr);
 
   // Connect the GObject and Glib::Object instances.
-  ObjectBase::initialize(new_object);
+  ObjectBase::initialize(static_cast<GObject*>(new_object));
 }
 
 Object::Object(const Glib::ConstructParams& construct_params)
@@ -193,11 +232,16 @@ Object::Object(const Glib::ConstructParams& construct_params)
   // This works with custom types too, since those inherit the properties of
   // their base class.
 
-  GObject* const new_object =
-    g_object_new_with_properties(object_type, construct_params.n_parameters, construct_params.parameter_names, construct_params.parameter_values);
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  //TODO: Replace g_object_newv() by g_object_new_with_properties() when we can
+  // require glib 2.54. GParameter is also deprecated.
+  // Don't use it in ConstructParams when we can break ABI.
+  void* const new_object =
+    g_object_newv(object_type, construct_params.n_parameters, construct_params.parameters);
+  G_GNUC_END_IGNORE_DEPRECATIONS
 
   // Connect the GObject and Glib::Object instances.
-  ObjectBase::initialize(new_object);
+  ObjectBase::initialize(static_cast<GObject*>(new_object));
 }
 
 Object::Object(GObject* castitem)
index cda1552..824c6b7 100644 (file)
@@ -47,15 +47,14 @@ namespace Glib
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-class Class;
-class Object_Class;
-class GSigConnectionNode;
+class GLIBMM_API Class;
+class GLIBMM_API Object_Class;
+class GLIBMM_API GSigConnectionNode;
 
 /* ConstructParams::ConstructParams() takes a varargs list of properties
  * and values, like g_object_new() does.  This list will then be converted
- * to an array of parameter names and an array of parameter values,
- * for use with g_object_new_with_properties().  No overhead is
- * involved, since g_object_new() is just a wrapper around g_object_new_with_properties()
+ * to a GParameter array, for use with g_object_newv().  No overhead is
+ * involved, since g_object_new() is just a wrapper around g_object_newv()
  * as well.
  *
  * The advantage of an auxiliary ConstructParams object over g_object_new()
@@ -66,21 +65,29 @@ class GSigConnectionNode;
  * The comments in object.cc and objectbase.cc should explain in detail
  * how this works.
  */
-class ConstructParams
+class GLIBMM_API ConstructParams
 {
 public:
   const Glib::Class& glibmm_class;
   unsigned int n_parameters;
-  const char ** parameter_names;
-  GValue* parameter_values;
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  GParameter* parameters;
+G_GNUC_END_IGNORE_DEPRECATIONS
 
   explicit ConstructParams(const Glib::Class& glibmm_class_);
   ConstructParams(const Glib::Class& glibmm_class_, const char* first_property_name,
     ...) G_GNUC_NULL_TERMINATED; // warn if called without a trailing NULL pointer
   ~ConstructParams() noexcept;
 
-  ConstructParams(const ConstructParams& other) = delete;
-  ConstructParams& operator=(const ConstructParams&) = delete;
+  // The copy constructor is semantically required by the C++ compiler
+  // (since g++ 3.4) to be able to create temporary instances, depending
+  // on the usage context.  Apparently the compiler will actually optimize
+  // away the copy, though.  See bug #132300.
+  ConstructParams(const ConstructParams& other);
+
+private:
+  // no copy assignment
+  ConstructParams& operator=(const ConstructParams&);
 };
 
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
@@ -180,7 +187,7 @@ struct TypeTraits<Glib::RefPtr<T>>
     // because that would be "dependent", and g++ 3.4 does not allow that.
     // The specific Glib::wrap() overloads don't do anything special anyway.
     GObject* cobj = (GObject*)const_cast<CTypeNonConst>(ptr);
-    return Glib::make_refptr_for_instance<T>(dynamic_cast<T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
+    return Glib::RefPtr<T>(dynamic_cast<T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
     // We use dynamic_cast<> in case of multiple inheritance.
   }
 
@@ -216,7 +223,7 @@ struct TypeTraits<Glib::RefPtr<const T>>
     // because that would be "dependent", and g++ 3.4 does not allow that.
     // The specific Glib::wrap() overloads don't do anything special anyway.
     GObject* cobj = (GObject*)(ptr);
-    return Glib::make_refptr_for_instance<const T>(
+    return Glib::RefPtr<const T>(
       dynamic_cast<const T*>(Glib::wrap_auto(cobj, true /* take_copy */)));
     // We use dynamic_cast<> in case of multiple inheritance.
   }
@@ -232,9 +239,9 @@ struct TypeTraits<Glib::RefPtr<const T>>
 
 } // namespace Container_Helpers
 
-template <class PtrT>
+template <class T, class PtrT>
 inline PtrT
-Value_Pointer<PtrT>::get_(Glib::Object*) const
+Value_Pointer<T, PtrT>::get_(Glib::Object*) const
 {
   return dynamic_cast<T*>(get_object());
 }
@@ -251,8 +258,8 @@ public:
 
   static GType value_type() { return T::get_base_type(); }
 
-  void set(const CppType& data) { set_object(data.get()); }
-  CppType get() const { return std::dynamic_pointer_cast<T>(get_object_copy()); }
+  void set(const CppType& data) { set_object(data.operator->()); }
+  CppType get() const { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
 };
 
 // The SUN Forte Compiler has a problem with this:
@@ -270,8 +277,8 @@ public:
 
   static GType value_type() { return T::get_base_type(); }
 
-  void set(const CppType& data) { set_object(const_cast<T*>(data.get())); }
-  CppType get() const { return std::dynamic_pointer_cast<T>(get_object_copy()); }
+  void set(const CppType& data) { set_object(const_cast<T*>(data.operator->())); }
+  CppType get() const { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
 };
 #endif /* GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS */
 
index f23c497..19edd8a 100644 (file)
@@ -39,16 +39,9 @@ namespace Glib
 
 /**** Glib::ObjectBase *****************************************************/
 
-// Used only during the construction of named custom types.
-struct ObjectBase::PrivImpl
-{
-  // Pointers to the interfaces of custom types.
-  Class::interface_classes_type custom_interface_classes;
-  // Pointers to extra class init functions.
-  Class::class_init_funcs_type custom_class_init_functions;
-  // Pointer to the instance init function.
-  GInstanceInitFunc custom_instance_init_function = nullptr;
-};
+// static data members
+ObjectBase::extra_object_base_data_type ObjectBase::extra_object_base_data;
+std::mutex ObjectBase::extra_object_base_data_mutex;
 
 ObjectBase::ObjectBase()
 : gobject_(nullptr),
@@ -58,14 +51,12 @@ ObjectBase::ObjectBase()
 }
 
 ObjectBase::ObjectBase(const char* custom_type_name)
-: gobject_(nullptr), custom_type_name_(custom_type_name),
-  cpp_destruction_in_progress_(false)
+: gobject_(nullptr), custom_type_name_(custom_type_name), cpp_destruction_in_progress_(false)
 {
 }
 
 ObjectBase::ObjectBase(const std::type_info& custom_type_info)
-: gobject_(nullptr), custom_type_name_(custom_type_info.name()),
-  cpp_destruction_in_progress_(false)
+: gobject_(nullptr), custom_type_name_(custom_type_info.name()), cpp_destruction_in_progress_(false)
 {
 }
 
@@ -162,6 +153,14 @@ ObjectBase::~ObjectBase() noexcept
   // we have to call g_object_unref() on our own.
   //
 
+  // Just a precaution. Unless a derived class's ctor has thrown an exception,
+  // 'this' should have been erased from extra_object_base_data by
+  // Glib::Object's constructor.
+  {
+    std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+    extra_object_base_data.erase(this);
+  }
+
   if (GObject* const gobject = gobject_)
   {
 #ifdef GLIBMM_DEBUG_REFCOUNTING
@@ -279,9 +278,9 @@ ObjectBase::destroy_notify_callback_(void* data)
     (void*)cppObject, (void*)cppObject->gobject_, G_OBJECT_TYPE_NAME(cppObject->gobject_));
 #endif
 
-  if (cppObject) // This will be nullptr if the C++ destructor has already run.
+  if (cppObject) // This will be 0 if the C++ destructor has already run.
   {
-    cppObject->destroy_notify_(); // Virtual - it does different things for Glib::ObjectBase and Gtk::Object.
+    cppObject->destroy_notify_(); // Virtual - it does different things for GObject and GtkObject.
   }
 }
 
@@ -290,13 +289,13 @@ ObjectBase::destroy_notify_()
 {
 // The C instance is about to be disposed, making it unusable.  Now is a
 // good time to delete the C++ wrapper of the C instance.  There is no way
-// to force the disposal of the GObject (though Gtk::Object::destroy_notify_()
-// can call g_object_run_dispose()), so this is the *only* place where we delete
-// the C++ wrapper.
+// to force the disposal of the GObject (though GtkObject  has
+// gtk_object_destroy()), So this is the *only* place where we delete the
+// C++ wrapper.
 //
 // This will only happen after the last unreference(), which will be done by
 // the RefPtr<> destructor.  There should be no way to access the wrapper or
-// the underlying object instance after that, so it's OK to delete this.
+// the undobjecterlying instance after that, so it's OK to delete this.
 
 #ifdef GLIBMM_DEBUG_REFCOUNTING
   g_warning("Glib::ObjectBase::destroy_notify_: gobject_ = %p", (void*)gobject_);
@@ -351,9 +350,22 @@ ObjectBase::get_property_value(const Glib::ustring& property_name, Glib::ValueBa
   g_object_get_property(const_cast<GObject*>(gobj()), property_name.c_str(), value.gobj());
 }
 
-sigc::connection
+void
 ObjectBase::connect_property_changed(
-  const Glib::ustring& property_name, const sigc::slot<void()>& slot)
+  const Glib::ustring& property_name, const sigc::slot<void>& slot)
+{
+  connect_property_changed_with_return(property_name, slot);
+}
+
+void
+ObjectBase::connect_property_changed(const Glib::ustring& property_name, sigc::slot<void>&& slot)
+{
+  connect_property_changed_with_return(property_name, std::move(slot));
+}
+
+sigc::connection
+ObjectBase::connect_property_changed_with_return(
+  const Glib::ustring& property_name, const sigc::slot<void>& slot)
 {
   // Create a proxy to hold our connection info
   // This will be deleted by destroy_notify_handler.
@@ -365,8 +377,8 @@ ObjectBase::connect_property_changed(
 }
 
 sigc::connection
-ObjectBase::connect_property_changed(
-  const Glib::ustring& property_name, sigc::slot<void()>&& slot)
+ObjectBase::connect_property_changed_with_return(
+  const Glib::ustring& property_name, sigc::slot<void>&& slot)
 {
   // Create a proxy to hold our connection info
   // This will be deleted by destroy_notify_handler.
@@ -389,51 +401,54 @@ ObjectBase::thaw_notify()
   g_object_thaw_notify(gobj());
 }
 
-GType ObjectBase::get_base_type()
-{
-  return G_TYPE_OBJECT;
-}
-
 void ObjectBase::add_custom_interface_class(const Interface_Class* iface_class)
 {
-  if (!priv_pimpl_)
-    priv_pimpl_ = std::make_unique<PrivImpl>();
-  priv_pimpl_->custom_interface_classes.emplace_back(iface_class);
+  // The GObject is not instantiated yet. Add to the custom_interface_classes
+  // and add the interface in the Glib::Object constructor.
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  extra_object_base_data[this].custom_interface_classes.emplace_back(iface_class);
 }
 
 void ObjectBase::add_custom_class_init_function(GClassInitFunc class_init_func, void* class_data)
 {
-  if (!priv_pimpl_)
-    priv_pimpl_ = std::make_unique<PrivImpl>();
-  priv_pimpl_->custom_class_init_functions.emplace_back(
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  extra_object_base_data[this].custom_class_init_functions.emplace_back(
     std::make_tuple(class_init_func, class_data));
 }
 
 void ObjectBase::set_custom_instance_init_function(GInstanceInitFunc instance_init_func)
 {
-  if (!priv_pimpl_)
-    priv_pimpl_ = std::make_unique<PrivImpl>();
-  priv_pimpl_->custom_instance_init_function = instance_init_func;
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  extra_object_base_data[this].custom_instance_init_function = instance_init_func;
 }
 
-const Class::interface_classes_type* ObjectBase::get_custom_interface_classes() const
+const Class::interface_class_vector_type* ObjectBase::get_custom_interface_classes() const
 {
-  return priv_pimpl_ ? &priv_pimpl_->custom_interface_classes : nullptr;
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  const auto iter = extra_object_base_data.find(this);
+  return (iter != extra_object_base_data.end()) ? &iter->second.custom_interface_classes : nullptr;
 }
 
 const Class::class_init_funcs_type* ObjectBase::get_custom_class_init_functions() const
 {
-  return priv_pimpl_ ? &priv_pimpl_->custom_class_init_functions : nullptr;
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  const auto iter = extra_object_base_data.find(this);
+  return (iter != extra_object_base_data.end()) ? &iter->second.custom_class_init_functions : nullptr;
 }
 
 GInstanceInitFunc ObjectBase::get_custom_instance_init_function() const
 {
-  return priv_pimpl_ ? priv_pimpl_->custom_instance_init_function : nullptr;
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  const auto iter = extra_object_base_data.find(this);
+  return (iter != extra_object_base_data.end()) ? iter->second.custom_instance_init_function : nullptr;
 }
 
 void ObjectBase::custom_class_init_finished()
 {
-  priv_pimpl_.reset();
+  std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
+  const auto iter = extra_object_base_data.find(this);
+  if (iter != extra_object_base_data.end())
+    extra_object_base_data.erase(iter);
 }
 
 /**** Global function *****************************************************/
index cf391dc..16d1a79 100644 (file)
@@ -27,7 +27,9 @@
 #include <glibmm/debug.h>
 #include <sigc++/trackable.h>
 #include <typeinfo>
-#include <memory>
+#include <map> // Needed until the next ABI break.
+#include <memory> // Not used by ObjectBase any more, but user code may rely on it being here.
+#include <mutex>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" {
@@ -39,8 +41,8 @@ namespace Glib
 {
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-class GSigConnectionNode;
-class Interface_Class;
+class GLIBMM_API GSigConnectionNode;
+class GLIBMM_API Interface_Class;
 #endif
 
 // This inherits virtually from sigc::trackable so that people can multiply inherit glibmm classes
@@ -59,14 +61,6 @@ public:
   ObjectBase(const ObjectBase&) = delete;
   ObjectBase& operator=(const ObjectBase&) = delete;
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-  // get_base_type() is needed so Glib::ObjectBase can be used with
-  // Glib::Value and _WRAP_PROPERTY in Glib::Binding without a
-  // Value<RefPtr<ObjectBase>> specialization.
-  // The Value<RefPtr<T>> specialization requires T::get_base_type().
-  static GType get_base_type() G_GNUC_CONST;
-#endif
-
 protected:
   /** This default constructor is called implicitly from the constructor of user-derived
    * classes, even if, for instance, Gtk::Button calls a different ObjectBase constructor.
@@ -125,19 +119,34 @@ public:
   template <class PropertyType>
   void get_property(const Glib::ustring& property_name, PropertyType& value) const;
 
-  /// You probably want to use a specific property_*() accessor method instead.
-  template <class PropertyType>
-  PropertyType get_property(const Glib::ustring& property_name) const;
+  // TODO: At the next ABI break, delete connect_property_changed_with_return()
+  // and let connect_property_changed() return sigc::connection.
+  /** You can use the signal_changed() signal of the property proxy instead.
+   *
+   * See also connect_property_changed_with_return().
+   */
+  void connect_property_changed(const Glib::ustring& property_name, const sigc::slot<void>& slot);
 
   /** You can use the signal_changed() signal of the property proxy instead.
+   *
+   * @newin{2,48}
+   */
+  void connect_property_changed(const Glib::ustring& property_name, sigc::slot<void>&& slot);
+
+  /** You can use the signal_changed() signal of the property proxy instead.
+   *
+   * This method was added because connect_property_changed() does not return a sigc::connection,
+   * and we could not break the ABI by changing that function.
    */
-  sigc::connection connect_property_changed(const Glib::ustring& property_name, const sigc::slot<void()>& slot);
+  sigc::connection connect_property_changed_with_return(
+    const Glib::ustring& property_name, const sigc::slot<void>& slot);
 
   /** You can use the signal_changed() signal of the property proxy instead.
    *
    * @newin{2,48}
    */
-  sigc::connection connect_property_changed(const Glib::ustring& property_name, sigc::slot<void()>&& slot);
+  sigc::connection connect_property_changed_with_return(
+    const Glib::ustring& property_name, sigc::slot<void>&& slot);
 
   /** Increases the freeze count on object. If the freeze count is non-zero, the
    * emission of "notify" signals on object is stopped. The signals are queued
@@ -215,7 +224,7 @@ protected:
   void add_custom_interface_class(const Interface_Class* iface_class);
   void add_custom_class_init_function(GClassInitFunc class_init_func, void* class_data = nullptr);
   void set_custom_instance_init_function(GInstanceInitFunc instance_init_func);
-  const Class::interface_classes_type* get_custom_interface_classes() const;
+  const Class::interface_class_vector_type* get_custom_interface_classes() const;
   const Class::class_init_funcs_type* get_custom_class_init_functions() const;
   GInstanceInitFunc get_custom_instance_init_function() const;
   void custom_class_init_finished();
@@ -246,15 +255,34 @@ protected:
 
 private:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  virtual void set_manage(); // calls g_error()
+
+  // TODO: At the next ABI break, replace extra_object_base_data by a non-static
+  // data member.
   // Private part of implementation.
   // Used only during construction of named custom types.
-  struct PrivImpl;
-  std::unique_ptr<PrivImpl> priv_pimpl_;
-
-  virtual void set_manage(); // calls g_error()
+  // This is a new data member that can't be added as instance data to
+  // ObjectBase now, because it would break ABI.
+  struct ExtraObjectBaseData
+  {
+    // Pointers to the interfaces of custom types.
+    Class::interface_class_vector_type custom_interface_classes;
+    // Pointers to extra class init functions.
+    Class::class_init_funcs_type custom_class_init_functions;
+    // Pointer to the instance init function.
+    GInstanceInitFunc custom_instance_init_function = nullptr;
+  };
+
+  using extra_object_base_data_type = std::map<const ObjectBase*, ExtraObjectBaseData>;
+  static extra_object_base_data_type extra_object_base_data;
+  // ObjectBase instances may be used in different threads.
+  // Accesses to extra_object_base_data must be thread-safe.
+  static std::mutex extra_object_base_data_mutex;
+#endif // DOXYGEN_SHOULD_SKIP_THIS
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
   friend class Glib::GSigConnectionNode; // for GSigConnectionNode::notify()
-#endif // DOXYGEN_SHOULD_SKIP_THIS
+#endif
 };
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -282,18 +310,9 @@ ObjectBase::get_property(const Glib::ustring& property_name, PropertyType& value
   value = property_value.get();
 }
 
-template <class PropertyType>
-inline PropertyType
-ObjectBase::get_property(const Glib::ustring& property_name) const
-{
-  PropertyType value;
-  get_property(property_name, value);
-
-  return value;
-}
-
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
+GLIBMM_API
 bool _gobject_cppinstance_already_deleted(GObject* gobject);
 
 } // namespace Glib
index 0446907..db36446 100644 (file)
@@ -33,7 +33,7 @@ namespace Glib
  * @{
  */
 
-class PatternSpec
+class GLIBMM_API PatternSpec
 {
 public:
   explicit PatternSpec(const Glib::ustring& pattern);
index 56dad84..a2624e5 100644 (file)
@@ -98,7 +98,7 @@ void destroy_notify_obj_custom_props(void* data)
   auto obj_custom_props = static_cast<custom_properties_type*>(data);
   // prop_base_vector does not own the objects pointed to.
   // prop_value_map owns the objects pointed to.
-  auto map_end = obj_custom_props->prop_value_map.end();
+  const auto map_end = obj_custom_props->prop_value_map.end();
   for (auto it = obj_custom_props->prop_value_map.begin(); it != map_end; ++it)
   {
     g_value_unset(it->second);
index 35e074c..a7fa676 100644 (file)
@@ -32,9 +32,11 @@ namespace Glib
 extern "C" {
 #endif // GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
 
+GLIBMM_API
 void custom_get_property_callback(
   GObject* object, unsigned int property_id, GValue* value, GParamSpec* param_spec);
 
+GLIBMM_API
 void custom_set_property_callback(
   GObject* object, unsigned int property_id, const GValue* value, GParamSpec* param_spec);
 
@@ -49,7 +51,7 @@ void custom_set_property_callback(
  * This class manages the generic parts of the object properties.
  * Derived (templated) classes handle the specific value types.
  */
-class PropertyBase
+class GLIBMM_API PropertyBase
 {
 public:
   // noncopyable
@@ -131,9 +133,9 @@ private:
  *
  * This %Property class currently supports the name, nick name, description, default value and flags.
  * The minimum and maximum bounds are set to the full range of the value.
- * Because of internal implementation, flags shouldn't be set to values: Glib::ParamFlags::STATIC_NAME,
- * Glib::ParamFlags::STATIC_NICK, Glib::ParamFlags::STATIC_BLURB, Glib::ParamFlags::CONSTRUCT and
- * Glib::ParamFlags::CONSTRUCT_ONLY.
+ * Because of internal implementation, flags shouldn't be set to values: Glib::PARAM_STATIC_NAME,
+ * Glib::PARAM_STATIC_NICK, Glib::PARAM_STATIC_BLURB, Glib::PARAM_CONSTRUCT and
+ * Glib::PARAM_CONSTRUCT_ONLY.
  *
  * The class information must be installed into the GObject system once per
  * property, but this is handled automatically.
@@ -284,6 +286,11 @@ public:
    */
   inline operator PropertyType() const;
 
+  //TODO: Remove the non-const get_proxy() when we can break ABI.
+  /** Returns a proxy object that can be used to read this property.
+   */
+  inline Glib::PropertyProxy_ReadOnly<T> get_proxy();
+
   /** Returns a proxy object that can be used to read this property.
    */
   inline Glib::PropertyProxy_ReadOnly<T> get_proxy() const;
@@ -344,7 +351,7 @@ public:
 
 template <class T>
 Property<T>::Property(Glib::Object& object, const Glib::ustring& name)
-: Property(object, name, Glib::ustring(), Glib::ustring(), Glib::ParamFlags::READWRITE)
+: Property(object, name, Glib::ustring(), Glib::ustring(), Glib::PARAM_READWRITE)
 {
 }
 
@@ -352,7 +359,7 @@ template <class T>
 Property<T>::Property(Glib::Object& object, const Glib::ustring& name,
   const typename Property<T>::PropertyType& default_value)
 : Property(object, name, default_value, Glib::ustring(),
-    Glib::ustring(), Glib::ParamFlags::READWRITE)
+    Glib::ustring(), Glib::PARAM_READWRITE)
 {
 }
 
@@ -361,7 +368,7 @@ Property<T>::Property(Glib::Object& object, const Glib::ustring& name,
            const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags)
 : PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::READWRITE;
+  flags |= Glib::PARAM_READWRITE;
 
   if (!lookup_property(name))
     install_property(static_cast<ValueType&>(value_).create_param_spec(name, nick, blurb, flags));
@@ -373,7 +380,7 @@ Property<T>::Property(Glib::Object& object, const Glib::ustring& name, const Pro
 :
   PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::READWRITE;
+  flags |= Glib::PARAM_READWRITE;
 
   static_cast<ValueType&>(value_).set(default_value);
 
@@ -429,7 +436,7 @@ Property<T>::get_proxy() const
 
 template <class T>
 Property_ReadOnly<T>::Property_ReadOnly(Glib::Object& object, const Glib::ustring& name)
-: Property_ReadOnly(object, name, Glib::ustring(), Glib::ustring(), Glib::ParamFlags::READABLE)
+: Property_ReadOnly(object, name, Glib::ustring(), Glib::ustring(), Glib::PARAM_READABLE)
 {
 }
 
@@ -437,7 +444,7 @@ template <class T>
 Property_ReadOnly<T>::Property_ReadOnly(Glib::Object& object, const Glib::ustring& name,
   const typename Property_ReadOnly<T>::PropertyType& default_value)
 : Property_ReadOnly(object, name, default_value, Glib::ustring(), Glib::ustring(),
-    Glib::ParamFlags::READABLE)
+    Glib::PARAM_READABLE)
 {
 }
 
@@ -446,8 +453,8 @@ Property_ReadOnly<T>::Property_ReadOnly(Glib::Object& object, const Glib::ustrin
            const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags)
 : PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::READABLE;
-  flags &= ~Glib::ParamFlags::WRITABLE;
+  flags |= Glib::PARAM_READABLE;
+  flags &= ~Glib::PARAM_WRITABLE;
 
   if (!lookup_property(name))
     install_property(static_cast<ValueType&>(value_).create_param_spec(name, nick, blurb, flags));
@@ -458,8 +465,8 @@ Property_ReadOnly<T>::Property_ReadOnly(Glib::Object& object, const Glib::ustrin
            const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags)
 : PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::READABLE;
-  flags &= ~Glib::ParamFlags::WRITABLE;
+  flags |= Glib::PARAM_READABLE;
+  flags &= ~Glib::PARAM_WRITABLE;
 
   static_cast<ValueType&>(value_).set(default_value);
 
@@ -482,6 +489,13 @@ inline Property_ReadOnly<T>::operator T() const
 
 template <class T>
 inline Glib::PropertyProxy_ReadOnly<T>
+Property_ReadOnly<T>::get_proxy()
+{
+  return Glib::PropertyProxy_ReadOnly<T>(object_, get_name_internal());
+}
+
+template <class T>
+inline Glib::PropertyProxy_ReadOnly<T>
 Property_ReadOnly<T>::get_proxy() const
 {
   return Glib::PropertyProxy_ReadOnly<T>(object_, get_name_internal());
@@ -492,7 +506,7 @@ Property_ReadOnly<T>::get_proxy() const
 template <class T>
 Property_WriteOnly<T>::Property_WriteOnly(Glib::Object& object, const Glib::ustring& name)
 : Property_WriteOnly(object, name, Glib::ustring(),
-    Glib::ustring(), Glib::ParamFlags::WRITABLE)
+    Glib::ustring(), Glib::PARAM_WRITABLE)
 {
 }
 
@@ -500,7 +514,7 @@ template <class T>
 Property_WriteOnly<T>::Property_WriteOnly(Glib::Object& object, const Glib::ustring& name,
   const typename Property_WriteOnly<T>::PropertyType& default_value)
 : Property_WriteOnly(object, name, default_value, Glib::ustring(),
-    Glib::ustring(), Glib::ParamFlags::WRITABLE)
+    Glib::ustring(), Glib::PARAM_WRITABLE)
 {
 }
 
@@ -509,8 +523,8 @@ Property_WriteOnly<T>::Property_WriteOnly(Glib::Object& object, const Glib::ustr
            const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags)
 : PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::WRITABLE;
-  flags &= ~Glib::ParamFlags::READABLE;
+  flags |= Glib::PARAM_WRITABLE;
+  flags &= ~Glib::PARAM_READABLE;
 
   if (!lookup_property(name))
     install_property(static_cast<ValueType&>(value_).create_param_spec(name, nick, blurb, flags));
@@ -522,8 +536,8 @@ Property_WriteOnly<T>::Property_WriteOnly(Glib::Object& object, const Glib::ustr
            const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags)
 : PropertyBase(object, ValueType::value_type())
 {
-  flags |= Glib::ParamFlags::WRITABLE;
-  flags &= ~Glib::ParamFlags::READABLE;
+  flags |= Glib::PARAM_WRITABLE;
+  flags &= ~Glib::PARAM_READABLE;
 
   static_cast<ValueType&>(value_).set(default_value);
 
index d473c63..21f01fe 100644 (file)
@@ -57,7 +57,7 @@ void PropertyProxyConnectionNode::callback(GObject*, GParamSpec* pspec, gpointer
   if (pspec && data)
   {
     if (sigc::slot_base* const slot = SignalProxyBase::data_to_slot(data))
-      (*static_cast<sigc::slot<void()>*>(slot))();
+      (*static_cast<sigc::slot<void>*>(slot))();
   }
 }
 
index 1e84070..ef5cbfb 100644 (file)
 namespace Glib
 {
 
-class ObjectBase;
+class GLIBMM_API ObjectBase;
 
 /// Use the connect() method, with sigc::ptr_fun() or sigc::mem_fun() to connect signals to signal
 /// handlers.
-class SignalProxyProperty : public SignalProxyBase
+class GLIBMM_API SignalProxyProperty : public SignalProxyBase
 {
 public:
   friend class PropertyProxy_Base;
@@ -38,7 +38,7 @@ public:
   SignalProxyProperty(Glib::ObjectBase* obj, const gchar* property_name);
   ~SignalProxyProperty() noexcept;
 
-  using SlotType = sigc::slot<void()>;
+  using SlotType = sigc::slot<void>;
   sigc::connection connect(const SlotType& slot);
   /** @newin{2,48}
    */
@@ -51,7 +51,7 @@ private:
   SignalProxyProperty& operator=(const SignalProxyProperty&); // not implemented
 };
 
-class PropertyProxy_Base
+class GLIBMM_API PropertyProxy_Base
 {
 public:
   PropertyProxy_Base(ObjectBase* obj, const char* property_name);
@@ -79,13 +79,13 @@ private:
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-class SignalProxyProperty;
+class GLIBMM_API SignalProxyProperty;
 
 /** PropertyProxyConnectionNode is a connection node for use with SignalProxyProperty.
   * It's like SignalProxyConnectionNode, but it contains the property name too.
   * This is not public API.
   */
-class PropertyProxyConnectionNode : public SignalProxyConnectionNode
+class GLIBMM_API PropertyProxyConnectionNode : public SignalProxyConnectionNode
 {
 public:
   friend class SignalProxyProperty;
index b860e74..bf83959 100644 (file)
@@ -39,7 +39,7 @@ namespace Glib
  *   void set_data (const Quark&, void * data);
  *   void* get_data (const QueryQuark&);
  */
-class QueryQuark
+class GLIBMM_API QueryQuark
 {
 public:
   QueryQuark(const GQuark& q);
@@ -56,7 +56,7 @@ private:
   GQuark quark_;
 };
 
-class Quark : public QueryQuark
+class GLIBMM_API Quark : public QueryQuark
 {
 public:
   Quark(const ustring& s);
index 3b9893e..83d2caa 100644 (file)
@@ -33,7 +33,7 @@ namespace Glib
  * @{
  */
 
-class Rand
+class GLIBMM_API Rand
 {
 public:
   Rand();
index c77b21d..74ed041 100644 (file)
 
 #include <glibmmconfig.h>
 #include <glib.h>
-#include <memory>
+#include <utility>
 
 namespace Glib
 {
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-template <class T_CppObject>
-void RefPtrDeleter(T_CppObject* object)
-{
-  if (!object)
-    return;
-
-  object->unreference();
-}
-#endif // DOXYGEN_SHOULD_SKIP_THIS
-
 /** RefPtr<> is a reference-counting shared smartpointer.
  *
  * Some objects in gtkmm are obtained from a shared
  * store. Consequently you cannot instantiate them yourself. Instead they
  * return a RefPtr which behaves much like an ordinary pointer in that members
  * can be reached with the usual <code>object_ptr->member</code> notation.
+ * Unlike most other smart pointers, RefPtr doesn't support dereferencing
+ * through <code>*object_ptr</code>.
  *
  * Reference counting means that a shared reference count is incremented each
  * time a RefPtr is copied, and decremented each time a RefPtr is destroyed,
@@ -48,41 +39,481 @@ void RefPtrDeleter(T_CppObject* object)
  * zero, the contained object is deleted, meaning  you don't need to remember
  * to delete the object.
  *
+ * RefPtr<> can store any class that has reference() and unreference() methods,
+ * and whose destructor is noexcept (the default for destructors).
+ * In gtkmm, that is anything derived from Glib::ObjectBase, such as
+ * Gdk::Pixbuf.
+ *
  * See the "Memory Management" section in the "Programming with gtkmm"
  * book for further information.
  */
 template <class T_CppObject>
-using RefPtr = std::shared_ptr<T_CppObject>;
+class RefPtr
+{
+private:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  /** Helper class for disallowing use of Glib::RefPtr with certain classes.
+   *
+   * Disallow for instance in Gtk::Widget and its subclasses.
+   * Glib::RefPtr<T>::is_allowed_type::value is false if
+   * T:dont_allow_use_in_glib_refptr_ is a public type, else it's true.
+   * Example:
+   * @code
+   * using dont_allow_use_in_glib_refptr_ = int;
+   * @endcode
+   */
+  class is_allowed_type
+  {
+  private:
+    struct big
+    {
+      int memory[64];
+    };
 
-/* This would not be useful,
- * because application code should not new these objects anyway.
- * And it is not useful inside glibmm or gtkmm code because
- * the constructors are protected, so can't be called from this utilility
- * function.
- *
-template <class T_CppObject, class... T_Arg>
-RefPtr<T_CppObject>
-make_refptr(T_Arg... arg)
+    static big check(...);
+
+    // If X::dont_allow_use_in_glib_refptr_ is not a type, this check() overload
+    // is ignored because of the SFINAE rule (Substitution Failure Is Not An Error).
+    template <typename X>
+    static typename X::dont_allow_use_in_glib_refptr_ check(X* obj);
+
+  public:
+    static const bool value = sizeof(check(static_cast<T_CppObject*>(nullptr))) == sizeof(big);
+  };
+
+  static_assert(is_allowed_type::value, "Glib::RefPtr must not be used with this class.");
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+public:
+  /** Default constructor
+   *
+   * Afterwards it will be null and use of -> will invoke undefined behaviour.
+   */
+  inline RefPtr() noexcept;
+
+  /// Destructor - decrements reference count.
+  inline ~RefPtr() noexcept;
+
+  /// For use only by the \::create() methods.
+  explicit inline RefPtr(T_CppObject* pCppObject) noexcept;
+
+  /** Copy constructor
+   *
+   * This increments the shared reference count.
+   */
+  inline RefPtr(const RefPtr& src) noexcept;
+
+  /** Move constructor
+   */
+  inline RefPtr(RefPtr&& src) noexcept;
+
+  /** Move constructor (from different, but castable type).
+   */
+  template <class T_CastFrom>
+  inline RefPtr(RefPtr<T_CastFrom>&& src) noexcept;
+
+  /** Copy constructor (from different, but castable type).
+   *
+   * Increments the reference count.
+   */
+  template <class T_CastFrom>
+  inline RefPtr(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /** Swap the contents of two RefPtr<>.
+   * This method swaps the internal pointers to T_CppObject.  This can be
+   * done safely without involving a reference/unreference cycle and is
+   * therefore highly efficient.
+   */
+  inline void swap(RefPtr& other) noexcept;
+
+  /// Copy from another RefPtr:
+  inline RefPtr& operator=(const RefPtr& src) noexcept;
+
+  /// Move assignment operator:
+  inline RefPtr& operator=(RefPtr&& src) noexcept;
+
+  /// Move assignment operator (from different, but castable type):
+  template <class T_CastFrom>
+  inline RefPtr& operator=(RefPtr<T_CastFrom>&& src) noexcept;
+
+  /** Copy from different, but castable type.
+   *
+   * Increments the reference count.
+   */
+  template <class T_CastFrom>
+  inline RefPtr& operator=(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /// Tests whether the RefPtr<> point to the same underlying instance.
+  inline bool operator==(const RefPtr& src) const noexcept;
+
+  /// See operator==().
+  inline bool operator!=(const RefPtr& src) const noexcept;
+
+  /** Dereferencing.
+   *
+   * Use the methods of the underlying instance like so:
+   * <code>refptr->memberfun()</code>.
+   */
+  inline T_CppObject* operator->() const noexcept;
+
+  /** Returns the stored pointer.
+   *
+   * @newin{2,56}
+   */
+  inline T_CppObject* get() const noexcept;
+
+  /** Test whether the RefPtr<> points to any underlying instance.
+   *
+   * Mimics usage of ordinary pointers:
+   * @code
+   *   if (ptr)
+   *     do_something();
+   * @endcode
+   */
+  inline explicit operator bool() const noexcept;
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+  /// @deprecated Use reset() instead because this leads to confusion with clear() methods on the
+  /// underlying class. For instance, people use .clear() when they mean ->clear().
+  inline void clear() noexcept;
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+  /** Set underlying instance to nullptr, decrementing reference count of existing instance
+   * appropriately.
+   * @newin{2,16}
+   */
+  inline void reset() noexcept;
+
+  /** Release the ownership of underlying instance.
+   *
+   * RefPtr's underlying instance is set to nullptr, therefore underlying object can't be accessed
+   * through this RefPtr anymore.
+   * @return an underlying instance.
+   *
+   * Most users should not use release(). It can spoil the automatic destruction
+   * of the managed object. A legitimate use is if you immediately give RefPtr's
+   * reference to another object.
+   */
+  inline T_CppObject* release() noexcept G_GNUC_WARN_UNUSED_RESULT;
+
+  /** Dynamic cast to derived class.
+   *
+   * The RefPtr can't be cast with the usual notation so instead you can use
+   * @code
+   *   ptr_derived = RefPtr<Derived>::cast_dynamic(ptr_base);
+   * @endcode
+   */
+  template <class T_CastFrom>
+  static inline RefPtr cast_dynamic(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /** Static cast to derived class.
+   *
+   * Like the dynamic cast; the notation is
+   * @code
+   *   ptr_derived = RefPtr<Derived>::cast_static(ptr_base);
+   * @endcode
+   */
+  template <class T_CastFrom>
+  static inline RefPtr cast_static(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /** Cast to non-const.
+   *
+   * The RefPtr can't be cast with the usual notation so instead you can use
+   * @code
+   *   ptr_unconst = RefPtr<UnConstType>::cast_const(ptr_const);
+   * @endcode
+   */
+  template <class T_CastFrom>
+  static inline RefPtr cast_const(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /** Compare based on the underlying instance address.
+   *
+   * This is needed in code that requires an ordering on
+   * RefPtr<T_CppObject> instances, e.g. std::set<RefPtr<T_CppObject> >.
+   *
+   * Without these, comparing two RefPtr<T_CppObject> instances
+   * is still syntactically possible, but the result is semantically
+   * wrong, as p1 REL_OP p2 is interpreted as (bool)p1 REL_OP (bool)p2.
+   */
+  inline bool operator<(const RefPtr& src) const noexcept;
+
+  /// See operator<().
+  inline bool operator<=(const RefPtr& src) const noexcept;
+
+  /// See operator<().
+  inline bool operator>(const RefPtr& src) const noexcept;
+
+  /// See operator<().
+  inline bool operator>=(const RefPtr& src) const noexcept;
+
+private:
+  T_CppObject* pCppObject_;
+};
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+// RefPtr<>::operator->() comes first here since it's used by other methods.
+// If it would come after them it wouldn't be inlined.
+
+template <class T_CppObject>
+inline T_CppObject* RefPtr<T_CppObject>::operator->() const noexcept
 {
-  return RefPtr<T_CppObject>(new T_CppObject(arg...));
+  return pCppObject_;
 }
-*/
 
-/** Create a RefPtr<> to an instance of any class that has reference() and
- * unreference() methods, and whose destructor is noexcept (the default for destructors).
- *
- * In gtkmm, that is anything derived from Glib::ObjectBase, such as
- * Gdk::Pixbuf.
- *
- * Normal application code should not need to use this. However, this is necessary
- * when implementing create() methods for derived Glib::ObjectBase-derived
- * (not Gtk::Widget-derived) classes, such as derived Gtk::TreeModels.
- */
 template <class T_CppObject>
-RefPtr<T_CppObject>
-make_refptr_for_instance(T_CppObject* object)
+inline RefPtr<T_CppObject>::RefPtr() noexcept : pCppObject_(nullptr)
+{
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>::~RefPtr() noexcept
+{
+  if (pCppObject_)
+    pCppObject_->unreference(); // This could cause pCppObject to be deleted.
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>::RefPtr(T_CppObject* pCppObject) noexcept : pCppObject_(pCppObject)
+{
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>::RefPtr(const RefPtr& src) noexcept : pCppObject_(src.pCppObject_)
+{
+  if (pCppObject_)
+    pCppObject_->reference();
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>::RefPtr(RefPtr&& src) noexcept : pCppObject_(src.pCppObject_)
+{
+  src.pCppObject_ = nullptr;
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>::RefPtr(RefPtr<T_CastFrom>&& src) noexcept : pCppObject_(src.release())
+{
+}
+
+// The templated ctor allows copy construction from any object that's
+// castable.  Thus, it does downcasts:
+//   base_ref = derived_ref
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src) noexcept :
+  // A different RefPtr<> will not allow us access to pCppObject_.  We need
+  // to add a get_underlying() for this, but that would encourage incorrect
+  // use, so we use the less well-known operator->() accessor:
+  pCppObject_(src.operator->())
+{
+  if (pCppObject_)
+    pCppObject_->reference();
+}
+
+template <class T_CppObject>
+inline void
+RefPtr<T_CppObject>::swap(RefPtr& other) noexcept
+{
+  T_CppObject* const temp = pCppObject_;
+  pCppObject_ = other.pCppObject_;
+  other.pCppObject_ = temp;
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>&
+RefPtr<T_CppObject>::operator=(const RefPtr& src) noexcept
+{
+  // In case you haven't seen the swap() technique to implement copy
+  // assignment before, here's what it does:
+  //
+  // 1) Create a temporary RefPtr<> instance via the copy ctor, thereby
+  //    increasing the reference count of the source object.
+  //
+  // 2) Swap the internal object pointers of *this and the temporary
+  //    RefPtr<>.  After this step, *this already contains the new pointer,
+  //    and the old pointer is now managed by temp.
+  //
+  // 3) The destructor of temp is executed, thereby unreferencing the
+  //    old object pointer.
+  //
+  // This technique is described in Herb Sutter's "Exceptional C++", and
+  // has a number of advantages over conventional approaches:
+  //
+  // - Code reuse by calling the copy ctor.
+  // - Strong exception safety for free.
+  // - Self assignment is handled implicitely.
+  // - Simplicity.
+  // - It just works and is hard to get wrong; i.e. you can use it without
+  //   even thinking about it to implement copy assignment whereever the
+  //   object data is managed indirectly via a pointer, which is very common.
+
+  RefPtr<T_CppObject> temp(src);
+  this->swap(temp);
+  return *this;
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>&
+RefPtr<T_CppObject>::operator=(RefPtr&& src) noexcept
+{
+  RefPtr<T_CppObject> temp(std::move(src));
+  this->swap(temp);
+  src.pCppObject_ = nullptr;
+
+  return *this;
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>&
+RefPtr<T_CppObject>::operator=(RefPtr<T_CastFrom>&& src) noexcept
+{
+  if (pCppObject_)
+    pCppObject_->unreference();
+  pCppObject_ = src.release();
+
+  return *this;
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>&
+RefPtr<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src) noexcept
+{
+  RefPtr<T_CppObject> temp(src);
+  this->swap(temp);
+  return *this;
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator==(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ == src.pCppObject_);
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator!=(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ != src.pCppObject_);
+}
+
+template <class T_CppObject>
+inline T_CppObject* RefPtr<T_CppObject>::get() const noexcept
+{
+  return pCppObject_;
+}
+
+template <class T_CppObject>
+inline RefPtr<T_CppObject>::operator bool() const noexcept
+{
+  return (pCppObject_ != nullptr);
+}
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+template <class T_CppObject>
+inline void
+RefPtr<T_CppObject>::clear() noexcept
+{
+  reset();
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+template <class T_CppObject>
+inline void
+RefPtr<T_CppObject>::reset() noexcept
+{
+  RefPtr<T_CppObject> temp; // swap with an empty RefPtr<> to clear *this
+  this->swap(temp);
+}
+
+template <class T_CppObject>
+inline T_CppObject*
+RefPtr<T_CppObject>::release() noexcept
+{
+  T_CppObject* tmp = pCppObject_;
+  pCppObject_ = nullptr;
+  return tmp;
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>
+RefPtr<T_CppObject>::cast_dynamic(const RefPtr<T_CastFrom>& src) noexcept
+{
+  T_CppObject* const pCppObject = dynamic_cast<T_CppObject*>(src.operator->());
+
+  if (pCppObject)
+    pCppObject->reference();
+
+  return RefPtr<T_CppObject>(pCppObject);
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>
+RefPtr<T_CppObject>::cast_static(const RefPtr<T_CastFrom>& src) noexcept
+{
+  T_CppObject* const pCppObject = static_cast<T_CppObject*>(src.operator->());
+
+  if (pCppObject)
+    pCppObject->reference();
+
+  return RefPtr<T_CppObject>(pCppObject);
+}
+
+template <class T_CppObject>
+template <class T_CastFrom>
+inline RefPtr<T_CppObject>
+RefPtr<T_CppObject>::cast_const(const RefPtr<T_CastFrom>& src) noexcept
+{
+  T_CppObject* const pCppObject = const_cast<T_CppObject*>(src.operator->());
+
+  if (pCppObject)
+    pCppObject->reference();
+
+  return RefPtr<T_CppObject>(pCppObject);
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator<(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ < src.pCppObject_);
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator<=(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ <= src.pCppObject_);
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator>(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ > src.pCppObject_);
+}
+
+template <class T_CppObject>
+inline bool
+RefPtr<T_CppObject>::operator>=(const RefPtr& src) const noexcept
+{
+  return (pCppObject_ >= src.pCppObject_);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+/** @relates Glib::RefPtr */
+template <class T_CppObject>
+inline void
+swap(RefPtr<T_CppObject>& lhs, RefPtr<T_CppObject>& rhs) noexcept
 {
-  return RefPtr<T_CppObject>(object, &RefPtrDeleter<T_CppObject>);
+  lhs.swap(rhs);
 }
 
 } // namespace Glib
similarity index 76%
rename from gio/src/filedescriptorbased.ccg
rename to glib/glibmm/sarray.cc
index 84882c1..69958a7 100644 (file)
@@ -1,4 +1,6 @@
-/* Copyright (C) 2017 The giomm Development Team
+/* sarray.cc
+ *
+ * Copyright (C) 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
@@ -11,8 +13,7 @@
  * 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 <http://www.gnu.org/licenses/>.
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <gio/gio.h>
-#include <gio/gfiledescriptorbased.h>
+#include <glibmm/sarray.h>
similarity index 54%
rename from gio/src/propertyaction.ccg
rename to glib/glibmm/sarray.h
index 85da4a8..dbd0b5c 100644 (file)
@@ -1,4 +1,9 @@
-/* Copyright (C) 2017 The giomm Development Team
+#ifndef _GLIBMM_SARRAY_H
+#define _GLIBMM_SARRAY_H
+
+/* array.h
+ *
+ * Copyright (C) 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
  * 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 <http://www.gnu.org/licenses/>.
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <gio/gio.h>
+#include <glibmmconfig.h>
 
-namespace Gio
-{
+#ifndef GLIBMM_DISABLE_DEPRECATED
+#include <glibmm/arrayhandle.h>
+#include <glibmm/ustring.h>
 
-PropertyAction::PropertyAction(const Glib::ustring& name,
-  const Glib::PropertyProxy_Base& property_proxy, bool invert_boolean)
-:
-_CONSTRUCT("name", name.c_str(), "object", property_proxy.get_object()->gobj(),
-           "property-name",  property_proxy.get_name(),
-           "invert-boolean", invert_boolean)
+namespace Glib
 {
+
+/**
+ * @deprecated Use a std::vector instead.
+ */
+using SArray = Glib::ArrayHandle<Glib::ustring>;
 }
 
-} // namespace Gio
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+#endif // _GLIBMM_SARRAY_H
index c36d713..04ab68d 100644 (file)
@@ -42,7 +42,19 @@ SignalProxyNormal::~SignalProxyNormal() noexcept
 }
 
 sigc::slot_base&
-SignalProxyNormal::connect_impl_(bool notify, const sigc::slot_base& slot, bool after)
+SignalProxyNormal::connect_(const sigc::slot_base& slot, bool after)
+{
+  return connect_impl_(info_->callback, slot, after);
+}
+
+sigc::slot_base&
+SignalProxyNormal::connect_notify_(const sigc::slot_base& slot, bool after)
+{
+  return connect_impl_(info_->notify_callback, slot, after);
+}
+
+sigc::slot_base&
+SignalProxyNormal::connect_impl_(GCallback callback, const sigc::slot_base& slot, bool after)
 {
   // create a proxy to hold our connection info
   auto pConnectionNode = new SignalProxyConnectionNode(slot, obj_->gobj());
@@ -50,9 +62,8 @@ SignalProxyNormal::connect_impl_(bool notify, const sigc::slot_base& slot, bool
   // connect it to glib
   // pConnectionNode will be passed in the data argument to the callback.
   pConnectionNode->connection_id_ = g_signal_connect_data(obj_->gobj(), info_->signal_name,
-    notify ? info_->notify_callback : info_->callback, pConnectionNode,
-    &SignalProxyConnectionNode::destroy_notify_handler,
-    static_cast<GConnectFlags>(after ? G_CONNECT_AFTER : 0));
+    callback, pConnectionNode, &SignalProxyConnectionNode::destroy_notify_handler,
+    static_cast<GConnectFlags>((after) ? G_CONNECT_AFTER : 0));
 
   return pConnectionNode->slot_;
 }
@@ -89,7 +100,7 @@ SignalProxyNormal::slot0_void_callback(GObject* self, void* data)
     try
     {
       if (sigc::slot_base* const slot = data_to_slot(data))
-        (*static_cast<sigc::slot<void()>*>(slot))();
+        (*static_cast<sigc::slot<void>*>(slot))();
     }
     catch (...)
     {
@@ -98,9 +109,9 @@ SignalProxyNormal::slot0_void_callback(GObject* self, void* data)
   }
 }
 
-// SignalProxyDetailedBase implementation:
+// SignalProxyDetailed implementation:
 
-SignalProxyDetailedBase::SignalProxyDetailedBase(
+SignalProxyDetailed::SignalProxyDetailed(
   Glib::ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& detail_name)
 : SignalProxyBase(obj),
   info_(info),
@@ -109,12 +120,12 @@ SignalProxyDetailedBase::SignalProxyDetailedBase(
 {
 }
 
-SignalProxyDetailedBase::~SignalProxyDetailedBase() noexcept
+SignalProxyDetailed::~SignalProxyDetailed() noexcept
 {
 }
 
 sigc::slot_base&
-SignalProxyDetailedBase::connect_impl_(bool notify, const sigc::slot_base& slot, bool after)
+SignalProxyDetailed::connect_impl_(bool notify, const sigc::slot_base& slot, bool after)
 {
   // create a proxy to hold our connection info
   auto pConnectionNode = new SignalProxyConnectionNode(slot, obj_->gobj());
@@ -130,7 +141,7 @@ SignalProxyDetailedBase::connect_impl_(bool notify, const sigc::slot_base& slot,
 }
 
 sigc::slot_base&
-SignalProxyDetailedBase::connect_impl_(bool notify, sigc::slot_base&& slot, bool after)
+SignalProxyDetailed::connect_impl_(bool notify, sigc::slot_base&& slot, bool after)
 {
   // create a proxy to hold our connection info
   auto pConnectionNode = new SignalProxyConnectionNode(std::move(slot), obj_->gobj());
@@ -146,7 +157,7 @@ SignalProxyDetailedBase::connect_impl_(bool notify, sigc::slot_base&& slot, bool
 }
 
 void
-SignalProxyDetailedBase::emission_stop()
+SignalProxyDetailed::emission_stop()
 {
   g_signal_stop_emission_by_name(obj_->gobj(), detailed_name_.c_str());
 }
index 8641d24..93781b1 100644 (file)
@@ -33,7 +33,7 @@ namespace Glib
 {
 
 // Forward declarations
-class ObjectBase;
+class GLIBMM_API ObjectBase;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
@@ -46,8 +46,8 @@ struct SignalProxyInfo
 
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
-// This base class is used by SignalProxyNormal, SignalProxyDetailedBase and SignalProxyProperty.
-class SignalProxyBase
+// This base class is used by SignalProxyNormal, SignalProxyDetailed and SignalProxyProperty.
+class GLIBMM_API SignalProxyBase
 {
 public:
   SignalProxyBase(Glib::ObjectBase* obj);
@@ -66,7 +66,7 @@ protected:
   ObjectBase* obj_;
 
 private:
-  SignalProxyBase& operator=(const SignalProxyBase&) = delete;
+  SignalProxyBase& operator=(const SignalProxyBase&); // not implemented
 };
 
 // Shared portion of a Signal without detail
@@ -78,9 +78,9 @@ private:
  * the template derivatives, which serve as gatekeepers for the
  * types allowed on a particular signal.
  *
- * For signals with a detailed name (signal_name::detail_name) see SignalProxyDetailedBase.
+ * For signals with a detailed name (signal_name::detail_name) see SignalProxyDetailed.
  */
-class SignalProxyNormal : public SignalProxyBase
+class GLIBMM_API SignalProxyNormal : public SignalProxyBase
 {
 public:
   ~SignalProxyNormal() noexcept;
@@ -89,7 +89,7 @@ public:
   void emission_stop();
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-  // This callback for SignalProxy<void()>
+  // This callback for SignalProxy<void>
   // is defined here to avoid code duplication.
   static void slot0_void_callback(GObject*, void* data);
 #endif
@@ -102,20 +102,28 @@ protected:
    */
   SignalProxyNormal(Glib::ObjectBase* obj, const SignalProxyInfo* info);
 
-  /** Connects a signal handler to a signal.
-   * This is called by connect() and connect_notify() in derived SignalProxy classes.
+  /** Connects a generic signal handler to a signal.
+   * This is called by connect() in derived SignalProxy classes.
    *
-   * @param notify Whether this method is called by connect_notify() or by connect().
    * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
    * @param after Whether this signal handler should be called before or after the default signal
    * handler.
+   */
+  sigc::slot_base& connect_(const sigc::slot_base& slot, bool after);
+
+  /** Connects a signal handler without a return value to a signal.
+   * This is called by connect_notify() in derived SignalProxy classes.
    *
-   * @newin{2,58}
+   * @param slot The signal handler, which should have a @c void return type,
+   *        usually created with sigc::mem_fun() or sigc::ptr_fun().
+   * @param after Whether this signal handler should be called before or after the default signal
+   * handler.
    */
-  sigc::slot_base& connect_impl_(bool notify, const sigc::slot_base& slot, bool after);
+  sigc::slot_base& connect_notify_(const sigc::slot_base& slot, bool after);
 
   /** Connects a signal handler to a signal.
-   * @see connect_impl_(bool notify, const sigc::slot_base& slot, bool after).
+   * @see connect_(const sigc::slot_base& slot, bool after) and
+   * connect_notify_(const sigc::slot_base& slot, bool after).
    *
    * @newin{2,48}
    */
@@ -124,56 +132,42 @@ protected:
 private:
   const SignalProxyInfo* info_;
 
+  // TODO: We could maybe replace both connect_() and connect_notify_() with this in future, because
+  // they don't do anything extra.
+  /** This is called by connect_() and connect_notify_().
+   */
+  sigc::slot_base& connect_impl_(GCallback callback, const sigc::slot_base& slot, bool after);
+
   // no copy assignment
-  SignalProxyNormal& operator=(const SignalProxyNormal&) = delete;
+  SignalProxyNormal& operator=(const SignalProxyNormal&);
 };
 
 /**** Glib::SignalProxy ***************************************************/
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-template <class R, class... T>
-class SignalProxy;
-#endif // DOXYGEN_SHOULD_SKIP_THIS
-
 /** Proxy for signals with any number of arguments.
  * Use the connect() or connect_notify() method, with sigc::mem_fun() or sigc::ptr_fun()
  * to connect signal handlers to signals.
- *
- * This is the primary template. There is a specialization for signal handlers
- * that return @c void. The specialization has no %connect_notify() method, and
- * the @a after parameter in its %connect() method has a default value.
  */
 template <class R, class... T>
-class SignalProxy<R(T...)> : public SignalProxyNormal
+class SignalProxy : public SignalProxyNormal
 {
 public:
-  using SlotType = sigc::slot<R(T...)>;
-  using VoidSlotType = sigc::slot<void(T...)>;
+  using SlotType = sigc::slot<R, T...>;
+  using VoidSlotType = sigc::slot<void, T...>;
 
   SignalProxy(ObjectBase* obj, const SignalProxyInfo* info) : SignalProxyNormal(obj, info) {}
 
   /** Connects a signal handler to a signal.
    *
-   * For instance, connect(sigc::mem_fun(*this, &TheClass::on_something), false);
-   *
-   * For some signal handlers that return a value, it can make a big difference
-   * whether you connect before or after the default signal handler.
-   * Examples:
-   * - Gio::Application::signal_command_line() calls only one signal handler.
-   *   A handler connected after the default handler will never be called.
-   * - X event signals, such as Gtk::Widget::signal_button_press_event(), stop
-   *   calling signal handlers as soon as a called handler returns <tt>true</tt>.
-   *   If the default handler returns <tt>true</tt>, a handler connected after it
-   *   will not be called.
+   * For instance, connect( sigc::mem_fun(*this, &TheClass::on_something) );
    *
    * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
    * @param after Whether this signal handler should be called before or after the default signal
    * handler.
-   * @return A sigc::connection.
    */
-  sigc::connection connect(const SlotType& slot, bool after)
+  sigc::connection connect(const SlotType& slot, bool after = true)
   {
-    return sigc::connection(connect_impl_(false, slot, after));
+    return sigc::connection(connect_(slot, after));
   }
 
   /** Connects a signal handler to a signal.
@@ -181,7 +175,7 @@ public:
    *
    * @newin{2,48}
    */
-  sigc::connection connect(SlotType&& slot, bool after)
+  sigc::connection connect(SlotType&& slot, bool after = true)
   {
     return sigc::connection(connect_impl_(false, std::move(slot), after));
   }
@@ -191,23 +185,27 @@ public:
    *
    * For instance, connect_notify( sigc::mem_fun(*this, &TheClass::on_something) );
    *
+   * If the signal requires signal handlers with a @c void return type,
+   * the only difference between connect() and connect_notify() is the default
+   * value of @a after.
+   *
    * If the signal requires signal handlers with a return value of type T,
-   * %connect_notify() binds <tt>return T()</tt> to the connected signal handler.
+   * connect_notify() binds <tt>return T()</tt> to the connected signal handler.
    * For instance, if the return type is @c bool, the following two calls are equivalent.
    * @code
-   * connect_notify(sigc::mem_fun(*this, &TheClass::on_something));
-   * connect(sigc::bind_return<bool>(sigc::mem_fun(*this, &TheClass::on_something), false), false);
+   * connect_notify( sigc::mem_fun(*this, &TheClass::on_something) );
+   * connect( sigc::bind_return<bool>(sigc::mem_fun(*this, &TheClass::on_something), false), false
+   * );
    * @endcode
    *
    * @param slot The signal handler, which should have a @c void return type,
    *        usually created with sigc::mem_fun() or sigc::ptr_fun().
    * @param after Whether this signal handler should be called before or after the default signal
    * handler.
-   * @return A sigc::connection.
    */
   sigc::connection connect_notify(const VoidSlotType& slot, bool after = false)
   {
-    return sigc::connection(connect_impl_(true, slot, after));
+    return sigc::connection(connect_notify_(slot, after));
   }
 
   /** Connects a signal handler without a return value to a signal.
@@ -221,47 +219,28 @@ public:
   }
 };
 
-/** Proxy for signals with any number of arguments.
- * Use the connect() method, with sigc::mem_fun() or sigc::ptr_fun()
- * to connect signal handlers to signals.
- *
- * This is a specialization for signal handlers that return @c void.
+/* Templates below has been added to avoid API break, and should not be
+ * used in a newly created code. SignalProxy class should be used instead
+ * of SignalProxy# class.
  */
-template <class... T>
-class SignalProxy<void(T...)> : public SignalProxyNormal
-{
-public:
-  using SlotType = sigc::slot<void(T...)>;
-
-  SignalProxy(ObjectBase* obj, const SignalProxyInfo* info) : SignalProxyNormal(obj, info) {}
-
-  /** Connects a signal handler to a signal.
-   *
-   * For instance, connect( sigc::mem_fun(*this, &TheClass::on_something) );
-   *
-   * By default, the signal handler will be called after the default signal handler.
-   * This is usually fine for signal handlers that don't return a value.
-   *
-   * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
-   * @param after Whether this signal handler should be called before or after the default signal
-   * handler.
-   * @return A sigc::connection.
-   */
-  sigc::connection connect(const SlotType& slot, bool after = true)
-  {
-    return sigc::connection(connect_impl_(false, slot, after));
-  }
-
-  /** Connects a signal handler to a signal.
-   * @see connect(const SlotType& slot, bool after).
-   *
-   * @newin{2,48}
-   */
-  sigc::connection connect(SlotType&& slot, bool after = true)
-  {
-    return sigc::connection(connect_impl_(false, std::move(slot), after));
-  }
-};
+template <typename R>
+using SignalProxy0 = SignalProxy<R>;
+template <typename R, typename T1>
+using SignalProxy1 = SignalProxy<R, T1>;
+template <typename R, typename T1, typename T2>
+using SignalProxy2 = SignalProxy<R, T1, T2>;
+template <typename R, typename T1, typename T2, typename T3>
+using SignalProxy3 = SignalProxy<R, T1, T2, T3>;
+template <typename R, typename T1, typename T2, typename T3, typename T4>
+using SignalProxy4 = SignalProxy<R, T1, T2, T3, T4>;
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
+using SignalProxy5 = SignalProxy<R, T1, T2, T3, T4, T5>;
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+using SignalProxy6 = SignalProxy<R, T1, T2, T3, T4, T5, T6>;
+
+// TODO: When we can break ABI, consider renaming
+// SignalProxyDetailed => SignalProxyDetailedBase
+// SignalProxyDetailedAnyType => SignalProxyDetailed
 
 // Shared portion of a Signal with detail
 /** The SignalProxy provides an API similar to sigc::signal that can be used to
@@ -272,10 +251,10 @@ public:
  * the template derivatives, which serve as gatekeepers for the
  * types allowed on a particular signal.
  */
-class SignalProxyDetailedBase : public SignalProxyBase
+class GLIBMM_API SignalProxyDetailed : public SignalProxyBase
 {
 public:
-  ~SignalProxyDetailedBase() noexcept;
+  ~SignalProxyDetailed() noexcept;
 
   /// Stops the current signal emission (not in libsigc++)
   void emission_stop();
@@ -287,11 +266,11 @@ protected:
    *             and the C callbacks that should be called by glib.
    * @param detail_name The detail name, if any.
    */
-  SignalProxyDetailedBase(
+  SignalProxyDetailed(
     Glib::ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& detail_name);
 
   /** Connects a signal handler to a signal.
-   * This is called by connect() and connect_notify() in derived SignalProxyDetailed classes.
+   * This is called by connect() and connect_notify() in derived SignalProxyDetailedAnyType classes.
    *
    * @param notify Whether this method is called by connect_notify() or by connect().
    * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
@@ -312,57 +291,35 @@ private:
   const Glib::ustring detailed_name_; // signal_name[::detail_name]
 
   // no copy assignment
-  SignalProxyDetailedBase& operator=(const SignalProxyDetailedBase&) = delete;
+  SignalProxyDetailed& operator=(const SignalProxyDetailed&);
 };
 
-/**** Glib::SignalProxyDetailed **********************************************/
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-template <class R, class... T>
-class SignalProxyDetailed;
-#endif // DOXYGEN_SHOULD_SKIP_THIS
-
 /** Proxy for signals with any number of arguments and possibly a detailed name.
  * Use the connect() or connect_notify() method, with sigc::mem_fun() or sigc::ptr_fun()
  * to connect signal handlers to signals.
- *
- * This is the primary template. There is a specialization for signal handlers
- * that return @c void. The specialization has no %connect_notify() method, and
- * the @a after parameter in its %connect() method has a default value.
  */
 template <class R, class... T>
-class SignalProxyDetailed<R(T...)> : public SignalProxyDetailedBase
+class SignalProxyDetailedAnyType : public SignalProxyDetailed
 {
 public:
-  using SlotType = sigc::slot<R(T...)>;
-  using VoidSlotType = sigc::slot<void(T...)>;
+  using SlotType = sigc::slot<R, T...>;
+  using VoidSlotType = sigc::slot<void, T...>;
 
-  SignalProxyDetailed(
+  SignalProxyDetailedAnyType(
     ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& detail_name)
-  : SignalProxyDetailedBase(obj, info, detail_name)
+  : SignalProxyDetailed(obj, info, detail_name)
   {
   }
 
   /** Connects a signal handler to a signal.
    *
-   * For instance, connect(sigc::mem_fun(*this, &TheClass::on_something), false);
-   *
-   * For some signal handlers that return a value, it can make a big difference
-   * whether you connect before or after the default signal handler.
-   * Examples:
-   * - Gio::Application::signal_command_line() calls only one signal handler.
-   *   A handler connected after the default handler will never be called.
-   * - X event signals, such as Gtk::Widget::signal_button_press_event(), stop
-   *   calling signal handlers as soon as a called handler returns <tt>true</tt>.
-   *   If the default handler returns <tt>true</tt>, a handler connected after it
-   *   will not be called.
+   * For instance, connect( sigc::mem_fun(*this, &TheClass::on_something) );
    *
    * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
    * @param after Whether this signal handler should be called before or after the default signal
    * handler.
-   * @return A sigc::connection.
    */
-  sigc::connection connect(const SlotType& slot, bool after)
+  sigc::connection connect(const SlotType& slot, bool after = true)
   {
     return sigc::connection(connect_impl_(false, slot, after));
   }
@@ -372,7 +329,7 @@ public:
    *
    * @newin{2,48}
    */
-  sigc::connection connect(SlotType&& slot, bool after)
+  sigc::connection connect(SlotType&& slot, bool after = true)
   {
     return sigc::connection(connect_impl_(false, std::move(slot), after));
   }
@@ -382,19 +339,23 @@ public:
    *
    * For instance, connect_notify( sigc::mem_fun(*this, &TheClass::on_something) );
    *
+   * If the signal requires signal handlers with a @c void return type,
+   * the only difference between connect() and connect_notify() is the default
+   * value of @a after.
+   *
    * If the signal requires signal handlers with a return value of type T,
-   * %connect_notify() binds <tt>return T()</tt> to the connected signal handler.
+   * connect_notify() binds <tt>return T()</tt> to the connected signal handler.
    * For instance, if the return type is @c bool, the following two calls are equivalent.
    * @code
-   * connect_notify(sigc::mem_fun(*this, &TheClass::on_something));
-   * connect(sigc::bind_return<bool>(sigc::mem_fun(*this, &TheClass::on_something), false), false);
+   * connect_notify( sigc::mem_fun(*this, &TheClass::on_something) );
+   * connect( sigc::bind_return<bool>(sigc::mem_fun(*this, &TheClass::on_something), false), false
+   * );
    * @endcode
    *
    * @param slot The signal handler, which should have a @c void return type,
    *        usually created with sigc::mem_fun() or sigc::ptr_fun().
    * @param after Whether this signal handler should be called before or after the default signal
    * handler.
-   * @return A sigc::connection.
    */
   sigc::connection connect_notify(const VoidSlotType& slot, bool after = false)
   {
@@ -412,51 +373,24 @@ public:
   }
 };
 
-/** Proxy for signals with any number of arguments and possibly a detailed name.
- * Use the connect() method, with sigc::mem_fun() or sigc::ptr_fun()
- * to connect signal handlers to signals.
- *
- * This is a specialization for signal handlers that return @c void.
+/* Templates below has been added to avoid API break, and should not be
+ * used in a newly created code. SignalProxyDetailedAnyType class should be
+ * used instead of SignalProxyDetailed# class.
  */
-template <class... T>
-class SignalProxyDetailed<void(T...)> : public SignalProxyDetailedBase
-{
-public:
-  using SlotType = sigc::slot<void(T...)>;
-
-  SignalProxyDetailed(
-    ObjectBase* obj, const SignalProxyInfo* info, const Glib::ustring& detail_name)
-  : SignalProxyDetailedBase(obj, info, detail_name)
-  {
-  }
-
-  /** Connects a signal handler to a signal.
-   *
-   * For instance, connect( sigc::mem_fun(*this, &TheClass::on_something) );
-   *
-   * By default, the signal handler will be called after the default signal handler.
-   * This is usually fine for signal handlers that don't return a value.
-   *
-   * @param slot The signal handler, usually created with sigc::mem_fun() or sigc::ptr_fun().
-   * @param after Whether this signal handler should be called before or after the default signal
-   * handler.
-   * @return A sigc::connection.
-   */
-  sigc::connection connect(const SlotType& slot, bool after = true)
-  {
-    return sigc::connection(connect_impl_(false, slot, after));
-  }
-
-  /** Connects a signal handler to a signal.
-   * @see connect(const SlotType& slot, bool after).
-   *
-   * @newin{2,48}
-   */
-  sigc::connection connect(SlotType&& slot, bool after = true)
-  {
-    return sigc::connection(connect_impl_(false, std::move(slot), after));
-  }
-};
+template <typename R>
+using SignalProxyDetailed0 = SignalProxyDetailedAnyType<R>;
+template <typename R, typename T1>
+using SignalProxyDetailed1 = SignalProxyDetailedAnyType<R, T1>;
+template <typename R, typename T1, typename T2>
+using SignalProxyDetailed2 = SignalProxyDetailedAnyType<R, T1, T2>;
+template <typename R, typename T1, typename T2, typename T3>
+using SignalProxyDetailed3 = SignalProxyDetailedAnyType<R, T1, T2, T3>;
+template <typename R, typename T1, typename T2, typename T3, typename T4>
+using SignalProxyDetailed4 = SignalProxyDetailedAnyType<R, T1, T2, T3, T4>;
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
+using SignalProxyDetailed5 = SignalProxyDetailedAnyType<R, T1, T2, T3, T4, T5>;
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+using SignalProxyDetailed6 = SignalProxyDetailedAnyType<R, T1, T2, T3, T4, T5, T6>;
 
 } // namespace Glib
 
index af50254..2d51630 100644 (file)
@@ -40,8 +40,8 @@ SignalProxyConnectionNode::SignalProxyConnectionNode(sigc::slot_base&& slot, GOb
 // notify is a message coming up from the slot to be passed back to Gtk+
 // disconnect is a message coming up from the Gtk+ to be passed down to SigC++
 // static
-void
-SignalProxyConnectionNode::notify(sigc::notifiable* data)
+void*
+SignalProxyConnectionNode::notify(void* data)
 {
   // notification from libsigc++.
   SignalProxyConnectionNode* conn = static_cast<SignalProxyConnectionNode*>(data);
@@ -72,6 +72,8 @@ SignalProxyConnectionNode::notify(sigc::notifiable* data)
       g_signal_handler_disconnect(o, connection_id);
     }
   }
+
+  return nullptr; // apparently unused in libsigc++
 }
 
 // static
index da82bdf..226b685 100644 (file)
@@ -19,6 +19,8 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glibmmconfig.h>
+
 #include <sigc++/sigc++.h>
 #include <glib.h>
 
@@ -36,7 +38,7 @@ namespace Glib
   * It lives between the layer of Gtk+ and libsigc++.
   * It is very much an internal class.
   */
-class SignalProxyConnectionNode : public sigc::notifiable
+class GLIBMM_API SignalProxyConnectionNode
 {
 public:
   /** @param slot The signal handler for the glib signal.
@@ -55,7 +57,7 @@ public:
    * This callback is registered in the slot.
    * @param data The SignalProxyConnectionNode object (@p this).
    */
-  static void notify(sigc::notifiable* data);
+  static void* notify(void* data);
 
   /** Callback that is executed when the glib closure is destroyed.
    * @param data The SignalProxyConnectionNode object (@p this).
diff --git a/glib/glibmm/slisthandle.h b/glib/glibmm/slisthandle.h
new file mode 100644 (file)
index 0000000..7b95279
--- /dev/null
@@ -0,0 +1,410 @@
+#ifndef _GLIBMM_SLISTHANDLE_H
+#define _GLIBMM_SLISTHANDLE_H
+
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+#include <glibmm/containerhandle_shared.h>
+#include <glib.h>
+
+namespace Glib
+{
+
+namespace Container_Helpers
+{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/* Create and fill a GSList as efficient as possible.
+ * This requires bidirectional iterators.
+ */
+template <class Bi, class Tr>
+GSList*
+create_slist(Bi pbegin, Bi pend, Tr)
+{
+  GSList* head = nullptr;
+
+  while (pend != pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void* const item = Tr::to_c_type(*&*--pend);
+    head = g_slist_prepend(head, const_cast<void*>(item));
+  }
+
+  return head;
+}
+
+/* Create a GSList from a 0-terminated input sequence.
+ * Build it in reverse order and reverse the whole list afterwards,
+ * because appending to the list would be horribly inefficient.
+ */
+template <class For, class Tr>
+GSList*
+create_slist(For pbegin, Tr)
+{
+  GSList* head = nullptr;
+
+  while (*pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void* const item = Tr::to_c_type(*&*pbegin);
+    head = g_slist_prepend(head, const_cast<void*>(item));
+    ++pbegin;
+  }
+
+  return g_slist_reverse(head);
+}
+
+/* Convert from any container that supports bidirectional iterators.
+ */
+template <class Tr, class Cont>
+struct SListSourceTraits
+{
+  static GSList* get_data(const Cont& cont)
+  {
+    return Glib::Container_Helpers::create_slist(cont.begin(), cont.end(), Tr());
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+/* Convert from a 0-terminated array.  The Cont
+ * argument must be a pointer to the first element.
+ */
+template <class Tr, class Cont>
+struct SListSourceTraits<Tr, Cont*>
+{
+  static GSList* get_data(const Cont* array)
+  {
+    return (array) ? Glib::Container_Helpers::create_slist(array, Tr()) : nullptr;
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+template <class Tr, class Cont>
+struct SListSourceTraits<Tr, const Cont*> : SListSourceTraits<Tr, Cont*>
+{
+};
+
+/* Convert from a 0-terminated array.  The Cont argument must be a pointer
+ * to the first element.  For consistency, the array must be 0-terminated,
+ * even though the array size is known at compile time.
+ */
+template <class Tr, class Cont, std::size_t N>
+struct SListSourceTraits<Tr, Cont[N]>
+{
+  static GSList* get_data(const Cont* array)
+  {
+    return Glib::Container_Helpers::create_slist(array, array + (N - 1), Tr());
+  }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
+
+template <class Tr, class Cont, std::size_t N>
+struct SListSourceTraits<Tr, const Cont[N]> : SListSourceTraits<Tr, Cont[N]>
+{
+};
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+/**
+ * @ingroup ContHelpers
+ */
+template <class Tr>
+class SListHandleIterator
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = CppType;
+  using difference_type = std::ptrdiff_t;
+  using reference = value_type;
+  using pointer = void;
+
+  explicit inline SListHandleIterator(const GSList* node);
+
+  inline value_type operator*() const;
+  inline SListHandleIterator<Tr>& operator++();
+  inline const SListHandleIterator<Tr> operator++(int);
+
+  inline bool operator==(const SListHandleIterator<Tr>& rhs) const;
+  inline bool operator!=(const SListHandleIterator<Tr>& rhs) const;
+
+private:
+  const GSList* node_;
+};
+
+} // namespace Container_Helpers
+
+// TODO: Remove this when we can break glibmm API.
+/** This is an intermediate type. When a method takes this, or returns this, you
+ * should use a standard C++ container of your choice, such as std::list or
+ * std::vector.
+ *
+ * However, this is not used in new API. We now prefer to just use std::vector,
+ * which is less flexibile, but makes the API clearer.
+ * @ingroup ContHandles
+ */
+template <class T, class Tr = Glib::Container_Helpers::TypeTraits<T>>
+class SListHandle
+{
+public:
+  using CppType = typename Tr::CppType;
+  using CType = typename Tr::CType;
+
+  using value_type = CppType;
+  using size_type = std::size_t;
+  using difference_type = std::ptrdiff_t;
+
+  using const_iterator = Glib::Container_Helpers::SListHandleIterator<Tr>;
+  using iterator = Glib::Container_Helpers::SListHandleIterator<Tr>;
+
+  template <class Cont>
+  inline SListHandle(const Cont& container);
+
+  // Take over ownership of a GSList created by GTK+ functions.
+  inline SListHandle(GSList* glist, Glib::OwnershipType ownership);
+
+  // Copying clears the ownership flag of the source handle.
+  inline SListHandle(const SListHandle<T, Tr>& other);
+
+  ~SListHandle() noexcept;
+
+  inline const_iterator begin() const;
+  inline const_iterator end() const;
+
+  template <class U>
+  inline operator std::vector<U>() const;
+  template <class U>
+  inline operator std::deque<U>() const;
+  template <class U>
+  inline operator std::list<U>() const;
+
+  template <class Cont>
+  inline void assign_to(Cont& container) const;
+  template <class Out>
+  inline void copy(Out pdest) const;
+
+  inline GSList* data() const;
+  inline std::size_t size() const;
+  inline bool empty() const;
+
+private:
+  GSList* pslist_;
+  mutable Glib::OwnershipType ownership_;
+
+  // No copy assignment.
+  SListHandle<T, Tr>& operator=(const SListHandle<T, Tr>&);
+};
+
+/***************************************************************************/
+/*  Inline implementation                                                  */
+/***************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Container_Helpers
+{
+
+/**** Glib::Container_Helpers::SListHandleIterator<> ***********************/
+
+template <class Tr>
+inline SListHandleIterator<Tr>::SListHandleIterator(const GSList* node) : node_(node)
+{
+}
+
+template <class Tr>
+inline typename SListHandleIterator<Tr>::value_type SListHandleIterator<Tr>::operator*() const
+{
+  return Tr::to_cpp_type(static_cast<typename Tr::CTypeNonConst>(node_->data));
+}
+
+template <class Tr>
+inline SListHandleIterator<Tr>& SListHandleIterator<Tr>::operator++()
+{
+  node_ = node_->next;
+  return *this;
+}
+
+template <class Tr>
+inline const SListHandleIterator<Tr> SListHandleIterator<Tr>::operator++(int)
+{
+  const SListHandleIterator<Tr> tmp(*this);
+  node_ = node_->next;
+  return tmp;
+}
+
+template <class Tr>
+inline bool
+SListHandleIterator<Tr>::operator==(const SListHandleIterator<Tr>& rhs) const
+{
+  return (node_ == rhs.node_);
+}
+
+template <class Tr>
+inline bool
+SListHandleIterator<Tr>::operator!=(const SListHandleIterator<Tr>& rhs) const
+{
+  return (node_ != rhs.node_);
+}
+
+} // namespace Container_Helpers
+
+/**** Glib::SListHandle<> **************************************************/
+
+template <class T, class Tr>
+template <class Cont>
+inline SListHandle<T, Tr>::SListHandle(const Cont& container)
+: pslist_(Glib::Container_Helpers::SListSourceTraits<Tr, Cont>::get_data(container)),
+  ownership_(Glib::Container_Helpers::SListSourceTraits<Tr, Cont>::initial_ownership)
+{
+}
+
+template <class T, class Tr>
+inline SListHandle<T, Tr>::SListHandle(GSList* gslist, Glib::OwnershipType ownership)
+: pslist_(gslist), ownership_(ownership)
+{
+}
+
+template <class T, class Tr>
+inline SListHandle<T, Tr>::SListHandle(const SListHandle<T, Tr>& other)
+: pslist_(other.pslist_), ownership_(other.ownership_)
+{
+  other.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <class T, class Tr>
+SListHandle<T, Tr>::~SListHandle() noexcept
+{
+  if (ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      for (GSList* node = pslist_; node != nullptr; node = node->next)
+        Tr::release_c_type(static_cast<typename Tr::CTypeNonConst>(node->data));
+    }
+    g_slist_free(pslist_);
+  }
+}
+
+template <class T, class Tr>
+inline typename SListHandle<T, Tr>::const_iterator
+SListHandle<T, Tr>::begin() const
+{
+  return Glib::Container_Helpers::SListHandleIterator<Tr>(pslist_);
+}
+
+template <class T, class Tr>
+inline typename SListHandle<T, Tr>::const_iterator
+SListHandle<T, Tr>::end() const
+{
+  return Glib::Container_Helpers::SListHandleIterator<Tr>(nullptr);
+}
+
+template <class T, class Tr>
+template <class U>
+inline SListHandle<T, Tr>::operator std::vector<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::vector<U>(this->begin(), this->end());
+#else
+  std::vector<U> temp;
+  temp.reserve(this->size());
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline SListHandle<T, Tr>::operator std::deque<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::deque<U>(this->begin(), this->end());
+#else
+  std::deque<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class U>
+inline SListHandle<T, Tr>::operator std::list<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::list<U>(this->begin(), this->end());
+#else
+  std::list<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class T, class Tr>
+template <class Cont>
+inline void
+SListHandle<T, Tr>::assign_to(Cont& container) const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  container.assign(this->begin(), this->end());
+#else
+  Cont temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  container.swap(temp);
+#endif
+}
+
+template <class T, class Tr>
+template <class Out>
+inline void
+SListHandle<T, Tr>::copy(Out pdest) const
+{
+  std::copy(this->begin(), this->end(), pdest);
+}
+
+template <class T, class Tr>
+inline GSList*
+SListHandle<T, Tr>::data() const
+{
+  return pslist_;
+}
+
+template <class T, class Tr>
+inline std::size_t
+SListHandle<T, Tr>::size() const
+{
+  return g_slist_length(pslist_);
+}
+
+template <class T, class Tr>
+inline bool
+SListHandle<T, Tr>::empty() const
+{
+  return (pslist_ == nullptr);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+#endif /* _GLIBMM_SLISTHANDLE_H */
diff --git a/glib/glibmm/streamiochannel.cc b/glib/glibmm/streamiochannel.cc
new file mode 100644 (file)
index 0000000..f82a279
--- /dev/null
@@ -0,0 +1,207 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/streamiochannel.h>
+#include <glibmm/main.h> //For Source
+#include <glib.h>
+#include <fstream>
+#include <iostream>
+
+namespace Glib
+{
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+
+// static
+Glib::RefPtr<StreamIOChannel>
+StreamIOChannel::create(std::istream& stream)
+{
+  return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(&stream, nullptr));
+}
+
+// static
+Glib::RefPtr<StreamIOChannel>
+StreamIOChannel::create(std::ostream& stream)
+{
+  return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(nullptr, &stream));
+}
+
+// static
+Glib::RefPtr<StreamIOChannel>
+StreamIOChannel::create(std::iostream& stream)
+{
+  return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(&stream, &stream));
+}
+
+StreamIOChannel::StreamIOChannel(std::istream* stream_in, std::ostream* stream_out)
+: stream_in_(stream_in), stream_out_(stream_out)
+{
+  get_flags_vfunc(); // initialize GIOChannel flag bits
+}
+
+StreamIOChannel::~StreamIOChannel() noexcept
+{
+}
+
+IOStatus
+StreamIOChannel::read_vfunc(char* buf, gsize count, gsize& bytes_read)
+{
+  g_return_val_if_fail(stream_in_ != nullptr, IO_STATUS_ERROR);
+
+  stream_in_->clear();
+  stream_in_->read(buf, count);
+  bytes_read = stream_in_->gcount();
+
+  if (stream_in_->eof())
+    return IO_STATUS_EOF;
+
+  if (stream_in_->fail())
+  {
+    throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Reading from stream failed");
+  }
+
+  return IO_STATUS_NORMAL;
+}
+
+IOStatus
+StreamIOChannel::write_vfunc(const char* buf, gsize count, gsize& bytes_written)
+{
+  g_return_val_if_fail(stream_out_ != nullptr, IO_STATUS_ERROR);
+
+  bytes_written = 0;
+
+  stream_out_->clear();
+  stream_out_->write(buf, count);
+
+  if (stream_out_->fail())
+  {
+    throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Writing to stream failed");
+  }
+
+  bytes_written = count; // all or nothing ;)
+
+  return IO_STATUS_NORMAL;
+}
+
+IOStatus
+StreamIOChannel::seek_vfunc(gint64 offset, SeekType type)
+{
+  std::ios::seekdir direction = std::ios::beg;
+
+  switch (type)
+  {
+  case SEEK_TYPE_SET:
+    direction = std::ios::beg;
+    break;
+  case SEEK_TYPE_CUR:
+    direction = std::ios::cur;
+    break;
+  case SEEK_TYPE_END:
+    direction = std::ios::end;
+    break;
+  }
+
+  bool failed = false;
+
+  if (stream_in_)
+  {
+    stream_in_->clear();
+    stream_in_->seekg(offset, direction);
+    failed = stream_in_->fail();
+  }
+  if (stream_out_)
+  {
+    stream_out_->clear();
+    stream_out_->seekp(offset, direction);
+    failed = (failed || stream_out_->fail());
+  }
+
+  if (failed)
+  {
+    throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Seeking into stream failed");
+  }
+
+  return Glib::IO_STATUS_NORMAL;
+}
+
+IOStatus
+StreamIOChannel::close_vfunc()
+{
+  bool failed = false;
+
+  if (std::fstream* const fstream = dynamic_cast<std::fstream*>(stream_in_))
+  {
+    fstream->clear();
+    fstream->close();
+    failed = fstream->fail();
+  }
+  else if (std::ifstream* const ifstream = dynamic_cast<std::ifstream*>(stream_in_))
+  {
+    ifstream->clear();
+    ifstream->close();
+    failed = ifstream->fail();
+  }
+  else if (std::ofstream* const ofstream = dynamic_cast<std::ofstream*>(stream_out_))
+  {
+    ofstream->clear();
+    ofstream->close();
+    failed = ofstream->fail();
+  }
+  else
+  {
+    throw Glib::Error(
+      G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Attempt to close non-file stream");
+  }
+
+  if (failed)
+  {
+    throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Failed to close stream");
+  }
+
+  return IO_STATUS_NORMAL;
+}
+
+IOStatus StreamIOChannel::set_flags_vfunc(IOFlags)
+{
+  return IO_STATUS_NORMAL;
+}
+
+IOFlags
+StreamIOChannel::get_flags_vfunc()
+{
+  gobj()->is_seekable = 1;
+  gobj()->is_readable = (stream_in_ != nullptr);
+  gobj()->is_writeable = (stream_out_ != nullptr);
+
+  IOFlags flags = IO_FLAG_IS_SEEKABLE;
+
+  if (stream_in_)
+    flags |= IO_FLAG_IS_READABLE;
+  if (stream_out_)
+    flags |= IO_FLAG_IS_WRITEABLE;
+
+  return flags;
+}
+
+Glib::RefPtr<Glib::Source> StreamIOChannel::create_watch_vfunc(IOCondition)
+{
+  g_warning("Glib::StreamIOChannel::create_watch_vfunc() not implemented");
+  return Glib::RefPtr<Glib::Source>();
+}
+
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+} // namespace Glib
diff --git a/glib/glibmm/streamiochannel.h b/glib/glibmm/streamiochannel.h
new file mode 100644 (file)
index 0000000..7b10110
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GLIBMM_STREAMIOCHANNEL_H
+#define _GLIBMM_STREAMIOCHANNEL_H
+
+#include <glibmmconfig.h>
+#include <glibmm/iochannel.h>
+#include <iosfwd>
+
+namespace Glib
+{
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+
+/** @deprecated This whole class was deprecated in glibmm 2.2 - See the Glib::IOChannel
+ * documentation for an explanation.
+ */
+class GLIBMM_API StreamIOChannel : public Glib::IOChannel
+{
+public:
+  ~StreamIOChannel() noexcept override;
+
+  static Glib::RefPtr<StreamIOChannel> create(std::istream& stream);
+  static Glib::RefPtr<StreamIOChannel> create(std::ostream& stream);
+  static Glib::RefPtr<StreamIOChannel> create(std::iostream& stream);
+
+protected:
+  std::istream* stream_in_;
+  std::ostream* stream_out_;
+
+  StreamIOChannel(std::istream* stream_in, std::ostream* stream_out);
+
+  IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read) override;
+  IOStatus write_vfunc(const char* buf, gsize count, gsize& bytes_written) override;
+  IOStatus seek_vfunc(gint64 offset, SeekType type) override;
+  IOStatus close_vfunc() override;
+  IOStatus set_flags_vfunc(IOFlags flags) override;
+  IOFlags get_flags_vfunc() override;
+  Glib::RefPtr<Glib::Source> create_watch_vfunc(IOCondition cond) override;
+};
+
+#endif //#GLIBMM_DISABLE_DEPRECATED
+
+} // namespace Glib
+
+#endif /* _GLIBMM_STREAMIOCHANNEL_H */
index 466a9b6..66ad2c5 100644 (file)
@@ -34,6 +34,7 @@ namespace Glib
  * @param prefix The prefix to look for.
  * @return <tt>true</tt> if @a str begins with @a prefix, <tt>false</tt> otherwise.
  */
+GLIBMM_API
 bool str_has_prefix(const std::string& str, const std::string& prefix);
 
 /** Looks whether the string @a str ends with @a suffix.
@@ -42,6 +43,7 @@ bool str_has_prefix(const std::string& str, const std::string& prefix);
  * @param suffix The suffix to look for.
  * @return <tt>true</tt> if @a str ends with @a suffix, <tt>false</tt> otherwise.
  */
+GLIBMM_API
 bool str_has_suffix(const std::string& str, const std::string& suffix);
 
 namespace Ascii
@@ -65,6 +67,7 @@ namespace Ascii
  * @throw std::overflow_error  Thrown if the correct value would cause overflow.
  * @throw std::underflow_error Thrown if the correct value would cause underflow.
  */
+GLIBMM_API
 double strtod(const std::string& str);
 
 /** Converts a string to a <tt>double</tt> value.
@@ -88,6 +91,7 @@ double strtod(const std::string& str);
  * @throw std::overflow_error  Thrown if the correct value would cause overflow.
  * @throw std::underflow_error Thrown if the correct value would cause underflow.
  */
+GLIBMM_API
 double strtod(const std::string& str, std::string::size_type& end_index,
   std::string::size_type start_index = 0);
 
@@ -100,6 +104,7 @@ double strtod(const std::string& str, std::string::size_type& end_index,
  * @param d The <tt>double</tt> value to convert.
  * @return The converted string.
  */
+GLIBMM_API
 std::string dtostr(double d);
 
 } // namespace Ascii
@@ -118,6 +123,7 @@ std::string dtostr(double d);
  * @param source A string to escape.
  * @return A copy of @a source with certain characters escaped. See above.
  */
+GLIBMM_API
 std::string strescape(const std::string& source);
 
 /** Escapes all special characters in the string.
@@ -136,6 +142,7 @@ std::string strescape(const std::string& source);
  * @param exceptions A string of characters not to escape in @a source.
  * @return A copy of @a source with certain characters escaped. See above.
  */
+GLIBMM_API
 std::string strescape(const std::string& source, const std::string& exceptions);
 
 /** Replaces all escaped characters with their one byte equivalent.
@@ -145,6 +152,7 @@ std::string strescape(const std::string& source, const std::string& exceptions);
  * @param source A string to compress.
  * @return A copy of @a source with all escaped characters compressed.
  */
+GLIBMM_API
 std::string strcompress(const std::string& source);
 
 /** Returns a string corresponding to the given error code, e.g.\ <tt>"no such process"</tt>.
@@ -156,6 +164,7 @@ std::string strcompress(const std::string& source);
  * @return A string describing the error code. If the error code is unknown,
  * <tt>&quot;unknown error (<em>\<errnum\></em>)&quot;</tt> is returned.
  */
+GLIBMM_API
 Glib::ustring strerror(int errnum);
 
 /** Returns a string describing the given signal, e.g.\ <tt>"Segmentation fault"</tt>.
@@ -167,6 +176,7 @@ Glib::ustring strerror(int errnum);
  * @return A string describing the signal. If the signal is unknown,
  * <tt>&quot;unknown signal (<em>\<signum\></em>)&quot;</tt> is returned.
  */
+GLIBMM_API
 Glib::ustring strsignal(int signum);
 
 } // namespace Glib
diff --git a/glib/glibmm/threadpool.cc b/glib/glibmm/threadpool.cc
new file mode 100644 (file)
index 0000000..7bc93dd
--- /dev/null
@@ -0,0 +1,254 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+#ifndef GLIBMM_DISABLE_DEPRECATED
+
+#include <glibmm/threadpool.h>
+#include <glibmm/exceptionhandler.h>
+#include <glibmm/threads.h>
+#include <glib.h>
+#include <list>
+
+namespace Glib
+{
+
+// internal
+class ThreadPool::SlotList
+{
+public:
+  SlotList();
+  ~SlotList() noexcept;
+
+  // noncopyable
+  SlotList(const ThreadPool::SlotList&) = delete;
+  ThreadPool::SlotList& operator=(const ThreadPool::SlotList&) = delete;
+
+  sigc::slot<void>* push(const sigc::slot<void>& slot);
+  sigc::slot<void> pop(sigc::slot<void>* slot_ptr);
+
+  void lock_and_unlock();
+
+private:
+  Glib::Threads::Mutex mutex_;
+  std::list<sigc::slot<void>> list_;
+};
+
+ThreadPool::SlotList::SlotList()
+{
+}
+
+ThreadPool::SlotList::~SlotList() noexcept
+{
+}
+
+sigc::slot<void>*
+ThreadPool::SlotList::push(const sigc::slot<void>& slot)
+{
+  Threads::Mutex::Lock lock(mutex_);
+
+  list_.emplace_back(slot);
+  return &list_.back();
+}
+
+sigc::slot<void>
+ThreadPool::SlotList::pop(sigc::slot<void>* slot_ptr)
+{
+  sigc::slot<void> slot;
+
+  {
+    Threads::Mutex::Lock lock(mutex_);
+
+    std::list<sigc::slot<void>>::iterator pslot = list_.begin();
+    while (pslot != list_.end() && slot_ptr != &*pslot)
+      ++pslot;
+
+    if (pslot != list_.end())
+    {
+      slot = *pslot;
+      list_.erase(pslot);
+    }
+  }
+
+  return slot;
+}
+
+void
+ThreadPool::SlotList::lock_and_unlock()
+{
+  mutex_.lock();
+  mutex_.unlock();
+}
+
+} // namespace Glib
+
+namespace
+{
+
+static void
+call_thread_entry_slot(void* data, void* user_data)
+{
+  try
+  {
+    Glib::ThreadPool::SlotList* const slot_list =
+      static_cast<Glib::ThreadPool::SlotList*>(user_data);
+
+    sigc::slot<void> slot(slot_list->pop(static_cast<sigc::slot<void>*>(data)));
+
+    slot();
+  }
+  catch (Glib::Threads::Thread::Exit&)
+  {
+    // Just exit from the thread.  The Thread::Exit exception
+    // is our sane C++ replacement of g_thread_exit().
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+}
+
+} // anonymous namespace
+
+namespace Glib
+{
+
+ThreadPool::ThreadPool(int max_threads, bool exclusive)
+: gobject_(nullptr), slot_list_(new SlotList())
+{
+  GError* error = nullptr;
+
+  gobject_ = g_thread_pool_new(&call_thread_entry_slot, slot_list_, max_threads, exclusive, &error);
+
+  if (error)
+  {
+    delete slot_list_;
+    slot_list_ = nullptr;
+    Glib::Error::throw_exception(error);
+  }
+}
+
+ThreadPool::~ThreadPool() noexcept
+{
+  if (gobject_)
+    g_thread_pool_free(gobject_, 1, 1);
+
+  if (slot_list_)
+  {
+    slot_list_->lock_and_unlock();
+    delete slot_list_;
+  }
+}
+
+void
+ThreadPool::push(const sigc::slot<void>& slot)
+{
+  sigc::slot<void>* const slot_ptr = slot_list_->push(slot);
+
+  GError* error = nullptr;
+  g_thread_pool_push(gobject_, slot_ptr, &error);
+
+  if (error)
+  {
+    slot_list_->pop(slot_ptr);
+    Glib::Error::throw_exception(error);
+  }
+}
+
+void
+ThreadPool::set_max_threads(int max_threads)
+{
+  GError* error = nullptr;
+  g_thread_pool_set_max_threads(gobject_, max_threads, &error);
+
+  if (error)
+    Glib::Error::throw_exception(error);
+}
+
+int
+ThreadPool::get_max_threads() const
+{
+  return g_thread_pool_get_max_threads(gobject_);
+}
+
+unsigned int
+ThreadPool::get_num_threads() const
+{
+  return g_thread_pool_get_num_threads(gobject_);
+}
+
+unsigned int
+ThreadPool::unprocessed() const
+{
+  return g_thread_pool_unprocessed(gobject_);
+}
+
+bool
+ThreadPool::get_exclusive() const
+{
+  g_return_val_if_fail(gobject_ != nullptr, false);
+
+  return gobject_->exclusive;
+}
+
+void
+ThreadPool::shutdown(bool immediately)
+{
+  if (gobject_)
+  {
+    g_thread_pool_free(gobject_, immediately, 1);
+    gobject_ = nullptr;
+  }
+
+  if (slot_list_)
+  {
+    slot_list_->lock_and_unlock();
+    delete slot_list_;
+    slot_list_ = nullptr;
+  }
+}
+
+// static
+void
+ThreadPool::set_max_unused_threads(int max_threads)
+{
+  g_thread_pool_set_max_unused_threads(max_threads);
+}
+
+// static
+int
+ThreadPool::get_max_unused_threads()
+{
+  return g_thread_pool_get_max_unused_threads();
+}
+
+// static
+unsigned int
+ThreadPool::get_num_unused_threads()
+{
+  return g_thread_pool_get_num_unused_threads();
+}
+
+// static
+void
+ThreadPool::stop_unused_threads()
+{
+  g_thread_pool_stop_unused_threads();
+}
+
+} // namespace Glib
+
+#endif // GLIBMM_DISABLE_DEPRECATED
diff --git a/glib/glibmm/threadpool.h b/glib/glibmm/threadpool.h
new file mode 100644 (file)
index 0000000..a7a7553
--- /dev/null
@@ -0,0 +1,199 @@
+#ifndef _GLIBMM_THREADPOOL_H
+#define _GLIBMM_THREADPOOL_H
+
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmmconfig.h>
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+
+#include <sigc++/sigc++.h>
+
+extern "C" {
+using GThreadPool = struct _GThreadPool;
+}
+
+namespace Glib
+{
+
+/** @defgroup ThreadPools Thread Pools
+ * Pools of threads to execute work concurrently.
+ *
+ * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14.
+ *
+ * @{
+ */
+
+// TODO: Is std::async() an appropriate replacement to mention for this deprecated API?
+
+/** A pool of threads to execute work concurrently.
+ *
+ * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14.
+ */
+class GLIBMM_API ThreadPool
+{
+public:
+  /** Constructs a new thread pool.
+   * Whenever you call ThreadPool::push(), either a new thread is created or an
+   * unused one is reused. At most @a max_threads threads are running
+   * concurrently for this thread pool. @a max_threads&nbsp;=&nbsp;-1 allows
+   * unlimited threads to be created for this thread pool.
+   *
+   * The parameter @a exclusive determines, whether the thread pool owns all
+   * threads exclusive or whether the threads are shared globally. If @a
+   * exclusive is <tt>true</tt>, @a max_threads threads are started immediately
+   * and they will run exclusively for this thread pool until it is destroyed
+   * by ~ThreadPool(). If @a exclusive is <tt>false</tt>, threads are created
+   * when needed and shared between all non-exclusive thread pools.  This
+   * implies that @a max_threads may not be -1 for exclusive thread pools.
+   *
+   * @param max_threads The maximal number of threads to execute concurrently
+   * in the new thread pool, -1 means no limit.
+   * @param exclusive Should this thread pool be exclusive?
+   * @throw Glib::ThreadError An error can only occur when @a exclusive is
+   * set to <tt>true</tt> and not all @a max_threads threads could be created.
+   */
+  explicit ThreadPool(int max_threads = -1, bool exclusive = false);
+  virtual ~ThreadPool() noexcept;
+
+  // See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+  // TODO: At the next ABI break, consider changing const sigc::slot<void>& slot
+  // to const std::function<void()>& func, if it can be assumed that all supported
+  // compilers understand the C++11 template class std::function<>.
+  /** Inserts @a slot into the list of tasks to be executed by the pool.
+   * When the number of currently running threads is lower than the maximal
+   * allowed number of threads, a new thread is started (or reused).  Otherwise
+   * @a slot stays in the queue until a thread in this pool finishes its
+   * previous task and processes @a slot.
+   *
+   * Because sigc::trackable is not thread-safe, if the slot represents a
+   * non-static class method and is created by sigc::mem_fun(), the class concerned
+   * should not derive from sigc::trackable. You can use, say, boost::bind() or,
+   * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
+   *
+   * @param slot A new task for the thread pool.
+   * @throw Glib::ThreadError An error can only occur when a new thread
+   * couldn't be created. In that case @a slot is simply appended to the
+   * queue of work to do.
+   */
+  void push(const sigc::slot<void>& slot);
+
+  /** Sets the maximal allowed number of threads for the pool.
+   * A value of -1 means that the maximal number of threads is unlimited.
+   * Setting @a max_threads to 0 means stopping all work for pool. It is
+   * effectively frozen until @a max_threads is set to a non-zero value again.
+   *
+   * A thread is never terminated while it is still running. Instead the
+   * maximal number of threads only has effect for the allocation of new
+   * threads in ThreadPool::push().  A new thread is allocated whenever the
+   * number of currently running threads in the pool is smaller than the
+   * maximal number.
+   *
+   * @param max_threads A new maximal number of threads for the pool.
+   * @throw Glib::ThreadError An error can only occur when a new thread
+   * couldn't be created.
+   */
+  void set_max_threads(int max_threads);
+
+  /** Returns the maximal number of threads for the pool.
+   * @return The maximal number of threads.
+   */
+  int get_max_threads() const;
+
+  /** Returns the number of threads currently running in the pool.
+   * @return The number of threads currently running.
+   */
+  unsigned int get_num_threads() const;
+
+  /** Returns the number of tasks still unprocessed in the pool.
+   * @return The number of unprocessed tasks.
+   */
+  unsigned int unprocessed() const;
+
+  /** Returns whether all threads are exclusive to this pool.
+   * @return Whether all threads are exclusive to this pool.
+   */
+  bool get_exclusive() const;
+
+  /** Frees all resources allocated for the pool.
+   * If @a immediately is <tt>true</tt>, no new task is processed.  Otherwise the
+   * pool is not freed before the last task is processed.  Note however, that no
+   * thread of this pool is interrupted while processing a task. Instead at least
+   * all still running threads can finish their tasks before the pool is freed.
+   *
+   * This method does not return before all tasks to be processed (dependent on
+   * @a immediately, whether all or only the currently running) are ready.
+   * After calling shutdown() the pool must not be used anymore.
+   *
+   * @param immediately Should the pool shut down immediately?
+   */
+  void shutdown(bool immediately = false);
+
+  /** Sets the maximal number of unused threads to @a max_threads.
+   * If @a max_threads is -1, no limit is imposed on the number of unused threads.
+   * @param max_threads Maximal number of unused threads.
+   */
+  static void set_max_unused_threads(int max_threads);
+
+  /** Returns the maximal allowed number of unused threads.
+   * @return The maximal number of unused threads.
+   */
+  static int get_max_unused_threads();
+
+  /** Returns the number of currently unused threads.
+   * @return The number of currently unused threads.
+   */
+  static unsigned int get_num_unused_threads();
+
+  /** Stops all currently unused threads.
+   * This does not change the maximal number of unused threads.  This function can
+   * be used to regularly stop all unused threads e.g. from Glib::signal_timeout().
+   */
+  static void stop_unused_threads();
+
+  GThreadPool* gobj() { return gobject_; }
+  const GThreadPool* gobj() const { return gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  class SlotList;
+#endif
+
+private:
+  GThreadPool* gobject_;
+  SlotList* slot_list_;
+
+  ThreadPool(const ThreadPool&);
+  ThreadPool& operator=(const ThreadPool&);
+};
+
+/** @} group ThreadPools */
+
+/***************************************************************************/
+/*  inline implementation                                                  */
+/***************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/**** Glib::Private ********************************************************/
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+#endif /* _GLIBMM_THREADPOOL_H */
index fcee92b..43fff37 100644 (file)
@@ -29,7 +29,7 @@ namespace Glib
 /** Portable stop watch interface.
  * This resembles a convient and portable timer with microseconds resolution.
  */
-class Timer
+class GLIBMM_API Timer
 {
 public:
   /** Create a new timer.
@@ -66,6 +66,7 @@ private:
   GTimer* gobject_;
 };
 
+GLIBMM_API
 void usleep(unsigned long microseconds);
 
 } // namespace Glib
diff --git a/glib/glibmm/timeval.cc b/glib/glibmm/timeval.cc
new file mode 100644 (file)
index 0000000..1e2c079
--- /dev/null
@@ -0,0 +1,143 @@
+/* timeval.cc
+ *
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/timeval.h>
+
+namespace Glib
+{
+#ifndef GLIBMM_DISABLE_DEPRECATED
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+void
+TimeVal::assign_current_time()
+{
+  g_get_current_time(this);
+}
+
+bool
+TimeVal::assign_from_iso8601(const Glib::ustring& iso_date)
+{
+  return g_time_val_from_iso8601(iso_date.c_str(), this);
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+void
+TimeVal::add(const TimeVal& rhs)
+{
+  g_return_if_fail(tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+  g_return_if_fail(rhs.tv_usec >= 0 && rhs.tv_usec < G_USEC_PER_SEC);
+
+  tv_usec += rhs.tv_usec;
+
+  if (tv_usec >= G_USEC_PER_SEC)
+  {
+    tv_usec -= G_USEC_PER_SEC;
+    ++tv_sec;
+  }
+
+  tv_sec += rhs.tv_sec;
+}
+
+void
+TimeVal::subtract(const TimeVal& rhs)
+{
+  g_return_if_fail(tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+  g_return_if_fail(rhs.tv_usec >= 0 && rhs.tv_usec < G_USEC_PER_SEC);
+
+  tv_usec -= rhs.tv_usec;
+
+  if (tv_usec < 0)
+  {
+    tv_usec += G_USEC_PER_SEC;
+    --tv_sec;
+  }
+
+  tv_sec -= rhs.tv_sec;
+}
+
+void
+TimeVal::add_seconds(long seconds)
+{
+  g_return_if_fail(tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+
+  tv_sec += seconds;
+}
+
+void
+TimeVal::subtract_seconds(long seconds)
+{
+  g_return_if_fail(tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+
+  tv_sec -= seconds;
+}
+
+void
+TimeVal::add_milliseconds(long milliseconds)
+{
+  g_return_if_fail(tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+
+  tv_usec += (milliseconds % 1000) * 1000;
+
+  if (tv_usec < 0)
+  {
+    tv_usec += G_USEC_PER_SEC;
+    --tv_sec;
+  }
+  else if (tv_usec >= G_USEC_PER_SEC)
+  {
+    tv_usec -= G_USEC_PER_SEC;
+    ++tv_sec;
+  }
+
+  tv_sec += milliseconds / 1000;
+}
+
+void
+TimeVal::subtract_milliseconds(long milliseconds)
+{
+  add_milliseconds(-1 * milliseconds);
+}
+
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+void
+TimeVal::add_microseconds(long microseconds)
+{
+  g_time_val_add(this, microseconds);
+}
+
+void
+TimeVal::subtract_microseconds(long microseconds)
+{
+  g_time_val_add(this, -1 * microseconds);
+}
+
+Glib::ustring
+TimeVal::as_iso8601() const
+{
+  gchar* retval = g_time_val_to_iso8601(const_cast<Glib::TimeVal*>(this));
+  if (retval)
+  {
+    Glib::ustring iso_date(retval);
+    g_free(retval);
+    return iso_date;
+  }
+  return Glib::ustring();
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+#endif // GLIBMM_DISABLE_DEPRECATED
+
+} // namespace Glib
diff --git a/glib/glibmm/timeval.h b/glib/glibmm/timeval.h
new file mode 100644 (file)
index 0000000..831ed7a
--- /dev/null
@@ -0,0 +1,253 @@
+#ifndef _GLIBMM_TIMEVAL_H
+#define _GLIBMM_TIMEVAL_H
+
+/* timeval.h
+ *
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glibmm/ustring.h>
+
+namespace Glib
+{
+
+// GTimeVal is deprecated.
+// The deprecated GTimeVal is used in the non-deprecated gdk_pixbuf_animation_iter_advance().
+// That's why not all of struct Glib::TimeVal is surrounded by
+// #ifndef GLIBMM_DISABLE_DEPRECATED/#endif. It would result in compilation errors,
+// if you define GLIBMM_DISABLE_DEPRECATED and include gdkmm/pixbufanimationiter.h.
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+/** Glib::TimeVal is a wrapper around the glib structure GTimeVal.
+ * The glib structure GTimeVal itself is equivalent to struct timeval,
+ * which is returned by the gettimeofday() UNIX call. Additionally
+ * this wrapper provides an assortment of time manipulation functions.
+ *
+ * @deprecated Use Glib::DateTime instead.
+ */
+struct GLIBMM_API TimeVal : public GTimeVal
+{
+  inline TimeVal();
+  inline TimeVal(long seconds, long microseconds);
+
+  inline TimeVal(const GTimeVal& gtimeval);
+  inline TimeVal& operator=(const GTimeVal& gtimeval);
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+  /** Assigns the current time to the TimeVal instance.
+   * Equivalent to the UNIX gettimeofday() function, but is portable and
+   * works also on Win32.
+   */
+  void assign_current_time();
+
+  /** Converts a string containing an ISO 8601 encoded date and time
+   * to a Glib::TimeVal and puts it in TimeVal instance.
+   * @param iso_date ISO 8601 encoded string.
+   * @return <tt>true</tt> if conversion was successful.
+   *
+   * @newin{2,22}
+   */
+  bool assign_from_iso8601(const Glib::ustring& iso_date);
+
+  void add(const TimeVal& rhs);
+  void subtract(const TimeVal& rhs);
+  void add_seconds(long seconds);
+  void subtract_seconds(long seconds);
+  void add_milliseconds(long milliseconds);
+  void subtract_milliseconds(long milliseconds);
+  void add_microseconds(long microseconds);
+  void subtract_microseconds(long microseconds);
+
+  inline TimeVal& operator+=(const TimeVal& gtimeval);
+  inline TimeVal& operator-=(const TimeVal& gtimeval);
+  inline TimeVal& operator+=(long seconds);
+  inline TimeVal& operator-=(long seconds);
+
+  /** Returns a double representation of the time interval.
+   * This member function converts the time interval, that is
+   * internally stored as two long values for seconds and microseconds,
+   * to a double representation, whose unit is seconds.
+   */
+  inline double as_double() const;
+
+  /** Returns an ISO 8601 encoded string, relative to the Coordinated
+   * Universal Time (UTC).
+   *
+   * @newin{2,22}
+   */
+  Glib::ustring as_iso8601() const;
+
+  inline bool negative() const;
+
+  /** Checks whether the stored time interval is positive.
+   * Returns true if the stored time / time interval is positive.
+   */
+  inline bool valid() const;
+#endif // GLIBMM_DISABLE_DEPRECATED
+};
+
+inline TimeVal::TimeVal()
+{
+  tv_sec = 0;
+  tv_usec = 0;
+}
+
+inline TimeVal::TimeVal(long seconds, long microseconds)
+{
+  tv_sec = seconds;
+  tv_usec = microseconds;
+}
+
+inline TimeVal::TimeVal(const GTimeVal& gtimeval)
+{
+  tv_sec = gtimeval.tv_sec;
+  tv_usec = gtimeval.tv_usec;
+}
+
+inline TimeVal&
+TimeVal::operator=(const GTimeVal& gtimeval)
+{
+  tv_sec = gtimeval.tv_sec;
+  tv_usec = gtimeval.tv_usec;
+  return *this;
+}
+
+#ifndef GLIBMM_DISABLE_DEPRECATED
+inline TimeVal&
+TimeVal::operator+=(const TimeVal& gtimeval)
+{
+  add(gtimeval);
+
+  return *this;
+}
+
+inline TimeVal&
+TimeVal::operator-=(const TimeVal& gtimeval)
+{
+  subtract(gtimeval);
+
+  return *this;
+}
+
+inline TimeVal&
+TimeVal::operator+=(long seconds)
+{
+  add_seconds(seconds);
+
+  return *this;
+}
+
+inline TimeVal&
+TimeVal::operator-=(long seconds)
+{
+  subtract_seconds(seconds);
+
+  return *this;
+}
+
+inline double
+TimeVal::as_double() const
+{
+  return double(tv_sec) + double(tv_usec) / double(G_USEC_PER_SEC);
+}
+
+inline bool
+TimeVal::negative() const
+{
+  return (tv_sec < 0);
+}
+
+inline bool
+TimeVal::valid() const
+{
+  return (tv_usec >= 0 && tv_usec < G_USEC_PER_SEC);
+}
+
+/** @relates Glib::TimeVal */
+inline TimeVal
+operator+(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return TimeVal(lhs) += rhs;
+}
+
+/** @relates Glib::TimeVal */
+inline TimeVal
+operator+(const TimeVal& lhs, long seconds)
+{
+  return TimeVal(lhs) += seconds;
+}
+
+/** @relates Glib::TimeVal */
+inline TimeVal
+operator-(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return TimeVal(lhs) -= rhs;
+}
+
+/** @relates Glib::TimeVal */
+inline TimeVal
+operator-(const TimeVal& lhs, long seconds)
+{
+  return TimeVal(lhs) -= seconds;
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator==(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec == rhs.tv_usec);
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator!=(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return (lhs.tv_sec != rhs.tv_sec || lhs.tv_usec != rhs.tv_usec);
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator<(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return ((lhs.tv_sec < rhs.tv_sec) || (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec < rhs.tv_usec));
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator>(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return ((lhs.tv_sec > rhs.tv_sec) || (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec > rhs.tv_usec));
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator<=(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return ((lhs.tv_sec < rhs.tv_sec) || (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec <= rhs.tv_usec));
+}
+
+/** @relates Glib::TimeVal */
+inline bool
+operator>=(const TimeVal& lhs, const TimeVal& rhs)
+{
+  return ((lhs.tv_sec > rhs.tv_sec) || (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec >= rhs.tv_usec));
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+} // namespace Glib
+
+#endif /* _GLIBMM_TIMEVAL_H */
index d17107a..cd012fc 100644 (file)
 #include <config.h>
 #endif
 
+// If glibmm is built with Autotools, GLIBMM_SIZEOF_WCHAR_T is not defined and
+// SIZEOF_WCHAR_T is defined in config.h.
+// If glibmm is built with Meson, config.h does not exist and
+// GLIBMM_SIZEOF_WCHAR_T is defined in glibmmconfig.h.
+#if !defined(SIZEOF_WCHAR_T) && defined(GLIBMM_SIZEOF_WCHAR_T)
+#define SIZEOF_WCHAR_T GLIBMM_SIZEOF_WCHAR_T
+#endif
+
 namespace
 {
 
@@ -1283,13 +1291,13 @@ ustring::casefold_collate_key() const
 
 // static
 ustring
-ustring::compose_private(const Glib::ustring& fmt, std::initializer_list<const ustring*> const ilist)
+ustring::compose_argv(const Glib::ustring& fmt, int argc, const ustring* const* argv)
 {
   std::string::size_type result_size = fmt.raw().size();
 
   // Guesstimate the final string size.
-  for (auto const it: ilist)
-    result_size += it->raw().size();
+  for (int i = 0; i < argc; ++i)
+    result_size += argv[i]->raw().size();
 
   std::string result;
   result.reserve(result_size);
@@ -1307,12 +1315,11 @@ ustring::compose_private(const Glib::ustring& fmt, std::initializer_list<const u
     else
     {
       const int index = Ascii::digit_value(stop[1]) - 1;
-      const int size = ilist.size();
 
-      if (index >= 0 && index < size)
+      if (index >= 0 && index < argc)
       {
         result.append(start, stop - start);
-        result += (*(ilist.begin() + index))->raw();
+        result += argv[index]->raw();
         start = stop + 2;
       }
       else
index a5bfca4..33a3017 100644 (file)
 #include <glibmm/unicode.h>
 #include <glib.h>
 
-#include <cstddef> // for std::size_t and optionally std::ptrdiff_t
-#include <initializer_list>
 #include <iosfwd>
 #include <iterator>
 #include <sstream>
 #include <string>
+#ifndef GLIBMM_HAVE_STD_ITERATOR_TRAITS
+#include <cstddef> /* for std::ptrdiff_t */
+#endif
+
+/* work around linker error on Visual Studio if we don't have GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS */
+#if (_MSC_VER >= 1600) && !defined (GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS)
+const std::basic_string<char>::size_type std::basic_string<char>::npos = (std::basic_string<char>::size_type) -1;
+#endif
 
 namespace Glib
 {
 
+class GLIBMM_API ustring;
+
+//********** Glib::StdStringView and Glib::UStringView *************
+
+// It would be possible to replace StdStringView and UStringView with a
+// template class BasicStringView + two type aliases defining StdStringView
+// and UStringView. But Doxygen don't generate links to type aliases.
+//
+// It would also be possible to replace StdStringView and UStringView with
+// a StringView class with 3 constructors, taking const std::string&,
+// const Glib::ustring& and const char*, respectively. The split into two classes
+// is by design. Using the wrong string class shall not be as easy as using
+// the right string class.
+
+/** Helper class to avoid unnecessary string copying in function calls.
+ *
+ * A %Glib::StdStringView holds a const char pointer. It can be used as an argument
+ * type in a function that passes a const char pointer to a C function.
+ *
+ * Unlike std::string_view, %Glib::StdStringView shall be used only for
+ * null-terminated strings.
+ * @code
+ * std::string f1(Glib::StdStringView s1, Glib::StdStringView s2);
+ * // can be used instead of
+ * std::string f2(const std::string& s1, const std::string& s2);
+ * @endcode
+ * The strings are not copied when f1() is called with string literals.
+ * @code
+ * auto r1 = f1("string 1", "string 2");
+ * @endcode
+ * To pass a Glib::ustring to a function taking a %Glib::StdStringView, you may have
+ * to use Glib::ustring::c_str().
+ * @code
+ * std::string str = "non-UTF8 string";
+ * Glib::ustring ustr = "UTF8 string";
+ * auto r1 = f1(str, ustr.c_str());
+ * @endcode
+ *
+ * @newin{2,64}
+ */
+class GLIBMM_API StdStringView
+{
+public:
+  StdStringView(const std::string& s) : pstring_(s.c_str()) {}
+  StdStringView(const char* s) : pstring_(s) {}
+  const char* c_str() const { return pstring_; }
+private:
+  const char* pstring_;
+};
+
+/** Helper class to avoid unnecessary string copying in function calls.
+ *
+ * A %Glib::UStringView holds a const char pointer. It can be used as an argument
+ * type in a function that passes a const char pointer to a C function.
+ *
+ * Unlike std::string_view, %Glib::UStringView shall be used only for
+ * null-terminated strings.
+ * @code
+ * Glib::ustring f1(Glib::UStringView s1, Glib::UStringView s2);
+ * // can be used instead of
+ * Glib::ustring f2(const Glib::ustring& s1, const Glib::ustring& s2);
+ * @endcode
+ * The strings are not copied when f1() is called with string literals.
+ * @code
+ * auto r1 = f1("string 1", "string 2");
+ * @endcode
+ * To pass a std::string to a function taking a %Glib::UStringView, you may have
+ * to use std::string::c_str().
+ * @code
+ * std::string str = "non-UTF8 string";
+ * Glib::ustring ustr = "UTF8 string";
+ * auto r1 = f1(str.c_str(), ustr);
+ * @endcode
+ *
+ * @newin{2,64}
+ */
+class GLIBMM_API UStringView
+{
+public:
+  inline UStringView(const Glib::ustring& s);
+  UStringView(const char* s) : pstring_(s) {}
+  const char* c_str() const { return pstring_; }
+private:
+  const char* pstring_;
+};
+
+//***************************************************
+
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 #ifndef GLIBMM_HAVE_STD_ITERATOR_TRAITS
 
@@ -105,6 +199,7 @@ public:
 
   inline ustring_Iterator();
   inline ustring_Iterator(const ustring_Iterator<std::string::iterator>& other);
+  ustring_Iterator& operator=(const ustring_Iterator& other) = default;
 
   inline value_type operator*() const;
 
@@ -130,6 +225,7 @@ private:
  * but it might be useful as utility function if you prefer using
  * std::string even for UTF-8 encoding.
  */
+GLIBMM_API
 gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_PURE;
 
 /** %Glib::ustring has much the same interface as std::string, but contains
@@ -192,9 +288,7 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
  * If you're using std::ostringstream to build strings for display in the
  * user interface, you must convert the result back to UTF-8 as shown below:
  * @code
- * std::locale::global(std::locale("")); // Set the global locale to the user's preferred locale.
- *                                       // Usually unnecessary here, because Glib::init()
- *                                       // does it for you.
+ * std::locale::global(std::locale("")); // set the global locale to the user's preferred locale
  * std::ostringstream output;
  * output << percentage << " % done";
  * label->set_text(Glib::locale_to_utf8(output.str()));
@@ -221,7 +315,7 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
  * reimplement the interface so that all operations are based on characters
  * instead of bytes.
  */
-class ustring
+class GLIBMM_API ustring
 {
 public:
   using size_type = std::string::size_type;
@@ -252,11 +346,11 @@ public:
 #endif /* GLIBMM_HAVE_SUN_REVERSE_ITERATOR */
 
 #ifdef GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS
-  static GLIBMM_API const size_type npos = std::string::npos;
+  static const size_type npos = std::string::npos;
 #else
   // The IRIX MipsPro compiler says "The indicated constant value is not known",
   // so we need to initalize the static member data elsewhere.
-  static GLIBMM_API const size_type npos;
+  static const size_type npos;
 #endif
 
   /*! Default constructor, which creates an empty string.
@@ -604,9 +698,9 @@ public:
   /*! Check whether the string is valid UTF-8. */
   bool validate(const_iterator& first_invalid) const;
 
-  /*! Return a copy that is a valid UTF-8 string replacing invalid bytes in the
-   *  original with %Unicode replacement character (U+FFFD).
-   *  If the string is valid, return a copy of it.
+  /*! Return a copy that is a valid UTF-8 string replacing invalid bytes
+   * in the original with %Unicode replacement character (U+FFFD).
+   * If the string is valid, return a copy of it.
    */
   ustring make_valid() const;
 
@@ -619,7 +713,7 @@ public:
   bool is_ascii() const;
 
   /*! "Normalize" the %Unicode character representation of the string. */
-  ustring normalize(NormalizeMode mode = NormalizeMode::DEFAULT_COMPOSE) const;
+  ustring normalize(NormalizeMode mode = NORMALIZE_DEFAULT_COMPOSE) const;
 
   //! @}
   //! @name Character case conversion.
@@ -655,74 +749,170 @@ public:
   /* Returns fmt as is, but checks for invalid references in the format string.
    * @newin{2,18}
    */
+  template <class T1>
   static inline ustring compose(const ustring& fmt);
 
   /*! Substitute placeholders in a format string with the referenced arguments.
-   *
-   * The template string uses a similar format to Qt’s QString class, in that
-   * <tt>%1</tt>, <tt>%2</tt>, and so on to <tt>%9</tt> are used as placeholders
-   * to be substituted with the string representation of the @a args 1–9, while
-   * <tt>%%</tt> inserts a literal <tt>%</tt> in the output. Placeholders do not
-   * have to appear in the same order as their corresponding function arguments.
-   *
+   * The template string should be in <tt>qt-format</tt>, that is
+   * <tt>"%1"</tt>, <tt>"%2"</tt>, ..., <tt>"%9"</tt> are used as placeholders
+   * and <tt>"%%"</tt> denotes a literal <tt>"%"</tt>.  Substitutions may be
+   * reordered.
    * @par Example:
    * @code
    * using Glib::ustring;
    * const int percentage = 50;
    * const ustring text = ustring::compose("%1%% done", percentage);
    * @endcode
-   *
-   * @param fmt The template string, in the format described above.
-   * @param args 1 to 9 arguments to substitute for <tt>%1</tt> to <tt>%9</tt>
-   * respectively.
-   *
+   * @param fmt A template string in <tt>qt-format</tt>.
+   * @param a1 The argument to substitute for <tt>"%1"</tt>.
    * @return The substituted message string.
-   *
    * @throw Glib::ConvertError
    *
-   * @newin{2,58}
+   * @newin{2,16}
    */
-  template <class... Ts>
-  static inline ustring compose(const ustring& fmt, const Ts&... args);
+  template <class T1>
+  static inline ustring compose(const ustring& fmt, const T1& a1);
 
-  /*! Format the argument(s) to a string representation.
-   *
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4>
+  static inline ustring compose(
+    const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5>
+  static inline ustring compose(
+    const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3,
+    const T4& a4, const T5& a5, const T6& a6);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3,
+    const T4& a4, const T5& a5, const T6& a6, const T7& a7);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3,
+    const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8);
+
+  /* See the documentation for compose(const ustring& fmt, const T1& a1).
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8,
+    class T9>
+  static inline ustring compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3,
+    const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9);
+
+  /*! Format the argument to its string representation.
    * Applies the arguments in order to an std::wostringstream and returns the
    * resulting string.  I/O manipulators may also be used as arguments.  This
    * greatly simplifies the common task of converting a number to a string, as
    * demonstrated by the example below.  The format() methods can also be used
    * in conjunction with compose() to facilitate localization of user-visible
    * messages.
-   *
    * @code
    * using Glib::ustring;
    * double value = 22.0 / 7.0;
    * ustring text = ustring::format(std::fixed, std::setprecision(2), value);
    * @endcode
-   *
    * @note The use of a wide character stream in the implementation of format()
    * is almost completely transparent.  However, one of the instances where the
    * use of wide streams becomes visible is when the std::setfill() stream
    * manipulator is used.  In order for std::setfill() to work the argument
    * must be of type <tt>wchar_t</tt>.  This can be achieved by using the
    * <tt>L</tt> prefix with a character literal, as shown in the example.
-   *
    * @code
    * using Glib::ustring;
    * // Insert leading zeroes to fill in at least six digits
    * ustring text = ustring::format(std::setfill(L'0'), std::setw(6), 123);
    * @endcode
    *
-   * @param args One or more streamable values or I/O manipulators.
-   *
+   * @param a1 A streamable value or an I/O manipulator.
    * @return The string representation of the argument stream.
-   *
    * @throw Glib::ConvertError
    *
-   * @newin{2,58}
+   * @newin{2,16}
    */
-  template <class... Ts>
-  static inline ustring format(const Ts&... args);
+  template <class T1>
+  static inline ustring format(const T1& a1);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2>
+  static inline ustring format(const T1& a1, const T2& a2);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3>
+  static inline ustring format(const T1& a1, const T2& a2, const T3& a3);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4>
+  static inline ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5>
+  static inline ustring format(
+    const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6>
+  static inline ustring format(
+    const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+  static inline ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5,
+    const T6& a6, const T7& a7);
+
+  /* See the documentation for format(const T1& a1).
+   *
+   * @newin{2,16}
+   */
+  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
+  static inline ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5,
+    const T6& a6, const T7& a7, const T8& a8);
 
   /*! Substitute placeholders in a format string with the referenced arguments.
    *
@@ -837,11 +1027,10 @@ private:
 
   template <class T>
   class Stringify;
-
-  static ustring compose_private(const ustring& fmt, std::initializer_list<const ustring*> ilist);
-
   class FormatStream;
 
+  static ustring compose_argv(const ustring& fmt, int argc, const ustring* const* argv);
+
   template<class T> static inline const T& sprintify(const T& arg);
   static inline const char* sprintify(const ustring& arg);
   static inline const char* sprintify(const std::string& arg);
@@ -871,18 +1060,19 @@ struct ustring::SequenceToString<In, gunichar> : public std::string
 };
 
 template <>
-struct ustring::SequenceToString<Glib::ustring::iterator, gunichar> : public std::string
+struct GLIBMM_API ustring::SequenceToString<Glib::ustring::iterator, gunichar> : public std::string
 {
   SequenceToString(Glib::ustring::iterator pbegin, Glib::ustring::iterator pend);
 };
 
 template <>
-struct ustring::SequenceToString<Glib::ustring::const_iterator, gunichar> : public std::string
+struct GLIBMM_API ustring::SequenceToString<Glib::ustring::const_iterator, gunichar> : public std::string
 {
   SequenceToString(Glib::ustring::const_iterator pbegin, Glib::ustring::const_iterator pend);
 };
 
-class ustring::FormatStream
+
+class GLIBMM_API ustring::FormatStream
 {
 public:
   // noncopyable
@@ -918,12 +1108,14 @@ public:
  * @relates Glib::ustring
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::istream& operator>>(std::istream& is, Glib::ustring& utf8_string);
 
 /** Stream output operator.
  * @relates Glib::ustring
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::ostream& operator<<(std::ostream& os, const Glib::ustring& utf8_string);
 
 #ifdef GLIBMM_HAVE_WIDE_STREAM
@@ -932,12 +1124,14 @@ std::ostream& operator<<(std::ostream& os, const Glib::ustring& utf8_string);
  * @relates Glib::ustring
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::wistream& operator>>(std::wistream& is, ustring& utf8_string);
 
 /** Wide stream output operator.
  * @relates Glib::ustring
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::wostream& operator<<(std::wostream& os, const ustring& utf8_string);
 
 #endif /* GLIBMM_HAVE_WIDE_STREAM */
@@ -1128,7 +1322,8 @@ template <class In>
 void
 ustring::insert(ustring::iterator p, In pbegin, In pend)
 {
-  string_.insert(p.base(), Glib::ustring::SequenceToString<In>(pbegin, pend));
+  size_type pos = p.base() - string_.begin();
+  string_.insert(pos, Glib::ustring::SequenceToString<In>(pbegin, pend));
 }
 
 template <class In>
@@ -1159,13 +1354,114 @@ ustring::raw() const
   return string_;
 }
 
-template <class... Ts>
+template <class T1>
+inline // static
+  ustring
+  ustring::format(const T1& a1)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  return buf.to_string();
+}
+
+template <class T1, class T2>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2, const T3& a3)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  buf.stream(a4);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4, class T5>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  buf.stream(a4);
+  buf.stream(a5);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6>
 inline // static
   ustring
-  ustring::format(const Ts&... args)
+  ustring::format(
+    const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
 {
   ustring::FormatStream buf;
-  (buf.stream(args), ...);
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  buf.stream(a4);
+  buf.stream(a5);
+  buf.stream(a6);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5,
+    const T6& a6, const T7& a7)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  buf.stream(a4);
+  buf.stream(a5);
+  buf.stream(a6);
+  buf.stream(a7);
+  return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
+inline // static
+  ustring
+  ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5,
+    const T6& a6, const T7& a7, const T8& a8)
+{
+  ustring::FormatStream buf;
+  buf.stream(a1);
+  buf.stream(a2);
+  buf.stream(a3);
+  buf.stream(a4);
+  buf.stream(a5);
+  buf.stream(a6);
+  buf.stream(a7);
+  buf.stream(a8);
   return buf.to_string();
 }
 
@@ -1175,21 +1471,24 @@ template <class T>
 class ustring::Stringify
 {
 private:
-  const ustring string_;
+  ustring string_;
 
 public:
   explicit inline Stringify(const T& arg) : string_(ustring::format(arg)) {}
 
+  // TODO: Why is this here? See the template specialization:
+  explicit inline Stringify(const char* arg) : string_(arg) {}
+
   // noncopyable
   Stringify(const ustring::Stringify<T>&) = delete;
   Stringify<T>& operator=(const ustring::Stringify<T>&) = delete;
 
-  inline const ustring& ref() const { return string_; }
+  inline const ustring* ptr() const { return &string_; }
 };
 
 /// A template specialization for Stringify<ustring>:
 template <>
-class ustring::Stringify<ustring>
+class GLIBMM_API ustring::Stringify<ustring>
 {
 private:
   const ustring& string_;
@@ -1201,14 +1500,14 @@ public:
   Stringify(const ustring::Stringify<ustring>&) = delete;
   Stringify<ustring>& operator=(const ustring::Stringify<ustring>&) = delete;
 
-  inline const ustring& ref() const { return string_; }
+  inline const ustring* ptr() const { return &string_; }
 };
 
 /** A template specialization for Stringify<const char*>,
  * because the regular template has ambiguous constructor overloads for char*.
  */
 template <>
-class ustring::Stringify<const char*>
+class GLIBMM_API ustring::Stringify<const char*>
 {
 private:
   const ustring string_;
@@ -1220,7 +1519,7 @@ public:
   Stringify(const ustring::Stringify<const char*>&) = delete;
   Stringify<ustring>& operator=(const ustring::Stringify<const char*>&) = delete;
 
-  inline const ustring& ref() const { return string_; }
+  inline const ustring* ptr() const { return &string_; }
 };
 
 /** A template specialization for Stringify<char[N]> (for string literals),
@@ -1239,7 +1538,7 @@ public:
   Stringify(const ustring::Stringify<char[N]>&) = delete;
   Stringify<ustring>& operator=(const ustring::Stringify<char[N]>&) = delete;
 
-  inline const ustring& ref() const { return string_; }
+  inline const ustring* ptr() const { return &string_; }
 };
 
 /** A template specialization for Stringify<const char[N]> (for string literals),
@@ -1259,9 +1558,17 @@ public:
   Stringify(const ustring::Stringify<const char[N]>&) = delete;
   Stringify<ustring>& operator=(const ustring::Stringify<const char[N]>&) = delete;
 
-  inline const ustring& ref() const { return string_; }
+  inline const ustring* ptr() const { return &string_; }
 };
 
+template <class T1>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt)
+{
+  return ustring::compose_argv(fmt, 0, nullptr);
+}
+
 /* These helper functions used by ustring::sprintf() let users pass C++ strings
  * to match %s placeholders, without the hassle of writing .c_str() in user code
  */
@@ -1289,22 +1596,147 @@ inline // static
 
 // Public methods
 
+template <class T1>
 inline // static
   ustring
-  ustring::compose(const ustring& fmt)
+  ustring::compose(const ustring& fmt, const T1& a1)
 {
-  return ustring::compose_private(fmt, {});
+  const ustring::Stringify<T1> s1(a1);
+
+  const ustring* const argv[] = { s1.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
 }
 
-template <class... Ts>
+template <class T1, class T2>
 inline // static
   ustring
-  ustring::compose(const ustring& fmt, const Ts&... args)
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2)
 {
-  static_assert(sizeof...(Ts) <= 9,
-                "ustring::compose only supports up to 9 placeholders.");
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
 
-  return compose_private(fmt, {&Stringify<Ts>(args).ref()...});
+  const ustring* const argv[] = { s1.ptr(), s2.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4, class T5>
+inline // static
+  ustring
+  ustring::compose(
+    const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+  const ustring::Stringify<T5> s5(a5);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+    const T5& a5, const T6& a6)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+  const ustring::Stringify<T5> s5(a5);
+  const ustring::Stringify<T6> s6(a6);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr(), s6.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+    const T5& a5, const T6& a6, const T7& a7)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+  const ustring::Stringify<T5> s5(a5);
+  const ustring::Stringify<T6> s6(a6);
+  const ustring::Stringify<T7> s7(a7);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr(), s6.ptr(),
+    s7.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+    const T5& a5, const T6& a6, const T7& a7, const T8& a8)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+  const ustring::Stringify<T5> s5(a5);
+  const ustring::Stringify<T6> s6(a6);
+  const ustring::Stringify<T7> s7(a7);
+  const ustring::Stringify<T8> s8(a8);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr(), s6.ptr(),
+    s7.ptr(), s8.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
+inline // static
+  ustring
+  ustring::compose(const ustring& fmt, const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+    const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
+{
+  const ustring::Stringify<T1> s1(a1);
+  const ustring::Stringify<T2> s2(a2);
+  const ustring::Stringify<T3> s3(a3);
+  const ustring::Stringify<T4> s4(a4);
+  const ustring::Stringify<T5> s5(a5);
+  const ustring::Stringify<T6> s6(a6);
+  const ustring::Stringify<T7> s7(a7);
+  const ustring::Stringify<T8> s8(a8);
+  const ustring::Stringify<T9> s9(a9);
+
+  const ustring* const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr(), s6.ptr(),
+    s7.ptr(), s8.ptr(), s9.ptr() };
+  return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
 }
 
 template <class... Ts>
@@ -1562,6 +1994,10 @@ operator+(char lhs, const ustring& rhs)
   return temp;
 }
 
+//********** Glib::StdStringView and Glib::UStringView *************
+
+inline UStringView::UStringView(const ustring& s) : pstring_(s.c_str()) {}
+
 } // namespace Glib
 
 #endif /* _GLIBMM_USTRING_H */
index 6c7378a..9ce3b05 100644 (file)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+/* Occasionally, a struct variable has to be initialized after its definition,
+ * i.e. when using structs as class member data.  For convenience, the macro
+ * GLIBMM_INITIALIZE_STRUCT(Var, Type) is provided.  It even avoids creating
+ * a temporary if the compiler is GCC.
+ *
+ * @deprecated Use e.g. std::memset() instead.
+ * It's not used any more in the code generated by _CLASS_BOXEDTYPE_STATIC.
+ * It generates compiler warnings if __STRICT_ANSI__ is defined.
+ */
+#if ((__GNUC__ >= 3) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) && !defined(__STRICT_ANSI__)
+
+#define GLIBMM_INITIALIZE_STRUCT(Var, Type) __builtin_memset(&(Var), 0, sizeof(Type))
+
+#else
+
+// TODO: This causes warnings like this:
+//"missing initializer for member"
+#define GLIBMM_INITIALIZE_STRUCT(Var, Type) \
+  G_STMT_START                              \
+  {                                         \
+    Type const temp_initializer__ = {       \
+      0,                                    \
+    };                                      \
+    (Var) = temp_initializer__;             \
+  }                                         \
+  G_STMT_END
+
+#endif
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 namespace Glib
 {
 
 // These are used by gmmproc-generated type conversions:
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+/** Helper to deal with memory allocated
+ * by GLib functions in an exception-safe manner.
+ *
+ * @deprecated Use make_unique_ptr_gfree() instead.
+ */
+template <typename T>
+class ScopedPtr
+{
+private:
+  T* ptr_;
+  ScopedPtr(const ScopedPtr<T>&);
+  ScopedPtr<T>& operator=(const ScopedPtr<T>&);
+
+public:
+  ScopedPtr() : ptr_(nullptr) {}
+  explicit ScopedPtr(T* ptr) : ptr_(ptr) {}
+  ~ScopedPtr() noexcept { g_free(ptr_); }
+  T* get() const { return ptr_; }
+  T** addr() { return &ptr_; }
+};
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 /** Helper to deal with memory allocated
  * by GLib functions in an exception-safe manner.
  *
@@ -41,6 +95,17 @@ make_unique_ptr_gfree(T* p)
   return std::unique_ptr<T[], decltype(&g_free)>(p, &g_free);
 }
 
+// TODO: Deprecate this? We don't use it ourselves.
+/** Removes the const nature of a ptr
+ *
+ */
+template <class T>
+inline T*
+unconst(const T* t)
+{
+  return const_cast<T*>(t);
+}
+
 // Convert const gchar* to ustring, while treating NULL as empty string.
 inline Glib::ustring
 convert_const_gchar_ptr_to_ustring(const char* str)
@@ -80,6 +145,7 @@ c_str_or_nullptr(const T& str)
 }
 
 // Append type_name to dest, while replacing special characters with '+'.
+GLIBMM_API
 void append_canonical_typename(std::string& dest, const char* type_name);
 
 // Delete data referred to by a void*.
index 6f8eee2..664d33c 100644 (file)
@@ -94,6 +94,13 @@ ValueBase_Boxed::get_boxed() const
   return g_value_get_boxed(&gobject_);
 }
 
+GParamSpec*
+ValueBase_Boxed::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+    static_cast<Glib::ParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
 GParamSpec* ValueBase_Boxed::create_param_spec(const Glib::ustring& name,
   const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags) const
 {
@@ -128,7 +135,14 @@ Glib::RefPtr<Glib::ObjectBase>
 ValueBase_Object::get_object_copy() const
 {
   GObject* const data = static_cast<GObject*>(g_value_get_object(&gobject_));
-  return Glib::make_refptr_for_instance<Glib::ObjectBase>(Glib::wrap_auto(data, true));
+  return Glib::RefPtr<Glib::ObjectBase>(Glib::wrap_auto(data, true));
+}
+
+GParamSpec*
+ValueBase_Object::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+      static_cast<Glib::ParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 GParamSpec*
@@ -177,6 +191,13 @@ ValueBase_Enum::get_enum() const
 }
 
 GParamSpec*
+ValueBase_Enum::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+      static_cast<Glib::ParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+GParamSpec*
 ValueBase_Enum::create_param_spec(const Glib::ustring& name,
   const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags) const
 {
@@ -206,6 +227,13 @@ ValueBase_Flags::get_flags() const
   return g_value_get_flags(&gobject_);
 }
 
+GParamSpec*
+ValueBase_Flags::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+      static_cast<Glib::ParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
 GParamSpec* ValueBase_Flags::create_param_spec(const Glib::ustring& name,
   const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags) const
 {
@@ -238,6 +266,13 @@ ValueBase_String::get_cstring() const
 }
 
 GParamSpec*
+ValueBase_String::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+      static_cast<Glib::ParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+GParamSpec*
 ValueBase_String::create_param_spec(const Glib::ustring& name,
   const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags) const
 {
index 8afc5bf..f236471 100644 (file)
@@ -27,8 +27,8 @@
 namespace Glib
 {
 
-class ObjectBase;
-class Object;
+class GLIBMM_API ObjectBase;
+class GLIBMM_API Object;
 
 /** @defgroup glibmmValue Generic Values
  *
@@ -49,7 +49,7 @@ class Object;
 /**
  * @ingroup glibmmValue
  */
-class ValueBase
+class GLIBMM_API ValueBase
 {
 public:
   /** Initializes the GValue, but without a type.  You have to
@@ -97,12 +97,13 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_Boxed : public ValueBase
+class GLIBMM_API ValueBase_Boxed : public ValueBase
 {
 public:
   static GType value_type() G_GNUC_CONST;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
 #endif
@@ -115,14 +116,16 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_Object : public ValueBase
+class GLIBMM_API ValueBase_Object : public ValueBase
 {
 public:
   static GType value_type() G_GNUC_CONST;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
+
 #endif
 
 protected:
@@ -134,14 +137,17 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_Enum : public ValueBase
+class GLIBMM_API ValueBase_Enum : public ValueBase
 {
 public:
+  using CType = gint;
   static GType value_type() G_GNUC_CONST;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
+
 #endif
 
 protected:
@@ -152,14 +158,17 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_Flags : public ValueBase
+class GLIBMM_API ValueBase_Flags : public ValueBase
 {
 public:
+  using CType = guint;
   static GType value_type() G_GNUC_CONST;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
+
 #endif
 
 protected:
@@ -170,14 +179,17 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_String : public ValueBase
+class GLIBMM_API ValueBase_String : public ValueBase
 {
 public:
+  using CType = const gchar*;
   static GType value_type() G_GNUC_CONST;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
+
 #endif
 
 protected:
@@ -188,7 +200,7 @@ protected:
 /**
  * @ingroup glibmmValue
  */
-class ValueBase_Variant : public ValueBase
+class GLIBMM_API ValueBase_Variant : public ValueBase
 {
 public:
   static GType value_type() G_GNUC_CONST;
@@ -224,11 +236,12 @@ class Value_Boxed : public ValueBase_Boxed
 // Used by _CLASS_BOXEDTYPE and _CLASS_BOXEDTYPE_STATIC
 public:
   using CppType = T;
+  using CType = typename T::BaseObjectType*;
 
   static GType value_type() { return T::get_type(); }
 
   void set(const CppType& data) { set_boxed(data.gobj()); }
-  CppType get() const { return CppType(static_cast<typename T::BaseObjectType*>(get_boxed())); }
+  CppType get() const { return CppType(static_cast<CType>(get_boxed())); }
 };
 
 /**
@@ -254,43 +267,20 @@ public:
 // More spec-compliant compilers (such as Tru64) need this to be near Glib::Object instead.
 #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
 
-namespace Traits {
-
-template<typename, typename>
-struct HasGetBaseType;
-
-template<typename T, typename Ret, typename... Args>
-struct HasGetBaseType<T, Ret(Args...)> {
-  template<typename U, U>
-   struct Check;
-
-  template<typename U>
-  static std::true_type
-  Test(Check<Ret(*)(Args...), &U::get_base_type>*);
-
-  template<typename U>
-  static std::false_type Test(...);
-
-  static const bool value = decltype(Test<T>(0))::value;
-  //using type = decltype(Test<T>(0));
-};
-
-} // namespace Traits
-
 /** Partial specialization for RefPtr<> to Glib::Object.
  * @ingroup glibmmValue
  */
 template <class T>
-class Value<Glib::RefPtr<T>, typename std::enable_if<Glib::Traits::HasGetBaseType<T, GType()>::value>::type>
-: public ValueBase_Object
+class Value<Glib::RefPtr<T>> : public ValueBase_Object
 {
 public:
   using CppType = Glib::RefPtr<T>;
+  using CType = typename T::BaseObjectType*;
 
   static GType value_type() { return T::get_base_type(); }
 
-  void set(const CppType& data) { set_object(const_cast<std::remove_const_t<T>*>(data.get())); }
-  CppType get() const { return std::dynamic_pointer_cast<T>(get_object_copy()); }
+  void set(const CppType& data) { set_object(data.operator->()); }
+  CppType get() const { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
 };
 
 // The SUN Forte Compiler has a problem with this:
@@ -299,19 +289,18 @@ public:
 /** Partial specialization for RefPtr<> to const Glib::Object.
  * @ingroup glibmmValue
  */
-/*
 template <class T>
-class Value<Glib::RefPtr<const T>, typename std::enable_if<std::is_base_of<Glib::ObjectBase, T>::value>::type> : public ValueBase_Object
+class Value<Glib::RefPtr<const T>> : public ValueBase_Object
 {
 public:
   using CppType = Glib::RefPtr<const T>;
+  using CType = typename T::BaseObjectType*;
 
   static GType value_type() { return T::get_base_type(); }
 
-  void set(const CppType& data) { set_object(const_cast<T*>(data.get())); }
-  CppType get() const { return std::dynamic_pointer_cast<T>(get_object_copy()); }
+  void set(const CppType& data) { set_object(const_cast<T*>(data.operator->())); }
+  CppType get() const { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
 };
-*/
 #endif // GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
 
 #endif // GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
@@ -331,7 +320,7 @@ namespace Glib
  * @ingroup glibmmValue
  */
 template <>
-class Value<std::string> : public ValueBase_String
+class GLIBMM_API Value<std::string> : public ValueBase_String
 {
 public:
   using CppType = std::string;
@@ -344,7 +333,7 @@ public:
  * @ingroup glibmmValue
  */
 template <>
-class Value<Glib::ustring> : public ValueBase_String
+class GLIBMM_API Value<Glib::ustring> : public ValueBase_String
 {
 public:
   using CppType = Glib::ustring;
@@ -357,7 +346,7 @@ public:
  * @ingroup glibmmValue
  */
 template <>
-class Value<std::vector<std::string>> : public ValueBase_Boxed
+class GLIBMM_API Value<std::vector<std::string>> : public ValueBase_Boxed
 {
 public:
   using CppType = std::vector<std::string>;
@@ -372,7 +361,7 @@ public:
  * @ingroup glibmmValue
  */
 template <>
-class Value<std::vector<Glib::ustring>> : public ValueBase_Boxed
+class GLIBMM_API Value<std::vector<Glib::ustring>> : public ValueBase_Boxed
 {
 public:
   using CppType = std::vector<Glib::ustring>;
@@ -392,7 +381,7 @@ class Value_Enum : public ValueBase_Enum
 public:
   using CppType = T;
 
-  void set(CppType data) { set_enum(static_cast<int>(data)); }
+  void set(CppType data) { set_enum(data); }
   CppType get() const { return CppType(get_enum()); }
 };
 
@@ -405,7 +394,7 @@ class Value_Flags : public ValueBase_Flags
 public:
   using CppType = T;
 
-  void set(CppType data) { set_flags(static_cast<unsigned int>(data)); }
+  void set(CppType data) { set_flags(data); }
   CppType get() const { return CppType(get_flags()); }
 };
 
index e5c1989..53da3db 100644 (file)
@@ -42,6 +42,8 @@ typedef void (*ValueCopyFunc)(const GValue*, GValue*);
  * as subtype of G_TYPE_BOXED, via this function.  The type_name argument
  * should be the C++ RTTI name.
  */
+
+GLIBMM_API
 GType custom_boxed_type_register(
   const char* type_name, ValueInitFunc init_func, ValueFreeFunc free_func, ValueCopyFunc copy_func);
 
@@ -49,6 +51,7 @@ GType custom_boxed_type_register(
  * each T* or const T* will be registered as a subtype of G_TYPE_POINTER,
  * via this function.  The type_name argument should be the C++ RTTI name.
  */
+GLIBMM_API
 GType custom_pointer_type_register(const char* type_name);
 
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
@@ -56,12 +59,12 @@ GType custom_pointer_type_register(const char* type_name);
 /**
  * @ingroup glibmmValue
  */
-template <class PtrT>
+template <class T, class PtrT>
 class Value_Pointer : public ValueBase_Object
 {
 public:
-  using T = std::remove_cv_t<std::remove_pointer_t<PtrT>>;
   using CppType = PtrT;
+  using CType = void*;
 
   static inline GType value_type() G_GNUC_CONST;
 
@@ -95,15 +98,12 @@ private:
  * cannot ensure that no exceptions will be thrown, consider using either
  * a normal pointer or a smart pointer to hold your objects indirectly.
  */
-template <class T, typename Enable = void>
+template <class T>
 class Value : public ValueBase_Boxed
 {
 public:
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-  // Used in class Glib::Traits::ValueCompatibleWithWrapProperty.
-  using dont_use_with_wrap_property_ = int;
-#endif
   using CppType = T;
+  using CType = T*;
 
   static GType value_type() G_GNUC_CONST;
 
@@ -123,8 +123,8 @@ private:
  * No attempt is made to manage the memory associated with the
  * pointer, you must take care of that yourself.
  */
-template <class T, typename Enable>
-class Value<T*, Enable> : public Value_Pointer<T*>
+template <class T>
+class Value<T*> : public Value_Pointer<T, T*>
 {
 };
 
@@ -133,37 +133,37 @@ class Value<T*, Enable> : public Value_Pointer<T*>
  * No attempt is made to manage the memory associated with the
  * pointer, you must take care of that yourself.
  */
-template <class T, typename Enable>
-class Value<const T*, Enable> : public Value_Pointer<const T*>
+template <class T>
+class Value<const T*> : public Value_Pointer<T, const T*>
 {
 };
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-/**** Glib::Value_Pointer<PtrT> *****************************************/
+/**** Glib::Value_Pointer<T, PtrT> *****************************************/
 
 /** Implementation for Glib::Object pointers **/
 
 // static
-template <class PtrT>
+template <class T, class PtrT>
 inline GType
-Value_Pointer<PtrT>::value_type_(Glib::Object*)
+Value_Pointer<T, PtrT>::value_type_(Glib::Object*)
 {
   return T::get_base_type();
 }
 
-template <class PtrT>
+template <class T, class PtrT>
 inline void
-Value_Pointer<PtrT>::set_(PtrT data, Glib::Object*)
+Value_Pointer<T, PtrT>::set_(PtrT data, Glib::Object*)
 {
   set_object(const_cast<T*>(data));
 }
 
 // More spec-compliant compilers (such as Tru64) need this to be near Glib::Object instead.
 #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
-template <class PtrT>
+template <class T, class PtrT>
 inline PtrT
-Value_Pointer<PtrT>::get_(Glib::Object*) const
+Value_Pointer<T, PtrT>::get_(Glib::Object*) const
 {
   return dynamic_cast<T*>(get_object());
 }
@@ -172,9 +172,9 @@ Value_Pointer<PtrT>::get_(Glib::Object*) const
 /** Implementation for custom pointers **/
 
 // static
-template <class PtrT>
+template <class T, class PtrT>
 GType
-Value_Pointer<PtrT>::value_type_(void*)
+Value_Pointer<T, PtrT>::value_type_(void*)
 {
   static GType custom_type = 0;
 
@@ -184,16 +184,16 @@ Value_Pointer<PtrT>::value_type_(void*)
   return custom_type;
 }
 
-template <class PtrT>
+template <class T, class PtrT>
 inline void
-Value_Pointer<PtrT>::set_(PtrT data, void*)
+Value_Pointer<T, PtrT>::set_(PtrT data, void*)
 {
   gobject_.data[0].v_pointer = const_cast<T*>(data);
 }
 
-template <class PtrT>
+template <class T, class PtrT>
 inline PtrT
-Value_Pointer<PtrT>::get_(void*) const
+Value_Pointer<T, PtrT>::get_(void*) const
 {
   return static_cast<T*>(gobject_.data[0].v_pointer);
 }
@@ -201,25 +201,25 @@ Value_Pointer<PtrT>::get_(void*) const
 /** Public forwarding interface **/
 
 // static
-template <class PtrT>
+template <class T, class PtrT>
 inline GType
-Value_Pointer<PtrT>::value_type()
+Value_Pointer<T, PtrT>::value_type()
 {
   // Dispatch to the specific value_type_() overload.
-  return Value_Pointer<PtrT>::value_type_(static_cast<T*>(nullptr));
+  return Value_Pointer<T, PtrT>::value_type_(static_cast<T*>(nullptr));
 }
 
-template <class PtrT>
+template <class T, class PtrT>
 inline void
-Value_Pointer<PtrT>::set(PtrT data)
+Value_Pointer<T, PtrT>::set(PtrT data)
 {
   // Dispatch to the specific set_() overload.
   this->set_(data, static_cast<T*>(nullptr));
 }
 
-template <class PtrT>
+template <class T, class PtrT>
 inline PtrT
-Value_Pointer<PtrT>::get() const
+Value_Pointer<T, PtrT>::get() const
 {
   // Dispatch to the specific get_() overload.
   return this->get_(static_cast<T*>(nullptr));
@@ -228,29 +228,29 @@ Value_Pointer<PtrT>::get() const
 /**** Glib::Value<T> *******************************************************/
 
 // Static data, specific to each template instantiation.
-template <class T, typename Enable>
-GType Value<T, Enable>::custom_type_ = 0;
+template <class T>
+GType Value<T>::custom_type_ = 0;
 
-template <class T, typename Enable>
+template <class T>
 inline void
-Value<T, Enable>::set(const typename Value<T, Enable>::CppType& data)
+Value<T>::set(const typename Value<T>::CppType& data)
 {
   // Assume the value is already default-initialized.  See value_init_func().
   *static_cast<T*>(gobject_.data[0].v_pointer) = data;
 }
 
-template <class T, typename Enable>
-inline typename Value<T, Enable>::CppType
-Value<T, Enable>::get() const
+template <class T>
+inline typename Value<T>::CppType
+Value<T>::get() const
 {
   // Assume the pointer is not NULL.  See value_init_func().
   return *static_cast<T*>(gobject_.data[0].v_pointer);
 }
 
 // static
-template <class T, typename Enable>
+template <class T>
 GType
-Value<T, Enable>::value_type()
+Value<T>::value_type()
 {
   if (!custom_type_)
   {
@@ -261,63 +261,32 @@ Value<T, Enable>::value_type()
 }
 
 // static
-template <class T, typename Enable>
+template <class T>
 void
-Value<T, Enable>::value_init_func(GValue* value)
+Value<T>::value_init_func(GValue* value)
 {
   // Never store a NULL pointer (unless we're out of memory).
   value->data[0].v_pointer = new (std::nothrow) T();
 }
 
 // static
-template <class T, typename Enable>
+template <class T>
 void
-Value<T, Enable>::value_free_func(GValue* value)
+Value<T>::value_free_func(GValue* value)
 {
   delete static_cast<T*>(value->data[0].v_pointer);
 }
 
 // static
-template <class T, typename Enable>
+template <class T>
 void
-Value<T, Enable>::value_copy_func(const GValue* src_value, GValue* dest_value)
+Value<T>::value_copy_func(const GValue* src_value, GValue* dest_value)
 {
   // Assume the source is not NULL.  See value_init_func().
   const T& source = *static_cast<T*>(src_value->data[0].v_pointer);
   dest_value->data[0].v_pointer = new (std::nothrow) T(source);
 }
 
-namespace Traits
-{
-/** Helper class for testing if Glib::Value<T> would instantiate a Glib::Value
- * that can be used in _WRAP_PROPERTY and _WRAP_CHILD_PROPERTY.
- *
- * Some instantiations of Glib::Value, such as instantiations of the primary
- * template, generate code which is useless but compilable when generated by
- * _WRAP_PROPERTY and _WRAP_CHILD_PROPERTY.
- */
-template <typename T>
-class ValueCompatibleWithWrapProperty
-{
-private:
-  struct big
-  {
-    int memory[64];
-  };
-
-  static big check_type(...);
-
-  // If Glib::Value<X>::dont_use_with_wrap_property_ is not a type, this check_type()
-  // overload is ignored because of the SFINAE rule (Substitution Failure Is Not An Error).
-  template <typename X>
-  static typename Glib::Value<X>::dont_use_with_wrap_property_ check_type(X* obj);
-
-public:
-  static const bool value = sizeof(check_type(static_cast<T*>(nullptr))) == sizeof(big);
-};
-
-} // namespace Traits
-
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 } // namespace Glib
index f6a6e75..ced63b8 100644 (file)
@@ -36,7 +36,7 @@ namespace Glib
  * @newin{2,54}
  * @ingroup Variant
 */
-class DBusObjectPathString : public Glib::ustring
+class GLIBMM_API DBusObjectPathString : public Glib::ustring
 {
 public:
   using Glib::ustring::ustring;
@@ -53,7 +53,7 @@ public:
  * @newin{2,54}
  * @ingroup Variant
 */
-class DBusSignatureString : public Glib::ustring
+class GLIBMM_API DBusSignatureString : public Glib::ustring
 {
 public:
   using Glib::ustring::ustring;
index f68903d..7339ef0 100644 (file)
@@ -110,6 +110,7 @@ create_array(typename std::vector<typename Tr::CppType>::const_iterator pbegin,
 /* first class function for bools, because std::vector<bool> is a specialization
  * which does not conform to being an STL container.
  */
+GLIBMM_API
 gboolean* create_bool_array(std::vector<bool>::const_iterator pbegin, std::size_t size);
 
 /* Create and fill a GList as efficient as possible.
@@ -479,7 +480,7 @@ public:
 };
 
 template <>
-class ArrayHandler<bool>
+class GLIBMM_API ArrayHandler<bool>
 {
 public:
   using CType = gboolean;
diff --git a/glib/glibmm/weakref.h b/glib/glibmm/weakref.h
new file mode 100644 (file)
index 0000000..f4226cf
--- /dev/null
@@ -0,0 +1,465 @@
+#ifndef _GLIBMM_WEAKREF_H
+#define _GLIBMM_WEAKREF_H
+
+/* Copyright (C) 2015 The glibmm 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib-object.h>
+#include <glibmm/refptr.h>
+#include <glibmm/objectbase.h>
+#include <type_traits> // std::is_base_of<>
+#include <utility> // std::swap<>, std::forward<>
+
+namespace Glib
+{
+
+/** WeakRef<> is a weak reference smartpointer.
+ *
+ * WeakRef can store a pointer to any class that is derived from Glib::ObjectBase,
+ * and whose reference() method is noexcept.
+ * In glibmm and gtkmm, that is anything derived from Glib::ObjectBase.
+ *
+ * Unlike a RefPtr, a WeakRef does not contribute to the reference counting of
+ * the underlying object.
+ *
+ * @newin{2,46}
+ */
+template <typename T_CppObject>
+class WeakRef
+{
+  static_assert(std::is_base_of<Glib::ObjectBase, T_CppObject>::value,
+    "Glib::WeakRef can be used only for classes derived from Glib::ObjectBase.");
+
+public:
+  /** Default constructor.
+   *
+   * Create an empty weak reference.
+   */
+  inline WeakRef() noexcept;
+
+  /// Copy constructor.
+  inline WeakRef(const WeakRef& src) noexcept;
+
+  /// Move constructor.
+  inline WeakRef(WeakRef&& src) noexcept;
+
+  /// Copy constructor from different, but castable type.
+  template <typename T_CastFrom>
+  inline WeakRef(const WeakRef<T_CastFrom>& src) noexcept;
+
+  /// Move constructor from different, but castable type.
+  template <typename T_CastFrom>
+  inline WeakRef(WeakRef<T_CastFrom>&& src) noexcept;
+
+  /** Constructor from a RefPtr of the same or a castable type.
+   *
+   * Create a weak reference from a RefPtr of the same or a castable type.
+   * If the RefPtr references nothing, an empty weak reference will be constructed.
+   */
+  template <typename T_CastFrom>
+  inline WeakRef(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /// Destructor.
+  inline ~WeakRef() noexcept;
+
+  /// Swap the contents of two WeakRef<>.
+  inline void swap(WeakRef& other) noexcept;
+
+  /// Copy assignment operator.
+  inline WeakRef& operator=(const WeakRef& src) noexcept;
+
+  /// Move assignment operator.
+  inline WeakRef& operator=(WeakRef&& src) noexcept;
+
+  /// Copy assignment from different, but castable type.
+  template <typename T_CastFrom>
+  inline WeakRef& operator=(const WeakRef<T_CastFrom>& src) noexcept;
+
+  /// Move assignment from different, but castable type.
+  template <typename T_CastFrom>
+  inline WeakRef& operator=(WeakRef<T_CastFrom>&& src) noexcept;
+
+  /// Assignment from a RefPtr of the same or a castable type.
+  template <typename T_CastFrom>
+  inline WeakRef& operator=(const RefPtr<T_CastFrom>& src) noexcept;
+
+  /** Test whether the WeakRef<> points to any underlying instance.
+   *
+   * Mimics usage of ordinary pointers:
+   * @code
+   * if (ptr)
+   *   do_something();
+   * @endcode
+   *
+   * In a multi-threaded program a <tt>true</tt> return value can become
+   * obsolete at any time, even before the caller has a chance to test it,
+   * because the underlying instance may lose its last reference in another
+   * thread. Use get() if this is not acceptable.
+   */
+  inline explicit operator bool() const noexcept;
+
+  /** Create a strong reference to the underlying object.
+   *
+   * This is a thread-safe way to acquire a strong reference to the underlying
+   * object. If the WeakRef is empty, the returned RefPtr will reference nothing.
+   */
+  inline RefPtr<T_CppObject> get() const noexcept;
+
+  /// Make this WeakRef empty.
+  inline void reset() noexcept;
+
+  /** Dynamic cast to derived class.
+   *
+   * The WeakRef can't be cast with the usual notation so instead you can use
+   * @code
+   * ptr_derived = Glib::WeakRef<Derived>::cast_dynamic(ptr_base);
+   * @endcode
+   */
+  template <typename T_CastFrom>
+  static inline WeakRef cast_dynamic(const WeakRef<T_CastFrom>& src) noexcept;
+
+  /** Static cast to derived class.
+   *
+   * The WeakRef can't be cast with the usual notation so instead you can use
+   * @code
+   * ptr_derived = Glib::WeakRef<Derived>::cast_static(ptr_base);
+   * @endcode
+   */
+  template <typename T_CastFrom>
+  static inline WeakRef cast_static(const WeakRef<T_CastFrom>& src) noexcept;
+
+  /** Cast to non-const.
+   *
+   * The WeakRef can't be cast with the usual notation so instead you can use
+   * @code
+   * ptr_nonconst = Glib::WeakRef<NonConstType>::cast_const(ptr_const);
+   * @endcode
+   */
+  template <typename T_CastFrom>
+  static inline WeakRef cast_const(const WeakRef<T_CastFrom>& src) noexcept;
+
+private:
+  // Let all instantiations of WeakRef access private data.
+  template <typename T_CastFrom>
+  friend class WeakRef;
+
+  // If pCppObject != nullptr && gobject == nullptr,
+  // then the caller holds a strong reference.
+  void set(T_CppObject* pCppObject, GWeakRef* gobject) noexcept;
+
+  // WeakRef owns *gobject_, but it does not own *pCppObject_.
+  // Invariant: (!pCppObject_ || gobject_),
+  // i.e. if pCppObject_ != nullptr then also gobject_ != nullptr.
+  T_CppObject* pCppObject_;
+  GWeakRef* gobject_;
+
+  // Some methods would be simpler if gobject_ were a GWeakRef instead of
+  // a GWeakRef*, but then the move constructor and the move assignment
+  // operation would not be efficient.
+
+}; // end class WeakRef
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>::WeakRef() noexcept : pCppObject_(nullptr), gobject_(nullptr)
+{
+}
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>::WeakRef(const WeakRef& src) noexcept : pCppObject_(src.pCppObject_),
+                                                             gobject_(nullptr)
+{
+  if (pCppObject_)
+  {
+    // We must own a strong reference to the underlying GObject while
+    // calling g_weak_ref_init().
+    gpointer ptr = g_weak_ref_get(src.gobject_);
+    if (ptr)
+    {
+      gobject_ = new GWeakRef;
+      g_weak_ref_init(gobject_, pCppObject_->gobj());
+      g_object_unref(ptr);
+    }
+    else
+      pCppObject_ = nullptr;
+  }
+}
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>::WeakRef(WeakRef&& src) noexcept : pCppObject_(src.pCppObject_),
+                                                        gobject_(src.gobject_)
+{
+  src.pCppObject_ = nullptr;
+  src.gobject_ = nullptr;
+}
+
+// The templated ctor allows copy construction from any object that's
+// castable. Thus, it does downcasts:
+//   base_ref = derived_ref
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>::WeakRef(const WeakRef<T_CastFrom>& src) noexcept
+  : pCppObject_(src.pCppObject_),
+    gobject_(nullptr)
+{
+  if (pCppObject_)
+  {
+    // We must own a strong reference to the underlying GObject while
+    // calling g_weak_ref_init().
+    gpointer ptr = g_weak_ref_get(src.gobject_);
+    if (ptr)
+    {
+      gobject_ = new GWeakRef;
+      g_weak_ref_init(gobject_, pCppObject_->gobj());
+      g_object_unref(ptr);
+    }
+    else
+      pCppObject_ = nullptr;
+  }
+}
+
+// The templated ctor allows move construction from any object that's
+// castable. Thus, it does downcasts:
+//   base_ref = std::move(derived_ref)
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>::WeakRef(WeakRef<T_CastFrom>&& src) noexcept : pCppObject_(src.pCppObject_),
+                                                                    gobject_(src.gobject_)
+{
+  src.pCppObject_ = nullptr;
+  src.gobject_ = nullptr;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>::WeakRef(const RefPtr<T_CastFrom>& src) noexcept
+  : pCppObject_(src.operator->()),
+    gobject_(nullptr)
+{
+  if (pCppObject_)
+  {
+    gobject_ = new GWeakRef;
+    g_weak_ref_init(gobject_, pCppObject_->gobj());
+  }
+}
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>::~WeakRef() noexcept
+{
+  if (gobject_)
+  {
+    g_weak_ref_clear(gobject_);
+    delete gobject_;
+  }
+}
+
+template <class T_CppObject>
+void
+WeakRef<T_CppObject>::swap(WeakRef& other) noexcept
+{
+  std::swap(pCppObject_, other.pCppObject_);
+  std::swap(gobject_, other.gobject_);
+}
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>&
+WeakRef<T_CppObject>::operator=(const WeakRef& src) noexcept
+{
+  set(src.pCppObject_, src.gobject_);
+  return *this;
+}
+
+template <typename T_CppObject>
+WeakRef<T_CppObject>&
+WeakRef<T_CppObject>::operator=(WeakRef&& src) noexcept
+{
+  // See RefPtr for an explanation of the swap() technique to implement
+  // copy assignment and move assignment.
+  // This technique is inefficient for copy assignment of WeakRef,
+  // because it involves copy construction + destruction, i.e. in a typical
+  // case g_weak_ref_init() + g_weak_ref_clear(), when a g_weak_ref_set()
+  // would be enough. For move assignment, the swap technique is fine.
+  WeakRef<T_CppObject> temp(std::forward<WeakRef<T_CppObject>>(src));
+  this->swap(temp);
+  return *this;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>&
+WeakRef<T_CppObject>::operator=(const WeakRef<T_CastFrom>& src) noexcept
+{
+  set(src.pCppObject_, src.gobject_);
+  return *this;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>&
+WeakRef<T_CppObject>::operator=(WeakRef<T_CastFrom>&& src) noexcept
+{
+  WeakRef<T_CppObject> temp(std::forward<WeakRef<T_CastFrom>>(src));
+  this->swap(temp);
+  return *this;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>&
+WeakRef<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src) noexcept
+{
+  T_CppObject* pCppObject = src.operator->();
+  set(pCppObject, nullptr);
+  return *this;
+}
+
+template <class T_CppObject>
+WeakRef<T_CppObject>::operator bool() const noexcept
+{
+  if (!pCppObject_)
+    return false;
+
+  gpointer ptr = g_weak_ref_get(gobject_);
+  if (!ptr)
+    return false;
+
+  g_object_unref(ptr);
+  return true;
+}
+
+template <typename T_CppObject>
+RefPtr<T_CppObject>
+WeakRef<T_CppObject>::get() const noexcept
+{
+  RefPtr<T_CppObject> ret;
+
+  if (!pCppObject_)
+    return ret;
+
+  gpointer ptr = g_weak_ref_get(gobject_);
+  if (!ptr)
+    return ret;
+
+  // A RefPtr constructed from pointer expects reference to be done externally.
+  pCppObject_->reference();
+  ret = RefPtr<T_CppObject>(pCppObject_);
+
+  g_object_unref(ptr);
+
+  return ret;
+}
+
+template <typename T_CppObject>
+void
+WeakRef<T_CppObject>::reset() noexcept
+{
+  set(nullptr, nullptr);
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>
+WeakRef<T_CppObject>::cast_dynamic(const WeakRef<T_CastFrom>& src) noexcept
+{
+  WeakRef<T_CppObject> ret;
+
+  if (!src.pCppObject_)
+    return ret;
+
+  gpointer ptr = g_weak_ref_get(src.gobject_);
+  if (!ptr)
+    return ret;
+
+  // Don't call dynamic_cast<>() unless we know that the referenced object
+  // still exists.
+  T_CppObject* const pCppObject = dynamic_cast<T_CppObject*>(src.pCppObject_);
+  ret.set(pCppObject, nullptr);
+  g_object_unref(ptr);
+
+  return ret;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>
+WeakRef<T_CppObject>::cast_static(const WeakRef<T_CastFrom>& src) noexcept
+{
+  T_CppObject* const pCppObject = static_cast<T_CppObject*>(src.pCppObject_);
+
+  WeakRef<T_CppObject> ret;
+  ret.set(pCppObject, src.gobject_);
+  return ret;
+}
+
+template <typename T_CppObject>
+template <typename T_CastFrom>
+WeakRef<T_CppObject>
+WeakRef<T_CppObject>::cast_const(const WeakRef<T_CastFrom>& src) noexcept
+{
+  T_CppObject* const pCppObject = const_cast<T_CppObject*>(src.pCppObject_);
+
+  WeakRef<T_CppObject> ret;
+  ret.set(pCppObject, src.gobject_);
+  return ret;
+}
+
+template <typename T_CppObject>
+void
+WeakRef<T_CppObject>::set(T_CppObject* pCppObject, GWeakRef* gobject) noexcept
+{
+  // We must own a strong reference to the underlying GObject while
+  // calling g_weak_ref_init() or g_weak_ref_set().
+  // If pCppObject != nullptr && gobject == nullptr,
+  // then the caller holds a strong reference.
+
+  // An aim with this moderately complicated method is to keep the same
+  // GWeakRef, calling g_weak_ref_set() when possible, instead of using swap(),
+  // which implies creating a new WeakRef, swapping with *this, and deleting
+  // the new WeakRef.
+
+  gpointer ptr = nullptr;
+  if (pCppObject && gobject)
+    ptr = g_weak_ref_get(gobject);
+
+  pCppObject_ = (ptr || !gobject) ? pCppObject : nullptr;
+  if (pCppObject_ && !gobject_)
+  {
+    gobject_ = new GWeakRef;
+    g_weak_ref_init(gobject_, pCppObject_->gobj());
+  }
+  else if (gobject_)
+    g_weak_ref_set(gobject_, pCppObject_ ? pCppObject_->gobj() : nullptr);
+
+  if (ptr)
+    g_object_unref(ptr);
+}
+
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+/** Swap the contents of two WeakRef<>.
+ * @relates Glib::WeakRef
+ */
+template <class T_CppObject>
+inline void
+swap(WeakRef<T_CppObject>& lhs, WeakRef<T_CppObject>& rhs) noexcept
+{
+  lhs.swap(rhs);
+}
+
+} // namespace Glib
+
+#endif // _GLIBMM_WEAKREF_H
index 08f0309..3e78c3b 100644 (file)
@@ -212,7 +212,7 @@ wrap_auto(GObject* object, bool take_copy)
 Glib::RefPtr<Object>
 wrap(GObject* object, bool take_copy /* = false */)
 {
-  return Glib::make_refptr_for_instance<Object>(dynamic_cast<Object*>(wrap_auto(object, take_copy)));
+  return Glib::RefPtr<Object>(dynamic_cast<Object*>(wrap_auto(object, take_copy)));
 }
 
 } /* namespace Glib */
index dfa4c96..0b54a7e 100644 (file)
@@ -26,22 +26,27 @@ namespace Glib
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-class ObjectBase;
-class Object;
+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
@@ -50,6 +55,7 @@ Glib::ObjectBase* wrap_auto(GObject* object, bool take_copy = false);
  * @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,
@@ -107,6 +113,7 @@ wrap_auto_interface(GObject* object, bool take_copy = false)
 // use take_copy = true when wrapping a struct member.
 // TODO: move to object.h ?
 /** @relates Glib::Object */
+GLIBMM_API
 Glib::RefPtr<Glib::Object> wrap(GObject* object, bool take_copy = false);
 
 /** Get the underlying C instance from the C++ instance.  This is just
index df27023..950816f 100644 (file)
@@ -24,6 +24,7 @@
 namespace Glib
 {
 
+GLIBMM_API
 void wrap_init();
 
 } // namespace Glib
index 56e7a42..ef82084 100644 (file)
    type. */
 #undef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
 
+/* Define if the compiler honors namespaces inside extern "C" blocks. */
+#undef GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC
+
+/* Defined when the SUN Forte C++ compiler is being used. */
+#undef GLIBMM_COMPILER_SUN_FORTE
+
 /* Defined when the --enable-debug-refcounting configure argument was given */
 #undef GLIBMM_DEBUG_REFCOUNTING
 
+/* This is always set. This is only for backwards compatibility. */
+#undef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
+
 /* Define to omit deprecated API from the library. */
 #undef GLIBMM_DISABLE_DEPRECATED
 
+/* This is always set. This is only for backwards compatibility. */
+#undef GLIBMM_EXCEPTIONS_ENABLED
+
+/* This is always set. This is only for backwards compatibility. */
+#undef GLIBMM_VFUNCS_ENABLED
+
 /* Defined if a static member variable may be initialized inline to
    std::string::npos */
 #undef GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS
 
+/* Defined when time_t is not equivalent to gint32, meaning that it can be
+   used for a method overload */
+#undef GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+
 /* Define if the compiler disambiguates template specializations for const and
    non-const types. */
 #undef GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
 
+/* Defined when the libstdc++ declares the std-namespace */
+#undef GLIBMM_HAVE_NAMESPACE_STD
+
 /* Defined if std::iterator_traits<> is standard-conforming */
 #undef GLIBMM_HAVE_STD_ITERATOR_TRAITS
 
 /* Major version number of glibmm. */
 #undef GLIBMM_MAJOR_VERSION
 
+/* Define if C++ member functions may refer to member templates. */
+#undef GLIBMM_MEMBER_FUNCTIONS_MEMBER_TEMPLATES
+
 /* Micro version number of glibmm. */
 #undef GLIBMM_MICRO_VERSION
 
 /* Minor version number of glibmm. */
 #undef GLIBMM_MINOR_VERSION
 
+/* This is always set. This is only for backwards compatibility. */
+#undef GLIBMM_PROPERTIES_ENABLED
+
 /* Define if glibmm is built as a static library */
 #undef GLIBMM_STATIC_LIB
 
+/* Define if the thread_local keyword is supported. */
+#undef GLIBMM_CAN_USE_THREAD_LOCAL
 
 #endif /* GLIBMM_CONFIGURE */
 
 # define GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS 2
 # define GLIBMM_HAVE_WIDE_STREAM 1
 # define GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS 1
+# define GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32 1
 # define GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION 1
 # define GLIBMM_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS 1
+# define GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC 1
+# define GLIBMM_CAN_USE_THREAD_LOCAL 1
+# define GLIBMM_PROPERTIES_ENABLED 1
+# define GLIBMM_VFUNCS_ENABLED 1
+# define GLIBMM_EXCEPTIONS_ENABLED 1
+# define GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED 1
 # pragma warning (disable: 4786 4355 4800 4181)
 
-#if (_MSC_VER < 1900)
-/* The C++-11 keywords noexcept and thread_local are supported on
- * Visual Studio 2013 via Microsoft-specific extensions, but are
- * supported directly in Visual Studio 2015
- */
-
-#define _ALLOW_KEYWORD_MACROS 1
-
-#ifndef noexcept
-#define noexcept _NOEXCEPT
-#endif
-
-#ifndef thread_local
-#define thread_local __declspec (thread)
+/* We have GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS for Visual Studio 2017+ */
+#if (_MSC_VER >= 1910)
+#define GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS 1
 #endif
 
-#endif /* _MSC_VER < 1900 */
 #endif /* GLIBMM_MSC */
 
+/* Dummy macro definition for compatibility with old code that expects
+ * it to be defined.  Remove after grace period. */
+#define GLIBMM_USING_STD(Symbol)
+
 /* Enable DLL-specific stuff only when not building a static library */
 #if !defined(__CYGWIN__) && defined(__MINGW32__) && !defined(GLIBMM_STATIC_LIB)
 # define GLIBMM_DLL 1
 #endif
 
 #ifdef GLIBMM_DLL
-# if defined(GLIBMM_BUILD) && defined(_WINDLL)
-   /* Do not dllexport as it is handled by gendef on MSVC */
-#  define GLIBMM_API
-# elif !defined(GLIBMM_BUILD)
-#  define GLIBMM_API __declspec(dllimport)
+# if defined(GLIBMM_BUILD)
+#  define GLIBMM_API __declspec(dllexport)
 # else
-   /* Build a static library */
-#  define GLIBMM_API
+#  define GLIBMM_API __declspec(dllimport)
 # endif /* GLIBMM_BUILD - _WINDLL */
 #else
+/* Build a static library or a non-native-Windows library */
 # define GLIBMM_API
 #endif /* GLIBMM_DLL */
 
diff --git a/glib/glibmmconfig.h.meson b/glib/glibmmconfig.h.meson
new file mode 100644 (file)
index 0000000..6fff505
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef _GLIBMM_CONFIG_H
+#define _GLIBMM_CONFIG_H
+
+/* Define to omit deprecated API from the library. */
+#mesondefine GLIBMM_DISABLE_DEPRECATED
+
+/* Major version number of glibmm. */
+#mesondefine GLIBMM_MAJOR_VERSION
+
+/* Minor version number of glibmm. */
+#mesondefine GLIBMM_MINOR_VERSION
+
+/* Micro version number of glibmm. */
+#mesondefine GLIBMM_MICRO_VERSION
+
+/* Define if glibmm is built as a static library */
+#mesondefine GLIBMM_STATIC_LIB
+
+/* The size of wchar_t, as computed by sizeof. */
+#mesondefine GLIBMM_SIZEOF_WCHAR_T
+
+/* Defined when the -Ddebug-refcounting configure argument was given */
+#mesondefine GLIBMM_DEBUG_REFCOUNTING
+
+/* This is always set. This is only for backwards compatibility. */
+#define GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED 1
+
+/* This is always set. This is only for backwards compatibility. */
+#define GLIBMM_EXCEPTIONS_ENABLED 1
+
+/* This is always set. This is only for backwards compatibility. */
+#define GLIBMM_VFUNCS_ENABLED 1
+
+/* This is always set. This is only for backwards compatibility. */
+#define GLIBMM_PROPERTIES_ENABLED 1
+
+/* This is always set. This is only for backwards compatibility.
+ * All acceptable C++ compilers have namespace std. */
+#define GLIBMM_HAVE_NAMESPACE_STD 1
+
+/* Dummy macro definition for compatibility with old code that expects
+ * it to be defined. */
+#define GLIBMM_USING_STD(Symbol)
+
+#ifdef _WIN32
+  /* Win32 compilers have a lot of varation */
+# if defined(_MSC_VER)
+#  define GLIBMM_MSC 1
+#  define GLIBMM_WIN32 1
+#  define GLIBMM_DLL 1
+# elif defined(__CYGWIN__)
+#  define GLIBMM_CONFIGURE 1
+# elif defined(__MINGW32__)
+#  define GLIBMM_WIN32 1
+#  define GLIBMM_CONFIGURE 1
+# else
+   /* AIX clR compiler complains about this even though it doesn't get this far */
+#  error "Unknown architecture (send me gcc --dumpspecs or equiv)"
+# endif
+#else
+# define GLIBMM_CONFIGURE 1
+#endif /* _WIN32 */
+
+#ifdef GLIBMM_CONFIGURE
+
+/* Define only on Mac OS, COCOA */
+#mesondefine GLIBMM_OS_COCOA
+
+/* Define if extern "C" and extern "C++" function pointers are compatible. */
+#mesondefine GLIBMM_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS
+
+/* Define if non-instantiated templates may dynamic_cast<> to an undefined
+   type. */
+#mesondefine GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
+
+/* Define if the compiler honors namespaces inside extern "C" blocks. */
+#mesondefine GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC
+
+/* Defined when the SUN Forte C++ compiler is being used. */
+#mesondefine GLIBMM_COMPILER_SUN_FORTE
+
+/* Defined if a static member variable may be initialized inline to
+   std::string::npos */
+#mesondefine GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS
+
+/* Defined when time_t is not equivalent to gint32, meaning that it can be
+   used for a method overload */
+#mesondefine GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+
+/* Define if the compiler disambiguates template specializations for const and
+   non-const types. */
+#mesondefine GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
+
+/* Defined if std::iterator_traits<> is standard-conforming */
+#mesondefine GLIBMM_HAVE_STD_ITERATOR_TRAITS
+
+/* Defined if std::reverse_iterator is in Sun libCstd style */
+#mesondefine GLIBMM_HAVE_SUN_REVERSE_ITERATOR
+
+/* Defined if the STL containers have templated sequence ctors */
+#mesondefine GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+
+/* Define to 1 if wide stream is available. */
+#mesondefine GLIBMM_HAVE_WIDE_STREAM
+
+/* Define if C++ member functions may refer to member templates. */
+#mesondefine GLIBMM_MEMBER_FUNCTIONS_MEMBER_TEMPLATES
+
+/* Define if the thread_local keyword is supported. */
+#mesondefine GLIBMM_CAN_USE_THREAD_LOCAL
+
+#endif /* GLIBMM_CONFIGURE */
+
+#ifdef GLIBMM_MSC
+# define GLIBMM_HAVE_STD_ITERATOR_TRAITS 1
+# define GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS 1
+# define GLIBMM_HAVE_WIDE_STREAM 1
+# define GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS 1
+# define GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32 1
+# define GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION 1
+# define GLIBMM_CAN_USE_THREAD_LOCAL 1
+# define GLIBMM_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS 1
+# define GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC 1
+# pragma warning (disable: 4786 4355 4800 4181)
+
+/* We have GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS for Visual Studio 2017+ */
+#if (_MSC_VER >= 1910)
+#define GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS 1
+#endif
+
+#endif /* GLIBMM_MSC */
+
+/* Enable DLL-specific stuff only when not building a static library */
+#if !defined(__CYGWIN__) && defined(__MINGW32__) && !defined(GLIBMM_STATIC_LIB)
+# define GLIBMM_DLL 1
+#endif
+
+#ifdef GLIBMM_DLL
+# if defined(GLIBMM_BUILD)
+#  define GLIBMM_API __declspec(dllexport)
+# else
+#  define GLIBMM_API __declspec(dllimport)
+# endif /* GLIBMM_BUILD - _WINDLL */
+#else
+/* Build a static library or a non-native-Windows library */
+# define GLIBMM_API
+#endif /* GLIBMM_DLL */
+
+#endif /* _GLIBMM_CONFIG_H */
diff --git a/glib/meson.build b/glib/meson.build
new file mode 100644 (file)
index 0000000..99c4377
--- /dev/null
@@ -0,0 +1,130 @@
+# glib
+
+# Input: install_prefix, install_libdir, install_datadir, install_includedir,
+#        glibmm_pcname, giomm_pcname, glibmm_api_version, glibmm_requires,
+#        giomm_requires, build_deprecated_api, install_pkgconfigdir,
+#        is_os_cocoa, cpp_compiler, glibmm_major_version, glibmm_minor_version,
+#        glibmm_micro_version
+# Output: pkg_conf_data, install_glibmmconfigdir, glibmmconfig_h
+
+pkg_conf_data = configuration_data()
+pkg_conf_data.set('prefix', install_prefix)
+pkg_conf_data.set('exec_prefix', '${prefix}')
+pkg_conf_data.set('libdir', '${exec_prefix}' / install_libdir)
+pkg_conf_data.set('datarootdir', '${prefix}' / install_datadir)
+pkg_conf_data.set('datadir', '${datarootdir}')
+pkg_conf_data.set('includedir', '${prefix}' / install_includedir)
+pkg_conf_data.set('PACKAGE_TARNAME', meson.project_name())
+pkg_conf_data.set('PACKAGE_VERSION', meson.project_version())
+pkg_conf_data.set('GLIBMM_MODULE_NAME', glibmm_pcname)
+pkg_conf_data.set('GLIBMM_API_VERSION', glibmm_api_version)
+pkg_conf_data.set('GLIBMM_MODULES', glibmm_requires)
+pkg_conf_data.set('GIOMM_MODULE_NAME', giomm_pcname)
+pkg_conf_data.set('GIOMM_API_VERSION', glibmm_api_version)
+pkg_conf_data.set('GIOMM_MODULES', giomm_requires)
+if not build_deprecated_api
+  pkg_conf_data.set('GLIBMM_DISABLE_DEPRECATED', 1)
+  pkg_conf_data.set('GIOMM_DISABLE_DEPRECATED', 1)
+endif
+pkg_conf_data.set('GLIBMM_MAJOR_VERSION', glibmm_major_version)
+pkg_conf_data.set('GLIBMM_MINOR_VERSION', glibmm_minor_version)
+pkg_conf_data.set('GLIBMM_MICRO_VERSION', glibmm_micro_version)
+pkg_conf_data.set('GIOMM_MAJOR_VERSION', glibmm_major_version)
+pkg_conf_data.set('GIOMM_MINOR_VERSION', glibmm_minor_version)
+pkg_conf_data.set('GIOMM_MICRO_VERSION', glibmm_micro_version)
+
+library_build_type = get_option('default_library')
+
+if cpp_compiler.get_argument_syntax() == 'msvc'
+  if library_build_type == 'static' or library_build_type == 'both'
+    error('Static builds are not supported by MSVC-style builds')
+  endif
+endif
+
+if library_build_type == 'static'
+  pkg_conf_data.set('GLIBMM_STATIC_LIB', 1)
+  pkg_conf_data.set('GIOMM_STATIC_LIB', 1)
+endif
+
+configure_file(
+  input: 'glibmm.pc.in',
+  output: glibmm_pcname + '.pc',
+  configuration: pkg_conf_data,
+  install_dir: install_pkgconfigdir,
+)
+
+glibmm_pkg_uninst_conf_data = configuration_data()
+glibmm_pkg_uninst_conf_data.merge_from(pkg_conf_data)
+glibmm_pkg_uninst_conf_data.set('srcdir', meson.current_source_dir())
+
+configure_file(
+  input: 'glibmm-uninstalled.pc.in',
+  output: glibmm_pcname + '-uninstalled.pc',
+  configuration: glibmm_pkg_uninst_conf_data,
+)
+
+glibmm_config_conf_data = configuration_data()
+glibmm_config_conf_data.merge_from(pkg_conf_data)
+if get_option('debug-refcounting')
+  glibmm_config_conf_data.set('GLIBMM_DEBUG_REFCOUNTING', 1)
+endif
+if is_os_cocoa
+  glibmm_config_conf_data.set('GLIBMM_OS_COCOA', 1)
+endif
+glibmm_config_conf_data.set('GLIBMM_SIZEOF_WCHAR_T', cpp_compiler.sizeof('wchar_t'))
+
+# Leave GLIBMM_COMPILER_SUN_FORTE undefined. It's not used by glibmm itself.
+# The Sun Forte compiler (a.k.a. Sun WorkShop) is not one of the compilers
+# that Meson recognizes. According to Wikipedia it's old, and has been
+# replaced by Oracle Developer Studio.
+# https://en.wikipedia.org/wiki/Oracle_Developer_Studio
+#if ???
+#  glibmm_config_conf_data.set('GLIBMM_COMPILER_SUN_FORTE', 1)
+#endif
+
+conf_tests = [
+# [preprocessor-macro-name, file-name, message]
+  ['GLIBMM_HAVE_WIDE_STREAM', 'have_wide_stream.cc', 'Wide stream support'],
+  ['GLIBMM_HAVE_STD_ITERATOR_TRAITS', 'have_std_iterator_traits.cc',
+     'std::iterator_traits<> is standard-conforming'],
+  ['GLIBMM_HAVE_SUN_REVERSE_ITERATOR', 'have_sun_reverse_iterator.cc',
+    'std::reverse_iterator is in Sun libCstd style'],
+  ['GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS', 'have_template_sequence_ctors.cc',
+    'STL containers have templated sequence ctors'],
+  ['GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS', 
+    'have_disambiguous_const_template_specializations.cc',
+    'Disambiguates template specializations for const and non-const types'],
+  ['GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION',
+    'can_use_dynamic_cast_in_unused_template_wo_def.cc',
+    'Non-instantiated templates may dynamic_cast<> to an undefined type'],
+  ['GLIBMM_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS',
+    'can_assign_non_extern_c_functions_to_extern_c_cb.cc',
+    'extern "C" and extern "C++" function pointers are compatible'],
+  ['GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS', 'allows_static_inline_npos.cc',
+    'A static member variable may be initialized inline to std::string::npos'],
+  ['GLIBMM_MEMBER_FUNCTIONS_MEMBER_TEMPLATES',
+    'member_functions_member_templates.cc',
+    'Member functions can refer to spezialized member function templates'],
+  ['GLIBMM_CAN_USE_NAMESPACES_INSIDE_EXTERNC',
+    'can_use_namespaces_inside_externc.cc',
+    'extern "C" functions in the global namespace, even inside a namespace'],
+  ['GLIBMM_CAN_USE_THREAD_LOCAL', 'can_use_thread_local.cc', 'thread_local support'],
+  ['GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32', 'std_time_t_is_not_int32.cc',
+    'std::time_t and gint32 are typedefs of different builtin types'],
+]
+
+foreach conf_test : conf_tests
+  if cpp_compiler.compiles(
+      files('..' / 'tools' / 'conf_tests' / conf_test[1]),
+      name: conf_test[2])
+    glibmm_config_conf_data.set(conf_test[0], 1)
+  endif
+endforeach
+
+install_glibmmconfigdir = install_libdir / glibmm_pcname / 'include'
+glibmmconfig_h = configure_file(
+  input: 'glibmmconfig.h.meson',
+  output: 'glibmmconfig.h',
+  configuration: glibmm_config_conf_data,
+  install_dir: install_glibmmconfigdir,
+)
index 31be6e4..ce69ace 100644 (file)
@@ -19,8 +19,7 @@ _DEFS(glibmm,glib)
 #include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
 #include <glibmm/error.h>
-#include <sigc++/slot.h>
-#include <sigc++/bind.h>
+#include <glibmm/arrayhandle.h>
 #include <glib.h>
 
 namespace Glib
@@ -57,8 +56,8 @@ class BalancedTree
 {
   _CLASS_GENERIC(BalancedTree, GTree)
 public:
-  using TraverseFunc = sigc::slot<bool(const K&, const V&)>;
-  using CompareFunc = sigc::slot<int(const K&, const K&)>;
+  using TraverseFunc = sigc::slot<bool, const K&, const V&>;
+  using CompareFunc = sigc::slot<int, const K&, const K&>;
 
 protected:
   BalancedTree() :
@@ -67,7 +66,7 @@ protected:
     gobject_ = g_tree_new_full(on_compare_tree, &key_compare_slot, on_destroy_key, on_destroy_value);
   }
 
-  explicit BalancedTree(const CompareFunc &key_compare_slot_) :
+  BalancedTree(const CompareFunc &key_compare_slot_) :
     key_compare_slot(key_compare_slot_)
   {
     gobject_ = g_tree_new_full(on_compare_tree, &key_compare_slot, on_destroy_key, on_destroy_value);
@@ -78,12 +77,12 @@ protected:
 public:
   static Glib::RefPtr< BalancedTree<K, V> > create()
   {
-    return Glib::make_refptr_for_instance< BalancedTree<K, V> >(new BalancedTree());
+    return Glib::RefPtr< BalancedTree<K, V> >(new BalancedTree());
   }
 
   static Glib::RefPtr< BalancedTree<K, V> > create(const CompareFunc &key_compare_slot)
   {
-    return Glib::make_refptr_for_instance< BalancedTree<K, V> >(new BalancedTree(key_compare_slot));
+    return Glib::RefPtr< BalancedTree<K, V> >(new BalancedTree(key_compare_slot));
   }
 
   ~BalancedTree()
@@ -235,8 +234,8 @@ public:
    */
   V* search(const CompareFunc &search_func, const K& key)
   {
-    sigc::slot<int(const K&, const CompareFunc&, const K&)> real_slot = sigc::ptr_fun(on_compare_key);
-    sigc::slot<int(const K&)> bound_slot = sigc::bind(real_slot, search_func, key);
+    sigc::slot<int, const K&, const CompareFunc&, const K&> real_slot = sigc::ptr_fun(on_compare_key);
+    sigc::slot<int, const K&> bound_slot = sigc::bind(real_slot, search_func, key);
     gpointer value = g_tree_search(gobj(), c_callback_search, reinterpret_cast<gconstpointer>(&bound_slot));
 
     return reinterpret_cast<V*>(value);
@@ -278,7 +277,7 @@ private:
   /// Wrapper for invoking GCompareFunc.
   static gint c_callback_search(gconstpointer a, gconstpointer b)
   {
-    const auto slot = reinterpret_cast<const sigc::slot<int(const K&)> *>(b);
+    const sigc::slot<int, const K&>* slot = reinterpret_cast<const sigc::slot<int, const K&> *>(b);
     return (*slot)(*reinterpret_cast<const K*>(a));
   }
 
index dfad8a6..576b64f 100644 (file)
@@ -14,8 +14,6 @@
  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
-using Flags = Glib::Binding::Flags;
-
 #include <glibmm/binding.h>
 #include <glib.h>
 
@@ -82,7 +80,7 @@ namespace Glib
 // static
 Glib::RefPtr<Binding>
 Binding::bind_property_value(const PropertyProxy_Base& source_property,
-  const PropertyProxy_Base& target_property, Flags flags, const SlotTransform& transform_to,
+  const PropertyProxy_Base& target_property, BindingFlags flags, const SlotTransform& transform_to,
   const SlotTransform& transform_from)
 {
   GBinding* binding = nullptr;
@@ -114,7 +112,7 @@ Binding::bind_property_value(const PropertyProxy_Base& source_property,
   // either the source object or the target object is finalized.
   // The GBinding object must not be destroyed while there are RefPtrs around.
   g_object_ref(binding);
-  return Glib::make_refptr_for_instance<Binding>(new Binding(binding));
+  return Glib::RefPtr<Binding>(new Binding(binding));
 }
 
 void
index 6d1f837..c8c7f35 100644 (file)
@@ -24,6 +24,7 @@ _PINCLUDE(glibmm/private/object_p.h)
 
 namespace Glib
 {
+_WRAP_ENUM(BindingFlags, GBindingFlags, newin "2,44")
 
 /** Bind two object properties.
  *
@@ -95,20 +96,46 @@ namespace Glib
  *
  * @newin{2,44}
  */
-class Binding : public Glib::Object
+class GLIBMM_API Binding : public Glib::Object
 {
-  _CLASS_GOBJECT(Binding, GBinding, G_BINDING, Glib::Object, GObject)
+  _CLASS_GOBJECT(Binding, GBinding, G_BINDING, Glib::Object, GObject, , , GLIBMM_API)
 
 public:
-  _WRAP_ENUM(Flags, GBindingFlags, newin "2,44")
-
-  /** For instance,<br>
+  /** A slot to be called to transform values in a binding created by
+   * bind_property_value().
+   *
+   * For instance:
+   * @code
    *   bool on_transform_to(const GValue* from_value, GValue* to_value);
+   * @endcode
    *
    * @return <tt>true</tt> if the transformation was successful, and <tt>false</tt> otherwise.
    */
-  using SlotTransform = sigc::slot<bool(const GValue*, GValue*)>;
+  using SlotTransform = sigc::slot<bool, const GValue*, GValue*>;
 
+  /** A slot to be called to transform values in a binding created by
+   * bind_property().
+   *
+   * For instance:
+   * @code
+   *   bool on_transform_to(const Glib::ustring& from_string, int& to_int);
+   * @endcode
+   *
+   * @return <tt>true</tt> if the transformation was successful, and <tt>false</tt> otherwise.
+   */
+  template <typename T_from, typename T_to>
+  using SlotTypedTransform = sigc::slot<bool, const T_from&, T_to&>;
+
+  // GValue* or Glib::ValueBase& in SlotTransform?
+  // Binding_transform_callback_common() is simpler and faster with GValue*.
+  // No need to copy between GValue and Glib::ValueBase. ValueBase would only
+  // be marginally better for users of bind_property_value(). Users would want
+  // Value<T_source> and Value<T_target>, meaning that bind_property_value()
+  // would have to be a template function. Most users would probably still
+  // prefer bind_property(). bind_property_value() is public partly because
+  // it's a good place to present documentation common to all the
+  // bind_property() overloads.
+  // See also https://gitlab.gnome.org/GNOME/glibmm/issues/61
   /** Creates a binding between @a source_property and @a target_property,
    * allowing you to set the transformation functions to be used by the binding.
    *
@@ -141,9 +168,9 @@ public:
   static Glib::RefPtr<Binding> bind_property_value(
     const PropertyProxy_Base& source_property,
     const PropertyProxy_Base& target_property,
-    Flags flags = Flags::DEFAULT,
-    const SlotTransform& transform_to = {},
-    const SlotTransform& transform_from = {});
+    BindingFlags flags = BINDING_DEFAULT,
+    const SlotTransform& transform_to = SlotTransform(),
+    const SlotTransform& transform_from = SlotTransform());
 
   _IGNORE(g_object_bind_property, g_object_bind_property_full, g_object_bind_property_with_closures)
 
@@ -162,7 +189,7 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy_Base& source_property,
     const PropertyProxy_Base& target_property,
-    Flags flags = Flags::DEFAULT)
+    BindingFlags flags = BINDING_DEFAULT)
   {
     return bind_property_value(source_property, target_property, flags);
   }
@@ -183,8 +210,7 @@ public:
    * @tparam T_target Type of the target property. Must be a type that can be
    *         stored in a Glib::Value<T_target> object.
    * @tparam T_functor_to Type of functor that translates from the source to the target.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_source&, T_target&)>.
+   *         Must be convertible to SlotTypedTransform<T_source, T_target>.
    *
    * @see bind_property_value()
    *
@@ -194,10 +220,10 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy<T_source>& source_property,
     const PropertyProxy<T_target>& target_property,
-    Flags flags,
+    BindingFlags flags,
     const T_functor_to& transform_to)
   {
-    sigc::slot<bool(const T_source&, T_target&)> slot_transform_to = transform_to;
+    SlotTypedTransform<T_source, T_target> slot_transform_to = transform_to;
 
     return bind_property_value(source_property, target_property, flags,
       slot_transform_to.empty() ? SlotTransform() : TransformProp<T_source, T_target>(slot_transform_to));
@@ -219,8 +245,7 @@ public:
    * @tparam T_target Type of the target property. Must be a type that can be
    *         stored in a Glib::Value<T_target> object.
    * @tparam T_functor_to Type of functor that translates from the source to the target.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_source&, T_target&)>.
+   *         Must be convertible to SlotTypedTransform<T_source, T_target>.
    *
    * @see bind_property_value()
    *
@@ -230,10 +255,10 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy<T_source>& source_property,
     const PropertyProxy_WriteOnly<T_target>& target_property,
-    Flags flags,
+    BindingFlags flags,
     const T_functor_to& transform_to)
   {
-    sigc::slot<bool(const T_source&, T_target&)> slot_transform_to = transform_to;
+    SlotTypedTransform<T_source, T_target> slot_transform_to = transform_to;
 
     return bind_property_value(source_property, target_property, flags,
       slot_transform_to.empty() ? SlotTransform() : TransformProp<T_source, T_target>(slot_transform_to));
@@ -255,8 +280,7 @@ public:
    * @tparam T_target Type of the target property. Must be a type that can be
    *         stored in a Glib::Value<T_target> object.
    * @tparam T_functor_to Type of functor that translates from the source to the target.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_source&, T_target&)>.
+   *         Must be convertible to SlotTypedTransform<T_source, T_target>.
    *
    * @see bind_property_value()
    *
@@ -266,10 +290,10 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy_ReadOnly<T_source>& source_property,
     const PropertyProxy<T_target>& target_property,
-    Flags flags,
+    BindingFlags flags,
     const T_functor_to& transform_to)
   {
-    sigc::slot<bool(const T_source&, T_target&)> slot_transform_to = transform_to;
+    SlotTypedTransform<T_source, T_target> slot_transform_to = transform_to;
 
     return bind_property_value(source_property, target_property, flags,
       slot_transform_to.empty() ? SlotTransform() : TransformProp<T_source, T_target>(slot_transform_to));
@@ -291,8 +315,7 @@ public:
    * @tparam T_target Type of the target property. Must be a type that can be
    *         stored in a Glib::Value<T_target> object.
    * @tparam T_functor_to Type of functor that translates from the source to the target.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_source&, T_target&)>.
+   *         Must be convertible to SlotTypedTransform<T_source, T_target>.
    *
    * @see bind_property_value()
    *
@@ -302,10 +325,10 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy_ReadOnly<T_source>& source_property,
     const PropertyProxy_WriteOnly<T_target>& target_property,
-    Flags flags,
+    BindingFlags flags,
     const T_functor_to& transform_to)
   {
-    sigc::slot<bool(const T_source&, T_target&)> slot_transform_to = transform_to;
+    SlotTypedTransform<T_source, T_target> slot_transform_to = transform_to;
 
     return bind_property_value(source_property, target_property, flags,
       slot_transform_to.empty() ? SlotTransform() : TransformProp<T_source, T_target>(slot_transform_to));
@@ -329,11 +352,9 @@ public:
    * @tparam T_target Type of the target property. Must be a type that can be
    *         stored in a Glib::Value<T_target> object.
    * @tparam T_functor_to Type of functor that translates from the source to the target.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_source&, T_target&)>.
+   *         Must be convertible to SlotTypedTransform<T_source, T_target>.
    * @tparam T_functor_from Type of functor that translates from the target to the source.
-   *         Must be convertible to<br>
-   *         sigc::slot<bool(const T_target&, T_source&)>.
+   *         Must be convertible to SlotTypedTransform<T_target, T_source>.
    *
    * @see bind_property_value()
    *
@@ -343,12 +364,12 @@ public:
   static Glib::RefPtr<Binding> bind_property(
     const PropertyProxy<T_source>& source_property,
     const PropertyProxy<T_target>& target_property,
-    Flags flags,
+    BindingFlags flags,
     const T_functor_to& transform_to,
     const T_functor_from& transform_from)
   {
-    sigc::slot<bool(const T_source&, T_target&)> slot_transform_to = transform_to;
-    sigc::slot<bool(const T_target&, T_source&)> slot_transform_from = transform_from;
+    SlotTypedTransform<T_source, T_target> slot_transform_to = transform_to;
+    SlotTypedTransform<T_target, T_source> slot_transform_from = transform_from;
 
     return bind_property_value(source_property, target_property, flags,
       slot_transform_to.empty() ? SlotTransform() : TransformProp<T_source, T_target>(slot_transform_to),
@@ -361,7 +382,7 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Glib::ObjectBase> get_target(), g_binding_get_target, refreturn, newin "2,44")
   _WRAP_METHOD(Glib::RefPtr<const Glib::ObjectBase> get_target() const, g_binding_get_target, refreturn, constversion, newin "2,44")
   _WRAP_METHOD(Glib::ustring get_target_property() const, g_binding_get_target_property, newin "2,44")
-  _WRAP_METHOD(Flags get_flags() const, g_binding_get_flags, newin "2,44")
+  _WRAP_METHOD(BindingFlags get_flags() const, g_binding_get_flags, newin "2,44")
 
   /** Explicitly releases the binding between the source and the target
    * property expressed by this Binding instance.
@@ -375,7 +396,7 @@ public:
   void unbind();
   _IGNORE(g_binding_unbind)
 
-  _WRAP_PROPERTY("flags", Flags, newin "2,44")
+  _WRAP_PROPERTY("flags", Glib::BindingFlags, newin "2,44")
   _WRAP_PROPERTY("source", Glib::RefPtr<Glib::ObjectBase>, newin "2,44")
   _WRAP_PROPERTY("source-property", Glib::ustring, newin "2,44")
   _WRAP_PROPERTY("target", Glib::RefPtr<Glib::ObjectBase>, newin "2,44")
@@ -392,29 +413,31 @@ private:
   // The functor TransformProp can be implicitly converted to a SlotTransform
   // and used in a call to bind_property_value().
   template <typename T_from, typename T_to>
-  class TransformProp
+  class TransformProp : public sigc::functor_base
   {
   public:
-    using SlotTypedTransform = sigc::slot<bool(const T_from&, T_to&)>;
+    using result_type = bool;
 
-    explicit TransformProp(const SlotTypedTransform& slot) : typed_transform(slot) {}
+    TransformProp(const SlotTypedTransform<T_from, T_to>& slot) : typed_transform(slot) {}
 
     bool operator()(const GValue* from_value, GValue* to_value)
     {
       Glib::Value<T_from> from_glib_value;
       from_glib_value.init(from_value);
+      T_to to{};
+
+      if (!typed_transform(from_glib_value.get(), to))
+        return false;
+
       Glib::Value<T_to> to_glib_value;
       to_glib_value.init(to_value);
-      T_to to = to_glib_value.get();
-
-      const bool result = typed_transform(from_glib_value.get(), to);
       to_glib_value.set(to);
       g_value_copy(to_glib_value.gobj(), to_value);
-      return result;
+      return true;
     }
 
   private:
-    SlotTypedTransform typed_transform;
+    SlotTypedTransform<T_from, T_to> typed_transform;
   };
 };
 
index c04fa00..003c58b 100644 (file)
@@ -50,4 +50,10 @@ ByteArray::get_data() const
   return gobj()->data;
 }
 
+GType
+ByteArray::get_type()
+{
+  return g_byte_array_get_type();
+}
+
 } // namespace Glib
index 518080e..cf222b2 100644 (file)
@@ -41,10 +41,9 @@ namespace Glib
  *
  * @newin{2,36}
  */
-class ByteArray final
+class GLIBMM_API ByteArray final
 {
-  _CLASS_OPAQUE_REFCOUNTED(ByteArray, GByteArray, NONE, g_byte_array_ref, g_byte_array_unref)
-  _IS_REFCOUNTED_BOXEDTYPE
+  _CLASS_OPAQUE_REFCOUNTED(ByteArray, GByteArray, NONE, g_byte_array_ref, g_byte_array_unref, GLIBMM_API)
   _IGNORE(g_byte_array_ref, g_byte_array_unref)
 
 public:
@@ -58,7 +57,7 @@ public:
    * int compare(const guint8* first, const guint8* second);
    * </code>
    */
-  using SlotCompare = sigc::slot<int(const guint8*, const guint8*)>;
+  using SlotCompare = sigc::slot<int, const guint8*, const guint8*>;
 
   _WRAP_METHOD(static Glib::RefPtr<ByteArray> create(), g_byte_array_new)
 
@@ -91,6 +90,21 @@ public:
   _IGNORE(g_byte_array_sort)
 
   _WRAP_METHOD(Glib::RefPtr<ByteArray> set_size(guint length), g_byte_array_set_size, refreturn)
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  static GType get_type() G_GNUC_CONST;
+#endif
+};
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <>
+class GLIBMM_API Value< Glib::RefPtr<Glib::ByteArray> > : public ValueBase_Boxed
+{
+public:
+  static GType value_type() { return Glib::ByteArray::get_type(); }
+  void set(const Glib::RefPtr<Glib::ByteArray>& array) { set_boxed(Glib::unwrap(array)); }
+  Glib::RefPtr<Glib::ByteArray> get()                  { return Glib::RefPtr<Glib::ByteArray>(reinterpret_cast<Glib::ByteArray*>(get_boxed())); }
 };
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 } // namespace Glib
index 60b92d1..dd5cc3d 100644 (file)
@@ -20,6 +20,7 @@ _DEFS(glibmm,glib)
 #include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
 #include <glibmm/error.h>
+#include <glibmm/arrayhandle.h>
 #include <glib.h>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -49,9 +50,9 @@ namespace Glib
  *
  * @newin{2,34}
  */
-class Bytes final
+class GLIBMM_API Bytes final
 {
-  _CLASS_OPAQUE_REFCOUNTED(Bytes, GBytes, NONE, g_bytes_ref, g_bytes_unref)
+  _CLASS_OPAQUE_REFCOUNTED(Bytes, GBytes, NONE, g_bytes_ref, g_bytes_unref, GLIBMM_API)
   _IGNORE(g_bytes_ref, g_bytes_unref)
 public:
 
index c612049..be5f9e2 100644 (file)
@@ -20,7 +20,7 @@
 namespace Glib
 {
 
-Checksum::Checksum(Type type) : gobject_(g_checksum_new((GChecksumType)type))
+Checksum::Checksum(ChecksumType type) : gobject_(g_checksum_new((GChecksumType)type))
 {
 }
 
@@ -30,15 +30,15 @@ Checksum::operator bool() const
 }
 
 gssize
-Checksum::get_length(Type checksum_type)
+Checksum::get_length(ChecksumType checksum_type)
 {
   return g_checksum_type_get_length((GChecksumType)checksum_type);
 }
 
 std::string
-Checksum::compute_checksum(Type checksum_type, const std::string& data)
+Checksum::compute_checksum(ChecksumType checksum_type, const std::string& data)
 {
-  return Glib::convert_return_gchar_ptr_to_ustring(
+  return Glib::convert_return_gchar_ptr_to_stdstring(
     g_compute_checksum_for_string(((GChecksumType)checksum_type), data.c_str(), data.size()));
 }
 
@@ -48,4 +48,20 @@ Checksum::update(const std::string& data)
   g_checksum_update(gobj(), (const guchar*)data.c_str(), data.size());
 }
 
+// Glib::Value<Glib::Checksum>
+GType Value<Checksum>::value_type()
+{
+  return G_TYPE_CHECKSUM;
+}
+
+void Value<Checksum>::set(const CppType& data)
+{
+  set_boxed(data.gobj());
+}
+
+Value<Checksum>::CppType Value<Checksum>::get() const
+{
+  return Glib::wrap(static_cast<CType>(get_boxed()), true);
+}
+
 } // Glib namespace
index 2bb8e58..0a78434 100644 (file)
@@ -24,6 +24,8 @@ _DEFS(glibmm,glib)
 extern "C" { typedef struct _GChecksum GChecksum; }
 #endif
 
+//TODO: When we can change API, make Checksum a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
@@ -37,22 +39,22 @@ namespace Glib
  *
  * @newin{2,16}
  */
-class Checksum
+class GLIBMM_API Checksum
 {
-  _CLASS_BOXEDTYPE(Checksum, GChecksum, NONE, g_checksum_copy, g_checksum_free)
+  _CLASS_OPAQUE_COPYABLE(Checksum, GChecksum, NONE, g_checksum_copy, g_checksum_free, GLIBMM_API)
   _IGNORE(g_checksum_copy, g_checksum_free)
 
 public:
-  _WRAP_ENUM(Type, GChecksumType, NO_GTYPE)
+  _WRAP_ENUM(ChecksumType, GChecksumType, NO_GTYPE)
 
-#m4 _CONVERSION(`Type', `GChecksumType', `(static_cast<$2>($3))')
+#m4 _CONVERSION(`ChecksumType', `GChecksumType', `(($2)$3)')
 
   /** Creates a new Checksum, using the checksum algorithm @a checksum_type.
    * If the checksum_type is not known, then operator bool() will return false.
    *
    * @param checksum_type Checksum type, one of defined above.
    */
-  explicit Checksum(Type checksum_type);
+  explicit Checksum(ChecksumType checksum_type);
 
   /** Returns true if the Checksum object is valid.
    * This will return false, for instance, if an unsupported checksum type was provided to the constructor.
@@ -61,7 +63,9 @@ public:
 
   _WRAP_METHOD(void reset(), g_checksum_reset)
 
-  _WRAP_METHOD(void update(const guchar* data, gssize length), g_checksum_update)
+  //TODO: length should really be gssize, not gsize, when we can break ABI:
+#m4 _CONVERSION(`gsize',`gssize',`(gssize)($3)')
+  _WRAP_METHOD(void update(const guchar* data, gsize length), g_checksum_update)
 
   /** Feeds data into an existing Checksum.
    * The checksum must still be open, that is get_string() or get_digest() must not have been called on the checksum.
@@ -75,25 +79,42 @@ public:
   _WRAP_METHOD(std::string get_string() const, g_checksum_get_string)
 
 
-  _WRAP_METHOD(static std::string compute_checksum(Type checksum_type, const guchar* data, gsize length), g_compute_checksum_for_data)
+  _WRAP_METHOD(static std::string compute_checksum(ChecksumType checksum_type, const guchar* data, gsize length), g_compute_checksum_for_data)
 
   /** Computes the checksum of a string.
    *
-   * @param checksum_type A Type
+   * @param checksum_type A ChecksumType
    * @param str The string to compute the checksum of.
    * @result The checksum as a hexadecimal string.
    */
-  static std::string compute_checksum(Type checksum_type, const std::string& str);
+  static std::string compute_checksum(ChecksumType checksum_type, const std::string& str);
   _IGNORE(g_compute_checksum_for_string)
 
 
   //We don't use _WRAP_METHOD because this is not really a GCheckSum function:
   /** Gets the length in bytes of digests of type @a checksum_type.
    *
-   * @param checksum_type A Type.
+   * @param checksum_type A ChecksumType.
    * @result The checksum length, or -1 if @a checksum_type is not supported.
    */
-  static gssize get_length(Type checksum_type);
+  static gssize get_length(ChecksumType checksum_type);
 };
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::Checksum can be used with Glib::Value and _WRAP_PROPERTY.
+template <>
+class GLIBMM_API Value<Glib::Checksum> : public ValueBase_Boxed
+{
+public:
+  using CppType = Glib::Checksum;
+  using CType = GChecksum*;
+
+  static GType value_type();
+
+  void set(const CppType& data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 } //namespace Glib
+
index 9c211bc..d07e8e3 100644 (file)
@@ -40,7 +40,7 @@ namespace Glib
  * you should always catch those errors, and then try to recover, or tell the
  * user the input was invalid.
  */
-_WRAP_GERROR(ConvertError, GConvertError, G_CONVERT_ERROR, NO_GTYPE)
+_WRAP_GERROR(ConvertError, GConvertError, G_CONVERT_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 
 /** Thin %iconv() wrapper.
@@ -49,7 +49,7 @@ _WRAP_GERROR(ConvertError, GConvertError, G_CONVERT_ERROR, NO_GTYPE)
  * creating an IConv object once and using the convert() method could
  * be useful when converting multiple times between the same charsets.
  */
-class IConv
+class GLIBMM_API IConv
 {
 public:
   /** Open new conversion descriptor.
@@ -107,12 +107,14 @@ private:
 /** Get the charset used by the current locale.
  * @return Whether the current locale uses the UTF-8 charset.
  */
+GLIBMM_API
 bool get_charset();
 
 /** Get the charset used by the current locale.
  * @param charset Will be filled with the charset's name.
  * @return Whether the current locale uses the UTF-8 charset.
  */
+GLIBMM_API
 bool get_charset(std::string& charset);
 
 /** Convert from one encoding to another.
@@ -122,6 +124,7 @@ bool get_charset(std::string& charset);
  * @return The converted string.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string convert(const std::string& str,
                     const std::string& to_codeset,
                     const std::string& from_codeset);
@@ -136,6 +139,7 @@ std::string convert(const std::string& str,
  * @return The converted string.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string convert_with_fallback(const std::string& str,
                                   const std::string& to_codeset,
                                   const std::string& from_codeset);
@@ -156,6 +160,7 @@ std::string convert_with_fallback(const std::string& str,
  * @return The converted string.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string convert_with_fallback(const std::string& str,
                                   const std::string& to_codeset,
                                   const std::string& from_codeset,
@@ -168,6 +173,7 @@ std::string convert_with_fallback(const std::string& str,
  * @return The input string converted to UTF-8 encoding.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 Glib::ustring locale_to_utf8(const std::string& opsys_string);
 
 /** Convert from UTF-8 to the current locale's encoding.
@@ -177,6 +183,7 @@ Glib::ustring locale_to_utf8(const std::string& opsys_string);
  *  system's current locale.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string locale_from_utf8(const Glib::ustring& utf8_string);
 
 /** Converts a string which is in the encoding used for filenames into
@@ -185,6 +192,7 @@ std::string locale_from_utf8(const Glib::ustring& utf8_string);
  * @return The converted string.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 Glib::ustring filename_to_utf8(const std::string& opsys_string);
 
 /** Converts a string from UTF-8 to the encoding used for filenames.
@@ -192,6 +200,7 @@ Glib::ustring filename_to_utf8(const std::string& opsys_string);
  * @return The converted string.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string filename_from_utf8(const Glib::ustring& utf8_string);
 
 /** Converts an escaped UTF-8 encoded URI to a local filename
@@ -202,6 +211,7 @@ std::string filename_from_utf8(const Glib::ustring& utf8_string);
  * @return The resulting filename.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string filename_from_uri(const Glib::ustring& uri, Glib::ustring& hostname);
 
 /** Converts an escaped UTF-8 encoded URI to a local filename in the encoding
@@ -210,6 +220,7 @@ std::string filename_from_uri(const Glib::ustring& uri, Glib::ustring& hostname)
  * @return The resulting filename.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 std::string filename_from_uri(const Glib::ustring& uri);
 
 /** Converts an absolute filename to an escaped UTF-8 encoded URI.
@@ -219,6 +230,7 @@ std::string filename_from_uri(const Glib::ustring& uri);
  * @return The resulting URI.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 Glib::ustring filename_to_uri(const std::string& filename, const Glib::ustring& hostname);
 
 /** Converts an absolute filename to an escaped UTF-8 encoded URI.
@@ -227,6 +239,7 @@ Glib::ustring filename_to_uri(const std::string& filename, const Glib::ustring&
  * @return The resulting URI.
  * @throw Glib::ConvertError
  */
+GLIBMM_API
 Glib::ustring filename_to_uri(const std::string& filename);
 
 /** Returns the display basename for the particular filename, guaranteed
@@ -243,6 +256,7 @@ Glib::ustring filename_to_uri(const std::string& filename);
  * @param filename An absolute pathname in the GLib file name encoding.
  * @result A string containing a rendition of the basename of the filename in valid UTF-8
  */
+GLIBMM_API
 Glib::ustring filename_display_basename(const std::string& filename);
 
 /** Converts a filename into a valid UTF-8 string. The
@@ -260,6 +274,7 @@ Glib::ustring filename_display_basename(const std::string& filename);
  * @param filename: a pathname hopefully in the GLib file name encoding
  * @result A string containing a rendition of the filename in valid UTF-8.
  */
+GLIBMM_API
 Glib::ustring filename_display_name(const std::string& filename);
 
 /** @} group CharsetConv */
index 07f0812..65f0d64 100644 (file)
@@ -75,6 +75,24 @@ Date::set_parse(const Glib::ustring& str)
   g_date_set_parse(&gobject_, str.c_str());
 }
 
+_DEPRECATE_IFDEF_START
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+// Avoid a build problem in the case that std::time_t is equivalent to gint32 (GTime is also gint32)
+// That would make the set_time() method overload impossible.
+#ifdef GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+void
+Date::set_time(GTime time)
+{
+  // This method, and the C function g_date_set_time() that it wraps, are deprecated.
+  //(::time_t is used here instead of std::time_t, since the C function is declared
+  // with ::time_t. It's not important. The C++ standard requires that ::time_t
+  // and std::time_t shall be identical when both are defined.)
+  g_date_set_time_t(&gobject_, static_cast<time_t>(time));
+}
+#endif // GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+G_GNUC_END_IGNORE_DEPRECATIONS
+_DEPRECATE_IFDEF_END
+
 void
 Date::set_time(std::time_t timet)
 {
@@ -88,6 +106,16 @@ Date::set_time_current()
   g_date_set_time_t(&gobject_, time(nullptr));
 }
 
+_DEPRECATE_IFDEF_START
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+void
+Date::set_time(const GTimeVal& timeval)
+{
+  g_date_set_time_val(&gobject_, const_cast<GTimeVal*>(&timeval));
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+_DEPRECATE_IFDEF_END
+
 void
 Date::set_month(Date::Month month)
 {
@@ -223,22 +251,12 @@ Date::get_weekday() const
   return (Date::Weekday)g_date_get_weekday(&gobject_);
 }
 
-int Date::get_weekday_as_int() const
-{
-  return g_date_get_weekday(&gobject_);
-}
-
 Date::Month
 Date::get_month() const
 {
   return (Date::Month)g_date_get_month(&gobject_);
 }
 
-int Date::get_month_as_int() const
-{
-  return g_date_get_month(&gobject_);
-}
-
 Date::Year
 Date::get_year() const
 {
index 1633d07..c1ec4a0 100644 (file)
@@ -30,15 +30,15 @@ namespace Glib
 
 /** Julian calendar date.
  */
-class Date
+class GLIBMM_API Date
 {
 public:
   using Day = guint8 ;
   using Year = guint16;
 
-  _WRAP_ENUM(Month, GDateMonth, NO_GTYPE)
-  _WRAP_ENUM(Weekday, GDateWeekday, NO_GTYPE)
-  _WRAP_ENUM(DMY, GDateDMY, NO_GTYPE)
+  _WRAP_ENUM(Month, GDateMonth, s#^DATE_##, NO_GTYPE)
+  _WRAP_ENUM(Weekday, GDateWeekday, s#^DATE_##, NO_GTYPE)
+  _WRAP_ENUM(DMY, GDateDMY, s#^DATE_##, NO_GTYPE)
 
   static const Day     BAD_DAY    = 0;
   static const Year    BAD_YEAR   = 0;
@@ -108,6 +108,22 @@ public:
    */
   void set_parse (const Glib::ustring& str);
 
+  _DEPRECATE_IFDEF_START
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  //Avoid a build problem in the case that std::time_t is equivalent to gint32 (GTime is also gint32)
+  //That would make the set_time() method overload impossible.
+  #ifdef GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+  /** Sets the value of a date from a GTime value.
+   *
+   * @param time GTime value to set.
+   *
+   * @deprecated Please use set_time(std::time_t) instead.
+   */
+  void set_time(GTime time);
+  #endif //GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
+  G_GNUC_END_IGNORE_DEPRECATIONS
+  _DEPRECATE_IFDEF_END
+
   /** Sets the value of a date from a <type>std::time_t</type> value.
    *
    * @param timet std::time_t value to set
@@ -118,6 +134,22 @@ public:
    */
   void set_time(std::time_t timet);
 
+  _DEPRECATE_IFDEF_START
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  /** Sets the value of a date from a GTimeVal value.  Note that the
+   * tv_usec member is ignored, because Glib::Date can't make use of the
+   * additional precision.
+   *
+   * @deprecated Use set_time(std::time_t timet) instead.
+   *
+   * @param timeval GTimeVal value to set
+   *
+   * Since: 2.10
+   */
+  void set_time(const GTimeVal& timeval);
+  G_GNUC_END_IGNORE_DEPRECATIONS
+  _DEPRECATE_IFDEF_END
+
   /** Set this Glib::Date to the current time.
    */
   void set_time_current();
@@ -264,21 +296,11 @@ public:
    */
   Weekday get_weekday() const;
 
-  /** Returns the day of the week for a Date. The date must be valid.
-   * @return Day of the week as an int. Monday=1 .. Sunday=7.
-   */
-  int get_weekday_as_int() const;
-
   /** Returns the month of the year. The date must be valid.
    * @return Month of the year as a Date::Month.
    */
   Month        get_month()               const;
 
-  /** Returns the month of the year. The date must be valid.
-   * @return Month of the year as an int. January=1 .. December=12.
-   */
-  int          get_month_as_int()        const;
-
   /** Returns the year of a Date. The date must be valid.
    * @return Year in which the date falls.
    */
index dd6db94..9207fef 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <glibmm/utility.h>
+#include <glibmm/timeval.h>
 #include <glibmm/wrap.h>
 
 namespace Glib
@@ -25,4 +26,20 @@ DateTime::operator bool() const
   return (gobject_ != nullptr);
 }
 
+// Glib::Value<Glib::DateTime>
+GType Value<DateTime>::value_type()
+{
+  return G_TYPE_DATE_TIME;
+}
+
+void Value<DateTime>::set(const CppType& data)
+{
+  set_boxed(data.gobj());
+}
+
+Value<DateTime>::CppType Value<DateTime>::get() const
+{
+  return Glib::wrap(static_cast<CType>(get_boxed()), true);
+}
+
 } // namespace Glib
index 657efec..ff62b52 100644 (file)
@@ -17,6 +17,7 @@
 _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
+#include <glibmm/refptr.h>
 #include <glibmm/timezone.h>
 #include <glibmm/ustring.h>
 #include <glibmm/value.h>
@@ -26,9 +27,13 @@ _DEFS(glibmm,glib)
 typedef struct _GDateTime GDateTime;
 #endif
 
+//TODO: When we can change API, make DateTime a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
+struct TimeVal;
+
 /** A value representing an interval of time, in microseconds.  As GTimeSpan,
  * its underlying type is gint64.
  */
@@ -55,16 +60,10 @@ using TimeSpan = GTimeSpan;
  * in length).
  * @newin{2,30}
  */
-class DateTime
+class GLIBMM_API DateTime
 {
-  // GDateTime is refcounted, but Glib::DateTime is not.
-  // GDateTime is immutable. Therefore, there is no problem having several
-  // Glib::DateTime instances wrap the same GDateTime, and it's easier to use
-  // Glib::DateTime without Glib::RefPtr.
-  _CLASS_BOXEDTYPE(DateTime, GDateTime, NONE, g_date_time_ref, g_date_time_unref)
+  _CLASS_OPAQUE_COPYABLE(DateTime, GDateTime, NONE, g_date_time_ref, g_date_time_unref, GLIBMM_API)
   _IGNORE(g_date_time_ref, g_date_time_unref)
-  _IGNORE(g_date_time_new_from_timeval_local, g_date_time_new_from_timeval_utc,
-          g_date_time_to_timeval)dnl // deprecated
 
 public:
   _WRAP_METHOD(static DateTime create_now(const TimeZone& tz), g_date_time_new_now)
@@ -74,7 +73,14 @@ public:
   _WRAP_METHOD(static DateTime create_now_local(gint64 t), g_date_time_new_from_unix_local)
   _WRAP_METHOD(static DateTime create_now_utc(gint64 t), g_date_time_new_from_unix_utc)
 
-  _WRAP_METHOD(static DateTime create_from_iso8601(const Glib::ustring& text, const TimeZone& default_tz{?}), g_date_time_new_from_iso8601)
+  _WRAP_METHOD(static DateTime create_now_local(const TimeVal& tv), g_date_time_new_from_timeval_local,
+    deprecated "Use create_now_local(gint64 t) instead.")
+
+  _WRAP_METHOD(static DateTime create_now_utc(const TimeVal& tv), g_date_time_new_from_timeval_utc,
+    deprecated "Use create_now_utc(gint64 t) instead.")
+
+  _WRAP_METHOD(static DateTime create_from_iso8601(const Glib::ustring& text, const TimeZone& default_tz{?}),
+    g_date_time_new_from_iso8601, newin "2,62")
   _WRAP_METHOD(static DateTime create(const TimeZone& tz, int year, int month, int day, int hour, int minute, double seconds), g_date_time_new)
   _WRAP_METHOD(static DateTime create_local(int year, int month, int day, int hour, int minute, double seconds), g_date_time_new_local)
   _WRAP_METHOD(static DateTime create_utc(int year, int month, int day, int hour, int minute, double seconds), g_date_time_new_utc)
@@ -82,6 +88,8 @@ public:
   /** Returns true if the %DateTime object is valid.
    * This will return false, for instance, if the @a text in create_from_iso8601()
    * is not a valid ISO 8601 formatted string.
+   *
+   * @newin{2,62}
    */
   explicit operator bool() const;
 
@@ -146,6 +154,10 @@ public:
   _WRAP_METHOD(int get_microsecond() const, g_date_time_get_microsecond)
   _WRAP_METHOD(double get_seconds() const, g_date_time_get_seconds)
   _WRAP_METHOD(gint64 to_unix() const, g_date_time_to_unix)
+
+  _WRAP_METHOD(bool to_timeval(TimeVal& tv) const, g_date_time_to_timeval,
+    deprecated "Use to_unix() instead.")
+
   _WRAP_METHOD(TimeSpan get_utc_offset() const, g_date_time_get_utc_offset)
 #m4 _CONVERSION(`GTimeZone*',`TimeZone',`Glib::wrap($3, true)')
   _WRAP_METHOD(TimeZone get_timezone() const, g_date_time_get_timezone, newin "2,60")
@@ -158,4 +170,20 @@ public:
   _WRAP_METHOD(Glib::ustring format_iso8601() const, g_date_time_format_iso8601)
 };
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::DateTime can be used with Glib::Value and _WRAP_PROPERTY.
+template <>
+class GLIBMM_API Value<Glib::DateTime> : public ValueBase_Boxed
+{
+public:
+  using CppType = Glib::DateTime;
+  using CType = GDateTime*;
+
+  static GType value_type();
+
+  void set(const CppType& data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 } // namespace Glib
index 162eec3..bab18c1 100644 (file)
@@ -36,9 +36,12 @@ glibmm_files_any_hg =                \
        regex.hg                \
        shell.hg                \
        spawn.hg                \
+       thread.hg               \
+       threads.hg              \
        timezone.hg             \
        unicode.hg              \
        uriutils.hg             \
+       valuearray.hg \
        variant.hg              \
        variantdict.hg          \
        variantiter.hg          \
index 1cbe3eb..46b6f54 100644 (file)
@@ -59,90 +59,158 @@ _WRAP_GERROR(FileError, GFileError, G_FILE_ERROR, NO_GTYPE,
     s#^AGAIN$#TRYAGAIN#,
     s#^INTR$#INTERRUPTED#,
     s#^IO$#IO_ERROR#,
-    s#^PERM$#NOT_OWNER#
+    s#^PERM$#NOT_OWNER#,
+    decl_prefix GLIBMM_API
 )
 
+/** @enum FileError::Code
+ * Values corresponding to <tt>errno</tt> codes returned from file operations
+ * on UNIX.
+ * Unlike <tt>errno</tt> codes, FileError::Code values are available on all
+ * systems, even Windows. The exact meaning of each code depends on what sort
+ * of file operation you were performing; the UNIX documentation gives more
+ * details.  The following error code descriptions come from the GNU C Library
+ * manual, and are under the copyright of that manual.
+ *
+ * It's not very portable to make detailed assumptions about exactly which
+ * errors will be returned from a given operation. Some errors don't occur on
+ * some systems, etc., sometimes there are subtle differences in when a system
+ * will report a given error, etc.
+ */
+
 /** @var FileError::Code FileError::EXISTS
- * <tt>(EEXIST)</tt>
- *
- * @var FileError::Code FileError::IS_DIRECTORY
- * <tt>(EISDIR)</tt>
- *
- * @var FileError::Code FileError::ACCESS_DENIED
- * <tt>(EACCES)</tt>
- *
- * @var FileError::Code FileError::NAME_TOO_LONG
- * <tt>(ENAMETOOLONG)</tt>
- *
- * @var FileError::Code FileError::NO_SUCH_ENTITY
- * <tt>(ENOENT)</tt>
- *
- * @var FileError::Code FileError::NOT_DIRECTORY
- * <tt>(ENOTDIR)</tt>
- *
- * @var FileError::Code FileError::NO_SUCH_DEVICE
- * <tt>(ENXIO)</tt>
- *
- * @var FileError::Code FileError::NOT_DEVICE
- * <tt>(ENODEV)</tt>
- *
- * @var FileError::Code FileError::READONLY_FILESYSTEM
- * <tt>(EROFS)</tt>
- *
- * @var FileError::Code FileError::TEXT_FILE_BUSY
- * <tt>(ETXTBSY)</tt>
- *
- * @var FileError::Code FileError::FAULTY_ADDRESS
- * <tt>(EFAULT)</tt>
- *
- * @var FileError::Code FileError::SYMLINK_LOOP
- * <tt>(ELOOP)</tt>
- *
- * @var FileError::Code FileError::NO_SPACE_LEFT
- * <tt>(ENOSPC)</tt>
- *
- * @var FileError::Code FileError::NOT_ENOUGH_MEMORY
- * <tt>(ENOMEM)</tt>
- *
- * @var FileError::Code FileError::TOO_MANY_OPEN_FILES
- * <tt>(EMFILE)</tt>
- *
- * @var FileError::Code FileError::FILE_TABLE_OVERFLOW
- * <tt>(ENFILE)</tt>
- *
- * @var FileError::Code FileError::BAD_FILE_DESCRIPTOR
- * <tt>(EBADF)</tt>
- *
- * @var FileError::Code FileError::INVALID_ARGUMENT
- * <tt>(EINVAL)</tt>
- *
- * @var FileError::Code FileError::BROKEN_PIPE
- * <tt>(EPIPE)</tt>
- *
- * @var FileError::Code FileError::TRYAGAIN
- * <tt>(EAGAIN)</tt>
- *
- * We use TRYAGAIN instead of TRY_AGAIN, because that is defined as a macro by a Unix header.
- *
- * @var FileError::Code FileError::INTERRUPTED
- * <tt>(EINTR)</tt>
- *
- * @var FileError::Code FileError::IO_ERROR
- * <tt>(EIO)</tt>
- *
- * @var FileError::Code FileError::NOT_OWNER
- * <tt>(EPERM)</tt>
- *
- * @var FileError::Code FileError::FAILED
- * Returned if no specific code applies.
+ * <tt>(EEXIST)</tt> Operation not permitted; only the owner of the file (or
+ * other resource) or processes with special privileges can perform the operation.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::IS_DIRECTORY
+ * <tt>(EISDIR)</tt> File is a directory; you cannot open a directory for writing,
+ * or create or remove hard links to it.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::ACCESS_DENIED
+ * <tt>(EACCES)</tt> Permission denied; the file permissions do not allow the
+ * attempted operation.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NAME_TOO_LONG
+ * <tt>(ENAMETOOLONG)</tt> Filename too long.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NO_SUCH_ENTITY
+ * <tt>(ENOENT)</tt> No such file or directory.  This is a "file doesn't exist"
+ * error for ordinary files that are referenced in contexts where they are expected
+ * to already exist.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NOT_DIRECTORY
+ * <tt>(ENOTDIR)</tt> A file that isn't a directory was specified when a directory
+ * is required.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NO_SUCH_DEVICE
+ * <tt>(ENXIO)</tt> No such device or address.  The system tried to use the device
+ * represented by a file you specified, and it couldn't find the device. This can
+ * mean that the device file was installed incorrectly, or that the physical device
+ * is missing or not correctly attached to the computer.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NOT_DEVICE
+ * <tt>(ENODEV)</tt> This file is of a type that doesn't support mapping.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::READONLY_FILESYSTEM
+ * <tt>(EROFS)</tt> The directory containing the new link can't be modified
+ * because it's on a read-only file system.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::TEXT_FILE_BUSY
+ * <tt>(ETXTBSY)</tt> Text file busy.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::FAULTY_ADDRESS
+ * <tt>(EFAULT)</tt> You passed in a pointer to bad memory.  (Glib won't
+ * reliably return this, don't pass in pointers to bad memory.)
+ * <br><br>
+ */
+/** @var FileError::Code FileError::SYMLINK_LOOP
+ * <tt>(ELOOP)</tt> Too many levels of symbolic links were encountered in
+ * looking up a file name.  This often indicates a cycle of symbolic links.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NO_SPACE_LEFT
+ * <tt>(ENOSPC)</tt> No space left on device; write operation on a file failed
+ * because the disk is full.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NOT_ENOUGH_MEMORY
+ * <tt>(ENOMEM)</tt> No memory available.  The system cannot allocate more
+ * virtual memory because its capacity is full.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::TOO_MANY_OPEN_FILES
+ * <tt>(EMFILE)</tt> The current process has too many files open and can't
+ * open any more.  Duplicate descriptors do count toward this limit.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::FILE_TABLE_OVERFLOW
+ * <tt>(ENFILE)</tt> There are too many distinct file openings in the
+ * entire system.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::BAD_FILE_DESCRIPTOR
+ * <tt>(EBADF)</tt> Bad file descriptor; for example, I/O on a descriptor
+ * that has been closed or reading from a descriptor open only for writing
+ * (or vice versa).
+ * <br><br>
+ */
+/** @var FileError::Code FileError::INVALID_ARGUMENT
+ * <tt>(EINVAL)</tt> Invalid argument. This is used to indicate various kinds
+ * of problems with passing the wrong argument to a library function.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::BROKEN_PIPE
+ * <tt>(EPIPE)</tt> Broken pipe; there is no process reading from the other
+ * end of a pipe.  Every library function that returns this error code also
+ * generates a <tt>SIGPIPE</tt> signal; this signal terminates the program
+ * if not handled or blocked.  Thus, your program will never actually see
+ * this code unless it has handled or blocked <tt>SIGPIPE</tt>.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::TRYAGAIN
+ * <tt>(EAGAIN)</tt> Resource temporarily unavailable; the call might work
+ * if you try again later.
+ * We used TRYAGAIN instead of TRY_AGAIN, because that is a defined as a macro by a Unix header.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::INTERRUPTED
+ * <tt>(EINTR)</tt> Interrupted function call; an asynchronous signal occurred
+ * and prevented completion of the call.  When this happens, you should try
+ * the call again.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::IO_ERROR
+ * <tt>(EIO)</tt> Input/output error; usually used for physical read or write
+ * errors.  I.e. the disk or other physical device hardware is returning errors.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::NOT_OWNER
+ * <tt>(EPERM)</tt> Operation not permitted; only the owner of the file (or other
+ * resource) or processes with special privileges can perform the operation.
+ * <br><br>
+ */
+/** @var FileError::Code FileError::FAILED
+ * Does not correspond to a UNIX error code; this is the standard "failed for
+ * unspecified reason" error code present in all Glib::Error error code
+ * enumerations.  Returned if no specific code applies.
  */
 
-class Dir;
+class GLIBMM_API Dir;
 
 /** The iterator type of Glib::Dir.
  * @ingroup FileUtils
  */
-class DirIterator
+class GLIBMM_API DirIterator
 {
 public:
   typedef std::input_iterator_tag   iterator_category;
@@ -186,7 +254,7 @@ private:
  * @note The encoding of the directory entries isn't necessarily UTF-8.
  * Use Glib::filename_to_utf8() if you need to display them.
  */
-class Dir
+class GLIBMM_API Dir
 {
 public:
   using iterator = DirIterator;
@@ -263,6 +331,7 @@ private:
  * @param test Bitfield of Glib::FileTest flags.
  * @return Whether a test was true.
  */
+GLIBMM_API
 bool file_test(const std::string& filename, FileTest test);
 
 /** Opens a temporary file.
@@ -278,6 +347,7 @@ bool file_test(const std::string& filename, FileTest test);
  *   is a difference. The file handle should be closed with close(). In
  *   case of errors, <tt>-1</tt> is returned.
  */
+GLIBMM_API
 int mkstemp(std::string& filename_template);
 
 /** Opens a file for writing in the preferred directory for temporary files
@@ -295,6 +365,7 @@ int mkstemp(std::string& filename_template);
  * difference. The file handle should be closed with <tt>close()</tt>.
  * @throw Glib::FileError
  */
+GLIBMM_API
 int file_open_tmp(std::string& name_used, const std::string& prefix);
 
 /** Opens a file for writing in the preferred directory for temporary files
@@ -309,6 +380,7 @@ int file_open_tmp(std::string& name_used, const std::string& prefix);
  * difference. The file handle should be closed with <tt>close()</tt>.
  * @throw Glib::FileError
  */
+GLIBMM_API
 int file_open_tmp(std::string& name_used);
 
 /** Reads an entire file into a string, with good error checking.
@@ -317,6 +389,7 @@ int file_open_tmp(std::string& name_used);
  * @return The file contents.
  * @throw Glib::FileError
  */
+GLIBMM_API
 std::string file_get_contents(const std::string& filename);
 
 /** Writes all of @a contents to a file named @a filename, with good error checking.
@@ -354,11 +427,13 @@ std::string file_get_contents(const std::string& filename);
  *
  * @newin{2,22}
  **/
+GLIBMM_API
 void file_set_contents (const std::string& filename, const gchar *contents, gssize length);
 /** A variant of file_set_contents which accepts a standard C++ string
  *
  * @newin{2,22}
  * */
+GLIBMM_API
 void file_set_contents (const std::string& filename, const std::string& contents);
 
 } // namespace Glib
index 9604e1f..21f0a75 100644 (file)
@@ -20,7 +20,10 @@ Since: 2.26
 <property name="GBinding:source-property">
 <description>
 The name of the property of #GBinding:source that should be used
-as the source of the binding
+as the source of the binding.
+
+This should be in [canonical form][canonical-parameter-names] to get the
+best performance.
 
 Since: 2.26
 
@@ -39,7 +42,10 @@ Since: 2.26
 <property name="GBinding:target-property">
 <description>
 The name of the property of #GBinding:target that should be used
-as the target of the binding
+as the target of the binding.
+
+This should be in [canonical form][canonical-parameter-names] to get the
+best performance.
 
 Since: 2.26
 
@@ -2115,7 +2121,7 @@ match signals by.
 </parameter_description>
 </parameter>
 <parameter name="G_SIGNAL_MATCH_DETAIL">
-<parameter_description> The signal detail be equal.
+<parameter_description> The signal detail must be equal.
 </parameter_description>
 </parameter>
 <parameter name="G_SIGNAL_MATCH_CLOSURE">
@@ -2131,7 +2137,7 @@ match signals by.
 </parameter_description>
 </parameter>
 <parameter name="G_SIGNAL_MATCH_UNBLOCKED">
-<parameter_description> Only unblocked signals may matched.
+<parameter_description> Only unblocked signals may be matched.
 </parameter_description>
 </parameter>
 </parameters>
@@ -3903,6 +3909,10 @@ Error codes returned by parsing text-format GVariants.
 <parameter_description> no value given
 </parameter_description>
 </parameter>
+<parameter name="G_VARIANT_PARSE_ERROR_RECURSION">
+<parameter_description> variant was too deeply nested; #GVariant is only guaranteed to handle nesting up to 64 levels (Since: 2.64)
+</parameter_description>
+</parameter>
 </parameters>
 </enum>
 
@@ -4607,6 +4617,47 @@ This did not actually work, so any such code should be removed.
 <return></return>
 </function>
 
+<function name="g_array_steal">
+<description>
+Frees the data in the array and resets the size to zero, while
+the underlying array is preserved for use elsewhere and returned
+to the caller.
+
+If the array was created with the @zero_terminate property
+set to %TRUE, the returned data is zero terminated too.
+
+If array elements contain dynamically-allocated memory,
+the array elements should also be freed by the caller.
+
+A short example of use:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+...
+gpointer data;
+gsize data_len;
+data = g_array_steal (some_array, &amp;data_len);
+...
+]|
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="array">
+<parameter_description> a #GArray.
+</parameter_description>
+</parameter>
+<parameter name="len">
+<parameter_description> pointer to retrieve the number of
+elements of the original array
+</parameter_description>
+</parameter>
+</parameters>
+<return> the element data, which should be
+freed using g_free().
+
+</return>
+</function>
+
 <function name="g_array_unref">
 <description>
 Atomically decrements the reference count of @array by one. If the
@@ -5434,7 +5485,7 @@ Since: 2.16
 </description>
 <parameters>
 <parameter name="n1">
-<parameter_description> an floating point number
+<parameter_description> a floating point number
 </parameter_description>
 </parameter>
 <parameter name="cmp">
@@ -5464,7 +5515,7 @@ Since: 2.58
 </description>
 <parameters>
 <parameter name="n1">
-<parameter_description> an floating point number
+<parameter_description> a floating point number
 </parameter_description>
 </parameter>
 <parameter name="n2">
@@ -5549,6 +5600,8 @@ the same as `g_assert_true (l1 == l2 &amp;&amp; memcmp (m1, m2, l1) == 0)`.
 The advantage of this macro is that it can produce a message that
 includes the actual values of @l1 and @l2.
 
+@m1 may be %NULL if (and only if) @l1 is zero; similarly for @m2 and @l2.
+
 |[&lt;!-- language=&quot;C&quot; --&gt;
 g_assert_cmpmem (buf-&gt;data, buf-&gt;len, expected, sizeof (expected));
 ]|
@@ -7781,10 +7834,10 @@ The output buffer must be large enough to fit all the data that will
 be written to it. Due to the way base64 encodes you will need
 at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of
 non-zero state). If you enable line-breaking you will need at least:
-((@len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space.
+((@len / 3 + 1) * 4 + 4) / 76 + 1 bytes of extra space.
 
 @break_lines is typically used when putting base64-encoded data in emails.
-It breaks the lines at 72 columns instead of putting all of the text on
+It breaks the lines at 76 columns instead of putting all of the text on
 the same line. This avoids problems with long lines in the email system.
 Note however that it breaks the lines with `LF` characters, not
 `CR LF` sequences, so the result cannot be passed directly to SMTP
@@ -9892,6 +9945,32 @@ user data argument.
 <return></return>
 </function>
 
+<function name="g_byte_array_steal">
+<description>
+Frees the data in the array and resets the size to zero, while
+the underlying array is preserved for use elsewhere and returned
+to the caller.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="array">
+<parameter_description> a #GByteArray.
+</parameter_description>
+</parameter>
+<parameter name="len">
+<parameter_description> pointer to retrieve the number of
+elements of the original array
+</parameter_description>
+</parameter>
+</parameters>
+<return> the element data, which should be
+freed using g_free().
+
+</return>
+</function>
+
 <function name="g_byte_array_unref">
 <description>
 Atomically decrements the reference count of @array by one. If the
@@ -12619,7 +12698,7 @@ After the call it contains the length of the digest.
 
 <function name="g_checksum_get_string">
 <description>
-Gets the digest as an hexadecimal string.
+Gets the digest as a hexadecimal string.
 
 Once this function has been called the #GChecksum can no longer be
 updated with g_checksum_update().
@@ -12966,6 +13045,28 @@ Since: 2.56
 <return></return>
 </function>
 
+<function name="g_clear_list">
+<description>
+Clears a pointer to a #GList, freeing it and, optionally, freeing its elements using @destroy.
+
+@list_ptr must be a valid pointer. If @list_ptr points to a null #GList, this does nothing.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="list_ptr">
+<parameter_description> a #GList return location
+</parameter_description>
+</parameter>
+<parameter name="destroy">
+<parameter_description> the function to pass to g_list_free_full() or %NULL to not free elements
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
 <function name="g_clear_object">
 <description>
 Clears a reference to a #GObject.
@@ -13052,6 +13153,28 @@ Since: 2.62
 <return></return>
 </function>
 
+<function name="g_clear_slist">
+<description>
+Clears a pointer to a #GSList, freeing it and, optionally, freeing its elements using @destroy.
+
+@slist_ptr must be a valid pointer. If @slist_ptr points to a null #GSList, this does nothing.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="slist_ptr">
+<parameter_description> a #GSList return location
+</parameter_description>
+</parameter>
+<parameter name="destroy">
+<parameter_description> the function to pass to g_slist_free_full() or %NULL to not free elements
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
 <function name="g_clear_weak_pointer">
 <description>
 Clears a weak reference to a #GObject.
@@ -16988,9 +17111,17 @@ Since: 2.26
 <description>
 Creates a #GDateTime corresponding to the given
 [ISO 8601 formatted string](https://en.wikipedia.org/wiki/ISO_8601)
-@text. ISO 8601 strings of the form &lt;date&gt;&lt;sep&gt;&lt;time&gt;&lt;tz&gt; are supported.
+@text. ISO 8601 strings of the form &lt;date&gt;&lt;sep&gt;&lt;time&gt;&lt;tz&gt; are supported, with
+some extensions from [RFC 3339](https://tools.ietf.org/html/rfc3339) as
+mentioned below.
+
+Note that as #GDateTime &quot;is oblivious to leap seconds&quot;, leap seconds information
+in an ISO-8601 string will be ignored, so a `23:59:60` time would be parsed as
+`23:59:59`.
 
-&lt;sep&gt; is the separator and can be either 'T', 't' or ' '.
+&lt;sep&gt; is the separator and can be either 'T', 't' or ' '. The latter two
+separators are an extension from
+[RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6).
 
 &lt;date&gt; is in the form:
 
@@ -19041,8 +19172,8 @@ including the type suffix.
 </parameter_description>
 </parameter>
 </parameters>
-<return> a newly-allocated string with the absolute path,
-or %NULL
+<return> a newly-allocated
+string with the absolute path, or %NULL
 </return>
 </function>
 
@@ -19189,17 +19320,22 @@ Since: 2.54
 
 <function name="g_fopen">
 <description>
-A wrapper for the stdio fopen() function. The fopen() function
+A wrapper for the stdio `fopen()` function. The `fopen()` function
 opens a file and associates a new stream with it.
 
 Because file descriptors are specific to the C library on Windows,
-and a file descriptor is part of the FILE struct, the FILE* returned
+and a file descriptor is part of the `FILE` struct, the `FILE*` returned
 by this function makes sense only to functions in the same C library.
 Thus if the GLib-using code uses a different C library than GLib does,
 the FILE* returned by this function cannot be passed to C library
-functions like fprintf() or fread().
+functions like `fprintf()` or `fread()`.
 
-See your C library manual for more details about fopen().
+See your C library manual for more details about `fopen()`.
+
+As `close()` and `fclose()` are part of the C library, this implies that it is
+currently impossible to close a file if the application C library and the C library
+used by GLib are different. Convenience functions like g_file_set_contents()
+avoid this problem.
 
 Since: 2.6
 
@@ -19215,7 +19351,7 @@ Since: 2.6
 </parameter_description>
 </parameter>
 </parameters>
-<return> A FILE* if the file was successfully opened, or %NULL if
+<return> A `FILE*` if the file was successfully opened, or %NULL if
 an error occurred
 
 </return>
@@ -19246,8 +19382,8 @@ Since: 2.30
 </parameter_description>
 </parameter>
 </parameters>
-<return> a newly-allocated formatted string containing a human readable
-file size
+<return> a newly-allocated formatted string containing
+a human readable file size
 
 </return>
 </function>
@@ -19276,8 +19412,8 @@ suffixes to denote IEC units. Use g_format_size() instead.
 </parameter_description>
 </parameter>
 </parameters>
-<return> a newly-allocated formatted string containing a human
-readable file size
+<return> a newly-allocated formatted string
+containing a human readable file size
 
 </return>
 </function>
@@ -19302,8 +19438,8 @@ Since: 2.30
 </parameter_description>
 </parameter>
 </parameters>
-<return> a newly-allocated formatted string containing a human
-readable file size
+<return> a newly-allocated formatted string
+containing a human readable file size
 
 </return>
 </function>
@@ -19386,6 +19522,29 @@ an error occurred.
 </return>
 </function>
 
+<function name="g_fsync">
+<description>
+A wrapper for the POSIX fsync() function (_commit() on Windows).
+The fsync() function is used to synchronize a file's in-core
+state with that of the disk.
+
+See the C library manual for more details about fsync().
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="fd">
+<parameter_description> a file descriptor
+</parameter_description>
+</parameter>
+</parameters>
+<return> 0 on success, or -1 if an error occurred.
+The return value can be used exactly like the return value from fsync().
+
+</return>
+</function>
+
 <function name="g_get_application_name">
 <description>
 Gets a human-readable name for the application, as set by
@@ -19401,7 +19560,8 @@ Since: 2.2
 </description>
 <parameters>
 </parameters>
-<return> human-readable application name. may return %NULL
+<return> human-readable application
+name. May return %NULL
 
 </return>
 </function>
@@ -19713,10 +19873,15 @@ It must not be modified or freed. It must be copied if planned to be used in ano
 Returns a list of derived variants of @locale, which can be used to
 e.g. construct locale-dependent filenames or search paths. The returned
 list is sorted from most desirable to least desirable.
-This function handles territory, charset and extra locale modifiers.
+This function handles territory, charset and extra locale modifiers. See
+[`setlocale(3)`](man:setlocale) for information about locales and their format.
+
+@locale itself is guaranteed to be returned in the output.
 
-For example, if @locale is &quot;fr_BE&quot;, then the returned list
-is &quot;fr_BE&quot;, &quot;fr&quot;.
+For example, if @locale is `fr_BE`, then the returned list
+is `fr_BE`, `fr`. If @locale is `en_GB.UTF-8@euro`, then the returned list
+is `en_GB.UTF-8@euro`, `en_GB.UTF-8`, `en_GB@euro`, `en_GB`, `en.UTF-8@euro`,
+`en.UTF-8`, `en@euro`, `en`.
 
 If you need the list of variants for the current locale,
 use g_get_language_names().
@@ -19777,6 +19942,32 @@ Since: 2.36
 </return>
 </function>
 
+<function name="g_get_os_info">
+<description>
+Get information about the operating system.
+
+On Linux this comes from the `/etc/os-release` file. On other systems, it may
+come from a variety of sources. You can either use the standard key names
+like %G_OS_INFO_KEY_NAME or pass any UTF-8 string key name. For example,
+`/etc/os-release` provides a number of other less commonly used values that may
+be useful. No key is guaranteed to be provided, so the caller should always
+check if the result is %NULL.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="key_name">
+<parameter_description> a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
+</parameter_description>
+</parameter>
+</parameters>
+<return> The associated value for the requested key or %NULL if
+this information is not provided.
+
+</return>
+</function>
+
 <function name="g_get_prgname">
 <description>
 Gets the name of the program. This name should not be localized,
@@ -19792,8 +19983,8 @@ taking the last component of @argv[0].
 </description>
 <parameters>
 </parameters>
-<return> the name of the program, or %NULL if it has not been
-set yet. The returned string belongs
+<return> the name of the program,
+or %NULL if it has not been set yet. The returned string belongs
 to GLib and must not be modified or freed.
 </return>
 </function>
@@ -19960,8 +20151,8 @@ Since: 2.6
 </description>
 <parameters>
 </parameters>
-<return> a string owned by GLib that must not be modified
-or freed.
+<return> a string owned by GLib that
+must not be modified or freed.
 </return>
 </function>
 
@@ -19987,8 +20178,8 @@ Since: 2.6
 </description>
 <parameters>
 </parameters>
-<return> a string owned by GLib that must not be modified
-or freed.
+<return> a string owned by GLib that
+must not be modified or freed.
 </return>
 </function>
 
@@ -20014,8 +20205,9 @@ Since: 2.6
 </description>
 <parameters>
 </parameters>
-<return> a string owned by GLib that must not be modified
-or freed.
+<return> a string owned by GLib that must
+not be modified or freed.
+
 </return>
 </function>
 
@@ -20118,6 +20310,10 @@ This is a convenience function for using a #GHashTable as a set.  It
 is equivalent to calling g_hash_table_replace() with @key as both the
 key and the value.
 
+In particular, this means that if @key already exists in the hash table, then
+the old copy of @key in the hash table is freed and @key replaces it in the
+table.
+
 When a hash table only ever contains keys that have themselves as the
 corresponding value it is able to be stored more efficiently.  See
 the discussion in the section description.
@@ -20234,6 +20430,9 @@ be modified while iterating over it (you can't add/remove
 items). To remove all items matching a predicate, use
 g_hash_table_foreach_remove().
 
+The order in which g_hash_table_foreach() iterates over the keys/values in
+the hash table is not defined.
+
 See g_hash_table_find() for performance caveats for linear
 order searches in contrast to g_hash_table_lookup().
 
@@ -20480,6 +20679,10 @@ Since: 2.16
 Initializes a key/value pair iterator and associates it with
 @hash_table. Modifying the hash table after calling this function
 invalidates the returned iterator.
+
+The iteration order of a #GHashTableIter over the keys/values in a hash
+table is not defined.
+
 |[&lt;!-- language=&quot;C&quot; --&gt;
 GHashTableIter iter;
 gpointer key, value;
@@ -21028,7 +21231,7 @@ size of @buffer. After the call it contains the length of the digest
 
 <function name="g_hmac_get_string">
 <description>
-Gets the HMAC as an hexadecimal string.
+Gets the HMAC as a hexadecimal string.
 
 Once this function has been called the #GHmac can no longer be
 updated with g_hmac_update().
@@ -23271,6 +23474,9 @@ Creates a #GSource that's dispatched when @condition is met for the
 given @channel. For example, if condition is #G_IO_IN, the source will 
 be dispatched when there's data available for reading.
 
+The callback function invoked by the #GSource should be added with
+g_source_set_callback(), but it has type #GIOFunc (not #GSourceFunc).
+
 g_io_add_watch() is a simpler interface to this same functionality, for 
 the case where you want to add the source to the default main loop context 
 at the default priority.
@@ -24520,7 +24726,7 @@ Since: 2.12
 </parameter_description>
 </parameter>
 <parameter name="value">
-<parameter_description> an double value
+<parameter_description> a double value
 </parameter_description>
 </parameter>
 </parameters>
@@ -25195,6 +25401,13 @@ The freed elements are returned to the slice allocator.
 If list elements contain dynamically-allocated memory, you should
 either use g_list_free_full() or free them manually first.
 
+It can be combined with g_steal_pointer() to ensure the list head pointer
+is not left dangling:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+GList *list_of_borrowed_things = â€¦;  /&lt;!-- --&gt;* (transfer container) *&lt;!-- --&gt;/
+g_list_free (g_steal_pointer (&amp;list_of_borrowed_things));
+]|
+
 </description>
 <parameters>
 <parameter name="list">
@@ -25241,6 +25454,15 @@ and calls @free_func on every element's data.
 @free_func must not modify the list (eg, by removing the freed
 element from it).
 
+It can be combined with g_steal_pointer() to ensure the list head pointer
+is not left dangling Â­â€” this also has the nice property that the head pointer
+is cleared before any of the list elements are freed, to prevent double frees
+from @free_func:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+GList *list_of_owned_things = â€¦;  /&lt;!-- --&gt;* (transfer full) (element-type GObject) *&lt;!-- --&gt;/
+g_list_free_full (g_steal_pointer (&amp;list_of_owned_things), g_object_unref);
+]|
+
 Since: 2.28
 
 </description>
@@ -27200,6 +27422,79 @@ Since: 2.22
 <return></return>
 </function>
 
+<function name="g_main_context_pusher_free">
+<description>
+Pop @pusher’s main context as the thread default main context.
+See g_main_context_pusher_new() for details.
+
+This will pop the #GMainContext as the current thread-default main context,
+but will not call g_main_context_unref() on it.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="pusher">
+<parameter_description> a #GMainContextPusher
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
+<function name="g_main_context_pusher_new">
+<description>
+Push @main_context as the new thread-default main context for the current
+thread, using g_main_context_push_thread_default(), and return a new
+#GMainContextPusher. Pop with g_main_context_pusher_free(). Using
+g_main_context_pop_thread_default() on @main_context while a
+#GMainContextPusher exists for it can lead to undefined behaviour.
+
+Using two #GMainContextPushers in the same scope is not allowed, as it leads
+to an undefined pop order.
+
+This is intended to be used with g_autoptr().  Note that g_autoptr()
+is only available when using GCC or clang, so the following example
+will only work with those compilers:
+|[
+typedef struct
+{
+...
+GMainContext *context;
+...
+} MyObject;
+
+static void
+my_object_do_stuff (MyObject *self)
+{
+g_autoptr(GMainContextPusher) pusher = g_main_context_pusher_new (self-&gt;context);
+
+// Code with main context as the thread default here
+
+if (cond)
+// No need to pop
+return;
+
+// Optionally early pop
+g_clear_pointer (&amp;pusher, g_main_context_pusher_free);
+
+// Code with main context no longer the thread default here
+}
+]|
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="main_context">
+<parameter_description> a main context to push
+</parameter_description>
+</parameter>
+</parameters>
+<return> a #GMainContextPusher
+</return>
+</function>
+
 <function name="g_main_context_query">
 <description>
 Determines information necessary to poll this main loop.
@@ -29124,7 +29419,7 @@ includes the key `gc-friendly`.
 <description>
 Checks whether the allocator used by g_malloc() is the system's
 malloc implementation. If it returns %TRUE memory allocated with
-malloc() can be used interchangeable with memory allocated using g_malloc().
+malloc() can be used interchangeably with memory allocated using g_malloc().
 This function is useful for avoiding an extra copy of allocated memory returned
 by a non-GLib-based API.
 
@@ -29542,7 +29837,7 @@ If that fails and @file_name has the &quot;.la&quot;-suffix (and is a libtool
 archive) it tries to open the corresponding module. If that fails
 and it doesn't have the proper module suffix for the platform
 (#G_MODULE_SUFFIX), this suffix will be appended and the corresponding
-module will be opended. If that fails and @file_name doesn't have the
+module will be opened. If that fails and @file_name doesn't have the
 &quot;.la&quot;-suffix, this suffix is appended and g_module_open() tries to open
 the corresponding module. If eventually that fails as well, %NULL is
 returned.
@@ -29708,6 +30003,8 @@ already been locked by the same thread results in undefined behaviour
 <description>
 Unlock @locker's mutex. See g_mutex_locker_new() for details.
 
+No memory is freed, it is equivalent to a g_mutex_unlock() call.
+
 Since: 2.44
 
 </description>
@@ -29726,6 +30023,8 @@ Lock @mutex and return a new #GMutexLocker. Unlock with
 g_mutex_locker_free(). Using g_mutex_unlock() on @mutex
 while a #GMutexLocker exists can lead to undefined behaviour.
 
+No allocation is performed, it is equivalent to a g_mutex_lock() call.
+
 This is intended to be used with g_autoptr().  Note that g_autoptr()
 is only available when using GCC or clang, so the following example
 will only work with those compilers:
@@ -31157,7 +31456,7 @@ A convenience function to connect multiple signals at once.
 
 The signal specs expected by this function have the form
 &quot;modifier::signal_name&quot;, where modifier can be one of the following:
-- signal: equivalent to g_signal_connect_data (..., NULL, 0)
+- signal: equivalent to g_signal_connect_data (..., NULL, 0)
 - object-signal, object_signal: equivalent to g_signal_connect_object (..., 0)
 - swapped-signal, swapped_signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED)
 - swapped_object_signal, swapped-object-signal: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED)
@@ -31373,16 +31672,18 @@ Here is an example of using g_object_get() to get the contents
 of three properties: an integer, a string and an object:
 |[&lt;!-- language=&quot;C&quot; --&gt; 
 gint intval;
+guint64 uint64val;
 gchar *strval;
 GObject *objval;
 
 g_object_get (my_object,
 &quot;int-property&quot;, &amp;intval,
+&quot;uint64-property&quot;, &amp;uint64val,
 &quot;str-property&quot;, &amp;strval,
 &quot;obj-property&quot;, &amp;objval,
 NULL);
 
-// Do something with intval, strval, objval
+// Do something with intval, uint64val, strval, objval
 
 g_free (strval);
 g_object_unref (objval);
@@ -31667,6 +31968,20 @@ Creates a new instance of a #GObject subtype and sets its properties.
 Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY)
 which are not explicitly specified are set to their default values.
 
+Note that in C, small integer types in variable argument lists are promoted
+up to #gint or #guint as appropriate, and read back accordingly. #gint is 32
+bits on every platform on which GLib is currently supported. This means that
+you can use C expressions of type #gint with g_object_new() and properties of
+type #gint or #guint or smaller. Specifically, you can use integer literals
+with these property types.
+
+When using property types of #gint64 or #guint64, you must ensure that the
+value that you provide is 64 bit. This means that you should use a cast or
+make use of the %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
+
+Similarly, #gfloat is promoted to #gdouble, so you must ensure that the value
+you provide is a #gdouble, even for a property of type #gfloat.
+
 
 </description>
 <parameters>
@@ -32091,6 +32406,11 @@ This function should only be called from object system implementations.
 <description>
 Sets properties on an object.
 
+The same caveats about passing integer literals as varargs apply as with
+g_object_new(). In particular, any integer literals set as the values for
+properties of type #gint64 or #guint64 must be 64 bits wide, using the
+%G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
+
 Note that the &quot;notify&quot; signals are queued and only emitted (in
 reverse order) after all properties have been set. See
 g_object_freeze_notify().
@@ -33091,8 +33411,10 @@ Since: 2.40
 </parameter_description>
 </parameter>
 <parameter name="arguments">
-<parameter_description> a pointer to the
-command line arguments (which must be in UTF-8 on Windows)
+<parameter_description> a pointer
+to the command line arguments (which must be in UTF-8 on Windows).
+Starting with GLib 2.62, @arguments can be %NULL, which matches
+g_option_context_parse().
 </parameter_description>
 </parameter>
 <parameter name="error">
@@ -34092,15 +34414,9 @@ See g_param_spec_internal() for details on property names.
 <description>
 Creates a new #GParamSpec instance.
 
-A property name consists of segments consisting of ASCII letters and
-digits, separated by either the '-' or '_' character. The first
-character of a property name must be a letter. Names which violate these
-rules lead to undefined behaviour.
-
-When creating and looking up a #GParamSpec, either separator can be
-used, but they cannot be mixed. Using '-' is considerably more
-efficient and in fact required when using property names as detail
-strings for signals.
+See [canonical parameter names][canonical-parameter-names] for details of
+the rules for @name. Names which violate these rules lead to undefined
+behaviour.
 
 Beyond the name, #GParamSpecs have two more descriptive
 strings associated with them, the @nick, which should be suitable
@@ -35003,7 +35319,8 @@ Sets @value to its default value as specified in @pspec.
 </parameter_description>
 </parameter>
 <parameter name="value">
-<parameter_description> a #GValue of correct type for @pspec
+<parameter_description> a #GValue of correct type for @pspec; since 2.64, you
+can also pass an empty #GValue, initialized with %G_VALUE_INIT
 </parameter_description>
 </parameter>
 </parameters>
@@ -36337,7 +36654,32 @@ greater than second arg).
 
 Note that the comparison function for g_ptr_array_sort() doesn't
 take the pointers from the array as arguments, it takes pointers to
-the pointers in the array.
+the pointers in the array. Here is a full example of usage:
+
+|[&lt;!-- language=&quot;C&quot; --&gt;
+typedef struct
+{
+gchar *name;
+gint size;
+} FileListEntry;
+
+static gint
+sort_filelist (gconstpointer a, gconstpointer b)
+{
+const FileListEntry *entry1 = *((FileListEntry **) a);
+const FileListEntry *entry2 = *((FileListEntry **) b);
+
+return g_ascii_strcasecmp (entry1-&gt;name, entry2-&gt;name);
+}
+
+…
+g_autoptr (GPtrArray) file_list = NULL;
+
+// initialize file_list array and load with many FileListEntry entries
+...
+// now sort it with
+g_ptr_array_sort (file_list, sort_filelist);
+]|
 
 This is guaranteed to be a stable sort since version 2.32.
 
@@ -36362,7 +36704,52 @@ user data argument.
 
 Note that the comparison function for g_ptr_array_sort_with_data()
 doesn't take the pointers from the array as arguments, it takes
-pointers to the pointers in the array.
+pointers to the pointers in the array. Here is a full example of use:
+
+|[&lt;!-- language=&quot;C&quot; --&gt;
+typedef enum { SORT_NAME, SORT_SIZE } SortMode;
+
+typedef struct
+{
+gchar *name;
+gint size;
+} FileListEntry;
+
+static gint
+sort_filelist (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+gint order;
+const SortMode sort_mode = GPOINTER_TO_INT (user_data);
+const FileListEntry *entry1 = *((FileListEntry **) a);
+const FileListEntry *entry2 = *((FileListEntry **) b);
+
+switch (sort_mode)
+{
+case SORT_NAME:
+order = g_ascii_strcasecmp (entry1-&gt;name, entry2-&gt;name);
+break;
+case SORT_SIZE:
+order = entry1-&gt;size - entry2-&gt;size;
+break;
+default:
+order = 0;
+break;
+}
+return order;
+}
+
+...
+g_autoptr (GPtrArray) file_list = NULL;
+SortMode sort_mode;
+
+// initialize file_list array and load with many FileListEntry entries
+...
+// now sort it with
+sort_mode = SORT_NAME;
+g_ptr_array_sort_with_data (file_list,
+sort_filelist,
+GINT_TO_POINTER (sort_mode));
+]|
 
 This is guaranteed to be a stable sort since version 2.32.
 
@@ -36384,6 +36771,69 @@ This is guaranteed to be a stable sort since version 2.32.
 <return></return>
 </function>
 
+<function name="g_ptr_array_steal">
+<description>
+Frees the data in the array and resets the size to zero, while
+the underlying array is preserved for use elsewhere and returned
+to the caller.
+
+Even if set, the #GDestroyNotify function will never be called
+on the current contents of the array and the caller is
+responsible for freeing the array elements.
+
+An example of use:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+g_autoptr(GPtrArray) chunk_buffer = g_ptr_array_new_with_free_func (g_bytes_unref);
+
+// Some part of your application appends a number of chunks to the pointer array.
+g_ptr_array_add (chunk_buffer, g_bytes_new_static (&quot;hello&quot;, 5));
+g_ptr_array_add (chunk_buffer, g_bytes_new_static (&quot;world&quot;, 5));
+
+…
+
+// Periodically, the chunks need to be sent as an array-and-length to some
+// other part of the program.
+GBytes **chunks;
+gsize n_chunks;
+
+chunks = g_ptr_array_steal (chunk_buffer, &amp;n_chunks);
+for (gsize i = 0; i &lt; n_chunks; i++)
+{
+// Do something with each chunk here, and then free them, since
+// g_ptr_array_steal() transfers ownership of all the elements and the
+// array to the caller.
+…
+
+g_bytes_unref (chunks[i]);
+}
+
+g_free (chunks);
+
+// After calling g_ptr_array_steal(), the pointer array can be reused for the
+// next set of chunks.
+g_assert (chunk_buffer-&gt;len == 0);
+]|
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="array">
+<parameter_description> a #GPtrArray.
+</parameter_description>
+</parameter>
+<parameter name="len">
+<parameter_description> pointer to retrieve the number of
+elements of the original array
+</parameter_description>
+</parameter>
+</parameters>
+<return> the element data, which should be
+freed using g_free().
+
+</return>
+</function>
+
 <function name="g_ptr_array_steal_index">
 <description>
 Removes the pointer at the given index from the pointer array.
@@ -37501,7 +37951,7 @@ Since: 2.4
 <function name="g_rand_boolean">
 <description>
 Returns a random #gboolean from @rand_.
-This corresponds to a unbiased coin toss.
+This corresponds to an unbiased coin toss.
 
 
 </description>
@@ -37737,7 +38187,7 @@ Since: 2.4
 <function name="g_random_boolean">
 <description>
 Returns a random #gboolean.
-This corresponds to a unbiased coin toss.
+This corresponds to an unbiased coin toss.
 
 
 </description>
@@ -38173,6 +38623,8 @@ Since: 2.32
 <description>
 Unlock @locker's recursive mutex. See g_rec_mutex_locker_new() for details.
 
+No memory is freed, it is equivalent to a g_rec_mutex_unlock() call.
+
 Since: 2.60
 
 </description>
@@ -38191,6 +38643,8 @@ Lock @rec_mutex and return a new #GRecMutexLocker. Unlock with
 g_rec_mutex_locker_free(). Using g_rec_mutex_unlock() on @rec_mutex
 while a #GRecMutexLocker exists can lead to undefined behaviour.
 
+No allocation is performed, it is equivalent to a g_rec_mutex_lock() call.
+
 This is intended to be used with g_autoptr().  Note that g_autoptr()
 is only available when using GCC or clang, so the following example
 will only work with those compilers:
@@ -39308,7 +39762,7 @@ token.
 
 As a special case, the result of splitting the empty string &quot;&quot; is an
 empty vector, not a vector containing a single string. The reason for
-this special case is that being able to represent a empty vector is
+this special case is that being able to represent an empty vector is
 typically more useful than consistent handling of empty elements. If
 you do need to represent empty elements, you'll need to check for the
 empty string before calling this function.
@@ -39351,7 +39805,7 @@ token.
 
 As a special case, the result of splitting the empty string &quot;&quot; is an
 empty vector, not a vector containing a single string. The reason for
-this special case is that being able to represent a empty vector is
+this special case is that being able to represent an empty vector is
 typically more useful than consistent handling of empty elements. If
 you do need to represent empty elements, you'll need to check for the
 empty string before calling this function.
@@ -39425,7 +39879,7 @@ g_regex_new() and then use g_regex_split().
 As a special case, the result of splitting the empty string &quot;&quot;
 is an empty vector, not a vector containing a single string.
 The reason for this special case is that being able to represent
-a empty vector is typically more useful than consistent handling
+an empty vector is typically more useful than consistent handling
 of empty elements. If you do need to represent empty elements,
 you'll need to check for the empty string before calling this
 function.
@@ -40040,6 +40494,8 @@ Since: 2.32
 Release a read lock on @locker's read-write lock. See
 g_rw_lock_reader_locker_new() for details.
 
+No memory is freed, it is equivalent to a g_rw_lock_reader_unlock() call.
+
 Since: 2.62
 
 </description>
@@ -40059,6 +40515,8 @@ Unlock with g_rw_lock_reader_locker_free(). Using g_rw_lock_reader_unlock()
 on @rw_lock while a #GRWLockReaderLocker exists can lead to undefined
 behaviour.
 
+No allocation is performed, it is equivalent to a g_rw_lock_reader_lock() call.
+
 This is intended to be used with g_autoptr(). For a code sample, see
 g_rw_lock_writer_locker_new().
 
@@ -40137,6 +40595,8 @@ Since: 2.32
 Release a write lock on @locker's read-write lock. See
 g_rw_lock_writer_locker_new() for details.
 
+No memory is freed, it is equivalent to a g_rw_lock_writer_unlock() call.
+
 Since: 2.62
 
 </description>
@@ -40156,6 +40616,8 @@ Unlock with g_rw_lock_writer_locker_free(). Using g_rw_lock_writer_unlock()
 on @rw_lock while a #GRWLockWriterLocker exists can lead to undefined
 behaviour.
 
+No allocation is performed, it is equivalent to a g_rw_lock_writer_lock() call.
+
 This is intended to be used with g_autoptr().  Note that g_autoptr()
 is only available when using GCC or clang, so the following example
 will only work with those compilers:
@@ -43241,6 +43703,10 @@ somewhat faster than using the name each time.
 
 Also tries the ancestors of the given type.
 
+The type class passed as @itype must already have been instantiated (for
+example, using g_type_class_ref()) for this function to work, as signals are
+always installed during class initialization.
+
 See g_signal_new() for details on allowed signal names.
 
 
@@ -43282,12 +43748,14 @@ Two different signals may have the same name, if they have differing types.
 Creates a new signal. (This is usually done in the class initializer.)
 
 A signal name consists of segments consisting of ASCII letters and
-digits, separated by either the '-' or '_' character. The first
+digits, separated by either the `-` or `_` character. The first
 character of a signal name must be a letter. Names which violate these
-rules lead to undefined behaviour of the GSignal system.
+rules lead to undefined behaviour. These are the same rules as for property
+naming (see g_param_spec_internal()).
 
 When registering a signal and looking up a signal, either separator can
-be used, but they cannot be mixed.
+be used, but they cannot be mixed. Using `-` is considerably more efficient.
+Using `_` is discouraged.
 
 If 0 is used for @class_offset subclasses cannot override the class handler
 in their class_init method by doing super_class-&gt;signal_handler = my_signal_handler.
@@ -44404,6 +44872,13 @@ If list elements contain dynamically-allocated memory,
 you should either use g_slist_free_full() or free them manually
 first.
 
+It can be combined with g_steal_pointer() to ensure the list head pointer
+is not left dangling:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+GSList *list_of_borrowed_things = â€¦;  /&lt;!-- --&gt;* (transfer container) *&lt;!-- --&gt;/
+g_slist_free (g_steal_pointer (&amp;list_of_borrowed_things));
+]|
+
 </description>
 <parameters>
 <parameter name="list">
@@ -44449,6 +44924,15 @@ calls the specified destroy function on every element's data.
 @free_func must not modify the list (eg, by removing the freed
 element from it).
 
+It can be combined with g_steal_pointer() to ensure the list head pointer
+is not left dangling Â­â€” this also has the nice property that the head pointer
+is cleared before any of the list elements are freed, to prevent double frees
+from @free_func:
+|[&lt;!-- language=&quot;C&quot; --&gt;
+GSList *list_of_owned_things = â€¦;  /&lt;!-- --&gt;* (transfer full) (element-type GObject) *&lt;!-- --&gt;/
+g_slist_free_full (g_steal_pointer (&amp;list_of_owned_things), g_object_unref);
+]|
+
 Since: 2.28
 
 </description>
@@ -45044,6 +45528,9 @@ Since: 2.36
 Adds a #GSource to a @context so that it will be executed within
 that context. Remove it by calling g_source_destroy().
 
+This function is safe to call from any thread, regardless of which thread
+the @context is running in.
+
 
 </description>
 <parameters>
@@ -45071,6 +45558,9 @@ removed from their context.
 This does not unref the #GSource: if you still hold a reference, use
 g_source_unref() to drop it.
 
+This function is safe to call from any thread, regardless of which thread
+the #GMainContext is running in.
+
 </description>
 <parameters>
 <parameter name="source">
@@ -45705,6 +46195,41 @@ filled in with pointers to appropriate functions.
 <return></return>
 </function>
 
+<function name="g_source_set_dispose_function">
+<description>
+Set @dispose as dispose function on @source. @dispose will be called once
+the reference count of @source reaches 0 but before any of the state of the
+source is freed, especially before the finalize function is called.
+
+This means that at this point @source is still a valid #GSource and it is
+allow for the reference count to increase again until @dispose returns.
+
+The dispose function can be used to clear any &quot;weak&quot; references to the
+@source in other data structures in a thread-safe way where it is possible
+for another thread to increase the reference count of @source again while
+it is being freed.
+
+The finalize function can not be used for this purpose as at that point
+@source is already partially freed and not valid anymore.
+
+This should only ever be called from #GSource implementations.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="source">
+<parameter_description> A #GSource to set the dispose function on
+</parameter_description>
+</parameter>
+<parameter name="dispose">
+<parameter_description> #GSourceDisposeFunc to set on the source
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
 <function name="g_source_set_dummy_callback">
 <description>
 Sets a dummy callback for @source. The callback will do nothing, and
@@ -47704,6 +48229,10 @@ calculates the maximum space required and allocates memory to hold
 the result. The returned string should be freed with g_free() when no
 longer needed.
 
+The returned string is guaranteed to be non-NULL, unless @format
+contains `%lc` or `%ls` conversions, which can fail if no multibyte
+representation is available for the given character.
+
 
 </description>
 <parameters>
@@ -47747,6 +48276,10 @@ calculates the maximum space required and allocates memory to hold
 the result. The returned string should be freed with g_free() when
 no longer needed.
 
+The returned string is guaranteed to be non-NULL, unless @format
+contains `%lc` or `%ls` conversions, which can fail if no multibyte
+representation is available for the given character.
+
 See also g_vasprintf(), which offers the same functionality, but
 additionally returns the length of the allocated string.
 
@@ -49232,7 +49765,7 @@ and &quot;&quot;.
 
 As a special case, the result of splitting the empty string &quot;&quot; is an empty
 vector, not a vector containing a single string. The reason for this
-special case is that being able to represent a empty vector is typically
+special case is that being able to represent an empty vector is typically
 more useful than consistent handling of empty elements. If you do need
 to represent empty elements, you'll need to check for the empty string
 before calling g_strsplit().
@@ -49277,7 +49810,7 @@ vector containing the four strings &quot;&quot;, &quot;def&quot;, &quot;ghi&quot
 
 As a special case, the result of splitting the empty string &quot;&quot; is an empty
 vector, not a vector containing a single string. The reason for this
-special case is that being able to represent a empty vector is typically
+special case is that being able to represent an empty vector is typically
 more useful than consistent handling of empty elements. If you do need
 to represent empty elements, you'll need to check for the empty string
 before calling g_strsplit_set().
@@ -49637,7 +50170,9 @@ Since: 2.34
 This function adds a message to test reports that
 associates a bug URI with a test case.
 Bug URIs are constructed from a base URI set with g_test_bug_base()
-and @bug_uri_snippet.
+and @bug_uri_snippet. If g_test_bug_base() has not been called, it is
+assumed to be the empty string, so a full URI can be provided to
+g_test_bug() instead.
 
 Since: 2.16
 See also: g_test_summary()
@@ -49666,6 +50201,9 @@ Bug URIs are constructed by appending a bug specific URI
 portion to @uri_pattern, or by replacing the special string
 '\%s' within @uri_pattern if that is present.
 
+If g_test_bug_base() is not called, bug URIs are formed solely
+from the value provided by g_test_bug().
+
 Since: 2.16
 
 </description>
@@ -51290,6 +51828,14 @@ multiple #GThreads.
 To free the struct returned by this function, use g_thread_unref().
 Note that g_thread_join() implicitly unrefs the #GThread as well.
 
+New threads by default inherit their scheduler policy (POSIX) or thread
+priority (Windows) of the thread creating the new thread.
+
+This behaviour changed in GLib 2.64: before threads on Windows were not
+inheriting the thread priority but were spawned with the default priority.
+Starting with GLib 2.64 the behaviour is now consistent between Windows and
+POSIX and all threads inherit their parent thread's priority.
+
 Since: 2.32
 
 </description>
@@ -51997,7 +52543,7 @@ Since: 2.26
 
 <function name="g_time_zone_find_interval">
 <description>
-Finds an the interval within @tz that corresponds to the given @time_.
+Finds an interval within @tz that corresponds to the given @time_.
 The meaning of @time_ depends on @type.
 
 If @type is %G_TIME_TYPE_UNIVERSAL then this function will always
@@ -52158,7 +52704,8 @@ time values to be added to Coordinated Universal Time (UTC) to get
 the local time.
 
 In UNIX, the `TZ` environment variable typically corresponds
-to the name of a file in the zoneinfo database, or string in
+to the name of a file in the zoneinfo database, an absolute path to a file
+somewhere else, or a string in
 &quot;std offset [dst [offset],start[/time],end[/time]]&quot; (POSIX) format.
 There  are  no spaces in the specification. The name of standard
 and daylight savings time zone must be three or more alphabetic
@@ -52345,6 +52892,8 @@ the callback will be invoked in whichever thread is running that main
 context. You can do these steps manually if you need greater control or to
 use a custom main context.
 
+It is safe to call this function from any thread.
+
 The interval given is in terms of monotonic time, not wall clock
 time.  See g_get_monotonic_time().
 
@@ -52438,6 +52987,8 @@ g_timeout_source_new_seconds() and attaches it to the main loop context
 using g_source_attach(). You can do these steps manually if you need
 greater control. Also see g_timeout_add_seconds_full().
 
+It is safe to call this function from any thread.
+
 Note that the first call of the timer may not be precise for timeouts
 of one second. If you need finer precision and have such a timeout,
 you may want to use g_timeout_add() instead.
@@ -52506,6 +53057,8 @@ g_timeout_source_new_seconds() and attaches it to the main loop context
 using g_source_attach(). You can do these steps manually if you need 
 greater control.
 
+It is safe to call this function from any thread.
+
 The interval given is in terms of monotonic time, not wall clock
 time.  See g_get_monotonic_time().
 
@@ -53531,7 +54084,7 @@ Since: 2.24
 </description>
 <parameters>
 <parameter name="class_type">
-<parameter_description> GType of an classed type
+<parameter_description> GType of a classed type
 </parameter_description>
 </parameter>
 <parameter name="private_size">
@@ -53573,7 +54126,7 @@ is initialized
 
 <function name="g_type_add_interface_dynamic">
 <description>
-Adds the dynamic @interface_type to @instantiable_type. The information
+Adds @interface_type to the dynamic @instantiable_type. The information
 contained in the #GTypePlugin structure pointed to by @plugin
 is used to manage the relationship.
 
@@ -53597,7 +54150,7 @@ is used to manage the relationship.
 
 <function name="g_type_add_interface_static">
 <description>
-Adds the static @interface_type to @instantiable_type.
+Adds @interface_type to the static @instantiable_type.
 The information contained in the #GInterfaceInfo structure
 pointed to by @info is used to manage the relationship.
 
@@ -53986,7 +54539,7 @@ Since: 2.4
 <parameters>
 <parameter name="g_iface">
 <parameter_description> the default vtable
-structure for a interface, as returned by g_type_default_interface_ref()
+structure for an interface, as returned by g_type_default_interface_ref()
 </parameter_description>
 </parameter>
 </parameters>
@@ -55879,7 +56432,7 @@ Converts a character to uppercase.
 </parameter>
 </parameters>
 <return> the result of converting @c to uppercase.
-If @c is not an lowercase or titlecase character,
+If @c is not a lowercase or titlecase character,
 or has no upper case equivalent @c is returned unchanged.
 </return>
 </function>
@@ -56147,6 +56700,38 @@ Since: 2.36
 </return>
 </function>
 
+<function name="g_unix_get_passwd_entry">
+<description>
+Get the `passwd` file entry for the given @user_name using `getpwnam_r()`.
+This can fail if the given @user_name doesn’t exist.
+
+The returned `struct passwd` has been allocated using g_malloc() and should
+be freed using g_free(). The strings referenced by the returned struct are
+included in the same allocation, so are valid until the `struct passwd` is
+freed.
+
+This function is safe to call from multiple threads concurrently.
+
+You will need to include `pwd.h` to get the definition of `struct passwd`.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="user_name">
+<parameter_description> the username to get the passwd file entry for
+</parameter_description>
+</parameter>
+<parameter name="error">
+<parameter_description> return location for a #GError, or %NULL
+</parameter_description>
+</parameter>
+</parameters>
+<return> passwd entry, or %NULL on error; free the returned
+value with g_free()
+</return>
+</function>
+
 <function name="g_unix_open_pipe">
 <description>
 Similar to the UNIX pipe() call, but on modern systems like Linux
@@ -56996,7 +57581,7 @@ text rendering and therefore has to be as fast as possible.
 
 <function name="g_utf8_pointer_to_offset">
 <description>
-Converts from a pointer to position within a string to a integer
+Converts from a pointer to position within a string to an integer
 character offset.
 
 Since 2.10, this function allows @pos to be before @str, and returns
@@ -57497,7 +58082,9 @@ Since: 2.52
 
 <function name="g_uuid_string_random">
 <description>
-Generates a random UUID (RFC 4122 version 4) as a string.
+Generates a random UUID (RFC 4122 version 4) as a string. It has the same
+randomness guarantees as #GRand, so must not be used for cryptographic
+purposes such as key generation, nonces, salts or one-time pads.
 
 Since: 2.52
 
@@ -60476,7 +61063,7 @@ Since: 2.24
 </description>
 <parameters>
 <parameter name="value">
-<parameter_description> a int16 #GVariant instance
+<parameter_description> an int16 #GVariant instance
 </parameter_description>
 </parameter>
 </parameters>
@@ -60497,7 +61084,7 @@ Since: 2.24
 </description>
 <parameters>
 <parameter name="value">
-<parameter_description> a int32 #GVariant instance
+<parameter_description> an int32 #GVariant instance
 </parameter_description>
 </parameter>
 </parameters>
@@ -60518,7 +61105,7 @@ Since: 2.24
 </description>
 <parameters>
 <parameter name="value">
-<parameter_description> a int64 #GVariant instance
+<parameter_description> an int64 #GVariant instance
 </parameter_description>
 </parameter>
 </parameters>
@@ -62422,6 +63009,10 @@ then it will be set to reflect the error that occurred.
 Officially, the language understood by the parser is &quot;any string
 produced by g_variant_print()&quot;.
 
+There may be implementation specific restrictions on deeply nested values,
+which would result in a %G_VARIANT_PARSE_ERROR_RECURSION error. #GVariant is
+guaranteed to handle nesting up to at least 64 levels.
+
 
 </description>
 <parameters>
@@ -63421,6 +64012,10 @@ This function is similar to g_vsprintf(), except that it allocates a
 string to hold the output, instead of putting the output in a buffer 
 you allocate in advance.
 
+The returned value in @string is guaranteed to be non-NULL, unless
+@format contains `%lc` or `%ls` conversions, which can fail if no
+multibyte representation is available for the given character.
+
 `glib/gprintf.h` must be explicitly included in order to use this function.
 
 Since: 2.4
@@ -63787,6 +64382,29 @@ into the format string (as with printf())
 <return></return>
 </function>
 
+<function name="g_warning_once">
+<description>
+Logs a warning only once.
+
+g_warning_once() calls g_warning() with the passed message the first time
+the statement is executed; subsequent times it is a no-op.
+
+Note! On platforms where the compiler doesn't support variadic macros, the
+warning is printed each time instead of only once.
+
+Since: 2.64
+
+</description>
+<parameters>
+<parameter name="Varargs">
+<parameter_description> format string, followed by parameters to insert
+into the format string (as with printf())
+</parameter_description>
+</parameter>
+</parameters>
+<return></return>
+</function>
+
 <function name="g_weak_ref_clear">
 <description>
 Frees resources associated with a non-statically-allocated #GWeakRef.
index a64a435..469c90a 100644 (file)
@@ -1,27 +1,8 @@
 <root>
-  <substitute_type_name from="GBindingFlags" to="Glib::Binding::Flags" />
-  <substitute_type_name from="GChecksumType" to="Glib::Checksum::Type" />
   <substitute_type_name from="GDateMonth" to="Glib::Date::Month" />
   <substitute_type_name from="GDateWeekday" to="Glib::Date::Weekday" />
   <substitute_type_name from="GDateDMY" to="Glib::Date::DMY" />
-  <substitute_type_name from="GKeyFileFlags" to="Glib::KeyFile::Flags" />
-  <substitute_type_name from="GMarkupParseFlags" to="Glib::Markup::ParseFlags" />
-  <substitute_type_name from="GModuleFlags" to="Glib::Module::Flags" />
-  <substitute_type_name from="GRegexCompileFlags" to="Glib::Regex::CompileFlags" />
-  <substitute_type_name from="GRegexMatchFlags" to="Glib::Regex::MatchFlags" />
-
-  <substitute_enumerator_name from_prefix="G_BINDING_" to_prefix="Glib::Binding::Flags::" />
-  <substitute_enumerator_name from_prefix="G_DATE_" to_prefix="Glib::Date::" />
-  <substitute_enumerator_name from_prefix="G_PARAM_" to_prefix="Glib::ParamFlags::" />
-  <substitute_enumerator_name from_prefix="G_REGEX_MATCH_" to_prefix="Glib::Regex::MatchFlags::" />
-  <substitute_enumerator_name from_prefix="G_REGEX_" to_prefix="Glib::Regex::CompileFlags::" />
-  <substitute_enumerator_name from_prefix="G_SPAWN_ERROR_" to_prefix="Glib::SpawnError::" />
-  <substitute_enumerator_name from_prefix="G_TIME_TYPE_" to_prefix="Glib::TimeType::" />
-  <substitute_enumerator_name from_prefix="G_UNICODE_BREAK_" to_prefix="Glib::UnicodeBreakType::" />
-  <substitute_enumerator_name from_prefix="G_NORMALIZE_" to_prefix="Glib::NormalizeMode::" />
-  <substitute_enumerator_name from="G_FILE_ERROR" to="Glib::FileError" />
-  <substitute_enumerator_name from="G_KEY_FILE_ERROR" to="Glib::KeyFileError" />
-  <substitute_enumerator_name from_prefix="G_KEY_FILE_ERROR_" to_prefix="Glib::KeyFileError::" />
+
   <!-- enum GOptionArg is not wrapped. Don't substitute. -->
   <substitute_enumerator_name from_prefix="G_OPTION_ARG_" to_prefix="G_OPTION_ARG_" />
   <!-- These are preprocessor defines. Don't substitute. -->
index b0876fa..dc17af7 100644 (file)
 ;;   G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN,
 ;;   G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD,
 ;;   G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT,
-;;   G_VARIANT_PARSE_ERROR_VALUE_EXPECTED
+;;   G_VARIANT_PARSE_ERROR_VALUE_EXPECTED,
+;;   G_VARIANT_PARSE_ERROR_RECURSION
 ;; } GVariantParseError;
 
 (define-enum-extended VariantParseError
     '("unknown-keyword" "G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD" "15")
     '("unterminated-string-constant" "G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT" "16")
     '("value-expected" "G_VARIANT_PARSE_ERROR_VALUE_EXPECTED" "17")
+    '("recursion" "G_VARIANT_PARSE_ERROR_RECURSION" "18")
   )
 )
 
index 2171e9e..cfb6876 100644 (file)
   (gtype-id "G_TYPE_MATCH_INFO")
 )
 
-(define-object NodeTree
-  (in-module "Glib")
-  (c-name "GNode")
-)
-
 (define-object Object
   (in-module "Glib")
   (c-name "GObject")
   (c-name "GTimeZone")
 )
 
-(define-object Tree
-  (in-module "Glib")
-  (c-name "GTree")
-)
-
 (define-object Variant
   (in-module "Glib")
   (c-name "GVariant")
index 1885ee0..27f8680 100644 (file)
     '("unknown-keyword" "G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD")
     '("unterminated-string-constant" "G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT")
     '("value-expected" "G_VARIANT_PARSE_ERROR_VALUE_EXPECTED")
+    '("recursion" "G_VARIANT_PARSE_ERROR_RECURSION")
   )
 )
 
   )
 )
 
+(define-method steal
+  (of-object "GArray")
+  (c-name "g_array_steal")
+  (return-type "gpointer")
+  (parameters
+    '("gsize*" "len")
+  )
+)
+
 (define-function g_array_sized_new
   (c-name "g_array_sized_new")
   (is-constructor-of "GArraySized")
   )
 )
 
+(define-method steal
+  (of-object "GPtrArray")
+  (c-name "g_ptr_array_steal")
+  (return-type "gpointer*")
+  (parameters
+    '("gsize*" "len")
+  )
+)
+
 (define-method copy
   (of-object "GPtrArray")
   (c-name "g_ptr_array_copy")
   )
 )
 
+(define-method steal
+  (of-object "GByteArray")
+  (c-name "g_byte_array_steal")
+  (return-type "guint8*")
+  (parameters
+    '("gsize*" "len")
+  )
+)
+
 (define-function g_byte_array_sized_new
   (c-name "g_byte_array_sized_new")
   (is-constructor-of "GByteArraySized")
   )
 )
 
+(define-function g_clear_list
+  (c-name "g_clear_list")
+  (return-type "none")
+  (parameters
+    '("GList**" "list_ptr")
+    '("GDestroyNotify" "destroy")
+  )
+)
+
 
 
 ;; From gmacros.h
   (return-type "GMainContext*")
 )
 
+(define-method pusher_new
+  (of-object "GMainContext")
+  (c-name "g_main_context_pusher_new")
+  (return-type "GMainContextPusher*")
+)
+
+(define-method free
+  (of-object "GMainContextPusher")
+  (c-name "g_main_context_pusher_free")
+  (return-type "none")
+)
+
 (define-function g_main_loop_new
   (c-name "g_main_loop_new")
   (is-constructor-of "GMainLoop")
   )
 )
 
+(define-method set_dispose_function
+  (of-object "GSource")
+  (c-name "g_source_set_dispose_function")
+  (return-type "none")
+  (parameters
+    '("GSourceDisposeFunc" "dispose")
+  )
+)
+
 (define-method ref
   (of-object "GSource")
   (c-name "g_source_ref")
   )
 )
 
+(define-function g_clear_slist
+  (c-name "g_clear_slist")
+  (return-type "none")
+  (parameters
+    '("GSList**" "slist_ptr")
+    '("GDestroyNotify" "destroy")
+  )
+)
+
 
 
 ;; From gspawn.h
   )
 )
 
+(define-function g_fsync
+  (c-name "g_fsync")
+  (return-type "gint")
+  (parameters
+    '("gint" "fd")
+  )
+)
+
 (define-function g_utime
   (c-name "g_utime")
   (return-type "int")
   )
 )
 
+(define-function g_get_os_info
+  (c-name "g_get_os_info")
+  (return-type "gchar*")
+  (parameters
+    '("const-gchar*" "key_name")
+  )
+)
+
 (define-function g_reload_user_special_dirs_cache
   (c-name "g_reload_user_special_dirs_cache")
   (return-type "none")
index acb8648..77f0096 100644 (file)
   (return-type "gboolean")
   (parameters
     '("GParamSpec*" "pspec")
-    '("GValue*" "value")
+    '("const-GValue*" "value")
   )
 )
 
index 5e8113f..b9d100f 100644 (file)
@@ -34,7 +34,9 @@ namespace
 // g_io_channel_new_file().  Neither is there a way to hook up a wrapper
 // object in an existing GIOChannel, nor exists any destroy notification.
 //
-// So that means: If the IOChannel backend is unknown (normal case), then the
+// So that means:  If the IOChannel is implemented in C++ -- that is, our
+// GlibmmIOChannel backend is used -- we use the GIOChannel reference
+// counting mechanism.  If the IOChannel backend is unknown, then the
 // wrapper instance holds always exactly one reference to the GIOChannel.
 // The wrapper object itself is then managed via our own refcounting
 // mechanism.  To do that a utility class ForeignIOChannel is introduced to
@@ -73,8 +75,51 @@ ForeignIOChannel::unreference() const
 namespace Glib
 {
 
+class GlibmmIOChannel
+{
+public:
+  GIOChannel base;
+  Glib::IOChannel* wrapper;
+
+  static const GIOFuncs vfunc_table;
+
+  static GIOStatus io_read(
+    GIOChannel* channel, char* buf, gsize count, gsize* bytes_read, GError** err);
+
+  static GIOStatus io_write(
+    GIOChannel* channel, const char* buf, gsize count, gsize* bytes_written, GError** err);
+
+  static GIOStatus io_seek(GIOChannel* channel, gint64 offset, GSeekType type, GError** err);
+  static GIOStatus io_close(GIOChannel* channel, GError** err);
+
+  static GSource* io_create_watch(GIOChannel* channel, GIOCondition condition);
+  static void io_free(GIOChannel* channel);
+
+  static GIOStatus io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err);
+  static GIOFlags io_get_flags(GIOChannel* channel);
+};
+
+// static
+const GIOFuncs GlibmmIOChannel::vfunc_table = {
+  &GlibmmIOChannel::io_read, &GlibmmIOChannel::io_write, &GlibmmIOChannel::io_seek,
+  &GlibmmIOChannel::io_close, &GlibmmIOChannel::io_create_watch, &GlibmmIOChannel::io_free,
+  &GlibmmIOChannel::io_set_flags, &GlibmmIOChannel::io_get_flags,
+};
+
 /**** GLib::IOChannel ******************************************************/
 
+/* Construct a custom C++-implemented IOChannel.  GlibmmIOChannel is an
+ * extended GIOChannel struct which allows us to hook up a pointer to this
+ * persistent wrapper instance.
+ */
+IOChannel::IOChannel() : gobject_(static_cast<GIOChannel*>(g_malloc(sizeof(GlibmmIOChannel))))
+{
+  g_io_channel_init(gobject_);
+  gobject_->funcs = const_cast<GIOFuncs*>(&GlibmmIOChannel::vfunc_table);
+
+  reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = this;
+}
+
 IOChannel::IOChannel(IOChannel&& other) noexcept : sigc::trackable(std::move(other)),
                                                    gobject_(std::move(other.gobject_))
 {
@@ -100,7 +145,9 @@ IOChannel::operator=(IOChannel&& other) noexcept
  */
 IOChannel::IOChannel(GIOChannel* gobject, bool take_copy) : gobject_(gobject)
 {
+  // This ctor should never be called for GlibmmIOChannel instances.
   g_assert(gobject != nullptr);
+  g_assert(gobject->funcs != &GlibmmIOChannel::vfunc_table);
 
   if (take_copy)
     g_io_channel_ref(gobject_);
@@ -111,6 +158,19 @@ IOChannel::release_gobject()
 {
   if (gobject_)
   {
+    // Check whether this IOChannel is implemented in C++, i.e. whether it
+    // uses our GlibmmIOChannel forwarding backend.  Normally, this will never
+    // be true because the wrapper should only be deleted in the io_free()
+    // callback, which clears gobject_ before deleting.  But in case the ctor
+    // of a derived class threw an exception the GIOChannel must be destroyed
+    // prematurely.
+    //
+    if (gobject_->funcs == &GlibmmIOChannel::vfunc_table)
+    {
+      // Disconnect the wrapper object so that it won't be deleted twice.
+      reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = nullptr;
+    }
+
     const auto tmp_gobject = gobject_;
     gobject_ = nullptr;
 
@@ -275,7 +335,56 @@ IOChannel::get_line_term() const
 Glib::RefPtr<IOSource>
 IOChannel::create_watch(IOCondition condition)
 {
-  return IOSource::create(gobj(), condition);
+  // The corresponding unreference() takes place in the dtor
+  // of the Glib::RefPtr<IOChannel> object below.
+  reference();
+  return IOSource::create(Glib::RefPtr<IOChannel>(this), condition);
+}
+
+IOStatus
+IOChannel::read_vfunc(char*, gsize, gsize&)
+{
+  g_assert_not_reached();
+  return IO_STATUS_ERROR;
+}
+
+IOStatus
+IOChannel::write_vfunc(const char*, gsize, gsize&)
+{
+  g_assert_not_reached();
+  return IO_STATUS_ERROR;
+}
+
+IOStatus IOChannel::seek_vfunc(gint64, SeekType)
+{
+  g_assert_not_reached();
+  return IO_STATUS_ERROR;
+}
+
+IOStatus
+IOChannel::close_vfunc()
+{
+  g_assert_not_reached();
+  return IO_STATUS_ERROR;
+}
+
+Glib::RefPtr<Glib::Source> IOChannel::create_watch_vfunc(IOCondition)
+{
+  g_assert_not_reached();
+  return Glib::RefPtr<Glib::Source>();
+}
+
+IOStatus IOChannel::set_flags_vfunc(IOFlags)
+{
+  g_assert_not_reached();
+  return IO_STATUS_ERROR;
+}
+
+IOFlags
+IOChannel::get_flags_vfunc()
+{
+  g_assert_not_reached();
+  return IOFlags(0);
 }
 
 void
@@ -297,11 +406,180 @@ wrap(GIOChannel* gobject, bool take_copy)
 
   if (gobject)
   {
-    cpp_object = new ForeignIOChannel(gobject, take_copy);
-    cpp_object->reference(); // the refcount is initially 0
+    if (gobject->funcs == &GlibmmIOChannel::vfunc_table)
+    {
+      cpp_object = reinterpret_cast<GlibmmIOChannel*>(gobject)->wrapper;
+
+      if (take_copy && cpp_object)
+        cpp_object->reference();
+    }
+    else
+    {
+      cpp_object = new ForeignIOChannel(gobject, take_copy);
+      cpp_object->reference(); // the refcount is initially 0
+    }
+  }
+
+  return Glib::RefPtr<IOChannel>(cpp_object);
+}
+
+/**** Glib::GlibmmIOChannel ************************************************/
+
+GIOStatus
+GlibmmIOChannel::io_read(
+  GIOChannel* channel, char* buf, gsize count, gsize* bytes_read, GError** err)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOStatus)wrapper->read_vfunc(buf, count, *bytes_read);
+  }
+  catch (Glib::Error& error)
+  {
+    error.propagate(err);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return G_IO_STATUS_ERROR;
+}
+
+GIOStatus
+GlibmmIOChannel::io_write(
+  GIOChannel* channel, const char* buf, gsize count, gsize* bytes_written, GError** err)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOStatus)wrapper->write_vfunc(buf, count, *bytes_written);
+  }
+  catch (Glib::Error& error)
+  {
+    error.propagate(err);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return G_IO_STATUS_ERROR;
+}
+
+GIOStatus
+GlibmmIOChannel::io_seek(GIOChannel* channel, gint64 offset, GSeekType type, GError** err)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOStatus)wrapper->seek_vfunc(offset, (SeekType)type);
+  }
+  catch (Glib::Error& error)
+  {
+    error.propagate(err);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return G_IO_STATUS_ERROR;
+}
+
+GIOStatus
+GlibmmIOChannel::io_close(GIOChannel* channel, GError** err)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOStatus)wrapper->close_vfunc();
+  }
+  catch (Glib::Error& error)
+  {
+    error.propagate(err);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return G_IO_STATUS_ERROR;
+}
+
+// static
+GSource*
+GlibmmIOChannel::io_create_watch(GIOChannel* channel, GIOCondition condition)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    const auto source = wrapper->create_watch_vfunc((IOCondition)condition);
+    return (source) ? source->gobj_copy() : nullptr;
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return nullptr;
+}
+
+// static
+void
+GlibmmIOChannel::io_free(GIOChannel* channel)
+{
+  if (IOChannel* const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper)
+  {
+    wrapper->gobject_ = nullptr;
+    delete wrapper;
+  }
+
+  g_free(channel);
+}
+
+GIOStatus
+GlibmmIOChannel::io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOStatus)wrapper->set_flags_vfunc((IOFlags)flags);
+  }
+  catch (Glib::Error& error)
+  {
+    error.propagate(err);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return G_IO_STATUS_ERROR;
+}
+
+// static
+GIOFlags
+GlibmmIOChannel::io_get_flags(GIOChannel* channel)
+{
+  const auto wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+  try
+  {
+    return (GIOFlags)wrapper->get_flags_vfunc();
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
   }
 
-  return Glib::make_refptr_for_instance<IOChannel>(cpp_object);
+  return GIOFlags(0);
 }
 
 } // namespace Glib
index 8c761d5..84120e4 100644 (file)
@@ -17,7 +17,7 @@
 _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
-#include <glib.h> //For the GIOCondition enum values.
+#include <glib.h> //For the GIOChannel enum values.
 #include <glibmm/error.h>
 #include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
@@ -31,35 +31,25 @@ extern "C" { typedef struct _GIOChannel GIOChannel; }
 namespace Glib
 {
 
-class Source;
-class IOSource;
+class GLIBMM_API Source;
+class GLIBMM_API IOSource;
 
-_WRAP_ENUM(SeekType, GSeekType, NO_GTYPE)
-_WRAP_ENUM(IOStatus, GIOStatus, NO_GTYPE, s#^EOF$#ENDOFFILE#)
+_WRAP_ENUM(SeekType, GSeekType, NO_GTYPE, s#^SEEK_#SEEK_TYPE_#)
+_WRAP_ENUM(IOStatus, GIOStatus, NO_GTYPE)
 _WRAP_ENUM(IOFlags, GIOFlags, NO_GTYPE)
 
 
-// Glib::IOCondition::IN and Glib::IOCondition::OUT would be problematic.
-// IN and OUT can be preprocessor macros.
-// See https://bugzilla.gnome.org/show_bug.cgi?id=786717
-/** @enum IOCondition
- * A bitwise combination representing an I/O condition to watch for on an
+/** A bitwise combination representing an I/O condition to watch for on an
  * event source.
  * The flags correspond to those used by the <tt>%poll()</tt> system call
  * on UNIX (see <tt>man 2 poll</tt>).  To test for individual flags, do
  * something like this:
  * @code
- * if ((condition & Glib::IOCondition::IO_OUT) == Glib::IOCondition::IO_OUT)
+ * if((condition & Glib::IO_OUT) != 0)
  *   do_some_output();
  * @endcode
  */
-_WRAP_ENUM(IOCondition, GIOCondition, NO_GTYPE,
-  s#^IN$#IO_IN#,
-  s#^OUT$#IO_OUT#,
-  s#^PRI$#IO_PRI#,
-  s#^ERR$#IO_ERR#,
-  s#^HUP$#IO_HUP#,
-  s#^NVAL$#IO_NVAL#)
+_WRAP_ENUM(IOCondition, GIOCondition, NO_GTYPE)
 
 /** Exception class for IOChannel errors.
  */
@@ -72,10 +62,11 @@ _WRAP_GERROR(IOChannelError, GIOChannelError, G_IO_CHANNEL_ERROR, NO_GTYPE,
     s#^ACCES$#ACCESS_DENIED#,
     s#^FBIG$#FILE_TOO_BIG#,
     s#^IO$#IO_ERROR#,
-    s#^OVERFLOW$#OVERFLOWN#)
+    s#^OVERFLOW$#OVERFLOWN#,
+    decl_prefix GLIBMM_API)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-class GlibmmIOChannel;
+class GLIBMM_API GlibmmIOChannel;
 #endif
 
 /** IOChannel aims to provide portable I/O support for files, pipes
@@ -89,7 +80,7 @@ class GlibmmIOChannel;
  *
  * You can create an IOChannel with one of the static create methods.
  */
-class IOChannel : public sigc::trackable
+class GLIBMM_API IOChannel : public sigc::trackable
 {
   _CLASS_GENERIC(IOChannel, GIOChannel)
 
@@ -212,8 +203,8 @@ public:
 
   /** Reads all the remaining data from the file.
    * @param[out] str The resulting string.
-   * @return Glib::IOStatus::NORMAL on success. This function never
-   *  returns Glib::IOStatus::ENDOFFILE.
+   * @return Glib::IO_STATUS_NORMAL on success. This function never
+   *  returns Glib::IO_STATUS_EOF.
    * @throw Glib::IOChannelError
    * @throw Glib::ConvertError
    */
@@ -223,7 +214,7 @@ public:
   /** Write a string to the I/O channel.
    * Note that this method does not return the number of characters written.
    * If the channel is blocking and the returned value is
-   * Glib::IOStatus::NORMAL, the whole string was written.
+   * Glib::IO_STATUS_NORMAL, the whole string was written.
    * @param str the string to write.
    * @return The status of the operation.
    * @throw Glib::IOChannelError
@@ -252,14 +243,14 @@ public:
 
   /** Seek the I/O channel to a specific position.
    * @param offset The offset in bytes from the position specified by @a type.
-   * @param type A SeekType. The type Glib::SeekType::CUR is only allowed in
+   * @param type A SeekType. The type Glib::SEEK_TYPE_CUR is only allowed in
    * those cases where a call to set_encoding() is allowed. See the
    * documentation for set_encoding() for details.
    * @return The status of the operation.
    * @throw Glib::IOChannelError
    * @throw Glib::ConvertError
    */
-  _WRAP_METHOD(IOStatus seek(gint64 offset, SeekType type = SeekType::SET),
+  _WRAP_METHOD(IOStatus seek(gint64 offset, SeekType type = SEEK_TYPE_SET),
                g_io_channel_seek_position, errthrow)
 
   /** Flush the buffers of the I/O channel.
@@ -315,10 +306,10 @@ public:
    *
    * A buffered channel can only be set unbuffered if the channel's internal
    * buffers have been flushed. Newly created channels or channels which have
-   * returned Glib::IOStatus::ENDOFFILE not require such a flush. For write-only
+   * returned Glib::IO_STATUS_EOF not require such a flush. For write-only
    * channels, a call to flush() is sufficient. For all other channels, the
    * buffers may be flushed by a call to seek().  This includes the possibility
-   * of seeking with seek type Glib::SeekType::CUR and an offset of zero. Note
+   * of seeking with seek type Glib::SEEK_TYPE_CUR and an offset of zero. Note
    * that this means that socket-based channels cannot be set unbuffered once
    * they have had data read from them.
    *
@@ -371,24 +362,24 @@ public:
    * -# The channel is a file, and the file pointer was just repositioned by a
    *  call to seek_position().  (This flushes all the internal buffers.)
    * -# The current encoding is <tt>""</tt> or UTF-8.
-   * -# One of the read methods has just returned Glib::IOStatus::ENDOFFILE (or, in
-   *  the case of read_to_end(), Glib::IOStatus::NORMAL).
-   * -# The read() method has returned Glib::IOStatus::AGAIN or thrown
+   * -# One of the read methods has just returned Glib::IO_STATUS_EOF (or, in
+   *  the case of read_to_end(), Glib::IO_STATUS_NORMAL).
+   * -# The read() method has returned Glib::IO_STATUS_AGAIN or thrown
    *  a Glib::Error exception.  This may be useful in the case of
    *  ConvertError::ILLEGAL_SEQUENCE.  Returning one of these statuses
    *  from read_line() or read_to_end() does <em>not</em> guarantee that
    *  the encoding can be changed.
    *
    * Channels which do not meet one of the above conditions cannot call
-   * seek_position() with a seek type of Glib::SeekType::CUR and, if they
+   * seek_position() with a seek type of Glib::SEEK_TYPE_CUR and, if they
    * are "seekable", cannot call write() after calling one of the API
    * "read" methods.
    *
    * @param encoding The encoding name, or <tt>""</tt> for binary.
-   * @return Glib::IOStatus::NORMAL if the encoding was successfully set.
+   * @return Glib::IO_STATUS_NORMAL if the encoding was successfully set.
    * @throw Glib::IOChannelError
    */
-  IOStatus set_encoding(const std::string& encoding = {});
+  IOStatus set_encoding(const std::string& encoding = std::string());
   _IGNORE(g_io_channel_set_encoding)
 
   /** Get the encoding of the I/O channel.
@@ -397,7 +388,7 @@ public:
   std::string get_encoding() const;
   _IGNORE(g_io_channel_get_encoding)
 
-  void set_line_term(const std::string& term = {});
+  void set_line_term(const std::string& term = std::string());
   _IGNORE(g_io_channel_set_line_term)
 
   std::string get_line_term() const;
@@ -428,16 +419,66 @@ public:
 protected:
   GIOChannel* gobject_;
 
+  /** Constructor that should be used by derived classes.
+   * Use this constructor if you want to inherit from IOChannel.
+   * It will set up a GIOChannel that will call the vfuncs of your
+   * class even if it is being used from C code, and it will keep
+   * a reference to the C++ code while the GIOChannel exists.
+   */
+  IOChannel();
   _IGNORE(g_io_channel_init)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   IOChannel(GIOChannel* gobject, bool take_copy);
 #endif
 
+  //We don't put GLIBMM_DISABLE_DEPRECATED around these deprecated methods
+  //because they are virtual and that would make the ABI dependent on the ifdef.
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read);
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOStatus write_vfunc(const char* buf, gsize count, gsize& bytes_written);
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOStatus seek_vfunc(gint64 offset, SeekType type);
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOStatus close_vfunc();
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOStatus set_flags_vfunc(IOFlags flags);
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual IOFlags  get_flags_vfunc();
+
+  /**
+   * @deprecated Custom Glib::IOChannel implementation was never really supported.
+   */
+  virtual Glib::RefPtr<Glib::Source> create_watch_vfunc(IOCondition cond);
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  friend class Glib::GlibmmIOChannel;
+#endif
+
 private:
   void release_gobject();
 };
 
+GLIBMM_API
 Glib::RefPtr<IOChannel> wrap(GIOChannel* gobject, bool take_copy = false);
 
 } // namespace Glib
index 05637fc..08572fd 100644 (file)
 namespace Glib
 {
 
+/**** Glib::KeyFile ********************************************************/
+
+KeyFile::KeyFile()
+{
+  gobject_ = g_key_file_new();
+  owns_gobject_ = true;
+}
+
+KeyFile::KeyFile(GKeyFile* castitem, bool takes_ownership)
+{
+  gobject_ = castitem;
+  owns_gobject_ = takes_ownership;
+}
+
+KeyFile::KeyFile(KeyFile&& other) noexcept : gobject_(std::move(other.gobject_)),
+                                             owns_gobject_(std::move(other.owns_gobject_))
+{
+  other.gobject_ = nullptr;
+  other.owns_gobject_ = false;
+}
+
+KeyFile&
+KeyFile::operator=(KeyFile&& other) noexcept
+{
+  if (owns_gobject_)
+    g_key_file_free(gobject_);
+
+  gobject_ = std::move(other.gobject_);
+  owns_gobject_ = std::move(other.owns_gobject_);
+
+  other.gobject_ = nullptr;
+  other.owns_gobject_ = false;
+
+  return *this;
+}
+
+KeyFile::~KeyFile()
+{
+  if (owns_gobject_)
+    g_key_file_free(gobject_);
+}
+
 bool
-KeyFile::load_from_data(const Glib::ustring& data, Flags flags)
+KeyFile::load_from_data(const Glib::ustring& data, KeyFileFlags flags)
 {
   GError* gerror = nullptr;
 
@@ -32,7 +74,7 @@ KeyFile::load_from_data(const Glib::ustring& data, Flags flags)
 }
 
 bool
-KeyFile::load_from_data_dirs(const std::string& file, std::string& full_path, Flags flags)
+KeyFile::load_from_data_dirs(const std::string& file, std::string& full_path, KeyFileFlags flags)
 {
   GError* gerror = nullptr;
   char* full_path_c = nullptr;
@@ -52,14 +94,14 @@ KeyFile::load_from_data_dirs(const std::string& file, std::string& full_path, Fl
 }
 
 bool
-KeyFile::load_from_dirs(const std::string& file, const std::vector<std::string>&  search_dirs,
-  std::string& full_path, Flags flags)
+KeyFile::load_from_dirs(const std::string& file, const Glib::ArrayHandle<std::string>& search_dirs,
+  std::string& full_path, KeyFileFlags flags)
 {
   GError* gerror = nullptr;
   char* full_path_c = nullptr;
 
   const gboolean result =
-    g_key_file_load_from_dirs(gobj(), file.c_str(), const_cast<const gchar**>(Glib::ArrayHandler<std::string>::vector_to_array(search_dirs).data()),
+    g_key_file_load_from_dirs(gobj(), file.c_str(), const_cast<const gchar**>(search_dirs.data()),
       &full_path_c, static_cast<GKeyFileFlags>(unsigned(flags)), &gerror);
 
   if (gerror)
@@ -91,16 +133,16 @@ KeyFile::to_data()
   return Glib::convert_return_gchar_ptr_to_ustring(str);
 }
 
-std::vector<Glib::ustring>
+Glib::ArrayHandle<Glib::ustring>
 KeyFile::get_groups() const
 {
   gsize length = 0;
   char** const array = g_key_file_get_groups(const_cast<GKeyFile*>(gobj()), &length);
 
-  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(array, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<Glib::ustring>(array, length, Glib::OWNERSHIP_DEEP);
 }
 
-std::vector<Glib::ustring>
+Glib::ArrayHandle<Glib::ustring>
 KeyFile::get_keys(const Glib::ustring& group_name) const
 {
   gsize length = 0;
@@ -112,7 +154,7 @@ KeyFile::get_keys(const Glib::ustring& group_name) const
   if (gerror)
     Glib::Error::throw_exception(gerror);
 
-  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(array, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<Glib::ustring>(array, length, Glib::OWNERSHIP_DEEP);
 }
 
 Glib::ustring
@@ -204,7 +246,7 @@ KeyFile::set_double(const Glib::ustring& key, double value)
   if (err)                \
   Glib::Error::throw_exception(err)
 
-std::vector<Glib::ustring>
+Glib::ArrayHandle<Glib::ustring>
 KeyFile::get_string_list(
   const Glib::ustring& group_name, const Glib::ustring& key GLIBMM_ERROR_ARG) const
 {
@@ -216,10 +258,10 @@ KeyFile::get_string_list(
 
   GLIBMM_THROW(gerror);
 
-  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(array, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<Glib::ustring>(array, length, Glib::OWNERSHIP_DEEP);
 }
 
-std::vector<Glib::ustring>
+Glib::ArrayHandle<Glib::ustring>
 KeyFile::get_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key,
   const Glib::ustring& locale GLIBMM_ERROR_ARG) const
 {
@@ -231,10 +273,10 @@ KeyFile::get_locale_string_list(const Glib::ustring& group_name, const Glib::ust
 
   GLIBMM_THROW(gerror);
 
-  return Glib::ArrayHandler<Glib::ustring>::array_to_vector(array, length, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<Glib::ustring>(array, length, Glib::OWNERSHIP_DEEP);
 }
 
-std::vector<bool>
+Glib::ArrayHandle<bool>
 KeyFile::get_boolean_list(
   const Glib::ustring& group_name, const Glib::ustring& key GLIBMM_ERROR_ARG) const
 {
@@ -246,10 +288,10 @@ KeyFile::get_boolean_list(
 
   GLIBMM_THROW(gerror);
 
-  return Glib::ArrayHandler<bool>::array_to_vector(array, length, Glib::OWNERSHIP_SHALLOW);
+  return Glib::ArrayHandle<bool>(array, length, Glib::OWNERSHIP_SHALLOW);
 }
 
-std::vector<int>
+Glib::ArrayHandle<int>
 KeyFile::get_integer_list(
   const Glib::ustring& group_name, const Glib::ustring& key GLIBMM_ERROR_ARG) const
 {
@@ -261,10 +303,10 @@ KeyFile::get_integer_list(
 
   GLIBMM_THROW(gerror);
 
-  return Glib::ArrayHandler<int>::array_to_vector(array, length, Glib::OWNERSHIP_SHALLOW);
+  return Glib::ArrayHandle<int>(array, length, Glib::OWNERSHIP_SHALLOW);
 }
 
-std::vector<double>
+Glib::ArrayHandle<double>
 KeyFile::get_double_list(
   const Glib::ustring& group_name, const Glib::ustring& key GLIBMM_ERROR_ARG) const
 {
@@ -275,47 +317,47 @@ KeyFile::get_double_list(
     const_cast<GKeyFile*>(gobj()), group_name.c_str(), key.c_str(), &length, &gerror);
   GLIBMM_THROW(gerror);
 
-  return Glib::ArrayHandler<double>::array_to_vector(array, length, Glib::OWNERSHIP_SHALLOW);
+  return Glib::ArrayHandle<double>(array, length, Glib::OWNERSHIP_SHALLOW);
 }
 
 void
 KeyFile::set_string_list(const Glib::ustring& group_name, const Glib::ustring& key,
-  const std::vector<Glib::ustring>& list)
+  const Glib::ArrayHandle<Glib::ustring>& list)
 {
   g_key_file_set_string_list(
-    gobj(), Glib::c_str_or_nullptr(group_name), key.c_str(), Glib::ArrayHandler<Glib::ustring>::vector_to_array(list).data(), list.size());
+    gobj(), Glib::c_str_or_nullptr(group_name), key.c_str(), list.data(), list.size());
 }
 
 void
 KeyFile::set_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key,
-  const Glib::ustring& locale, const std::vector<Glib::ustring>& list)
+  const Glib::ustring& locale, const Glib::ArrayHandle<Glib::ustring>& list)
 {
   g_key_file_set_locale_string_list(gobj(), Glib::c_str_or_nullptr(group_name), key.c_str(),
-    locale.c_str(), Glib::ArrayHandler<Glib::ustring>::vector_to_array(list).data(), list.size());
+    locale.c_str(), list.data(), list.size());
 }
 
 void
 KeyFile::set_integer_list(
-  const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<int>&  list)
+  const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<int>& list)
 {
   g_key_file_set_integer_list(gobj(), Glib::c_str_or_nullptr(group_name), key.c_str(),
-    const_cast<int*>(Glib::ArrayHandler<int>::vector_to_array(list).data()), list.size());
+    const_cast<int*>(list.data()), list.size());
 }
 
 void
 KeyFile::set_double_list(
-  const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<double>&  list)
+  const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<double>& list)
 {
   g_key_file_set_double_list(
-    gobj(), group_name.c_str(), key.c_str(), const_cast<double*>(Glib::ArrayHandler<double>::vector_to_array(list).data()), list.size());
+    gobj(), group_name.c_str(), key.c_str(), const_cast<double*>(list.data()), list.size());
 }
 
 void
 KeyFile::set_boolean_list(
-  const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<bool>&  list)
+  const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<bool>& list)
 {
   g_key_file_set_boolean_list(gobj(), Glib::c_str_or_nullptr(group_name), key.c_str(),
-    const_cast<gboolean*>(Glib::ArrayHandler<bool>::vector_to_array(list).data()), list.size());
+    const_cast<gboolean*>(list.data()), list.size());
 }
 
 Glib::ustring
index a2641bb..60afd90 100644 (file)
@@ -18,11 +18,10 @@ _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
 #include <glibmm/ustring.h>
+#include <glibmm/arrayhandle.h>
 #include <glibmm/error.h>
 #include <glibmm/utility.h>
-#include <glibmm/refptr.h>
 #include <glib.h>
-#include <vector>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" { typedef struct _GKeyFile GKeyFile; }
@@ -31,9 +30,11 @@ extern "C" { typedef struct _GKeyFile GKeyFile; }
 namespace Glib
 {
 
+  _WRAP_ENUM(KeyFileFlags, GKeyFileFlags, NO_GTYPE)
+
 /** Exception class for KeyFile errors.
  */
-_WRAP_GERROR(KeyFileError, GKeyFileError, G_KEY_FILE_ERROR, NO_GTYPE)
+_WRAP_GERROR(KeyFileError, GKeyFileError, G_KEY_FILE_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 /** This class lets you parse, edit or create files containing groups of key-value pairs, which we call key files
  * for lack of a better name. Several freedesktop.org specifications use key files now, e.g the Desktop Entry
@@ -90,19 +91,43 @@ _WRAP_GERROR(KeyFileError, GKeyFileError, G_KEY_FILE_ERROR, NO_GTYPE)
  *
  * @newin{2,14}
  */
-class KeyFile final
+class GLIBMM_API KeyFile
 {
-  _CLASS_OPAQUE_REFCOUNTED(KeyFile, GKeyFile, g_key_file_new, g_key_file_ref, g_key_file_unref)
-  _IGNORE(g_key_file_new, g_key_file_ref, g_key_file_unref, g_key_file_free)
-
+  _CLASS_GENERIC(KeyFile, GKeyFile)
 public:
 
-  _WRAP_ENUM(Flags, GKeyFileFlags, NO_GTYPE)
+  //TODO: GKeyFile now seems to be a reference-counted type.
 
   //TODO: Maybe replace all the get_*/set_* methods with some generic get/set
   //methods when it is possible.
 
-  _WRAP_METHOD(bool load_from_file(const std::string& file, Flags flags = Flags::NONE), g_key_file_load_from_file, errthrow)
+  /** Creates a new, empty KeyFile object.
+   */
+  KeyFile();
+
+  KeyFile(const KeyFile&) = delete;
+  KeyFile& operator=(const KeyFile&) = delete;
+
+  KeyFile(KeyFile&& other) noexcept;
+  KeyFile& operator=(KeyFile&& other) noexcept;
+
+  /** Destructor
+   */
+  ~KeyFile();
+  _IGNORE(g_key_file_free)
+
+  /** Creates a glibmm KeyFile wrapper for a GKeyFile object.
+   * Note, when using this that when the wrapper is deleted,
+   * it will not automatically delete the GKeyFile unless you
+   * set the @a takes_ownership boolean to <tt>true</tt>.
+   * @param castitem The C instance to wrap.
+   * @param takes_ownership If the C instance should be deleted when
+   * the wrapper is deleted.
+   */
+  KeyFile(GKeyFile* castitem, bool takes_ownership = false);
+
+public:
+  _WRAP_METHOD(bool load_from_file(const std::string& file, KeyFileFlags flags = Glib::KEY_FILE_NONE), g_key_file_load_from_file, errthrow)
 
   /** Loads a KeyFile from memory
    * @param data The data to use as a KeyFile
@@ -110,15 +135,17 @@ public:
    * @return true if the KeyFile was successfully loaded, false otherwise
    * @throw Glib::KeyFileError
    */
-  bool load_from_data(const Glib::ustring& data, Flags flags = Flags::NONE);
+  bool load_from_data(const Glib::ustring& data, KeyFileFlags flags = Glib::KEY_FILE_NONE);
   _IGNORE(g_key_file_load_from_data)
 
-#m4 _CONVERSION(`const std::vector<std::string>& ', `const gchar**', `const_cast<const gchar**>($3.data())')
+#m4 _CONVERSION(`const Glib::ArrayHandle<std::string>&', `const gchar**', `const_cast<const gchar**>($3.data())')
+#m4 _CONVERSION(`Glib::ArrayHandle<std::string>&', `gchar**', `const_cast<gchar**>($3.data())')
 
-  _IGNORE(g_key_file_load_from_dirs)
+  _WRAP_METHOD(bool load_from_dirs(const std::string& file, const Glib::ArrayHandle<std::string>& search_dirs, Glib::ArrayHandle<std::string>& full_path, KeyFileFlags flags = Glib::KEY_FILE_NONE),
+    g_key_file_load_from_dirs, errthrow "Glib::KeyFileError, Glib::FileError", errthrow, deprecated "Use the load_from_dirs() method that takes a std::string& full_path.")
 
   _WRAP_METHOD_DOCS_ONLY(g_key_file_load_from_dirs, errthrow "Glib::KeyFileError, Glib::FileError")
-  bool load_from_dirs(const std::string& file, const std::vector<std::string>&  search_dirs, std::string& full_path, Flags flags = Flags::NONE);
+  bool load_from_dirs(const std::string& file, const Glib::ArrayHandle<std::string>& search_dirs, std::string& full_path, KeyFileFlags flags = Glib::KEY_FILE_NONE);
 
   /** Looks for a KeyFile named @a file in the paths returned from
    * g_get_user_data_dir() and g_get_system_data_dirs() and loads them
@@ -131,7 +158,7 @@ public:
    * @throw Glib::KeyFileError
    * @throw Glib::FileError
    */
-  bool load_from_data_dirs(const std::string& file, std::string& full_path, Flags flags = Flags::NONE);
+  bool load_from_data_dirs(const std::string& file, std::string& full_path, KeyFileFlags flags = Glib::KEY_FILE_NONE);
   _IGNORE(g_key_file_load_from_data_dirs)
 
   /** Outputs the KeyFile as a string
@@ -141,14 +168,14 @@ public:
   Glib::ustring to_data();
   _IGNORE(g_key_file_to_data)
 
-  _WRAP_METHOD(bool save_to_file(const std::string& filename), g_key_file_save_to_file, errthrow "Glib::FileError")
+  _WRAP_METHOD(bool save_to_file(const std::string& filename), g_key_file_save_to_file, errthrow "Glib::FileError", errthrow)
 
   _WRAP_METHOD(Glib::ustring get_start_group() const, g_key_file_get_start_group)
 
   /** Gets a list of all groups in the KeyFile
    * @returns A list containing the names of the groups
    */
-  std::vector<Glib::ustring> get_groups() const;
+  Glib::ArrayHandle<Glib::ustring> get_groups() const;
   _IGNORE(g_key_file_get_groups)
 
   /** Gets a list of all keys from the group @a group_name.
@@ -156,7 +183,7 @@ public:
    * @returns A list containing the names of the keys in @a group_name
    * @throw Glib::KeyFileError
    */
-  std::vector<Glib::ustring> get_keys(const Glib::ustring& group_name) const;
+  Glib::ArrayHandle<Glib::ustring> get_keys(const Glib::ustring& group_name) const;
   _IGNORE(g_key_file_get_keys)
 
   _WRAP_METHOD(bool has_group(const Glib::ustring& group_name) const, g_key_file_has_group)
@@ -212,7 +239,7 @@ public:
    */
   gint64 get_int64(const Glib::ustring& key) const;
 
-  _WRAP_METHOD(gint64 get_int64(const Glib::ustring& group_name, const Glib::ustring& key) const, g_key_file_get_int64, errthrow "Glib::KeyFileError")
+  _WRAP_METHOD(gint64 get_int64(const Glib::ustring& group_name, const Glib::ustring& key) const, g_key_file_get_int64, errthrow "Glib::KeyFileError", errthrow)
 
   /** Gets the value in the first group, under @a key, interpreting it as
    * an unsigned 64-bit integer. This is similar to get_integer() but can
@@ -225,7 +252,7 @@ public:
    */
   guint64 get_uint64(const Glib::ustring& key) const;
 
-  _WRAP_METHOD(guint64 get_uint64(const Glib::ustring& group_name, const Glib::ustring& key) const, g_key_file_get_uint64, errthrow "Glib::KeyFileError")
+  _WRAP_METHOD(guint64 get_uint64(const Glib::ustring& group_name, const Glib::ustring& key) const, g_key_file_get_uint64, errthrow "Glib::KeyFileError", errthrow)
 
   /** Gets the value in the first group, under @a key, interpreting it as
    * a double.
@@ -257,7 +284,7 @@ public:
    * @return A list containing the values requested
    * @throw Glib::KeyFileError
    */
-  std::vector<Glib::ustring> get_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
+  Glib::ArrayHandle<Glib::ustring> get_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
   _IGNORE(g_key_file_get_string_list)
 
   /** Returns the values associated with @a key under @a group_name
@@ -267,7 +294,7 @@ public:
    * @return A list containing the values requested
    * @throw Glib::KeyFileError
    */
-  std::vector<Glib::ustring> get_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
+  Glib::ArrayHandle<Glib::ustring> get_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
 
   /** Returns the values associated with @a key under @a group_name
    * translated into @a locale, if available.
@@ -277,7 +304,7 @@ public:
    * @return A list containing the values requested
    * @throw Glib::KeyFileError
    */
-  std::vector<Glib::ustring> get_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ustring& locale) const;
+  Glib::ArrayHandle<Glib::ustring> get_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ustring& locale) const;
   _IGNORE(g_key_file_get_locale_string_list)
 
   /** Returns the values associated with @a key under @a group_name
@@ -286,7 +313,7 @@ public:
    * @return A list of booleans
    * @throw Glib::KeyFileError
    */
-  std::vector<bool> get_boolean_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
+  Glib::ArrayHandle<bool> get_boolean_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
   _IGNORE(g_key_file_get_boolean_list)
 
   /** Returns the values associated with @a key under @a group_name
@@ -295,7 +322,7 @@ public:
    * @return A list of integers
    * @throw Glib::KeyFileError
    */
-  std::vector<int> get_integer_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
+  Glib::ArrayHandle<int> get_integer_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
   _IGNORE(g_key_file_get_integer_list)
 
   /** Returns the values associated with @a key under @a group_name
@@ -304,7 +331,7 @@ public:
    * @return A list of doubles
    * @throw Glib::KeyFileError
    */
-  std::vector<double> get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
+  Glib::ArrayHandle<double> get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const;
   _IGNORE(g_key_file_get_double_list)
 
   /** Get comment from top of file
@@ -338,7 +365,7 @@ public:
    * @param key The name of a key
    * @param list A list holding objects of type Glib::ustring
    */
-  void set_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<Glib::ustring>&  list);
+  void set_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<Glib::ustring>& list);
   _IGNORE(g_key_file_set_string_list)
 
   /** Sets a list of string values for the @a key under @a group_name and marks
@@ -349,7 +376,7 @@ public:
    * @param locale A locale
    * @param list A list holding objects of type Glib::ustring
    */
-  void set_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ustring& locale, const std::vector<Glib::ustring>&  list);
+  void set_locale_string_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ustring& locale, const Glib::ArrayHandle<Glib::ustring>& list);
   _IGNORE(g_key_file_set_locale_string_list)
 
   /** Sets a list of booleans for the @a key under @a group_name.
@@ -358,7 +385,7 @@ public:
    * @param key The name of a key
    * @param list A list holding object of type bool
    */
-  void set_boolean_list(const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<bool>&  list);
+  void set_boolean_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<bool>& list);
   _IGNORE(g_key_file_set_boolean_list)
 
   /** Sets a list of integers for the @a key under @a group_name.
@@ -367,7 +394,7 @@ public:
    * @param key The name of a key
    * @param list A list holding object of type int
    */
-  void set_integer_list(const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<int>&  list);
+  void set_integer_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<int>& list);
   _IGNORE(g_key_file_set_integer_list)
 
   /** Sets a list of doubles for the @a key under @a group_name.
@@ -378,7 +405,7 @@ public:
    *
    * @newin{2,14}
    */
-  void set_double_list(const Glib::ustring& group_name, const Glib::ustring& key, const std::vector<double>&  list);
+  void set_double_list(const Glib::ustring& group_name, const Glib::ustring& key, const Glib::ArrayHandle<double>& list);
   _IGNORE(g_key_file_set_double_list)
 
 
@@ -400,6 +427,14 @@ public:
   _WRAP_METHOD(void remove_comment(const Glib::ustring& group_name, const Glib::ustring& key), g_key_file_remove_comment, errthrow)
   _WRAP_METHOD(void remove_key(const Glib::ustring& group_name, const Glib::ustring& key), g_key_file_remove_key, errthrow)
   _WRAP_METHOD(void remove_group(const Glib::ustring& group_name), g_key_file_remove_group, errthrow)
+
+  GKeyFile*       gobj()       { return gobject_; }
+  const GKeyFile* gobj() const { return gobject_; }
+
+protected:
+  GKeyFile* gobject_;
+  bool owns_gobject_;
 };
 
 } // namespace Glib
+
index 8e014ba..2bd258c 100644 (file)
@@ -63,7 +63,7 @@ namespace Glib
 
 /** %Exception class for markup parsing errors.
  */
-_WRAP_GERROR(MarkupError, GMarkupError, G_MARKUP_ERROR, NO_GTYPE)
+_WRAP_GERROR(MarkupError, GMarkupError, G_MARKUP_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 /*! @var MarkupError::Code MarkupError::BAD_UTF8
  * Text being parsed was not valid UTF-8.
@@ -93,7 +93,7 @@ _WRAP_GERROR(MarkupError, GMarkupError, G_MARKUP_ERROR, NO_GTYPE)
 namespace Markup
 {
 
-class ParseContext;
+class GLIBMM_API ParseContext;
 
 /** @ingroup Markup */
 using Error = Glib::MarkupError;
@@ -107,9 +107,20 @@ using Error = Glib::MarkupError;
  * @param text Some valid UTF-8 text.
  * @return Escaped text.
  */
+GLIBMM_API
 Glib::ustring escape_text(const Glib::ustring& text);
 
-_WRAP_ENUM(ParseFlags, GMarkupParseFlags, NO_GTYPE)
+
+/** There are no flags right now. Pass <tt>Glib::Markup::ParseFlags(0)</tt> for
+ * the flags argument to all functions (this should be the default argument
+ * anyway).
+ */
+_WRAP_ENUM(ParseFlags, GMarkupParseFlags, NO_GTYPE, s#^MARKUP_##)
+
+/*! @var Markup::ParseFlags DO_NOT_USE_THIS_UNSUPPORTED_FLAG
+ * Flag you should not use.
+ */
+
 
 /** Binary predicate used by Markup::Parser::AttributeMap.
  * @ingroup Markup
@@ -118,7 +129,7 @@ _WRAP_ENUM(ParseFlags, GMarkupParseFlags, NO_GTYPE)
  * the AttributeKeyLess predicate is locale-independent.  This is both
  * more correct and much more efficient.
  */
-class AttributeKeyLess
+class GLIBMM_API AttributeKeyLess
 {
 public:
   using first_argument_type = Glib::ustring;
@@ -147,7 +158,7 @@ class ParserCallbacks;
  * error from a method, Glib::Markup::ParseContext::parse() will report that
  * error back to its caller.
  */
-class Parser : public sigc::trackable
+class GLIBMM_API Parser : public sigc::trackable
 {
 public:
   typedef std::map<Glib::ustring, Glib::ustring, Glib::Markup::AttributeKeyLess> AttributeMap;
@@ -243,7 +254,7 @@ private:
  * occur; once an error occurs, the parse context can't continue to parse text
  * (you have to destroy it and create a new parse context).
  */
-class ParseContext : public sigc::trackable
+class GLIBMM_API ParseContext : public sigc::trackable
 {
 public:
   /** Creates a new parse context.
index 90043af..b059f1d 100644 (file)
@@ -74,10 +74,16 @@ unsetenv(const std::string& variable)
   g_unsetenv(variable.c_str());
 }
 
-std::vector<std::string>
+Glib::ArrayHandle<std::string>
 listenv()
 {
-  return Glib::ArrayHandler<std::string>::array_to_vector(g_listenv(), Glib::OWNERSHIP_DEEP);
+  char** value = g_listenv();
+  char** end = value;
+  while (*end)
+  {
+    ++end;
+  }
+  return Glib::ArrayHandle<std::string>(value, end - value, Glib::OWNERSHIP_DEEP);
 }
 
 std::string
@@ -92,6 +98,12 @@ get_real_name()
   return convert_const_gchar_ptr_to_stdstring(g_get_real_name());
 }
 
+Glib::ustring
+get_host_name()
+{
+  return convert_const_gchar_ptr_to_ustring(g_get_host_name());
+}
+
 std::string
 get_home_dir()
 {
@@ -110,6 +122,14 @@ get_current_dir()
   return convert_return_gchar_ptr_to_stdstring(g_get_current_dir());
 }
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+std::string
+get_user_special_dir(GUserDirectory directory)
+{
+  return convert_const_gchar_ptr_to_stdstring(g_get_user_special_dir(directory));
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 std::string
 get_user_special_dir(UserDirectory directory)
 {
@@ -131,13 +151,35 @@ get_user_config_dir()
 std::vector<std::string>
 get_system_data_dirs()
 {
-  return Glib::ArrayHandler<std::string>::array_to_vector(g_get_system_data_dirs(), Glib::OWNERSHIP_NONE);
+  // TODO: Use a utility function:
+  std::vector<std::string> result;
+  const char* const* cresult = g_get_system_data_dirs();
+  if (!cresult)
+    return result;
+
+  for (const gchar* const* iter = cresult; *iter != nullptr; ++iter)
+  {
+    result.emplace_back(convert_const_gchar_ptr_to_stdstring(*iter));
+  }
+
+  return result;
 }
 
 std::vector<std::string>
 get_system_config_dirs()
 {
-  return Glib::ArrayHandler<std::string>::array_to_vector(g_get_system_config_dirs(), Glib::OWNERSHIP_NONE);
+  // TODO: Use a utility function:
+  std::vector<std::string> result;
+  const char* const* cresult = g_get_system_config_dirs();
+  if (!cresult)
+    return result;
+
+  for (const gchar* const* iter = cresult; *iter != nullptr; ++iter)
+  {
+    result.emplace_back(convert_const_gchar_ptr_to_stdstring(*iter));
+  }
+
+  return result;
 }
 
 std::string
@@ -146,6 +188,12 @@ get_user_cache_dir()
   return convert_const_gchar_ptr_to_stdstring(g_get_user_cache_dir());
 }
 
+std::string
+get_user_runtime_dir()
+{
+  return convert_const_gchar_ptr_to_stdstring(g_get_user_runtime_dir());
+}
+
 bool
 path_is_absolute(const std::string& filename)
 {
@@ -173,10 +221,17 @@ path_get_dirname(const std::string& filename)
 }
 
 std::string
-build_filename(const std::vector<std::string>& elements)
+canonicalize_filename(StdStringView filename, StdStringView relative_to)
+{
+  return convert_return_gchar_ptr_to_stdstring(g_canonicalize_filename(
+    filename.c_str(), relative_to.c_str()));
+}
+
+std::string
+build_filename(const Glib::ArrayHandle<std::string>& elements)
 {
   return convert_return_gchar_ptr_to_stdstring(
-    g_build_filenamev(const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(elements).data())));
+    g_build_filenamev(const_cast<char**>(elements.data())));
 }
 
 std::string
@@ -247,10 +302,10 @@ build_filename(const std::string& elem1, const std::string& elem2, const std::st
 }
 
 std::string
-build_path(const std::string& separator, const std::vector<std::string>& elements)
+build_path(const std::string& separator, const Glib::ArrayHandle<std::string>& elements)
 {
   return convert_return_gchar_ptr_to_stdstring(
-    g_build_pathv(separator.c_str(), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(elements).data())));
+    g_build_pathv(separator.c_str(), const_cast<char**>(elements.data())));
 }
 
 std::string
index ffc87f3..4ec3137 100644 (file)
 
 _DEFS(glibmm,glib)
 
+#include <glibmm/arrayhandle.h>
 #include <glibmm/ustring.h>
-#include <vector>
 
 namespace Glib
 {
-_WRAP_ENUM(UserDirectory, GUserDirectory, NO_GTYPE, s#^DIRECTORY_##)
+_WRAP_ENUM(UserDirectory, GUserDirectory, NO_GTYPE)
 _WRAP_ENUM(FormatSizeFlags, GFormatSizeFlags, NO_GTYPE)
 
 /** @defgroup MiscUtils Miscellaneous Utility Functions
@@ -40,6 +40,7 @@ _WRAP_ENUM(FormatSizeFlags, GFormatSizeFlags, NO_GTYPE)
  *
  * @return Human-readable application name. May return <tt>""</tt>.
  */
+GLIBMM_API
 Glib::ustring get_application_name();
 
 /** Sets a human-readable name for the application.
@@ -55,6 +56,7 @@ Glib::ustring get_application_name();
  *
  * @param application_name Localized name of the application.
  */
+GLIBMM_API
 void set_application_name(const Glib::ustring& application_name);
 
 /** Gets the name of the program.
@@ -68,11 +70,13 @@ void set_application_name(const Glib::ustring& application_name);
  *
  * @return The name of the program.
  */
+GLIBMM_API
 std::string get_prgname();
 
 /** Sets the name of the program.
  * @param prgname The name of the program.
  */
+GLIBMM_API
 void set_prgname(const std::string& prgname);
 
 /** Returns the value of an environment variable. The name and value
@@ -86,6 +90,7 @@ void set_prgname(const std::string& prgname);
  * @param[out] found Whether the environment variable has been found.
  * @return The value of the environment variable, or <tt>""</tt> if not found.
  */
+GLIBMM_API
 std::string getenv(const std::string& variable, bool& found);
 
 /** Returns the value of an environment variable. The name and value
@@ -98,6 +103,7 @@ std::string getenv(const std::string& variable, bool& found);
  * @param variable The environment variable to get.
  * @return The value of the environment variable, or <tt>""</tt> if not found.
  */
+GLIBMM_API
 std::string getenv(const std::string& variable);
 
 
@@ -114,6 +120,7 @@ std::string getenv(const std::string& variable);
  * @param overwrite Whether to change the variable if it already exists.
  * @result false if the environment variable couldn't be set.
  */
+GLIBMM_API
 bool setenv(const std::string& variable, const std::string& value, bool overwrite = true);
 
 /** Removes an environment variable from the environment.
@@ -125,6 +132,7 @@ bool setenv(const std::string& variable, const std::string& value, bool overwrit
  *
  * @param variable: the environment variable to remove. It  must not contain '='.
  **/
+GLIBMM_API
 void unsetenv(const std::string& variable);
 
 /** Gets the names of all variables set in the environment.
@@ -139,7 +147,8 @@ void unsetenv(const std::string& variable);
  * @return Array of environment names (The generic ArrayHandle will be
  * implicitly converted to any STL compatible container type).
  */
-std::vector<std::string> listenv();
+GLIBMM_API
+Glib::ArrayHandle<std::string> listenv();
 
 /** Gets the user name of the current user.
  *
@@ -150,6 +159,7 @@ std::vector<std::string> listenv();
  *
  * @return The name of the current user.
  */
+GLIBMM_API
 std::string get_user_name();
 
 /** Gets the real name of the current user.
@@ -161,11 +171,31 @@ std::string get_user_name();
  *
  * @return The current user's real name.
  */
+GLIBMM_API
 std::string get_real_name();
 
+/** Return a name for the machine. 
+ *
+ * The returned name is not necessarily a fully-qualified domain name,
+ * or even present in DNS or some other name service at all. It need
+ * not even be unique on your local network or site, but usually it
+ * is. Callers should not rely on the return value having any specific
+ * properties like uniqueness for security purposes. Even if the name
+ * of the machine is changed while an application is running, the
+ * return value from this function does not change. If no name can be
+ * determined, a default fixed string "localhost" is returned.
+ *
+ * @return The host name of the machine.
+ *
+ * @newin{2,64}
+ */
+GLIBMM_API
+Glib::ustring get_host_name();
+
 /** Gets the current user's home directory.
  * @return The current user's home directory or an empty string if not defined.
  */
+GLIBMM_API
 std::string get_home_dir();
 
 /** Gets the directory to use for temporary files.
@@ -174,13 +204,38 @@ std::string get_home_dir();
  * <tt>"/tmp"</tt> is returned on UNIX and <tt>"C:\\"</tt> on Windows.
  * @return The directory to use for temporary files.
  */
+GLIBMM_API
 std::string get_tmp_dir();
 
 /** Gets the current directory.
  * @return The current directory.
  */
+GLIBMM_API
 std::string get_current_dir();
 
+#ifndef GLIBMM_DISABLE_DEPRECATED
+/** Returns the full path of a special directory using its logical id.
+ *
+ * On Unix this is done using the XDG special user directories.
+ * For compatibility with existing practise, G_USER_DIRECTORY_DESKTOP
+ * falls back to `$HOME/Desktop` when XDG special user directories have
+ * not been set up.
+ *
+ * Depending on the platform, the user might be able to change the path
+ * of the special directory without requiring the session to restart; GLib
+ * will not reflect any change once the special directories are loaded.
+ *
+ * @param directory The logical id of special directory.
+ * @return The path to the specified special directory, or an empty string
+ *         if the logical id was not found.
+ *
+ * @newin{2,14}
+ * @deprecated Use get_user_special_dir(Glib::UserDirectory directory) instead.
+ */
+GLIBMM_API
+std::string get_user_special_dir(GUserDirectory directory);
+#endif // GLIBMM_DISABLE_DEPRECATED
+
 /** Returns the full path of a special directory using its logical id.
  *
  * On Unix this is done using the XDG special user directories.
@@ -198,6 +253,7 @@ std::string get_current_dir();
  *
  * @newin{2,46}
  */
+GLIBMM_API
 std::string get_user_special_dir(UserDirectory directory);
 
 /** Returns a base directory in which to access application data such as icons
@@ -208,6 +264,7 @@ std::string get_user_special_dir(UserDirectory directory);
  *
  * @newin{2,14}
  */
+GLIBMM_API
 std::string get_user_data_dir();
 
 /** Returns a base directory in which to store user-specific application
@@ -218,6 +275,7 @@ std::string get_user_data_dir();
  *
  * @newin{2,14}
  */
+GLIBMM_API
 std::string get_user_config_dir();
 
 /** Returns an ordered list of base directories in which to access system-wide application data.
@@ -225,6 +283,7 @@ std::string get_user_config_dir();
  *
  * @newin{2,18}
  */
+GLIBMM_API
 std::vector<std::string> get_system_data_dirs();
 
 /** Returns an ordered list of base directories in which to access system-wide configuration information.
@@ -232,6 +291,7 @@ std::vector<std::string> get_system_data_dirs();
  *
  * @newin{2,18}
  */
+GLIBMM_API
 std::vector<std::string> get_system_config_dirs();
 
 /** Returns a base directory in which to store non-essential, cached data
@@ -242,14 +302,27 @@ std::vector<std::string> get_system_config_dirs();
  *
  * @newin{2,14}
  */
+GLIBMM_API
 std::string get_user_cache_dir();
 
+/** Returns a directory that is unique to the current user on the local system.
+ *
+ * This is the directory specified in the XDG_RUNTIME_DIR environment variable.
+ * In the case that this variable is not set, we return the value of
+ * Glib::get_user_cache_dir(), after verifying that it exists.
+ *
+ * @newin{2,64}
+ */
+GLIBMM_API
+std::string get_user_runtime_dir();
+
 /** Returns @c true if the given @a filename is an absolute file name, i.e.\ it
  * contains a full path from the root directory such as <tt>"/usr/local"</tt>
  * on UNIX or <tt>"C:\\windows"</tt> on Windows systems.
  * @param filename A file name.
  * @return Whether @a filename is an absolute path.
  */
+GLIBMM_API
 bool path_is_absolute(const std::string& filename);
 
 /** Returns the remaining part of @a filename after the root component,
@@ -258,12 +331,14 @@ bool path_is_absolute(const std::string& filename);
  * @param filename A file name.
  * @return The file name without the root component, or <tt>""</tt>.
  */
+GLIBMM_API
 std::string path_skip_root(const std::string& filename);
 
 /** Gets the name of the file without any leading directory components.
  * @param filename The name of the file.
  * @return The name of the file without any leading directory components.
  */
+GLIBMM_API
 std::string path_get_basename(const std::string& filename);
 
 /** Gets the directory components of a file name.
@@ -271,8 +346,35 @@ std::string path_get_basename(const std::string& filename);
  * @param filename The name of the file.
  * @return The directory components of the file.
  */
+GLIBMM_API
 std::string path_get_dirname(const std::string& filename);
 
+/** Gets the canonical file name from @a filename.
+ *
+ * All triple slashes are turned into single slashes, and all `..` and `.`s
+ * resolved against @a relative_to.
+ *
+ * Symlinks are not followed, and the returned path is guaranteed to be absolute.
+ *
+ * If @a filename is an absolute path, @a relative_to is ignored. Otherwise,
+ * @a relative_to will be prepended to @a filename to make it absolute. @a relative_to
+ * must be an absolute path, or <tt>nullptr</tt>. If @a relative_to is <tt>nullptr</tt>,
+ * it'll fallback to get_current_dir().
+ *
+ * This function never fails, and will canonicalize file paths even if they don't exist.
+ *
+ * No file system I/O is done.
+ *
+ * @param filename The name of the file.
+ * @param relative_to The relative directory, or <tt>nullptr</tt> to use the
+ *                    current working directory.
+ * @return The canonical file path.
+ *
+ * @newin{2,64}
+ */
+GLIBMM_API
+std::string canonicalize_filename(StdStringView filename, StdStringView relative_to = nullptr);
+
 /** Creates a filename from a series of elements using the correct
  * separator for filenames.
  * This function behaves identically to Glib::build_path(G_DIR_SEPARATOR_S,
@@ -283,7 +385,28 @@ std::string path_get_dirname(const std::string& filename);
  *   Any STL compatible container type is accepted.
  * @return The resulting path.
  */
-std::string build_filename(const std::vector<std::string>&  elements);
+GLIBMM_API
+std::string build_filename(const Glib::ArrayHandle<std::string>& elements);
+
+/** Creates a filename from one or more elements using the correct separator for filenames.
+ * No attempt is made to force the resulting filename to be an absolute path.
+ * If the first element is a relative path, the result will be a relative path.
+ * @tparam Strings std::string or const char*.
+ * @param strings The path elements.
+ * @return The resulting path.
+ *
+ * @newin{2,64}
+ */
+template <typename... Strings>
+std::string build_filename(const Strings&... strings)
+{
+  return Glib::convert_return_gchar_ptr_to_stdstring(
+    g_build_filename(StdStringView(strings).c_str()..., nullptr));
+}
+
+// When the templated build_filename() overload was added, the following
+// build_filename() overloads became unnecessary.
+//TODO: They can be removed when we can break ABI.
 
 /** Creates a filename from two elements using the correct separator for filenames.
  * No attempt is made to force the resulting filename to be an absolute path.
@@ -292,6 +415,7 @@ std::string build_filename(const std::vector<std::string>&  elements);
  * @param elem2 Second path element.
  * @return The resulting path.
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2);
 
 /** Creates a filename from three elements using the correct separator for filenames.
@@ -304,6 +428,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2);
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3);
 
@@ -319,6 +444,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4);
 
@@ -332,6 +458,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  * @param elem5 Fifth path element.
  * @return The resulting path.
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4,
                            const std::string& elem5);
@@ -349,6 +476,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4,
                            const std::string& elem5, const std::string& elem6);
@@ -367,6 +495,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4,
                            const std::string& elem5, const std::string& elem6,
@@ -387,6 +516,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4,
                            const std::string& elem5, const std::string& elem6,
@@ -408,6 +538,7 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *
  * @newin{2,28}
  */
+GLIBMM_API
 std::string build_filename(const std::string& elem1, const std::string& elem2,
                            const std::string& elem3, const std::string& elem4,
                            const std::string& elem5, const std::string& elem6,
@@ -448,8 +579,9 @@ std::string build_filename(const std::string& elem1, const std::string& elem2,
  *   Any STL compatible container type is accepted.
  * @return The resulting path.
  */
+GLIBMM_API
 std::string build_path(const std::string& separator,
-                       const std::vector<std::string>&  elements);
+                       const Glib::ArrayHandle<std::string>& elements);
 
 /** Locates the first executable named @a program in the user's path, in the
  * same way that <tt>execvp()</tt> would locate it.
@@ -471,6 +603,7 @@ std::string build_path(const std::string& separator,
  * @param program A program name.
  * @return An absolute path, or <tt>""</tt>.
  */
+GLIBMM_API
 std::string find_program_in_path(const std::string& program);
 
 /** Formats a size (for example the size of a file) into a human readable string.
@@ -480,7 +613,7 @@ std::string find_program_in_path(const std::string& program);
  * 3292528 bytes will be converted into the string "3.2 MB".
  *
  * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes), unless the
- * Glib::FormatSizeFlags::IEC_UNITS flag is set.
+ * Glib::FORMAT_SIZE_IEC_UNITS flag is set.
  *
  * @param size A size in bytes.
  * @param flags Flags to modify the output.
@@ -488,7 +621,8 @@ std::string find_program_in_path(const std::string& program);
  *
  * @newin{2,46}
  */
-Glib::ustring format_size(guint64 size, FormatSizeFlags flags = FormatSizeFlags::DEFAULT);
+GLIBMM_API
+Glib::ustring format_size(guint64 size, FormatSizeFlags flags = FORMAT_SIZE_DEFAULT);
 
 /** @} group MiscUtils */
 
index 6322cae..139e913 100644 (file)
@@ -20,7 +20,7 @@
 namespace Glib
 {
 
-Module::Module(const std::string& file_name, Flags flags)
+Module::Module(const std::string& file_name, ModuleFlags flags)
 : gobject_(g_module_open(file_name.c_str(), (GModuleFlags)flags))
 {
 }
index 89ddedf..e0e23aa 100644 (file)
@@ -25,6 +25,8 @@ extern "C" { typedef struct _GModule GModule; }
 namespace Glib
 {
 
+_WRAP_ENUM(ModuleFlags, GModuleFlags, NO_GTYPE)
+
 //TODO: Replace get_last_error() with exceptions?
 //Provide operator()?
 
@@ -35,15 +37,13 @@ namespace Glib
  * (e.g. Linux/Sun), as well as HP-UX via its shl_load() mechanism,
  * and Windows platforms via DLLs.
  */
-class Module
+class GLIBMM_API Module
 {
   _CLASS_GENERIC(Module, GModule)
   _IGNORE(g_module_open, g_module_close)
 
 public:
 
-  _WRAP_ENUM(Flags, GModuleFlags, NO_GTYPE)
-
   /** Opens a module.
    *
    * First of all it tries to open file_name as a module. If that
@@ -68,7 +68,7 @@ public:
    * @param file_name The library filename to open
    * @param flags Flags to configure the load process
    */
-  explicit Module(const std::string& file_name, Flags flags = Flags(0));
+  explicit Module(const std::string& file_name, ModuleFlags flags = ModuleFlags(0));
 
   Module(const Module&) = delete;
   Module& operator=(const Module&) = delete;
index 1db7f1a..cdd526b 100644 (file)
@@ -20,16 +20,30 @@ _DEFS(glibmm,glib)
 #include <stack>
 #include <deque>
 
-#include <sigc++/bind.h>
-#include <sigc++/slot.h>
 #include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
 #include <glibmm/error.h>
+#include <glibmm/arrayhandle.h>
 #include <glib.h>
 
 namespace Glib
 {
 
+//Hand-written, instead of using _WRAP_ENUM,
+//because the C enum values don't have a prefix.
+
+/** Specifies the type of traveral performed by methods such as NodeTree::_traverse() and NodeTree::find().
+ *
+ * @ingroup glibmmEnums
+ */
+enum TraverseType
+{
+  TRAVERSE_IN_ORDER = G_IN_ORDER, /*!< Visits a node's left child first, then the node itself, then its right child. This is the one to use if you want the output sorted according to the compare function.  */
+  TRAVERSE_PRE_ORDER = G_PRE_ORDER, /*!< Visits a node, then its children. */
+  TRAVERSE_POST_ORDER = G_POST_ORDER, /*!< Visits the node's children, then the node itself. */
+  TRAVERSE_LEVEL_ORDER = G_LEVEL_ORDER /*!< For NodeTree, it vists the root node first, then its children, then its grandchildren, and so on. Note that this is less efficient than the other orders. This is not implemented for Glib::Tree. */
+};
+
 /** N-ary Trees - trees of data with any number of branches
  * The NodeTree class and its associated functions provide an N-ary tree data structure, in which nodes in the tree can contain arbitrary data.
  *
@@ -54,10 +68,8 @@ class NodeTree
 {
   _CLASS_GENERIC(NodeTree, GNode)
 public:
-  _WRAP_ENUM(TraverseType, GTraverseType, NO_GTYPE)
-
-  using TraverseFunc = sigc::slot<bool(NodeTree<T>&)>;
-  using ForeachFunc = sigc::slot<void(NodeTree<T>&)>;
+  using TraverseFunc = sigc::slot<bool, NodeTree<T>&>;
+  using ForeachFunc = sigc::slot<void, NodeTree<T>&>;
 
 private:
   static NodeTree<T>* wrap(GNode* node)
@@ -269,19 +281,18 @@ public:
   }
   _IGNORE(g_node_get_root)
 
-  // Can't use _WRAP_ENUM for a Flags-type enum in a template class.
-  // gmmproc would get the bitwise operators wrong.
+
   /** Specifies which nodes are visited during several of the NodeTree methods,
    *  including traverse() and find().
    *
    * @ingroup glibmmEnums
    */
-  enum class TraverseFlags
+  enum TraverseFlags
   {
-    LEAVES = G_TRAVERSE_LEAVES, /*!< Only leaf nodes should be visited. */
-    NON_LEAVES = G_TRAVERSE_NON_LEAVES, /*!< Only non-leaf nodes should be visited. */
-    ALL = G_TRAVERSE_ALL, /*!< All nodes should be visited. */
-    MASK = G_TRAVERSE_MASK /*!< A mask of all traverse flags. */
+    TRAVERSE_LEAVES = G_TRAVERSE_LEAVES, /*!< Only leaf nodes should be visited. */
+    TRAVERSE_NON_LEAVES = G_TRAVERSE_NON_LEAVES, /*!< Only non-leaf nodes should be visited. */
+    TRAVERSE_ALL = G_TRAVERSE_ALL, /*!< All nodes should be visited. */
+    TRAVERSE_MASK = G_TRAVERSE_MASK /*!< A mask of all traverse flags. */
   };
 
   /** Traverses a tree starting at the current node.
@@ -297,7 +308,7 @@ public:
    * If max_depth is 2, the root and its children are visited. And so on.
    * @param func the slot to invoke for each visited child
    */
-  void traverse(const TraverseFunc& func, TraverseType order = TraverseType::IN_ORDER, TraverseFlags flags = TraverseFlags::ALL, int max_depth = -1)
+  void traverse(const TraverseFunc& func, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL, int max_depth = -1)
   {
     TraverseFunc func_copy = func;
     g_node_traverse(gobj(), (GTraverseType)order, (GTraverseFlags)flags, max_depth, c_callback_traverse, reinterpret_cast<gpointer>(&func_copy));
@@ -310,7 +321,7 @@ public:
    * @param flags Wwhich types of children are to be visited.
    * @param func The slot to invoke for each visited node.
    */
-  void foreach(const ForeachFunc& func, TraverseFlags flags = TraverseFlags::ALL)
+  void foreach(const ForeachFunc& func, TraverseFlags flags = TRAVERSE_ALL)
   {
     ForeachFunc func_copy = func;
     g_node_children_foreach(gobj(), (GTraverseFlags)flags, c_callback_foreach, reinterpret_cast<gpointer>(&func_copy));
@@ -319,16 +330,16 @@ public:
 
   /** Finds the first child of a NodeTree with the given data.
    *
-   * @param flags Which types of children are to be visited, one of TraverseFlags::ALL, TraverseFlags::LEAVES or TraverseFlags::NON_LEAVES.
+   * @param flags Which types of children are to be visited, one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
    * @param the_data The data for which to search.
    * @return the found child, or <tt>nullptr</tt> if the data is not found
    */
-  NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TraverseFlags::ALL)
+  NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TRAVERSE_ALL)
   {
-    sigc::slot<void(GNode*, const T&, GNode**)> real_slot = sigc::ptr_fun(on_compare_child);
+    sigc::slot<void, GNode*, const T&, GNode**> real_slot = sigc::ptr_fun(on_compare_child);
 
     GNode* child = nullptr;
-    using type_foreach_gnode_slot = sigc::slot<void(GNode*)>;
+    using type_foreach_gnode_slot = sigc::slot<void, GNode*>;
     type_foreach_gnode_slot bound_slot = sigc::bind(real_slot, the_data, &child);
 
     g_node_children_foreach(gobj(), (GTraverseFlags)flags, c_callback_foreach_compare_child, reinterpret_cast<gpointer>(&bound_slot));
@@ -338,11 +349,11 @@ public:
 
   /** Finds the first child of a NodeTree with the given data.
    *
-   * @param flags Which types of children are to be visited, one of TraverseFlags::ALL, TraverseFlags::LEAVES or TraverseFlags::NON_LEAVES.
+   * @param flags Which types of children are to be visited, one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
    * @param the_data The data for which to search.
    * @return the found child, or <tt>nullptr</tt> if the data is not found
    */
-  const NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TraverseFlags::ALL) const
+  const NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TRAVERSE_ALL) const
   {
     return const_cast<NodeTree<T>*>(this)->find_child(flags, the_data);
   }
@@ -351,18 +362,18 @@ public:
 
   /** Finds a node in a tree.
    *
-   * @param order The order in which nodes are visited: TraverseType::IN_ORDER, TraverseType::PRE_ORDER, TraverseType::POST_ORDER, or TraverseType::LEVEL_ORDER
-   * @param flags Which types of children are to be visited: one of TraverseFlags::ALL, TraverseFlags::LEAVES or TraverseFlags::NON_LEAVES.
+   * @param order The order in which nodes are visited: IN_ORDER, TRAVERSE_PRE_ORDER, TRAVERSE_POST_ORDER, or TRAVERSE_LEVEL_ORDER
+   * @param flags Which types of children are to be visited: one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
    * @param the_data The data for which to search.
    * @return The found node, or <tt>nullptr</tt> if the data is not found.
    */
-  NodeTree<T>* find(const T& the_data, TraverseType order = TraverseType::IN_ORDER, TraverseFlags flags = TraverseFlags::ALL)
+  NodeTree<T>* find(const T& the_data, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL)
   {
     //We use a sigc::slot for the C callback, so we can bind some extra data.
-    sigc::slot<gboolean(GNode*, const T&, GNode**)> real_slot = sigc::ptr_fun(on_compare_node);
+    sigc::slot<gboolean, GNode*, const T&, GNode**> real_slot = sigc::ptr_fun(on_compare_node);
     GNode* child = nullptr;
 
-    using type_traverse_gnode_slot = sigc::slot<gboolean(GNode*)>;
+    using type_traverse_gnode_slot = sigc::slot<gboolean, GNode*>;
     type_traverse_gnode_slot bound_slot = sigc::bind(real_slot, the_data, &child);
 
     g_node_traverse(const_cast<GNode*>(gobj()), (GTraverseType)order, (GTraverseFlags)flags, -1, c_callback_traverse_compare_node, reinterpret_cast<gpointer>(&bound_slot));
@@ -377,7 +388,7 @@ public:
    * @param the_data The data for which to search.
    * @return The found node, or <tt>nullptr</tt> if the data is not found.
    */
-  const NodeTree<T>* find(const T& the_data, TraverseType order = TraverseType::IN_ORDER, TraverseFlags flags = TraverseFlags::ALL) const
+  const NodeTree<T>* find(const T& the_data, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL) const
   {
     return const_cast<NodeTree<T>*>(this)->find(order, flags, the_data);
   }
@@ -580,10 +591,10 @@ public:
 
   /** Gets the number of nodes in a tree.
    *
-   * @param flags Which types of children are to be counted: one of TraverseFlags::ALL, TraverseFlags::LEAVES or TraverseFlags::NON_LEAVES
+   * @param flags Which types of children are to be counted: one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES
    * @return The number of nodes in the tree.
    */
-  guint node_count(TraverseFlags flags = TraverseFlags::ALL) const
+  guint node_count(TraverseFlags flags = TRAVERSE_ALL) const
   {
     return g_node_n_nodes(const_cast<GNode*>(gobj()), (GTraverseFlags)flags);
   }
@@ -720,7 +731,7 @@ private:
     }
   }
 
-  /// Wrapper for invoking a sigc::slot<void(GNode*)> (Internal use).
+  /// Wrapper for invoking a sigc::slot<void,GNode*> (Internal use).
   static void c_callback_foreach_compare_child(GNode* node, gpointer data)
   {
     const ForeachFunc* slot = reinterpret_cast<const ForeachFunc*>(data);
@@ -738,7 +749,7 @@ private:
     return FALSE;
   }
 
-  /// Wrapper for invoking a sigc::slot<gboolean(GNode*)> (Internal use).
+  /// Wrapper for invoking a sigc::slot<gboolean,GNode*> (Internal use).
   static gboolean c_callback_traverse_compare_node(GNode* node, gpointer data)
   {
     const TraverseFunc* slot = reinterpret_cast<const TraverseFunc*>(data);
index b63434e..2b44a73 100644 (file)
@@ -93,15 +93,15 @@ OptionContext::~OptionContext()
 void
 OptionContext::add_group(OptionGroup& group)
 {
-  // GObjectContext takes ownership of the GOptionGroup, unrefing it later.
-  g_option_context_add_group(gobj(), group.gobj_copy());
+  // Strangely, GObjectContext actually takes ownership of the GOptionGroup, deleting it later.
+  g_option_context_add_group(gobj(), (group).gobj_give_ownership());
 }
 
 void
 OptionContext::set_main_group(OptionGroup& group)
 {
-  // GObjectContext takes ownership of the GOptionGroup, unrefing it later.
-  g_option_context_set_main_group(gobj(), group.gobj_copy());
+  // Strangely, GObjectContext actually takes ownership of the GOptionGroup, deleting it later.
+  g_option_context_set_main_group(gobj(), (group).gobj_give_ownership());
 }
 
 /*
index ad696ad..7fdfccc 100644 (file)
@@ -31,7 +31,7 @@ namespace Glib
 
 /** Exception class for options.
  */
-_WRAP_GERROR(OptionError, GOptionError, G_OPTION_ERROR, NO_GTYPE)
+_WRAP_GERROR(OptionError, GOptionError, G_OPTION_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 /** An OptionContext defines and parses commandline options, using OptionGroup%s and \link OptionEntry option entries \endlink.
  *
@@ -83,7 +83,7 @@ _WRAP_GERROR(OptionError, GOptionError, G_OPTION_ERROR, NO_GTYPE)
  *
  *
  */
-class OptionContext
+class GLIBMM_API OptionContext
 {
   _CLASS_GENERIC(OptionContext, GOptionContext)
   _IGNORE(g_option_context_free)
@@ -92,14 +92,15 @@ public:
   /** Creates a new option context.
    * @param parameter_string A string which is displayed in the first line of --help output, after programname [OPTION...]
    */
-  explicit OptionContext(const Glib::ustring& parameter_string = {});
+  explicit OptionContext(const Glib::ustring& parameter_string = Glib::ustring());
 
   //Note that, unlike Glib::wrap(), this would create a second C++ instance for the same C instance,
   //so it should be used carefully. For instance you could not access data in a derived class via this second instance.
   explicit OptionContext(GOptionContext* castitem, bool take_ownership = false);
 
-  OptionContext(const OptionContext& other) = delete;
-  OptionContext& operator=(const OptionContext& other) = delete;
+  //TODO?:
+  //OptionContext(const OptionContext& other) = delete;
+  //OptionContext& operator=(const OptionContext& other) = delete;
 
   OptionContext(OptionContext&& other) noexcept;
   OptionContext& operator=(OptionContext&& other) noexcept;
@@ -115,7 +116,7 @@ public:
   _WRAP_METHOD(bool get_strict_posix() const, g_option_context_get_strict_posix)
 
 #m4 _CONVERSION(`char**&',`gchar***',`&($3)')
-  _WRAP_METHOD(bool parse(int& argc, char**& argv), g_option_context_parse, errthrow "Glib::OptionError, Glib::ConvertError")
+  _WRAP_METHOD(bool parse(int& argc, char**& argv), g_option_context_parse, errthrow "Glib::OptionError, Glib::ConvertError", errthrow)
 
   /** Parses the command line arguments.
    *
@@ -199,7 +200,7 @@ public:
    * This function is used to translate user-visible strings, for --help output.
    * The function takes an untranslated string and returns a translated string
    */
-  using SlotTranslate = sigc::slot<Glib::ustring(const Glib::ustring&)>;
+  using SlotTranslate = sigc::slot<Glib::ustring, const Glib::ustring&>;
 
   /**
    * Sets the function which is used to translate user-visible
index 4e56b4d..3d320b3 100644 (file)
@@ -20,8 +20,6 @@
 namespace Glib
 {
 
-using Flags = OptionEntry::Flags;
-
 OptionEntry::OptionEntry()
 {
   gobject_ = g_new0(GOptionEntry, 1);
@@ -99,4 +97,44 @@ OptionEntry::operator=(OptionEntry&& other) noexcept
   return *this;
 }
 
+void
+OptionEntry::set_long_name(const Glib::ustring& value)
+{
+  if (gobject_->long_name)
+  {
+    g_free((gchar*)(gobject_->long_name));
+    gobject_->long_name = nullptr;
+  }
+
+  // Note that we do not use nullptr for an empty string,
+  // because G_OPTION_REMAINING is actually a "", so it actually has a distinct meaning:
+  // TODO: Wrap G_OPTION_REMAINING in C++ somehow, maybe as an explicit set_long_name(void) or
+  // set_is_remaining()? murrayc.
+  gobj()->long_name = (value).c_str() ? g_strdup((value).c_str()) : nullptr;
+}
+
+void
+OptionEntry::set_description(const Glib::ustring& value)
+{
+  if (gobject_->description)
+  {
+    g_free((gchar*)(gobject_->description));
+    gobject_->description = nullptr;
+  }
+
+  gobj()->description = (value).empty() ? nullptr : g_strdup((value).c_str());
+}
+
+void
+OptionEntry::set_arg_description(const Glib::ustring& value)
+{
+  if (gobject_->arg_description)
+  {
+    g_free((gchar*)(gobject_->arg_description));
+    gobject_->arg_description = nullptr;
+  }
+
+  gobj()->arg_description = (value).empty() ? nullptr : g_strdup((value).c_str());
+}
+
 } // namespace Glib
index bf9847d..ff17725 100644 (file)
@@ -22,6 +22,7 @@ _DEFS(glibmm,glib)
 extern "C" { typedef struct _GOptionEntry GOptionEntry; }
 #endif
 
+
 namespace Glib
 {
 
@@ -38,12 +39,22 @@ namespace Glib
  *
  * The arg_descripton is the placeholder to use for the extra argument parsed by the option in --help  output.
  */
-class OptionEntry
+class GLIBMM_API OptionEntry
 {
   _CLASS_GENERIC(OptionEntry, GOptionEntry)
 public:
 
-  _WRAP_ENUM(Flags, GOptionFlags, NO_GTYPE)
+  //Copied from goption.h, instead of generated, so that we can put it inside the class.
+  enum Flags
+  {
+    FLAG_HIDDEN = 1 << 0,
+    FLAG_IN_MAIN = 1 << 1,
+    FLAG_REVERSE = 1 << 2,
+    FLAG_NO_ARG = 1 << 3,
+    FLAG_FILENAME = 1 << 4,
+    FLAG_OPTIONAL_ARG = 1 << 5,
+    FLAG_NOALIAS = 1 << 6
+  } GOptionFlags;
 
   OptionEntry();
   OptionEntry(const OptionEntry& src);
@@ -55,34 +66,30 @@ public:
 
   OptionEntry& operator=(const OptionEntry& src);
 
-  // We do not use nullptr for an empty string in set_long_name(),
-  // because G_OPTION_REMAINING is actually a "", so it has a distinct meaning.
-  // TODO: Wrap G_OPTION_REMAINING in C++ somehow, maybe as an overloaded
-  // set_long_name(void) or set_is_remaining()? murrayc.
-  #m4 _CONVERSION(`Glib::ustring',`const char*',`($3).c_str()')
+  //#m4 _CONVERSION(`Glib::ustring',`const gchar*',`($3).empty() ? nullptr : g_strdup(($3).c_str())')
+
   _MEMBER_GET(long_name, long_name, Glib::ustring, const char*)
-  _MEMBER_SET_STR(long_name, long_name, Glib::ustring, const char*)
+
+  void set_long_name(const Glib::ustring& value);
 
   _MEMBER_GET(short_name, short_name, gchar, gchar)
   _MEMBER_SET(short_name, short_name, gchar, gchar)
 
-#m4 _CONVERSION(`int',`Flags',`static_cast<Flags>($3)')
-  _MEMBER_GET(flags, flags, Flags, int)
+  _MEMBER_GET(flags, flags, int, int)
 
-#m4 _CONVERSION(`Flags',`int',`static_cast<int>($3)')
   /** Set one or more OptionEntry::Flags.
-   * Do not set Flags::FILENAME. Character encoding is chosen when the OptionEntry
+   * Do not set FLAG_FILENAME. Character encoding is chosen when the OptionEntry
    * is added to an OptionGroup.
    */
-  _MEMBER_SET(flags, flags, Flags, int)
+  _MEMBER_SET(flags, flags, int, int)
 
-  // We use nullptr for an empty string in set_description() and set_arg_description().
-  #m4 _CONVERSION(`Glib::ustring',`const char*',`Glib::c_str_or_nullptr($3)')
   _MEMBER_GET(description, description, Glib::ustring, const char*)
-  _MEMBER_SET_STR(description, description, Glib::ustring, const char*)
+
+  void set_description(const Glib::ustring& value);
 
   _MEMBER_GET(arg_description, arg_description, Glib::ustring, const char*)
-  _MEMBER_SET_STR(arg_description, arg_description, Glib::ustring, const char*)
+
+  void set_arg_description(const Glib::ustring& value);
 
   GOptionEntry*       gobj()       { return gobject_; }
   const GOptionEntry* gobj() const { return gobject_; }
@@ -91,6 +98,7 @@ private:
   void release_gobject() noexcept;
 
 protected:
+
   GOptionEntry* gobject_;
 };
 
index ee9b7bf..f45c5a9 100644 (file)
@@ -18,6 +18,7 @@
 #include <glibmm/optioncontext.h>
 #include <glibmm/utility.h>
 #include <glibmm/exceptionhandler.h>
+//#include <glibmm/containers.h>
 #include <glib.h> // g_malloc
 #include <cstring> // std::memset()
 
@@ -83,7 +84,7 @@ g_callback_pre_parse(
 
   try
   {
-    return option_group->on_pre_parse(cppContext);
+    return option_group->on_pre_parse(cppContext, *option_group);
   }
   catch (Glib::Error& err)
   {
@@ -98,25 +99,18 @@ g_callback_pre_parse(
 
 static void
 g_callback_error(
-  GOptionContext* context, GOptionGroup* /* group */, gpointer data, GError** error)
+  GOptionContext* context, GOptionGroup* /* group */, gpointer data, GError** /* TODO error */)
 {
-  // GError** error is input data containing information on an error that
-  // has occurred before this function is called.
+  // TODO GError** error is input data containing information on an error that
+  // has occurred before this function is called. When API can be broken,
+  // the function prototype of on_error ought to be changed to
+  // void on_error(OptionContext& context, Error& error).
 
   OptionContext cppContext(context, false /* take_ownership */);
 
   auto option_group = static_cast<OptionGroup*>(data);
-  if (option_group && error && *error)
-  {
-    try
-    {
-      Error::throw_exception(g_error_copy(*error));
-    }
-    catch (const Error& err)
-    {
-      return option_group->on_error(cppContext, err);
-    }
-  }
+  if (option_group)
+    return option_group->on_error(cppContext, *option_group);
 }
 
 const gchar*
@@ -173,7 +167,7 @@ OptionGroup::post_parse_callback(
 
   try
   {
-    return option_group->on_post_parse(cppContext);
+    return option_group->on_post_parse(cppContext, *option_group);
   }
   catch (Glib::Error& err)
   {
@@ -275,7 +269,8 @@ OptionGroup::option_arg_callback(
 OptionGroup::OptionGroup(const Glib::ustring& name, const Glib::ustring& description,
   const Glib::ustring& help_description)
 : gobject_(g_option_group_new(name.c_str(), description.c_str(), help_description.c_str(),
-    this /* user_data */, nullptr /* destroy_func */))
+    this /* user_data */, nullptr /* destroy_func */)),
+  has_ownership_(true)
 {
   // g_callback_pre_parse(), post_parse_callback(), g_callback_error(), and
   // option_arg_callback() depend on user_data being this. The first three
@@ -288,11 +283,35 @@ OptionGroup::OptionGroup(const Glib::ustring& name, const Glib::ustring& descrip
   g_option_group_set_error_hook(gobj(), &g_callback_error);
 }
 
-OptionGroup::OptionGroup(GOptionGroup* castitem) : gobject_(castitem)
+OptionGroup::OptionGroup(GOptionGroup* castitem) : gobject_(castitem), has_ownership_(true)
 {
   // Always takes ownership - never takes copy.
 }
 
+OptionGroup::OptionGroup(OptionGroup&& other) noexcept
+  : map_entries_(std::move(other.map_entries_)),
+    gobject_(std::move(other.gobject_)),
+    has_ownership_(std::move(other.has_ownership_))
+{
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+}
+
+OptionGroup&
+OptionGroup::operator=(OptionGroup&& other) noexcept
+{
+  release_gobject();
+
+  map_entries_ = std::move(other.map_entries_);
+  gobject_ = std::move(other.gobject_);
+  has_ownership_ = std::move(other.has_ownership_);
+
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+
+  return *this;
+}
+
 void
 OptionGroup::release_gobject() noexcept
 {
@@ -303,7 +322,7 @@ OptionGroup::release_gobject() noexcept
     cpp_entry.release_c_arg();
   }
 
-  if (gobject_)
+  if (has_ownership_ && gobject_)
   {
     g_option_group_unref(gobj());
     gobject_ = nullptr;
@@ -377,7 +396,7 @@ OptionGroup::add_entry_filename(const OptionEntry& entry, vecstrings& arg)
 }
 
 // When the command argument value is to be parsed by a user-supplied function
-// (indicated by G_OPTION_ARG_CALLBACK), the OptionEntry::Flags::FILENAME in 'entry' is ignored.
+// (indicated by G_OPTION_ARG_CALLBACK), the FLAG_FILENAME in 'entry' is ignored.
 // set_c_arg_default() clears or sets it as required in a copy of 'entry'.
 //
 // The glib API is inconsistent here. The choice between UTF-8 and filename
@@ -385,7 +404,7 @@ OptionGroup::add_entry_filename(const OptionEntry& entry, vecstrings& arg)
 // G_OPTION_ARG_STRING_ARRAY, and G_OPTION_ARG_FILENAME_ARRAY, which in glibmm
 // are set by OptionGroup::add_entry[_filename]. But when a callback function
 // is chosen, there is only G_OPTION_ARG_CALLBACK, and the encoding is chosen
-// with OptionEntry::Flags::FILENAME. We do this automatiically in set_c_arg_default().
+// with G_OPTION_FLAG_FILENAME. We do this automatiically in set_c_arg_default().
 // Other option flags are set by OptionEntry::set_flags().
 
 void
@@ -463,19 +482,19 @@ OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg arg_typ
 }
 
 bool
-OptionGroup::on_pre_parse(OptionContext& /* context */)
+OptionGroup::on_pre_parse(OptionContext& /* context */, OptionGroup& /* group */)
 {
   return true;
 }
 
 bool
-OptionGroup::on_post_parse(OptionContext& /* context */)
+OptionGroup::on_post_parse(OptionContext& /* context */, OptionGroup& /* group */)
 {
   return true;
 }
 
 void
-OptionGroup::on_error(OptionContext& /* context */, const Error& /* error */)
+OptionGroup::on_error(OptionContext& /* context */, OptionGroup& /* group */)
 {
 }
 
@@ -613,15 +632,15 @@ OptionGroup::CppOptionEntry::set_c_arg_default(void* cpp_arg)
   {
     // No value to set here. The arg pointer is a function pointer.
 
-    // Set or clear OptionEntry::Flags::FILENAME in *entry_.
+    // Set or clear FLAG_FILENAME in *entry_.
     const OptionArgCallback* const option_arg = static_cast<const OptionArgCallback*>(cpp_arg);
     if (option_arg->is_filename_option())
     {
-      entry_->set_flags(entry_->get_flags() | OptionEntry::Flags::FILENAME);
+      entry_->set_flags(entry_->get_flags() | OptionEntry::FLAG_FILENAME);
     }
     else
     {
-      entry_->set_flags(entry_->get_flags() & ~OptionEntry::Flags::FILENAME);
+      entry_->set_flags(entry_->get_flags() & ~OptionEntry::FLAG_FILENAME);
     }
     break;
   }
@@ -751,7 +770,7 @@ OptionGroup::CppOptionEntry::convert_c_to_cpp()
       typed_cpp_arg->clear();
 
       // The C array is null-terminated.
-      // std::vector<Glib::ustring> array_handle(*typed_arg,  Glib::OWNERSHIP_NONE);
+      // Glib::StringArrayHandle array_handle(*typed_arg,  Glib::OWNERSHIP_NONE);
 
       // The SUN Forte compiler complains about this:
       // "optiongroup.cc", line 354: Error: Cannot assign Glib::ArrayHandle<Glib::ustring,
@@ -766,7 +785,7 @@ OptionGroup::CppOptionEntry::convert_c_to_cpp()
       //     of a pointer dynamic_cast must be a pointer to a complete class type
       //   return dynamic_cast<CppType>(Glib::wrap_auto(cobj, false /* take_copy */));
 
-      // for(auto iter = array_handle.begin(); iter !=
+      // for(Glib::StringArrayHandle::iterator iter = array_handle.begin(); iter !=
       // array_handle.end(); ++iter)
       //{
       //  typed_cpp_arg->emplace_back(*iter);
@@ -821,9 +840,10 @@ OptionGroup::CppOptionEntry::convert_c_to_cpp()
 }
 
 GOptionGroup*
-OptionGroup::gobj_copy() const
+OptionGroup::gobj_give_ownership()
 {
-  return g_option_group_ref(gobject_);
+  has_ownership_ = false;
+  return gobj();
 }
 
 } // namespace Glib
index bf69089..e491f30 100644 (file)
@@ -16,7 +16,6 @@
 
 _DEFS(glibmm,glib)
 
-#include <glibmm/error.h>
 #include <glibmm/ustring.h>
 #include <sigc++/slot.h>
 #include <map>
@@ -33,43 +32,35 @@ namespace Glib
 {
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-class OptionEntry;
-class OptionContext;
+class GLIBMM_API OptionEntry;
+class GLIBMM_API OptionContext;
 #endif //DOXYGEN_SHOULD_SKIP_THIS
 
-// GOptionGroup is now refcounted. See https://bugzilla.gnome.org/show_bug.cgi?id=743349
-// But Glib::OptionGroup can't be a _CLASS_OPAQUE_REFCOUNTED, because it has
-// other data members than gobject_. The memory management would be more involved
-// if Glib::OptionGroup were refcounted. It would need a separate refcount for the
-// wrapper, like in Glib::IOChannel and Glib::Source. It's easier and good enough
-// to let Glib::OptionGroup remain non-refcounted. GOptionGroup's refcount still helps.
-// E.g. when GOptionContext takes ownership of a GOptionGroup, it's given a ref.
-// A drawback with this approach is that it's possible to have more than one wrapper
-// for one GOptionGroup, each wrapper with its own ref.
-
+//TODO: GOptionGroup is now refcounted. See https://bugzilla.gnome.org/show_bug.cgi?id=743349
+//When we can break API/ABI, make Glib::OptionGroup refcounted. _CLASS_OPAQUE_REFCOUNTED?
 /** An OptionGroup defines the options in a single group.
  * Libraries which need to parse commandline options are expected to provide a function that allows their OptionGroups to
  * be added to the application's OptionContext.
  */
-class OptionGroup
+class GLIBMM_API OptionGroup
 {
   _CLASS_GENERIC(OptionGroup, GOptionGroup)
 public:
   /** For example Glib::ustring on_translate(const Glib::ustring& original);.
    */
-  using SlotTranslate = sigc::slot<Glib::ustring(const Glib::ustring&)>;
+  using SlotTranslate = sigc::slot<Glib::ustring, const Glib::ustring&>;
 
   /** For example bool on_option_arg_string(const Glib::ustring& option_name,
    *  const Glib::ustring& value, bool has_value);.
    */
-  using SlotOptionArgString = sigc::slot<bool(const Glib::ustring&, const Glib::ustring&, bool)>;
+  using SlotOptionArgString = sigc::slot<bool, const Glib::ustring&, const Glib::ustring&, bool>;
 
   /** For example bool on_option_arg_filename(const Glib::ustring& option_name,
    *  const std::string& value, bool has_value);.
    */
-  using SlotOptionArgFilename = sigc::slot<bool(const Glib::ustring&, const std::string&, bool)>;
+  using SlotOptionArgFilename = sigc::slot<bool, const Glib::ustring&, const std::string&, bool>;
 
-  OptionGroup(const Glib::ustring& name, const Glib::ustring& description, const Glib::ustring& help_description = {});
+  OptionGroup(const Glib::ustring& name, const Glib::ustring& description, const Glib::ustring& help_description = Glib::ustring());
 
   /** This always takes ownership of the underlying GOptionGroup,
    * so it is only useful with C functions that return newly-allocated GOptionGroups.
@@ -77,21 +68,16 @@ public:
   explicit OptionGroup(GOptionGroup* castitem);
   _IGNORE(g_option_group_new, g_option_group_ref)
 
-  // OptionGroup can't be copied or moved. The underlying GOptionGroup contains
-  // a pointer to the wrapper, set in the call to g_option_group_new().
-  // That pointer can't be changed.
-  OptionGroup(const OptionGroup& other) = delete;
-  OptionGroup& operator=(const OptionGroup& other) = delete;
-  OptionGroup(OptionGroup&& other) = delete;
-  OptionGroup& operator=(OptionGroup&& other) = delete;
+  OptionGroup(OptionGroup&& other) noexcept;
+  OptionGroup& operator=(OptionGroup&& other) noexcept;
 
   virtual ~OptionGroup();
   _IGNORE(g_option_group_free, g_option_group_unref)
 
 
-  virtual bool on_pre_parse(OptionContext& context);
-  virtual bool on_post_parse(OptionContext& context);
-  virtual void on_error(OptionContext& context, const Error& error);
+  virtual bool on_pre_parse(OptionContext& context, OptionGroup& group);
+  virtual bool on_post_parse(OptionContext& context, OptionGroup& group);
+  virtual void on_error(OptionContext& context, OptionGroup& group);
   _IGNORE(g_option_group_set_parse_hooks, g_option_group_set_error_hook)
 
   void add_entry(const OptionEntry& entry);
@@ -180,14 +166,9 @@ public:
 
   _WRAP_METHOD(void set_translation_domain(const Glib::ustring& domain), g_option_group_set_translation_domain)
 
-  /// Provides access to the underlying C instance.
   GOptionGroup*       gobj()       { return gobject_; }
-
-  /// Provides access to the underlying C instance.
   const GOptionGroup* gobj() const { return gobject_; }
-
-  /// Provides access to the underlying C instance. The caller is responsible for unrefing it.
-  GOptionGroup*       gobj_copy() const;
+  GOptionGroup* gobj_give_ownership();
 
 protected:
 
@@ -219,10 +200,11 @@ protected:
     gpointer data, GError** error);
 
   //Map of entry names to CppOptionEntry:
-  using type_map_entries = std::map<Glib::ustring, CppOptionEntry>;
+  typedef std::map<Glib::ustring, CppOptionEntry> type_map_entries;
   type_map_entries map_entries_;
 
   GOptionGroup* gobject_;
+  bool has_ownership_; //Whether the gobject_ belongs to this C++ instance.
 #endif //DOXYGEN_SHOULD_SKIP_THIS
 
 private:
index 86272bc..9ceb1a3 100644 (file)
 
 #include <glibmm/utility.h>
 
-using CompileFlags = Glib::Regex::CompileFlags;
-using MatchFlags = Glib::Regex::MatchFlags;
-
 namespace Glib
 {
 
 Glib::RefPtr<Glib::Regex>
 Regex::create(
-  const Glib::ustring& pattern, CompileFlags compile_options, MatchFlags match_options)
+  const Glib::ustring& pattern, RegexCompileFlags compile_options, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   auto regex = g_regex_new(
@@ -46,7 +43,7 @@ Regex::escape_string(const Glib::ustring& string)
 
 bool
 Regex::match(
-  const Glib::ustring& string, Glib::MatchInfo& match_info, MatchFlags match_options)
+  const Glib::ustring& string, Glib::MatchInfo& match_info, RegexMatchFlags match_options)
 {
   GMatchInfo* ginfo = nullptr;
   bool const result = static_cast<bool>(
@@ -56,14 +53,14 @@ Regex::match(
 }
 
 bool
-Regex::match(const Glib::ustring& string, MatchFlags match_options)
+Regex::match(const Glib::ustring& string, RegexMatchFlags match_options)
 {
   return g_regex_match(gobj(), string.c_str(), (GRegexMatchFlags)(match_options), nullptr);
 }
 
 bool
 Regex::match(const Glib::ustring& string, int start_position, Glib::MatchInfo& match_info,
-  MatchFlags match_options)
+  RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   GMatchInfo* ginfo = nullptr;
@@ -80,7 +77,7 @@ Regex::match(const Glib::ustring& string, int start_position, Glib::MatchInfo& m
 
 bool
 Regex::match(const Glib::ustring& string, gssize string_len, int start_position,
-  Glib::MatchInfo& match_info, MatchFlags match_options)
+  Glib::MatchInfo& match_info, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   GMatchInfo* ginfo = nullptr;
@@ -96,7 +93,7 @@ Regex::match(const Glib::ustring& string, gssize string_len, int start_position,
 }
 
 bool
-Regex::match(const Glib::ustring& string, int start_position, MatchFlags match_options)
+Regex::match(const Glib::ustring& string, int start_position, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   bool retvalue = g_regex_match_full(gobj(), string.c_str(), -1, start_position,
@@ -109,7 +106,7 @@ Regex::match(const Glib::ustring& string, int start_position, MatchFlags match_o
 
 bool
 Regex::match(
-  const Glib::ustring& string, gssize string_len, int start_position, MatchFlags match_options)
+  const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   bool retvalue = g_regex_match_full(gobj(), string.c_str(), string_len, start_position,
@@ -122,7 +119,7 @@ Regex::match(
 
 bool
 Regex::match_all(
-  const Glib::ustring& string, Glib::MatchInfo& match_info, MatchFlags match_options)
+  const Glib::ustring& string, Glib::MatchInfo& match_info, RegexMatchFlags match_options)
 {
   GMatchInfo* ginfo = nullptr;
   bool const result = static_cast<bool>(g_regex_match_all(
@@ -132,14 +129,14 @@ Regex::match_all(
 }
 
 bool
-Regex::match_all(const Glib::ustring& string, MatchFlags match_options)
+Regex::match_all(const Glib::ustring& string, RegexMatchFlags match_options)
 {
   return g_regex_match_all(gobj(), string.c_str(), ((GRegexMatchFlags)(match_options)), nullptr);
 }
 
 bool
 Regex::match_all(const Glib::ustring& string, int start_position, Glib::MatchInfo& match_info,
-  MatchFlags match_options)
+  RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   GMatchInfo* ginfo = nullptr;
@@ -156,7 +153,7 @@ Regex::match_all(const Glib::ustring& string, int start_position, Glib::MatchInf
 
 bool
 Regex::match_all(const Glib::ustring& string, gssize string_len, int start_position,
-  Glib::MatchInfo& match_info, MatchFlags match_options)
+  Glib::MatchInfo& match_info, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   GMatchInfo* ginfo = nullptr;
@@ -172,7 +169,7 @@ Regex::match_all(const Glib::ustring& string, gssize string_len, int start_posit
 }
 
 bool
-Regex::match_all(const Glib::ustring& string, int start_position, MatchFlags match_options)
+Regex::match_all(const Glib::ustring& string, int start_position, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   bool retvalue = g_regex_match_all_full(gobj(), string.c_str(), -1, start_position,
@@ -185,7 +182,7 @@ Regex::match_all(const Glib::ustring& string, int start_position, MatchFlags mat
 
 bool
 Regex::match_all(
-  const Glib::ustring& string, gssize string_len, int start_position, MatchFlags match_options)
+  const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   bool retvalue = g_regex_match_all_full(gobj(), string.c_str(), string_len, start_position,
@@ -198,7 +195,7 @@ Regex::match_all(
 
 Glib::ustring
 Regex::replace(const Glib::ustring& string, int start_position, const Glib::ustring& replacement,
-  MatchFlags match_options)
+  RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   auto retvalue = Glib::convert_return_gchar_ptr_to_ustring(g_regex_replace(gobj(), string.c_str(),
@@ -211,7 +208,7 @@ Regex::replace(const Glib::ustring& string, int start_position, const Glib::ustr
 
 Glib::ustring
 Regex::replace_literal(const Glib::ustring& string, int start_position,
-  const Glib::ustring& replacement, MatchFlags match_options)
+  const Glib::ustring& replacement, RegexMatchFlags match_options)
 {
   GError* gerror = nullptr;
   auto retvalue =
@@ -223,12 +220,12 @@ Regex::replace_literal(const Glib::ustring& string, int start_position,
   return retvalue;
 }
 
-std::vector<Glib::ustring>
-Regex::split(const Glib::ustring& string, int start_position, MatchFlags match_options,
+Glib::StringArrayHandle
+Regex::split(const Glib::ustring& string, int start_position, RegexMatchFlags match_options,
   int max_tokens) const
 {
   GError* gerror = nullptr;
-  auto retvalue = Glib::ArrayHandler<Glib::ustring>::array_to_vector(
+  auto retvalue = Glib::StringArrayHandle(
     g_regex_split_full(const_cast<GRegex*>(gobj()), string.c_str(), -1, start_position,
       ((GRegexMatchFlags)(match_options)), max_tokens, &(gerror)),
     Glib::OWNERSHIP_DEEP);
@@ -238,50 +235,50 @@ Regex::split(const Glib::ustring& string, int start_position, MatchFlags match_o
   return retvalue;
 }
 
-MatchInfo::MatchInfo() : gobject_(nullptr), take_ownership_(false)
+MatchInfo::MatchInfo() : gobject_(nullptr), take_ownership(false)
 {
 }
 
-MatchInfo::MatchInfo(GMatchInfo* castitem, bool take_ownership)
-: gobject_(castitem), take_ownership_(take_ownership)
+MatchInfo::MatchInfo(GMatchInfo* castitem, bool take_the_ownership)
+: gobject_(castitem), take_ownership(take_the_ownership)
 {
 }
 
 MatchInfo::MatchInfo(MatchInfo&& other) noexcept : gobject_(std::move(other.gobject_)),
-                                                   take_ownership_(std::move(other.take_ownership_))
+                                                   take_ownership(std::move(other.take_ownership))
 {
   other.gobject_ = nullptr;
-  other.take_ownership_ = false;
+  other.take_ownership = false;
 }
 
 MatchInfo&
 MatchInfo::operator=(MatchInfo&& other) noexcept
 {
-  if (take_ownership_ && gobject_)
+  if (take_ownership && gobject_)
     g_match_info_free(gobject_);
 
   gobject_ = std::move(other.gobject_);
-  take_ownership_ = std::move(other.take_ownership_);
+  take_ownership = std::move(other.take_ownership);
 
   other.gobject_ = nullptr;
-  other.take_ownership_ = false;
+  other.take_ownership = false;
 
   return *this;
 }
 
 void
-MatchInfo::set_gobject(GMatchInfo* castitem, bool take_ownership)
+MatchInfo::set_gobject(GMatchInfo* castitem, bool take_the_ownership)
 {
-  if (gobject_ && this->take_ownership_)
+  if (gobject_ && this->take_ownership)
     g_match_info_free(gobject_);
 
   gobject_ = castitem;
-  this->take_ownership_ = take_ownership;
+  this->take_ownership = take_the_ownership;
 }
 
 MatchInfo::~MatchInfo()
 {
-  if (take_ownership_ && gobject_)
+  if (take_ownership && gobject_)
     g_match_info_free(gobject_);
 }
 
index 68bca08..ce85c95 100644 (file)
@@ -20,8 +20,8 @@ _DEFS(glibmm,glib)
 #include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
 #include <glibmm/error.h>
+#include <glibmm/arrayhandle.h>
 #include <glib.h>
-#include <vector>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 typedef struct _GRegex GRegex;
@@ -30,13 +30,15 @@ typedef struct _GRegex GRegex;
 namespace Glib
 {
 
+_WRAP_ENUM(RegexCompileFlags, GRegexCompileFlags, NO_GTYPE)
+_WRAP_ENUM(RegexMatchFlags, GRegexMatchFlags, NO_GTYPE)
 
 /** Exception class for Regex
  */
-_WRAP_GERROR(RegexError, GRegexError, G_REGEX_ERROR, NO_GTYPE)
+_WRAP_GERROR(RegexError, GRegexError, G_REGEX_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 
-class MatchInfo;
+class GLIBMM_API MatchInfo;
 
 /** Perl-compatible regular expressions - matches strings against regular expressions.
  *
@@ -88,19 +90,29 @@ class MatchInfo;
  * The regular expressions low level functionalities are obtained through the
  * excellent PCRE library written by Philip Hazel.
  *
+ * @note When you call a match() or a match_all() method taking a MatchInfo,
+ * use a Glib::ustring that still exists when you later call MatchInfo methods.
+ * If you call match() or match_all() with a std::string or a string literal,
+ * the method will internally use a temporary copy of the string. The copy will
+ * not exist when you call MatchInfo methods. The use of temporary string values
+ * is deprecated in all match() and match_all() methods since glibmm 2.64.
+ * @code
+ * Glib::ustring str1 = "String to search through";
+ * regex->match(str1, match_info);
+ * // ...
+ * if (match_info.matches()) // str1 must still exist here
+ * @endcode
+ *
  * @newin{2,14}
  */
-class Regex final
+class GLIBMM_API Regex final
 {
-  _CLASS_OPAQUE_REFCOUNTED(Regex, GRegex, NONE, g_regex_ref, g_regex_unref)
+  _CLASS_OPAQUE_REFCOUNTED(Regex, GRegex, NONE, g_regex_ref, g_regex_unref, GLIBMM_API)
   _IGNORE(g_regex_ref, g_regex_unref)
 public:
 
-  _WRAP_ENUM(CompileFlags, GRegexCompileFlags, NO_GTYPE)
-  _WRAP_ENUM(MatchFlags, GRegexMatchFlags, NO_GTYPE)
-
   /// @throws Glib::RegexError
-  static Glib::RefPtr<Glib::Regex> create(const Glib::ustring& pattern, CompileFlags compile_options = static_cast<CompileFlags>(0), MatchFlags match_options = static_cast<MatchFlags>(0));
+  static Glib::RefPtr<Glib::Regex> create(const Glib::ustring& pattern, RegexCompileFlags compile_options = static_cast<RegexCompileFlags>(0), RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0));
 
   _WRAP_METHOD(Glib::ustring get_pattern() const, g_regex_get_pattern)
   _WRAP_METHOD(int get_max_backref() const, g_regex_get_max_backref)
@@ -108,22 +120,22 @@ public:
   _WRAP_METHOD(bool get_has_cr_or_lf() const, g_regex_get_has_cr_or_lf)
   _WRAP_METHOD(int get_max_lookbehind() const, g_regex_get_max_lookbehind)
   _WRAP_METHOD(int get_string_number(const Glib::ustring& name) const, g_regex_get_string_number)
-  _WRAP_METHOD(CompileFlags get_compile_flags() const, g_regex_get_compile_flags)
-  _WRAP_METHOD(MatchFlags get_match_flags() const, g_regex_get_match_flags)
+  _WRAP_METHOD(RegexCompileFlags get_compile_flags() const, g_regex_get_compile_flags)
+  _WRAP_METHOD(RegexMatchFlags get_match_flags() const, g_regex_get_match_flags)
 
   static Glib::ustring escape_string(const Glib::ustring& string);
 
-  _WRAP_METHOD(static bool match_simple(const Glib::ustring& pattern, const Glib::ustring& string, CompileFlags compile_options = static_cast<CompileFlags>(0), MatchFlags match_options = static_cast<MatchFlags>(0)), g_regex_match_simple)
+  _WRAP_METHOD(static bool match_simple(const Glib::ustring& pattern, const Glib::ustring& string, RegexCompileFlags compile_options = static_cast<RegexCompileFlags>(0), RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)), g_regex_match_simple)
 
   _WRAP_METHOD_DOCS_ONLY(g_regex_match)
   bool match(
     const Glib::ustring& string,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   /// A match() method not requiring a Glib::MatchInfo.
-  bool match(const Glib::ustring& string, MatchFlags match_options = static_cast<MatchFlags>(0));
+  bool match(const Glib::ustring& string, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0));
 
   /** A match() method with a start position and a Glib::MatchInfo.
    * @throws Glib::RegexError
@@ -132,7 +144,7 @@ public:
     const Glib::ustring& string,
     int start_position,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   _WRAP_METHOD_DOCS_ONLY(g_regex_match_full, errthrow "Glib::RegexError")
@@ -141,28 +153,36 @@ public:
     gssize string_len,
     int start_position,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   /** A match() method with a start position not requiring a Glib::MatchInfo.
    * @throws Glib::RegexError
    */
-  bool match(const Glib::ustring& string, int start_position, MatchFlags match_options);
+  bool match(const Glib::ustring& string, int start_position, RegexMatchFlags match_options);
 
   /** A match() method with a string length and start position not requiring a
    * Glib::MatchInfo.
    */
-  bool match(const Glib::ustring& string, gssize string_len, int start_position, MatchFlags match_options);
+  bool match(const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options);
+
+#if defined(GLIBMM_DISABLE_DEPRECATED) || defined(DOXYGEN_SHOULD_SKIP_THIS)
+  /** Rvalue references, such as temporary values, are deprecated.
+   * This declaration is enabled if the preprocessor constant
+   * GLIBMM_DISABLE_DEPRECATED is defined.
+   */
+  bool match(Glib::ustring&& string, ...) = delete;
+#endif // GLIBMM_DISABLE_DEPRECATED || DOXYGEN_SHOULD_SKIP_THIS
 
   _WRAP_METHOD_DOCS_ONLY(g_regex_match_all)
   bool match_all(
     const Glib::ustring& string,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   /// A match_all() method not requiring a Glib::MatchInfo.
-  bool match_all(const Glib::ustring& string, MatchFlags match_options = static_cast<MatchFlags>(0));
+  bool match_all(const Glib::ustring& string, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0));
 
   /** A match_all() method with a start positon and a Glib::MatchInfo.
    * @throws Glib::RegexError
@@ -171,7 +191,7 @@ public:
     const Glib::ustring& string,
     int start_position,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   _WRAP_METHOD_DOCS_ONLY(g_regex_match_all_full, errthrow "Glib::RegexError")
@@ -180,39 +200,48 @@ public:
     gssize string_len,
     int start_position,
     Glib::MatchInfo& match_info,
-    MatchFlags match_options = static_cast<MatchFlags>(0)
+    RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)
   );
 
   /** A match_all() method with a start position not requiring a Glib::MatchInfo.
    * @throws Glib::RegexError
    */
-  bool match_all(const Glib::ustring& string, int start_position, MatchFlags match_options);
+  bool match_all(const Glib::ustring& string, int start_position, RegexMatchFlags match_options);
 
   /** A match_all() method with a start position and a string length not
    * requiring a Glib::MatchInfo.
    * @throws Glib::RegexError
    */
-  bool match_all(const Glib::ustring& string, gssize string_len, int start_position, MatchFlags match_options);
+  bool match_all(const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options);
+
+#if defined(GLIBMM_DISABLE_DEPRECATED) || defined(DOXYGEN_SHOULD_SKIP_THIS)
+  /** Rvalue references, such as temporary values, are deprecated.
+   * This declaration is enabled if the preprocessor constant
+   * GLIBMM_DISABLE_DEPRECATED is defined.
+   */
+  bool match_all(Glib::ustring&& string, ...) = delete;
+#endif // GLIBMM_DISABLE_DEPRECATED || DOXYGEN_SHOULD_SKIP_THIS
+
+#m4 _CONVERSION(`gchar**',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
 
-#m4 _CONVERSION(`gchar**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(static std::vector<Glib::ustring> split_simple(const Glib::ustring& pattern, const Glib::ustring& string, CompileFlags compile_options = static_cast<CompileFlags>(0), MatchFlags match_options = static_cast<MatchFlags>(0)), g_regex_split_simple)
-  _WRAP_METHOD(std::vector<Glib::ustring> split(const Glib::ustring& string, MatchFlags match_options = static_cast<MatchFlags>(0)), g_regex_split)
+  _WRAP_METHOD(static Glib::StringArrayHandle split_simple(const Glib::ustring& pattern, const Glib::ustring& string, RegexCompileFlags compile_options = static_cast<RegexCompileFlags>(0), RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)), g_regex_split_simple)
+  _WRAP_METHOD(Glib::StringArrayHandle split(const Glib::ustring& string, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)), g_regex_split)
 
-  _WRAP_METHOD(std::vector<Glib::ustring> split(const gchar* string, gssize string_len, int start_position, MatchFlags match_options = static_cast<MatchFlags>(0), int max_tokens = 0) const, g_regex_split_full, errthrow "Glib::RegexError")
+  _WRAP_METHOD(Glib::StringArrayHandle split(const gchar* string, gssize string_len, int start_position, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0), int max_tokens = 0) const, g_regex_split_full, errthrow "Glib::RegexError", errthrow)
 
   /// @throws Glib::RegexError
-  std::vector<Glib::ustring> split(const Glib::ustring& string, int start_position, MatchFlags match_options, int max_tokens) const;
+  Glib::StringArrayHandle split(const Glib::ustring& string, int start_position, RegexMatchFlags match_options, int max_tokens) const;
 
-  _WRAP_METHOD(Glib::ustring replace(const gchar* string, gssize string_len, int start_position, const Glib::ustring& replacement, MatchFlags match_options = static_cast<MatchFlags>(0)), g_regex_replace, errthrow "Glib::RegexError")
+  _WRAP_METHOD(Glib::ustring replace(const gchar* string, gssize string_len, int start_position, const Glib::ustring& replacement, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)), g_regex_replace, errthrow "Glib::RegexError", errthrow)
   /// @throws Glib::RegexError
-  Glib::ustring replace(const Glib::ustring& string, int start_position, const Glib::ustring& replacement, MatchFlags match_options);
+  Glib::ustring replace(const Glib::ustring& string, int start_position, const Glib::ustring& replacement, RegexMatchFlags match_options);
 
-  _WRAP_METHOD(Glib::ustring replace_literal(const gchar *string, gssize string_len, int start_position, const Glib::ustring& replacement, MatchFlags match_options = static_cast<MatchFlags>(0)), g_regex_replace_literal, errthrow "Glib::RegexError")
+  _WRAP_METHOD(Glib::ustring replace_literal(const gchar *string, gssize string_len, int start_position, const Glib::ustring& replacement, RegexMatchFlags match_options = static_cast<RegexMatchFlags>(0)), g_regex_replace_literal, errthrow "Glib::RegexError", errthrow)
   /// @throws Glib::RegexError
-  Glib::ustring replace_literal(const Glib::ustring& string, int start_position, const Glib::ustring& replacement, MatchFlags match_options);
+  Glib::ustring replace_literal(const Glib::ustring& string, int start_position, const Glib::ustring& replacement, RegexMatchFlags match_options);
 
-  _WRAP_METHOD(Glib::ustring replace_eval(const Glib::ustring& string, gssize string_len, int start_position, MatchFlags match_options, GRegexEvalCallback eval,  gpointer user_data), g_regex_replace_eval, errthrow "Glib::RegexError")
-  _WRAP_METHOD(static bool check_replacement(const Glib::ustring& replacement, gboolean* has_references), g_regex_check_replacement, errthrow "Glib::RegexError")
+  _WRAP_METHOD(Glib::ustring replace_eval(const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options, GRegexEvalCallback eval,  gpointer user_data), g_regex_replace_eval, errthrow "Glib::RegexError", errthrow)
+  _WRAP_METHOD(static bool check_replacement(const Glib::ustring& replacement, gboolean* has_references), g_regex_check_replacement, errthrow "Glib::RegexError", errthrow)
 };
 
 //TODO: Add C++ iterator like functionality for this class.
@@ -220,7 +249,7 @@ public:
  * expression match which created it.
  * @newin{2,28}
  */
-class MatchInfo
+class GLIBMM_API MatchInfo
 {
   _CLASS_GENERIC(MatchInfo, GMatchInfo)
   _IGNORE(g_match_info_ref, g_match_info_unref, g_match_info_free)
@@ -231,9 +260,10 @@ public:
 
   /** C object constructor.
    * @param castitem The C object.
-   * @param take_ownership Whether to destroy the C object with the wrapper or not.
+   * @param take_the_ownership Whether to destroy the C object with the wrapper or
+   * not.
    */
-  explicit MatchInfo(GMatchInfo* castitem, bool take_ownership = true);
+  explicit MatchInfo(GMatchInfo* castitem, bool take_the_ownership = true); //TODO: Rename to take_ownership when we can rename the member variable.
 
   MatchInfo(const MatchInfo& other) = delete;
   MatchInfo& operator=(const MatchInfo& other) = delete;
@@ -264,12 +294,12 @@ public:
   _WRAP_METHOD(Glib::ustring get_string() const, g_match_info_get_string)
   _WRAP_METHOD(bool matches() const, g_match_info_matches)
 
-  _WRAP_METHOD(bool next(), g_match_info_next, errthrow "Glib::RegexError")
+  _WRAP_METHOD(bool next(), g_match_info_next, errthrow "Glib::RegexError", errthrow)
 
   _WRAP_METHOD(int get_match_count() const, g_match_info_get_match_count)
   _WRAP_METHOD(bool is_partial_match() const, g_match_info_is_partial_match)
 
-  _WRAP_METHOD(Glib::ustring expand_references(const Glib::ustring& string_to_expand), g_match_info_expand_references, errthrow "Glib::RegexError")
+  _WRAP_METHOD(Glib::ustring expand_references(const Glib::ustring& string_to_expand), g_match_info_expand_references, errthrow "Glib::RegexError", errthrow)
 
   _WRAP_METHOD(Glib::ustring fetch(int match_num), g_match_info_fetch)
 
@@ -279,11 +309,11 @@ public:
 
   _WRAP_METHOD(bool fetch_named_pos(const Glib::ustring& name, int& start_pos, int& end_pos), g_match_info_fetch_named_pos)
 
-  _WRAP_METHOD(std::vector<Glib::ustring> fetch_all(), g_match_info_fetch_all)
+  _WRAP_METHOD(Glib::StringArrayHandle fetch_all(), g_match_info_fetch_all)
 
 protected:
   GMatchInfo* gobject_;      // The C object.
-  bool take_ownership_;      // Bool signaling ownership.
+  bool take_ownership;       // Bool signaling ownership. //TODO: Give this a _ suffix when we can break API.
 
 protected:
   // So that Glib::Regex::match() can set the C object.
index 940a9a3..901a63b 100644 (file)
@@ -21,7 +21,7 @@ namespace Glib
 
 /**** shell utility functions **********************************************/
 
-std::vector<std::string>
+Glib::ArrayHandle<std::string>
 shell_parse_argv(const std::string& command_line)
 {
   char** argv = nullptr;
@@ -33,7 +33,7 @@ shell_parse_argv(const std::string& command_line)
   if (error)
     Glib::Error::throw_exception(error);
 
-  return Glib::ArrayHandler<std::string>::array_to_vector(argv, argc, Glib::OWNERSHIP_DEEP);
+  return Glib::ArrayHandle<std::string>(argv, argc, Glib::OWNERSHIP_DEEP);
 }
 
 std::string
index 50736ea..737b6ad 100644 (file)
 
 _DEFS(glibmm,glib)
 
+#include <glibmm/arrayhandle.h>
 #include <glibmm/error.h>
 #include <glib.h>
 #include <string>
-#include <vector>
 
 namespace Glib
 {
@@ -31,7 +31,7 @@ namespace Glib
 
 /** Exception class for shell utility errors.
  */
-_WRAP_GERROR(ShellError, GShellError, G_SHELL_ERROR, NO_GTYPE)
+_WRAP_GERROR(ShellError, GShellError, G_SHELL_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 
 /** Parses a command line into an argument vector, in much the same way the
@@ -46,7 +46,8 @@ _WRAP_GERROR(ShellError, GShellError, G_SHELL_ERROR, NO_GTYPE)
  * converted to any STL compatible container type).
  * @throw Glib::ShellError
  */
-std::vector<std::string> shell_parse_argv(const std::string& command_line);
+GLIBMM_API
+Glib::ArrayHandle<std::string> shell_parse_argv(const std::string& command_line);
 
 /** Quotes a string so that the shell (/bin/sh) will interpret the quoted
  * string to mean @a unquoted_string.  If you pass a filename to the shell,
@@ -55,6 +56,7 @@ std::vector<std::string> shell_parse_argv(const std::string& command_line);
  * @param unquoted_string A literal string.
  * @return A quoted string.
  */
+GLIBMM_API
 std::string shell_quote(const std::string& unquoted_string);
 
 /** Unquotes a string as the shell (/bin/sh) would.  Only handles quotes; if
@@ -80,6 +82,7 @@ std::string shell_quote(const std::string& unquoted_string);
  * @return An unquoted string.
  * @throw Glib::ShellError
  */
+GLIBMM_API
 std::string shell_unquote(const std::string& quoted_string);
 
 /** @} group ShellUtils */
index 8475244..221c4da 100644 (file)
@@ -63,7 +63,7 @@ namespace Glib
 
 void
 spawn_async_with_pipes(const std::string& working_directory,
-  const std::vector<std::string>& argv, const std::vector<std::string>& envp,
+  const Glib::ArrayHandle<std::string>& argv, const Glib::ArrayHandle<std::string>& envp,
   SpawnFlags flags, const SlotSpawnChildSetup& child_setup, Pid* child_pid, int* standard_input,
   int* standard_output, int* standard_error)
 {
@@ -72,7 +72,7 @@ spawn_async_with_pipes(const std::string& working_directory,
   GError* gerror = nullptr;
 
   g_spawn_async_with_pipes(Glib::c_str_or_nullptr(working_directory),
-    const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(envp).data()),
+    const_cast<char**>(argv.data()), const_cast<char**>(envp.data()),
     static_cast<GSpawnFlags>(unsigned(flags)), (setup_slot) ? &child_setup_callback : nullptr,
     (setup_slot) ? &child_setup_ : nullptr, child_pid, standard_input, standard_output,
     standard_error, &gerror);
@@ -83,7 +83,7 @@ spawn_async_with_pipes(const std::string& working_directory,
 
 void
 spawn_async_with_pipes(const std::string& working_directory,
-  const std::vector<std::string>& argv, SpawnFlags flags,
+  const Glib::ArrayHandle<std::string>& argv, SpawnFlags flags,
   const SlotSpawnChildSetup& child_setup, Pid* child_pid, int* standard_input, int* standard_output,
   int* standard_error)
 {
@@ -92,7 +92,7 @@ spawn_async_with_pipes(const std::string& working_directory,
   GError* gerror = nullptr;
 
   g_spawn_async_with_pipes(Glib::c_str_or_nullptr(working_directory),
-    const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()), nullptr, static_cast<GSpawnFlags>(unsigned(flags)),
+    const_cast<char**>(argv.data()), nullptr, static_cast<GSpawnFlags>(unsigned(flags)),
     (setup_slot) ? &child_setup_callback : nullptr, (setup_slot) ? &child_setup_ : nullptr,
     child_pid, standard_input, standard_output, standard_error, &gerror);
 
@@ -101,16 +101,16 @@ spawn_async_with_pipes(const std::string& working_directory,
 }
 
 void
-spawn_async(const std::string& working_directory, const std::vector<std::string>& argv,
-  const std::vector<std::string>& envp, SpawnFlags flags,
+spawn_async(const std::string& working_directory, const Glib::ArrayHandle<std::string>& argv,
+  const Glib::ArrayHandle<std::string>& envp, SpawnFlags flags,
   const SlotSpawnChildSetup& child_setup, Pid* child_pid)
 {
   const bool setup_slot = !child_setup.empty();
   auto child_setup_ = child_setup;
   GError* gerror = nullptr;
 
-  g_spawn_async(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()),
-    const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(envp).data()), static_cast<GSpawnFlags>(unsigned(flags)),
+  g_spawn_async(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(argv.data()),
+    const_cast<char**>(envp.data()), static_cast<GSpawnFlags>(unsigned(flags)),
     (setup_slot) ? &child_setup_callback : nullptr, (setup_slot) ? &child_setup_ : nullptr,
     child_pid, &gerror);
 
@@ -119,14 +119,14 @@ spawn_async(const std::string& working_directory, const std::vector<std::string>
 }
 
 void
-spawn_async(const std::string& working_directory, const std::vector<std::string>& argv,
+spawn_async(const std::string& working_directory, const Glib::ArrayHandle<std::string>& argv,
   SpawnFlags flags, const SlotSpawnChildSetup& child_setup, Pid* child_pid)
 {
   const bool setup_slot = !child_setup.empty();
   auto child_setup_ = child_setup;
   GError* gerror = nullptr;
 
-  g_spawn_async(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()), nullptr,
+  g_spawn_async(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(argv.data()), nullptr,
     static_cast<GSpawnFlags>(unsigned(flags)), (setup_slot) ? &child_setup_callback : nullptr,
     (setup_slot) ? &child_setup_ : nullptr, child_pid, &gerror);
 
@@ -135,8 +135,8 @@ spawn_async(const std::string& working_directory, const std::vector<std::string>
 }
 
 void
-spawn_sync(const std::string& working_directory, const std::vector<std::string>& argv,
-  const std::vector<std::string>& envp, SpawnFlags flags,
+spawn_sync(const std::string& working_directory, const Glib::ArrayHandle<std::string>& argv,
+  const Glib::ArrayHandle<std::string>& envp, SpawnFlags flags,
   const SlotSpawnChildSetup& child_setup, std::string* standard_output, std::string* standard_error,
   int* exit_status)
 {
@@ -146,8 +146,8 @@ spawn_sync(const std::string& working_directory, const std::vector<std::string>&
   GError* gerror = nullptr;
   char* pch_buf_standard_output = nullptr;
   char* pch_buf_standard_error = nullptr;
-  g_spawn_sync(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()),
-    const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(envp).data()), static_cast<GSpawnFlags>(unsigned(flags)),
+  g_spawn_sync(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(argv.data()),
+    const_cast<char**>(envp.data()), static_cast<GSpawnFlags>(unsigned(flags)),
     (setup_slot) ? &child_setup_callback : nullptr, (setup_slot) ? &child_setup_ : nullptr,
     (standard_output) ? &pch_buf_standard_output : nullptr,
     (standard_error) ? &pch_buf_standard_error : nullptr, exit_status, &gerror);
@@ -162,7 +162,7 @@ spawn_sync(const std::string& working_directory, const std::vector<std::string>&
 }
 
 void
-spawn_sync(const std::string& working_directory, const std::vector<std::string>& argv,
+spawn_sync(const std::string& working_directory, const Glib::ArrayHandle<std::string>& argv,
   SpawnFlags flags, const SlotSpawnChildSetup& child_setup, std::string* standard_output,
   std::string* standard_error, int* exit_status)
 {
@@ -173,7 +173,7 @@ spawn_sync(const std::string& working_directory, const std::vector<std::string>&
   char* pch_buf_standard_error = nullptr;
   GError* gerror = nullptr;
 
-  g_spawn_sync(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(argv).data()), nullptr,
+  g_spawn_sync(Glib::c_str_or_nullptr(working_directory), const_cast<char**>(argv.data()), nullptr,
     static_cast<GSpawnFlags>(unsigned(flags)), (setup_slot) ? &child_setup_callback : nullptr,
     (setup_slot) ? &child_setup_ : nullptr, (standard_output) ? &pch_buf_standard_output : nullptr,
     (standard_error) ? &pch_buf_standard_error : nullptr, exit_status, &gerror);
index b3c171e..c40dc71 100644 (file)
 _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
+#include <glibmm/arrayhandle.h>
 #include <glibmm/error.h>
 #include <sigc++/sigc++.h>
 #include <string>
-#include <vector>
 
 namespace Glib
 {
@@ -36,12 +36,12 @@ _WRAP_ENUM(SpawnFlags, GSpawnFlags, NO_GTYPE)
 
 /** %Exception class for errors occuring when spawning processes.
  */
-_WRAP_GERROR(SpawnError, GSpawnError, G_SPAWN_ERROR, NO_GTYPE, s#^2BIG$#TOOBIG#)
+_WRAP_GERROR(SpawnError, GSpawnError, G_SPAWN_ERROR, NO_GTYPE, s#^2BIG$#TOOBIG#, decl_prefix GLIBMM_API)
 
 /** For instance,<br>
  *   void on_child_setup();
  */
-using SlotSpawnChildSetup = sigc::slot<void()>;
+using SlotSpawnChildSetup = sigc::slot<void>;
 
 /** Executes a child program asynchronously (your program will not
  * block waiting for the child to exit). The child program is
@@ -49,7 +49,7 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * The first string in @a argv is of
  * course the name of the program to execute. By default, the name of
  * the program must be a full path; the PATH shell variable
- * will only be searched if you pass the SpawnFlags::SEARCH_PATH flag.
+ * will only be searched if you pass the SPAWN_SEARCH_PATH flag.
  *
  * On Windows, note that all the string or string vector arguments to
  * this function and the other spawn*() functions are in UTF-8, the
@@ -91,7 +91,7 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * the child's environment.
  *
  * @a flags should be the bitwise OR of any flags you want to affect the
- * function's behaviour. The SpawnFlags::DO_NOT_REAP_CHILD flags means that
+ * function's behaviour. The SPAWN_DO_NOT_REAP_CHILD flags means that
  * the child will not automatically be reaped; you must use a
  * ChildWatch source to be notified about the death of the child
  * process. Eventually you must call spawn_close_pid() on the
@@ -105,19 +105,19 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * PAWN_LEAVE_DESCRIPTORS_OPEN means that the parent's open file
  * descriptors will be inherited by the child; otherwise all
  * descriptors except stdin/stdout/stderr will be closed before
- * calling exec() in the child. SpawnFlags::SEARCH_PATH
+ * calling exec() in the child. SPAWN_SEARCH_PATH
  * means that argv[0] need not be an absolute path, it
  * will be looked for in the user's PATH.
- * SpawnFlags::STDOUT_TO_DEV_NULL means that the child's standard output will
+ * SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output will
  * be discarded, instead of going to the same location as the parent's
  * standard output. If you use this flag, @a standard_output must be nullptr.
- * SpawnFlags::STDERR_TO_DEV_NULL means that the child's standard error
+ * SPAWN_STDERR_TO_DEV_NULL means that the child's standard error
  * will be discarded, instead of going to the same location as the parent's
  * standard error. If you use this flag, @a standard_error must be nullptr.
- * SpawnFlags::CHILD_INHERITS_STDIN means that the child will inherit the parent's
+ * SPAWN_CHILD_INHERITS_STDIN means that the child will inherit the parent's
  * standard input (by default, the child's standard input is attached to
  * /dev/null). If you use this flag, @a standard_input must be nullptr.
- * SpawnFlags::FILE_AND_ARGV_ZERO means that the first element of @a argv is
+ * G_SPAWN_FILE_AND_ARGV_ZERO means that the first element of @a argv is
  * the file to execute, while the remaining elements are the
  * actual argument vector to pass to the file. Normally
  * spawn_async_with_pipes() uses argv[0] as the file to execute, and
@@ -140,9 +140,9 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * If non-nullptr, @a child_pid will on Unix be filled with the child's
  * process ID. You can use the process ID to send signals to the
  * child, or to use child_watch_add() (or waitpid()) if you specified the
- * SpawnFlags::DO_NOT_REAP_CHILD flag. On Windows, @a child_pid will be
+ * SPAWN_DO_NOT_REAP_CHILD flag. On Windows, @a child_pid will be
  * filled with a handle to the child process only if you specified the
- * SpawnFlags::DO_NOT_REAP_CHILD flag. You can then access the child
+ * SPAWN_DO_NOT_REAP_CHILD flag. You can then access the child
  * process using the Win32 API, for example wait for its termination
  * with the WaitFor*() functions, or examine its
  * exit code with GetExitCodeProcess(). You should close the handle
@@ -151,19 +151,19 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * If non-nullptr, the @a standard_input, @a standard_output, @a standard_error
  * locations will be filled with file descriptors for writing to the child's
  * standard input or reading from its standard output or standard error.
- * The caller of pawn_async_with_pipes() must close these file descriptors
+ * The caller of spawn_async_with_pipes() must close these file descriptors
  * when they are no longer in use. If these parameters are nullptr, the corresponding
  * pipe won't be created.
  *
  * If @a standard_input is nullptr, the child's standard input is attached to
- * /dev/null unless SpawnFlags::CHILD_INHERITS_STDIN is set.
+ * /dev/null unless SPAWN_CHILD_INHERITS_STDIN is set.
  *
  * If @a standard_error is nullptr, the child's standard error goes to the same
- * location as the parent's standard error unless SpawnFlags::STDERR_TO_DEV_NULL
+ * location as the parent's standard error unless SPAWN_STDERR_TO_DEV_NULL
  * is set.
  *
  * If @a standard_output is nullptr, the child's standard output goes to the same
- * location as the parent's standard output unless SpawnFlags::STDOUT_TO_DEV_NULL
+ * location as the parent's standard output unless SPAWN_STDOUT_TO_DEV_NULL
  * is set.
  *
  * If @a child_pid is not nullptr and an error does not occur then the returned
@@ -191,11 +191,12 @@ using SlotSpawnChildSetup = sigc::slot<void()>;
  * to users. If an error occurs, @a child_pid, @a standard_input, @a standard_output,
  * and @a standard_error will not be filled with valid values.
  */
+GLIBMM_API
 void spawn_async_with_pipes(const std::string& working_directory,
-                            const std::vector<std::string>& argv,
-                            const std::vector<std::string>& envp,
-                            SpawnFlags flags = SpawnFlags::DEFAULT,
-                            const SlotSpawnChildSetup& child_setup = {},
+                            const Glib::ArrayHandle<std::string>& argv,
+                            const Glib::ArrayHandle<std::string>& envp,
+                            SpawnFlags flags = SPAWN_DEFAULT,
+                            const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                             Pid* child_pid = nullptr,
                             int* standard_input = nullptr,
                             int* standard_output = nullptr,
@@ -218,10 +219,11 @@ void spawn_async_with_pipes(const std::string& working_directory,
  * to users. If an error occurs, @a child_pid, @a standard_input, @a standard_output,
  * and @a standard_error will not be filled with valid values.
  */
+GLIBMM_API
 void spawn_async_with_pipes(const std::string& working_directory,
-                            const std::vector<std::string>& argv,
-                            SpawnFlags flags = SpawnFlags::DEFAULT,
-                            const SlotSpawnChildSetup& child_setup = {},
+                            const Glib::ArrayHandle<std::string>& argv,
+                            SpawnFlags flags = SPAWN_DEFAULT,
+                            const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                             Pid* child_pid = nullptr,
                             int* standard_input = nullptr,
                             int* standard_output = nullptr,
@@ -248,11 +250,12 @@ void spawn_async_with_pipes(const std::string& working_directory,
  * the message field of returned errors should be displayed
  * to users.
  */
+GLIBMM_API
 void spawn_async(const std::string& working_directory,
-                 const std::vector<std::string>& argv,
-                 const std::vector<std::string>& envp,
-                 SpawnFlags flags = SpawnFlags::DEFAULT,
-                 const SlotSpawnChildSetup& child_setup = {},
+                 const Glib::ArrayHandle<std::string>& argv,
+                 const Glib::ArrayHandle<std::string>& envp,
+                 SpawnFlags flags = SPAWN_DEFAULT,
+                 const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                  Pid* child_pid = nullptr);
 
 /** Like the main spawn_async() method, but inheriting the parent's environment.
@@ -268,22 +271,23 @@ void spawn_async(const std::string& working_directory,
  * the message field of returned errors should be displayed
  * to users.
  */
+GLIBMM_API
 void spawn_async(const std::string& working_directory,
-                 const std::vector<std::string>& argv,
-                 SpawnFlags flags = SpawnFlags::DEFAULT,
-                 const SlotSpawnChildSetup& child_setup = {},
+                 const Glib::ArrayHandle<std::string>& argv,
+                 SpawnFlags flags = SPAWN_DEFAULT,
+                 const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                  Pid* child_pid = nullptr);
 
 /** Executes a child synchronously (waits for the child to exit before returning).
  * All output from the child is stored in @a standard_output and @a standard_error,
  * if those parameters are non-nullptr. Note that you must set the
- * SpawnFlags::STDOUT_TO_DEV_NULL and SpawnFlags::STDERR_TO_DEV_NULL flags when
+ * SPAWN_STDOUT_TO_DEV_NULL and SPAWN_STDERR_TO_DEV_NULL flags when
  * passing nullptr for @a standard_output and @a standard_error.
  * If @a exit_status is non-nullptr, the exit status of the child is stored
  * there as it would be returned by waitpid(); standard UNIX macros such
  * as WIFEXITED() and WEXITSTATUS() must be used to evaluate the exit status.
  * Note that this function calls waitpid() even if @a exit_status is nullptr, and
- * does not accept the SpawnFlags::DO_NOT_REAP_CHILD flag.
+ * does not accept the SPAWN_DO_NOT_REAP_CHILD flag.
  * If an error occurs, no data is returned in @a standard_output,
  * @a standard_error, or @a exit_status.
  *
@@ -306,11 +310,12 @@ void spawn_async(const std::string& working_directory,
  * to users. If an error occurs, @a child_pid, @a standard_input, @a standard_output,
  * and @a standard_error will not be filled with valid values.
  */
+GLIBMM_API
 void spawn_sync(const std::string& working_directory,
-                const std::vector<std::string>& argv,
-                const std::vector<std::string>& envp,
-                SpawnFlags flags = SpawnFlags::DEFAULT,
-                const SlotSpawnChildSetup& child_setup = {},
+                const Glib::ArrayHandle<std::string>& argv,
+                const Glib::ArrayHandle<std::string>& envp,
+                SpawnFlags flags = SPAWN_DEFAULT,
+                const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                 std::string* standard_output = nullptr,
                 std::string* standard_error = nullptr,
                 int* exit_status = nullptr);
@@ -331,10 +336,11 @@ void spawn_sync(const std::string& working_directory,
  * to users. If an error occurs, @a child_pid, @a standard_input, @a standard_output,
  * and @a standard_error will not be filled with valid values.
  */
+GLIBMM_API
 void spawn_sync(const std::string& working_directory,
-                const std::vector<std::string>& argv,
-                SpawnFlags flags = SpawnFlags::DEFAULT,
-                const SlotSpawnChildSetup& child_setup = {},
+                const Glib::ArrayHandle<std::string>& argv,
+                SpawnFlags flags = SPAWN_DEFAULT,
+                const SlotSpawnChildSetup& child_setup = SlotSpawnChildSetup(),
                 std::string* standard_output = nullptr,
                 std::string* standard_error = nullptr,
                 int* exit_status = nullptr);
@@ -342,8 +348,8 @@ void spawn_sync(const std::string& working_directory,
 /** A simple version of spawn_async() that parses a command line with
  * shell_parse_argv() and passes it to spawn_async(). It runs a
  * command line in the background. Unlike spawn_async(), the
- * SpawnFlags::SEARCH_PATH flag is enabled, other flags are not. Note
- * that SpawnFlags::SEARCH_PATH can have security implications, so
+ * SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
+ * that SPAWN_SEARCH_PATH can have security implications, so
  * consider using spawn_async() directly if appropriate.
  *
  * The same concerns on Windows apply as for spawn_command_line_sync().
@@ -356,13 +362,14 @@ void spawn_sync(const std::string& working_directory,
  * to users.
  * @throws ShellError If the command line could not be parsed.
  */
+GLIBMM_API
 void spawn_command_line_async(const std::string& command_line);
 
 /** A simple version of spawn_sync() with little-used parameters
  * removed, taking a command line instead of an argument vector.  See
  * spawn_sync() for full details. @a command_line will be parsed by
- * shell_parse_argv(). Unlike spawn_sync(), the SpawnFlags::SEARCH_PATH flag
- * is enabled. Note that SpawnFlags::SEARCH_PATH can have security
+ * shell_parse_argv(). Unlike spawn_sync(), the SPAWN_SEARCH_PATH flag
+ * is enabled. Note that SPAWN_SEARCH_PATH can have security
  * implications, so consider using spawn_sync() directly if
  * appropriate.
  *
@@ -391,6 +398,7 @@ void spawn_command_line_async(const std::string& command_line);
  * to users.
  * @throws ShellError If the command line could not be parsed.
  */
+GLIBMM_API
 void spawn_command_line_sync(const std::string& command_line,
                              std::string* standard_output = nullptr,
                              std::string* standard_error = nullptr,
@@ -403,6 +411,7 @@ void spawn_command_line_sync(const std::string& command_line,
  *
  * @param pid The process identifier to close.
  */
+GLIBMM_API
 void spawn_close_pid(Pid pid);
 
 /** @} group Spawn */
diff --git a/glib/src/thread.ccg b/glib/src/thread.ccg
new file mode 100644 (file)
index 0000000..d6e81cf
--- /dev/null
@@ -0,0 +1,426 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/exceptionhandler.h>
+#include <glib.h>
+
+namespace
+{
+
+extern "C" {
+
+static void*
+call_thread_entry_slot(void* data)
+{
+  const auto slot = reinterpret_cast<sigc::slot_base*>(data);
+
+  try
+  {
+    // Recreate the specific slot, and drop the reference obtained by create().
+    (*static_cast<sigc::slot<void>*>(slot))();
+  }
+  catch (Glib::Thread::Exit&)
+  {
+    // Just exit from the thread.  The Thread::Exit exception
+    // is our sane C++ replacement of g_thread_exit().
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  delete slot;
+  return nullptr;
+}
+
+} // extern "C"
+
+} // anonymous namespace
+
+namespace Glib
+{
+
+// This was always meant as an internal method. It is no longer called,
+// and no longer needs to be called. We are keeping it just to avoid
+// breaking ABI, though hopefully nobody is using it anyway.
+// TODO: Remove this when we can break ABI.
+void
+thread_init_impl()
+{
+  // Make sure the exception map is initialized before creating any thread.
+  Glib::Error::register_init();
+}
+
+/**** Glib::Thread *********************************************************/
+
+// static
+Thread*
+Thread::create(const sigc::slot<void>& slot, bool /* joinable */)
+{
+  // Make a copy of slot on the heap
+  const auto slot_copy = new sigc::slot<void>(slot);
+
+  GError* error = nullptr;
+
+  const auto thread = g_thread_try_new(nullptr, &call_thread_entry_slot, slot_copy, &error);
+
+  if (error)
+  {
+    delete slot_copy;
+    // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
+    // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
+    if (error->domain == G_THREAD_ERROR)
+      throw Glib::ThreadError(error);
+    else
+      Glib::Error::throw_exception(error);
+  }
+
+  return reinterpret_cast<Thread*>(thread);
+}
+
+// static
+Thread*
+Thread::create(const sigc::slot<void>& slot, unsigned long stack_size, bool joinable, bool bound,
+  ThreadPriority priority)
+{
+  // Make a copy of slot on the heap
+  const auto slot_copy = new sigc::slot<void>(slot);
+
+  GError* error = nullptr;
+
+  const auto thread = g_thread_create_full(&call_thread_entry_slot, slot_copy, stack_size, joinable,
+    bound, (GThreadPriority)priority, &error);
+
+  if (error)
+  {
+    delete slot_copy;
+    // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
+    // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
+    if (error->domain == G_THREAD_ERROR)
+      throw Glib::ThreadError(error);
+    else
+      Glib::Error::throw_exception(error);
+  }
+
+  return reinterpret_cast<Thread*>(thread);
+}
+
+// static
+Thread*
+Thread::self()
+{
+  return reinterpret_cast<Thread*>(g_thread_self());
+}
+
+void
+Thread::join()
+{
+  g_thread_join(&gobject_);
+}
+
+bool
+Thread::joinable() const
+{
+  return true; // An appropriate result now that this is deprecated because all threads are now
+               // joinable.
+}
+
+void
+Thread::set_priority(ThreadPriority priority)
+{
+  g_thread_set_priority(&gobject_, (GThreadPriority)priority);
+}
+
+ThreadPriority
+Thread::get_priority() const
+{
+  return THREAD_PRIORITY_NORMAL; // An appropriate result now that this is deprecated because the
+                                 // priority concept has been removed.
+}
+
+void
+thread_init(GThreadFunctions* /* vtable */)
+{
+  // g_thread_init() is deprecated and now does nothing,
+  // so we do not even call it. That avoids a need to link to gthread-2.0,
+  // which contains the empty g_thread_init() implementation.
+  // g_thread_init(vtable);
+
+  Glib::thread_init_impl();
+}
+
+bool
+thread_supported()
+{
+  // MSVC++ needs the != 0 to avoid an int -> bool cast warning.
+  return (g_thread_supported() != 0);
+}
+
+// static
+void
+Thread::yield()
+{
+  g_thread_yield();
+}
+
+Thread*
+wrap(GThread* gobject)
+{
+  return reinterpret_cast<Thread*>(gobject);
+}
+
+/**** Glib::StaticMutex ****************************************************/
+
+void
+StaticMutex::lock()
+{
+  g_static_mutex_lock(&gobject_);
+}
+
+bool
+StaticMutex::trylock()
+{
+  return g_static_mutex_trylock(&gobject_);
+}
+
+void
+StaticMutex::unlock()
+{
+  g_static_mutex_unlock(&gobject_);
+}
+
+StaticMutex::operator Mutex&()
+{
+  // If GStaticMutex is implemented as struct (e.g. on Linux), its first struct
+  // member (runtime_mutex) is a GMutex pointer.  If the gthread implementation
+  // is native (i.e. the vtable pointer passed to g_thread_init() was 0), then
+  // the runtime_mutex pointer is unused, and the rest of the GStaticMutex
+  // struct resembles the mutex data.
+  //
+  // On Win32, GStaticMutex is just a typedef to struct _GMutex*.  Either way,
+  // the first sizeof(GMutex*) bytes of GStaticMutex always resemble a GMutex
+  // pointer.  The gthread implementation relies on that, and we'll also do so.
+
+  GMutex*& runtime_mutex = reinterpret_cast<GMutex*&>(gobject_);
+
+  // Fortunately, it cannot hurt if we set this to the GMutex pointer returned
+  // by g_static_mutex_get_mutex().  Either we just overwrite it with the same
+  // value, or it was unused anyway.  Doing that allows casting the pointer
+  // location to a Glib::Mutex reference (its only data member is a GMutex*).
+
+  runtime_mutex = g_static_mutex_get_mutex(&gobject_);
+
+  return reinterpret_cast<Mutex&>(runtime_mutex);
+}
+
+/**** Glib::Mutex **********************************************************/
+
+Mutex::Mutex()
+: gobject_(g_mutex_new()) // TODO: Use a statically-allocated GMutext instead, with g_mutex_init().
+{
+}
+
+Mutex::~Mutex()
+{
+  g_mutex_free(gobject_);
+}
+
+void
+Mutex::lock()
+{
+  g_mutex_lock(gobject_);
+}
+
+bool
+Mutex::trylock()
+{
+  return g_mutex_trylock(gobject_);
+}
+
+void
+Mutex::unlock()
+{
+  g_mutex_unlock(gobject_);
+}
+
+/**** Glib::StaticRecMutex *************************************************/
+
+void
+StaticRecMutex::lock()
+{
+  g_static_rec_mutex_lock(&gobject_);
+}
+
+bool
+StaticRecMutex::trylock()
+{
+  return g_static_rec_mutex_trylock(&gobject_);
+}
+
+void
+StaticRecMutex::unlock()
+{
+  g_static_rec_mutex_unlock(&gobject_);
+}
+
+void
+StaticRecMutex::lock_full(unsigned int depth)
+{
+  g_static_rec_mutex_lock_full(&gobject_, depth);
+}
+
+unsigned int
+StaticRecMutex::unlock_full()
+{
+  return g_static_rec_mutex_unlock_full(&gobject_);
+}
+
+StaticRecMutex::operator RecMutex&()
+{
+  return static_cast<RecMutex&>(*this);
+}
+
+/**** Glib::RecMutex *******************************************************/
+
+RecMutex::RecMutex()
+{
+  g_static_rec_mutex_init(&gobject_);
+}
+
+RecMutex::~RecMutex()
+{
+  g_static_rec_mutex_free(&gobject_);
+}
+
+/**** Glib::StaticRWLock ***************************************************/
+
+void
+StaticRWLock::reader_lock()
+{
+  g_static_rw_lock_reader_lock(&gobject_);
+}
+
+bool
+StaticRWLock::reader_trylock()
+{
+  return g_static_rw_lock_reader_trylock(&gobject_);
+}
+
+void
+StaticRWLock::reader_unlock()
+{
+  g_static_rw_lock_reader_unlock(&gobject_);
+}
+
+void
+StaticRWLock::writer_lock()
+{
+  g_static_rw_lock_writer_lock(&gobject_);
+}
+
+bool
+StaticRWLock::writer_trylock()
+{
+  return g_static_rw_lock_writer_trylock(&gobject_);
+}
+
+void
+StaticRWLock::writer_unlock()
+{
+  g_static_rw_lock_writer_unlock(&gobject_);
+}
+
+StaticRWLock::operator RWLock&()
+{
+  return static_cast<RWLock&>(*this);
+}
+
+/**** Glib::RWLock *********************************************************/
+
+RWLock::RWLock()
+{
+  g_static_rw_lock_init(&gobject_);
+
+  // GLib doesn't have GRWLock, only GStaticRWLock.  Force initialization
+  // of the mutex and the condition variables now, to mimic the behaviour
+  // of a (hypothetical) GRWLock.
+
+  if (g_static_mutex_get_mutex(&gobject_.mutex))
+  {
+    gobject_.read_cond = g_cond_new();
+    gobject_.write_cond = g_cond_new();
+  }
+}
+
+RWLock::~RWLock()
+{
+  g_static_rw_lock_free(&gobject_);
+}
+
+/**** Glib::Cond ***********************************************************/
+
+Cond::Cond() : gobject_(g_cond_new())
+{
+}
+
+Cond::~Cond()
+{
+  g_cond_free(gobject_);
+}
+
+void
+Cond::signal()
+{
+  g_cond_signal(gobject_);
+}
+
+void
+Cond::broadcast()
+{
+  g_cond_broadcast(gobject_);
+}
+
+void
+Cond::wait(Mutex& mutex)
+{
+  g_cond_wait(gobject_, mutex.gobj());
+}
+
+bool
+Cond::timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time)
+{
+  return g_cond_timed_wait(gobject_, mutex.gobj(), const_cast<Glib::TimeVal*>(&abs_time));
+}
+
+void*
+StaticPrivate_get_helper(GStaticPrivate* private_key)
+{
+  return g_static_private_get(private_key);
+}
+
+void
+StaticPrivate_set_helper(GStaticPrivate* private_key, gpointer data, GDestroyNotify notify)
+{
+  return g_static_private_set(private_key, data, notify);
+}
+
+GPrivate*
+GPrivate_new_helper(GDestroyNotify notify)
+{
+  return g_private_new(notify);
+}
+
+} // namespace Glib
diff --git a/glib/src/thread.hg b/glib/src/thread.hg
new file mode 100644 (file)
index 0000000..7c628b9
--- /dev/null
@@ -0,0 +1,1089 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+_DEFS(glibmm,glib)
+_CONFIGINCLUDE(glibmmconfig.h)
+
+_IS_DEPRECATED // This whole file is deprecated.
+
+#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
+//Stop the compiler warnings about using the deprecated API;
+#define GLIB_DISABLE_DEPRECATION_WARNINGS 1
+#m4 _POP()
+
+// We use GThreadFunctions in the (deprecated) API, so we must temporarily undef G_DISABLE_DEPRECATED.
+// Temporarily undef G_DISABLE_DEPRECATED, redefining it later if appropriate.
+// GLib ignores G_DISABLE_DEPRECATED since glib 2.61.2.
+#if defined(G_DISABLE_DEPRECATED) && !defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
+//Stop the deprecation ifdef guards around the API declarations:
+#undef G_DISABLE_DEPRECATED
+#define GLIBMM_G_DISABLE_DEPRECATED_UNDEFED 1
+#endif
+
+#include <glib.h>
+
+// Redefine G_DISABLE_DEPRECATED if it was defined before we temporarily undefed it:
+#if defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
+#define G_DISABLE_DEPRECATED 1
+#undef GLIBMM_G_DISABLE_DEPRECATED_UNDEFED
+#endif
+
+
+#include <glibmm/error.h>
+#include <glibmm/timeval.h>
+#include <sigc++/sigc++.h>
+
+#include <cstddef>
+
+// Necessary for glib 2.61.2 and newer.
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+/* Shadow THREAD_PRIORITY_NORMAL macro (from winbase.h).
+ */
+#if defined(THREAD_PRIORITY_NORMAL) && !defined(GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL)
+enum { GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL = THREAD_PRIORITY_NORMAL };
+#undef THREAD_PRIORITY_NORMAL
+enum { THREAD_PRIORITY_NORMAL = GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL };
+#define THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
+#define GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL 1
+#endif
+
+
+/** Initializer macro for Glib::StaticRecMutex.
+ * @relates Glib::StaticRecMutex
+ * @hideinitializer
+ *
+ * @deprecated Glib::StaticRecMutex is deprecated in favour of Glib::Threads::RecMutex, which can be used statically.
+ */
+#define GLIBMM_STATIC_REC_MUTEX_INIT { G_STATIC_REC_MUTEX_INIT }
+
+/** Initializer macro for Glib::StaticRWLock.
+ * @relates Glib::StaticRWLock
+ * @hideinitializer
+ *
+ * @deprecated Glib::StaticRWLock is deprecated in favour of Glib::Threads::RWLock, which can be used statically.
+ */
+#define GLIBMM_STATIC_RW_LOCK_INIT { G_STATIC_RW_LOCK_INIT }
+
+/** Initializer macro for Glib::StaticPrivate.
+ * @relates Glib::StaticPrivate
+ * @hideinitializer
+ *
+ * @deprecated Glib::StaticPrivate is deprecated in favour of Glib::Threads::Private, which can be used statically.
+ */
+#define GLIBMM_STATIC_PRIVATE_INIT { G_STATIC_PRIVATE_INIT }
+
+namespace Glib
+{
+
+/** @deprecated Thread priorities no longer have any effect.
+ */
+_WRAP_ENUM(ThreadPriority, GThreadPriority, NO_GTYPE)
+
+/*! @var ThreadPriority THREAD_PRIORITY_LOW
+ * A priority lower than normal.
+ */
+/*! @var ThreadPriority THREAD_PRIORITY_NORMAL
+ * The default priority.
+ */
+/*! @var ThreadPriority THREAD_PRIORITY_HIGH
+ * A priority higher than normal.
+ */
+/*! @var ThreadPriority THREAD_PRIORITY_URGENT
+ * The highest priority.
+ */
+
+/** Initializes the GLib thread system.
+ * @deprecated Calling thread_init() is no longer necessary and no longer has any effect.
+ */
+void thread_init(GThreadFunctions* vtable = nullptr);
+
+/** Returns whether the thread system is initialized.
+ * @return @c true, if the thread system is initialized.
+ * @deprecated This is no longer useful, because the thread system is always initialized.
+ */
+bool thread_supported();
+
+/**
+ * @deprecated Use Glib::Threads::NotLock instead.
+ */
+enum NotLock { NOT_LOCK };
+
+/**
+ * @deprecated Use Glib::Threads::TryLock instead.
+ */
+enum TryLock { TRY_LOCK };
+
+class GLIBMM_API Mutex;
+class GLIBMM_API RecMutex;
+class GLIBMM_API RWLock;
+
+struct GLIBMM_API StaticRecMutex;
+struct GLIBMM_API StaticRWLock;
+
+
+/** Exception class for thread-related errors.
+ * @deprecated Use Glib::Threads::ThreadError instead.
+ */
+_WRAP_GERROR(ThreadError, GThreadError, G_THREAD_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
+
+
+/** Represents a running thread.
+ * An instance of this class can only be obtained with create(), self(),
+ * or wrap(GThread*).  It's not possible to delete a Thread object.  If the
+ * thread is @em not joinable, its resources will be freed automatically
+ * when it exits.  Otherwise, if the thread @em is joinable, you must call
+ * join() to avoid a memory leak.
+ *
+ * @note g_thread_exit() is not wrapped, because that function exits a thread
+ * without any cleanup.  That's especially dangerous in C++ code, since the
+ * destructors of automatic objects won't be invoked.  Instead, you can throw
+ * a Thread::Exit exception, which will be caught by the internal thread
+ * entry function.
+ *
+ * @note You might have noticed that the thread entry slot doesn't have the
+ * usual void* return value.  If you want to return any data from your thread
+ * you can pass an additional output argument to the thread's entry slot.
+ *
+ * @deprecated Use Glib::Threads::Thread instead.
+ */
+class GLIBMM_API Thread
+{
+public:
+
+  Thread(const Thread&) = delete;
+  Thread& operator=(const Thread&) = delete;
+
+  class Exit;
+
+  //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+  /** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
+   * If @a joinable is @c true, you can wait for this thread's termination by
+   * calling join().  Otherwise the thread will just disappear, when ready.
+   *
+   * The new thread executes the function or method @a slot points to.  You can
+   * pass additional arguments using sigc::bind().  If the thread was created
+   * successfully, it is returned, otherwise a ThreadError exception is thrown.
+   *
+   * Because sigc::trackable is not thread safe, if the slot represents a
+   * non-static class method (that is, it is created by sigc::mem_fun()), the
+   * class concerned should not derive from sigc::trackable.
+   *
+   * @param slot A slot to execute in the new thread.
+   * @param joinable This parameter is now ignored because Threads are now always joinable.
+   * @return The new Thread* on success.
+   * @throw Glib::ThreadError
+   */
+  static Thread* create(const sigc::slot<void>& slot, bool joinable = true);
+
+  /** Returns the Thread* corresponding to the calling thread.
+   * @return The current thread.
+   */
+  static Thread* self();
+
+  /** Waits until the thread finishes.
+   * Waits until the thread finishes, i.e. the slot, as given to create(),
+   * returns or g_thread_exit() is called by the thread.  (Calling
+   * g_thread_exit() in a C++ program should be avoided.)  All resources of
+   * the thread including the Glib::Thread object are released.  The thread
+   * must have been created with <tt>joinable&nbsp;=&nbsp;true</tt>.
+   */
+  void join();
+
+  //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+  /** Creates a new thread with the priority @a priority. The stack gets the
+   * size @a stack_size or the default value for the current platform, if
+   * @a stack_size is <tt>0</tt>.
+   *
+   * If @a joinable is @c true, you can wait for this thread's termination by
+   * calling join().  Otherwise the thread will just disappear, when ready.
+   * If @a bound is @c true, this thread will be scheduled in the system scope,
+   * otherwise the implementation is free to do scheduling in the process
+   * scope.  The first variant is more expensive resource-wise, but generally
+   * faster.  On some systems (e.g. Linux) all threads are bound.
+   *
+   * The new thread executes the function or method @a slot points to.  You can
+   * pass additional arguments using sigc::bind().  If the thread was created
+   * successfully, it is returned.
+   *
+   * Because sigc::trackable is not thread safe, if the slot represents a
+   * non-static class method (that is, it is created by sigc::mem_fun()), the
+   * class concerned should not derive from sigc::trackable.
+   *
+   * @note It is not guaranteed, that threads with different priorities really
+   * behave accordingly.  On some systems (e.g. Linux) only root can increase
+   * priorities.  On other systems (e.g. Solaris) there doesn't seem to be
+   * different scheduling for different priorities.  All in all try to avoid
+   * being dependent on priorities.  Use <tt>Glib::THREAD_PRIORITY_NORMAL</tt>
+   * here as a default.
+   *
+   * @note Only use the extended
+   * create(const sigc::slot<void>&, unsigned long, bool, bool, ThreadPriority)
+   * function, when you really can't use the simple
+   * create(const sigc::slot<void>&, bool)
+   * instead.  The latter overload does not take @a stack_size, @a bound and
+   * @a priority as arguments, as they should only be used for cases, where
+   * it is inevitable.
+   *
+   * @param slot A slot to execute in the new thread.
+   * @param stack_size A stack size for the new thread, or <tt>0</tt>.
+   * @param joinable Should this thread be joinable?
+   * @param bound Should this thread be bound to a system thread?
+   * @param priority A priority for the thread.
+   * @return The new Thread* on success.
+   * @throw Glib::ThreadError
+   *
+   * @deprecated Use the simpler create() method instead, because all Threads
+   * are now joinable, and bounds and priority parameters now have no effect.
+   */
+  static Thread* create(const sigc::slot<void>& slot, unsigned long stack_size,
+                        bool joinable, bool bound, ThreadPriority priority);
+
+  /** Returns whether the thread is joinable.
+   * @return Whether the thread is joinable.
+   *
+   * @deprecated All threads are now joinable.
+   */
+  bool joinable() const;
+
+  /** Changes the priority of the thread to @a priority.
+   * @note It is not guaranteed, that threads with different priorities really
+   * behave accordingly.  On some systems (e.g. Linux) only @c root can
+   * increase priorities.  On other systems (e.g. Solaris) there doesn't seem
+   * to be different scheduling for different priorities.  All in all try to
+   * avoid being dependent on priorities.
+   * @param priority A new priority for the thread.
+   *
+   * @deprecated Thread priorities no longer have any effect.
+   */
+  void set_priority(ThreadPriority priority);
+
+  /** Returns the priority of the thread.
+   * @return The thread's priority.
+   *
+   * @deprecated Thread priorities no longer have any effect.
+   */
+  ThreadPriority get_priority() const;
+
+  /** Gives way to other threads waiting to be scheduled.
+   * This function is often used as a method to make busy wait less evil.  But
+   * in most cases, you will encounter, there are better methods to do that.
+   * So in general you shouldn't use this function.
+   */
+  static void yield();
+
+  GThread*       gobj()       { return &gobject_; }
+  const GThread* gobj() const { return &gobject_; }
+
+private:
+  GThread gobject_;
+
+  // Glib::Thread can neither be constructed nor deleted.
+  Thread();
+  void operator delete(void*, std::size_t);
+};
+
+/** %Exception class used to exit from a thread.
+ * @code
+ * throw Glib::Thread::Exit();
+ * @endcode
+ * Write this if you want to exit from a thread created by Thread::create().
+ * Of course you must make sure not to catch Thread::Exit by accident, i.e.
+ * when using <tt>catch(...)</tt> somewhere in your code.
+ *
+ * @deprecated Use Glib::Threads::Thread::Exit instead.
+ */
+class GLIBMM_API Thread::Exit
+{};
+
+
+//TODO: Make sure that Glib::wrap() uses Glib::Threads::wrap() instead.
+
+/** @relates Glib::Thread
+ *
+ * @deprecated Use Glib::Threads::wrap(GThread*) instead.
+ */
+Thread* wrap(GThread* gobject);
+
+struct StaticMutex;
+
+/** Like Glib::Mutex, but can be defined at compile time.
+ * Use @c GLIBMM_STATIC_MUTEX_INIT to initialize a StaticMutex:
+ * @code
+ * Glib::StaticMutex mutex = GLIBMM_STATIC_MUTEX_INIT;
+ * @endcode
+ *
+ * A StaticMutex can be used without calling Glib::thread_init(), it will
+ * silently do nothing then.  That will also work when using the implicit
+ * conversion to Mutex&, thus you can safely use Mutex::Lock with a
+ * StaticMutex.
+ *
+ * @deprecated Use Glib::Threads::Mutex instead, which can be used statically.
+ */
+struct StaticMutex
+{
+  void lock();
+  bool trylock();
+  void unlock();
+
+  operator Mutex&();
+
+  GStaticMutex* gobj() { return &gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  // Must be public to allow initialization at compile time.
+  GStaticMutex gobject_;
+#endif
+};
+
+/** Initializer macro for Glib::StaticMutex.
+ * @relates Glib::StaticMutex
+ * @hideinitializer
+ *
+ * @deprecated  Glib::StaticMutex is deprecated in favour of Glib::Threads::Mutex, which can be used statically.
+ */
+#define GLIBMM_STATIC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
+
+/** Represents a mutex (mutual exclusion).
+ * It can be used to protect data against shared access.  Try to use
+ * Mutex::Lock instead of calling lock() and unlock() directly&nbsp;--
+ * it will make your life much easier.
+ *
+ * @note Glib::Mutex is not recursive, i.e. a thread will deadlock, if it
+ * already has locked the mutex while calling lock().  Use Glib::RecMutex
+ * instead, if you need recursive mutexes.
+ *
+ * @deprecated Use Glib::Threads::Mutex instead.
+ */
+class GLIBMM_API Mutex
+{
+public:
+  class Lock;
+
+  Mutex();
+
+  Mutex(const Mutex&) = delete;
+  Mutex& operator=(const Mutex&) = delete;
+
+  ~Mutex();
+
+  /** Locks the mutex.
+   * If mutex is already locked by another thread, the current thread will
+   * block until mutex is unlocked by the other thread.
+   * @see Mutex::Lock
+   */
+  void lock();
+
+  /** Tries to lock the mutex.
+   * If the mutex is already locked by another thread, it immediately returns
+   * @c false.  Otherwise it locks the mutex and returns @c true.
+   * @return Whether the mutex could be locked.
+   * @see Mutex::Lock
+   */
+  bool trylock();
+
+  /** Unlocks the mutex.
+   * If another thread is blocked in a lock() call for this mutex, it will be
+   * woken and can lock the mutex itself.
+   * @see Mutex::Lock
+   */
+  void unlock();
+
+  GMutex* gobj() { return gobject_; }
+
+private:
+  GMutex* gobject_;
+};
+
+/** Utility class for exception-safe mutex locking.
+ * @par Usage example:
+ * @code
+ * {
+ *   Glib::Mutex::Lock lock (mutex); // calls mutex.lock()
+ *   do_something();
+ * } // the destructor calls mutex.unlock()
+ * @endcode
+ * As you can see, the compiler takes care of the unlocking.  This is not
+ * only exception safe but also much less error-prone.  You could even
+ * <tt>return</tt> while still holding the lock and it will be released
+ * properly.
+ *
+ * @deprecated Use Glib::Threads::Mutex::Lock instead.
+ */
+class GLIBMM_API Mutex::Lock
+{
+public:
+  explicit inline Lock(Mutex& mutex);
+  inline Lock(Mutex& mutex, NotLock);
+  inline Lock(Mutex& mutex, TryLock);
+  inline ~Lock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  Mutex&  mutex_;
+  bool    locked_;
+
+
+};
+
+
+/** Like Glib::RecMutex, but can be defined at compile time.
+ * Use @c GLIBMM_STATIC_REC_MUTEX_INIT to initialize a StaticRecMutex:
+ * @code
+ * Glib::StaticRecMutex mutex = GLIBMM_STATIC_REC_MUTEX_INIT;
+ * @endcode
+ * A StaticRecMutex can be used without calling Glib::thread_init(), it will
+ * silently do nothing then.  That will also work when using the implicit
+ * conversion to RecMutex&, thus you can safely use RecMutex::Lock with a
+ * StaticRecMutex.
+ *
+ * @deprecated Use Glib::Threads::RecMutex instead, which can be used statically.
+ */
+struct StaticRecMutex
+{
+  void lock();
+  bool trylock();
+  void unlock();
+
+  void lock_full(unsigned int depth);
+  unsigned int unlock_full();
+
+  operator RecMutex&();
+
+  GStaticRecMutex* gobj() { return &gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  // Must be public to allow initialization at compile time.
+  GStaticRecMutex gobject_;
+#endif
+};
+
+/**
+ *
+ * @deprecated Use Glib::Threads::RecMutex instead.
+ */
+class GLIBMM_API RecMutex : public StaticRecMutex
+{
+public:
+  class Lock;
+
+  RecMutex();
+  ~RecMutex();
+
+private:
+  // noncopyable
+  RecMutex(const RecMutex&);
+  RecMutex& operator=(const RecMutex&);
+};
+
+/** Utility class for exception-safe locking of recursive mutexes.
+ *
+ * @deprecated Use Glib::Threads::RecMutex instead.
+ */
+class GLIBMM_API RecMutex::Lock
+{
+public:
+  explicit inline Lock(RecMutex& mutex);
+  inline Lock(RecMutex& mutex, NotLock);
+  inline Lock(RecMutex& mutex, TryLock);
+
+  Lock(const RecMutex::Lock&) = delete;
+  RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
+
+  inline ~Lock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RecMutex& mutex_;
+  bool      locked_;
+};
+
+
+/** Like Glib::RWLock, but can be defined at compile time.
+ * Use @c GLIBMM_STATIC_RW_LOCK_INIT to initialize a StaticRWLock:
+ * @code
+ * Glib::StaticRWLock rw_lock = GLIBMM_STATIC_RW_LOCK_INIT;
+ * @endcode
+ * A StaticRWLock can be used without calling Glib::thread_init(), it will
+ * silently do nothing then.  That will also work when using the implicit
+ * conversion to RWLock&, thus you can safely use RWLock::ReaderLock and
+ * RWLock::WriterLock with a StaticRWLock.
+ *
+ * @deprecated Use Glib::Threads::RWLock instead, which can be used statically.
+ */
+struct StaticRWLock
+{
+  void reader_lock();
+  bool reader_trylock();
+  void reader_unlock();
+
+  void writer_lock();
+  bool writer_trylock();
+  void writer_unlock();
+
+  operator RWLock&();
+
+  GStaticRWLock* gobj() { return &gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  // Must be public to allow initialization at compile time.
+  GStaticRWLock gobject_;
+#endif
+};
+
+/**
+ *
+ * @deprecated Use Glib::Threads::RWLock instead.
+ */
+class GLIBMM_API RWLock : public StaticRWLock
+{
+public:
+  class ReaderLock;
+  class WriterLock;
+
+  RWLock();
+
+  RWLock(const RWLock&) = delete;
+  RWLock& operator=(const RWLock&) = delete;
+
+  ~RWLock();
+};
+
+/** Utility class for exception-safe locking of read/write locks.
+ *
+ * @deprecated Use Glib::Threads::RWLock::ReaderLock instead.
+ */
+class GLIBMM_API RWLock::ReaderLock
+{
+public:
+  explicit inline ReaderLock(RWLock& rwlock);
+  inline ReaderLock(RWLock& rwlock, NotLock);
+  inline ReaderLock(RWLock& rwlock, TryLock);
+
+  ReaderLock(const RWLock::ReaderLock&) = delete;
+  RWLock::ReaderLock& operator=(const RWLock::ReaderLock&) = delete;
+
+  inline ~ReaderLock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RWLock& rwlock_;
+  bool    locked_;
+};
+
+/** Utility class for exception-safe locking of read/write locks.
+ *
+ * @deprecated Use Glib::Threads::RWLock::WriterLock instead.
+ */
+class GLIBMM_API RWLock::WriterLock
+{
+public:
+  explicit inline WriterLock(RWLock& rwlock);
+  inline WriterLock(RWLock& rwlock, NotLock);
+  inline WriterLock(RWLock& rwlock, TryLock);
+
+  WriterLock(const RWLock::WriterLock&) = delete;
+  RWLock::WriterLock& operator=(const RWLock::WriterLock&) = delete;
+
+  inline ~WriterLock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RWLock& rwlock_;
+  bool    locked_;
+};
+
+/** An opaque data structure to represent a condition.
+ * A @a Cond is an object that threads can block on, if they find a certain
+ * condition to be false. If other threads change the state of this condition
+ * they can signal the @a Cond, such that the waiting thread is woken up.
+ * @par Usage example:
+ * @code
+ * Glib::Cond  data_cond;
+ * Glib::Mutex data_mutex;
+ * void* current_data = nullptr;
+ *
+ * void push_data(void* data)
+ * {
+ *   Glib::Mutex::Lock lock (data_mutex);
+ *
+ *   current_data = data;
+ *   data_cond.signal();
+ * }
+ *
+ * void* pop_data()
+ * {
+ *   Glib::Mutex::Lock lock (data_mutex);
+ *
+ *   while (!current_data)
+ *     data_cond.wait(data_mutex);
+ *
+ *   void *const data = current_data;
+ *   current_data = nullptr;
+ *
+ *   return data;
+ * }
+ * @endcode
+ *
+ * @deprecated Use Glib::Threads::Cond instead.
+ */
+class GLIBMM_API Cond
+{
+public:
+  Cond();
+
+  Cond(const Cond&) = delete;
+  Cond& operator=(const Cond&) = delete;
+
+  ~Cond();
+
+  /** If threads are waiting for this @a Cond, exactly one of them is woken up.
+   * It is good practice to hold the same lock as the waiting thread, while calling
+   * this method, though not required.
+   *
+   */
+  void signal();
+
+  /** If threads are waiting for this @a Cond, all of them are woken up.
+   * It is good practice to hold the same lock as the waiting thread, while calling
+   * this method, though not required.
+   */
+  void broadcast();
+
+  /** Waits until this thread is woken up on this @a Cond.
+   * The mutex is unlocked before falling asleep and locked again before resuming.
+   *
+   * @param mutex a @a Mutex that is currently locked.
+   *
+   * @note It is important to use the @a wait() and @a timed_wait() methods
+   * only inside a loop, which checks for the condition to be true as it is not
+   * guaranteed that the waiting thread will find it fulfilled, even if the signaling
+   * thread left the condition in that state. This is because another thread can have
+   * altered the condition, before the waiting thread got the chance to be woken up,
+   * even if the condition itself is protected by a @a Mutex.
+   */
+  void wait(Mutex& mutex);
+
+  /** Waits until this thread is woken up on this @a Cond, but not longer than until the time, that is specified by @a abs_time.
+   * The mutex is unlocked before falling asleep and locked again before resuming.
+   *
+   * @param mutex a @a Mutex that is currently locked.
+   * @param abs_time a max time to wait.
+   *
+   * @note It is important to use the @a wait() and @a timed_wait() methods
+   * only inside a loop, which checks for the condition to be true as it is not
+   * guaranteed that the waiting thread will find it fulfilled, even if the signaling
+   * thread left the condition in that state. This is because another thread can have
+   * altered the condition, before the waiting thread got the chance to be woken up,
+   * even if the condition itself is protected by a @a Mutex.
+   */
+  bool timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time);
+
+  GCond* gobj() { return gobject_; }
+
+private:
+  GCond* gobject_;
+};
+
+
+/** Thread-local data pointer.
+ *
+ * @deprecated Use Glib::Threads::Private instead, which can be used statically.
+ */
+template <class T>
+struct StaticPrivate
+{
+  using DestroyNotifyFunc =  void (*) (void*);
+
+  static void delete_ptr(void* data);
+
+  inline T* get();
+  inline void set(T* data, DestroyNotifyFunc notify_func = &StaticPrivate<T>::delete_ptr);
+
+  GStaticPrivate* gobj() { return &gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  // Must be public to allow initialization at compile time.
+  GStaticPrivate gobject_;
+#endif
+};
+
+/** Thread-local data pointer.
+ *
+ * @deprecated Use Glib::Threads::Private instead.
+ */
+template <class T>
+class Private
+{
+public:
+
+  Private(const Private<T>&) = delete;
+  Private<T>& operator=(const Private<T>&) = delete;
+
+  using DestructorFunc = void (*) (void*);
+
+  static void delete_ptr(void* data);
+
+  explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
+  inline T* get();
+  inline void set(T* data);
+
+  GPrivate* gobj() { return gobject_; }
+
+private:
+  GPrivate* gobject_;
+};
+
+/** @} group Threads */
+
+/*! A glibmm thread example.
+ * @example thread/thread.cc
+ */
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/***************************************************************************/
+/*  inline implementation                                                  */
+/***************************************************************************/
+
+// internal
+/** @deprecated This was always for internal glibmm use and is now unecessary even inside glibmm.
+ */
+void thread_init_impl();
+
+/**** Glib::Mutex::Lock ****************************************************/
+
+inline
+Mutex::Lock::Lock(Mutex& mutex)
+:
+  mutex_  (mutex),
+  locked_ (true)
+{
+  mutex_.lock();
+}
+
+inline
+Mutex::Lock::Lock(Mutex& mutex, NotLock)
+:
+  mutex_  (mutex),
+  locked_ (false)
+{}
+
+inline
+Mutex::Lock::Lock(Mutex& mutex, TryLock)
+:
+  mutex_  (mutex),
+  locked_ (mutex.trylock())
+{}
+
+inline
+Mutex::Lock::~Lock()
+{
+  if(locked_)
+    mutex_.unlock();
+}
+
+inline
+void Mutex::Lock::acquire()
+{
+  mutex_.lock();
+  locked_ = true;
+}
+
+inline
+bool Mutex::Lock::try_acquire()
+{
+  locked_ = mutex_.trylock();
+  return locked_;
+}
+
+inline
+void Mutex::Lock::release()
+{
+  mutex_.unlock();
+  locked_ = false;
+}
+
+inline
+bool Mutex::Lock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::RecMutex::Lock *************************************************/
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex)
+:
+  mutex_  (mutex),
+  locked_ (true)
+{
+  mutex_.lock();
+}
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
+:
+  mutex_  (mutex),
+  locked_ (false)
+{}
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
+:
+  mutex_  (mutex),
+  locked_ (mutex.trylock())
+{}
+
+inline
+RecMutex::Lock::~Lock()
+{
+  if(locked_)
+    mutex_.unlock();
+}
+
+inline
+void RecMutex::Lock::acquire()
+{
+  mutex_.lock();
+  locked_ = true;
+}
+
+inline
+bool RecMutex::Lock::try_acquire()
+{
+  locked_ = mutex_.trylock();
+  return locked_;
+}
+
+inline
+void RecMutex::Lock::release()
+{
+  mutex_.unlock();
+  locked_ = false;
+}
+
+inline
+bool RecMutex::Lock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::RWLock::ReaderLock *********************************************/
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
+:
+  rwlock_ (rwlock),
+  locked_ (true)
+{
+  rwlock_.reader_lock();
+}
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
+:
+  rwlock_ (rwlock),
+  locked_ (false)
+{}
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
+:
+  rwlock_ (rwlock),
+  locked_ (rwlock.reader_trylock())
+{}
+
+inline
+RWLock::ReaderLock::~ReaderLock()
+{
+  if(locked_)
+    rwlock_.reader_unlock();
+}
+
+inline
+void RWLock::ReaderLock::acquire()
+{
+  rwlock_.reader_lock();
+  locked_ = true;
+}
+
+inline
+bool RWLock::ReaderLock::try_acquire()
+{
+  locked_ = rwlock_.reader_trylock();
+  return locked_;
+}
+
+inline
+void RWLock::ReaderLock::release()
+{
+  rwlock_.reader_unlock();
+  locked_ = false;
+}
+
+inline
+bool RWLock::ReaderLock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::RWLock::WriterLock *********************************************/
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock)
+:
+  rwlock_ (rwlock),
+  locked_ (true)
+{
+  rwlock_.writer_lock();
+}
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
+:
+  rwlock_ (rwlock),
+  locked_ (false)
+{}
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
+:
+  rwlock_ (rwlock),
+  locked_ (rwlock.writer_trylock())
+{}
+
+inline
+RWLock::WriterLock::~WriterLock()
+{
+  if(locked_)
+    rwlock_.writer_unlock();
+}
+
+inline
+void RWLock::WriterLock::acquire()
+{
+  rwlock_.writer_lock();
+  locked_ = true;
+}
+
+inline
+bool RWLock::WriterLock::try_acquire()
+{
+  locked_ = rwlock_.writer_trylock();
+  return locked_;
+}
+
+inline
+void RWLock::WriterLock::release()
+{
+  rwlock_.writer_unlock();
+  locked_ = false;
+}
+
+inline
+bool RWLock::WriterLock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::StaticPrivate **************************************************/
+
+// static
+template <class T>
+void StaticPrivate<T>::delete_ptr(void* data)
+{
+  delete static_cast<T*>(data);
+}
+
+/** This is only for use by glibmm itself.
+ */
+void* StaticPrivate_get_helper(GStaticPrivate *private_key);
+
+template <class T> inline
+T* StaticPrivate<T>::get()
+{
+  return static_cast<T*>(StaticPrivate_get_helper(&gobject_));
+}
+
+/** This is only for use by glibmm itself.
+ */
+void StaticPrivate_set_helper(GStaticPrivate *private_key, gpointer data, GDestroyNotify notify);
+
+template <class T> inline
+void StaticPrivate<T>::set(T* data, typename StaticPrivate<T>::DestroyNotifyFunc notify_func)
+{
+  StaticPrivate_set_helper(&gobject_, data, notify_func);
+}
+
+
+/**** Glib::Private ********************************************************/
+
+// static
+template <class T>
+void Private<T>::delete_ptr(void* data)
+{
+  delete static_cast<T*>(data);
+}
+
+/** This is only for use by glibmm itself.
+ */
+GPrivate* GPrivate_new_helper(GDestroyNotify notify);
+
+template <class T> inline
+Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
+:
+  gobject_ (GPrivate_new_helper(destructor_func))
+{}
+
+template <class T> inline
+T* Private<T>::get()
+{
+  return static_cast<T*>(g_private_get(gobject_));
+}
+
+template <class T> inline
+void Private<T>::set(T* data)
+{
+  g_private_set(gobject_, data);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+G_GNUC_END_IGNORE_DEPRECATIONS
diff --git a/glib/src/threads.ccg b/glib/src/threads.ccg
new file mode 100644 (file)
index 0000000..a478433
--- /dev/null
@@ -0,0 +1,301 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/exceptionhandler.h>
+#include <glib.h>
+
+/* Why reinterpret_cast<Thread*>(gobject) is needed:
+ *
+ * A Thread instance is in fact always a GThread instance.
+ * Unfortunately, GThread cannot be a member of Thread,
+ * because it is an opaque struct. Also, the C interface does not provide
+ * any hooks to install a destroy notification handler, thus we cannot
+ * wrap it dynamically either.
+ *
+ * The cast works because Thread does not have any member data, and
+ * it is impossible to derive from it. This is ensured by not implementing
+ * the (private) default constructor.
+ * This trick is used also in classes declared as _CLASS_OPAQUE_REFCOUNTED.
+ */
+
+namespace
+{
+
+extern "C" {
+
+static void*
+call_thread_entry_slot(void* data)
+{
+  const auto slot = reinterpret_cast<sigc::slot_base*>(data);
+
+  try
+  {
+    // Recreate the specific slot.
+    (*static_cast<sigc::slot<void>*>(slot))();
+  }
+  catch (Glib::Threads::Thread::Exit&)
+  {
+    // Just exit from the thread.  The Threads::Thread::Exit exception
+    // is our sane C++ replacement of g_thread_exit().
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  delete slot;
+  return nullptr;
+}
+
+} // extern "C"
+
+} // anonymous namespace
+
+namespace Glib
+{
+
+namespace Threads
+{
+
+/**** Glib::Threads::Thread ************************************************/
+
+// static
+Thread*
+Thread::create(const sigc::slot<void>& slot, const std::string& name)
+{
+  // Make a copy of slot on the heap.
+  const auto slot_copy = new sigc::slot<void>(slot);
+
+  GError* error = nullptr;
+  auto thread = g_thread_try_new(
+    name.empty() ? nullptr : name.c_str(), &call_thread_entry_slot, slot_copy, &error);
+
+  if (error)
+  {
+    delete slot_copy;
+    Glib::Error::throw_exception(error);
+  }
+  if (!thread)
+  {
+    delete slot_copy;
+  }
+  return reinterpret_cast<Thread*>(thread);
+}
+
+// static
+Thread*
+Thread::create(const sigc::slot<void>& slot)
+{
+  return create(slot, std::string());
+}
+
+// static
+Thread*
+Thread::self()
+{
+  return reinterpret_cast<Thread*>(g_thread_self());
+}
+
+void
+Thread::join()
+{
+  g_thread_join(reinterpret_cast<GThread*>(this));
+}
+
+// static
+void
+Thread::yield()
+{
+  g_thread_yield();
+}
+
+GThread*
+Thread::gobj()
+{
+  return reinterpret_cast<GThread*>(this);
+}
+
+const GThread*
+Thread::gobj() const
+{
+  return reinterpret_cast<const GThread*>(this);
+}
+
+Thread*
+wrap(GThread* gobject)
+{
+  return reinterpret_cast<Thread*>(gobject);
+}
+
+/**** Glib::Threads::Mutex *************************************************/
+
+Mutex::Mutex()
+{
+  g_mutex_init(&gobject_);
+}
+
+Mutex::~Mutex()
+{
+  g_mutex_clear(&gobject_);
+}
+
+void
+Mutex::lock()
+{
+  g_mutex_lock(&gobject_);
+}
+
+bool
+Mutex::trylock()
+{
+  return g_mutex_trylock(&gobject_);
+}
+
+void
+Mutex::unlock()
+{
+  g_mutex_unlock(&gobject_);
+}
+
+Mutex*
+wrap(GMutex* gobject)
+{
+  return reinterpret_cast<Mutex*>(gobject);
+}
+
+/**** Glib::Threads::RecMutex **********************************************/
+
+RecMutex::RecMutex()
+{
+  g_rec_mutex_init(&gobject_);
+}
+
+RecMutex::~RecMutex()
+{
+  g_rec_mutex_clear(&gobject_);
+}
+
+void
+RecMutex::lock()
+{
+  g_rec_mutex_lock(&gobject_);
+}
+
+bool
+RecMutex::trylock()
+{
+  return g_rec_mutex_trylock(&gobject_);
+}
+
+void
+RecMutex::unlock()
+{
+  g_rec_mutex_unlock(&gobject_);
+}
+
+RecMutex*
+wrap(GRecMutex* gobject)
+{
+  return reinterpret_cast<RecMutex*>(gobject);
+}
+
+/**** Glib::Threads::RWLock ************************************************/
+
+void
+RWLock::reader_lock()
+{
+  g_rw_lock_reader_lock(&gobject_);
+}
+
+bool
+RWLock::reader_trylock()
+{
+  return g_rw_lock_reader_trylock(&gobject_);
+}
+
+void
+RWLock::reader_unlock()
+{
+  g_rw_lock_reader_unlock(&gobject_);
+}
+
+void
+RWLock::writer_lock()
+{
+  g_rw_lock_writer_lock(&gobject_);
+}
+
+bool
+RWLock::writer_trylock()
+{
+  return g_rw_lock_writer_trylock(&gobject_);
+}
+
+void
+RWLock::writer_unlock()
+{
+  g_rw_lock_writer_unlock(&gobject_);
+}
+
+RWLock::RWLock()
+{
+  g_rw_lock_init(&gobject_);
+}
+
+RWLock::~RWLock()
+{
+  g_rw_lock_clear(&gobject_);
+}
+
+/**** Glib::Threads::Cond **************************************************/
+
+Cond::Cond()
+{
+  g_cond_init(&gobject_);
+}
+
+Cond::~Cond()
+{
+  g_cond_clear(&gobject_);
+}
+
+void
+Cond::signal()
+{
+  g_cond_signal(&gobject_);
+}
+
+void
+Cond::broadcast()
+{
+  g_cond_broadcast(&gobject_);
+}
+
+void
+Cond::wait(Mutex& mutex)
+{
+  g_cond_wait(&gobject_, mutex.gobj());
+}
+
+bool
+Cond::wait_until(Mutex& mutex, gint64 end_time)
+{
+  return g_cond_wait_until(&gobject_, mutex.gobj(), end_time);
+}
+
+} // namespace Threads
+
+} // namespace Glib
diff --git a/glib/src/threads.hg b/glib/src/threads.hg
new file mode 100644 (file)
index 0000000..99ecbb3
--- /dev/null
@@ -0,0 +1,931 @@
+/* Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+_DEFS(glibmm,glib)
+_CONFIGINCLUDE(glibmmconfig.h)
+
+_IS_DEPRECATED // This whole file is deprecated.
+
+#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
+// Don't let glibmm.h include thread.h. Pretend that it's already included.
+// glib.h can then be included with G_DISABLE_DEPRECATED defined, and
+// the compiler can react if deprecated glib functions are used.
+#define _GLIBMM_THREAD_H
+#m4 _POP()
+
+#include <glib.h>
+#include <glibmm/error.h>
+#include <sigc++/sigc++.h>
+#include <string>
+#include <cstddef>
+
+namespace Glib
+{
+
+/**
+ * @deprecated The entire Glib::Threads API is deprecated in favor of the
+ * standard C++ concurrency API in C++11 and C++14.
+ */
+namespace Threads
+{
+//The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the Threads sub-namespace
+_GMMPROC_EXTRA_NAMESPACE(Threads)
+
+/** @defgroup Threads Threads
+ * %Thread abstraction; including threads, different mutexes,
+ * conditions and thread private data.
+ *
+ * @deprecated The entire Glib::Threads API is deprecated in favor of the
+ * standard C++ concurrency API in C++11 and C++14.
+ * @{
+ */
+
+/// @deprecated Please use std::lock_guard or std::unique_lock instead.
+enum NotLock { NOT_LOCK };
+
+/// @deprecated Please use std::lock_guard or std::unique_lock instead.
+enum TryLock { TRY_LOCK };
+
+class GLIBMM_API Mutex;
+class GLIBMM_API RecMutex;
+class GLIBMM_API RWLock;
+
+/** %Exception class for thread-related errors.
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead.
+ */
+_WRAP_GERROR(ThreadError, GThreadError, G_THREAD_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
+
+
+/** Represents a running thread.
+ * An instance of this class can only be obtained with create(), self(),
+ * or wrap(GThread*).  It's not possible to delete a Thread object.
+ * You must call join() to avoid a memory leak.
+ *
+ * @note g_thread_exit() is not wrapped, because that function exits a thread
+ * without any cleanup.  That's especially dangerous in C++ code, since the
+ * destructors of automatic objects won't be invoked.  Instead, you can throw
+ * a Threads::Thread::Exit exception, which will be caught by the internal thread
+ * entry function.
+ *
+ * @note The thread entry slot doesn't have the void* return value that a
+ * GThreadFunc has.  If you want to return any data from your thread,
+ * you can pass an additional output argument to the thread's entry slot.
+ *
+ * @deprecated Please use std::thread instead.
+ */
+class GLIBMM_API Thread
+{
+public:
+
+  Thread(const Thread&) = delete;
+  Thread& operator=(const Thread&) = delete;
+
+  class Exit;
+
+  //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
+  // TODO: At the next ABI break, consider changing const sigc::slot<void>& slot
+  // to const std::function<void()>& func, if it can be assumed that all supported
+  // compilers understand the C++11 template class std::function<>.
+  /** Creates a new thread.
+   * You can wait for this thread's termination by calling join().
+   *
+   * The new thread executes the function or method @a slot points to.  You can
+   * pass additional arguments using sigc::bind().  If the thread was created
+   * successfully, it is returned, otherwise a Threads::ThreadError exception is thrown.
+   *
+   * Because sigc::trackable is not thread-safe, if the slot represents a
+   * non-static class method and is created by sigc::mem_fun(), the class concerned
+   * should not derive from sigc::trackable. You can use, say, boost::bind() or,
+   * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
+   *
+   * @param slot A slot to execute in the new thread.
+   * @return The new Thread* on success.
+   * @throw Glib::Threads::ThreadError
+   */
+  static Thread* create(const sigc::slot<void>& slot);
+
+  // TODO: At next ABI break, remove the single parameter create
+  //       method and default name to std::string()
+
+  /** Creates a new named thread.
+   * You can wait for this thread's termination by calling join().
+   *
+   * The new thread executes the function or method @a slot points to.  You can
+   * pass additional arguments using sigc::bind().  If the thread was created
+   * successfully, it is returned, otherwise a Threads::ThreadError exception is thrown.
+   *
+   * Because sigc::trackable is not thread-safe, if the slot represents a
+   * non-static class method and is created by sigc::mem_fun(), the class concerned
+   * should not derive from sigc::trackable. You can use, say, boost::bind() or,
+   * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
+   *
+   * The @a name can be useful for discriminating threads in a debugger.
+   * It is not used for other purposes and does not have to be unique.
+   * Some systems restrict the length of @a name to 16 bytes.
+   *
+   * @param slot A slot to execute in the new thread.
+   * @param name A name for the new thread.
+   * @return The new Thread* on success.
+   * @throw Glib::Threads::ThreadError
+   *
+   * @newin{2,36}
+   */
+  static Thread* create(const sigc::slot<void>& slot, const std::string& name);
+
+  /** Returns the Thread* corresponding to the calling thread.
+   * @return The current thread.
+   */
+  static Thread* self();
+
+  /** Waits until the thread finishes.
+   * Waits until the thread finishes, i.e. the slot, as given to create(),
+   * returns or g_thread_exit() is called by the thread.  (Calling
+   * g_thread_exit() in a C++ program should be avoided.)  All resources of
+   * the thread including the Glib::Threads::Thread object are released.
+   */
+  void join();
+
+  /** Gives way to other threads waiting to be scheduled.
+   * This function is often used as a method to make busy wait less evil.  But
+   * in most cases, you will encounter, there are better methods to do that.
+   * So in general you shouldn't use this function.
+   */
+  static void yield();
+
+  GThread*       gobj();
+  const GThread* gobj() const;
+
+private:
+  // Glib::Thread can neither be constructed nor deleted.
+  Thread();
+  void operator delete(void*, std::size_t);
+};
+
+/** %Exception class used to exit from a thread.
+ * @code
+ * throw Glib::Threads::Thread::Exit();
+ * @endcode
+ * Write this if you want to exit from a thread created by Threads::Thread::create().
+ * Of course you must make sure not to catch Threads::Thread::Exit by accident, i.e.
+ * when using <tt>catch(...)</tt> somewhere in your code.
+ *
+ * @deprecated Please use std::thread instead.
+ */
+class GLIBMM_API Thread::Exit
+{};
+
+/** A C++ wrapper for the C object.
+ *
+ * @param gobject The C instance.
+ * @return The C++ wrapper.
+ *
+ * @relates Glib::Threads::Thread
+ *
+ * @deprecated Please use std::thread instead.
+ */
+Thread* wrap(GThread* gobject);
+
+/** Represents a mutex (mutual exclusion).
+ * It can be used to protect data against shared access.  Try to use
+ * Mutex::Lock instead of calling lock() and unlock() directly&nbsp;--
+ * it will make your life much easier.
+ *
+ * @note Glib::Threads::Mutex is not recursive, i.e. a thread will deadlock, if it
+ * already has locked the mutex while calling lock().  Use Glib::Threads::RecMutex
+ * instead, if you need recursive mutexes.
+ *
+ * @deprecated Please use std::mutex instead.
+ */
+class GLIBMM_API Mutex
+{
+public:
+  class Lock;
+
+  Mutex();
+
+  Mutex(const Mutex&) = delete;
+  Mutex& operator=(const Mutex&) = delete;
+
+  ~Mutex();
+
+  /** Locks the mutex.
+   * If mutex is already locked by another thread, the current thread will
+   * block until mutex is unlocked by the other thread.
+   * @see Mutex::Lock
+   */
+  void lock();
+
+  /** Tries to lock the mutex.
+   * If the mutex is already locked by another thread, it immediately returns
+   * @c false.  Otherwise it locks the mutex and returns @c true.
+   * @return Whether the mutex could be locked.
+   * @see Mutex::Lock
+   */
+  bool trylock();
+
+  /** Unlocks the mutex.
+   * If another thread is blocked in a lock() call for this mutex, it will be
+   * woken and can lock the mutex itself.
+   * @see Mutex::Lock
+   */
+  void unlock();
+
+  GMutex* gobj() { return &gobject_; }
+
+private:
+  GMutex gobject_;
+};
+
+/** Utility class for exception-safe mutex locking.
+ * @par Usage example:
+ * @code
+ * {
+ *   Glib::Threads::Mutex::Lock lock(mutex); // calls mutex.lock()
+ *   do_something();
+ * } // the destructor calls mutex.unlock()
+ * @endcode
+ * As you can see, the compiler takes care of the unlocking.  This is not
+ * only exception-safe but also much less error-prone.  You could even
+ * <tt>return</tt> while still holding the lock and it will be released
+ * properly.
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead.
+ */
+class GLIBMM_API Mutex::Lock
+{
+public:
+  explicit inline Lock(Mutex& mutex);
+  inline Lock(Mutex& mutex, NotLock);
+  inline Lock(Mutex& mutex, TryLock);
+
+  Lock(const Mutex::Lock&) = delete;
+  Mutex::Lock& operator=(const Mutex::Lock&) = delete;
+
+  inline ~Lock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  Mutex&  mutex_;
+  bool    locked_;
+};
+
+/** A C++ wrapper for the C object.
+ * Do not use operator delete on the returned pointer. If the caller owns the
+ * GMutex object, the caller must destroy it in the same way as if this function
+ * had not been called.
+ *
+ * @param gobject The C instance.
+ * @result The GMutex* cast to a Glib::Threads::Mutex*.
+ *
+ * @relates Glib::Threads::Mutex
+ */
+Mutex* wrap(GMutex* gobject);
+
+/** This represents a recursive mutex.
+ * It is similar to a Mutex with the difference
+ * that it is possible to lock a RecMutex multiple times in the same
+ * thread without deadlock. When doing so, care has to be taken to
+ * unlock the recursive mutex as often as it has been locked.
+ *
+ * @deprecated Please use std::recursive_mutex instead.
+ */
+class GLIBMM_API RecMutex
+{
+public:
+  class Lock;
+
+  RecMutex();
+
+  RecMutex(const RecMutex&) = delete;
+  RecMutex& operator=(const RecMutex&) = delete;
+
+  ~RecMutex();
+
+  void lock();
+  bool trylock();
+  void unlock();
+
+  GRecMutex* gobj() { return &gobject_; }
+
+private:
+  GRecMutex gobject_;
+};
+
+/** Utility class for exception-safe locking of recursive mutexes.
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead.
+ */
+class GLIBMM_API RecMutex::Lock
+{
+public:
+  explicit inline Lock(RecMutex& mutex);
+  inline Lock(RecMutex& mutex, NotLock);
+  inline Lock(RecMutex& mutex, TryLock);
+
+  Lock(const RecMutex::Lock&) = delete;
+  RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
+
+  inline ~Lock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RecMutex& mutex_;
+  bool      locked_;
+};
+
+/** A C++ wrapper for the C object.
+ * Do not use operator delete on the returned pointer. If the caller owns the
+ * GRecMutex object, the caller must destroy it in the same way as if this function
+ * had not been called.
+ *
+ * @param gobject The C instance.
+ * @result The GRecMutex* cast to a Glib::Threads::RecMutex*.
+ *
+ * @relates Glib::Threads::RecMutex
+ */
+RecMutex* wrap(GRecMutex* gobject);
+
+/** This represents a reader-writer lock.
+ * It is similar to a Mutex in that it allows
+ * multiple threads to coordinate access to a shared resource.
+ *
+ * The difference to a mutex is that a reader-writer lock discriminates
+ * between read-only ('reader') and full ('writer') access. While only
+ * one thread at a time is allowed write access (by holding the 'writer'
+ * lock via writer_lock()), multiple threads can gain
+ * simultaneous read-only access (by holding the 'reader' lock via
+ * reader_lock()).
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
+ */
+class GLIBMM_API RWLock
+{
+public:
+  class ReaderLock;
+  class WriterLock;
+
+  RWLock();
+
+  RWLock(const RWLock&) = delete;
+  RWLock& operator=(const RWLock&) = delete;
+
+  ~RWLock();
+
+  void reader_lock();
+  bool reader_trylock();
+  void reader_unlock();
+
+  void writer_lock();
+  bool writer_trylock();
+  void writer_unlock();
+
+  GRWLock* gobj() { return &gobject_; }
+
+private:
+  GRWLock gobject_;
+};
+
+/** Utility class for exception-safe locking of read/write locks.
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
+ */
+class GLIBMM_API RWLock::ReaderLock
+{
+public:
+  explicit inline ReaderLock(RWLock& rwlock);
+  inline ReaderLock(RWLock& rwlock, NotLock);
+  inline ReaderLock(RWLock& rwlock, TryLock);
+
+  ReaderLock(const RWLock::ReaderLock&) = delete;
+  RWLock::ReaderLock& operator=(const RWLock::ReaderLock&) = delete;
+
+  inline ~ReaderLock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RWLock& rwlock_;
+  bool    locked_;
+};
+
+/** Utility class for exception-safe locking of read/write locks.
+ *
+ * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
+ */
+class GLIBMM_API RWLock::WriterLock
+{
+public:
+  explicit inline WriterLock(RWLock& rwlock);
+  inline WriterLock(RWLock& rwlock, NotLock);
+  inline WriterLock(RWLock& rwlock, TryLock);
+
+  WriterLock(const RWLock::WriterLock&) = delete;
+  RWLock::WriterLock& operator=(const RWLock::WriterLock&) = delete;
+
+  inline ~WriterLock();
+
+  inline void acquire();
+  inline bool try_acquire();
+  inline void release();
+  inline bool locked() const;
+
+private:
+  RWLock& rwlock_;
+  bool    locked_;
+};
+
+/** An opaque data structure to represent a condition.
+ * A @a Cond is an object that threads can block on, if they find a certain
+ * condition to be false. If other threads change the state of this condition
+ * they can signal the @a Cond, such that the waiting thread is woken up.
+ *
+ * @deprecated Please use std::condition_variable instead.
+ *
+ * @par Usage example:
+ * @code
+ * Glib::Threads::Cond  data_cond;
+ * Glib::Threads::Mutex data_mutex;
+ * void* current_data = nullptr;
+ *
+ * void push_data(void* data)
+ * {
+ *   Glib::Threads::Mutex::Lock lock(data_mutex);
+ *
+ *   current_data = data;
+ *   data_cond.signal();
+ * }
+ *
+ * void* pop_data()
+ * {
+ *   Glib::Threads::Mutex::Lock lock(data_mutex);
+ *
+ *   while (!current_data)
+ *     data_cond.wait(data_mutex);
+ *
+ *   void* const data = current_data;
+ *   current_data = nullptr;
+ *
+ *   return data;
+ * }
+ * @endcode
+ */
+class GLIBMM_API Cond
+{
+public:
+  Cond();
+
+  Cond(const Cond&) = delete;
+  Cond& operator=(const Cond&) = delete;
+
+  ~Cond();
+
+  /** If threads are waiting for this @a Cond, exactly one of them is woken up.
+   * It is good practice to hold the same lock as the waiting thread, while calling
+   * this method, though not required.
+   */
+  void signal();
+
+  /** If threads are waiting for this @a Cond, all of them are woken up.
+   * It is good practice to hold the same lock as the waiting threads, while calling
+   * this method, though not required.
+   */
+  void broadcast();
+
+  /** Waits until this thread is woken up on this @a Cond.
+   * The mutex is unlocked before falling asleep and locked again before resuming.
+   *
+   * @param mutex A @a Mutex that is currently locked.
+   *
+   * @note It is important to use the @a wait() and @a wait_until() methods
+   * only inside a loop, which checks for the condition to be true as it is not
+   * guaranteed that the waiting thread will find it fulfilled, even if the signaling
+   * thread left the condition in that state. This is because another thread can have
+   * altered the condition, before the waiting thread got the chance to be woken up,
+   * even if the condition itself is protected by a @a Mutex.
+   */
+  void wait(Mutex& mutex);
+
+  /** Waits until this thread is woken up on this @a Cond, but not longer
+   * than until the time specified by @a end_time.
+   * The mutex is unlocked before falling asleep and locked again before resuming.
+   *
+   * @par Usage example:
+   * Extending the example presented in the documentation of class Cond.
+   * @code
+   * void* pop_data_timed()
+   * {
+   *   Glib::Threads::Mutex::Lock lock(data_mutex);
+   *
+   *   // Wait at most 5 seconds.
+   *   const gint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
+   *   while (!current_data)
+   *     if (!data_cond.wait_until(data_mutex, end_time)
+   *       return nullptr; // timeout
+   *
+   *   void* const data = current_data;
+   *   current_data = nullptr;
+   *
+   *   return data;
+   * }
+   * @endcode
+   * The end time is calculated once, before entering the loop, and reused.
+   * This is the motivation behind the use of absolute time. If a relative time
+   * of 5 seconds were passed directly to the call and a spurious wakeup
+   * occurred, the program would have to start over waiting again, which would
+   * lead to a total wait time of more than 5 seconds.
+   *
+   * @param mutex A @a Mutex that is currently locked.
+   * @param end_time The monotonic time to wait until, in microseconds.
+   *                 See g_get_monotonic_time().
+   * @return <tt>true</tt> if the condition variable was signalled (or in the case
+   *         of a spurious wakeup), <tt>false</tt> if @a end_time has passed.
+   *
+   * @note It is important to use the @a wait() and @a wait_until() methods
+   * only inside a loop, which checks for the condition to be true as it is not
+   * guaranteed that the waiting thread will find it fulfilled, even if the signaling
+   * thread left the condition in that state. This is because another thread can have
+   * altered the condition, before the waiting thread got the chance to be woken up,
+   * even if the condition itself is protected by a @a Mutex.
+   */
+  bool wait_until(Mutex& mutex, gint64 end_time);
+
+  GCond* gobj() { return &gobject_; }
+
+private:
+  GCond gobject_;
+};
+
+/** Thread-local data pointer.
+ *
+ * It is recommended that all instances of this class are statically allocated.
+ * The first time an instance is used (get(), set() or replace() is called)
+ * glib allocates a scarce OS resource that cannot be deallocated.
+ *
+ * @deprecated Please use the thread_local keyword instead.
+ */
+template <class T>
+class Private
+{
+public:
+  Private(const Private<T>&) = delete;
+  Private<T>& operator=(const Private<T>&) = delete;
+
+  using DestructorFunc = void (*) (void*);
+
+  /** Deletes static_cast<T*>(data)
+   */
+  static void delete_ptr(void* data);
+
+  /** Constructor.
+   *
+   * @param destructor_func Function pointer, or <tt>nullptr</tt>. If @a destructor_func is not <tt>nullptr</tt>
+   * and the stored data pointer is not <tt>nullptr</tt>, this function is called when replace()
+   * is called and when the thread exits.
+   */
+  explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
+
+  /** Gets the pointer stored in the calling thread.
+   *
+   * @return If no value has yet been set in this thread, <tt>nullptr</tt> is returned.
+   */
+  inline T* get();
+
+  /** Sets the pointer in the calling thread without calling <tt>destructor_func()</tt>.
+   */
+  inline void set(T* data);
+
+  /** Sets the pointer in the calling thread and calls <tt>destructor_func()</tt>.
+   * If a function pointer (and not <tt>nullptr</tt>) was specified in the constructor, and
+   * the stored data pointer before the call to replace() is not <tt>nullptr</tt>, then
+   * <tt>destructor_func()</tt> is called with this old pointer value.
+   *
+   * @newin{2,32}
+   */
+  inline void replace(T* data);
+
+  GPrivate* gobj() { return &gobject_; }
+
+private:
+  GPrivate gobject_;
+};
+
+/** @} group Threads */
+
+/*! A glibmm thread example.
+ * @example thread/thread.cc
+ */
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/***************************************************************************/
+/*  inline implementation                                                  */
+/***************************************************************************/
+
+/**** Glib::Threads::Mutex::Lock *******************************************/
+
+inline
+Mutex::Lock::Lock(Mutex& mutex)
+:
+  mutex_  (mutex),
+  locked_ (true)
+{
+  mutex_.lock();
+}
+
+inline
+Mutex::Lock::Lock(Mutex& mutex, NotLock)
+:
+  mutex_  (mutex),
+  locked_ (false)
+{}
+
+inline
+Mutex::Lock::Lock(Mutex& mutex, TryLock)
+:
+  mutex_  (mutex),
+  locked_ (mutex.trylock())
+{}
+
+inline
+Mutex::Lock::~Lock()
+{
+  if(locked_)
+    mutex_.unlock();
+}
+
+inline
+void Mutex::Lock::acquire()
+{
+  mutex_.lock();
+  locked_ = true;
+}
+
+inline
+bool Mutex::Lock::try_acquire()
+{
+  locked_ = mutex_.trylock();
+  return locked_;
+}
+
+inline
+void Mutex::Lock::release()
+{
+  mutex_.unlock();
+  locked_ = false;
+}
+
+inline
+bool Mutex::Lock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::Threads::RecMutex::Lock ****************************************/
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex)
+:
+  mutex_  (mutex),
+  locked_ (true)
+{
+  mutex_.lock();
+}
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
+:
+  mutex_  (mutex),
+  locked_ (false)
+{}
+
+inline
+RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
+:
+  mutex_  (mutex),
+  locked_ (mutex.trylock())
+{}
+
+inline
+RecMutex::Lock::~Lock()
+{
+  if(locked_)
+    mutex_.unlock();
+}
+
+inline
+void RecMutex::Lock::acquire()
+{
+  mutex_.lock();
+  locked_ = true;
+}
+
+inline
+bool RecMutex::Lock::try_acquire()
+{
+  locked_ = mutex_.trylock();
+  return locked_;
+}
+
+inline
+void RecMutex::Lock::release()
+{
+  mutex_.unlock();
+  locked_ = false;
+}
+
+inline
+bool RecMutex::Lock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::Threads::RWLock::ReaderLock ************************************/
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
+:
+  rwlock_ (rwlock),
+  locked_ (true)
+{
+  rwlock_.reader_lock();
+}
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
+:
+  rwlock_ (rwlock),
+  locked_ (false)
+{}
+
+inline
+RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
+:
+  rwlock_ (rwlock),
+  locked_ (rwlock.reader_trylock())
+{}
+
+inline
+RWLock::ReaderLock::~ReaderLock()
+{
+  if(locked_)
+    rwlock_.reader_unlock();
+}
+
+inline
+void RWLock::ReaderLock::acquire()
+{
+  rwlock_.reader_lock();
+  locked_ = true;
+}
+
+inline
+bool RWLock::ReaderLock::try_acquire()
+{
+  locked_ = rwlock_.reader_trylock();
+  return locked_;
+}
+
+inline
+void RWLock::ReaderLock::release()
+{
+  rwlock_.reader_unlock();
+  locked_ = false;
+}
+
+inline
+bool RWLock::ReaderLock::locked() const
+{
+  return locked_;
+}
+
+
+/**** Glib::Threads::RWLock::WriterLock ************************************/
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock)
+:
+  rwlock_ (rwlock),
+  locked_ (true)
+{
+  rwlock_.writer_lock();
+}
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
+:
+  rwlock_ (rwlock),
+  locked_ (false)
+{}
+
+inline
+RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
+:
+  rwlock_ (rwlock),
+  locked_ (rwlock.writer_trylock())
+{}
+
+inline
+RWLock::WriterLock::~WriterLock()
+{
+  if(locked_)
+    rwlock_.writer_unlock();
+}
+
+inline
+void RWLock::WriterLock::acquire()
+{
+  rwlock_.writer_lock();
+  locked_ = true;
+}
+
+inline
+bool RWLock::WriterLock::try_acquire()
+{
+  locked_ = rwlock_.writer_trylock();
+  return locked_;
+}
+
+inline
+void RWLock::WriterLock::release()
+{
+  rwlock_.writer_unlock();
+  locked_ = false;
+}
+
+inline
+bool RWLock::WriterLock::locked() const
+{
+  return locked_;
+}
+
+/**** Glib::Threads::Private<T> ********************************************/
+
+// static
+template <class T>
+void Private<T>::delete_ptr(void* data)
+{
+  delete static_cast<T*>(data);
+}
+
+template <class T> inline
+Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
+{
+  // gobject_ = G_PRIVATE_INIT(destructor_func);
+  // does not compile with --enable-warnings=fatal.
+  // GPrivate is a struct, and G_PRIVATE_INIT is an initializer of type { ... }.
+  // G_PRIVATE_INIT can be used only in initializations.
+  const GPrivate temp = G_PRIVATE_INIT(destructor_func);
+  gobject_ = temp;
+}
+
+template <class T> inline
+T* Private<T>::get()
+{
+  return static_cast<T*>(g_private_get(&gobject_));
+}
+
+template <class T> inline
+void Private<T>::set(T* data)
+{
+  g_private_set(&gobject_, data);
+}
+
+template <class T> inline
+void Private<T>::replace(T* data)
+{
+  g_private_replace(&gobject_, data);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} //namespace Threads
+
+} // namespace Glib
index 7faf86e..42a5ae1 100644 (file)
 namespace Glib
 {
 
+// Glib::Value<Glib::TimeZone>
+GType Value<TimeZone>::value_type()
+{
+  return G_TYPE_TIME_ZONE;
+}
+
+void Value<TimeZone>::set(const CppType& data)
+{
+  set_boxed(data.gobj());
+}
+
+Value<TimeZone>::CppType Value<TimeZone>::get() const
+{
+  return Glib::wrap(static_cast<CType>(get_boxed()), true);
+}
+
 } // namespace Glib
index 1d94ba0..35fe858 100644 (file)
@@ -17,6 +17,7 @@
 _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
+#include <glibmm/refptr.h>
 #include <glibmm/ustring.h>
 #include <glibmm/value.h>
 #include <glib.h>
@@ -25,6 +26,8 @@ _DEFS(glibmm,glib)
 typedef struct _GTimeZone GTimeZone;
 #endif
 
+//TODO: When we can change API, make TimeZone a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
@@ -51,13 +54,9 @@ _WRAP_ENUM(TimeType, GTimeType, NO_GTYPE)
  * changing.
  * @newin{2,30}
  */
-class TimeZone
+class GLIBMM_API TimeZone
 {
-  // GTimeZone is refcounted, but Glib::TimeZone is not.
-  // GTimeZone is immutable. Therefore, there is no problem having several
-  // Glib::TimeZone instances wrap the same GTimeZone, and it's easier to use
-  // Glib::TimeZone without Glib::RefPtr.
-  _CLASS_BOXEDTYPE(TimeZone, GTimeZone, NONE, g_time_zone_ref, g_time_zone_unref)
+  _CLASS_OPAQUE_COPYABLE(TimeZone, GTimeZone, NONE, g_time_zone_ref, g_time_zone_unref, GLIBMM_API)
   _IGNORE(g_time_zone_ref, g_time_zone_unref)
 
 public:
@@ -73,4 +72,20 @@ public:
   _WRAP_METHOD(Glib::ustring get_identifier() const, g_time_zone_get_identifier, newin "2,60")
 };
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::TimeZone can be used with Glib::Value and _WRAP_PROPERTY.
+template <>
+class Value<Glib::TimeZone> : public ValueBase_Boxed
+{
+public:
+  using CppType = Glib::TimeZone;
+  using CType = GTimeZone*;
+
+  static GType value_type();
+
+  void set(const CppType& data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 } // namespace Glib
index 167068b..7078a7d 100644 (file)
@@ -42,7 +42,8 @@ namespace Glib
  * @ingroup UriUtils
  * @newin{2,16}
  */
-std::string uri_unescape_string(const std::string& escaped_string, const std::string& illegal_characters = {});
+GLIBMM_API
+std::string uri_unescape_string(const std::string& escaped_string, const std::string& illegal_characters = std::string());
 
 //TODO: Use iterator?
 //char *   g_uri_unescape_segment      (const char *escaped_string,
@@ -61,6 +62,7 @@ std::string uri_unescape_string(const std::string& escaped_string, const std::st
  * @ingroup UriUtils
  * @newin{2,16}
  */
+GLIBMM_API
 std::string uri_parse_scheme(const std::string& uri);
 
 /** Escapes a string for use in a URI.
@@ -80,6 +82,7 @@ std::string uri_parse_scheme(const std::string& uri);
  * @ingroup UriUtils
  * @newin{2,16}
  */
-std::string uri_escape_string(const std::string& unescaped, const std::string& reserved_chars_allowed = {}, bool allow_utf8 = true);
+GLIBMM_API
+std::string uri_escape_string(const std::string& unescaped, const std::string& reserved_chars_allowed = std::string(), bool allow_utf8 = true);
 
 } // namespace Glib
index 1b8ba0d..6dd549f 100644 (file)
@@ -44,6 +44,12 @@ $1 Value<$1>::get() const
   return g_value_get_$2(&gobject_);
 }
 
+GParamSpec* Value<$1>::create_param_spec(const Glib::ustring& name) const
+{
+  return create_param_spec(name, Glib::ustring(), Glib::ustring(),
+      Glib::PARAM_READWRITE);
+}
+
 GParamSpec* Value<$1>::create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                          const Glib::ustring& blurb, Glib::ParamFlags flags) const
 {
@@ -71,6 +77,9 @@ G_GNUC_EXTENSION typedef long long long_long;
 G_GNUC_EXTENSION typedef unsigned long long unsigned_long_long;
 
 GLIB_VALUE_BASIC(bool, boolean)
+#ifndef GLIBMM_DISABLE_DEPRECATED
+GLIB_VALUE_BASIC(char, char, -128, 127)
+#endif // GLIBMM_DISABLE_DEPRECATED
 GLIB_VALUE_BASIC(signed char, schar, -128, 127)
 GLIB_VALUE_BASIC(unsigned char, uchar, 0, 255)
 GLIB_VALUE_BASIC(int, int, G_MININT, G_MAXINT)
index 40d980e..8cd90e7 100644 (file)
@@ -29,10 +29,11 @@ LINE(]__line__[)dnl
  * @ingroup glibmmValue
  */
 template <>
-class Value<$1> : public ValueBase
+class GLIBMM_API Value<$1> : public ValueBase
 {
 public:
   using CppType = $1;
+  using CType = g$2;
 
   static GType value_type() G_GNUC_CONST;
 
@@ -40,6 +41,7 @@ public:
   $1 get() const;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name) const;
   GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
                                 const Glib::ustring& blurb, Glib::ParamFlags flags) const;
 #endif
@@ -64,6 +66,10 @@ divert[]dnl
 namespace Glib
 {
 GLIB_VALUE_BASIC(bool, boolean)
+#ifndef GLIBMM_DISABLE_DEPRECATED
+/// @deprecated Use Value<signed char> instead.
+GLIB_VALUE_BASIC(char, char)
+#endif // GLIBMM_DISABLE_DEPRECATED
 /// @newin{2,44}
 GLIB_VALUE_BASIC(signed char, int8)
 GLIB_VALUE_BASIC(unsigned char, uchar)
diff --git a/glib/src/valuearray.ccg b/glib/src/valuearray.ccg
new file mode 100644 (file)
index 0000000..7776acb
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (C) 2002-2009 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/exceptionhandler.h>
+
+static int
+ValueArray_Compare_glibmm_callback(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+  Glib::ValueArray::SlotCompare* the_slot = static_cast<Glib::ValueArray::SlotCompare*>(user_data);
+
+  try
+  {
+    return (*the_slot)(
+      *reinterpret_cast<const Glib::ValueBase*>(a), *reinterpret_cast<const Glib::ValueBase*>(b));
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return 0;
+}
+
+namespace Glib
+{
+
+ValueArray::ValueArray() : gobject_(g_value_array_new(0))
+{
+}
+
+ValueArray::ValueArray(guint n_preallocated) : gobject_(g_value_array_new(n_preallocated))
+{
+}
+
+bool
+ValueArray::get_nth(guint index, Glib::ValueBase& value)
+{
+  const auto g_value = g_value_array_get_nth(gobj(), index);
+
+  if (g_value)
+  {
+    value.init(g_value);
+    return true;
+  }
+  else
+    return false;
+}
+
+Glib::ValueArray&
+ValueArray::append(const Glib::ValueBase& value)
+{
+  g_value_array_append(gobj(), value.gobj());
+  return *this;
+}
+
+Glib::ValueArray&
+ValueArray::prepend(const Glib::ValueBase& value)
+{
+  g_value_array_prepend(gobj(), value.gobj());
+  return *this;
+}
+
+Glib::ValueArray&
+ValueArray::insert(guint index, const Glib::ValueBase& value)
+{
+  g_value_array_insert(gobj(), index, value.gobj());
+  return *this;
+}
+
+Glib::ValueArray&
+ValueArray::remove(guint index)
+{
+  g_value_array_remove(gobj(), index);
+  return *this;
+}
+
+Glib::ValueArray&
+ValueArray::sort(const SlotCompare& compare_func)
+{
+  SlotCompare slot_copy(compare_func);
+  g_value_array_sort_with_data(gobj(), &ValueArray_Compare_glibmm_callback, &slot_copy);
+  return *this;
+}
+
+} // Glib namespace
diff --git a/glib/src/valuearray.hg b/glib/src/valuearray.hg
new file mode 100644 (file)
index 0000000..326079c
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (C) 2002-2009 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 <http://www.gnu.org/licenses/>.
+ */
+
+_CONFIGINCLUDE(glibmmconfig.h)
+
+_DEFS(glibmm,glib)
+
+#include <glib-object.h>
+#include <glibmm/value.h>
+#include <sigc++/functors/slot.h>
+
+#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
+#undef G_DISABLE_DEPRECATED
+#define GLIB_DISABLE_DEPRECATION_WARNINGS 1
+#m4 _POP()
+
+_IS_DEPRECATED // This whole file is deprecated.
+
+namespace Glib
+{
+
+/** A container structure to maintain an array of generic values.
+ * The prime purpose of a ValueArray is for it to be used as an object property
+ * that holds an array of values. A ValueArray wraps an array of ValueBase
+ * elements.
+ *
+ * @newin{2,22}
+ *
+ * @deprecated Use std::vector<Glib::ValueBase*> or std::vector< Glib::Value<> >
+ *             instead of Glib::ValueArray.
+ */
+class GLIBMM_API ValueArray
+{
+  _CLASS_BOXEDTYPE(ValueArray, GValueArray, NONE, g_value_array_copy, g_value_array_free, GLIBMM_API)
+  _IGNORE(g_value_array_copy, g_value_array_free)
+  _CUSTOM_DEFAULT_CTOR
+
+public:
+  /** For example,
+   *  int on_compare(const Glib::ValueBase& v1, const Glib::ValueBase& v2);.
+   *  The compare function should return -1 if v1 < v2, 0 if v1 == v2, and 1 if
+   *  v1 > v2.
+   */
+  using SlotCompare = sigc::slot<int, const Glib::ValueBase&, const Glib::ValueBase&>;
+
+  /** Default constructor.  Constructs a new array with no pre-allocation.
+   */
+  ValueArray();
+
+  /** Constructs a new array with pre-allocation.
+   */
+  ValueArray(guint n_preallocated);
+
+  /** Return the value at @a index contained in the value array.
+   * @param index Index of the value of interest.
+   * @param value An uninitialized ValueBase in which to store the result.  If
+   * the get is successful, @a value will be valid, otherwise it will remain
+   * uninitialized.
+   * @return whether the get was successful or not.
+   */
+  bool get_nth(guint index, Glib::ValueBase& value);
+  _IGNORE(g_value_array_get_nth)
+
+  _WRAP_METHOD_DOCS_ONLY(g_value_array_append)
+  Glib::ValueArray& append(const Glib::ValueBase& value);
+
+  _WRAP_METHOD_DOCS_ONLY(g_value_array_prepend)
+  Glib::ValueArray& prepend(const Glib::ValueBase& value);
+
+  _WRAP_METHOD_DOCS_ONLY(g_value_array_insert)
+  Glib::ValueArray& insert(guint index, const Glib::ValueBase& value);
+
+  _WRAP_METHOD_DOCS_ONLY(g_value_array_remove)
+  Glib::ValueArray& remove(guint index);
+
+  _WRAP_METHOD_DOCS_ONLY(g_value_array_sort)
+  Glib::ValueArray& sort(const SlotCompare& compare_func);
+  _IGNORE(g_value_array_sort_with_data)
+};
+
+} //namespace Glib
index 299a939..9ef2d2c 100644 (file)
@@ -22,8 +22,6 @@
 namespace Glib
 {
 
-/****************** VariantBase ***********************************/
-
 VariantBase::VariantBase(GVariant* castitem, bool make_a_copy /* = false */)
 {
   if (castitem)
@@ -38,32 +36,6 @@ VariantBase::VariantBase(GVariant* castitem, bool make_a_copy /* = false */)
   gobject_ = castitem;
 }
 
-VariantBase::operator bool() const
-{
-  return gobj();
-}
-
-void
-VariantBase::init(const GVariant* cobject, bool take_a_reference)
-{
-  if (gobject_)
-    g_variant_unref(gobject_);
-
-  gobject_ = const_cast<GVariant*>(cobject);
-  if (take_a_reference)
-    g_variant_ref(gobject_);
-}
-
-bool VariantBase::operator==(const VariantBase& other) const
-{
-  return equal(other);
-}
-
-bool VariantBase::operator!=(const VariantBase& other) const
-{
-  return !equal(other);
-}
-
 void
 VariantBase::get_normal_form(VariantBase& result) const
 {
@@ -136,8 +108,6 @@ VariantBase::is_castable_to(const VariantType& supertype) const
   return true;
 }
 
-/****************** VariantStringBase ***********************************/
-
 VariantStringBase::VariantStringBase() : VariantBase()
 {
 }
@@ -167,8 +137,6 @@ VariantStringBase::create_signature(VariantStringBase& output, const std::string
   output.init(result);
 }
 
-/****************** VariantContainerBase ***********************************/
-
 VariantContainerBase::VariantContainerBase() : VariantBase()
 {
 }
@@ -276,6 +244,29 @@ VariantContainerBase::get_iter(const VariantType& container_variant_type) const
 
 /****************** Specializations ***********************************/
 
+_DEPRECATE_IFDEF_START
+VariantBase::operator const void*() const
+{
+  return gobj() ? GINT_TO_POINTER(1) : nullptr;
+}
+_DEPRECATE_IFDEF_END
+
+VariantBase::operator bool() const
+{
+  return gobj() != nullptr;
+}
+
+void
+VariantBase::init(const GVariant* cobject, bool take_a_reference)
+{
+  if (gobject_)
+    g_variant_unref(gobject_);
+
+  gobject_ = const_cast<GVariant*>(cobject);
+  if (take_a_reference)
+    g_variant_ref(gobject_);
+}
+
 /*--------------------Variant<VariantBase>---------------------*/
 
 Variant<VariantBase>::Variant() : VariantContainerBase()
@@ -339,6 +330,30 @@ Variant<Glib::ustring>::get() const
   return convert_const_gchar_ptr_to_ustring(g_variant_get_string(gobject_, nullptr));
 }
 
+// Variant<Glib::ustring> makes sense for multiple types.
+// See http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
+template <>
+Variant<Glib::ustring>
+VariantBase::cast_dynamic<Variant<Glib::ustring>>(const VariantBase& v)
+{
+  if (!v.gobj())
+  {
+    return Variant<Glib::ustring>();
+  }
+
+  const VariantType vtype = v.get_type();
+  if (vtype.equal(VARIANT_TYPE_STRING) || vtype.equal(VARIANT_TYPE_OBJECT_PATH) ||
+      vtype.equal(VARIANT_TYPE_SIGNATURE))
+  {
+    return Variant<Glib::ustring>(const_cast<GVariant*>(v.gobj()), true);
+  }
+  else
+  {
+    // std::cerr << "vtype=" << v.get_type_string() << std::endl;
+    throw std::bad_cast();
+  }
+}
+
 /*--------------------Variant<Glib::DBusObjectPathString>---------------------*/
 
 Variant<Glib::DBusObjectPathString>::Variant() : VariantStringBase()
@@ -428,6 +443,30 @@ Variant<std::string>::create(const std::string& data)
   return result;
 }
 
+// Variant<std::string> makes sense for multiple types.
+// See http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
+template <>
+Variant<std::string>
+VariantBase::cast_dynamic<Variant<std::string>>(const VariantBase& v)
+{
+  if (!v.gobj())
+  {
+    return Variant<std::string>();
+  }
+
+  const VariantType vtype = v.get_type();
+  if (vtype.equal(VARIANT_TYPE_STRING) || vtype.equal(VARIANT_TYPE_BYTESTRING) ||
+      vtype.equal(VARIANT_TYPE_OBJECT_PATH) || vtype.equal(VARIANT_TYPE_SIGNATURE))
+  {
+    return Variant<std::string>(const_cast<GVariant*>(v.gobj()), true);
+  }
+  else
+  {
+    // std::cerr << "vtype=" << v.get_type_string() << std::endl;
+    throw std::bad_cast();
+  }
+}
+
 std::string
 Variant<std::string>::get() const
 {
index ff791df..807e52e 100644 (file)
@@ -30,6 +30,7 @@ _DEFS(glibmm,glib)
 #include <tuple>
 #include <stdexcept>
 #include <typeinfo>
+#include <cstddef>
 
 namespace Glib
 {
@@ -71,7 +72,7 @@ class Bytes;
 // Now (2014-01-30) it's also thrown by Gio::Action::parse_detailed_name().
 /** %Exception class for Variant parse errors.
  */
-_WRAP_GERROR(VariantParseError, GVariantParseError, G_VARIANT_PARSE_ERROR, NO_GTYPE)
+_WRAP_GERROR(VariantParseError, GVariantParseError, G_VARIANT_PARSE_ERROR, NO_GTYPE, decl_prefix GLIBMM_API)
 
 //TODO: Add this documentation from the API if we are confident of it for the C++ wrapper:
 // #GVariant is completely threadsafe.  A #GVariant instance can be
@@ -89,14 +90,37 @@ _WRAP_GERROR(VariantParseError, GVariantParseError, G_VARIANT_PARSE_ERROR, NO_GT
  * @newin{2,28}
  * @ingroup Variant
  */
-class VariantBase
+class GLIBMM_API VariantBase
 {
-  _CLASS_OPAQUE_COPYABLE(VariantBase, GVariant, NONE, g_variant_ref_sink, g_variant_unref)
+  _CLASS_OPAQUE_COPYABLE(VariantBase, GVariant, NONE, g_variant_ref_sink, g_variant_unref, GLIBMM_API)
   _CUSTOM_CTOR_CAST()
   _IGNORE(g_variant_ref, g_variant_ref_sink, g_variant_take_ref, g_variant_unref,
     g_variant_get, g_variant_get_va)
 public:
 
+_DEPRECATE_IFDEF_START
+  /** This typedef is just to make it more obvious that
+   * our operator const void* should be used like operator bool().
+   *
+   * @deprecated Use the explicit operator bool() instead.
+   */
+  using BoolExpr = const void*;
+
+  /** Test whether the Variant has an underlying instance.
+   *
+   * Mimics usage of pointers:
+   * @code
+   *   if (variant)
+   *     do_something();
+   * @endcode
+   *
+   * @deprecated Use the explicit operator bool() instead.
+   *
+   * @newin{2,36}
+   */
+   operator BoolExpr() const;
+_DEPRECATE_IFDEF_END
+
    /** Test whether the Variant has an underlying instance.
     *
     * @newin{2,50}
@@ -125,6 +149,7 @@ public:
   _WRAP_METHOD(GVariantClass classify() const, g_variant_classify)
 
   _WRAP_METHOD(gsize get_size() const, g_variant_get_size)
+  _WRAP_METHOD(gconstpointer get_data(), g_variant_get_data, deprecated "Use the const version instead.")
   _WRAP_METHOD(gconstpointer get_data() const, g_variant_get_data, newin "2,46")
   _WRAP_METHOD(Glib::RefPtr<const Glib::Bytes> get_data_as_bytes() const, g_variant_get_data_as_bytes, newin "2,46")
   _WRAP_METHOD(void store(gpointer data) const, g_variant_store)
@@ -144,39 +169,6 @@ public:
    */
   _WRAP_METHOD(bool equal(const VariantBase& other) const, g_variant_equal)
 
-  /** Checks if @a *this and @a other have the same type and value.
-   *
-   * @newin{2,58}
-   *
-   * @param other The Variant to compare with.
-   * @return <tt>true</tt> if @a *this and @a other are equal.
-   */
-  bool operator==(const VariantBase& other) const;
-
-  /** Checks if @a *this and @a other have the same type and value.
-   *
-   * @newin{2,58}
-   *
-   * @param other The Variant to compare with.
-   * @return <tt>true</tt> if @a *this and @a other are not equal.
-   */
-  bool operator!=(const VariantBase& other) const;
-
-  /** Ordering relational operators.
-   * These are explicitly deleted to prevent the compiler from generating
-   * error messages containing long lists of operators that can't be used.
-   */
-  bool operator<(const VariantBase& other) const = delete;
-
-  /// See operator<().
-  bool operator<=(const VariantBase& other) const = delete;
-
-  /// See operator<().
-  bool operator>(const VariantBase& other) const = delete;
-
-  /// See operator<().
-  bool operator>=(const VariantBase& other) const = delete;
-
   /** Gets a VariantBase instance that has the same value as this variant and
    * is trusted to be in normal form.
    *
@@ -257,6 +249,27 @@ protected:
    */
   bool is_castable_to(const VariantType& supertype) const;
 #endif //DOXYGEN_SHOULD_SKIP_THIS
+
+private:
+  /** Relational operators are deleted to prevent invalid conversion
+   * to const void*.
+   */
+  bool operator<(const VariantBase& src) const;
+
+  /// See operator<().
+  bool operator<=(const VariantBase& src) const;
+
+  /// See operator<().
+  bool operator>(const VariantBase& src) const;
+
+  /// See operator<().
+  bool operator>=(const VariantBase& src) const;
+
+  /// See operator<().
+  bool operator==(const VariantBase& src) const;
+
+  /// See operator<().
+  bool operator!=(const VariantBase& src) const;
 };
 
 template<class V_CastTo>
@@ -280,7 +293,7 @@ V_CastTo VariantBase::cast_dynamic(const VariantBase& v)
  * @newin{2,28}
  * @ingroup Variant
  */
-class VariantStringBase : public VariantBase
+class GLIBMM_API VariantStringBase : public VariantBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(VariantStringBase, GVariant)
@@ -330,12 +343,12 @@ public:
 };
 
 /** The base class for multiple-item Variants, such as Variants containing
- * tuples or arrays, and also for maybe-typed (i.e. nullable) Variant types.
+ * tuples or arrays, and also for maybe-typed (that is, nullable) Variant types.
  *
  * @newin{2,28}
  * @ingroup Variant
  */
-class VariantContainerBase : public VariantBase
+class GLIBMM_API VariantContainerBase : public VariantBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(VariantContainerBase, GVariant)
@@ -369,7 +382,7 @@ public:
 
   _WRAP_METHOD_DOCS_ONLY(g_variant_new_maybe)
   static VariantContainerBase create_maybe(const VariantType& child_type,
-    const VariantBase& child = {});
+    const VariantBase& child = VariantBase());
 
   _WRAP_METHOD(gsize get_n_children() const, g_variant_n_children)
 
@@ -421,7 +434,7 @@ protected:
 };
 
 template<>
-VariantContainerBase VariantBase::cast_dynamic<VariantContainerBase>(const VariantBase& v);
+GLIBMM_API VariantContainerBase VariantBase::cast_dynamic<VariantContainerBase>(const VariantBase& v);
 
 /** Template class used for the specialization of the Variant<> classes.
  * @newin{2,28}
@@ -446,7 +459,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant<VariantBase> : public VariantContainerBase
+class GLIBMM_API Variant<VariantBase> : public VariantContainerBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(Variant<VariantBase>, GVariant)
@@ -545,7 +558,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant<Glib::ustring> : public VariantStringBase
+class GLIBMM_API Variant<Glib::ustring> : public VariantStringBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(Variant<Glib::ustring>, GVariant)
@@ -586,13 +599,17 @@ public:
   _IGNORE(g_variant_get_string, g_variant_dup_string)
 };
 
+//TODO: When we can break ABI, remove this template specialization.
+template<>
+GLIBMM_API Variant<Glib::ustring> VariantBase::cast_dynamic< Variant<Glib::ustring> >(const VariantBase& v);
+
 /** Specialization of Variant containing a Glib::DBusObjectPathString,
  * for variants of type object path.
  * @newin{2,54}
  * @ingroup Variant
  */
 template<>
-class Variant<Glib::DBusObjectPathString> : public VariantStringBase
+class GLIBMM_API Variant<Glib::DBusObjectPathString> : public VariantStringBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(Variant<Glib::DBusObjectPathString>, GVariant)
@@ -638,7 +655,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant<Glib::DBusSignatureString> : public VariantStringBase
+class GLIBMM_API Variant<Glib::DBusSignatureString> : public VariantStringBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(Variant<Glib::DBusSignatureString>, GVariant)
@@ -685,7 +702,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant<std::string> : public VariantStringBase
+class GLIBMM_API Variant<std::string> : public VariantStringBase
 {
   // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
   _CLASS_GENERIC(Variant<std::string>, GVariant)
@@ -722,6 +739,10 @@ public:
   _IGNORE(g_variant_get_bytestring, g_variant_dup_bytestring)
 };
 
+//TODO: When we can break ABI, remove this template specialization.
+template<>
+GLIBMM_API Variant<std::string> VariantBase::cast_dynamic< Variant<std::string> >(const VariantBase& v);
+
 /** Specialization of Variant containing a dictionary entry.  See also
  * Variant< std::map<K, V> >.
  * @newin{2,28}
@@ -846,7 +867,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant< std::vector<Glib::ustring> > : public VariantContainerBase
+class GLIBMM_API Variant< std::vector<Glib::ustring> > : public VariantContainerBase
 {
 public:
   using CppType = Glib::ustring                ;
@@ -910,7 +931,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant<std::vector<Glib::DBusObjectPathString>> : public VariantContainerBase
+class GLIBMM_API Variant<std::vector<Glib::DBusObjectPathString>> : public VariantContainerBase
 {
 public:
   using CppType = Glib::DBusObjectPathString;
@@ -972,7 +993,7 @@ public:
  * @ingroup Variant
  */
 template<>
-class Variant< std::vector<std::string> > : public VariantContainerBase
+class GLIBMM_API Variant< std::vector<std::string> > : public VariantContainerBase
 {
 public:
   using CppType = std::string                  ;
@@ -1489,9 +1510,69 @@ const VariantType& Variant<std::tuple<Types...>>::variant_type()
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 namespace detail
 {
+// std::index_sequence and std::index_sequence_for are new in C++14,
+// but this version of glibmm requires only C++11.
+// The following code replaces std::index_sequence and std::index_sequence_for
+// until we can require C++14 support.
+// See https://bugzilla.gnome.org/show_bug.cgi?id=787648
+
+  /// Class template integer_sequence
+  template<typename T, T... Idx>
+    struct integer_sequence
+    {
+      typedef T value_type;
+      static constexpr std::size_t size() { return sizeof...(Idx); }
+    };
+
+  // Concatenates two integer_sequences.
+  template<typename Iseq1, typename Iseq2> struct iseq_cat;
+
+  template<typename T, std::size_t... Ind1, std::size_t... Ind2>
+    struct iseq_cat<integer_sequence<T, Ind1...>, integer_sequence<T, Ind2...>>
+    {
+      using type = integer_sequence<T, Ind1..., (Ind2 + sizeof...(Ind1))...>;
+    };
+
+  // Builds an integer_sequence<T, 0, 1, 2, ..., Num-1>.
+  template<typename T, std::size_t Num>
+    struct make_intseq
+    : iseq_cat<typename make_intseq<T, Num / 2>::type,
+               typename make_intseq<T, Num - Num / 2>::type>
+    { };
+
+  template<typename T>
+    struct make_intseq<T, 1>
+    {
+      typedef integer_sequence<T, 0> type;
+    };
+
+  template<typename T>
+    struct make_intseq<T, 0>
+    {
+      typedef integer_sequence<T> type;
+    };
+
+  /// Alias template make_integer_sequence
+  template<typename T, T Num>
+    using make_integer_sequence = typename make_intseq<T, Num>::type;
+
+  /// Alias template index_sequence
+  template<std::size_t... Idx>
+    using index_sequence = integer_sequence<std::size_t, Idx...>;
+
+  /// Alias template make_index_sequence
+  template<std::size_t Num>
+    using make_index_sequence = make_integer_sequence<std::size_t, Num>;
+
+  /// Alias template index_sequence_for
+  template<typename... Types>
+    using index_sequence_for = make_index_sequence<sizeof...(Types)>;
+
+// End of code that replaces std::index_sequence and std::index_sequence_for
+
 template <class Tuple, std::size_t... Is>
 void expand_tuple(std::vector<VariantBase> &variants, const Tuple & t,
-                  std::index_sequence<Is...>)
+                  detail::index_sequence<Is...>)
 {
   using swallow = int[]; // ensures left to right order
   auto expander = [&variants](const VariantBase &variant) -> int
@@ -1510,10 +1591,10 @@ Variant<std::tuple<Types...>>::create(const std::tuple<Types...>& data)
 {
   // create a vector containing all tuple values as variants
   std::vector<Glib::VariantBase> variants;
-  detail::expand_tuple(variants, data, std::index_sequence_for<Types...>{});
+  detail::expand_tuple(variants, data, detail::index_sequence_for<Types...>{});
 
   using var_ptr = GVariant*;
-  auto var_array = std::make_unique<var_ptr[]>(sizeof... (Types));
+  std::unique_ptr<var_ptr[]> var_array(new var_ptr[sizeof... (Types)]);
 
   for (std::vector<VariantBase>::size_type i = 0; i < variants.size(); i++)
     var_array[i] = const_cast<GVariant*>(variants[i].gobj());
@@ -1547,14 +1628,13 @@ namespace detail
 {
 // swallows any argument
 template <class T>
-constexpr int any_arg(T&& arg)
+constexpr int any_arg(T&& /* arg */)
 {
-  (void)arg;
   return 0;
 }
 
 template <class Tuple, std::size_t... Is>
-void assign_tuple(std::vector<VariantBase> &variants, Tuple & t, std::index_sequence<Is...>)
+void assign_tuple(std::vector<VariantBase> &variants, Tuple & t, detail::index_sequence<Is...>)
 {
   int i = 0;
   using swallow = int[]; // ensures left to right order
@@ -1577,7 +1657,7 @@ std::tuple<Types...> Variant<std::tuple<Types...>>::get() const
     return i++;
   };
   (void)swallow{(expander(get_child_variant<Types>(i)))...};
-  detail::assign_tuple(variants, data, std::index_sequence_for<Types...>{});
+  detail::assign_tuple(variants, data, detail::index_sequence_for<Types...>{});
 
   return data;
 }
@@ -1593,7 +1673,7 @@ VariantIter Variant<std::tuple<Types...>>::get_iter() const
 // This is needed so Glib::VariantBase can be used with
 // Glib::Value and _WRAP_PROPERTY in Gio::Action and elsewhere.
 template <>
-class Value<Glib::VariantBase> : public ValueBase_Variant
+class GLIBMM_API Value<Glib::VariantBase> : public ValueBase_Variant
 {
 public:
   using CppType = Glib::VariantBase;
index 5415177..199295b 100644 (file)
@@ -39,7 +39,7 @@ LINE(]__line__[)dnl
  * @ingroup Variant
  */
 template <>
-class Variant<$1> : public VariantBase
+class GLIBMM_API Variant<$1> : public VariantBase
 {
 public:
   using CType = $2;
index 1f9a5a1..4b69a08 100644 (file)
@@ -32,11 +32,11 @@ namespace Glib
  *
  * newin{2,40}
  */
-class VariantDict final
+class GLIBMM_API VariantDict final
 {
   //GVariantDict is registered as a boxed type, but it has ref/unref functions instead of copy/free,
   //so we use it via RefPtr.
-  _CLASS_OPAQUE_REFCOUNTED(VariantDict, GVariantDict, NONE, g_variant_dict_ref, g_variant_dict_unref)
+  _CLASS_OPAQUE_REFCOUNTED(VariantDict, GVariantDict, NONE, g_variant_dict_ref, g_variant_dict_unref, GLIBMM_API)
   _IGNORE(g_variant_dict_ref, g_variant_dict_unref, g_variant_dict_init)
 
 public:
index 7078951..f921b6c 100644 (file)
@@ -20,7 +20,7 @@
 namespace Glib
 {
 
-VariantIter::VariantIter(const VariantContainerBase& variant)
+VariantIter::VariantIter(const VariantBase& variant)
 : gobject_(g_variant_iter_new(const_cast<GVariant*>(variant.gobj())))
 {
 }
index c81dc29..a35c2e5 100644 (file)
@@ -20,22 +20,23 @@ _DEFS(glibmm,glib)
 namespace Glib
 {
 
-class VariantBase;
-class VariantContainerBase;
+class GLIBMM_API VariantBase;
+class GLIBMM_API VariantContainerBase;
 
 //This can't be like a real iterator (like Gtk::TextIter),
 //because g_iter_value_get_next_value() both gets a value and changes the iterator.
 //GtkTextIter allows us to go forward and then separately get the current value.
 /** VariantIter - An opaque data structure used to iterate through
- * VariantContainerBase containers such as arrays.
+ * VariantBase containers such as arrays.
  * @newin{2,28}
  */
-class VariantIter
+class GLIBMM_API VariantIter
 {
-  _CLASS_OPAQUE_COPYABLE(VariantIter, GVariantIter, NONE, g_variant_iter_copy, g_variant_iter_free)
+  _CLASS_OPAQUE_COPYABLE(VariantIter, GVariantIter, NONE, g_variant_iter_copy, g_variant_iter_free, GLIBMM_API)
   _IGNORE(g_variant_iter_copy, g_variant_iter_free)
 public:
-  explicit VariantIter(const VariantContainerBase& variant);
+  //TODO: The variant parameter should be a VariantContainerBase.
+  explicit VariantIter(const VariantBase& variant);
 
   _WRAP_METHOD(gsize init(const VariantContainerBase& value), g_variant_iter_init)
 
index 50ddac1..848c4f9 100644 (file)
@@ -88,9 +88,9 @@ namespace Glib
  * @newin{2,28}
  * @ingroup Variant
  */
-class VariantType
+class GLIBMM_API VariantType
 {
-  _CLASS_OPAQUE_COPYABLE(VariantType, GVariantType, NONE, g_variant_type_copy, g_variant_type_free)
+  _CLASS_OPAQUE_COPYABLE(VariantType, GVariantType, NONE, g_variant_type_copy, g_variant_type_free, GLIBMM_API)
   _IGNORE(g_variant_type_copy, g_variant_type_free)
 public:
 
@@ -126,8 +126,9 @@ public:
 
   _WRAP_METHOD(static VariantType create_dict_entry(const VariantType& key, const VariantType& value), g_variant_type_new_dict_entry)
 
-  _WRAP_METHOD(gsize get_string_length() const, g_variant_type_get_string_length)
-  dnl// wrapped by hand, because g_variant_type_peek_string does not return a nul-terminated C string.
+  //TODO: Use something instead of gsize?
+  _WRAP_METHOD(gsize _get_string_length() const, g_variant_type_get_string_length)
+  dnl wrapped by hand, because g_variant_type_peek_string does not return a C string.
   _WRAP_METHOD_DOCS_ONLY(g_variant_type_peek_string)
   std::string get_string() const;
   _IGNORE(g_variant_type_dup_string)
@@ -165,6 +166,8 @@ public:
 // g_variant_type_value() because they don't do that already.
 #m4 _CONVERSION(`const GVariantType*',`VariantType',`Glib::wrap(const_cast<GVariantType*>($3), true)')
   _WRAP_METHOD(VariantType element() const, g_variant_type_element)
+  _WRAP_METHOD(VariantType first() const, g_variant_type_first, deprecated "Use get_item_types() instead.")
+  _WRAP_METHOD(VariantType next () const, g_variant_type_next, deprecated "Use get_item_types() instead.")
   _WRAP_METHOD(gsize n_items() const, g_variant_type_n_items)
   _WRAP_METHOD(VariantType key() const, g_variant_type_key)
   _WRAP_METHOD(VariantType value() const, g_variant_type_value)
@@ -184,70 +187,69 @@ public:
    * @return The item types of this %VariantType, or an empty vector.
    */
   std::vector<VariantType> get_item_types() const;
-  _IGNORE(g_variant_type_first, g_variant_type_next)
 
   // This function is part of unexposed API in gvarianttypeinfo.{h,c} for an
   // also unexposed GVariantTypeInfo structure of glib.
   _IGNORE(g_variant_type_info_get)
 };
 
-extern const VariantType VARIANT_TYPE_BOOL;
+extern GLIBMM_API const VariantType VARIANT_TYPE_BOOL;
 
-extern const VariantType VARIANT_TYPE_BYTE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_BYTE;
 
-extern const VariantType VARIANT_TYPE_INT16;
+extern GLIBMM_API const VariantType VARIANT_TYPE_INT16;
 
-extern const VariantType VARIANT_TYPE_UINT16;
+extern GLIBMM_API const VariantType VARIANT_TYPE_UINT16;
 
-extern const VariantType VARIANT_TYPE_INT32;
+extern GLIBMM_API const VariantType VARIANT_TYPE_INT32;
 
-extern const VariantType VARIANT_TYPE_UINT32;
+extern GLIBMM_API const VariantType VARIANT_TYPE_UINT32;
 
-extern const VariantType VARIANT_TYPE_INT64;
+extern GLIBMM_API const VariantType VARIANT_TYPE_INT64;
 
-extern const VariantType VARIANT_TYPE_UINT64;
+extern GLIBMM_API const VariantType VARIANT_TYPE_UINT64;
 
-extern const VariantType VARIANT_TYPE_DOUBLE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_DOUBLE;
 
-extern const VariantType VARIANT_TYPE_STRING;
+extern GLIBMM_API const VariantType VARIANT_TYPE_STRING;
 
-extern const VariantType VARIANT_TYPE_OBJECT_PATH;
+extern GLIBMM_API const VariantType VARIANT_TYPE_OBJECT_PATH;
 
-extern const VariantType VARIANT_TYPE_SIGNATURE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_SIGNATURE;
 
-extern const VariantType VARIANT_TYPE_VARIANT;
+extern GLIBMM_API const VariantType VARIANT_TYPE_VARIANT;
 
-extern const VariantType VARIANT_TYPE_HANDLE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_HANDLE;
 
-extern const VariantType VARIANT_TYPE_UNIT;
+extern GLIBMM_API const VariantType VARIANT_TYPE_UNIT;
 
-extern const VariantType VARIANT_TYPE_ANY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_ANY;
 
-extern const VariantType VARIANT_TYPE_BASIC;
+extern GLIBMM_API const VariantType VARIANT_TYPE_BASIC;
 
-extern const VariantType VARIANT_TYPE_MAYBE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_MAYBE;
 
-extern const VariantType VARIANT_TYPE_ARRAY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_ARRAY;
 
-extern const VariantType VARIANT_TYPE_TUPLE;
+extern GLIBMM_API const VariantType VARIANT_TYPE_TUPLE;
 
-extern const VariantType VARIANT_TYPE_DICT_ENTRY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_DICT_ENTRY;
 
-extern const VariantType VARIANT_TYPE_DICTIONARY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_DICTIONARY;
 
-extern const VariantType VARIANT_TYPE_STRING_ARRAY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_STRING_ARRAY;
 
-extern const VariantType VARIANT_TYPE_OBJECT_PATH_ARRAY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_OBJECT_PATH_ARRAY;
 
-extern const VariantType VARIANT_TYPE_BYTESTRING;
+extern GLIBMM_API const VariantType VARIANT_TYPE_BYTESTRING;
 
-extern const VariantType VARIANT_TYPE_BYTESTRING_ARRAY;
+extern GLIBMM_API const VariantType VARIANT_TYPE_BYTESTRING_ARRAY;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 // This is needed so Glib::VariantType can be used with
 // Glib::Value and _WRAP_PROPERTY in Gio::Action and elsewhere.
 template <>
-class Value<Glib::VariantType> : public ValueBase_Boxed
+class GLIBMM_API Value<Glib::VariantType> : public ValueBase_Boxed
 {
 public:
   using CppType = Glib::VariantType;
diff --git a/meson.build b/meson.build
new file mode 100644 (file)
index 0000000..2e6be38
--- /dev/null
@@ -0,0 +1,261 @@
+# This file is part of glibmm.
+
+project('glibmm', 'cpp',
+  version: '2.64.0',
+  license: 'LGPLv2.1+',
+  default_options: [
+    'cpp_std=c++11'
+  ],
+  meson_version: '>= 0.50.0', # required for python3.path()
+)
+
+glibmm_api_version = '2.4'
+glibmm_pcname = meson.project_name() + '-' + glibmm_api_version
+giomm_pcname = 'giomm-' + glibmm_api_version
+
+glibmm_version_array = meson.project_version().split('.')
+glibmm_major_version = glibmm_version_array[0].to_int()
+glibmm_minor_version = glibmm_version_array[1].to_int()
+glibmm_micro_version = glibmm_version_array[2].to_int()
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+# The relation between libtool's current:revison:age interface versioning
+# and the .so filename, .so.x.y.z, is
+# x = current - age
+# y = age
+# z = revision
+# If libtool_soversion is updated as described in libtool's documentation,
+# x.y.z will usually *not* be equal to meson.project_version().
+libtool_soversion = [4, 0, 3]
+glibmm_libversion = '@0@.@1@.@2@'.format(
+  libtool_soversion[0] - libtool_soversion[2],
+  libtool_soversion[2],
+  libtool_soversion[1])
+
+# Use these instead of meson.source_root() and meson.build_root() in subdirectories.
+# source_root() and build_root() are not useful, if this is a subproject.
+project_source_root = meson.current_source_dir()
+project_build_root = meson.current_build_dir()
+
+cpp_compiler = meson.get_compiler('cpp')
+is_msvc = cpp_compiler.get_id() == 'msvc'
+is_host_windows = host_machine.system() == 'windows'
+
+is_os_cocoa = false
+if not is_host_windows
+  # This test for Mac OS is copied from glib. If the result of glib's test
+  # is ever made available outside glib, use glib's result instead of this test.
+  # glib: https://bugzilla.gnome.org/show_bug.cgi?id=780309
+  # glibmm: https://bugzilla.gnome.org/show_bug.cgi?id=781947
+  is_os_cocoa = cpp_compiler.compiles(
+    '''#include <Cocoa/Cocoa.h>
+    #ifdef GNUSTEP_BASE_VERSION
+    #error "Detected GNUstep, not Cocoa"
+    #endif''',
+    name: 'Mac OS X Cocoa support'
+  )
+endif
+
+python3 = import('python').find_installation()
+python_version = python3.language_version()
+python_version_req = '>= 3.5'
+if not python_version.version_compare(python_version_req)
+  error('Requires Python @0@, found @1@.'.format(python_version_req, python_version))
+endif
+
+# Do we build from a git repository?
+# Suppose we do if and only if a '.git' directory or file exists.
+cmd_py = '''
+import os
+import sys
+sys.exit(os.path.isdir("@0@") or os.path.isfile("@0@"))
+'''.format(project_source_root / '.git')
+is_git_build = run_command(python3, '-c', cmd_py).returncode() != 0
+
+# Options.
+maintainer_mode_opt = get_option('maintainer-mode')
+maintainer_mode = maintainer_mode_opt == 'true' or \
+                 (maintainer_mode_opt == 'if-git-build' and is_git_build)
+warning_level = get_option('warnings')
+build_deprecated_api = get_option('build-deprecated-api')
+build_documentation_opt = get_option('build-documentation')
+build_documentation = build_documentation_opt == 'true' or \
+                     (build_documentation_opt == 'if-maintainer-mode' and maintainer_mode)
+build_examples = get_option('build-examples')
+
+# Installation directories are relative to {prefix}.
+install_prefix = get_option('prefix')
+install_includedir = get_option('includedir')
+install_libdir = get_option('libdir')
+install_datadir = get_option('datadir')
+install_pkgconfigdir = install_libdir / 'pkgconfig'
+
+# Dependencies. <pkg> = glib and gio
+# <pkg>mm_build_dep: Dependencies when building the <pkg>mm library.
+# <pkg>mm_dep (created in <pkg>/<pkg>mm/meson.build):
+#   Dependencies when using the <pkg>mm library.
+
+sigcxx_req = '>= 2.9.1'
+glib_req = '>= 2.61.2'
+
+# There are pkg-config files for sigc++ and glib on MSVC, so just use that.
+sigcxx_dep = dependency('sigc++-2.0', version: sigcxx_req)
+glib_dep = dependency('glib-2.0', version: glib_req)
+gobject_dep = dependency('gobject-2.0', version: glib_req)
+gmodule_dep = dependency('gmodule-2.0', version: glib_req)
+
+glibmm_build_dep = [sigcxx_dep, glib_dep, gobject_dep, gmodule_dep]
+glibmm_requires = [
+  'sigc++-2.0', sigcxx_req,
+  'glib-2.0', glib_req,
+  'gobject-2.0', glib_req,
+  'gmodule-2.0', glib_req,
+]
+
+gio_dep = dependency('gio-2.0', version: glib_req)
+giomm_build_dep = glibmm_build_dep + [gio_dep]
+giomm_requires = glibmm_requires + ['gio-2.0', glib_req]
+if not is_host_windows
+  gio_unix_dep = dependency('gio-unix-2.0', version: glib_req)
+  giomm_build_dep += gio_unix_dep
+  giomm_requires += ['gio-unix-2.0', glib_req]
+endif
+
+glibmm_requires = ' '.join(glibmm_requires)
+giomm_requires = ' '.join(giomm_requires)
+
+# Some dependencies are required only in maintainer mode and/or if
+# reference documentation shall be built.
+mm_common_get = find_program('mm-common-get', required: maintainer_mode)
+m4 = find_program('m4', required: maintainer_mode) # Used by gmmproc
+perl = find_program('perl', required: maintainer_mode or build_documentation)
+doxygen = find_program('doxygen', required: build_documentation)
+dot = find_program('dot', required: build_documentation) # Used by Doxygen
+xsltproc = find_program('xsltproc', required: build_documentation)
+
+# Where to find gmmproc and generate_wrap_init.pl.
+gmmproc_dir = project_build_root / 'tools'
+
+# Script files copied to 'untracked' by mm-common-get.
+script_dir = project_source_root / 'untracked' / 'build_scripts'
+generate_binding_py = script_dir / 'generate-binding.py'
+doc_reference_py = script_dir / 'doc-reference.py'
+dist_changelog_py = script_dir / 'dist-changelog.py'
+dist_build_scripts_py = script_dir / 'dist-build-scripts.py'
+
+if maintainer_mode and mm_common_get.found()
+  # Copy files to untracked/build_scripts and untracked/docs.
+  run_command(mm_common_get, '--force', script_dir,
+    project_source_root / 'untracked' / 'docs')
+endif
+
+# glibmm's own script files.
+glibmm_script_dir = project_source_root / 'tools' / 'build_scripts'
+handle_built_files_py = glibmm_script_dir / 'handle-built-files.py'
+dummy_header_py = glibmm_script_dir / 'dummy-header.py'
+compile_schemas_py = glibmm_script_dir / 'compile-schemas.py'
+
+# Set compiler warnings.
+warning_flags = []
+if warning_level == 'min'
+  if is_msvc
+    warning_flags = ['/W3']
+  else
+    warning_flags = ['-Wall']
+  endif
+elif warning_level == 'max' or warning_level == 'fatal'
+  if is_msvc
+    warning_flags = ['/W4']
+  else
+    warning_flags = '-pedantic -Wall -Wextra -Wformat-security -Wsuggest-override -Wshadow -Wno-long-long'.split()
+  endif
+  if warning_level == 'fatal'
+    if is_msvc
+      warning_flags += ['/WX']
+    else
+      warning_flags += ['-Werror']
+    endif
+    deprecations = 'G SIGCXX'.split()
+    foreach d : deprecations
+      warning_flags += '-D@0@_DISABLE_DEPRECATED'.format(d)
+    endforeach
+  endif
+endif
+
+warning_flags = cpp_compiler.get_supported_arguments(warning_flags)
+add_project_arguments(warning_flags, language: 'cpp')
+
+# MSVC: Ignore warnings that aren't really harmful, but make those
+#       that should not be overlooked stand out.
+if is_msvc
+  disabled_warnings = cpp_compiler.get_supported_arguments([
+    '/FImsvc_recommended_pragmas.h', '/wd4146', '/wd4251', '/wd4275', '/wd4267', '/wd4530', '/wd4589', '/utf-8'
+  ])
+  add_project_arguments(disabled_warnings, language: 'cpp')
+endif
+
+subdir('tools')
+subdir('glib')
+subdir('MSVC_NMake/glibmm')
+subdir('glib/glibmm')
+subdir('gio')
+subdir('MSVC_NMake/giomm')
+subdir('gio/giomm')
+subdir('examples')
+subdir('tests')
+subdir('docs/reference')
+
+if not meson.is_subproject()
+  # Add a ChangeLog file to the distribution directory.
+  # (add_dist_script() is not allowed in a subproject)
+  meson.add_dist_script(
+    python3.path(), dist_changelog_py,
+    project_source_root,
+  )
+  # Add build scripts to the distribution directory, and delete .gitignore
+  # files and an empty $MESON_DIST_ROOT/build/ directory.
+  meson.add_dist_script(
+    python3.path(), dist_build_scripts_py,
+    project_source_root,
+    'untracked' / 'build_scripts',
+  )
+endif
+
+# Print a summary.
+real_maintainer_mode = ''
+if maintainer_mode_opt == 'if-git-build'
+  real_maintainer_mode = ' (@0@)'.format(maintainer_mode)
+endif
+
+real_build_documentation = ''
+if build_documentation_opt == 'if-maintainer-mode'
+  real_build_documentation = ' (@0@)'.format(build_documentation)
+endif
+
+summary = [
+  '',
+  '------',
+  meson.project_name() + ' ' + meson.project_version(),
+  '',
+  '         Maintainer mode: @0@@1@'.format(maintainer_mode_opt, real_maintainer_mode),
+  '       Compiler warnings: @0@'.format(warning_level),
+  '    Build deprecated API: @0@'.format(build_deprecated_api),
+  'Build HTML documentation: @0@@1@'.format(build_documentation_opt, real_build_documentation),
+  '  Build example programs: @0@'.format(build_examples),
+  'Directories:',
+  '                  prefix: @0@'.format(install_prefix),
+  '              includedir: @0@'.format(install_prefix / install_includedir),
+  '        includeglibmmdir: @0@'.format(install_prefix / install_includedir / glibmm_pcname),
+  '         includegiommdir: @0@'.format(install_prefix / install_includedir / giomm_pcname),
+  '                  libdir: @0@'.format(install_prefix / install_libdir),
+  '         glibmmconfigdir: @0@'.format(install_prefix / install_glibmmconfigdir),
+  '          giommconfigdir: @0@'.format(install_prefix / install_giommconfigdir),
+  '                   m4dir: @0@'.format(install_prefix / install_m4dir),
+  '            pkgconfigdir: @0@'.format(install_prefix / install_pkgconfigdir),
+  '                 datadir: @0@'.format(install_prefix / install_datadir),
+  '                  docdir: @0@'.format(install_prefix / install_docdir),
+  '              devhelpdir: @0@'.format(install_prefix / install_devhelpdir),
+  '------'
+]
+
+message('\n'.join(summary))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644 (file)
index 0000000..b5a526c
--- /dev/null
@@ -0,0 +1,12 @@
+option('maintainer-mode', type: 'combo', choices: ['false', 'if-git-build', 'true'],
+  value: 'if-git-build', description: 'Generate source code from .hg and .ccg files')
+option('warnings', type: 'combo', choices: ['no', 'min', 'max', 'fatal'], value: 'fatal',
+  description: 'Compiler warning level')
+option('build-deprecated-api', type: 'boolean', value: true,
+  description: 'Build deprecated API and include it in the library')
+option('build-documentation', type: 'combo', choices: ['false', 'if-maintainer-mode', 'true'],
+  value: 'if-maintainer-mode', description: 'Build and install the documentation')
+option('debug-refcounting', type: 'boolean', value: false,
+  description: 'Print debug messages in connection with reference counting')
+option('build-examples', type: 'boolean', value: true,
+  description: 'Build example programs')
index 3f6f81c..b898575 100644 (file)
@@ -22,34 +22,36 @@ check_PROGRAMS =                            \
        giomm_ioerror_and_iodbuserror/test      \
        giomm_memoryinputstream/test                    \
        giomm_simple/test                       \
-  giomm_stream_vfuncs/test \
        giomm_asyncresult_sourceobject/test     \
        giomm_tls_client/test                   \
        giomm_listmodel/test \
        glibmm_btree/test                       \
        glibmm_base64/test                      \
+       glibmm_binding/test                     \
        glibmm_date/test                        \
        glibmm_buildfilename/test               \
        glibmm_interface_implementation/test    \
        glibmm_interface_move/test                      \
        glibmm_mainloop/test                    \
        glibmm_nodetree/test                    \
-       glibmm_object/test                      \
        glibmm_object_move/test                 \
-       glibmm_objectbase/test                  \
        glibmm_objectbase_move/test                     \
        glibmm_ustring_compose/test             \
        glibmm_ustring_format/test              \
+       glibmm_ustring_make_valid/test \
        glibmm_ustring_sprintf/test             \
        glibmm_value/test                       \
+       glibmm_valuearray/test                  \
        glibmm_variant/test                     \
        glibmm_vector/test                      \
        glibmm_bool_vector/test                 \
+       glibmm_bool_arrayhandle/test            \
        glibmm_null_vectorutils/test            \
+       glibmm_null_containerhandle/test        \
        glibmm_refptr/test              \
        glibmm_refptr_sigc_bind/test            \
-       glibmm_bytearray/test                   \
-       glibmm_ustring_make_valid/test
+       glibmm_weakref/test             \
+       glibmm_bytearray/test
 
 TESTS =        $(check_PROGRAMS)
 
@@ -79,9 +81,6 @@ giomm_memoryinputstream_test_LDADD   = $(giomm_ldadd)
 giomm_simple_test_SOURCES  = giomm_simple/main.cc
 giomm_simple_test_LDADD    = $(giomm_ldadd)
 
-giomm_stream_vfuncs_test_SOURCES = giomm_stream_vfuncs/main.cc
-giomm_stream_vfuncs_test_LDADD   = $(giomm_ldadd)
-
 giomm_asyncresult_sourceobject_test_SOURCES  = giomm_asyncresult_sourceobject/main.cc
 giomm_asyncresult_sourceobject_test_LDADD    = $(giomm_ldadd)
 
@@ -92,6 +91,7 @@ giomm_listmodel_test_SOURCES                = giomm_listmodel/main.cc
 giomm_listmodel_test_LDADD                  = $(giomm_ldadd)
 
 glibmm_base64_test_SOURCES               = glibmm_base64/main.cc
+glibmm_binding_test_SOURCES              = glibmm_binding/main.cc
 glibmm_btree_test_SOURCES                = glibmm_btree/main.cc
 glibmm_buildfilename_test_SOURCES        = glibmm_buildfilename/main.cc
 glibmm_date_test_SOURCES                 = glibmm_date/main.cc
@@ -102,27 +102,25 @@ glibmm_interface_implementation_test_LDADD = $(giomm_ldadd)
 glibmm_interface_move_test_SOURCES       = glibmm_interface_move/main.cc
 glibmm_mainloop_test_SOURCES             = glibmm_mainloop/main.cc
 glibmm_nodetree_test_SOURCES             = glibmm_nodetree/main.cc
-glibmm_object_test_SOURCES               = glibmm_object/main.cc \
-                                          glibmm_object/test_derived_object.h
-glibmm_object_move_test_SOURCES          = glibmm_object_move/main.cc \
-                                          glibmm_object/test_derived_object.h
-glibmm_objectbase_test_SOURCES           = glibmm_objectbase/main.cc \
-                                          glibmm_objectbase/test_derived_objectbase.h \
-                                          glibmm_object/test_derived_object.h
-glibmm_objectbase_move_test_SOURCES      = glibmm_objectbase_move/main.cc \
-                                          glibmm_objectbase/test_derived_objectbase.h \
-                                          glibmm_object/test_derived_object.h
+glibmm_object_move_test_SOURCES          = glibmm_object_move/main.cc
+glibmm_objectbase_move_test_SOURCES      = glibmm_objectbase_move/main.cc
 glibmm_ustring_compose_test_SOURCES      = glibmm_ustring_compose/main.cc
 glibmm_ustring_format_test_SOURCES       = glibmm_ustring_format/main.cc
+glibmm_ustring_make_valid_test_SOURCES   = glibmm_ustring_make_valid/main.cc
 glibmm_ustring_sprintf_test_SOURCES      = glibmm_ustring_sprintf/main.cc
-glibmm_value_test_SOURCES                = glibmm_value/main.cc
+glibmm_value_test_SOURCES                = glibmm_value/glibmm_value.cc glibmm_value/main.cc
+glibmm_valuearray_test_SOURCES           = glibmm_valuearray/main.cc
 glibmm_variant_test_SOURCES              = glibmm_variant/main.cc
 glibmm_vector_test_SOURCES               = glibmm_vector/main.cc
 glibmm_vector_test_LDADD                 = $(giomm_ldadd)
 glibmm_bool_vector_test_SOURCES          = glibmm_bool_vector/main.cc
+glibmm_bool_arrayhandle_test_SOURCES     = glibmm_bool_arrayhandle/main.cc
 glibmm_null_vectorutils_test_SOURCES     = glibmm_null_vectorutils/main.cc
 glibmm_null_vectorutils_test_LDADD       = $(giomm_ldadd)
+glibmm_null_containerhandle_test_SOURCES = glibmm_null_containerhandle/main.cc
+glibmm_null_containerhandle_test_LDADD   = $(giomm_ldadd)
 glibmm_refptr_test_SOURCES               = glibmm_refptr/main.cc
 glibmm_refptr_sigc_bind_test_SOURCES     = glibmm_refptr_sigc_bind/main.cc
+glibmm_weakref_test_SOURCES              = glibmm_weakref/main.cc
+glibmm_weakref_test_LDADD                = $(giomm_ldadd)
 glibmm_bytearray_test_SOURCES            = glibmm_bytearray/main.cc
-glibmm_ustring_make_valid_test_SOURCES   = glibmm_ustring_make_valid/main.cc
index 1024a05..f40a943 100644 (file)
@@ -39,7 +39,7 @@ void test_store_boundaries()
 {
   auto store = Gio::ListStore<Gio::MenuItem>::create();
   auto item = Gio::MenuItem::create("", "");
-  std::weak_ptr<Gio::MenuItem> weakref_item = item;
+  auto weakref_item = Glib::WeakRef<Gio::MenuItem>(item);
 
   // Remove an item from an empty list.
   store->remove(0);
@@ -84,7 +84,7 @@ void test_store_boundaries()
 
   store.reset();
   item.reset();
-  if (weakref_item.lock())
+  if (weakref_item)
   {
     result = EXIT_FAILURE;
     std::cerr << "test_store_boundaries(), 10: weakref_item is not null" << std::endl;
@@ -116,16 +116,16 @@ void test_store_refcounts()
 
   const std::size_t n_items = 10;
   std::vector<Glib::RefPtr<Gio::MenuItem>> items;
-  std::vector<std::weak_ptr<Gio::MenuItem>> weakref_items;
+  std::vector<Glib::WeakRef<Gio::MenuItem>> weakref_items;
   for (std::size_t i = 0; i < n_items; ++i)
   {
     items.push_back(Gio::MenuItem::create("", ""));
-    weakref_items.emplace_back(items[i]);
+    weakref_items.push_back(Glib::WeakRef<Gio::MenuItem>(items[i]));
     store->append(items[i]);
   }
   check_store_refcounts_n_items(2, store, n_items);
 
-  if (store->get_item(3).get() != items[3].get())
+  if (store->get_item(3).operator->() != items[3].operator->())
   {
     result = EXIT_FAILURE;
     std::cerr << "test_store_refcounts(), 3: get_item(3) != items[3]" << std::endl;
@@ -134,15 +134,25 @@ void test_store_refcounts()
   for (std::size_t i = 0; i < n_items; ++i)
   {
     items[i].reset();
+    if (!weakref_items[i])
+    {
+      result = EXIT_FAILURE;
+      std::cerr << "test_store_refcounts(), 4: weakref_items[" << i << "] is null" << std::endl;
+    }
   }
 
   store->remove(4);
+  if (weakref_items[4])
+  {
+    result = EXIT_FAILURE;
+    std::cerr << "test_store_refcounts(), 5: weakref_items[4] is not null" << std::endl;
+  }
   check_store_refcounts_n_items(6, store, n_items-1);
 
   store.reset();
   for (std::size_t i = 0; i < n_items; ++i)
   {
-    if (weakref_items[i].lock())
+    if (weakref_items[i])
     {
       result = EXIT_FAILURE;
       std::cerr << "test_store_refcounts(), 7: weakref_items[" << i << "] is not null" << std::endl;
@@ -168,8 +178,8 @@ gint32 get_next_number()
 int compare_items1(const Glib::RefPtr<const Glib::Object>& a,
   const Glib::RefPtr<const Glib::Object>& b)
 {
-  const auto action_a = std::dynamic_pointer_cast<const Gio::SimpleAction>(a);
-  const auto action_b = std::dynamic_pointer_cast<const Gio::SimpleAction>(b);
+  const auto action_a = Glib::RefPtr<const Gio::SimpleAction>::cast_dynamic(a);
+  const auto action_b = Glib::RefPtr<const Gio::SimpleAction>::cast_dynamic(b);
   if (!action_a || !action_b)
   {
     result = EXIT_FAILURE;
@@ -218,7 +228,7 @@ void test_store_sorted1()
       result = EXIT_FAILURE;
       std::cerr << "test_store_sorted1(), 2: i=" << i << ", items are not equal" << std::endl;
     }
-    if (a.get() == b.get())
+    if (a.operator->() == b.operator->())
     {
       result = EXIT_FAILURE;
       std::cerr << "test_store_sorted1(), 3: i=" << i << ", items are the same" << std::endl;
@@ -227,7 +237,7 @@ void test_store_sorted1()
     if (i > 0)
     {
       auto c = store->get_item(i * 2 - 1);
-      if (c.get() == a.get() || c.get() == b.get())
+      if (c.operator->() == a.operator->() || c.operator->() == b.operator->())
       {
         result = EXIT_FAILURE;
         std::cerr << "test_store_sorted1(), 4: i=" << i << ", items are the same" << std::endl;
@@ -245,12 +255,12 @@ void test_store_sorted1()
 class MyObject : public Glib::Object
 {
 protected:
-  explicit MyObject(int id) : m_id(id) {}
+  MyObject(int id) : m_id(id) {}
 
 public:
   static Glib::RefPtr<MyObject> create(int id)
   {
-    return Glib::make_refptr_for_instance<MyObject>(new MyObject(id));
+    return Glib::RefPtr<MyObject>(new MyObject(id));
   }
 
   int get_id() const { return m_id; }
@@ -301,7 +311,7 @@ void test_store_sorted2()
       result = EXIT_FAILURE;
       std::cerr << "test_store_sorted2(), 2: i=" << i << ", items are not equal" << std::endl;
     }
-    if (a.get() == b.get())
+    if (a.operator->() == b.operator->())
     {
       result = EXIT_FAILURE;
       std::cerr << "test_store_sorted2(), 3: i=" << i << ", items are the same" << std::endl;
@@ -310,7 +320,7 @@ void test_store_sorted2()
     if (i > 0)
     {
       auto c = store->get_item(i * 2 - 1);
-      if (c.get() == a.get() || c.get() == b.get())
+      if (c.operator->() == a.operator->() || c.operator->() == b.operator->())
       {
         result = EXIT_FAILURE;
         std::cerr << "test_store_sorted2(), 4: i=" << i << ", items are the same" << std::endl;
index 2c35d1a..ce1b54e 100644 (file)
@@ -27,7 +27,7 @@ destroy_func1(void* data)
 }
 
 void
-destroy_func2(void* data, const Glib::ustring& intro)
+destroy_func2(void* data, const std::string& intro)
 {
   char* cdata = static_cast<char*>(data);
   func2_output += intro + cdata;
diff --git a/tests/giomm_stream_vfuncs/main.cc b/tests/giomm_stream_vfuncs/main.cc
deleted file mode 100644 (file)
index ad42e98..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Copyright (C) 2016 The giomm 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <giomm.h>
-#include <iostream>
-#include <string>
-#include <cstdlib>
-
-// A simple custom stream that base64 encodes data.
-// Do not copy it to your code, because it's very slow.
-class Base64OutputStream : public Gio::FilterOutputStream
-{
-public:
-  unsigned get_column_width() const { return column_width; }
-  void set_column_width(unsigned cw) { column_width = cw; }
-  static Glib::RefPtr<Base64OutputStream> create(const Glib::RefPtr<OutputStream>& base_stream)
-  {
-    return Glib::make_refptr_for_instance<Base64OutputStream>(new Base64OutputStream(base_stream));
-  }
-
-protected:
-  explicit Base64OutputStream(const Glib::RefPtr<Gio::OutputStream>& base_stream)
-    : Gio::FilterOutputStream(base_stream), column(0), bit_count(0), bit_buffer(0), column_width(72) {}
-
-  gssize write_vfunc(const void* buffer, gsize count, const Glib::RefPtr<Gio::Cancellable>& cancellable) override
-  {
-    char const *byte = (char const *) buffer;
-    for (unsigned i = 0; i < count; ++i, ++byte)
-    {
-      // kindergarten implementation, because the object is not performance :)
-      bit_buffer <<= 8;
-      bit_buffer |= (*byte & 0xff);
-      bit_count += 8;
-
-      if (bit_count == 24)
-      {
-        clear_pending(); // TODO why is this necessary to avoid an outstanding op. exception?
-        flush(cancellable);
-        set_pending();
-        bit_count = 0;
-      }
-
-      if (cancellable && cancellable->is_cancelled())
-        throw Gio::Error(Gio::Error::CANCELLED, "Operation cancelled");
-    }
-    return count;
-  }
-
-  bool flush_vfunc(const Glib::RefPtr<Gio::Cancellable>& cancellable) override
-  {
-    if (bit_count != 24)
-      return true;
-    char to_write[5];
-    gsize len = 4;
-
-    for (unsigned i=0; i<4; ++i)
-    {
-      unsigned index = (bit_buffer & (0x3f<<(i*6))) >> (i*6);
-      to_write[3-i] = base64_encode_str[index];
-    }
-    column += 4;
-    // Yes, I know this is completely wrong.
-    if (column >= column_width)
-    {
-      column = 0;
-      to_write[4] = '\n';
-      ++len;
-    }
-
-    get_base_stream()->write(&to_write, len, cancellable);
-
-    bit_count = 0;
-    bit_buffer = 0;
-
-    return true;
-  }
-
-  bool close_vfunc(const Glib::RefPtr<Gio::Cancellable>& cancellable) override
-  {
-    char to_write[5] = "====";
-    //get any last bytes (1 or 2) out of the buffer
-    switch (bit_count)
-    {
-    case 16:
-      bit_buffer <<= 2;  //pad to make 18 bits
-      to_write[0] = base64_encode_str[(bit_buffer & (0x3f << 12)) >> 12];
-      to_write[1] = base64_encode_str[(bit_buffer & (0x3f << 6)) >> 6];
-      to_write[2] = base64_encode_str[bit_buffer & 0x3f];
-      break;
-
-    case 8:
-      bit_buffer <<= 4; //pad to make 12 bits
-      to_write[0] = base64_encode_str[(bit_buffer & (0x3f << 6)) >> 6];
-      to_write[1] = base64_encode_str[bit_buffer & 0x3f];
-      break;
-    }
-
-    if (bit_count > 0)
-    {
-      get_base_stream()->write(&to_write, 5, cancellable);
-    }
-    else
-    {
-      // null terminate output
-      get_base_stream()->write("", 1, cancellable);
-    }
-    if (get_close_base_stream())
-      get_base_stream()->close(cancellable);
-
-    return true;
-  }
-
-private:
-  static char const *const base64_encode_str;
-  unsigned column;
-  unsigned bit_count;
-  unsigned bit_buffer;
-  unsigned column_width;
-};
-
-char const *const Base64OutputStream::base64_encode_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-int main(int, char**)
-{
-  Glib::init();
-  Gio::init();
-
-  try
-  {
-    char result[256];
-    Glib::RefPtr<Gio::MemoryOutputStream> memory_chunk = Gio::MemoryOutputStream::create(result, 256, nullptr, nullptr);
-    Glib::RefPtr<Base64OutputStream> base64 = Base64OutputStream::create(memory_chunk);
-
-    std::string data = "Custom GIO streams are cool!";
-
-    base64->set_close_base_stream(true);
-    base64->write(data);
-    base64->close();
-
-    const std::string base64_should_be("Q3VzdG9tIEdJTyBzdHJlYW1zIGFyZSBjb29sIQ==");
-    std::cout << "Original data:       " << data << std::endl;
-    std::cout << "base64-encoded data: " << result << std::endl;
-    std::cout << "base64 should be:    " << base64_should_be << std::endl;
-    if (base64_should_be != result)
-    {
-      std::cout << "Not correct!" << std::endl;
-      return EXIT_FAILURE;
-    }
-  }
-  catch (const Gio::Error& e)
-  {
-    std::cout << "Gio error: " << e.what() << std::endl;
-    return EXIT_FAILURE;
-  }
-
-  return EXIT_SUCCESS;
-}
index 703de75..5f13325 100644 (file)
@@ -77,7 +77,7 @@ main(int, char**)
             << std::endl;
 
   auto socket = Gio::Socket::create(
-    first_inet_address->get_family(), Gio::Socket::Type::STREAM, Gio::Socket::Protocol::TCP);
+    first_inet_address->get_family(), Gio::SOCKET_TYPE_STREAM, Gio::SOCKET_PROTOCOL_TCP);
 
   auto address = Gio::InetSocketAddress::create(first_inet_address, 443);
 
@@ -98,7 +98,7 @@ main(int, char**)
               << address->get_port() << "." << std::endl;
   }
 
-  auto conn = std::dynamic_pointer_cast<Gio::TcpConnection>(Gio::SocketConnection::create(socket));
+  auto conn = Glib::RefPtr<Gio::TcpConnection>::cast_dynamic(Gio::SocketConnection::create(socket));
 
   if (!conn || !conn->is_connected())
   {
@@ -115,7 +115,7 @@ main(int, char**)
   {
     auto tls_connection = Gio::TlsClientConnection::create(conn, address);
 
-    tls_connection->signal_accept_certificate().connect(sigc::ptr_fun(&on_accept_certificate), false);
+    tls_connection->signal_accept_certificate().connect(sigc::ptr_fun(&on_accept_certificate));
 
     tls_connection->handshake();
 
diff --git a/tests/glibmm_binding/main.cc b/tests/glibmm_binding/main.cc
new file mode 100644 (file)
index 0000000..cdbcaf7
--- /dev/null
@@ -0,0 +1,116 @@
+#include <glib.h>
+#include <glibmm/binding.h>
+#include <glibmm/init.h>
+#include <glibmm/object.h>
+#include <glibmm/property.h>
+#include <glibmm/propertyproxy.h>
+
+#include <limits>
+
+namespace {
+
+class StringSource final: public Glib::Object {
+public:
+  StringSource(): Glib::ObjectBase{"StringSource"} {}
+
+  auto property_string() -> Glib::PropertyProxy<Glib::ustring>
+    { return m_property_string.get_proxy(); }
+
+private:
+  Glib::Property<Glib::ustring> m_property_string{*this, "string"};
+};
+
+class IntTarget final: public Glib::Object {
+public:
+  IntTarget(): Glib::ObjectBase{"IntTarget"} {}
+
+  auto property_int() -> Glib::PropertyProxy<int>
+    { return m_property_int.get_proxy(); }
+
+private:
+  Glib::Property<int> m_property_int{*this, "int"};
+};
+
+template <typename T>
+auto
+clamp(const T& t, const T& min, const T& max) -> const T&
+{
+  return t < min ? min : t > max ? max : t;
+}
+
+auto
+transform_string_to_int(const Glib::ustring& source, int& target) -> bool
+{
+  char* str_end{};
+  auto long_int = std::strtol(source.c_str(), &str_end, 10);
+
+  if (str_end == source.c_str())
+    return false;
+
+  using IntLimits = std::numeric_limits<int>;
+  auto constexpr min = long{IntLimits::min()};
+  auto constexpr max = long{IntLimits::max()};
+  auto const clamped_int = clamp(long_int, min, max);
+
+  if (clamped_int != long_int)
+    return false;
+
+  target = static_cast<int>(clamped_int);
+  return true;
+}
+
+void
+test()
+{
+  Glib::init();
+  StringSource source{};
+  IntTarget target{};
+
+  // We should obviously not change the target before it has been bound!
+  target.property_int() = 7;
+  source.property_string() = "42";
+  g_assert_cmpint(target.property_int(), ==, 7);
+
+  {
+    auto binding = Glib::Binding::bind_property(
+      source.property_string(), target.property_int(),
+      Glib::BINDING_DEFAULT, &transform_string_to_int);
+
+    // Without SYNC_CREATE, only changes after bound will be synced
+    g_assert_cmpint(target.property_int(), ==, 7);
+
+    // An empty string is not a zero
+    source.property_string() = "";
+    g_assert_cmpint(target.property_int(), ==, 7);
+
+    // Ensure the change is synced
+    source.property_string() = "47";
+    g_assert_cmpint(target.property_int(), ==, 47);
+
+    // Ensure no change when invalid source results in false return
+    source.property_string() = "six six six";
+    g_assert_cmpint(target.property_int(), ==, 47);
+  }
+
+  // Ensure the binding was released when its RefPtr went out of scope
+  source.property_string() = "89";
+  g_assert_cmpint(target.property_int(), ==, 47);
+
+  {
+    auto binding = Glib::Binding::bind_property(
+      source.property_string(), target.property_int(),
+      Glib::BINDING_SYNC_CREATE, &transform_string_to_int);
+
+    // With SYNC_CREATE, value of source must sync to target on bind
+    g_assert_cmpint(target.property_int(), ==, 89);
+  }
+}
+
+} // namespace
+
+auto
+main() -> int
+{
+  test();
+  return 0;
+}
diff --git a/tests/glibmm_bool_arrayhandle/main.cc b/tests/glibmm_bool_arrayhandle/main.cc
new file mode 100644 (file)
index 0000000..5144d26
--- /dev/null
@@ -0,0 +1,96 @@
+/* Copyright (C) 2011 The glibmm 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 <http://www.gnu.org/licenses/>.
+ */
+#include <cstdlib>
+#include <ctime>
+
+#include <iostream>
+
+#include <glibmm.h>
+
+// Use this line if you want debug output:
+// std::ostream& ostr = std::cout;
+
+// This seems nicer and more useful than putting an ifdef around the use of std::cout:
+std::stringstream debug;
+std::ostream& ostr = debug;
+
+const unsigned int magic_limit(5);
+
+void
+setup_rand()
+{
+  static bool setup(false);
+
+  if (!setup)
+  {
+    std::srand(std::time(nullptr));
+    setup = true;
+  }
+}
+
+gboolean*
+c_get_bool_array()
+{
+  gboolean* array(static_cast<gboolean*>(g_malloc((magic_limit + 1) * sizeof(gboolean))));
+
+  setup_rand();
+  for (unsigned int iter(0); iter < magic_limit; ++iter)
+  {
+    array[iter] = std::rand() % 2 ? TRUE : FALSE;
+  }
+  array[magic_limit] = FALSE;
+  return array;
+}
+
+void
+c_print_bool_array(gboolean* array)
+{
+  for (unsigned int iter(0); iter < magic_limit; ++iter)
+  {
+    ostr << iter << ": " << (array[iter] ? "TRUE" : "FALSE") << "\n";
+  }
+}
+
+Glib::ArrayHandle<bool>
+cxx_get_bool_array()
+{
+  return Glib::ArrayHandle<bool>(c_get_bool_array(), magic_limit, Glib::OWNERSHIP_SHALLOW);
+}
+
+void
+cxx_print_bool_array(const Glib::ArrayHandle<bool>& array)
+{
+  c_print_bool_array(const_cast<gboolean*>(array.data()));
+}
+
+int
+main()
+{
+  Glib::init();
+
+  std::vector<bool> v(cxx_get_bool_array());
+  std::list<bool> l(cxx_get_bool_array());
+  std::deque<bool> d(cxx_get_bool_array());
+
+  ostr << "vector:\n";
+  cxx_print_bool_array(v);
+  ostr << "list:\n";
+  cxx_print_bool_array(l);
+  ostr << "deque:\n";
+  cxx_print_bool_array(d);
+
+  return EXIT_SUCCESS;
+}
index e92559c..1e6411d 100644 (file)
@@ -17,7 +17,7 @@ main(int, char**)
   date.subtract_days(1);
   date.add_years(1);
 
-  ostr << "The date a year and a month from yesterday will be: " << date.get_month_as_int() << "/"
+  ostr << "The date a year and a month from yesterday will be: " << date.get_month() << "/"
        << (int)date.get_day() << "/" << date.get_year() << "." << std::endl;
 
   Glib::Date copy_date(date);
@@ -25,7 +25,7 @@ main(int, char**)
 
   assigned_date = copy_date;
 
-  ostr << "The copied date is: " << copy_date.get_month_as_int() << "/" << (int)copy_date.get_day() << "/"
+  ostr << "The copied date is: " << copy_date.get_month() << "/" << (int)copy_date.get_day() << "/"
        << copy_date.get_year() << "." << std::endl;
 
   return EXIT_SUCCESS;
index b1888fd..e73a3bf 100644 (file)
@@ -22,10 +22,12 @@ test_Iface_get_type(void)
 {
   // Avoid compiler warnings about unused functions.
   // TODO: With C++17, use [[maybe unused]].
+#ifndef _MSC_VER
   (void)TEST_IFACE;
   (void)TEST_IS_IFACE;
   (void)TEST_IFACE_GET_IFACE;
   (void)glib_autoptr_cleanup_TestIface;
+#endif
 
   static GType type = 0;
 
@@ -116,7 +118,7 @@ class TestInterface : public Glib::Interface
 protected:
   using CppClassType = TestInterface_Class;
 
-  TestInterface() : Glib::Interface(derived_interface_class_.init()), i_(0) {}
+  TestInterface() : Glib::Interface(derived_interface_class_.init()) {}
 
 public:
   // A real application would never make the constructor public.
@@ -194,7 +196,7 @@ public:
 
   // A real application would never make the constructor public.
   // It would instead have a protected constructor and a public create() method.
-  explicit DerivedObject(int i)
+  DerivedObject(int i)
   : Glib::ObjectBase(nullptr),
     Glib::Object(Glib::ConstructParams(derived_object_class_.init())),
     i_(i)
index fee12ff..0554c48 100644 (file)
@@ -14,6 +14,7 @@ node_build_string(type_nodetree_string& node, std::string& string)
 int
 main()
 {
+  std::list<std::string> alma;
   std::string tstring, cstring;
   type_nodetree_string* root;
   type_nodetree_string* node;
@@ -49,16 +50,16 @@ main()
   g_assert(root->depth() == 1);
   g_assert(root->get_max_height() == 4);
   g_assert(node_G->first_child()->next_sibling()->depth() == 4);
-  g_assert(root->node_count(type_nodetree_string::TraverseFlags::LEAVES) == 7);
-  g_assert(root->node_count(type_nodetree_string::TraverseFlags::NON_LEAVES) == 4);
-  g_assert(root->node_count(type_nodetree_string::TraverseFlags::ALL) == 11);
+  g_assert(root->node_count(type_nodetree_string::TRAVERSE_LEAVES) == 7);
+  g_assert(root->node_count(type_nodetree_string::TRAVERSE_NON_LEAVES) == 4);
+  g_assert(root->node_count(type_nodetree_string::TRAVERSE_ALL) == 11);
   g_assert(node_F->get_max_height() == 3);
   g_assert(node_G->child_count() == 4);
-  g_assert(root->find_child("F", type_nodetree_string::TraverseFlags::ALL) == node_F);
+  g_assert(root->find_child("F", type_nodetree_string::TRAVERSE_ALL) == node_F);
   g_assert(
-    root->find("I", type_nodetree_string::TraverseType::LEVEL_ORDER, type_nodetree_string::TraverseFlags::NON_LEAVES) == NULL);
+    root->find("I", Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_NON_LEAVES) == NULL);
   g_assert(
-    root->find("J", type_nodetree_string::TraverseType::IN_ORDER, type_nodetree_string::TraverseFlags::LEAVES) == node_J);
+    root->find("J", Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_LEAVES) == node_J);
 
   for (guint i = 0; i < node_B->child_count(); i++)
   {
@@ -83,28 +84,28 @@ main()
 
   tstring.clear();
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::PRE_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_PRE_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == "ABCDEFGHIJK");
   tstring.clear();
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::POST_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_POST_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == "CDEBHIJKGFA");
   tstring.clear();
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::IN_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == "CBDEAHGIJKF");
   tstring.clear();
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::LEVEL_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == "ABFCDEGHIJK");
   tstring.clear();
 
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::LEVEL_ORDER, type_nodetree_string::TraverseFlags::LEAVES, -1);
+    Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_LEAVES, -1);
   g_assert(tstring == "CDEHIJK");
   tstring.clear();
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::PRE_ORDER, type_nodetree_string::TraverseFlags::NON_LEAVES, -1);
+    Glib::TRAVERSE_PRE_ORDER, type_nodetree_string::TRAVERSE_NON_LEAVES, -1);
   g_assert(tstring == "ABFG");
   tstring.clear();
 
@@ -112,18 +113,18 @@ main()
   node_G->reverse_children();
 
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::LEVEL_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == "ABFEDCGKJIH");
   tstring.clear();
 
   node = new type_nodetree_string(*root); // A deep copy.
-  g_assert(root->node_count(type_nodetree_string::TraverseFlags::ALL) ==
-           node->node_count(type_nodetree_string::TraverseFlags::ALL));
+  g_assert(root->node_count(type_nodetree_string::TRAVERSE_ALL) ==
+           node->node_count(type_nodetree_string::TRAVERSE_ALL));
   g_assert(root->get_max_height() == node->get_max_height());
   root->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(tstring)),
-    type_nodetree_string::TraverseType::IN_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   node->traverse(sigc::bind(sigc::ptr_fun(node_build_string), std::ref(cstring)),
-    type_nodetree_string::TraverseType::IN_ORDER, type_nodetree_string::TraverseFlags::ALL, -1);
+    Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_ALL, -1);
   g_assert(tstring == cstring);
 
   delete node;
@@ -142,7 +143,7 @@ main()
       node = node->first_child()->next_sibling();
   }
   g_assert(root->get_max_height() > 100);
-  g_assert(root->node_count(type_nodetree_string::TraverseFlags::ALL) == 1 + 2048);
+  g_assert(root->node_count(type_nodetree_string::TRAVERSE_ALL) == 1 + 2048);
 
   delete root;
 
diff --git a/tests/glibmm_null_containerhandle/main.cc b/tests/glibmm_null_containerhandle/main.cc
new file mode 100644 (file)
index 0000000..513daca
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/arrayhandle.h>
+#include <glibmm/listhandle.h>
+#include <glibmm/slisthandle.h>
+
+#include <giomm/credentials.h>
+#include <giomm/init.h>
+
+int
+main()
+{
+  Gio::init();
+  using CrePtr = Glib::RefPtr<Gio::Credentials>;
+
+  std::vector<CrePtr> v1(Glib::ArrayHandle<CrePtr>(nullptr, Glib::OWNERSHIP_DEEP));
+  std::vector<CrePtr> v2(Glib::ArrayHandle<CrePtr>(nullptr, 5, Glib::OWNERSHIP_DEEP));
+  std::vector<CrePtr> v3(Glib::ListHandle<CrePtr>(nullptr, Glib::OWNERSHIP_DEEP));
+  std::vector<CrePtr> v4(Glib::SListHandle<CrePtr>(nullptr, Glib::OWNERSHIP_DEEP));
+  std::vector<bool> v5(Glib::ArrayHandle<bool>(nullptr, Glib::OWNERSHIP_DEEP));
+  std::vector<bool> v6(Glib::ArrayHandle<bool>(nullptr, 5, Glib::OWNERSHIP_DEEP));
+
+  if (v1.empty() && v2.empty() && v3.empty() && v4.empty() && v5.empty() && v6.empty())
+  {
+    return 0;
+  }
+  return 1;
+}
diff --git a/tests/glibmm_object/main.cc b/tests/glibmm_object/main.cc
deleted file mode 100644 (file)
index 925b875..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "test_derived_object.h"
-#include <glibmm.h>
-#include <iostream>
-#include <stdlib.h>
-
-static void
-test_object()
-{
-  GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr));
-  DerivedObject derived(gobject, 5);
-  // std::cout << "debug: gobj(): " << derived.gobj() << std::endl;
-  g_assert(derived.gobj() == gobject);
-}
-
-int
-main(int, char**)
-{
-  Glib::init();
-
-  test_object();
-
-  return EXIT_SUCCESS;
-}
diff --git a/tests/glibmm_object/test_derived_object.h b/tests/glibmm_object/test_derived_object.h
deleted file mode 100644 (file)
index 4c506b2..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _GLIBMM_TEST_DERIVED_OBJECT_H
-#define _GLIBMM_TEST_DERIVED_OBJECT_H
-
-#include <glibmm.h>
-
-// A basic derived GObject, just to test Glib::Object.
-typedef struct
-{
-  GObject parent;
-} TestDerived;
-
-typedef struct
-{
-  GObjectClass parent;
-} TestDerivedClass;
-
-#define TEST_TYPE_DERIVED (test_derived_get_type())
-#define TEST_DERIVED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_DERIVED, TestDerived))
-#define TEST_DERIVED_CLASS(cls) \
-  (G_TYPE_CHECK_CLASS_CAST((cls), TEST_TYPE_DERIVED, TestDerivedClass))
-#define TEST_DERIVED_GET_CLASS(obj) \
-  (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_DERIVED, TestDerivedClass))
-
-static void
-test_derived_class_init(TestDerivedClass*)
-{
-}
-static void
-test_derived_init(TestDerived*)
-{
-}
-
-G_DEFINE_TYPE(TestDerived, test_derived, G_TYPE_OBJECT)
-
-class DerivedObject : public Glib::Object
-{
-public:
-  // A real application would never make the constructor public.
-  // It would instead have a protected constructor and a public create() method.
-  DerivedObject(GObject* gobject, int i) : Glib::Object(gobject), i_(i) {}
-
-  DerivedObject(const DerivedObject& src) = delete;
-  DerivedObject& operator=(const DerivedObject& src) = delete;
-
-  DerivedObject(DerivedObject&& src) noexcept : Glib::Object(std::move(src)), i_(std::move(src.i_))
-  {
-  }
-
-  DerivedObject& operator=(DerivedObject&& src) noexcept
-  {
-    Glib::Object::operator=(std::move(src));
-    i_ = std::move(src.i_);
-
-    return *this;
-  }
-
-  int i_;
-};
-
-#endif // _GLIBMM_TEST_DERIVED_OBJECT_H
index 1383b74..4f34cb7 100644 (file)
@@ -1,8 +1,61 @@
-#include "../glibmm_object/test_derived_object.h"
 #include <glibmm.h>
 #include <iostream>
 #include <stdlib.h>
 
+// A basic derived GObject, just to test Glib::Object.
+typedef struct
+{
+  GObject parent;
+} TestDerived;
+
+typedef struct
+{
+  GObjectClass parent;
+} TestDerivedClass;
+
+#define TEST_TYPE_DERIVED (test_derived_get_type())
+#define TEST_DERIVED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_DERIVED, TestDerived))
+#define TEST_DERIVED_CLASS(cls) \
+  (G_TYPE_CHECK_CLASS_CAST((cls), TEST_TYPE_DERIVED, TestDerivedClass))
+#define TEST_DERIVED_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_DERIVED, TestDerivedClass))
+
+static void
+test_derived_class_init(TestDerivedClass*)
+{
+}
+static void
+test_derived_init(TestDerived*)
+{
+}
+
+G_DEFINE_TYPE(TestDerived, test_derived, G_TYPE_OBJECT)
+
+class DerivedObject : public Glib::Object
+{
+public:
+  // A real application would never make the constructor public.
+  // It would instead have a protected constructor and a public create() method.
+  DerivedObject(GObject* gobject, int i) : Glib::Object(gobject), i_(i) {}
+
+  DerivedObject(const DerivedObject& src) = delete;
+  DerivedObject& operator=(const DerivedObject& src) = delete;
+
+  DerivedObject(DerivedObject&& src) noexcept : Glib::Object(std::move(src)), i_(std::move(src.i_))
+  {
+  }
+
+  DerivedObject& operator=(DerivedObject&& src) noexcept
+  {
+    Glib::Object::operator=(std::move(src));
+    i_ = std::move(src.i_);
+
+    return *this;
+  }
+
+  int i_;
+};
+
 static void
 test_object_move_constructor()
 {
diff --git a/tests/glibmm_objectbase/main.cc b/tests/glibmm_objectbase/main.cc
deleted file mode 100644 (file)
index 9ccf52e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "test_derived_objectbase.h"
-#include "../glibmm_object/test_derived_object.h"
-#include <glibmm.h>
-#include <iostream>
-#include <stdlib.h>
-
-static void
-test_objectbase()
-{
-  GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr));
-  DerivedObjectBase derived(gobject, 5);
-  // std::cout << "debug: gobj(): " << derived.gobj() << std::endl;
-  g_assert(derived.gobj() == gobject);
-}
-
-int
-main(int, char**)
-{
-  Glib::init();
-
-  test_objectbase();
-
-  return EXIT_SUCCESS;
-}
diff --git a/tests/glibmm_objectbase/test_derived_objectbase.h b/tests/glibmm_objectbase/test_derived_objectbase.h
deleted file mode 100644 (file)
index a4a509a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _GLIBMM_TEST_DERIVED_OBJECTBASE_H
-#define _GLIBMM_TEST_DERIVED_OBJECTBASE_H
-
-#include <glibmm.h>
-
-class DerivedObjectBase : public Glib::ObjectBase
-{
-public:
-  // A real application would never make the constructor public.
-  // It would instead have a protected constructor and a public create() method.
-  DerivedObjectBase(GObject* gobject, int i) : Glib::ObjectBase(nullptr), i_(i)
-  {
-    Glib::ObjectBase::initialize(gobject);
-  }
-
-  DerivedObjectBase(const DerivedObjectBase& src) = delete;
-  DerivedObjectBase& operator=(const DerivedObjectBase& src) = delete;
-
-  DerivedObjectBase(DerivedObjectBase&& src) noexcept : Glib::ObjectBase(std::move(src)),
-                                                        i_(std::move(src.i_))
-  {
-    ObjectBase::initialize_move(src.gobject_, &src);
-  }
-
-  DerivedObjectBase& operator=(DerivedObjectBase&& src) noexcept
-  {
-    Glib::ObjectBase::operator=(std::move(src));
-    i_ = std::move(src.i_);
-
-    return *this;
-  }
-
-  int i_;
-};
-
-#endif // _GLIBMM_TEST_DERIVED_OBJECTBASE_H
index 79bab6a..697f3cf 100644 (file)
@@ -1,9 +1,66 @@
-#include "../glibmm_objectbase/test_derived_objectbase.h"
-#include "../glibmm_object/test_derived_object.h"
 #include <glibmm.h>
 #include <iostream>
 #include <stdlib.h>
 
+// A basic derived GObject, just to test Glib::ObjectBase.
+typedef struct
+{
+  GObject parent;
+} TestDerived;
+
+typedef struct
+{
+  GObjectClass parent;
+} TestDerivedClass;
+
+#define TEST_TYPE_DERIVED (test_derived_get_type())
+#define TEST_DERIVED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_DERIVED, TestDerived))
+#define TEST_DERIVED_CLASS(cls) \
+  (G_TYPE_CHECK_CLASS_CAST((cls), TEST_TYPE_DERIVED, TestDerivedClass))
+#define TEST_DERIVED_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_DERIVED, TestDerivedClass))
+
+static void
+test_derived_class_init(TestDerivedClass*)
+{
+}
+static void
+test_derived_init(TestDerived*)
+{
+}
+
+G_DEFINE_TYPE(TestDerived, test_derived, G_TYPE_OBJECT)
+
+class DerivedObjectBase : public Glib::ObjectBase
+{
+public:
+  // A real application would never make the constructor public.
+  // It would instead have a protected constructor and a public create() method.
+  DerivedObjectBase(GObject* gobject, int i) : Glib::ObjectBase(nullptr), i_(i)
+  {
+    Glib::ObjectBase::initialize(gobject);
+  }
+
+  DerivedObjectBase(const DerivedObjectBase& src) = delete;
+  DerivedObjectBase& operator=(const DerivedObjectBase& src) = delete;
+
+  DerivedObjectBase(DerivedObjectBase&& src) noexcept : Glib::ObjectBase(std::move(src)),
+                                                        i_(std::move(src.i_))
+  {
+    ObjectBase::initialize_move(src.gobject_, &src);
+  }
+
+  DerivedObjectBase& operator=(DerivedObjectBase&& src) noexcept
+  {
+    Glib::ObjectBase::operator=(std::move(src));
+    i_ = std::move(src.i_);
+
+    return *this;
+  }
+
+  int i_;
+};
+
 static void
 test_objectbase_move_constructor()
 {
index 050db35..4caea0c 100644 (file)
@@ -91,6 +91,11 @@ test_initial_refcount()
   Glib::RefPtr<Something> refSomething(new Something());
   g_assert_cmpint(refSomething->ref_count(), ==, 1);
   g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+
+  // Test the get() method:
+  g_assert_cmpint(refSomething.get()->ref_count(), ==, 1);
+  refSomething.reset();
+  g_assert(refSomething.get() == nullptr);
 }
 
 static void
@@ -101,18 +106,16 @@ test_refptr_copy_constructor()
   g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
 
   {
-    //The reference count should not change,
-    //because we only take and release a single reference:
     Glib::RefPtr<Something> refSomething2(refSomething);
-    g_assert_cmpint(refSomething->ref_count(), ==, 1);
-    g_assert_cmpint(refSomething2->ref_count(), ==, 1);
-    g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+    g_assert_cmpint(refSomething->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
   }
 
   // Test the refcount after other references should have been released
   // when other RefPtrs went out of scope:
   g_assert_cmpint(refSomething->ref_count(), ==, 1);
-  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
 }
 
 static void
@@ -123,18 +126,16 @@ test_refptr_assignment_operator()
   g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
 
   {
-    //The reference count should not change,
-    //because we only take and release a single reference:
     Glib::RefPtr<Something> refSomething2 = refSomething;
-    g_assert_cmpint(refSomething->ref_count(), ==, 1);
-    g_assert_cmpint(refSomething2->ref_count(), ==, 1);
-    g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+    g_assert_cmpint(refSomething->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
   }
 
   // Test the refcount after other references should have been released
   // when other RefPtrs went out of scope:
   g_assert_cmpint(refSomething->ref_count(), ==, 1);
-  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
 }
 
 static Glib::RefPtr<Something>
@@ -143,7 +144,7 @@ get_something()
   static Glib::RefPtr<Something> something_to_get;
 
   // Reinitialize it each time:
-  something_to_get = Glib::make_refptr_for_instance<Something>(new Something());
+  something_to_get = Glib::RefPtr<Something>(new Something());
 
   return something_to_get;
 }
@@ -152,25 +153,23 @@ static void
 test_refptr_with_parent_copy_constructor()
 {
   // We use get_something() because test_refptr_with_parent_move_constructor() does.
-  //The reference count should not change,
-  //because we only take and release a single reference:
   Glib::RefPtr<Something> refSomething = get_something();
-  g_assert_cmpint(refSomething->ref_count(), ==, 1);
-  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->ref_count(), ==, 2); // 1 here and 1 inside get_something()
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
 
   {
     Parent parent(refSomething);
     g_assert(!parent.was_constructed_via_move_constructor());
     g_assert(parent.was_constructed_via_copy_constructor());
     g_assert_cmpint(
-      parent.something_ref_count(), ==, 1);
-    g_assert_cmpint(parent.something_max_ref_count(), ==, 1);
+      parent.something_ref_count(), ==, 3); // 1 here, 1 in parent, and 1 inside get_something()
+    g_assert_cmpint(parent.something_max_ref_count(), ==, 3);
   }
 
   // Test the refcount after other references should have been released
   // when other RefPtrs went out of scope:
-  g_assert_cmpint(refSomething->ref_count(), ==, 1);
-  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->ref_count(), ==, 2); // 1 here and 1 inside get_something()
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 3);
 }
 
 static void
@@ -179,8 +178,8 @@ test_refptr_with_parent_move_constructor()
   Parent parent(get_something());
   g_assert(parent.was_constructed_via_move_constructor());
   g_assert(!parent.was_constructed_via_copy_constructor());
-  g_assert_cmpint(parent.something_ref_count(), ==, 1);
-  g_assert_cmpint(parent.something_max_ref_count(), ==, 1);
+  g_assert_cmpint(parent.something_ref_count(), ==, 2); // 1 in parent and 1 inside get_something()
+  g_assert_cmpint(parent.something_max_ref_count(), ==, 2);
 }
 
 static void
index 62a39ba..0925f84 100644 (file)
@@ -1,15 +1,10 @@
 #include <glibmm.h>
 
-#include <iomanip>
 #include <iostream>
 
 int
 main(int, char**)
 {
-  // Don't use the user's preferred locale. The decimal delimiter may be ','
-  // instead of the expected '.'.
-  Glib::set_init_to_users_preferred_locale(false);
-
   Glib::init();
 
   char carr[10] = "Užduotys";
@@ -32,26 +27,5 @@ main(int, char**)
   // This threw an exception before we added a ustring::FormatStream::stream(char*) overload.
   Glib::ustring::format(cptr);
 
-  // Test substitution of various types and I/O manipulators
-  Glib::ustring expected("The meaning of life is 42, or with 2 decimal places, 42.00.");
-  auto the = "The";
-  std::string meaning("meaning");
-  Glib::ustring life("life");
-  auto number = 42.0;
-  auto places = 2;
-  auto actual = Glib::ustring::format(the, ' ', meaning, " of ", life, " is ",
-                                      number,
-                                      ", or with ", places, " decimal places, ",
-                                      std::fixed, std::setprecision(places), number,
-                                      '.');
-
-  if (actual != expected)
-  {
-    std::cerr << "expected (" << expected.size() << "):\n" << expected << "\n\n"
-              << "actual   (" << actual  .size() << "):\n" << actual   << "\n";
-
-    return EXIT_FAILURE;
-  }
-
   return EXIT_SUCCESS;
 }
index 232be15..cfa2755 100644 (file)
@@ -27,10 +27,6 @@ test(const Glib::ustring& expected, const Glib::ustring& fmt, const Ts&... ts)
 int
 main(int, char**)
 {
-  // Don't use the user's preferred locale. The decimal delimiter may be ','
-  // instead of the expected '.'.
-  Glib::set_init_to_users_preferred_locale(false);
-
   Glib::init();
 
   test("No formatting here, just a boring string",
diff --git a/tests/glibmm_value/glibmm_value.cc b/tests/glibmm_value/glibmm_value.cc
new file mode 100644 (file)
index 0000000..1f598a3
--- /dev/null
@@ -0,0 +1,32 @@
+
+#include <glibmm.h>
+
+struct Foo
+{
+  int bar;
+};
+
+namespace Gtk
+{
+class Widget;
+}
+
+void
+some_method()
+{
+  // custom copyable
+  Glib::Value<Foo> value_foo;
+
+  // custom pointer
+  Glib::Value<Foo*> value_foo_pointer;
+  Glib::Value<const Foo*> value_foo_const_pointer;
+
+  // Glib::Object pointer
+  Glib::Value<Gtk::Widget*> value_widget_pointer;
+  Glib::Value<const Gtk::Widget*> value_widget_const_pointer;
+}
+
+// Glib::Object RefPtr<>
+
+// template Glib::Value< Glib::RefPtr<Gdk::Pixbuf> >;
+// template Glib::Value< Glib::RefPtr<const Gdk::Pixbuf> >;
index a824f94..7682ffd 100644 (file)
@@ -1,156 +1,8 @@
-#include "../glibmm_object/test_derived_object.h"
-#include <glibmm.h>
-#include <cassert>
-
-struct Foo
-{
-  int bar = 1;
-};
-
-namespace Gtk
-{
-
-class Widget {
-};
 
-}
+#include <glibmm.h>
 
-void
-test()
+int
+main(int, char**)
 {
-  {
-    Foo foo;
-
-    // custom copyable
-    Glib::Value<Foo> value;
-    value.init(Glib::Value<Foo>::value_type()); // TODO: Avoid this step?
-    value.set(foo);
-
-    const auto v = value.get();
-    assert(v.bar == 1);
-  }
-
-  {
-    Foo foo;
-
-    // custom pointer
-    Glib::Value<Foo*> value;
-    value.init(Glib::Value<Foo*>::value_type()); // TODO: Avoid this step?
-    value.set(&foo);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    Foo foo;
-
-    Glib::Value<const Foo*> value;
-    value.init(Glib::Value<const Foo*>::value_type()); // TODO: Avoid this step?
-    value.set(&foo);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    Gtk::Widget widget;
-
-    // Glib::Object pointer
-    Glib::Value<Gtk::Widget*> value;
-    value.init(Glib::Value<Gtk::Widget*>::value_type()); // TODO: Avoid this step?
-    value.set(&widget);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    Gtk::Widget widget;
-
-    Glib::Value<const Gtk::Widget*> value;
-    value.init(Glib::Value<const Gtk::Widget*>::value_type()); // TODO: Avoid this step?
-    value.set(&widget);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  Glib::init();
-
-  // TODO: Put this test, of internal stuff, somewhere else.
-  static_assert(Glib::Traits::HasGetBaseType<DerivedObject, GType()>::value,
-    "DerivedObject has no get_base_type().");
-
-  // RefPtr to Glib::ObjectBase-derived type:
-  {
-    GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr));
-    auto derived = Glib::make_refptr_for_instance(new DerivedObject(gobject, 5));
-
-    using ValueType = Glib::Value<Glib::RefPtr<DerivedObject>>;
-    ValueType value;
-    value.init(ValueType::value_type()); // TODO: Avoid this step?
-
-    // Check that value_type() returns the type of the underlying GObjectBase,
-    // not a custom GType for the Glib::RefPtr:
-    assert(ValueType::value_type() == DerivedObject::get_base_type());
-
-    value.set(derived);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr));
-    auto derived = Glib::make_refptr_for_instance(new DerivedObject(gobject, 5));
-
-    using ValueType = Glib::Value<Glib::RefPtr<const DerivedObject>>;
-    ValueType value;
-    value.init(ValueType::value_type()); // TODO: Avoid this step?
-
-    // Check that value_type() returns the type of the underlying GObjectBase,
-    // not a custom GType for the Glib::RefPtr:
-    assert(ValueType::value_type() == DerivedObject::get_base_type());
-
-    value.set(derived);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    auto foo = std::make_shared<Foo>();
-
-    // custom pointer
-    Glib::Value<std::shared_ptr<Foo>> value;
-    value.init(Glib::Value<std::shared_ptr<Foo>>::value_type()); // TODO: Avoid this step?
-    value.set(foo);
-
-    const auto v = value.get();
-    assert(v);
-  }
-
-  {
-    auto foo = std::make_shared<Foo>();
-
-    Glib::Value<std::shared_ptr<const Foo>> value;
-    value.init(Glib::Value<std::shared_ptr<const Foo>>::value_type()); // TODO: Avoid this step?
-    value.set(foo);
-
-    const auto v = value.get();
-    assert(v);
-  }
-}
-
-// Glib::Object RefPtr<>
-
-// template Glib::Value< Glib::RefPtr<Gdk::Pixbuf> >;
-// template Glib::Value< Glib::RefPtr<const Gdk::Pixbuf> >;
-//
-
-int main() {
-  test();
-
   return EXIT_SUCCESS;
 }
diff --git a/tests/glibmm_valuearray/main.cc b/tests/glibmm_valuearray/main.cc
new file mode 100644 (file)
index 0000000..b9fc12a
--- /dev/null
@@ -0,0 +1,102 @@
+// Glib::ValueArray is deprecated, but let's keep the test.
+// The recommended replacement is std::vector<> which requires no test here.
+#undef GLIBMM_DISABLE_DEPRECATED
+
+#include <glibmm.h>
+#include <iostream>
+
+#ifdef GLIBMM_DISABLE_DEPRECATED
+int
+main(int, char**)
+{
+  // If glibmm is configured with --disable-deprecated-api, GLIBMM_DISABLE_DEPRECATED
+  // is defined in glibmm.h (actually in glibmmconfig.h). The undef at the start of
+  // this file has no effect.
+  return 77; // Tell automake's test harness to skip this test.
+}
+
+#else
+
+// Use this line if you want debug output:
+// std::ostream& ostr = std::cout;
+
+// This seems nicer and more useful than putting an ifdef around the use of ostr:
+std::stringstream debug;
+std::ostream& ostr = debug;
+
+int
+on_compare(const Glib::ValueBase& v1, const Glib::ValueBase& v2)
+{
+  const Glib::Value<int>& intVal1 = static_cast<const Glib::Value<int>&>(v1);
+  const Glib::Value<int>& intVal2 = static_cast<const Glib::Value<int>&>(v2);
+
+  int int1 = intVal1.get();
+  int int2 = intVal2.get();
+
+  if (int1 < int2)
+    return -1;
+  else if (int1 == int2)
+    return EXIT_SUCCESS;
+  else
+    return 1;
+}
+
+int
+main(int, char**)
+{
+  const int VALUES_COUNT = 10;
+
+  Glib::init();
+
+  Glib::Value<int> values[VALUES_COUNT];
+  Glib::ValueArray array;
+
+  for (int i = 0; i < VALUES_COUNT; i++)
+  {
+    values[i].init(Glib::Value<int>::value_type());
+    values[i].set(i + 1); //  (i + 1) ==> Set to natural counting numbers.
+    array.prepend(values[i]);
+  }
+
+  ostr << "Array members before sorting:" << std::endl;
+
+  for (int i = 0; i < VALUES_COUNT; i++)
+  {
+    Glib::ValueBase value;
+
+    if (!array.get_nth(i, value))
+    {
+      std::cerr << "Error getting element " << i << " of value array." << std::endl;
+      return EXIT_FAILURE;
+      break;
+    }
+
+    auto int_val = static_cast<Glib::Value<int>&>(value);
+    ostr << int_val.get() << " ";
+  }
+  ostr << std::endl; // End of line for list of array elements.
+
+  // Sort array and remove last element:
+  array.sort(sigc::ptr_fun(&on_compare)).remove(VALUES_COUNT - 1);
+
+  ostr << "Array members after sorting without last element:" << std::endl;
+
+  for (int i = 0; i < VALUES_COUNT - 1; i++)
+  {
+    Glib::ValueBase value;
+
+    if (!array.get_nth(i, value))
+    {
+      std::cerr << "Error getting element " << i << " of value array." << std::endl;
+      return EXIT_FAILURE;
+      break;
+    }
+
+    auto int_val = static_cast<Glib::Value<int>&>(value);
+    ostr << int_val.get() << " ";
+  }
+  ostr << std::endl; // End of line for list of array elements.
+
+  return EXIT_SUCCESS;
+}
+#endif // GLIBMM_DISABLE_DEPRECATED
index f3d4e26..8c521f9 100644 (file)
@@ -57,16 +57,26 @@ bool test_tuple()
   ostr << "Index of first map entry: " << child0.first << std::endl;
   result_ok &= child0.first == 4;
   auto extracted_tuple = child0.second;
+#if __cplusplus > 201103L // C++14 or higher
   auto q3 = std::get<guint16>(extracted_tuple);
   auto s3 = std::get<Glib::ustring>(extracted_tuple);
   auto b3 = std::get<bool>(extracted_tuple);
+#else // C++11
+  auto q3 = std::get<0>(extracted_tuple);
+  auto s3 = std::get<1>(extracted_tuple);
+  auto b3 = std::get<2>(extracted_tuple);
+#endif
   ostr << "Extracted tuple1 from map: (" << q3 << ", " << s3 << ", " << b3 << ")" << std::endl;
   result_ok &= q3 == q1 && s3 == s1 && b3 == b1;
 
   // Extract from a tuple.
   auto q4 = tuple2_variant.get_child<guint16>(0);
   auto s4 = tuple2_variant.get_child_variant<Glib::ustring>(1).get();
+#if __cplusplus > 201103L // C++14 or higher
   auto b4 = std::get<bool>(tuple2_variant.get());
+#else // C++11
+  auto b4 = std::get<2>(tuple2_variant.get());
+#endif
   ostr << "Extracted tuple2: (" << q4 << ", " << s4 << ", " << b4 << ")" << std::endl;
   result_ok &= q4 == q2 && s4 == s2 && b4 == b2;
 
@@ -120,38 +130,6 @@ bool test_object_path()
   return result_ok;
 }
 
-bool test_comparison()
-{
-  bool result_ok = true;
-
-  std::vector<int> int_vector1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
-  std::vector<int> int_vector2 = { 1, 2, 3, 4, 5, 6, 7 };
-
-  auto int_variant1 = Glib::Variant<std::vector<int>>::create(int_vector1);
-  auto int_variant2 = Glib::Variant<std::vector<int>>::create(int_vector2);
-  auto int_variant3 = Glib::Variant<std::vector<int>>::create(int_vector1);
-
-  // Equality and inequality operators
-  ostr << "int_variant1 == int_variant2 (0): " << (int_variant1 == int_variant2) << std::endl;
-  result_ok &= !(int_variant1 == int_variant2);
-  ostr << "int_variant1 != int_variant2 (1): " << (int_variant1 != int_variant2) << std::endl;
-  result_ok &= (int_variant1 != int_variant2);
-
-  ostr << "int_variant1 == int_variant3 (1): " << (int_variant1 == int_variant3) << std::endl;
-  result_ok &= (int_variant1 == int_variant3);
-  ostr << "int_variant1 != int_variant3 (0): " << (int_variant1 != int_variant3) << std::endl;
-  result_ok &= !(int_variant1 != int_variant3);
-
-#if 0
-  // Less than (activate if operator<() exists)
-  ostr << "int_variant2 < int_variant1 (1): " << (int_variant2 < int_variant1) << std::endl;
-  result_ok &= (int_variant2 < int_variant1);
-  ostr << "int_variant1 < int_variant3 (0): " << (int_variant1 < int_variant3) << std::endl;
-  result_ok &= !(int_variant1 < int_variant3);
-#endif
-  return result_ok;
-}
-
 } // anonymous namespace
 
 int
@@ -308,7 +286,6 @@ main(int, char**)
 
   bool result_ok = test_tuple();
   result_ok &= test_object_path();
-  result_ok &= test_comparison();
   return result_ok ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
@@ -547,7 +524,7 @@ get_log_flags()
 
 struct WarnCatcher
 {
-  explicit WarnCatcher(const std::string& domain)
+  WarnCatcher(const std::string& domain)
   : m_domain(domain), m_old_flags(g_log_set_fatal_mask(m_domain.c_str(), get_log_flags()))
   {
   }
diff --git a/tests/glibmm_weakref/main.cc b/tests/glibmm_weakref/main.cc
new file mode 100644 (file)
index 0000000..20a8031
--- /dev/null
@@ -0,0 +1,174 @@
+/* Copyright (C) 2015 The glibmm 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstring>
+#include <giomm.h> //There is no class derived from Glib::Object in glibmm
+#include <glibmm.h>
+#include <iostream>
+#include <utility> // std::move
+
+int
+main(int, char**)
+{
+  Glib::init();
+  bool success = true;
+
+  // A Glib::WeakRef cannot be created from a Glib::RefPtr<Glib::Bytes>,
+  // because Glib::Bytes is not derived from Glib::ObjectBase.
+  // const int bdata = 1234;
+  // Glib::RefPtr<Glib::Bytes> bytes = Glib::Bytes::create(&bdata, sizeof bdata);
+  // Glib::WeakRef<Glib::Bytes> weakbytes = bytes; // does not compile
+
+  // Gio::MemoryInputStream
+  Glib::RefPtr<Gio::MemoryInputStream> memstream1 = Gio::MemoryInputStream::create();
+  const char data[] = "Some arbitrary data";
+  memstream1->add_data(data, sizeof data, Gio::MemoryInputStream::SlotDestroyData());
+
+  // Downcast copy, followed by upcast.
+  Glib::WeakRef<Gio::MemoryInputStream> weakmemstream1 = memstream1;
+  Glib::WeakRef<Gio::InputStream> weakstream1 = weakmemstream1;
+  Glib::WeakRef<Gio::MemoryInputStream> weakmemstream2 =
+    Glib::WeakRef<Gio::MemoryInputStream>::cast_dynamic(weakstream1);
+  Glib::RefPtr<Gio::MemoryInputStream> memstream2 = weakmemstream2.get();
+  if (memstream2)
+  {
+    char buffer[200];
+    gsize bytes_read = 0;
+    try
+    {
+      memstream2->read_all(buffer, sizeof buffer, bytes_read);
+      std::cout << buffer << std::endl;
+      success &= std::strcmp(buffer, data) == 0;
+    }
+    catch (const Glib::Error& ex)
+    {
+      std::cout << "Error reading from memory stream: " << ex.what() << std::endl;
+      success = false;
+    }
+  }
+  else
+  {
+    std::cout << "!memstream2" << std::endl;
+    success = false;
+  }
+
+  // Move construction.
+  Glib::WeakRef<Gio::MemoryInputStream> weakmemstream3(std::move(weakmemstream1));
+  if (weakmemstream1.get() || !weakmemstream3.get())
+  {
+    success = false;
+    if (weakmemstream1.get())
+      std::cout << "weakmemstream1 || !weakmemstream3: weakmemstream1" << std::endl;
+    if (!weakmemstream3.get())
+      std::cout << "weakmemstream1 || !weakmemstream3: !weakmemstream3" << std::endl;
+  }
+  else
+  {
+    // Move assignment.
+    weakmemstream2 = std::move(weakmemstream3);
+    if (!weakmemstream2 || weakmemstream3)
+    {
+      success = false;
+      if (!weakmemstream2.get())
+        std::cout << "!weakmemstream2 || weakmemstream3: !weakmemstream2" << std::endl;
+      if (weakmemstream3.get())
+        std::cout << "!weakmemstream2 || weakmemstream3: weakmemstream3" << std::endl;
+    }
+    else
+    {
+      // Downcast move, followed by upcast.
+      weakstream1 = std::move(weakmemstream2);
+      weakmemstream1 = Glib::WeakRef<Gio::MemoryInputStream>::cast_dynamic(weakstream1);
+      if (weakmemstream2 || !weakmemstream1)
+      {
+        success = false;
+        if (weakmemstream2)
+          std::cout << "weakmemstream2 || !weakmemstream1: weakmemstream2" << std::endl;
+        if (!weakmemstream1)
+          std::cout << "weakmemstream2 || !weakmemstream1: !weakmemstream1" << std::endl;
+      }
+    }
+  }
+
+  // Gio::SimpleAction
+  Glib::RefPtr<Gio::SimpleAction> action1 = Gio::SimpleAction::create("Action1");
+
+  Glib::ustring name = action1->get_name();
+  std::cout << "The name is '" << name << "'." << std::endl;
+  success &= name == "Action1";
+
+  Glib::WeakRef<Gio::SimpleAction> weakaction1 = action1;
+  Glib::WeakRef<Gio::SimpleAction> weakaction2 = weakaction1;
+
+  // A second RefPtr
+  Glib::RefPtr<Gio::SimpleAction> action2 = weakaction1.get();
+  if (action2)
+  {
+    name = action2->get_name();
+    std::cout << "The name is '" << name << "'." << std::endl;
+    success &= name == "Action1";
+  }
+  else
+  {
+    std::cout << "!action2" << std::endl;
+    success = false;
+  }
+
+  weakaction1.reset();
+  if (weakaction1.get())
+  {
+    std::cout << "weakaction1" << std::endl;
+    success = false;
+  }
+
+  action2 = weakaction2.get();
+  if (action2)
+  {
+    name = action2->get_name();
+    std::cout << "The name is '" << name << "'." << std::endl;
+    success &= name == "Action1";
+  }
+  else
+  {
+    std::cout << "!action2" << std::endl;
+    success = false;
+  }
+
+  // Reset one of the RefPtrs. One remains.
+  action1.reset();
+  action2 = weakaction2.get();
+  if (action2)
+  {
+    name = action2->get_name();
+    std::cout << "The name is '" << name << "'." << std::endl;
+    success &= name == "Action1";
+  }
+  else
+  {
+    std::cout << "!action2" << std::endl;
+    success = false;
+  }
+
+  // Reset the other RefPtr as well.
+  action2.reset();
+  if (weakaction2.get())
+  {
+    std::cout << "weakaction2" << std::endl;
+    success = false;
+  }
+
+  return success ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644 (file)
index 0000000..4b7c5de
--- /dev/null
@@ -0,0 +1,63 @@
+# tests
+
+# input: glibmm_dep, giomm_dep
+
+test_programs = [
+# [[dir-name], exe-name, [sources], giomm-example (not just glibmm-example)]
+  [['giomm_asyncresult_sourceobject'], 'test', ['main.cc'], true],
+  [['giomm_ioerror'], 'test', ['main.cc'], true],
+  [['giomm_ioerror_and_iodbuserror'], 'test', ['main.cc'], true],
+  [['giomm_listmodel'], 'test', ['main.cc'], true],
+  [['giomm_memoryinputstream'], 'test', ['main.cc'], true],
+  [['giomm_simple'], 'test', ['main.cc'], true],
+  [['giomm_tls_client'], 'test', ['main.cc'], true],
+  [['glibmm_base64'], 'test', ['main.cc'], false],
+  [['glibmm_binding'], 'test', ['main.cc'], false],
+  [['glibmm_bool_arrayhandle'], 'test', ['main.cc'], false],
+  [['glibmm_bool_vector'], 'test', ['main.cc'], false],
+  [['glibmm_btree'], 'test', ['main.cc'], false],
+  [['glibmm_buildfilename'], 'test', ['main.cc'], false],
+  [['glibmm_bytearray'], 'test', ['main.cc'], false],
+  [['glibmm_date'], 'test', ['main.cc'], false],
+  [['glibmm_interface_implementation'], 'test', ['main.cc'], true],
+  [['glibmm_interface_move'], 'test', ['main.cc'], false],
+  [['glibmm_mainloop'], 'test', ['main.cc'], false],
+  [['glibmm_nodetree'], 'test', ['main.cc'], false],
+  [['glibmm_null_containerhandle'], 'test', ['main.cc'], true],
+  [['glibmm_null_vectorutils'], 'test', ['main.cc'], true],
+  [['glibmm_object_move'], 'test', ['main.cc'], false],
+  [['glibmm_objectbase_move'], 'test', ['main.cc'], false],
+  [['glibmm_refptr'], 'test', ['main.cc'], false],
+  [['glibmm_refptr_sigc_bind'], 'test', ['main.cc'], false],
+  [['glibmm_ustring_compose'], 'test', ['main.cc'], false],
+  [['glibmm_ustring_format'], 'test', ['main.cc'], false],
+  [['glibmm_ustring_make_valid'], 'test', ['main.cc'], false],
+  [['glibmm_ustring_sprintf'], 'test', ['main.cc'], false],
+  [['glibmm_value'], 'test', ['main.cc'], false],
+  [['glibmm_valuearray'], 'test', ['main.cc'], false],
+  [['glibmm_variant'], 'test', ['main.cc'], false],
+  [['glibmm_vector'], 'test', ['main.cc'], true],
+  [['glibmm_weakref'], 'test', ['main.cc'], true],
+]
+
+foreach ex : test_programs
+  dir = ''
+  foreach dir_part : ex[0]
+    dir = dir / dir_part
+  endforeach
+  ex_name = (dir / ex[1]).underscorify()
+  ex_sources = []
+  foreach src : ex[2]
+    ex_sources += dir / src
+  endforeach
+
+  exe_file = executable(ex_name, ex_sources,
+    cpp_args: ['-DGLIBMM_DISABLE_DEPRECATED', '-DGIOMM_DISABLE_DEPRECATED'],
+    dependencies: ex[3] ? giomm_dep : glibmm_dep,
+    gui_app: false,
+    build_by_default: true,
+    install: false,
+  )
+
+  test(ex_name, exe_file)
+endforeach
index f304ee8..af53de8 100644 (file)
@@ -34,16 +34,16 @@ dist_noinst_DATA    = README TODO
 dist_noinst_SCRIPTS = enum.pl
 
 noinst_PROGRAMS = extra_defs_gen/generate_defs_glib extra_defs_gen/generate_defs_gio
-lib_LTLIBRARIES = extra_defs_gen/libglibmm_generate_extra_defs-2.64.la
+lib_LTLIBRARIES = extra_defs_gen/libglibmm_generate_extra_defs-2.4.la
 
 extradefs_includedir      = $(includedir)/$(GLIBMM_MODULE_NAME)/glibmm_generate_extra_defs
 extradefs_include_HEADERS = extra_defs_gen/generate_extra_defs.h
 
 extradefs_ldflags = -no-undefined -version-info $(LIBGLIBMM_SO_VERSION)
 
-extra_defs_gen_libglibmm_generate_extra_defs_2_64_la_SOURCES = extra_defs_gen/generate_extra_defs.cc
-extra_defs_gen_libglibmm_generate_extra_defs_2_64_la_LDFLAGS = $(extradefs_ldflags)
-extra_defs_gen_libglibmm_generate_extra_defs_2_64_la_LIBADD  = $(GLIBMM_LIBS)
+extra_defs_gen_libglibmm_generate_extra_defs_2_4_la_SOURCES = extra_defs_gen/generate_extra_defs.cc
+extra_defs_gen_libglibmm_generate_extra_defs_2_4_la_LDFLAGS = $(extradefs_ldflags)
+extra_defs_gen_libglibmm_generate_extra_defs_2_4_la_LIBADD  = $(GLIBMM_LIBS)
 
 extra_defs_gen_generate_defs_glib_SOURCES = extra_defs_gen/generate_defs_glib.cc
 extra_defs_gen_generate_defs_glib_LDADD   = $(GLIBMM_LIBS) $(lib_LTLIBRARIES)
diff --git a/tools/build_scripts/compile-schemas.py b/tools/build_scripts/compile-schemas.py
new file mode 100755 (executable)
index 0000000..e0136e3
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+# External command, intended to be called with custom_target() in meson.build
+
+#                      argv[1]      argv[2]       argv[3]
+# compile-schemas.py <schema_dir> <target_dir> <output_file>
+
+import os
+import sys
+import subprocess
+import shutil
+
+schema_dir = sys.argv[1]
+target_dir = sys.argv[2]
+output_file = sys.argv[3]
+
+# Create the target directory, if it does not exist.
+os.makedirs(target_dir, exist_ok=True)
+
+cmd = [
+  'glib-compile-schemas',
+  '--strict',
+  '--targetdir=' + target_dir,
+  schema_dir,
+]
+
+result = subprocess.run(cmd)
+if result.returncode == 0:
+  shutil.copy(os.path.join(target_dir, 'gschemas.compiled'), output_file)
+sys.exit(result.returncode)
diff --git a/tools/build_scripts/dummy-header.py b/tools/build_scripts/dummy-header.py
new file mode 100755 (executable)
index 0000000..8c61464
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+# External command, intended to be called with custom_target() in meson.build.
+
+# dummy-header.py <output_file>
+
+import os
+import sys
+
+output_file = sys.argv[1]
+
+# A dummy header file is created if it does not exist, but it's never updated.
+if not os.path.isfile(output_file):
+  with open(output_file, 'w') as f:
+    f.write('// Dummy header file. Created and used by meson.build\n')
diff --git a/tools/build_scripts/handle-built-files.py b/tools/build_scripts/handle-built-files.py
new file mode 100755 (executable)
index 0000000..1b23f16
--- /dev/null
@@ -0,0 +1,182 @@
+#!/usr/bin/env python3
+
+# External command, intended to be called with run_command(), custom_target(),
+# meson.add_install_script() and meson.add_dist_script().
+
+#                         argv[1]   argv[2:]
+# handle-built-files.py <subcommand> <xxx>...
+
+import os
+import sys
+import shutil
+import subprocess
+from pathlib import Path
+
+subcommand = sys.argv[1]
+
+# Invoked from custom_target() in meson.build.
+# This is similar to gmmproc() in mm-common's generate-binding.py.
+# It's slightly different because glibmm uses its uninstalled gmmproc.
+def gmmproc():
+  #  argv[2]       argv[3]    argv[4]       argv[5]      argv[6]   argv[7:]
+  # <gmmproc_dir> <pm_dir> <output_file> <basefilename> <src_dir> <m4_dirs>...
+
+  # <gmmproc_dir> is an absolute path in the build directory.
+  # <pm_dir> is an absolute path in the source directory.
+  # <output_file> is a relative or absolute path in the build directory.
+  # <src_dir> is an absolute path in the source directory.
+  # <m4_dirs> are absolute paths in the source directory.
+  gmmproc_dir = sys.argv[2]
+  pm_dir = sys.argv[3]
+  output_file = sys.argv[4]
+  output_dir = os.path.dirname(output_file)
+  basefilename = sys.argv[5] # name without filetype
+  src_dir = sys.argv[6]
+
+  include_m4_dirs = []
+  for dir in sys.argv[7:]:
+    include_m4_dirs += ['-I', dir]
+
+  # Create the private/ directory, if it does not exist.
+  os.makedirs(os.path.join(output_dir, 'private'), exist_ok=True)
+
+  # gmmproc generates output_dir/basefilename.cc, output_dir/basefilename.h
+  # and output_dir/private/{basefilename}_p.h
+  cmd = [
+    'perl',
+    '-I' + pm_dir,
+    '--',
+    os.path.join(gmmproc_dir, 'gmmproc'),
+  ] + include_m4_dirs + [
+    '--defs',
+    src_dir,
+    basefilename,
+    src_dir,
+    output_dir,
+  ]
+  result = subprocess.run(cmd)
+  if result.returncode:
+    return result.returncode
+
+  # gmmproc does not update the timestamps of output files that have not changed.
+  # That's by design, to avoid unnecessary recompilations.
+  # The updated timestamp of output_file shows meson that this custom_target()
+  # has been updated.
+  Path(output_file).touch(exist_ok=True)
+  return 0
+
+# Invoked from custom_target() in meson.build.
+def build_from_m4():
+  #     argv[2]      argv[3]      argv[4]
+  # <include_dir> <input_file> <output_file>
+
+  include_dir = sys.argv[2]
+  input_file = sys.argv[3]
+  output_file = sys.argv[4]
+
+  # Create the destination directory, if it does not exist.
+  output_dir = os.path.dirname(output_file)
+  os.makedirs(output_dir, exist_ok=True)
+
+  cmd = [
+    'm4',
+    '-I', include_dir,
+    input_file,
+  ]
+  output_file_obj = open(output_file, mode='w')
+  result = subprocess.run(cmd, stdout=output_file_obj)
+  output_file_obj.close()
+
+  return result.returncode
+
+# Invoked from meson.add_install_script().
+def install_built_h_files():
+  #    argv[2]       argv[3]          argv[4:]
+  # <built_h_dir> <install_subdir> <built_h_files>...
+
+  # <built_h_dir> is an absolute path in the build directory or source directory.
+  # <install_subdir> is an installation directory, relative to {prefix}.
+  built_h_dir = sys.argv[2]
+  install_dir_root = os.path.join(os.getenv('MESON_INSTALL_DESTDIR_PREFIX'), sys.argv[3])
+
+  for file in sys.argv[4:]:
+    path_h = os.path.join(built_h_dir, file)
+    rel_dir = os.path.dirname(file)
+    if rel_dir:
+      install_dir = os.path.join(install_dir_root, rel_dir)
+    else:
+      install_dir = install_dir_root
+    print('Installing ', path_h, ' to ', install_dir)
+
+    # Create the installation directory, if it does not exist.
+    os.makedirs(install_dir, exist_ok=True)
+
+    # shutil.copy2() copies timestamps and some other file metadata.
+    shutil.copy2(path_h, install_dir)
+  return 0
+
+# Invoked from meson.add_dist_script().
+def dist_built_files(is_msvc_files=False):
+  #     argv[2]        argv[3]     argv[4:]
+  # <built_h_cc_dir> <dist_dir> <built_files>...
+
+  # <built_h_cc_dir> is an absolute path in the build directory or source directory.
+  # <dist_dir> is a distribution directory, relative to MESON_DIST_ROOT.
+  built_h_cc_dir = sys.argv[2]
+  dist_dir_root = os.path.join(os.getenv('MESON_DIST_ROOT'), sys.argv[3])
+  dist_dir = dist_dir_root
+
+  # Distribute .h and .cc files built from .m4 files, or generated MSVC files.
+  for file in sys.argv[4:]:
+    if not is_msvc_files:
+      dist_dir = os.path.join(dist_dir_root, os.path.dirname(file))
+
+    # Create the distribution directory, if it does not exist.
+    os.makedirs(dist_dir, exist_ok=True)
+
+    shutil.copy(os.path.join(built_h_cc_dir, file), dist_dir)
+  return 0
+
+# Invoked from run_command() in meson.build.
+def copy_built_files():
+  #  argv[2]    argv[3]    argv[4:]
+  # <from_dir> <to_dir> <file_names>...
+
+  # <from_dir> is an absolute or relative path of the directory to copy from.
+  # <to_dir> is an absolute or relative path of the directory to copy to.
+  from_dir_root = sys.argv[2]
+  to_dir_root = sys.argv[3]
+
+  # Copy some built files if they exist in from_dir, but not in the destination
+  # directory, or if they are not up to date in the destination directory.
+  # (The term "source directory" is avoided here, because from_dir might not
+  # be what Meson calls a source directory as opposed to a build directory.)
+
+  # Copy .h and .cc files built from .m4 files.
+  for file in sys.argv[4:]:
+    from_file = os.path.join(from_dir_root, file)
+    to_file = os.path.join(to_dir_root, file)
+    if os.path.isfile(from_file) and ((not os.path.isfile(to_file))
+       or (os.stat(from_file).st_mtime > os.stat(to_file).st_mtime)):
+
+      # Create the destination directory, if it does not exist.
+      os.makedirs(os.path.dirname(to_file), exist_ok=True)
+
+      shutil.copy(from_file, to_file)
+  return 0
+
+# ----- Main -----
+if subcommand == 'gmmproc':
+  sys.exit(gmmproc())
+if subcommand == 'build_from_m4':
+  sys.exit(build_from_m4())
+if subcommand == 'install_built_h_files':
+  sys.exit(install_built_h_files())
+if subcommand == 'dist_built_files':
+  sys.exit(dist_built_files())
+if subcommand == 'copy_built_files':
+  sys.exit(copy_built_files())
+if subcommand == 'dist_gen_msvc_files':
+  sys.exit(dist_built_files(True))
+print(sys.argv[0], ': illegal subcommand,', subcommand)
+sys.exit(1)
diff --git a/tools/conf_tests/allows_static_inline_npos.cc b/tools/conf_tests/allows_static_inline_npos.cc
new file mode 100644 (file)
index 0000000..ac11b5d
--- /dev/null
@@ -0,0 +1,21 @@
+// Configuration-time test program, used in Meson build.
+// Check whether a static member variable may be initialized inline to std::string::npos.
+// The MipsPro (IRIX) compiler does not like this.
+// Corresponds to the M4 macro GLIBMM_CXX_ALLOWS_STATIC_INLINE_NPOS.
+
+#include <string>
+#include <iostream>
+
+class ustringtest
+{
+public:
+  // The MipsPro compiler (IRIX) says "The indicated constant value is not known",
+  // so we need to initialize the static member data elsewhere.
+  static const std::string::size_type ustringnpos = std::string::npos;
+};
+
+int main()
+{
+  std::cout << "npos=" << ustringtest::ustringnpos << std::endl;
+  return 0;
+}
diff --git a/tools/conf_tests/can_assign_non_extern_c_functions_to_extern_c_cb.cc b/tools/conf_tests/can_assign_non_extern_c_functions_to_extern_c_cb.cc
new file mode 100644 (file)
index 0000000..d3c937f
--- /dev/null
@@ -0,0 +1,22 @@
+// Configuration-time test program, used in Meson build.
+// Check whether the compiler allows us to use a non-extern "C" function,
+// such as a static member function, to an extern "C" function pointer,
+// such as a GTK callback.
+// Corresponds to the M4 macro GLIBMM_CXX_CAN_ASSIGN_NON_EXTERN_C_FUNCTIONS_TO_EXTERN_C_CALLBACKS.
+
+extern "C"
+{
+struct somestruct
+{
+  void (*callback) (int);
+};
+} // extern "C"
+
+void somefunction(int) {}
+
+int main()
+{
+  somestruct something;
+  something.callback = &somefunction;
+  return 0;
+}
diff --git a/tools/conf_tests/can_use_dynamic_cast_in_unused_template_wo_def.cc b/tools/conf_tests/can_use_dynamic_cast_in_unused_template_wo_def.cc
new file mode 100644 (file)
index 0000000..9620d80
--- /dev/null
@@ -0,0 +1,21 @@
+// Configuration-time test program, used in Meson build.
+// Check whether the compiler allows us to define a template that uses
+// dynamic_cast<> with an object whose type is not defined, even if we do
+// not use that template before we have defined the type. This should
+// probably not be allowed anyway.
+// Corresponds to the M4 macro GLIBMM_CXX_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION.
+
+class SomeClass;
+
+SomeClass* some_function();
+
+template <class T>
+class SomeTemplate
+{
+  static bool do_something()
+  {
+    // This does not compile with the MipsPro (IRIX) compiler
+    // even if we don't use this template at all.
+    return (dynamic_cast<T*>(some_function()) != 0);
+  }
+};
diff --git a/tools/conf_tests/can_use_namespaces_inside_externc.cc b/tools/conf_tests/can_use_namespaces_inside_externc.cc
new file mode 100644 (file)
index 0000000..6d303cf
--- /dev/null
@@ -0,0 +1,25 @@
+// Configuration-time test program, used in Meson build.
+// Check whether the compiler puts extern "C" functions in the global
+// namespace, even inside a namespace declaration. The AIX xlC compiler does
+// this, and also gets confused if we declare the namespace again inside the
+// extern "C" block.
+// Corresponds to the M4 macro GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC.
+
+namespace test
+{
+
+extern "C" { void do_something(); }
+
+class Something
+{
+  int i;
+  friend void do_something();
+};
+
+void do_something()
+{
+  Something something;
+  something.i = 1;
+}
+
+} // namespace test
diff --git a/tools/conf_tests/can_use_thread_local.cc b/tools/conf_tests/can_use_thread_local.cc
new file mode 100644 (file)
index 0000000..ee21c3c
--- /dev/null
@@ -0,0 +1,5 @@
+// Configuration-time test program, used in Meson build.
+// Check for thread_local support.
+// Corresponds to the M4 macro GLIBMM_CXX_CAN_USE_THREAD_LOCAL.
+
+thread_local int i = 0;
diff --git a/tools/conf_tests/have_disambiguous_const_template_specializations.cc b/tools/conf_tests/have_disambiguous_const_template_specializations.cc
new file mode 100644 (file)
index 0000000..3f4eaf1
--- /dev/null
@@ -0,0 +1,37 @@
+// Configuration-time test program, used in Meson build.
+// Check whether the compiler finds it ambiguous to have both const and
+// non-const template specializations. The SUN Forte compiler has this
+// problem, though we are not 100% sure that it's a C++ standard violation.
+// Corresponds to the M4 macro GLIBMM_CXX_CAN_DISAMBIGUATE_CONST_TEMPLATE_SPECIALIZATIONS.
+
+template <class T> class Foo {};
+
+template <class T> class Traits
+{
+public:
+  const char* whoami() { return "generic template"; }
+};
+
+template <class T> class Traits< Foo<T> >
+{
+public:
+  const char* whoami() { return "partial specialization for Foo<T>"; }
+};
+
+template <class T> class Traits< Foo<const T> >
+{
+public:
+  const char* whoami() { return "partial specialization for Foo<const T>"; }
+};
+
+int main()
+{
+  Traits<int> it;
+  Traits< Foo<int> > fit;
+  Traits< Foo<const int> > cfit;
+
+  (void) it.whoami();
+  (void) fit.whoami();
+  (void) cfit.whoami();
+  return 0;
+}
diff --git a/tools/conf_tests/have_std_iterator_traits.cc b/tools/conf_tests/have_std_iterator_traits.cc
new file mode 100644 (file)
index 0000000..1e1f2b0
--- /dev/null
@@ -0,0 +1,11 @@
+// Configuration-time test program, used in Meson build.
+// Check for standard-conforming std::iterator_traits<>.
+// Corresponds to the M4 macro GLIBMM_CXX_HAS_STD_ITERATOR_TRAITS.
+
+#include <iterator>
+
+int main()
+{
+  typedef std::iterator_traits<char*>::value_type ValueType;
+  return 0;
+}
diff --git a/tools/conf_tests/have_sun_reverse_iterator.cc b/tools/conf_tests/have_sun_reverse_iterator.cc
new file mode 100644 (file)
index 0000000..43721e0
--- /dev/null
@@ -0,0 +1,11 @@
+// Configuration-time test program, used in Meson build.
+// Check for Sun libCstd style std::reverse_iterator,
+// Corresponds to the M4 macro GLIBMM_CXX_HAS_SUN_REVERSE_ITERATOR.
+
+#include <iterator>
+
+int main()
+{
+  typedef std::reverse_iterator<char*, std::random_access_iterator_tag, char, char&, char*, int> ReverseIter;
+  return 0;
+}
diff --git a/tools/conf_tests/have_template_sequence_ctors.cc b/tools/conf_tests/have_template_sequence_ctors.cc
new file mode 100644 (file)
index 0000000..6423684
--- /dev/null
@@ -0,0 +1,17 @@
+// Configuration-time test program, used in Meson build.
+// Check whether the STL containers have templated sequence ctors,
+// Corresponds to the M4 macro GLIBMM_CXX_HAS_TEMPLATE_SEQUENCE_CTORS.
+
+#include <vector>
+#include <deque>
+#include <list>
+
+int main()
+{
+  const int array[8] = { 0, };
+  std::vector<int>  test_vector(&array[0], &array[8]);
+  std::deque<short> test_deque(test_vector.begin(), test_vector.end());
+  std::list<long>   test_list(test_deque.begin(),  test_deque.end());
+  test_vector.assign(test_list.begin(), test_list.end());
+  return 0;
+}
diff --git a/tools/conf_tests/have_wide_stream.cc b/tools/conf_tests/have_wide_stream.cc
new file mode 100644 (file)
index 0000000..9cfd19d
--- /dev/null
@@ -0,0 +1,12 @@
+// Configuration-time test program, used in Meson build.
+// Check whether std::wostringstream exists.
+// Corresponds to some code in configure.ac.
+
+#include <sstream>
+
+int main()
+{
+  std::wostringstream s;
+  (void) s.str();
+  return 0;
+}
diff --git a/tools/conf_tests/member_functions_member_templates.cc b/tools/conf_tests/member_functions_member_templates.cc
new file mode 100644 (file)
index 0000000..b005ad5
--- /dev/null
@@ -0,0 +1,41 @@
+// Configuration-time test program, used in Meson build.
+// Test whether the compiler allows member functions to refer to spezialized
+// member function templates.
+// Corresponds to the M4 macro GLIBMM_CXX_MEMBER_FUNCTIONS_MEMBER_TEMPLATES.
+
+struct foo
+{
+  template <class C> inline void doit();
+  void thebug();
+};
+
+template <class C>
+inline void foo::doit()
+{}
+
+struct bar
+{
+  void neitherabug();
+};
+
+void bar::neitherabug()
+{
+  void (foo::*func)();
+  func = &foo::doit<int>;
+  (void)func;
+}
+
+void foo::thebug()
+{
+  void (foo::*func)();
+  func = &foo::doit<int>; // the compiler bugs usually show here
+  (void)func;
+}
+
+int main()
+{
+  void (foo::*func)();
+  func = &foo::doit<int>;
+  (void)func;
+  return 0;
+}
diff --git a/tools/conf_tests/std_time_t_is_not_int32.cc b/tools/conf_tests/std_time_t_is_not_int32.cc
new file mode 100644 (file)
index 0000000..5dff2ab
--- /dev/null
@@ -0,0 +1,20 @@
+// Configuration-time test program, used in Meson build.
+// Test whether std::time_t and gint32 are typedefs of the same builting type.
+// If they aren't then they can be used for method overload.
+// Corresponds to the M4 macro GLIBMM_C_STD_TIME_T_IS_NOT_INT32.
+
+#include <ctime>
+
+int main()
+{
+  typedef signed int gint32;
+  class Test
+  {
+    void something(gint32 val)
+    {}
+
+    void something(std::time_t val)
+    {}
+  };
+  return 0;
+}
index 300df4c..8ad6fa7 100644 (file)
 #include <iostream>
 #include <string>
 
+#if defined (_MSC_VER) && !defined (GLIBMM_GEN_EXTRA_DEFS_STATIC)
+#if defined (GLIBMM_GEN_EXTRA_DEFS_BUILD)
+#define GLIBMM_GEN_EXTRA_DEFS_API __declspec (dllexport)
+#else
+#define GLIBMM_GEN_EXTRA_DEFS_API __declspec (dllimport)
+#endif
+#else
+#define GLIBMM_GEN_EXTRA_DEFS_API
+#endif
+
 /** Function pointer type for functions that determine if a GType is a pointer
  * type.
  */
@@ -30,21 +40,29 @@ using GTypeIsAPointerFunc = bool(*)(GType gtype);
  * @param gtype The GType.
  * @return true if the GType is a GObject or a boxed type, false otherwise.
  */
+GLIBMM_GEN_EXTRA_DEFS_API
 bool gtype_is_a_pointer(GType gtype);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_defs(GType gtype, GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_property_with_node_name(
   GParamSpec* pParamSpec, const std::string& strObjectName, const std::string& strNodeName);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_properties(GType gtype);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_type_name(GType gtype, GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_type_name_parameter(
   GType gtype, GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_type_name_signal(
   GType gtype, GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+GLIBMM_GEN_EXTRA_DEFS_API
 std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
diff --git a/tools/extra_defs_gen/meson.build b/tools/extra_defs_gen/meson.build
new file mode 100644 (file)
index 0000000..900943c
--- /dev/null
@@ -0,0 +1,26 @@
+# tools/extra_defs_gen
+
+# Input: is_msvc, glibmm_build_dep, giomm_build_dep, glibmm_api_version,
+#        glibmm_libversion
+# Output: -
+
+glibmm_generate_extra_defs_library = library(
+  'glibmm_generate_extra_defs-' + glibmm_api_version,
+  'generate_extra_defs.cc',
+  version: glibmm_libversion,
+  cpp_args: '-DGLIBMM_GEN_EXTRA_DEFS_BUILD',
+  dependencies: glibmm_build_dep,
+  install: true,
+)
+
+executable('generate_defs_glib', 'generate_defs_glib.cc',
+  dependencies: glibmm_build_dep,
+  link_with: glibmm_generate_extra_defs_library,
+  install: false,
+)
+
+executable('generate_defs_gio', 'generate_defs_gio.cc',
+  dependencies: giomm_build_dep,
+  link_with: glibmm_generate_extra_defs_library,
+  install: false,
+)
index 5ce3895..f8c0804 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# This file is part of glibmm.
+# This file is part of glibmm-2.4.
 # Initializes some variables for the scripts that generate docs and defs files.
 # Not intented to be called directly from the command line.
 
@@ -16,7 +16,7 @@
 # Usually you can leave GMMPROC_GEN_SOURCE_DIR undefined.
 # If you have set buildroot=None, GMMPROC_GEN_BUILD_DIR can also be undefined.
 
-# Root directory of glibmm source files.
+# Root directory of glibmm-2.4 source files.
 root_dir="$(dirname "$0")/../.."
 
 # Where to search for source files.
@@ -29,15 +29,15 @@ if [ -z "$GMMPROC_GEN_BUILD_DIR" ]; then
   GMMPROC_GEN_BUILD_DIR="$GMMPROC_GEN_SOURCE_DIR"
 fi
 
-# Scripts in glibmm. These are source files.
-gen_docs="$GMMPROC_GEN_SOURCE_DIR/glibmm/tools/defs_gen/docextract_to_xml.py"
-gen_methods="$GMMPROC_GEN_SOURCE_DIR/glibmm/tools/defs_gen/h2def.py"
-gen_enums="$GMMPROC_GEN_SOURCE_DIR/glibmm/tools/enum.pl"
+# Scripts in glibmm-2.4. These are source files.
+gen_docs="$GMMPROC_GEN_SOURCE_DIR/glibmm-2.4/tools/defs_gen/docextract_to_xml.py"
+gen_methods="$GMMPROC_GEN_SOURCE_DIR/glibmm-2.4/tools/defs_gen/h2def.py"
+gen_enums="$GMMPROC_GEN_SOURCE_DIR/glibmm-2.4/tools/enum.pl"
 
 # Where to find executables that generate extra defs (signals and properties).
-# glibmm is built with autotools.
+# glibmm-2.4 is built with autotools.
 # autotools support, but don't require, non-source-dir builds.
-extra_defs_gen_dir="$GMMPROC_GEN_BUILD_DIR/glibmm/tools/extra_defs_gen"
+extra_defs_gen_dir="$GMMPROC_GEN_BUILD_DIR/glibmm-2.4/tools/extra_defs_gen"
 
 source_prefix="$GMMPROC_GEN_SOURCE_DIR/glib"
 build_prefix="$GMMPROC_GEN_BUILD_DIR/glib"
index cf57347..d725b19 100644 (file)
@@ -151,14 +151,18 @@ while ($ARGV[0])
       my $basename = lc($ccast);
       my @names = ($cppname, $basename, @extra_namespace);
 
+      # Don't remove the space between \ and @. When glibmm is built with Meson,
+      # the \ would be removed in generate_wrap_int.pl.
       if ($type_of_class eq "_CLASS_GOBJECT" or
-          $type_of_class eq "_CLASS_GTKOBJECT")
+         ($type_of_class eq "_CLASS_GTKOBJECT" and
+         #TODO: Remove this hack eventually.
+         ($cname ne "GtkTree" && $cname ne "GtkTreeItem" && $cname ne "GtkText")))
       {
-        push(@{$objects{$filename_header}}, \@names);
+        push(@{$objects{$filename_header}}, \ @names);
       }
       elsif ($type_of_class eq "_WRAP_GERROR")
       {
-        push(@{$exceptions{$filename_header}}, \@names);
+        push(@{$exceptions{$filename_header}}, \ @names);
       }
     }
     elsif (/\b_INCLUDE_IN_WRAP_INIT\((.+)\)/)
index 56b44e6..264955f 100644 (file)
@@ -73,7 +73,9 @@ sub parse_command_line_args();
 #main()
 parse_command_line_args();
 
-my $objOutputter = &Output::new($main::m4path, \@main::macrodirs);
+# Don't remove the space between \ and @. When glibmm is built with Meson,
+# the \ would be removed in gmmproc.
+my $objOutputter = &Output::new($main::m4path, \ @main::macrodirs);
 my $objWrapParser = &WrapParser::new($objOutputter);
 
 $$objWrapParser{srcdir} = $main::srcdir;
index a5046f5..a31f1f0 100644 (file)
@@ -1,7 +1,7 @@
 dnl $Id$
 
 dnl
-dnl _CLASS_BOXEDTYPE(Region, GdkRegion, gdk_region_new, gdk_region_copy, gdk_region_destroy)
+dnl _CLASS_BOXEDTYPE(Region, GdkRegion, gdk_region_new, gdk_region_copy, gdk_region_destroy, api_decoration)
 dnl
 
 define(`_CLASS_BOXEDTYPE',`dnl
@@ -13,6 +13,7 @@ define(`__CNAME__',`$2')
 define(`__BOXEDTYPE_FUNC_NEW',`$3')
 define(`__BOXEDTYPE_FUNC_COPY',`$4')
 define(`__BOXEDTYPE_FUNC_FREE',`$5')
+define(`__BOXEDTYPE_FUNC_DECORATION',`$6')
 
 define(`_CUSTOM_DEFAULT_CTOR',`dnl
 _PUSH()
@@ -79,12 +80,13 @@ ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl
  *
  * @relates __NAMESPACE__::__CPPNAME__
  */
+__BOXEDTYPE_FUNC_DECORATION
 __NAMESPACE__::__CPPNAME__ wrap(__CNAME__* object, bool take_copy = false);
 ')dnl endif __BOOL_NO_WRAP_FUNCTION__
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 template <>
-class Value<__NAMESPACE__::__CPPNAME__> : public Glib::Value_Boxed<__NAMESPACE__::__CPPNAME__>
+class __BOXEDTYPE_FUNC_DECORATION Value<__NAMESPACE__::__CPPNAME__> : public Glib::Value_Boxed<__NAMESPACE__::__CPPNAME__>
 {};
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
index 926ac49..bbb3441 100644 (file)
@@ -1,7 +1,7 @@
 dnl $Id$
 
 dnl
-dnl _CLASS_BOXEDTYPE_STATIC(TreeIter, GtkTreeIter)
+dnl _CLASS_BOXEDTYPE_STATIC(TreeIter, GtkTreeIter, api_decoration)
 dnl
 define(`_CLASS_BOXEDTYPE_STATIC',`dnl
 _PUSH()
@@ -9,6 +9,7 @@ dnl
 dnl Define the args for later macros
 define(`__CPPNAME__',`$1')
 define(`__CNAME__',`$2')
+define(`__FUNC_DECORATION__',`$3')
 
 define(`_CUSTOM_DEFAULT_CTOR',`dnl
 _PUSH()
@@ -53,18 +54,20 @@ ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl
  * @param object The C instance
  * @result A C++ instance that wraps this C instance.
  */
+__FUNC_DECORATION__
 __NAMESPACE__::__CPPNAME__& wrap(__CNAME__* object);
 
 /** @relates __NAMESPACE__::__CPPNAME__
  * @param object The C instance
  * @result A C++ instance that wraps this C instance.
  */
+__FUNC_DECORATION__
 const __NAMESPACE__::__CPPNAME__& wrap(const __CNAME__* object);
 ')dnl endif __BOOL_NO_WRAP_FUNCTION__
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 template <>
-class Value<__NAMESPACE__::__CPPNAME__> : public Glib::Value_Boxed<__NAMESPACE__::__CPPNAME__>
+class __FUNC_DECORATION__ Value<__NAMESPACE__::__CPPNAME__> : public Glib::Value_Boxed<__NAMESPACE__::__CPPNAME__>
 {};
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
index ff07505..8635946 100644 (file)
@@ -19,6 +19,8 @@ dnl the problem by supporting optional __REAL_* arguments to this macro.
 define(`__REAL_CNAME__',ifelse(`$6',,__CNAME__,`$6'))
 define(`__REAL_CPARENT__',ifelse(`$7',,__CPARENT__,`$7'))
 
+dnl $8 is for the optional api_decoration used for import/export
+define(`__FUNC_DECORATION__',`$8')
 
 _POP()
 _SECTION(SECTION_CLASS2)
@@ -105,7 +107,7 @@ define(`_CREATE_METHOD',`
 _PUSH(SECTION_CC)
 Glib::RefPtr<`'__CPPNAME__`'> __CPPNAME__`'::create(`'$2`')
 {
-  return Glib::make_refptr_for_instance<`'__CPPNAME__`'>( new __CPPNAME__`'(`'$3`') );
+  return Glib::RefPtr<`'__CPPNAME__`'>( new __CPPNAME__`'(`'$3`') );
 }
 
 _POP()
@@ -124,7 +126,7 @@ _STRUCT_PROTOTYPE()
 ')dnl
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-__NAMESPACE_BEGIN__ class __CPPNAME__`'_Class; __NAMESPACE_END__
+__NAMESPACE_BEGIN__ class __FUNC_DECORATION__ __CPPNAME__`'_Class; __NAMESPACE_END__
 #endif //DOXYGEN_SHOULD_SKIP_THIS
 
 _SECTION(SECTION_HEADER3)
@@ -141,6 +143,7 @@ namespace Glib
    *
    * @relates __NAMESPACE__::__CPPNAME__
    */
+  __FUNC_DECORATION__
   Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__REAL_CNAME__`'* object, bool take_copy = false);
 }
 ')dnl
@@ -169,7 +172,7 @@ namespace Glib
 
 Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__REAL_CNAME__`'* object, bool take_copy)
 {
-  return Glib::make_refptr_for_instance<__NAMESPACE__::__CPPNAME__>( dynamic_cast<__NAMESPACE__::__CPPNAME__*> (Glib::wrap_auto ((GObject*)(object), take_copy)) );
+  return Glib::RefPtr<__NAMESPACE__::__CPPNAME__>( dynamic_cast<__NAMESPACE__::__CPPNAME__*> (Glib::wrap_auto ((GObject*)(object), take_copy)) );
   //We use dynamic_cast<> in case of multiple inheritance.
 }
 
index bce51ff..b77c789 100644 (file)
@@ -15,6 +15,8 @@ define(`__CPARENT__',m4_ifelse($6,`',`GObject',$6)) #Optional parameter.
 define(`__PCAST__',`(__CPARENT__`'*)')
 define(`__BOOL_IS_INTERFACE__',`1')
 
+dnl $7 is for the optional api_decoration used for import/export
+define(`__FUNC_DECORATION__',`$7')
 
 dnl For classes that need custom code in their cast constructor.
 define(`_CUSTOM_CTOR_CAST',`dnl
@@ -118,7 +120,7 @@ _SECTION(SECTION_HEADER1)
 _STRUCT_PROTOTYPE()
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-__NAMESPACE_BEGIN__ class __CPPNAME__`'_Class; __NAMESPACE_END__
+__NAMESPACE_BEGIN__ class __FUNC_DECORATION__ __CPPNAME__`'_Class; __NAMESPACE_END__
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
 _SECTION(SECTION_HEADER3)
@@ -135,6 +137,7 @@ namespace Glib
    *
    * @relates __NAMESPACE__::__CPPNAME__
    */
+  __FUNC_DECORATION__
   Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__CNAME__`'* object, bool take_copy = false);
 
 } // namespace Glib
@@ -161,7 +164,7 @@ namespace Glib
 
 Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__CNAME__`'* object, bool take_copy)
 {
-  return Glib::make_refptr_for_instance<__NAMESPACE__::__CPPNAME__>( dynamic_cast<__NAMESPACE__::__CPPNAME__*> (Glib::wrap_auto_interface<__NAMESPACE__::__CPPNAME__> ((GObject*)(object), take_copy)) );
+  return Glib::RefPtr<__NAMESPACE__::__CPPNAME__>( dynamic_cast<__NAMESPACE__::__CPPNAME__*> (Glib::wrap_auto_interface<__NAMESPACE__::__CPPNAME__> ((GObject*)(object), take_copy)) );
   //We use dynamic_cast<> in case of multiple inheritance.
 }
 
index 7e04921..c725a42 100644 (file)
@@ -1,7 +1,7 @@
 dnl $Id$
 
 dnl
-dnl _CLASS_OPAQUE_COPYABLE(Region, GdkRegion, gdk_region_new, gdk_region_copy, gdk_region_destroy)
+dnl _CLASS_OPAQUE_COPYABLE(Region, GdkRegion, gdk_region_new, gdk_region_copy, gdk_region_destroy, api_decoration)
 dnl
 
 define(`_CLASS_OPAQUE_COPYABLE',`dnl
@@ -13,6 +13,7 @@ define(`__CNAME__',`$2')
 define(`__OPAQUE_FUNC_NEW',`$3')
 define(`__OPAQUE_FUNC_COPY',`$4')
 define(`__OPAQUE_FUNC_FREE',`$5')
+define(`__OPAQUE_FUNC_DECORATION',`$6')
 
 define(`_CUSTOM_DEFAULT_CTOR',`dnl
 _PUSH()
@@ -65,7 +66,8 @@ namespace Glib
    *
    * @relates __NAMESPACE__::__CPPNAME__
    */
-__NAMESPACE__::__CPPNAME__ wrap(__CNAME__* object, bool take_copy = false);
+  __OPAQUE_FUNC_DECORATION
+  __NAMESPACE__::__CPPNAME__ wrap(__CNAME__* object, bool take_copy = false);
 
 } // namespace Glib
 ')dnl endif __BOOL_NO_WRAP_FUNCTION__
index 85f57ee..2a5b913 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl _CLASS_OPAQUE_REFCOUNTED(Coverage, PangoCoverage, pango_coverage_new, pango_coverage_ref, pango_coverage_unref)
+dnl _CLASS_OPAQUE_REFCOUNTED(Coverage, PangoCoverage, pango_coverage_new, pango_coverage_ref, pango_coverage_unref, api_decoration)
 dnl
 
 define(`_CLASS_OPAQUE_REFCOUNTED',`dnl
@@ -11,6 +11,7 @@ define(`__CNAME__',`$2')
 define(`__OPAQUE_FUNC_NEW',`$3')
 define(`__OPAQUE_FUNC_REF',`$4')
 define(`__OPAQUE_FUNC_UNREF',`$5')
+define(`__OPAQUE_FUNC_DECORATION',`$6')
 undefine(`__OPAQUE_FUNC_GTYPE__')
 
 _POP()
@@ -56,12 +57,13 @@ namespace Glib
  *
  * @relates __NAMESPACE__::__CPPNAME__
  */
+__OPAQUE_FUNC_DECORATION
 Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__CNAME__* object, bool take_copy = false);
 
 ifdef(`__OPAQUE_FUNC_GTYPE__',`dnl
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 template <>
-class Value<Glib::RefPtr<__NAMESPACE__::__CPPNAME__>> : public Glib::Value_RefPtrBoxed<__NAMESPACE__::__CPPNAME__>
+class __OPAQUE_FUNC_DECORATION Value<Glib::RefPtr<__NAMESPACE__::__CPPNAME__>> : public Glib::Value_RefPtrBoxed<__NAMESPACE__::__CPPNAME__>
 {
 public:
   CppType get() const { return Glib::wrap(static_cast<__CNAME__*>(get_boxed()), true); }
@@ -95,7 +97,7 @@ Glib::RefPtr<__NAMESPACE__::__CPPNAME__> wrap(__CNAME__* object, bool take_copy)
     __OPAQUE_FUNC_REF`'(object);
 
   // See the comment at the top of this file, if you want to know why the cast works.
-  return Glib::make_refptr_for_instance<__NAMESPACE__::__CPPNAME__>(reinterpret_cast<__NAMESPACE__::__CPPNAME__*>(object));
+  return Glib::RefPtr<__NAMESPACE__::__CPPNAME__>(reinterpret_cast<__NAMESPACE__::__CPPNAME__*>(object));
 }
 
 } // namespace Glib
@@ -124,7 +126,7 @@ ifelse(__OPAQUE_FUNC_NEW,NONE,`dnl
 Glib::RefPtr<__CPPNAME__> __CPPNAME__::create()
 {
   // See the comment at the top of this file, if you want to know why the cast works.
-  return Glib::make_refptr_for_instance<__CPPNAME__>(reinterpret_cast<__CPPNAME__*>(__OPAQUE_FUNC_NEW`'()));
+  return Glib::RefPtr<__CPPNAME__>(reinterpret_cast<__CPPNAME__*>(__OPAQUE_FUNC_NEW`'()));
 }
 
 ')dnl endif __OPAQUE_FUNC_NEW
index da5137c..8d372fa 100644 (file)
@@ -1,3 +1,5 @@
+dnl $Id$
+
 #
 #  Define a hashing for names
 #
@@ -50,29 +52,11 @@ define(`_EQUAL',`define(EV`'__HASH(`$1'),`$2')')
 
 
 define(`__ARG3__',`$`'3')
-
-# _CONV_ENUM(namespace, enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of namespace+enum_name.
 define(`_CONV_ENUM',`dnl
-pushdef(`C_ENUM_NAME', `m4_ifelse(`$3',,`$1$2',`$3')')
-_CONVERSION(`C_ENUM_NAME', `$2', static_cast<$2>(__ARG3__))
-_CONVERSION(`C_ENUM_NAME', `$1::$2', static_cast<$1::$2>(__ARG3__))
-_CONVERSION(`$2', `C_ENUM_NAME', static_cast<C_ENUM_NAME>(__ARG3__))
-_CONVERSION(`$1::$2', `C_ENUM_NAME', static_cast<C_ENUM_NAME>(__ARG3__))
-popdef(`C_ENUM_NAME')
-')dnl
-
-# _CONV_INCLASS_ENUM(namespace, class_name, enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of namespace+class_name+enum_name.
-define(`_CONV_INCLASS_ENUM',`dnl
-pushdef(`C_ENUM_NAME', `m4_ifelse(`$4',,`$1$2$3',`$4')')
-_CONVERSION(`C_ENUM_NAME', `$3', static_cast<$3>(__ARG3__))
-_CONVERSION(`C_ENUM_NAME', `$2::$3', static_cast<$2::$3>(__ARG3__))
-_CONVERSION(`C_ENUM_NAME', `$1::$2::$3', static_cast<$1::$2::$3>(__ARG3__))
-_CONVERSION(`$3', `C_ENUM_NAME', static_cast<C_ENUM_NAME>(__ARG3__))
-_CONVERSION(`$2::$3', `C_ENUM_NAME', static_cast<C_ENUM_NAME>(__ARG3__))
-_CONVERSION(`$1::$2::$3', `C_ENUM_NAME', static_cast<C_ENUM_NAME>(__ARG3__))
-popdef(`C_ENUM_NAME')
+_CONVERSION(`$1$2', `$2', (($2)(__ARG3__)))
+_CONVERSION(`$1$2', `$1::$2', (($1::$2)(__ARG3__)))
+_CONVERSION(`$2', `$1$2', (($1$2)(__ARG3__)))
+_CONVERSION(`$1::$2', `$1$2', (($1$2)(__ARG3__)))
 ')dnl
 
 # e.g. Glib::RefPtr<Gdk::Something> to GdkSomething*
index 7589cc5..601f1c1 100644 (file)
@@ -1,87 +1,61 @@
-dnl
-dnl Gio C names have prefix 'G' or 'GDBus' but C++ namespace Gio ot Gio::DBus
-dnl
-# _CONV_GIO_ENUM(enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of G+enum_name.
-define(`_CONV_GIO_ENUM',`dnl
-_CONV_ENUM(`Gio',`$1',`m4_ifelse(`$2',,`G$1',`$2')')
-')dnl
-
-# _CONV_GIO_DBUS_ENUM(enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of GDBus+enum_name.
-define(`_CONV_GIO_DBUS_ENUM',`dnl
-_CONV_ENUM(`Gio::DBus',`$1',`m4_ifelse(`$2',,`GDBus$1',`$2')')
-')dnl
-
-# _CONV_GIO_INCLASS_ENUM(class_name, enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of G+class_name+enum_name.
-define(`_CONV_GIO_INCLASS_ENUM',`dnl
-_CONV_INCLASS_ENUM(`Gio',`$1',`$2',`m4_ifelse(`$3',,`G$1$2',`$3')')
-')dnl
-
-# _CONV_GIO_DBUS_INCLASS_ENUM(class_name, enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of GDBus+class_name+enum_name.
-define(`_CONV_GIO_DBUS_INCLASS_ENUM',`dnl
-_CONV_INCLASS_ENUM(`Gio::DBus',`$1',`$2',`m4_ifelse(`$3',,`GDBus$1$2',`$3')')
-')dnl
-
-_CONV_GIO_INCLASS_ENUM(AppInfo,CreateFlags)
-_CONV_GIO_INCLASS_ENUM(Application,Flags)
-_CONV_GIO_ENUM(AskPasswordFlags)
-_CONV_GIO_ENUM(BusType)
-_CONV_GIO_INCLASS_ENUM(Converter,Flags)
-_CONV_GIO_INCLASS_ENUM(Converter,Result)
-_CONV_GIO_INCLASS_ENUM(Credentials,Type)
-_CONV_GIO_ENUM(DataStreamByteOrder)
-_CONV_GIO_ENUM(DataStreamNewlineType)
-_CONV_GIO_DBUS_ENUM(CallFlags)
-_CONV_GIO_DBUS_ENUM(CapabilityFlags)
-_CONV_GIO_DBUS_INCLASS_ENUM(InterfaceSkeleton,Flags)
-_CONV_GIO_DBUS_INCLASS_ENUM(Message,ByteOrder)
-_CONV_GIO_DBUS_ENUM(MessageFlags)
-_CONV_GIO_DBUS_ENUM(MessageHeaderField)
-_CONV_GIO_DBUS_ENUM(MessageType)
-_CONV_GIO_DBUS_INCLASS_ENUM(ObjectManagerClient,Flags)
-_CONV_GIO_DBUS_ENUM(ProxyFlags)
-_CONV_GIO_DBUS_ENUM(ConnectionFlags)
-_CONV_GIO_DBUS_ENUM(SendMessageFlags)
-_CONV_GIO_DBUS_INCLASS_ENUM(Server,Flags)
-_CONV_GIO_INCLASS_ENUM(Drive,StartFlags)
-_CONV_GIO_INCLASS_ENUM(Drive,StartStopType)
-_CONV_GIO_INCLASS_ENUM(Emblem,Origin)
-_CONV_GIO_INCLASS_ENUM(FileAttributeInfo,Flags)
-_CONV_GIO_ENUM(FileAttributeStatus)
-_CONV_GIO_ENUM(FileAttributeType)
-_CONV_GIO_INCLASS_ENUM(FileCopy,Flags)
-_CONV_GIO_INCLASS_ENUM(FileCreate,Flags)
-_CONV_GIO_INCLASS_ENUM(FileMonitor,Event)
-_CONV_GIO_INCLASS_ENUM(FileMonitor,Flags)
-_CONV_GIO_ENUM(FileQueryInfoFlags)
-_CONV_GIO_ENUM(FileType)
-_CONV_GIO_INCLASS_ENUM(Mount,MountFlags)
-_CONV_GIO_ENUM(MountOperationResult)
-_CONV_GIO_INCLASS_ENUM(Mount,UnmountFlags)
-_CONV_GIO_ENUM(NetworkConnectivity)
-_CONV_GIO_INCLASS_ENUM(Notification,Priority)
-_CONV_GIO_INCLASS_ENUM(OutputStream,SpliceFlags)
-_CONV_GIO_ENUM(PasswordSave)
-_CONV_GIO_INCLASS_ENUM(Resolver,RecordType)
-_CONV_GIO_INCLASS_ENUM(Resource,Flags)
-_CONV_GIO_INCLASS_ENUM(Resource,LookupFlags)
-_CONV_GIO_INCLASS_ENUM(Settings,BindFlags)
-_CONV_GIO_ENUM(SocketClientEvent)
-_CONV_GIO_ENUM(SocketFamily)
-_CONV_GIO_INCLASS_ENUM(Socket,MsgFlags)
-_CONV_GIO_INCLASS_ENUM(Socket,Protocol)
-_CONV_GIO_INCLASS_ENUM(Socket,Type)
-_CONV_GIO_ENUM(TlsCertificateFlags)
-_CONV_GIO_ENUM(TlsCertificateRequestFlags)
-_CONV_GIO_INCLASS_ENUM(TlsDatabase,VerifyFlags)
-_CONV_GIO_INCLASS_ENUM(TlsDatabase,LookupFlags)
-_CONV_GIO_ENUM(TlsInteractionResult)
-_CONV_GIO_INCLASS_ENUM(TlsPassword,Flags)
-_CONV_GIO_INCLASS_ENUM(UnixSocketAddress,Type)
-_CONV_GIO_ENUM(ZlibCompressorFormat)
+_CONV_ENUM(G,AppInfoCreateFlags)
+_CONV_ENUM(G,ApplicationFlags)
+_CONV_ENUM(G,AskPasswordFlags)
+_CONV_ENUM(G,BusType)
+_CONV_ENUM(G,ConverterFlags)
+_CONV_ENUM(G,ConverterResult)
+_CONV_ENUM(G,CredentialsType)
+_CONV_ENUM(G,DataStreamByteOrder)
+_CONV_ENUM(G,DataStreamNewlineType)
+_CONV_ENUM(GDBus,CallFlags)
+_CONV_ENUM(GDBus,CapabilityFlags)
+_CONV_ENUM(GDBus,InterfaceSkeletonFlags)
+_CONV_ENUM(GDBus,MessageFlags)
+_CONV_ENUM(GDBus,MessageHeaderField)
+_CONV_ENUM(GDBus,MessageType)
+_CONV_ENUM(GDBus,ObjectManagerClientFlags)
+_CONV_ENUM(GDBus,ProxyFlags)
+_CONV_ENUM(GDBus,ConnectionFlags)
+_CONV_ENUM(GDBus,SendMessageFlags)
+_CONV_ENUM(GDBus,ServerFlags)
+_CONV_ENUM(G,DriveStartFlags)
+_CONV_ENUM(G,DriveStartFlags)
+_CONV_ENUM(G,DriveStartStopType)
+_CONV_ENUM(G,EmblemOrigin)
+_CONV_ENUM(G,FileAttributeInfoFlags)
+_CONV_ENUM(G,FileAttributeStatus)
+_CONV_ENUM(G,FileAttributeType)
+_CONV_ENUM(G,FileCopyFlags)
+_CONV_ENUM(G,FileCreateFlags)
+_CONV_ENUM(G,FileMonitorEvent)
+_CONV_ENUM(G,FileMonitorFlags)
+_CONV_ENUM(G,FileQueryInfoFlags)
+_CONV_ENUM(G,FileType)
+_CONV_ENUM(G,MountMountFlags)
+_CONV_ENUM(G,MountOperationResult)
+_CONV_ENUM(G,MountUnmountFlags)
+_CONV_ENUM(G,NetworkConnectivity)
+_CONV_ENUM(G,NotificationPriority)
+_CONV_ENUM(G,OutputStreamSpliceFlags)
+_CONV_ENUM(G,PasswordSave)
+_CONV_ENUM(G,ResolverRecordType)
+_CONV_ENUM(G,ResourceFlags)
+_CONV_ENUM(G,ResourceLookupFlags)
+_CONV_ENUM(G,SettingsBindFlags)
+_CONV_ENUM(G,SocketClientEvent)
+_CONV_ENUM(G,SocketFamily)
+_CONV_ENUM(G,SocketMsgFlags)
+_CONV_ENUM(G,SocketProtocol)
+_CONV_ENUM(G,SocketType)
+_CONV_ENUM(G,TlsCertificateFlags)
+_CONV_ENUM(G,TlsCertificateRequestFlags)
+_CONV_ENUM(G,TlsDatabaseVerifyFlags)
+_CONV_ENUM(G,TlsDatabaseLookupFlags)
+_CONV_ENUM(G,TlsInteractionResult)
+_CONV_ENUM(G,TlsPasswordFlags)
+_CONV_ENUM(G,TlsRehandshakeMode)
+_CONV_ENUM(G,UnixSocketAddressType)
+_CONV_ENUM(G,ZlibCompressorFormat)
 
 # Action
 _CONVERSION(`GAction*',`Glib::RefPtr<Action>',`Glib::wrap($3)')
@@ -97,7 +71,7 @@ _CONVERSION(`GAppLaunchContext*',`const Glib::RefPtr<AppLaunchContext>&',Glib::w
 _CONVERSION(`const Glib::RefPtr<AppInfo>&',`GAppInfo*',__CONVERT_REFPTR_TO_P)
 _CONVERSION(`Glib::RefPtr<AppInfo>',`GAppInfo*',__CONVERT_REFPTR_TO_P)
 _CONVERSION(`GAppInfo*',`const Glib::RefPtr<AppInfo>&',`Glib::wrap($3)')
-_CONVERSION(`const std::vector<Glib::RefPtr<Gio::File>>&',`GList*',`Glib::ListHandler<Glib::RefPtr<Gio::File>>::vector_to_list($3).data()')
+_CONVERSION(`const Glib::ListHandle< Glib::RefPtr<Gio::File> >&',`GList*',`$3.data()')
 
 # Application
 _CONVERSION(`GApplication*',`Glib::RefPtr<Application>',`Glib::wrap($3)')
@@ -204,6 +178,8 @@ _CONVERSION(`GFileEnumerator*',`Glib::RefPtr<FileEnumerator>',`Glib::wrap($3)')
 _CONVERSION(`GFileInfo*',`Glib::RefPtr<FileInfo>',`Glib::wrap($3)')
 _CONVERSION(`Glib::RefPtr<FileInfo>&',`GFileInfo*',__CONVERT_REFPTR_TO_P)
 _CONVERSION(`const Glib::RefPtr<FileInfo>&',`GFileInfo*',__CONVERT_REFPTR_TO_P)
+_CONVERSION(`Glib::TimeVal&', `GTimeVal*', static_cast<$2>(&$3))
+_CONVERSION(`const Glib::TimeVal&', `GTimeVal*', const_cast<GTimeVal*>(static_cast<const GTimeVal*>(&$3)))
 _CONVERSION(`const Glib::RefPtr<FileAttributeMatcher>&',`GFileAttributeMatcher*',__CONVERT_CONST_REFPTR_TO_P)
 
 # FileInputStream
@@ -246,7 +222,6 @@ _CONVERSION(`GInetAddress*',`Glib::RefPtr<InetAddress>',`Glib::wrap($3)')
 _CONVERSION(`const Glib::RefPtr<InputStream>&',`GInputStream*',__CONVERT_CONST_REFPTR_TO_P)
 _CONVERSION(`const Glib::RefPtr<Gio::InputStream>&',`GInputStream*',__CONVERT_CONST_REFPTR_TO_P)
 _CONVERSION(`GInputStream*',`Glib::RefPtr<InputStream>',`Glib::wrap($3)')
-_CONVERSION(`GInputStream*',`Glib::RefPtr<Gio::InputStream>',`Glib::wrap($3)')
 
 # MenuAttributeIter
 _CONVERSION(`GMenuAttributeIter*',`Glib::RefPtr<MenuAttributeIter>',`Glib::wrap($3)')
@@ -261,7 +236,7 @@ _CONVERSION(`const Glib::RefPtr<MenuModel>&',`GMenuModel*',__CONVERT_CONST_REFPT
 
 # MenuItem
 _CONVERSION(`GMenuItem*',`Glib::RefPtr<MenuItem>',`Glib::wrap($3)')
-_CONVERSION(`const Glib::RefPtr<const MenuItem>&',`GMenuItem*',__CONVERT_CONST_REFPTR_TO_P)
+_CONVERSION(`const Glib::RefPtr<MenuItem>&',`GMenuItem*',__CONVERT_CONST_REFPTR_TO_P)
 
 # Mount
 _CONVERSION(`GMount*',`Glib::RefPtr<Mount>',`Glib::wrap($3)')
@@ -297,7 +272,7 @@ _CONVERSION(`GResource*',`Glib::RefPtr<Resource>',`Glib::wrap($3)')
 
 #Settings
 _CONVERSION(`GSettings*',`Glib::RefPtr<Settings>',`Glib::wrap($3)')
-_CONVERSION(`const std::vector<Glib::ustring>&',`const gchar*-const*',`Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data()')
+_CONVERSION(`const Glib::StringArrayHandle&',`const gchar*-const*',`($3).data()')
 _CONVERSION(`const Glib::RefPtr<SettingsBackend>&',`GSettingsBackend*',__CONVERT_REFPTR_TO_P)
 
 _CONVERSION(`GSettingsSchemaKey*',`Glib::RefPtr<SettingsSchemaKey>',`Glib::wrap($3)')
index c7df34e..243255b 100644 (file)
@@ -1,16 +1,11 @@
 dnl
 dnl Glib C names have prefix 'G' but C++ namespace Glib
 dnl
-# _CONV_GLIB_ENUM(enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of G+enum_name.
 define(`_CONV_GLIB_ENUM',`dnl
-_CONV_ENUM(`Glib',`$1',`m4_ifelse(`$2',,`G$1',`$2')')
-')dnl
-
-# _CONV_GLIB_INCLASS_ENUM(class_name, enum_name[, C_enum_name])
-# Specify C_enum_name, if it's not the concatenation of G+class_name+enum_name.
-define(`_CONV_GLIB_INCLASS_ENUM',`dnl
-_CONV_INCLASS_ENUM(`Glib',`$1',`$2',`m4_ifelse(`$3',,`G$1$2',`$3')')
+_CONVERSION(`G$1', `$1', (($1)(__ARG3__)))
+_CONVERSION(`G$1', `Glib::$1', ((Glib::$1)(__ARG3__)))
+_CONVERSION(`$1', `G$1', ((G$1)(__ARG3__)))
+_CONVERSION(`Glib::$1', `G$1', ((G$1)(__ARG3__)))
 ')dnl
 
 _EQUAL(gchar,char)
@@ -65,14 +60,14 @@ dnl
 dnl # These are for fixmegtkconst
 _CONVERSION(`const guchar*',`guchar*',`const_cast<guchar*>($3)',`$3')
 
-_CONV_GLIB_INCLASS_ENUM(Binding,Flags)
+_CONV_GLIB_ENUM(BindingFlags)
 _CONV_GLIB_ENUM(IOCondition)
 _CONV_GLIB_ENUM(IOFlags)
 _CONV_GLIB_ENUM(IOStatus)
-_CONV_GLIB_INCLASS_ENUM(KeyFile,Flags)
+_CONV_GLIB_ENUM(KeyFileFlags)
 _CONV_GLIB_ENUM(OptionArg)
-_CONV_GLIB_INCLASS_ENUM(Regex,CompileFlags)
-_CONV_GLIB_INCLASS_ENUM(Regex,MatchFlags)
+_CONV_GLIB_ENUM(RegexCompileFlags)
+_CONV_GLIB_ENUM(RegexMatchFlags)
 _CONV_GLIB_ENUM(SeekType)
 _CONV_GLIB_ENUM(TimeType)
 
@@ -88,7 +83,9 @@ define(`__GCHARP_TO_STDSTRING',`Glib::convert_const_gchar_ptr_to_stdstring($`'3)
 _CONVERSION(`const Glib::ustring&',`const char*',`$3.c_str()')
 _CONVERSION(`const Glib::ustring&', `const guchar*', `(($2)$3.c_str())')
 _CONVERSION(`const std::string&',`const char*',`$3.c_str()')
+_CONVERSION(`std::string',`const char*',`$3.c_str()')
 _CONVERSION(`const Glib::ustring&',`gchar*',`const_cast<gchar*>($3.c_str())')
+_CONVERSION(`gchar*',`Glib::ustring',__GCHARP_TO_USTRING)
 _CONVERSION(`const-gchar*',`Glib::ustring',__GCHARP_TO_USTRING)
 _CONVERSION(`const-guchar*',`Glib::ustring',__GCHARP_TO_USTRING)
 _CONVERSION(`const gchar*',`Glib::ustring',__GCHARP_TO_USTRING)
@@ -98,6 +95,10 @@ _CONVERSION(`const char*',`std::string',__GCHARP_TO_STDSTRING)
 _CONVERSION(`const char*',`const-gchar*',`$3')
 _CONVERSION(`const-gchar*',`const char*',`$3')
 _CONVERSION(`const char*',`const std::string&',__GCHARP_TO_STDSTRING)
+_CONVERSION(`char*',`std::string',__GCHARP_TO_STDSTRING)
+_CONVERSION(`std::string', `char*', `g_strdup(($3).c_str())')
+_CONVERSION(`const std::string&', `char*', `g_strdup(($3).c_str())')
+_CONVERSION(`Glib::ustring', `char*', `g_strdup(($3).c_str())')
 
 _CONVERSION(`return-gchar*',`Glib::ustring',`Glib::convert_return_gchar_ptr_to_ustring($3)')
 _CONVERSION(`return-gchar*',`std::string',`Glib::convert_return_gchar_ptr_to_stdstring($3)')
@@ -110,8 +111,7 @@ _CONVERSION(`const DateTime&',`GDateTime*',`const_cast<$2>($3.gobj())')
 _CONVERSION(`const Glib::DateTime&',`GDateTime*',`const_cast<$2>($3.gobj())')
 
 dnl KeyFile
-_CONVERSION(`const Glib::RefPtr<Glib::KeyFile>&',`GKeyFile*',__CONVERT_REFPTR_TO_P)
-_CONVERSION(`const Glib::RefPtr<const Glib::KeyFile>&',`GKeyFile*',__CONVERT_CONST_REFPTR_TO_P)
+_CONVERSION(`Glib::KeyFile&',`GKeyFile*',`($3).gobj()')
 
 dnl Object
 _CONVERSION(`const Glib::RefPtr<Glib::Object>&',`GObject*',__CONVERT_REFPTR_TO_P)
@@ -141,6 +141,10 @@ _CONVERSION(`GRegex*',`Glib::RefPtr<const Regex>',`Glib::wrap($3)')
 #Source
 _CONVERSION(`GSource*',`Glib::RefPtr<Glib::Source>',`Glib::wrap($3)')
 
+dnl TimeVal
+_CONVERSION(`const TimeVal&',`const GTimeVal*',`&($3)')
+_CONVERSION(`TimeVal&',`GTimeVal*',`&($3)')
+
 dnl TimeZone
 _CONVERSION(`GTimeZone*',`TimeZone',`Glib::wrap($3)')
 _CONVERSION(`const TimeZone&',`GTimeZone*',`const_cast<$2>($3.gobj())')
index 09f3111..be07f5e 100644 (file)
@@ -1,18 +1,13 @@
 dnl
-dnl _ENUM(cpp_type, c_type, value_suffix, `element_list', `gtype_func', `conv_to_int',
-dnl          $1       $2         $3             $4             $5            $6
-dnl in_class, `optional_refdoc_comment', 'deprecated')
-dnl   $7                $8                    $9
+dnl _ENUM(cpp_type, c_type, value_suffix, `element_list', `gtype_func', `optional_refdoc_comment', 'deprecated')
+dnl          $1       $2         $3             $4             $5              $6                        $7
 dnl
 m4_define(`_ENUM',`dnl
 _PUSH()
 
 m4_define(`__ENUM_CPPNAME__',`$1')
 m4_define(`__ENUM_CNAME__',`$2')
-m4_define(`__ENUM_CLASS_CPPNAME__',m4_ifelse($7,0,,`__CPPNAME__::')`__ENUM_CPPNAME__')
-m4_define(`__ENUM_INDENT1__',m4_ifelse($7,0,,`  '))
-m4_define(`__ENUM_INDENT2__',__ENUM_INDENT1__`'m4_ifelse($6,,,`  '))
-m4_define(`__ENUM_VALUE_BASE__',`Glib::Value_$3<__NAMESPACE__::__ENUM_CLASS_CPPNAME__>')
+m4_define(`__ENUM_VALUE_BASE__',`Glib::Value_$3<__NAMESPACE__::__ENUM_CPPNAME__>')
 
 _POP()
 dnl
@@ -22,124 +17,84 @@ m4_ifdef(`__DOCGROUP_'__MODULE_CANONICAL__`_ENUMS__',,`dnl else
 m4_define(`__DOCGROUP_'__MODULE_CANONICAL__`_ENUMS__')dnl
 /** @addtogroup '__MODULE_CANONICAL__`Enums __MODULE_CANONICAL__ Enums and Flags */
 
-__ENUM_INDENT1__')`'dnl endif
+')dnl endif
 dnl
 dnl
-ifelse(`$9',,,`_DEPRECATE_IFDEF_START'`'__ENUM_INDENT1__)`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline
-ifelse($6,,,`/** Wrapper for enum __ENUM_CPPNAME__.
-__ENUM_INDENT1__ * __ENUM_CPPNAME__ enumerators are scoped and can be implicitly converted to int.
-__ENUM_INDENT1__ * The scope is __NAMESPACE__::__ENUM_CLASS_CPPNAME__::
-__ENUM_INDENT1__ *
-__ENUM_INDENT1__ * @ingroup __MODULE_CANONICAL__`'Enums
-__ENUM_INDENT1__ */
-__ENUM_INDENT1__`'class __ENUM_CPPNAME__`'_Wrapper final
-__ENUM_INDENT1__{
-__ENUM_INDENT1__`'public:
-__ENUM_INDENT2__')`'dnl endif conv_to_int
-/** $8
-__ENUM_INDENT2__ *
-__ENUM_INDENT2__ * @ingroup __MODULE_CANONICAL__`'Enums
-m4_ifelse($3,`Flags',`dnl
-__ENUM_INDENT2__ * @par Bitwise operators:
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator|(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator&(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator^(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator~(__ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator|=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator&=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br>
-__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator^=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br>
+ifelse(`$7',,,`_DEPRECATE_IFDEF_START')`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline
+/** $6
+ *
+ * @ingroup __MODULE_CANONICAL__`'Enums
+m4_ifelse($3,Flags,`dnl
+ * @par Bitwise operators:
+ * <tt>%__ENUM_CPPNAME__ operator|(__ENUM_CPPNAME__, __ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__ operator&(__ENUM_CPPNAME__, __ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__ operator^(__ENUM_CPPNAME__, __ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__ operator~(__ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__& operator|=(__ENUM_CPPNAME__&, __ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__& operator&=(__ENUM_CPPNAME__&, __ENUM_CPPNAME__)</tt><br>
+ * <tt>%__ENUM_CPPNAME__& operator^=(__ENUM_CPPNAME__&, __ENUM_CPPNAME__)</tt><br>
 ')dnl endif
-__ENUM_INDENT2__ */
-__ENUM_INDENT2__`'enum ifelse($6,,`class ',)`'__ENUM_CPPNAME__
-__ENUM_INDENT2__{
+ */
+enum __ENUM_CPPNAME__
+{
 $4
-__ENUM_INDENT2__};
-ifelse($6,,,`__ENUM_INDENT2__`'#ifndef DOXYGEN_SHOULD_SKIP_THIS
-__ENUM_INDENT2__`'__ENUM_CPPNAME__`'_Wrapper`'() = delete;
-__ENUM_INDENT2__`'#endif
-__ENUM_INDENT1__};
-__ENUM_INDENT1__/** __ENUM_CPPNAME__ enumerators are scoped by the wrapper class
-__ENUM_INDENT1__ * and can be implicitly converted to int.
-__ENUM_INDENT1__ *
-__ENUM_INDENT1__ * @ingroup __MODULE_CANONICAL__`'Enums
-__ENUM_INDENT1__ */
-__ENUM_INDENT1__`'using __ENUM_CPPNAME__ = __ENUM_CPPNAME__`'_Wrapper::__ENUM_CPPNAME__;
-')`'dnl endif conv_to_int
-m4_ifelse($3,`Flags',`dnl
-m4_ifelse($7,0,,`dnl  in_class
-_PUSH(SECTION_HEADER3)
-__NAMESPACE_BEGIN__
-ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl
-')dnl endif
+};
+m4_ifelse($3,Flags,`dnl
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__ operator|(__ENUM_CLASS_CPPNAME__ lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }
+inline __ENUM_CPPNAME__ operator|(__ENUM_CPPNAME__ lhs, __ENUM_CPPNAME__ rhs)
+  { return static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__ operator&(__ENUM_CLASS_CPPNAME__ lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }
+inline __ENUM_CPPNAME__ operator&(__ENUM_CPPNAME__ lhs, __ENUM_CPPNAME__ rhs)
+  { return static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__ operator^(__ENUM_CLASS_CPPNAME__ lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }
+inline __ENUM_CPPNAME__ operator^(__ENUM_CPPNAME__ lhs, __ENUM_CPPNAME__ rhs)
+  { return static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__ operator~(__ENUM_CLASS_CPPNAME__ flags)
-  { return static_cast<__ENUM_CLASS_CPPNAME__>(~static_cast<unsigned>(flags)); }
+inline __ENUM_CPPNAME__ operator~(__ENUM_CPPNAME__ flags)
+  { return static_cast<__ENUM_CPPNAME__>(~static_cast<unsigned>(flags)); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__& operator|=(__ENUM_CLASS_CPPNAME__& lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return (lhs = static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }
+inline __ENUM_CPPNAME__& operator|=(__ENUM_CPPNAME__& lhs, __ENUM_CPPNAME__ rhs)
+  { return (lhs = static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__& operator&=(__ENUM_CLASS_CPPNAME__& lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return (lhs = static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }
+inline __ENUM_CPPNAME__& operator&=(__ENUM_CPPNAME__& lhs, __ENUM_CPPNAME__ rhs)
+  { return (lhs = static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }
 
 /** @ingroup __MODULE_CANONICAL__`'Enums */
-inline __ENUM_CLASS_CPPNAME__& operator^=(__ENUM_CLASS_CPPNAME__& lhs, __ENUM_CLASS_CPPNAME__ rhs)
-  { return (lhs = static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }
-m4_ifelse($7,0,,`dnl  in_class
-ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl
-__NAMESPACE_END__
-_POP()
-')dnl endif
+inline __ENUM_CPPNAME__& operator^=(__ENUM_CPPNAME__& lhs, __ENUM_CPPNAME__ rhs)
+  { return (lhs = static_cast<__ENUM_CPPNAME__>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }
 ')dnl endif Flags
-
-ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline
+ifelse(`$7',,,`_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline
 
 m4_ifelse(`$5',`NO_GTYPE',,`dnl else
-m4_ifelse($7,0,`dnl  not in_class
 __NAMESPACE_END__
-',`dnl else
-_PUSH(SECTION_HEADER3)
-')dnl endif
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 namespace Glib
 {
 
-ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl
+ifelse(`$7',,,`_DEPRECATE_IFDEF_START')`'dnl
 template <>
-class Value<__NAMESPACE__::__ENUM_CLASS_CPPNAME__> : public __ENUM_VALUE_BASE__
+class Value<__NAMESPACE__::__ENUM_CPPNAME__> : public __ENUM_VALUE_BASE__
 {
 public:
   static GType value_type() G_GNUC_CONST;
 };
-ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl
+ifelse(`$7',,,`_DEPRECATE_IFDEF_END')`'dnl
 
 } // namespace Glib
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
-m4_ifelse($7,0,`dnl  not in_class
 __NAMESPACE_BEGIN__
-',`dnl else
-_POP()
-')dnl endif
 _PUSH(SECTION_SRC_GENERATED)
-ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl
+ifelse(`$7',,,`_DEPRECATE_IFDEF_START')`'dnl
 // static
-GType Glib::Value<__NAMESPACE__::__ENUM_CLASS_CPPNAME__>::value_type()
+GType Glib::Value<__NAMESPACE__::__ENUM_CPPNAME__>::value_type()
 {
 m4_ifelse(`$5',,`dnl
   return _GET_TYPE_FUNC(__ENUM_CNAME__);
@@ -147,7 +102,7 @@ m4_ifelse(`$5',,`dnl
   return `$5()';
 ')dnl
 }
-ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl
+ifelse(`$7',,,`_DEPRECATE_IFDEF_END')`'dnl
 
 _POP()
 ')dnl endif !NO_GTYPE
index 2f35e7e..78046ff 100644 (file)
@@ -1,6 +1,6 @@
 dnl
-dnl _GERROR(cpp_type, c_type, domain, `element_list', `gtype_func', `class_docs', `enum_docs', 'deprecated')
-dnl            $1       $2      $3         $4              $5           $6           $7            $8
+dnl _GERROR(cpp_type, c_type, domain, `element_list', `gtype_func', `class_docs', `enum_docs', 'deprecated', `decl_prefix')
+dnl            $1       $2      $3         $4              $5            $6           $7            $8             $9
 dnl
 
 m4_define(`_GERROR',`dnl
@@ -17,7 +17,7 @@ ifelse(`$6',,,`dnl
 /** $6
  */
 ')dnl
-class __CPPNAME__ : public Glib::Error
+class $9 __CPPNAME__ : public Glib::Error
 {
 public:
   /** $7
@@ -36,7 +36,7 @@ private:
 
   static void throw_func(GError* gobject);
 
-  friend void wrap_init(); // uses throw_func()
+  friend $9 void wrap_init(); // uses throw_func()
 
   _IMPORT(SECTION_H_GERROR_PRIVATE)
 #endif //DOXYGEN_SHOULD_SKIP_THIS
index 279f0ee..3ca4de6 100644 (file)
@@ -45,7 +45,7 @@ ifelse(`$8',,,`$8
 ')dnl
 ',dnl If the C function returns non-void:
 dnl Store the return if there are C output parameters.
-`ifelse(`$6',,`  return ',`  auto retvalue = ')_CONVERT($4,`$3',`$2`'(ifelse(`$9',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$7',,,`, ')$7)');
+`ifelse(`$6',,`  return ',`  `$3' retvalue = ')_CONVERT($4,`$3',`$2`'(ifelse(`$9',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$7',,,`, ')$7)');
 dnl Insert the initializations for the C output parameters
 ifelse(`$8',,,`$8
 ')dnl
@@ -78,7 +78,7 @@ dnl Insert the declarations for C output parameters
 ifelse(`$6',,,`$6
 ')`'dnl
 ifelse(`$16',,dnl If no C++ output parameter is specified:
-`  ifelse(`$3',void,,`auto retvalue = ')_CONVERT($4,`$3',`$2`'(ifelse(`$9',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$7',,,`, ')$7)');
+`  ifelse(`$3',void,,``$3' retvalue = ')_CONVERT($4,`$3',`$2`'(ifelse(`$9',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$7',,,`, ')$7)');
 'dnl
 ,dnl A C++ output parameter is specified:
 `  _INITIALIZE($17,$4,`$16',`$2`'(ifelse(`$9',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$7',,,`, ')$7)',$21);
@@ -144,7 +144,7 @@ dnl If no C++ output parameter is specified.
 `  ifelse(`$3',void,,dnl
 dnl Returns non-void:
 dnl Store the return if there are C output parameters
-ifelse(`$6',,`return ',`auto retval = '))_CONVERT($4,`$3',`$2`'($7)');'dnl
+ifelse(`$6',,`return ',``$3' retval = '))_CONVERT($4,`$3',`$2`'($7)');'dnl
 dnl A C++ output parameter is specified so initialize it from C return
 ,`  _INITIALIZE($14,$4,`$13',`$2`'($7)',$18);'dnl
 )
@@ -171,7 +171,7 @@ dnl Insert the declarations for the C output parameters
 ifelse(`$6',,,`$6
 ')`'dnl
 ifelse(`$13',,dnl If no C++ output parameter is specified:
-  ifelse(`$3',void,,`auto retvalue = ')_CONVERT($4,`$3',`$2`'($7)');dnl
+  ifelse(`$3',void,,``$3' retvalue = ')_CONVERT($4,`$3',`$2`'($7)');dnl
 dnl A C++ output parameter is specified:
 ,`  _INITIALIZE($14,$4,`$13',`$2`'($7)',$18);'dnl
 )dnl
index c4544de..1709aff 100644 (file)
@@ -4,8 +4,8 @@ dnl  Code generation sections for properties
 dnl
 dnl
 
-dnl                  $1         $2            $3          $4           $5        $6      $7
-dnl _PROPERTY_PROXY(name, name_underscored, cpp_type, proxy_suffix, deprecated, docs, check_type)
+dnl                  $1         $2            $3          $4           $5        $6
+dnl _PROPERTY_PROXY(name, name_underscored, cpp_type, proxy_suffix, deprecated, docs)
 dnl proxy_suffix could be "", "_WriteOnly" or "_ReadOnly"
 dnl The method will be const if the propertyproxy is _ReadOnly.
 dnl
@@ -25,12 +25,6 @@ ifelse($4,_ReadOnly,get,`ifelse($4,_WriteOnly,set,get or set)') the value of the
 _PUSH(SECTION_CC_PROPERTYPROXIES)
 ifelse(`$5',,,`_DEPRECATE_IFDEF_START
 ')dnl
-ifelse(`$7',,,`dnl
-static_assert(`$7'<_QUOTE($3)>::value,
-  "Type _QUOTE($3) cannot be used in _WRAP_PROPERTY. "
-  "There is no suitable template specialization of Glib::Value<>.");
-
-')dnl
 __PROXY_TYPE__ __CPPNAME__::property_$2`'() ifelse($4,_ReadOnly, const,)
 {
   return __PROXY_TYPE__`'(this, "$1");
index f245799..5b680f4 100644 (file)
@@ -24,17 +24,17 @@ ifelse(`$9',,,`_DEPRECATE_IFDEF_START
 ')dnl
 ifelse($13,,`dnl no detail_name
 $10
-  Glib::SignalProxy<$5`'($6)> signal_$4`'();
+  Glib::SignalProxy< $5`'_COMMA_PREFIX($6) > signal_$4`'();
 ',dnl detail_name
 $14,0,`dnl
 $10
-  Glib::SignalProxyDetailed<$5`'($6)> signal_$4`'(const Glib::ustring& $13 = {});
+  Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) > signal_$4`'(const Glib::ustring& $13 = Glib::ustring());
 ',`dnl detail_name and two_signal_methods
 $10
-  Glib::SignalProxy<$5`'($6)> signal_$4`'();
+  Glib::SignalProxy< $5`'_COMMA_PREFIX($6) > signal_$4`'();
 
 $10
-  Glib::SignalProxyDetailed<$5`'($6)> signal_$4`'(const Glib::ustring& $13);
+  Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) > signal_$4`'(const Glib::ustring& $13);
 ')dnl end detail_name
 ifelse(`$9',,,`_DEPRECATE_IFDEF_END
 ')dnl
@@ -65,7 +65,7 @@ ifelse($8,`1',,`dnl Do not generate the implementation if it should be custom:
 static $2 __CPPNAME__`'_signal_$4_callback`'(__CNAME__`'* self, _COMMA_SUFFIX($3)`'void* data)
 {
   using namespace __NAMESPACE__;
-  using SlotType = sigc::slot<$5`'($6)>;
+  using SlotType = sigc::slot< $5`'_COMMA_PREFIX($6) >;
 
   auto obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self));
   // Do not try to call a signal on a disassociated wrapper.
@@ -107,7 +107,7 @@ ifelse($2,void,,`dnl else
 static $2 __CPPNAME__`'_signal_$4_notify_callback`'(__CNAME__`'* self, _COMMA_SUFFIX($3)`' void* data)
 {
   using namespace __NAMESPACE__;
-  using SlotType = sigc::slot<void($6)>;
+  using SlotType = sigc::slot< void`'_COMMA_PREFIX($6) >;
 
   auto obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self));
   // Do not try to call a signal on a disassociated wrapper.
@@ -161,25 +161,25 @@ ifelse(`$11',,,`#ifdef $11'
 ifelse(`$9',,,`_DEPRECATE_IFDEF_START
 ')dnl
 ifelse($13,,`dnl no detail_name
-Glib::SignalProxy<$5`'($6)> __CPPNAME__::signal_$4`'()
+Glib::SignalProxy< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'()
 {
-  return Glib::SignalProxy<$5`'($6) >(this, &__CPPNAME__`'_signal_$4_info);
+  return Glib::SignalProxy< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info);
 }
 ',dnl detail_name
 $14,0,`dnl
-Glib::SignalProxyDetailed<$5`'($6)> __CPPNAME__::signal_$4`'(const Glib::ustring& $13)
+Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'(const Glib::ustring& $13)
 {
-  return Glib::SignalProxyDetailed<$5`'($6)>(this, &__CPPNAME__`'_signal_$4_info, $13);
+  return Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info, $13);
 }
 ',`dnl detail_name and two_signal_methods
-Glib::SignalProxy<$5`'($6)> __CPPNAME__::signal_$4`'()
+Glib::SignalProxy< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'()
 {
-  return Glib::SignalProxy<$5`'($6)>(this, &__CPPNAME__`'_signal_$4_info);
+  return Glib::SignalProxy< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info);
 }
 
-Glib::SignalProxyDetailed<$5`'($6)> __CPPNAME__::signal_$4`'(const Glib::ustring& $13)
+Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'(const Glib::ustring& $13)
 {
-  return Glib::SignalProxyDetailed<$5`'($6)>(this, &__CPPNAME__`'_signal_$4_info, $13);
+  return Glib::SignalProxyDetailedAnyType< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info, $13);
 }
 ')dnl end detail_name
 ifelse(`$9',,,`_DEPRECATE_IFDEF_END
@@ -350,3 +350,4 @@ ifelse($8,refreturn,`dnl Assume Glib::wrap() is correct if refreturn is requeste
 ifelse(`$9',,,`#endif // $9
 ')dnl
 _POP()')
+
diff --git a/tools/meson.build b/tools/meson.build
new file mode 100644 (file)
index 0000000..0bc3510
--- /dev/null
@@ -0,0 +1,101 @@
+# tools
+
+# Input: perl, m4, install_prefix, install_libdir, glibmm_pcname
+# Output: m4_files, install_m4dir, pm_files, install_pmdir, gmmproc,
+#         generate_wrap_init_pl
+
+subdir('extra_defs_gen')
+
+install_procdir = install_libdir / glibmm_pcname / 'proc'
+
+# Configuration data for gmmproc.
+gmmproc_conf_data = configuration_data()
+gmmproc_conf_data.set('PERL', perl.found() ? perl.path() : '')
+gmmproc_conf_data.set('configure_input', 'tools/gmmproc.  Generated from gmmproc.in')
+gmmproc_conf_data.set('prefix', install_prefix)
+gmmproc_conf_data.set('exec_prefix', '${prefix}')
+gmmproc_conf_data.set('libdir', '${exec_prefix}' / install_libdir)
+gmmproc_conf_data.set('GLIBMM_MODULE_NAME', glibmm_pcname)
+gmmproc_conf_data.set('M4', m4.found() ? '/'.join(m4.path().split('\\')) : '')
+gmmproc_conf_data.set('PACKAGE_VERSION', meson.project_version())
+
+gmmproc = configure_file(
+  input: 'gmmproc.in',
+  output: '@BASENAME@',
+  configuration: gmmproc_conf_data,
+  install_dir: install_procdir,
+)
+
+# Configuration data for generate_wrap_init.pl.
+gen_wrap_init_conf_data = configuration_data()
+gen_wrap_init_conf_data.set('PERL', perl.found() ? perl.path() : '')
+gen_wrap_init_conf_data.set('configure_input',
+  'tools/generate_wrap_init.pl.  Generated from generate_wrap_init.pl.in')
+
+generate_wrap_init_pl = configure_file(
+  input: 'generate_wrap_init.pl.in',
+  output: '@BASENAME@',
+  configuration: gen_wrap_init_conf_data,
+  install_dir: install_procdir,
+)
+
+# Install m4 files for reuse by other *mm projects, when building from git.
+m4_basefiles = [
+  'base.m4',
+  'class_boxedtype.m4',
+  'class_boxedtype_static.m4',
+  'class_generic.m4',
+  'class_gobject.m4',
+  'class_interface.m4',
+  'class_opaque_copyable.m4',
+  'class_opaque_refcounted.m4',
+  'class_shared.m4',
+  'compare.m4',
+  'convert.m4',
+  'convert_base.m4',
+  'convert_gio.m4',
+  'convert_glib.m4',
+  'convert_glibmm.m4',
+  'ctor.m4',
+  'doc.m4',
+  'enum.m4',
+  'gerror.m4',
+  'initialize.m4',
+  'initialize_base.m4',
+  'initialize_gio.m4',
+  'initialize_glib.m4',
+  'initialize_glibmm.m4',
+  'member.m4',
+  'method.m4',
+  'property.m4',
+  'signal.m4',
+  'vfunc.m4',
+]
+m4_files = []
+foreach file : m4_basefiles
+  m4_files += 'm4' / file
+endforeach
+m4_files = files(m4_files)
+install_m4dir = install_procdir / 'm4'
+install_data(m4_files, install_dir: install_m4dir)
+
+# Install pm files for reuse by other *mm projects, when building from git.
+pm_basefiles = [
+  'DocsParser.pm',
+  'Enum.pm',
+  'Function.pm',
+  'FunctionBase.pm',
+  'GtkDefs.pm',
+  'Object.pm',
+  'Output.pm',
+  'Property.pm',
+  'Util.pm',
+  'WrapParser.pm',
+]
+pm_files = []
+foreach file : pm_basefiles
+  pm_files += 'pm' / file
+endforeach
+pm_files = files(pm_files)
+install_pmdir = install_procdir / 'pm'
+install_data(pm_files, install_dir: install_pmdir)
index 20bcaf3..fb6d55c 100644 (file)
@@ -472,12 +472,6 @@ sub append_parameter_docs($$;$)
   # due to imperfections in the C docs, and it's difficult to get the C docs
   # corrected, correct docs can be added to the docs_override.xml file.
 
-  if (scalar @docs_param_names != scalar @c_param_names)
-  {
-    print STDERR "DocsParser.pm: Warning, $$obj_function{name}\n" .
-      "  Incompatible parameter lists in the docs.xml file and the methods.defs file.\n";
-  }
-
   # Skip first param if this is a signal.
   if ($$obj_function{name} =~ /\w+::/)
   {
@@ -514,14 +508,8 @@ sub append_parameter_docs($$;$)
   # Skip the last param if it's an error output param.
   if (scalar @docs_param_names && $docs_param_names[-1] eq "error")
   {
-    # If the number of parameters in @docs_param_names is not greater than
-    # the number of parameters in the _WRAP macro, the parameter called "error"
-    # is probably not an error output parameter.
-    if (!defined($objCppfunc) || scalar @docs_param_names > scalar @{$$objCppfunc{param_names}})
-    {
-      pop(@docs_param_names);
-      pop(@c_param_names);
-    }
+    pop(@docs_param_names);
+    pop(@c_param_names);
   }
 
   my $cpp_param_names;
@@ -535,11 +523,6 @@ sub append_parameter_docs($$;$)
     {
       $out_param_index = $$param_mappings{OUT};
     }
-    if (scalar @docs_param_names != scalar @$cpp_param_names)
-    {
-      print STDERR "DocsParser.pm: Warning, $$obj_function{name}\n" .
-        "  Incompatible parameter lists in the docs.xml file and the _WRAP macro.\n";
-    }
   }
   my %param_name_mappings; # C name -> C++ name
 
@@ -918,8 +901,7 @@ sub substitute_enumerator_name($$)
 
   my $cxx_name = (($module eq "G") ? "" : (ucfirst(lc($module)) . "::")) . $name;
 
-  print "DocsParser.pm: Assuming the enumerator $c_name shall become $cxx_name.\n";
-
+  #print "DocsParser.pm: Assuming the enumerator $c_name shall become $cxx_name.\n";
   return $cxx_name;
 }
 
index c3866c8..ceb705c 100644 (file)
@@ -26,7 +26,6 @@ our @EXPORT_OK;
 #       string module;
 #       string c_type;
 #
-#       string array elem_short_names;
 #       string array elem_names;
 #       string array elem_values;
 #       string c_prefix;
@@ -148,7 +147,6 @@ sub new
   $$self{flags} = 0;
   $$self{c_prefix} = "";
 
-  $$self{elem_short_names}  = [];
   $$self{elem_names}  = [];
   $$self{elem_values} = [];
 
@@ -175,7 +173,6 @@ sub new
   }
 
   # this should never happen
-  warn if(scalar(@{$$self{elem_short_names}}) != scalar(@{$$self{elem_values}}));
   warn if(scalar(@{$$self{elem_names}}) != scalar(@{$$self{elem_values}}));
 
   return $self;
@@ -185,7 +182,6 @@ sub parse_values($$)
 {
   my ($self, $value) = @_;
 
-  my $elem_short_names  = [];
   my $elem_names  = [];
   my $elem_values = [];
   my $common_prefix = undef;
@@ -193,9 +189,9 @@ sub parse_values($$)
   # and handles triples like '("dq-token", "MY_SCANNER_DQ_TOKEN", "'"'").
   foreach (split_enum_tokens($value))
   {
-    if (/^"(\S+)" "(\S+)" "(.+)"$/)
+    if (/^"\S+" "(\S+)" "(.+)"$/)
     {
-      my ($nick_name, $name, $value) = ($1, $2, $3);
+      my ($name, $value) = ($1, $2);
 
       # detect whether there is module prefix common to all names, e.g. GTK_
       my $prefix = $1 if ($name =~ /^([^_]+_)/);
@@ -209,18 +205,6 @@ sub parse_values($$)
         $common_prefix = "";
       }
 
-      # enum.pl generates nick names from the C names of the enum constants.
-      # A nick name consists of the trailing part of the enum name.
-      # The leading part which is common for each constant of an enum type
-      # has been removed. The remaining part is then transformed to lowercase
-      # and hyphens.
-      # The nick names would have been suitable for 'enum class' definitions
-      # if they had not been transformed to lowercase and hyphens.
-      # But the length of the nick names can be used. Create short names
-      # consisting of the trailing part of the names with the same length
-      # as the nick names.
-      my $short_name = substr($name, length($name) - length($nick_name));
-      push(@$elem_short_names, $short_name);
       push(@$elem_names, $name);
       push(@$elem_values, $value);
     }
@@ -239,18 +223,17 @@ sub parse_values($$)
     $$self{c_prefix}  = $common_prefix;
   }
 
-  $$self{elem_short_names}  = $elem_short_names;
   $$self{elem_names}  = $elem_names;
   $$self{elem_values} = $elem_values;
 }
 
-sub beautify_values($$)
+sub beautify_values($)
 {
-  my ($self, $use_short_names) = @_;
+  my ($self) = @_;
 
   return if($$self{flags});
 
-  my $elem_names  = $use_short_names ? $$self{elem_short_names} : $$self{elem_names};
+  my $elem_names  = $$self{elem_names};
   my $elem_values = $$self{elem_values};
 
   my $num_elements = scalar(@$elem_values);
@@ -294,9 +277,9 @@ sub beautify_values($$)
 
 sub build_element_list($$$$)
 {
-  my ($self, $use_short_names, $ref_subst_in, $ref_subst_out, $indent) = @_;
+  my ($self, $ref_subst_in, $ref_subst_out, $indent) = @_;
 
-  my $elem_names  = $use_short_names ? $$self{elem_short_names} : $$self{elem_names};
+  my $elem_names  = $$self{elem_names};
   my $elem_values = $$self{elem_values};
 
   my $num_elements = scalar(@$elem_names);
@@ -324,19 +307,6 @@ sub build_element_list($$$$)
   return $elements;
 }
 
-# The name prefix is defined by: $name_prefix . $short_name eq $name
-# I.e. what shall be chopped off the name to get the short name.
-sub get_name_prefix($)
-{
-  my ($self) = @_;
-
-  my $name = ${$$self{elem_names}}[0];
-  my $short_name = ${$$self{elem_short_names}}[0];
-  my $prefix_length = length($name) - length($short_name);
-
-  return substr($name, 0, $prefix_length);
-}
-
 sub dump($)
 {
   my ($self) = @_;
index 37ffdd3..f962216 100644 (file)
@@ -226,7 +226,7 @@ sub parse_param($$)
   # but possibly spaces between the multiple ">>".
   # Quoted strings are not detected. If a quoted string exists in a function
   # prototype, it's probably as part of a default value, inside ("x") or {"y"}.
-  # 
+  #
   my @str = ();
   foreach (split(/(\bconst\b|[,=&*>]|<.*?>|{.*?}|\(.*?\)|\s+)/, $line))
   {
index a7bdc8c..63dcd69 100644 (file)
@@ -684,13 +684,13 @@ sub output_wrap_sig_decl($$$$$$$$$$$$$$)
 }
 
 # void output_wrap_enum($filename, $line_num, $cpp_type, $c_type,
-#   $comment, $ref_subst_in, $ref_subst_out, $gtype_func, $conv_to_int,
-#   $in_class, $deprecated, $deprecation_docs, $newin)
-sub output_wrap_enum($$$$$$$$$$$$$$)
+#   $comment, $ref_subst_in, $ref_subst_out, $gtype_func,
+#   $deprecated, $deprecation_docs, $newin)
+sub output_wrap_enum($$$$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $cpp_type, $c_type,
-    $comment, $ref_subst_in, $ref_subst_out, $gtype_func, $conv_to_int,
-    $in_class, $deprecated, $deprecation_docs, $newin) = @_;
+    $comment, $ref_subst_in, $ref_subst_out, $gtype_func,
+    $deprecated, $deprecation_docs, $newin) = @_;
 
   my $objEnum = GtkDefs::lookup_enum($c_type);
   if(!$objEnum)
@@ -699,12 +699,9 @@ sub output_wrap_enum($$$$$$$$$$$$$$)
     return;
   }
 
-  $objEnum->beautify_values(1);
+  $objEnum->beautify_values();
 
-  my $indent = "  ";
-  $indent .= "  " if ($in_class);
-  $indent .= "  " if ($conv_to_int);
-  my $elements = $objEnum->build_element_list(1, $ref_subst_in, $ref_subst_out, $indent);
+  my $elements = $objEnum->build_element_list($ref_subst_in, $ref_subst_out, "  ");
   add_m4_quotes(\$elements);
 
   if(!$elements)
@@ -713,57 +710,37 @@ sub output_wrap_enum($$$$$$$$$$$$$$)
     return;
   }
 
-  # Chop off the name prefix in the documentation.
-  my $name_prefix = $objEnum->get_name_prefix();
-  unshift(@$ref_subst_in, "^$name_prefix");
-  unshift(@$ref_subst_out, "");
+  my $value_suffix = "Enum";
+  $value_suffix = "Flags" if($$objEnum{flags});
 
   # Get the enum documentation from the parsed docs.
-  $indent = substr($indent, 1); # Remove one blank
   my $enum_docs = DocsParser::lookup_enum_documentation("$c_type", "$cpp_type",
-    $indent, $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin);
+    " ", $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin);
 
   # Merge the passed in comment to the existing enum documentation.
-  $comment .= "\n$indent* $enum_docs" if $enum_docs ne "";
+  $comment .= "\n * " . $enum_docs if $enum_docs ne "";
 
-  my $value_suffix = "Enum";
-  $value_suffix = "Flags" if ($$objEnum{flags});
-
-  my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\',%d,\`%s\',\`%s\')dnl\n",
+  my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\')dnl\n",
     $cpp_type,
     $c_type,
     $value_suffix,
     $elements,
     $gtype_func,
-    $conv_to_int,
-    $in_class,
     $comment,
     $deprecated
   );
+
   $self->append($str);
 }
 
-sub output_wrap_enum_docs_only($$$$$$$$$$$$)
+sub output_wrap_enum_docs_only($$$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $module_canonical, $cpp_type, $c_type,
-    $comment, $ref_subst_in, $ref_subst_out, $in_class, $deprecation_docs, $newin) = @_;
+    $comment, $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin) = @_;
 
-  my $objEnum = GtkDefs::lookup_enum($c_type);
-  if(!$objEnum)
-  {
-    $self->output_wrap_failed($c_type, "enum defs lookup failed.");
-    return;
-  }
-  # Chop off the name prefix in the documentation.
-  my $name_prefix = $objEnum->get_name_prefix();
-  unshift(@$ref_subst_in, "^$name_prefix");
-  unshift(@$ref_subst_out, "");
-
-  # Get the enum documentation from the parsed docs.
-  my $indent = " ";
-  $indent .= "  " if ($in_class);
+  # Get the existing enum description from the parsed docs.
   my $enum_docs = DocsParser::lookup_enum_documentation("$c_type", "$cpp_type",
-    $indent, $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin);
+    " ", $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin);
 
   if($enum_docs eq "")
   {
@@ -772,22 +749,22 @@ sub output_wrap_enum_docs_only($$$$$$$$$$$$)
   }
 
   # Include the enum docs in the module's enum docs group.
-  $enum_docs .= "\n$indent*\n$indent* \@ingroup ${module_canonical}Enums";
+  $enum_docs .= "\n *\n * \@ingroup ${module_canonical}Enums";
 
   # Merge the passed in comment to the existing enum documentation.
-  $comment = "/** " . $comment . "\n$indent* " . $enum_docs . "\n$indent*/\n";
+  $comment = "/** " . $comment . "\n * " . $enum_docs . "\n */\n";
 
   $self->append($comment);
 }
 
 # void output_wrap_gerror($filename, $line_num, $cpp_type, $c_type, $domain,
 #  $class_docs, $ref_subst_in, $ref_subst_out, $gtype_func,
-#  $deprecated, $deprecation_docs, $newin)
-sub output_wrap_gerror($$$$$$$$$$$$$)
+#  $deprecated, $deprecation_docs, $newin, $decl_prefix)
+sub output_wrap_gerror($$$$$$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $cpp_type, $c_type, $domain,
     $class_docs, $ref_subst_in, $ref_subst_out, $gtype_func,
-    $deprecated, $deprecation_docs, $newin) = @_;
+    $deprecated, $deprecation_docs, $newin, $decl_prefix) = @_;
 
   my $objDefsParser = $$self{objDefsParser};
 
@@ -801,7 +778,7 @@ sub output_wrap_gerror($$$$$$$$$$$$$)
   # Shouldn't happen, and if it does, I'd like to know that.
   warn if($$objEnum{flags});
 
-  $objEnum->beautify_values(0);
+  $objEnum->beautify_values();
 
   # cut off the module prefix, e.g. GDK_
   my $prefix = $domain;
@@ -811,7 +788,7 @@ sub output_wrap_gerror($$$$$$$$$$$$$)
   unshift(@$ref_subst_in, "^${prefix}_");
   unshift(@$ref_subst_out, "");
 
-  my $elements = $objEnum->build_element_list(0, $ref_subst_in, $ref_subst_out, "    ");
+  my $elements = $objEnum->build_element_list($ref_subst_in, $ref_subst_out, "    ");
   add_m4_quotes(\$elements);
 
   # Get the enum documentation from the parsed docs.
@@ -845,7 +822,7 @@ sub output_wrap_gerror($$$$$$$$$$$$$)
   # Prevent Doxygen from auto-linking to a class called Exception.
   $class_docs =~ s/([^%])(Exception class)/$1%$2/g;
 
-  my $str = sprintf("_GERROR(%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',\`%s\')dnl\n",
+  my $str = sprintf("_GERROR(%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',\`%s\',\`%s\')dnl\n",
     $cpp_type,
     $c_type,
     $domain,
@@ -853,19 +830,19 @@ sub output_wrap_gerror($$$$$$$$$$$$$)
     $gtype_func,
     $class_docs,
     $enum_docs,
-    $deprecated
+    $deprecated,
+    $decl_prefix
   );
 
   $self->append($str);
 }
 
 # _PROPERTY_PROXY(name, cpp_type) and _CHILD_PROPERTY_PROXY(name, cpp_type)
-# void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class,
-#   $deprecated, $deprecation_docs, $newin, $bNoTypeCheck, $objProperty, $proxy_macro)
+# void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro)
 sub output_wrap_any_property($$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated,
-      $deprecation_docs, $newin, $bNoTypeCheck, $objProperty, $proxy_macro) = @_;
+      $deprecation_docs, $newin, $objProperty, $proxy_macro) = @_;
 
   my $objDefsParser = $$self{objDefsParser};
 
@@ -951,34 +928,19 @@ sub output_wrap_any_property($$$$$$$$$$)
     $documentation .= $default_value;
   }
 
-  # Possibly generate a static_assert(), asserting that the generated code
-  # will include a Glib::Value instantiation which is compatible with
-  # _WRAP_PROPERTY and _WRAP_CHILD_PROPERTY.
-  # This test is skipped for some types that are known to have suitable
-  # Glib::Value<> instantiations, or if the no_type_check parameter is specified.
-  my $check_type = "";
-  if (!$bNoTypeCheck)
-  {
-    my @good_types = qw(bool int guint float double std::string Glib::ustring
-                        Widget* Gtk::Widget*);
-    push(@good_types, "unsigned int");
-    $check_type = "Glib::Traits::ValueCompatibleWithWrapProperty" if (!grep {$cpp_type eq $_} @good_types);
-  }
-
   #Declaration:
   if($deprecated ne "")
   {
     $self->append("\n_DEPRECATE_IFDEF_START\n");
   }
 
-  my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s',`%s')dnl\n",
+  my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
     $name,
     $name_underscored,
     $cpp_type,
     $proxy_suffix,
     $deprecated,
-    $documentation,
-    $check_type
+    $documentation
   );
   $self->append($str);
   $self->append("\n");
@@ -987,15 +949,13 @@ sub output_wrap_any_property($$$$$$$$$$)
   # then add a second const accessor for a read-only propertyproxy:
   if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
   {
-    $check_type = ""; # Don't check twice.
-    my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s',`%s')dnl\n",
+    my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
       $name,
       $name_underscored,
       $cpp_type,
       "_ReadOnly",
       $deprecated,
-      $documentation,
-      $check_type
+      $documentation
     );
     $self->append($str);
   }
@@ -1008,11 +968,11 @@ sub output_wrap_any_property($$$$$$$$$$)
 
 # _PROPERTY_PROXY(name, cpp_type)
 # void output_wrap_property($filename, $line_num, $name, $cpp_type, $file_deprecated,
-#   $deprecated, $deprecation_docs, $newin, $bNoTypeCheck)
+#   $deprecated, $deprecation_docs)
 sub output_wrap_property($$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $file_deprecated,
-      $deprecated, $deprecation_docs, $newin, $bNoTypeCheck) = @_;
+      $deprecated, $deprecation_docs, $newin) = @_;
 
   my $objProperty = GtkDefs::lookup_property($c_class, $name);
   if($objProperty eq 0) #If the lookup failed:
@@ -1025,18 +985,17 @@ sub output_wrap_property($$$$$$$$$$)
       $deprecated, $name, "property", "PROPERTY");
 
     $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class,
-      $deprecated, $deprecation_docs, $newin, $bNoTypeCheck, $objProperty,
-      "_PROPERTY_PROXY");
+      $deprecated, $deprecation_docs, $newin, $objProperty, "_PROPERTY_PROXY");
   }
 }
 
 # _CHILD_PROPERTY_PROXY(name, cpp_type)
 # void output_wrap_child_property($filename, $line_num, $name, $cpp_type, $file_deprecated,
-#   $deprecated, $deprecation_docs, $newin, $bNoTypeCheck)
+#   $deprecated, $deprecation_docs)
 sub output_wrap_child_property($$$$$$$$$$)
 {
   my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $file_deprecated,
-      $deprecated, $deprecation_docs, $newin, $bNoTypeCheck) = @_;
+      $deprecated, $deprecation_docs, $newin) = @_;
 
   my $objChildProperty = GtkDefs::lookup_child_property($c_class, $name);
   if($objChildProperty eq 0) #If the lookup failed:
@@ -1049,8 +1008,7 @@ sub output_wrap_child_property($$$$$$$$$$)
       $deprecated, $name, "child property", "CHILD_PROPERTY");
 
     $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class,
-      $deprecated, $deprecation_docs, $newin, $bNoTypeCheck, $objChildProperty,
-      "_CHILD_PROPERTY_PROXY");
+      $deprecated, $deprecation_docs, $newin, $objChildProperty, "_CHILD_PROPERTY_PROXY");
   }
 }
 
index 20af0f0..2e2121a 100644 (file)
@@ -669,43 +669,45 @@ sub extract_bracketed_text($)
   my $str = "";
 
   # Move to the first "(":
-  while (scalar(@tokens))
-  {
-    my $t = $self->extract_token();
-    last if ($t eq "(");
-  }
+  while ( scalar(@tokens) )
+    {
+      my $t = $self->extract_token();
+      last if ($t eq "(");
+    }
 
-  my $filename = $$self{filename};
-  my $line_num = $$self{line_num};
+  # TODO: Don't count "(" and ")" within double quotes.
+  # There may be .hg files with unpaired quotes that generate correct
+  # .h and .cc files. Don't want to break such code yet.
+  # See also TODO in string_split_commas().
 
   # Concatenate until the corresponding ")":
-  while (scalar(@tokens) and $filename eq $$self{filename})
-  {
-    my $t = $self->extract_token();
-    $in_quotes = !$in_quotes if ($t eq '"');
-    # Don't count "(" and ")" within double quotes.
-    if (!$in_quotes)
+  while ( scalar(@tokens) )
     {
+      my $t = $self->extract_token();
+      $in_quotes = !$in_quotes if ($t eq '"');
       $level++ if ($t eq "(");
       $level-- if ($t eq ")");
-      return $str if (!$level); # Found matching ")"
+
+      if (!$level)
+      {
+        $self->error("End of gmmproc directive within a quoted string.\n") if $in_quotes;
+        return $str;
+      }
+      $str .= $t;
     }
-    $str .= $t;
-  }
 
-  # No matching ")" found.
-  my $quote_text = $in_quotes ? " in a quoted string" : "";
-  die "$filename:$line_num: *** End of file$quote_text in a gmmproc macro. ***\n";
+  return "";
 }
 
 
 ########################################
 ###  breaks up a string by commas (smart)
-# @strings string_split_commas($string)
-sub string_split_commas($)
+# @strings string_split_commas($string [, $ignore_quotes])
+sub string_split_commas($;$)
 {
-  my ($in) = @_;
+  my ($in, $ignore_quotes) = @_;
 
+  $ignore_quotes = 2 unless defined $ignore_quotes;
   my @out;
   my $level = 0;
   my $in_quotes = 0;
@@ -718,7 +720,10 @@ sub string_split_commas($)
 
     next if ($t eq "");
 
-    $in_quotes = !$in_quotes if ($t eq '"');
+    # TODO: Delete the test for scalar(@out) >= $ignore_quotes when we can stop accepting
+    # .hg files with unpaired quotes, such as _WRAP_PROPERTY("text_column, int).
+    # See also TODO in extract_bracketed_text().
+    $in_quotes = !$in_quotes if ($t eq '"' and scalar(@out) >= $ignore_quotes);
     if (!$in_quotes)
     {
       $level++ if ($t eq "(" or $t eq "<" or $t eq "{");
@@ -987,8 +992,8 @@ sub on_wrap_method($)
     }
     # The "slot_callback" option tells gmmproc the name of the
     # callback function that should be passed to the C function if the
-    # method has a slot. The name can contain a namespace prefix.
-    elsif($argRef =~ /^slot_callback\s+([:\w]+)/)
+    # method has a slot.
+    elsif($argRef =~ /^slot_callback\s+(\w+)/)
     {
       $$objCppfunc{slot_callback} = $1;
     }
@@ -1025,7 +1030,7 @@ sub on_wrap_method_docs_only($)
   my $line_num = $$self{line_num};
 
   my $str = $self->extract_bracketed_text();
-  my @args = string_split_commas($str);
+  my @args = string_split_commas($str, 1);
 
   my $entity_type = "method";
 
@@ -1436,10 +1441,10 @@ sub on_wrap_any_enum($$)
   my @subst_in  = [];
   my @subst_out = [];
   my $gtype_func = "";
-  my $conv_to_int = "";
   my $argDeprecated = "";
   my $deprecation_docs = "";
   my $newin = "";
+  my $decl_prefix = "";
 
   # $gtype_func:
   # 1. If an empty string, the M4 macro _ENUM or _GERROR calls _GET_TYPE_FUNC()
@@ -1457,16 +1462,12 @@ sub on_wrap_any_enum($$)
 
     if ($arg eq "NO_GTYPE")
     {
-      $gtype_func = $arg;
+      $gtype_func = "NO_GTYPE";
     }
     elsif ($arg =~ /^gtype_func\s+(\w+)/)
     {
       $gtype_func = $1;
     }
-    elsif (!$is_gerror and $arg eq "CONV_TO_INT")
-    {
-      $conv_to_int = $arg;
-    }
     elsif ($arg =~ /^s#([^#]+)#([^#]*)#$/)
     {
       push(@subst_in,  $1);
@@ -1485,33 +1486,15 @@ sub on_wrap_any_enum($$)
     {
       $newin = string_unquote(string_trim($1));
     }
+    elsif ($arg =~ /^decl_prefix(.*)/) #If decl_prefix is at the start.
+    {
+      $decl_prefix = string_unquote(string_trim($1));
+    }
   }
   return ($cpp_type, $c_type, $domain, \@subst_in, \@subst_out, $gtype_func,
-    $conv_to_int, $argDeprecated, $deprecation_docs, $newin);
+    $argDeprecated, $deprecation_docs, $newin, $decl_prefix);
 }
 
-# void on_wrap_enum()
-# _WRAP_ENUM(cpp_type, c_type [,NO_GTYPE] [,gtype_func funcname] [,CONV_TO_INT] [,s#regexpr#subst#]*)
-# Optional arguments:
-# NO_GTYPE Don't generate code for a specialization of the template
-#          Glib::Value_Enum or Glib::Value_Flags.
-#          Necessary, if the C type enum is not registered as a GType.
-# gtype_func funcname Call funcname() in the generated Glib::Value<>::value_type().
-#                     Necessary, if the M4 macro _GET_TYPE_FUNC() can't generate
-#                     the correct function name from the C type name of the enum.
-# CONV_TO_INT "Convertible to int" Generate a plain enum (not an enum class)
-#             within a class. Such an enum is scoped like an enum class,
-#             and it can be implicitly converted to int like a plain enum.
-# s#regexpr#subst# Zero or more substitutions in names of enum constants, e.g. s#^DATE_##.
-#
-# _WRAP_ENUM can be located either in a class or outside all classes.
-# When located in a class, and Value specialization shall be generated or it's
-# a Flags type (i.e. bitwise operators shall be generated), then the following
-# requirements must be fulfilled:
-# 1. _WRAP_ENUM must be located in the public part of the class.
-# 2. The class must contain a class macro (_CLASS_GENERIC, _CLASS_GOBJECT,
-#    _CLASS_GTKOBJECT, etc.) before _WRAP_ENUM.
-#
 sub on_wrap_enum($)
 {
   my ($self) = @_;
@@ -1521,13 +1504,13 @@ sub on_wrap_enum($)
   my $comment = $self->extract_preceding_documentation();
 
   # get the arguments
-  my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, $gtype_func, $conv_to_int,
+  my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, $gtype_func,
     $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(0);
 
   $$self{objOutputter}->output_wrap_enum(
     $$self{filename}, $$self{line_num}, $cpp_type, $c_type,
-    $comment, $ref_subst_in, $ref_subst_out, $gtype_func, $conv_to_int,
-    $$self{in_class}, $argDeprecated, $deprecation_docs, $newin);
+    $comment, $ref_subst_in, $ref_subst_out, $gtype_func,
+    $argDeprecated, $deprecation_docs, $newin);
 }
 
 sub on_wrap_enum_docs_only($)
@@ -1539,7 +1522,7 @@ sub on_wrap_enum_docs_only($)
   my $comment = $self->extract_preceding_documentation();
 
   # get the arguments
-  my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, undef, undef,
+  my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, undef,
     $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(0);
 
   # Get the module name so the enum docs can be included in the module's
@@ -1548,7 +1531,7 @@ sub on_wrap_enum_docs_only($)
 
   $$self{objOutputter}->output_wrap_enum_docs_only(
     $$self{filename}, $$self{line_num}, $module_canonical, $cpp_type, $c_type,
-    $comment, $ref_subst_in, $ref_subst_out, $$self{in_class}, $deprecation_docs, $newin);
+    $comment, $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin);
 }
 
 sub on_wrap_gerror($)
@@ -1563,13 +1546,13 @@ sub on_wrap_gerror($)
   my $class_docs = $self->extract_preceding_documentation();
 
   # get the arguments
-  my ($cpp_type, $c_type, $domain, $ref_subst_in, $ref_subst_out, $gtype_func, undef,
-    $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(1);
+  my ($cpp_type, $c_type, $domain, $ref_subst_in, $ref_subst_out, $gtype_func,
+    $argDeprecated, $deprecation_docs, $newin, $decl_prefix) = $self->on_wrap_any_enum(1);
 
   $$self{objOutputter}->output_wrap_gerror(
     $$self{filename}, $$self{line_num}, $cpp_type, $c_type, $domain,
     $class_docs, $ref_subst_in, $ref_subst_out, $gtype_func,
-    $argDeprecated, $deprecation_docs, $newin);
+    $argDeprecated, $deprecation_docs, $newin, $decl_prefix);
 }
 
 sub on_wrap_any_property($)
@@ -1600,7 +1583,6 @@ sub on_wrap_any_property($)
   my $argDeprecated = "";
   my $deprecation_docs = "";
   my $newin = "";
-  my $bNoTypeCheck = 0;
   while($#args >= 2) # If the optional arguments are there.
   {
     my $argRef = string_trim(pop @args);
@@ -1618,14 +1600,10 @@ sub on_wrap_any_property($)
     {
       $newin = string_unquote(string_trim($1));
     }
-    elsif($argRef eq "no_type_check")
-    {
-      $bNoTypeCheck = 1;
-    }
   }
 
   return ($filename, $line_num, $argPropertyName, $argCppType,
-          $argDeprecated, $deprecation_docs, $newin, $bNoTypeCheck);
+          $argDeprecated, $deprecation_docs, $newin);
 }
 
 sub on_wrap_property($)
@@ -1636,11 +1614,10 @@ sub on_wrap_property($)
   return unless ($self->check_for_eof());
 
   my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated,
-      $deprecation_docs, $newin, $bNoTypeCheck) = $self->on_wrap_any_property();
+      $deprecation_docs, $newin) = $self->on_wrap_any_property();
 
   $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName,
-    $argCppType, $$self{c_class}, $$self{deprecated}, $argDeprecated, $deprecation_docs,
-    $newin, $bNoTypeCheck);
+    $argCppType, $$self{c_class}, $$self{deprecated}, $argDeprecated, $deprecation_docs, $newin);
 }
 
 sub on_wrap_child_property($)
@@ -1651,11 +1628,10 @@ sub on_wrap_child_property($)
   return unless ($self->check_for_eof());
 
   my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated,
-      $deprecation_docs, $newin, $bNoTypeCheck) = $self->on_wrap_any_property();
+      $deprecation_docs, $newin) = $self->on_wrap_any_property();
 
   $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName,
-    $argCppType, $$self{c_class}, $$self{deprecated}, $argDeprecated, $deprecation_docs,
-    $newin, $bNoTypeCheck);
+    $argCppType, $$self{c_class}, $$self{deprecated}, $argDeprecated, $deprecation_docs, $newin);
 }
 
 sub output_wrap_check($$$$$$)
index f859c44..fe01c92 100755 (executable)
@@ -5,9 +5,9 @@
 # files that it depends on.
 
 # Example: In glibmm, go to directory glibmm, and run
-#   tools/test_scripts/testheaders.sh -I glib giomm-2.64 gio # compile glibmm/gio/giomm/*.h
-#   tools/test_scripts/testheaders.sh giomm-2.64 glib gio    # compile glibmm/glib/glibmm/*.h and glibmm/gio/giomm/*.h
-#   tools/test_scripts/testheaders.sh -I glib glibmm-2.64 glib/glibmm/ustring.h # compile glibmm/glib/glibmm/ustring.h
+#   tools/test_scripts/testheaders.sh -I glib giomm-2.4 gio # compile glibmm/gio/giomm/*.h
+#   tools/test_scripts/testheaders.sh giomm-2.4 glib gio    # compile glibmm/glib/glibmm/*.h and glibmm/gio/giomm/*.h
+#   tools/test_scripts/testheaders.sh -I glib glibmm-2.4 glib/glibmm/ustring.h # compile glibmm/glib/glibmm/ustring.h
 
 # Usage: testheaders.sh [-I<dir>]... <pkg> [<dir> | <file>]...
 # -I<dir> is added to the g++ command.
@@ -18,8 +18,6 @@ function usage() {
   exit 1
 }
 
-extra_gcc_args=-std=c++17
-
 # Search for directories to include in CFLAGS.
 idirs=""
 while [ $# -gt 0 ]
@@ -77,11 +75,11 @@ do
     for headerfile in $i/${i}mm/*.h
     do
       echo "=== $headerfile"
-      g++ -c -x c++ $extra_gcc_args -o /dev/null $headerfile $CFLAGS
+      g++ -c -x c++ -std=c++11 -o /dev/null $headerfile $CFLAGS
     done
   else
     echo "=== $i"
-    g++ -c -x c++ $extra_gcc_args -o /dev/null $i $CFLAGS
+    g++ -c -x c++ -std=c++11 -o /dev/null $i $CFLAGS
   fi
 done
 
diff --git a/untracked/README b/untracked/README
new file mode 100644 (file)
index 0000000..0b591d4
--- /dev/null
@@ -0,0 +1,39 @@
+untracked/README
+
+This directory contains files not tracked by a source code control program,
+such as git. (This README file is the exception.)
+
+The files can have one of two origins.
+
+1. Copied by the mm-common-get command.
+2. Generated when glibmm is built.
+
+Files of type 2 exist here only if glibmm is built with maintainer-mode=false,
+or the directory comes from a tarball.
+Files of both types exist here only if glibmm is built with Meson,
+or the tarball is created with Meson.
+
+1. Files copied by mm-common-get
+--------------------------------
+untracked/docs/doc-install.pl
+               doc-postprocess.pl
+               doxygen-extra.css
+               tagfile-to-devhelp2.xsl
+untracked/build_scripts/dist-build-scripts.py
+                        dist-changelog.py
+                        doc-reference.py
+                        generate-binding.py
+
+mm-common-get may copy more files, but they are not used by glibmm.
+
+2. Generated files
+------------------
+untracked/gio/giomm/*.h
+                    *.cc
+                    private/*_p.h
+untracked/glib/glibmm/*.h
+                      *.cc
+                      private/*_p.h
+untracked/docs/reference/glibmm-2.4.devhelp2
+                         glibmm-2.4.tag
+                         html/*